Projet

Général

Profil

0001-sms-factorise-sms-code-on-parameters-21465.patch

Nicolas Roche, 26 avril 2020 11:02

Télécharger (5,98 ko)

Voir les différences:

Subject: [PATCH 1/2] sms: factorise sms code on parameters (#21465)

 passerelle/base/models.py | 59 ++++++++++++++++++++++++---------------
 tests/test_sms.py         |  2 +-
 2 files changed, 38 insertions(+), 23 deletions(-)
passerelle/base/models.py
917 917
class SMSResource(BaseResource):
918 918
    category = _('SMS Providers')
919 919
    documentation_url = 'https://doc-publik.entrouvert.com/admin-fonctionnel/les-tutos/configuration-envoi-sms/'
920 920

  
921 921
    _can_send_messages_description = _('Sending messages is limited to the following API users:')
922 922

  
923 923
    max_message_length = models.IntegerField(_('Maximum message length'), default=160)
924 924

  
925
    @classmethod
926
    def clean_number(cls, destination, default_country_code='33',
927
                     default_trunk_prefix='0'):  # Yeah France first !
928
        # most gateways needs the number prefixed by the country code, this is
929
        # really unfortunate.
930
        dest = destination.strip()
931
        number = ''.join(re.findall('[0-9]', dest))
932
        if dest.startswith('+'):
933
            number = '00' + number
934
        elif number.startswith('00'):
935
            # assumes 00 is international access code, remove it
936
            pass
937
        elif number.startswith(default_trunk_prefix):
938
            number = '00' + default_country_code + number[len(default_trunk_prefix):]
939
        else:
940
            raise APIError('phone number %r is unsupported (no international prefix, '
941
                           'no local trunk prefix)' % number)
942
        return number
943

  
925 944
    @classmethod
926 945
    def clean_numbers(cls, destinations, default_country_code='33',
927 946
                      default_trunk_prefix='0'):  # Yeah France first !
928 947
        numbers = []
929 948
        for dest in destinations:
930
            # most gateways needs the number prefixed by the country code, this is
931
            # really unfortunate.
932
            dest = dest.strip()
933
            number = ''.join(re.findall('[0-9]', dest))
934
            if dest.startswith('+'):
935
                number = '00' + number
936
            elif number.startswith('00'):
937
                # assumes 00 is international access code, remove it
938
                pass
939
            elif number.startswith(default_trunk_prefix):
940
                number = '00' + default_country_code + number[len(default_trunk_prefix):]
941
            else:
942
                raise APIError('phone number %r is unsupported (no international prefix, '
943
                               'no local trunk prefix)' % number)
944
            numbers.append(number)
949
            numbers.append(cls.clean_number(
950
                dest, default_country_code, default_trunk_prefix))
945 951
        return numbers
946 952

  
947
    @endpoint(perm='can_send_messages', methods=['post'])
948
    def send(self, request, *args, **kwargs):
953
    def get_parameters(self, request, *args, **kwargs):
949 954
        try:
950 955
            data = json_loads(request.body)
951 956
            assert isinstance(data, dict), 'JSON payload is not a dict'
952 957
            assert 'message' in data, 'missing "message" in JSON payload'
953 958
            assert 'from' in data, 'missing "from" in JSON payload'
954 959
            assert 'to' in data, 'missing "to" in JSON payload'
955 960
            assert isinstance(data['message'], six.text_type), 'message is not a string'
956 961
            assert isinstance(data['from'], six.text_type), 'from is not a string'
957 962
            assert all(map(lambda x: isinstance(x, six.text_type), data['to'])), \
958 963
                'to is not a list of strings'
959 964
        except (ValueError, AssertionError) as e:
960 965
            raise APIError('Payload error: %s' % e)
961
        data['message'] = data['message'][:self.max_message_length]
962
        logging.info('sending message %r to %r with sending number %r',
963
                     data['message'], data['to'], data['from'])
964
        stop = not bool('nostop' in request.GET)
965
        result = {'data': self.send_msg(data['message'], data['from'], data['to'], stop=stop)}
966
        parameters = {
967
            'text': data['message'][:self.max_message_length],
968
            'sender': data['from'],
969
            'destinations': data['to'],
970
            'stop': not bool('nostop' in request.GET)
971
        }
972
        logging.info(
973
            'sending message %r to %r with sending number %r',
974
            parameters['text'], parameters['destinations'], parameters['sender'])
975
        return parameters
976

  
977
    @endpoint(perm='can_send_messages', methods=['post'])
978
    def send(self, request, *args, **kwargs):
979
        parameters = self.get_parameters(request, *args, **kwargs)
980
        result = {'data': self.send_msg(**parameters)}
966 981
        SMSLog.objects.create(appname=self.get_connector_slug(), slug=self.slug)
967 982
        return result
968 983

  
969 984
    class Meta:
970 985
        abstract = True
971 986

  
972 987

  
973 988
@six.python_2_unicode_compatible
tests/test_sms.py
86 86
    payload = {
87 87
        'message': message_above_limit,
88 88
        'from': '+33699999999',
89 89
        'to': ['+33688888888'],
90 90
    }
91 91
    with mock.patch.object(OVHSMSGateway, 'send_msg') as send_function:
92 92
        send_function.return_value = {}
93 93
        result = app.post_json(path, params=payload)
94
        assert send_function.call_args[0][0] == 'a' * connector.max_message_length
94
        assert send_function.call_args[1]['text'] == 'a' * connector.max_message_length
95 95

  
96 96

  
97 97
@pytest.mark.parametrize('connector', [OVHSMSGateway], indirect=True)
98 98
def test_sms_log(app, connector):
99 99
    path = '/%s/%s/send/' % (connector.get_connector_slug(), connector.slug)
100 100
    assert not SMSLog.objects.filter(appname=connector.get_connector_slug(), slug=connector.slug).exists()
101 101

  
102 102
    payload = {
103
-