def test_non_global_backends_with_direct_provider_fees( self, mock_log_smsbillables_error): bootstrap_twilio_gateway(apps) bootstrap_infobip_gateway(apps) bootstrap_usage_fees(apps) backends = generator.arbitrary_non_global_with_direct_fees_backends() for backend in backends: messages = [ message for phone_number in [generator.arbitrary_phone_number() for _ in range(10)] for message in generator.arbitrary_messages_by_backend_and_direction( {backend.hq_api_id: backend.couch_id}, phone_number=phone_number) ] for msg_log in messages: FakeMessageFactory.add_price_for_message( msg_log.backend_message_id, generator.arbitrary_fee()) for msg_log in messages: multipart_count = randint(1, 10) # Should be ignored billable = SmsBillable.create(msg_log, multipart_count=multipart_count) self.assertIsNotNone(billable) self.assertIsNone(billable.gateway_fee) self.assertEqual(billable.gateway_charge, 0) self.assertEqual(mock_log_smsbillables_error.call_count, 0)
def test_multipart_usage_charge_for_backends_with_direct_fees(self): self.apply_direction_fee() backends = generator.arbitrary_with_direct_fees_backends() for backend in backends: messages = generator.arbitrary_messages_by_backend_and_direction( {backend.hq_api_id: backend.couch_id}) for message in messages: FakeMessageFactory.add_num_segments_for_message( message.backend_message_id, randint(1, 10)) FakeMessageFactory.add_price_for_message( message.backend_message_id, generator.arbitrary_fee()) for message in messages: multipart_count = randint(1, 10) # Should be ignored billable = SmsBillable.create(message, multipart_count=multipart_count) self.assertIsNotNone(billable) self.assertEqual( billable.usage_charge, (self.least_specific_fees[message.direction] * FakeMessageFactory.get_num_segments_for_message( message.backend_message_id)))
class TestGatewayFee(TestCase): """ These tests take awhile to run. Ideally we can replace these tests with simpler tests to verify behavior of the gateway_charge method in test_gateway_charges. """ def setUp(self): super(TestGatewayFee, self).setUp() self.currency_usd = init_default_currency() self.backend_ids = generator.arbitrary_backend_ids() self.message_logs = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids) self.least_specific_fees = generator.arbitrary_fees_by_direction_and_backend( ) self.country_code_fees = generator.arbitrary_fees_by_country() self.instance_fees = generator.arbitrary_fees_by_backend_instance( self.backend_ids) self.most_specific_fees = generator.arbitrary_fees_by_all( self.backend_ids) self.country_code_and_prefixes = generator.arbitrary_country_code_and_prefixes( 3, 3) self.prefix_fees = generator.arbitrary_fees_by_prefix( self.backend_ids, self.country_code_and_prefixes) self.other_currency = generator.arbitrary_currency() # Must remove existing data populated in migrations SmsGatewayFee.objects.all().delete() SmsGatewayFeeCriteria.objects.all().delete() def create_least_specific_gateway_fees(self): for direction, fees in self.least_specific_fees.items(): for backend_api_id, amount in fees.items(): SmsGatewayFee.create_new(backend_api_id, direction, amount) def create_other_currency_fees(self): for direction, fees in self.least_specific_fees.items(): for backend_api_id, amount in fees.items(): SmsGatewayFee.create_new(backend_api_id, direction, amount, currency=self.other_currency) def create_country_code_gateway_fees(self): for direction, backend in self.country_code_fees.items(): for backend_api_id, country in backend.items(): for country_code, amount in country.items(): SmsGatewayFee.create_new(backend_api_id, direction, amount, country_code=country_code) def create_instance_gateway_fees(self): for direction, backend in self.instance_fees.items(): for backend_api_id, (backend_instance, amount) in backend.items(): SmsGatewayFee.create_new(backend_api_id, direction, amount, backend_instance=backend_instance) def create_most_specific_gateway_fees(self): for direction, backend in self.most_specific_fees.items(): for backend_api_id, country in backend.items(): for country_code, (backend_instance, amount) in country.items(): SmsGatewayFee.create_new(backend_api_id, direction, amount, country_code=country_code, backend_instance=backend_instance) def create_prefix_gateway_fees(self): for direction, backend in self.prefix_fees.items(): for backend_api_id, country in backend.items(): for country_code, prfx in country.items(): for prefix, backend_instance_and_amount in prfx.items(): for backend_instance, amount in backend_instance_and_amount.items( ): SmsGatewayFee.create_new( backend_api_id, direction, amount, country_code=country_code, prefix=prefix, backend_instance=backend_instance, ) def test_least_specific_fees(self): self.create_least_specific_gateway_fees() for msg_log in self.message_logs: billable = SmsBillable.create(msg_log) self.assertIsNotNone(billable) self.assertEqual( billable.gateway_charge, self.least_specific_fees[billable.direction][ billable.gateway_fee.criteria.backend_api_id]) def test_multipart_gateway_charge(self): self.create_least_specific_gateway_fees() for msg_log in self.message_logs: multipart_count = randint(1, 10) billable = SmsBillable.create(msg_log, multipart_count=multipart_count) self.assertIsNotNone(billable) self.assertEqual( billable.gateway_charge, self.least_specific_fees[billable.direction][ billable.gateway_fee.criteria.backend_api_id] * multipart_count) def test_other_currency_fees(self): self.create_other_currency_fees() for msg_log in self.message_logs: billable = SmsBillable.create(msg_log) self.assertIsNotNone(billable) self.assertEqual( billable.gateway_charge, self.least_specific_fees[billable.direction][ billable.gateway_fee.criteria.backend_api_id] / self.other_currency.rate_to_default) def test_country_code_fees(self): self.create_least_specific_gateway_fees() self.create_country_code_gateway_fees() phone_numbers = [generator.arbitrary_phone_number() for i in range(10)] for phone_number in phone_numbers: messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids, phone_number=phone_number) for msg_log in messages: billable = SmsBillable.create(msg_log) self.assertIsNotNone(billable) self.assertEqual( billable.gateway_charge, self.country_code_fees[billable.direction][ billable.gateway_fee.criteria.backend_api_id][int( phone_number[:-10])]) def test_instance_fees(self): self.create_least_specific_gateway_fees() self.create_country_code_gateway_fees() self.create_instance_gateway_fees() phone_numbers = [generator.arbitrary_phone_number() for i in range(10)] for phone_number in phone_numbers: messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids, phone_number=phone_number) for msg_log in messages: billable = SmsBillable.create(msg_log) self.assertIsNotNone(billable) self.assertEqual( billable.gateway_charge, self.instance_fees[billable.direction][ billable.gateway_fee.criteria.backend_api_id][1]) def test_specific_fees(self): self.create_least_specific_gateway_fees() self.create_country_code_gateway_fees() self.create_instance_gateway_fees() self.create_most_specific_gateway_fees() phone_numbers = [generator.arbitrary_phone_number() for i in range(10)] for phone_number in phone_numbers: messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids, phone_number=phone_number) for msg_log in messages: billable = SmsBillable.create(msg_log) self.assertIsNotNone(billable) self.assertEqual( billable.gateway_charge, self.most_specific_fees[billable.direction][ billable.gateway_fee.criteria.backend_api_id][int( phone_number[:-10])][1]) def test_prefix_fees(self): self.create_prefix_gateway_fees() for phone_number, prefix in generator.arbitrary_phone_numbers_and_prefixes( self.country_code_and_prefixes): random_key = choice(list(self.backend_ids)) messages = generator.arbitrary_messages_by_backend_and_direction( {random_key: self.backend_ids[random_key]}, phone_number=phone_number, ) for msg_log in messages: billable = SmsBillable.create(msg_log) self.assertIsNotNone(billable) try: self.assertEqual( billable.gateway_charge, self.prefix_fees[billable.direction] [billable.gateway_fee.criteria.backend_api_id][ phone_number[:-10]][prefix][msg_log.backend_id]) except AssertionError: raise Exception("Phone number: %s, " % phone_number + "given prefix: %s, " % prefix + "found prefix: %s" % billable.gateway_fee.criteria.prefix) def test_no_matching_fee(self): self.create_least_specific_gateway_fees() self.create_country_code_gateway_fees() self.create_instance_gateway_fees() self.create_most_specific_gateway_fees() phone_numbers = [generator.arbitrary_phone_number() for i in range(10)] for phone_number in phone_numbers: messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids, phone_number=phone_number, directions=['X', 'Y']) for msg_log in messages: billable = SmsBillable.create(msg_log) self.assertIsNotNone(billable) self.assertIsNone(billable.gateway_fee) def test_fee_for_non_global_backend(self): self.create_least_specific_gateway_fees() private_backend_ids = generator.arbitrary_non_global_backend_ids() messages = generator.arbitrary_messages_by_backend_and_direction( private_backend_ids) arbitrary_message = messages[randint(0, len(messages) - 1)] toggles.ENABLE_INCLUDE_SMS_GATEWAY_CHARGING.set( arbitrary_message.domain, True, toggles.NAMESPACE_DOMAIN) billable = SmsBillable.create(arbitrary_message) toggles.ENABLE_INCLUDE_SMS_GATEWAY_CHARGING.set( arbitrary_message.domain, False, toggles.NAMESPACE_DOMAIN) self.assertIsNotNone(billable) self.assertIsNotNone(billable.gateway_fee) self.assertEqual( billable.gateway_charge, self.least_specific_fees[billable.direction][ billable.gateway_fee.criteria.backend_api_id]) @patch( 'corehq.messaging.smsbackends.infobip.models.InfobipBackend.get_message', lambda self, message_id: FakeMessageFactory.get_infobip_message( message_id)) @patch('twilio.rest.api.v2010.account.message.MessageList.get', lambda self, message_id: FakeMessageFactory.get_twilio_message(message_id)) def test_global_backends_with_direct_provider_fees(self): bootstrap_twilio_gateway(apps) bootstrap_infobip_gateway(apps) bootstrap_usage_fees(apps) backends = generator.arbitrary_with_direct_fees_backends() for backend in backends: messages = [ message for phone_number in [generator.arbitrary_phone_number() for _ in range(10)] for message in generator.arbitrary_messages_by_backend_and_direction( {backend.hq_api_id: backend.couch_id}, phone_number=phone_number) ] for msg_log in messages: FakeMessageFactory.add_price_for_message( msg_log.backend_message_id, generator.arbitrary_fee()) for msg_log in messages: multipart_count = randint(1, 10) # Should be ignored billable = SmsBillable.create(msg_log, multipart_count=multipart_count) self.assertIsNotNone(billable) self.assertIsNotNone(billable.gateway_fee) self.assertEqual( billable.gateway_charge, FakeMessageFactory.get_price_for_message( msg_log.backend_message_id)) @patch('corehq.apps.smsbillables.models.log_smsbillables_error') @patch( 'corehq.messaging.smsbackends.infobip.models.InfobipBackend.get_message', lambda self, message_id: FakeMessageFactory.get_infobip_message( message_id)) @patch('twilio.rest.api.v2010.account.message.MessageList.get', lambda self, message_id: FakeMessageFactory.get_twilio_message(message_id)) def test_non_global_backends_with_direct_provider_fees( self, mock_log_smsbillables_error): bootstrap_twilio_gateway(apps) bootstrap_infobip_gateway(apps) bootstrap_usage_fees(apps) backends = generator.arbitrary_non_global_with_direct_fees_backends() for backend in backends: messages = [ message for phone_number in [generator.arbitrary_phone_number() for _ in range(10)] for message in generator.arbitrary_messages_by_backend_and_direction( {backend.hq_api_id: backend.couch_id}, phone_number=phone_number) ] for msg_log in messages: FakeMessageFactory.add_price_for_message( msg_log.backend_message_id, generator.arbitrary_fee()) for msg_log in messages: multipart_count = randint(1, 10) # Should be ignored billable = SmsBillable.create(msg_log, multipart_count=multipart_count) self.assertIsNotNone(billable) self.assertIsNone(billable.gateway_fee) self.assertEqual(billable.gateway_charge, 0) self.assertEqual(mock_log_smsbillables_error.call_count, 0) def tearDown(self): SmsBillable.objects.all().delete() SmsGatewayFee.objects.all().delete() SmsGatewayFeeCriteria.objects.all().delete() SmsUsageFee.objects.all().delete() SmsUsageFeeCriteria.objects.all().delete() self.currency_usd.delete() self.other_currency.delete() SMS.by_domain(generator.TEST_DOMAIN).delete() for api_id, backend_id in self.backend_ids.items(): SQLMobileBackend.load(backend_id, is_couch_id=True).delete() FakeMessageFactory.backend_message_id_to_price = {} super(TestGatewayFee, self).tearDown()
class TestUsageFee(TestCase): def setUp(self): super(TestUsageFee, self).setUp() # Must remove existing data populated in migrations SmsUsageFee.objects.all().delete() SmsUsageFeeCriteria.objects.all().delete() self.currency_usd = init_default_currency() self.least_specific_fees = generator.arbitrary_fees_by_direction() self.most_specific_fees = generator.arbitrary_fees_by_direction_and_domain( ) self.backend_ids = generator.arbitrary_backend_ids() def apply_direction_fee(self): for direction, amount in self.least_specific_fees.items(): SmsUsageFee.create_new(direction, amount) def apply_direction_and_domain_fee(self): for direction, domain_fee in self.most_specific_fees.items(): for domain, amount in domain_fee.items(): SmsUsageFee.create_new(direction, amount, domain=domain) def test_only_direction(self): self.apply_direction_fee() messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids) for message in messages: billable = SmsBillable.create(message) self.assertIsNotNone(billable) self.assertEqual(billable.usage_charge, self.least_specific_fees[message.direction]) def test_domain_and_direction(self): self.apply_direction_fee() self.apply_direction_and_domain_fee() for direction, domain_fee in self.most_specific_fees.items(): for domain in domain_fee: messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids, domain=domain, ) for message in messages: billable = SmsBillable.create(message) self.assertIsNotNone(billable) self.assertEqual( billable.usage_charge, self.most_specific_fees[message.direction][domain]) def test_multipart_usage_charge(self): self.apply_direction_fee() self.apply_direction_and_domain_fee() for direction, domain_fee in self.most_specific_fees.items(): for domain in domain_fee: messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids, domain=domain, ) for message in messages: multipart_count = randint(1, 10) billable = SmsBillable.create( message, multipart_count=multipart_count) self.assertIsNotNone(billable) self.assertEqual( billable.usage_charge, self.most_specific_fees[message.direction][domain] * multipart_count) @patch( 'corehq.messaging.smsbackends.infobip.models.InfobipBackend.get_message', lambda self, message_id: FakeMessageFactory.get_infobip_message( message_id)) @patch('twilio.rest.api.v2010.account.message.MessageList.get', lambda self, message_id: FakeMessageFactory.get_twilio_message(message_id)) def test_multipart_usage_charge_for_backends_with_direct_fees(self): self.apply_direction_fee() backends = generator.arbitrary_with_direct_fees_backends() for backend in backends: messages = generator.arbitrary_messages_by_backend_and_direction( {backend.hq_api_id: backend.couch_id}) for message in messages: FakeMessageFactory.add_num_segments_for_message( message.backend_message_id, randint(1, 10)) FakeMessageFactory.add_price_for_message( message.backend_message_id, generator.arbitrary_fee()) for message in messages: multipart_count = randint(1, 10) # Should be ignored billable = SmsBillable.create(message, multipart_count=multipart_count) self.assertIsNotNone(billable) self.assertEqual( billable.usage_charge, (self.least_specific_fees[message.direction] * FakeMessageFactory.get_num_segments_for_message( message.backend_message_id))) def test_log_no_usage_fee(self): self.apply_direction_fee() self.apply_direction_and_domain_fee() for direction, domain_fee in self.most_specific_fees.items(): for domain in domain_fee: messages = generator.arbitrary_messages_by_backend_and_direction( self.backend_ids, domain=domain, directions=['X', 'Y'], ) for message in messages: billable = SmsBillable.create(message) self.assertIsNotNone(billable) self.assertIsNone(billable.usage_fee) def tearDown(self): SmsBillable.objects.all().delete() SmsUsageFee.objects.all().delete() SmsUsageFeeCriteria.objects.all().delete() SmsGatewayFee.objects.all().delete() self.currency_usd.delete() for api_id, backend_id in self.backend_ids.items(): SQLMobileBackend.load(backend_id, is_couch_id=True).delete() FakeMessageFactory.backend_message_id_to_price = {} super(TestUsageFee, self).tearDown()