def test_action_schedule_job(self): to_get_scheduled = JobFactory.create_batch(2, status=Job.DRAFT) already_scheduled = JobFactory(status=Job.SCHEDULED) already_published = JobFactory(status=Job.PUBLISHED) cancelled = JobFactory(status=Job.CANCELED) completed = JobFactory(status=Job.COMPLETED) JobFactory.create_batch(2, status=Job.DRAFT) queryset = Job.objects.filter(id__in=[ to_get_scheduled[0].id, to_get_scheduled[1].id, already_scheduled.id, already_published.id, cancelled.id, completed.id, ]) request = Mock() request.user = UserFactory.create() with patch.multiple('snippets.base.admin.adminmodels.messages', warning=DEFAULT_MOCK, success=DEFAULT_MOCK) as message_mocks: JobAdmin(Job, None).action_schedule_job(request, queryset) self.assertEqual( set(Job.objects.filter(status=Job.SCHEDULED)), set(to_get_scheduled + [already_scheduled]) ) self.assertTrue(message_mocks['warning'].called) self.assertTrue(message_mocks['success'].called)
def test_change_status_to_completed(self): job = JobFactory.create(status=Job.DRAFT) with patch('snippets.base.models.datetime') as datetime_mock: datetime_mock.utcnow.return_value = datetime(2019, 1, 1, 0, 0) job.change_status(status=Job.COMPLETED, user=None, send_slack=False) job.refresh_from_db() self.assertEqual(job.status, Job.COMPLETED) self.assertEqual(job.completed_on, datetime(2019, 1, 1, 0, 0))
def test_channels(self): job = JobFactory.create(targets=[ TargetFactory.create(on_release=True), TargetFactory.create(on_beta=True, on_nightly=True), TargetFactory.create(on_release=False, on_esr=False, on_aurora=False, on_beta=False, on_nightly=False), ]) self.assertTrue(job.channels, set(['release', 'beta', 'nightly']))
def test_change_status(self): job = JobFactory.create(status=Job.DRAFT) with patch('snippets.base.models.slack') as slack_mock: with patch('snippets.base.models.LogEntry') as log_entry_mock: job.change_status(status=Job.SCHEDULED, user=job.creator, send_slack=True) job.refresh_from_db() self.assertEqual(job.status, Job.SCHEDULED) log_entry_mock.objects.log_action.assert_called() slack_mock._send_slack.assert_called()
def test_delete(self): distribution = DistributionFactory() distribution_bundle = DistributionBundleFactory( code_name='foo', enabled=False, ) distribution_bundle.distributions.add(distribution) target = TargetFactory(on_release=False, on_beta=False, on_nightly=True, on_esr=False, on_aurora=False) JobFactory( status=models.Job.COMPLETED, snippet__locale=',fr,', targets=[target], ) # Still published, but belongs to a disabled distribution JobFactory( status=models.Job.PUBLISHED, snippet__locale=',fr,', targets=[target], distribution=distribution, ) with patch( 'snippets.base.management.commands.generate_bundles.default_storage' ) as ds_mock: # Test that only removes if file exists. ds_mock.exists.return_value = True call_command('generate_bundles', stdout=Mock()) ds_mock.delete.assert_has_calls([ call('pregen/Firefox/nightly/fr/default.json'), call('pregen/Firefox/nightly/fr/foo.json') ]) ds_mock.save.assert_not_called()
def test_modified_date_updates_when_target_updates(self): target = TargetFactory() job = JobFactory(targets=[target]) snippet = job.snippet # Must refresh from db to get the actual datetime stored in db which # may be different by milliseconds from the original python datetime. snippet.refresh_from_db() old_modified = snippet.modified target.name = 'new name' target.save() snippet.refresh_from_db() new_modified = snippet.modified self.assertNotEqual(old_modified, new_modified)
def test_render_always_eval_to_false(self): job = JobFactory.create(weight=10, campaign__slug='demo-campaign', targets=[ TargetFactory(on_release=False, on_beta=False, on_esr=False, on_aurora=False, on_nightly=True, jexl_expr='(la==lo)'), ]) job.snippet.render = Mock() job.snippet.render.return_value = {} generated_output = job.render(always_eval_to_false=True) self.assertEqual(generated_output['targeting'], '(la==lo) && false')
def test_modified_date_updates_when_campaign_updates(self): job = JobFactory() snippet = job.snippet # Must refresh from db to get the actual datetime stored in db which # may be different by milliseconds from the original python datetime. snippet.refresh_from_db() old_modified = snippet.modified campaign = job.campaign campaign.name = 'new name' campaign.save() snippet.refresh_from_db() new_modified = snippet.modified self.assertNotEqual(old_modified, new_modified)
def test_modified_date_updates_when_distribution_bundle_updates(self): job = JobFactory() distribution_bundle = DistributionBundleFactory() distribution_bundle.distributions.add(job.distribution) snippet = job.snippet # Must refresh from db to get the actual datetime stored in db which # may be different by milliseconds from the original python datetime. snippet.refresh_from_db() old_modified = snippet.modified distribution_bundle.code_name = 'bar' distribution_bundle.save() snippet.refresh_from_db() new_modified = snippet.modified self.assertNotEqual(old_modified, new_modified)
def test_render(self): self.maxDiff = None job = JobFactory.create(weight=10, campaign__slug='demo-campaign', targets=[ TargetFactory(on_release=False, on_beta=False, on_esr=False, on_aurora=False, on_nightly=True, jexl_expr='(la==lo)'), TargetFactory(on_release=False, on_beta=True, on_esr=False, on_aurora=False, on_nightly=True), TargetFactory(on_release=False, on_beta=True, on_esr=False, on_aurora=False, on_nightly=True, jexl_expr='foo==bar'), ]) snippet_render = { 'template': 'simple_snippet', 'template_version': 'xx.xx', 'content': { 'block_button_text': 'Block me', 'text': 'This is text [[job_id]]', } } expected_output = copy.deepcopy(snippet_render) expected_output.update({ 'id': str(job.id), 'weight': 10, 'campaign': 'demo-campaign', 'targeting': '(la==lo) && foo==bar', 'content': { 'block_button_text': 'Block me', 'text': f'This is text {job.id}', } }) job.snippet.render = Mock() job.snippet.render.return_value = snippet_render generated_output = job.render() self.assertEqual(generated_output, expected_output)
def test_duplicate(self): user = UserFactory.create() job = JobFactory.create(status=Job.PUBLISHED, metric_impressions=500, metric_clicks=500, metric_blocks=500, completed_on=datetime.utcnow()) duplicate_job = job.duplicate(user) job.refresh_from_db() for attr in ['id', 'creator', 'created', 'modified', 'uuid']: self.assertNotEqual(getattr(job, attr), getattr(duplicate_job, attr)) self.assertEqual(duplicate_job.status, Job.DRAFT) self.assertEqual(duplicate_job.metric_impressions, 0) self.assertEqual(duplicate_job.metric_clicks, 0) self.assertEqual(duplicate_job.metric_blocks, 0) self.assertEqual(duplicate_job.completed_on, None)
def test_delete_does_not_exist(self): target = TargetFactory(on_release=False, on_beta=False, on_nightly=True, on_esr=False, on_aurora=False) JobFactory( status=models.Job.COMPLETED, snippet__locale=',fr,', targets=[target], ) with patch( 'snippets.base.management.commands.generate_bundles.default_storage' ) as ds_mock: # Test that only removes if file exists. ds_mock.exists.return_value = False call_command('generate_bundles', stdout=Mock()) ds_mock.delete.assert_not_called() ds_mock.save.assert_not_called()
def test_name(self): JobFactory.create(id=2990, snippet__id=20000, snippet__name='foo 1') JobFactory.create(id=2991, snippet__id=20001, snippet__name='foo 2') job = JobFactory.create(id=2992, snippet__id=20002, snippet__name='bar 1') JobFactory.create(id=2993, snippet__name='foo lala foo') filtr = JobFilter( QueryDict(query_string='only_scheduled=all&name=bar'), queryset=models.Job.objects.all()) self.assertEqual(set([job]), set(filtr.qs)) # Test search with Job ID filtr = JobFilter( QueryDict(query_string=f'only_scheduled=all&name={job.id}'), queryset=models.Job.objects.all()) self.assertEqual(set([job]), set(filtr.qs)) # Test search with Snippet ID filtr = JobFilter(QueryDict( query_string=f'only_scheduled=all&name={job.snippet.id}'), queryset=models.Job.objects.all()) self.assertEqual(set([job]), set(filtr.qs))
def test_only_scheduled_false(self): job1 = JobFactory.create(publish_start=None, publish_end=None) JobFactory.create(publish_end=datetime(2019, 2, 2)) filtr = JobFilter(QueryDict(query_string='only_scheduled=false'), queryset=models.Job.objects.all()) self.assertEqual(set([job1]), set(filtr.qs))
def test_render_client_limits(self): # Combined job = JobFactory.create( client_limit_lifetime=100, client_limit_per_hour=10, client_limit_per_month=100, campaign__slug='demo_campaign', ) expected_output = { 'id': str(job.id), 'weight': 100, 'campaign': 'demo_campaign', 'targeting': '', 'frequency': { 'lifetime': 100, 'custom': [{ 'period': 3600000, 'cap': 10 }, { 'period': 2592000000, 'cap': 100 }] } } job.snippet.render = Mock() job.snippet.render.return_value = {} generated_output = job.render() self.assertEqual(generated_output, expected_output) # Lifetime limit only job = JobFactory.create( client_limit_lifetime=100, campaign__slug='demo_campaign_1', ) expected_output = { 'id': str(job.id), 'weight': 100, 'campaign': 'demo_campaign_1', 'targeting': '', 'frequency': { 'lifetime': 100, } } job.snippet.render = Mock() job.snippet.render.return_value = {} generated_output = job.render() self.assertEqual(generated_output, expected_output) # Custom limits only # Lifetime limit only job = JobFactory.create( client_limit_per_week=9, client_limit_per_fortnight=99, campaign__slug='demo_campaign_2', ) expected_output = { 'id': str(job.id), 'weight': 100, 'campaign': 'demo_campaign_2', 'targeting': '', 'frequency': { 'custom': [{ 'period': 604800000, 'cap': 9 }, { 'period': 1296000000, 'cap': 99 }] } } job.snippet.render = Mock() job.snippet.render.return_value = {} generated_output = job.render() self.assertEqual(generated_output, expected_output)
def test_only_scheduled_all(self): job1, job2 = JobFactory.create_batch(2) job3 = JobFactory.create(publish_end=datetime(2019, 2, 2)) filtr = JobFilter(QueryDict(query_string='only_scheduled=all'), queryset=models.Job.objects.all()) self.assertEqual(set([job1, job2, job3]), set(filtr.qs))
def test_base(self): JobFactory.create( id=1000, status=Job.COMPLETED, publish_start=date(2020, 1, 1), completed_on=date(2020, 1, 10), ) JobFactory.create(id=2000) JobDailyPerformance(date=date(2020, 1, 9), impression=100, job=Job.objects.get(id=1000)).save() rows = [ [ { 'message_id': '1000', 'event_context': '{}', 'event': 'CLICK_BUTTON', 'channel': 'release', 'country_code': 'GR', 'counts': 5, 'no_clients': 2, 'no_clients_total': 0, }, { 'message_id': '1000', 'event_context': '{}', 'event': 'IMPRESSION', 'channel': 'release', 'country_code': 'ES', 'counts': 30, 'no_clients': 10, 'no_clients_total': 0, }, { 'message_id': '1000', 'event_context': '{}', 'event': 'IMPRESSION', 'channel': 'release', 'country_code': 'IT', 'counts': 50, 'no_clients': 20, 'no_clients_total': 0, }, { 'message_id': '1000', 'event_context': '{}', 'event': 'BLOCK', 'channel': 'releases', 'country_code': 'UK', 'counts': 23, 'no_clients': 9, 'no_clients_total': 0, }, { 'message_id': '1000', 'event_context': '{}', 'event': 'BLOCK', 'channel': 'beta-test', 'country_code': 'SW', 'counts': 27, 'no_clients': 50, 'no_clients_total': 0, }, # To be discarded { 'message_id': '500', 'event_context': '{}', 'event': 'CLICK', 'channel': 'demo', 'country_code': 'GR', 'counts': 5, 'no_clients': 10, 'no_clients_total': 0, }, { 'message_id': '1000', 'event_context': '', 'event': 'CLICK', 'channel': 'release', 'country_code': 'GR', 'counts': 6, 'no_clients': 10, 'no_clients_total': 0, }, { 'message_id': '2000', 'event_context': '{}', 'event': 'CLICK_BUTTON', 'additional_properties': '{"value": "scene1-button-learn-more", "foo": "bar"}', 'channel': 'release', 'country_code': 'GR', 'counts': 44, 'no_clients': 33, 'no_clients_total': 0, }, { 'message_id': '2000', 'event_context': '{}', 'event': 'CLICK_BUTTON', 'channel': 'release', 'country_code': 'BG', 'counts': 3, 'no_clients': 10, 'no_clients_total': 0, }, { 'message_id': '2000', 'event_context': '{}', 'event': 'CLICK_BUTTON', 'channel': 'release', 'country_code': 'AL', 'counts': 1, 'no_clients': 10, 'no_clients_total': 0, }, { 'message_id': '2000', 'event_context': 'conversion-subscribe-activation', 'event': 'CLICK_BUTTON', 'additional_properties': '{"foo": "bar"}', 'channel': 'release', 'country_code': 'GR', 'counts': 5, 'no_clients': 8, 'no_clients_total': 0, }, { 'message_id': '2000', 'event_context': 'subscribe-error', 'event': 'CLICK_BUTTON', 'additional_properties': '{"foo": "bar"}', 'channel': 'release', 'country_code': 'GR', 'counts': 3, 'no_clients': 4, 'no_clients_total': 0, }, { 'message_id': '2000', 'event_context': 'subscribe-success', 'event': 'CLICK_BUTTON', 'channel': 'release', 'country_code': 'ERROR', 'counts': 9, 'no_clients': 57, 'no_clients_total': 0, }, { 'message_id': '2000', 'event_context': '', 'event': 'DISMISS', 'channel': 'beta', 'country_code': 'ERROR', 'counts': 1, 'no_clients': 1, 'no_clients_total': 0, }, ], [ { 'message_id': '1000', 'event_context': '', 'event': 'IMPRESSION', 'channel': 'release', 'country_code': 'ES', 'counts': 0, 'no_clients': 0, 'no_clients_total': 232, }, { 'message_id': '1000', 'event_context': '', 'event': 'IMPRESSION', 'channel': 'release', 'country_code': 'IT', 'counts': 0, 'no_clients': 0, 'no_clients_total': 421, }, ], ] with patch('snippets.base.etl.redash_rows') as redash_rows_mock: redash_rows_mock.side_effect = rows result = etl.update_job_metrics(date(2020, 1, 10)) self.assertEqual(redash_rows_mock.call_count, 2) self.assertTrue(result) self.assertEqual(JobDailyPerformance.objects.count(), 3) jdp1 = JobDailyPerformance.objects.filter( job_id=1000).order_by('-id')[0] self.assertEqual(jdp1.impression, 80) self.assertEqual(jdp1.impression_no_clients, 30) self.assertEqual(jdp1.impression_no_clients_total, 653) self.assertEqual(jdp1.click, 11) self.assertEqual(jdp1.click_no_clients, 12) self.assertEqual(jdp1.click_no_clients_total, 0) self.assertEqual(jdp1.block, 50) self.assertEqual(jdp1.block_no_clients, 59) self.assertEqual(jdp1.block_no_clients_total, 0) self.assertEqual(jdp1.dismiss, 0) self.assertEqual(jdp1.dismiss_no_clients, 0) self.assertEqual(jdp1.dismiss_no_clients_total, 0) self.assertEqual(jdp1.go_to_scene2, 0) self.assertEqual(jdp1.go_to_scene2_no_clients, 0) self.assertEqual(jdp1.go_to_scene2_no_clients_total, 0) self.assertEqual(jdp1.subscribe_error, 0) self.assertEqual(jdp1.subscribe_error_no_clients, 0) self.assertEqual(jdp1.subscribe_error_no_clients_total, 0) self.assertEqual(jdp1.subscribe_success, 0) self.assertEqual(jdp1.subscribe_success_no_clients, 0) self.assertEqual(jdp1.subscribe_success_no_clients_total, 0) self.assertEqual(jdp1.other_click, 0) self.assertEqual(jdp1.other_click_no_clients, 0) self.assertEqual(jdp1.other_click_no_clients_total, 0) self.assertEqual(len(jdp1.details), 5) for detail in [{ 'event': 'click', 'counts': 11, 'channel': 'release', 'country': 'GR', 'no_clients': 12, 'no_clients_total': 0 }, { 'event': 'impression', 'counts': 30, 'channel': 'release', 'country': 'ES', 'no_clients': 10, 'no_clients_total': 232 }, { 'event': 'impression', 'counts': 50, 'channel': 'release', 'country': 'IT', 'no_clients': 20, 'no_clients_total': 421 }, { 'event': 'block', 'counts': 23, 'channel': 'release', 'country': 'UK', 'no_clients': 9, 'no_clients_total': 0 }, { 'event': 'block', 'counts': 27, 'channel': 'beta', 'country': 'SW', 'no_clients': 50, 'no_clients_total': 0 }]: self.assertTrue(detail in jdp1.details) jdp2 = JobDailyPerformance.objects.get(job_id=2000) self.assertEqual(jdp2.impression, 0) self.assertEqual(jdp2.impression_no_clients, 0) self.assertEqual(jdp2.impression_no_clients_total, 0) self.assertEqual(jdp2.click, 5) self.assertEqual(jdp2.click_no_clients, 8) self.assertEqual(jdp2.click_no_clients_total, 0) self.assertEqual(jdp2.block, 0) self.assertEqual(jdp2.block_no_clients, 0) self.assertEqual(jdp2.block_no_clients_total, 0) self.assertEqual(jdp2.dismiss, 1) self.assertEqual(jdp2.dismiss_no_clients, 1) self.assertEqual(jdp2.dismiss_no_clients_total, 0) self.assertEqual(jdp2.go_to_scene2, 44) self.assertEqual(jdp2.go_to_scene2_no_clients, 33) self.assertEqual(jdp2.go_to_scene2_no_clients_total, 0) self.assertEqual(jdp2.subscribe_error, 3) self.assertEqual(jdp2.subscribe_error_no_clients, 4) self.assertEqual(jdp2.subscribe_error_no_clients_total, 0) self.assertEqual(jdp2.subscribe_success, 9) self.assertEqual(jdp2.subscribe_success_no_clients, 57) self.assertEqual(jdp2.subscribe_success_no_clients_total, 0) self.assertEqual(jdp2.other_click, 4) self.assertEqual(jdp2.other_click_no_clients, 20) self.assertEqual(jdp2.other_click_no_clients_total, 0) self.assertEqual(len(jdp2.details), 7) for detail in [{ 'event': 'go_to_scene2', 'counts': 44, 'channel': 'release', 'country': 'GR', 'no_clients': 33, 'no_clients_total': 0 }, { 'event': 'other_click', 'counts': 3, 'channel': 'release', 'country': 'BG', 'no_clients': 10, 'no_clients_total': 0 }, { 'event': 'other_click', 'counts': 1, 'channel': 'release', 'country': 'AL', 'no_clients': 10, 'no_clients_total': 0 }, { 'event': 'click', 'counts': 5, 'channel': 'release', 'country': 'GR', 'no_clients': 8, 'no_clients_total': 0 }, { 'event': 'subscribe_error', 'counts': 3, 'channel': 'release', 'country': 'GR', 'no_clients': 4, 'no_clients_total': 0 }, { 'event': 'subscribe_success', 'counts': 9, 'channel': 'release', 'country': 'XX', 'no_clients': 57, 'no_clients_total': 0 }, { 'event': 'dismiss', 'counts': 1, 'channel': 'beta', 'country': 'XX', 'no_clients': 1, 'no_clients_total': 0 }]: self.assertTrue(detail in jdp2.details)
def test_base(self): now = datetime.utcnow() job_without_end_date = JobFactory(status=models.Job.PUBLISHED, publish_end=None) job_that_has_ended = JobFactory(status=models.Job.PUBLISHED, publish_end=now) job_ending_in_the_future = JobFactory(status=models.Job.PUBLISHED, limit_impressions=10000, metric_last_update=now, publish_end=now + timedelta(days=1)) job_scheduled_not_ready_to_go = JobFactory(status=models.Job.SCHEDULED, publish_start=now) job_scheduled_ready_to_go = JobFactory(status=models.Job.SCHEDULED, publish_start=now - timedelta(minutes=10)) job_scheduled_in_the_future = JobFactory(status=models.Job.SCHEDULED, publish_start=now + timedelta(days=1)) job_impression_limit_reached = JobFactory(status=models.Job.PUBLISHED, limit_impressions=10000, metric_impressions=10000, metric_last_update=now, publish_end=now + timedelta(days=1)) job_click_limit_reached = JobFactory(status=models.Job.PUBLISHED, limit_impressions=10000, metric_impressions=1000, limit_clicks=1000, metric_clicks=1001, metric_last_update=now, publish_end=now + timedelta(days=1)) job_block_limit_reached = JobFactory( status=models.Job.PUBLISHED, limit_blocks=10, metric_blocks=1000, metric_last_update=now - timedelta(minutes=30), publish_end=now + timedelta(days=1)) job_impression_limit_not_reached = JobFactory( status=models.Job.PUBLISHED, limit_impressions=100, metric_impressions=10, metric_last_update=now - timedelta(hours=12), publish_end=now + timedelta(days=1)) job_click_limit_not_reached = JobFactory( status=models.Job.PUBLISHED, limit_clicks=100, metric_clicks=10, metric_last_update=now - timedelta(hours=1), publish_end=now + timedelta(days=1)) job_block_limit_not_reached = JobFactory(status=models.Job.PUBLISHED, limit_blocks=100, metric_blocks=10, metric_last_update=now, publish_end=now + timedelta(days=1)) job_impression_limit_not_reached_but_no_data = JobFactory( status=models.Job.PUBLISHED, limit_impressions=100, metric_impressions=10, metric_last_update=now - timedelta(hours=26), publish_end=now + timedelta(days=1)) job_click_limit_not_reached_but_no_data = JobFactory( status=models.Job.PUBLISHED, limit_clicks=100, metric_clicks=10, metric_last_update=now - timedelta(hours=30), publish_end=now + timedelta(days=1)) job_block_limit_not_reached_but_no_data = JobFactory( status=models.Job.PUBLISHED, limit_blocks=100, metric_blocks=10, metric_last_update=now - timedelta(hours=40), publish_end=now + timedelta(days=1)) job_block_limit_not_reached_just_created = JobFactory( status=models.Job.PUBLISHED, limit_blocks=100, metric_blocks=10, publish_end=now + timedelta(days=1)) job_cancelled = JobFactory(status=models.Job.CANCELED) job_completed = JobFactory(status=models.Job.COMPLETED) call_command('update_jobs', stdout=Mock()) job_without_end_date.refresh_from_db() job_that_has_ended.refresh_from_db() job_ending_in_the_future.refresh_from_db() job_scheduled_not_ready_to_go.refresh_from_db() job_scheduled_ready_to_go.refresh_from_db() job_scheduled_in_the_future.refresh_from_db() job_cancelled.refresh_from_db() job_completed.refresh_from_db() job_impression_limit_reached.refresh_from_db() job_click_limit_reached.refresh_from_db() job_block_limit_reached.refresh_from_db() job_impression_limit_not_reached.refresh_from_db() job_click_limit_not_reached.refresh_from_db() job_block_limit_not_reached.refresh_from_db() job_impression_limit_not_reached_but_no_data.refresh_from_db() job_click_limit_not_reached_but_no_data.refresh_from_db() job_block_limit_not_reached_but_no_data.refresh_from_db() job_block_limit_not_reached_just_created.refresh_from_db() self.assertEqual(job_without_end_date.status, models.Job.PUBLISHED) self.assertEqual(job_that_has_ended.status, models.Job.COMPLETED) self.assertEqual(job_ending_in_the_future.status, models.Job.PUBLISHED) self.assertEqual(job_scheduled_not_ready_to_go.status, models.Job.SCHEDULED) self.assertEqual(job_scheduled_ready_to_go.status, models.Job.PUBLISHED) self.assertEqual(job_scheduled_in_the_future.status, models.Job.SCHEDULED) self.assertEqual(job_cancelled.status, models.Job.CANCELED) self.assertEqual(job_completed.status, models.Job.COMPLETED) self.assertEqual(job_impression_limit_reached.status, models.Job.COMPLETED) self.assertEqual(job_click_limit_reached.status, models.Job.COMPLETED) self.assertEqual(job_block_limit_reached.status, models.Job.COMPLETED) self.assertEqual(job_impression_limit_not_reached.status, models.Job.PUBLISHED) self.assertEqual(job_click_limit_not_reached.status, models.Job.PUBLISHED) self.assertEqual(job_block_limit_not_reached.status, models.Job.PUBLISHED) self.assertEqual(job_impression_limit_not_reached_but_no_data.status, models.Job.COMPLETED) self.assertEqual(job_click_limit_not_reached_but_no_data.status, models.Job.COMPLETED) self.assertEqual(job_block_limit_not_reached_but_no_data.status, models.Job.COMPLETED) self.assertEqual(job_block_limit_not_reached_just_created.status, models.Job.PUBLISHED)
def test_generation(self): target = TargetFactory(on_release=True, on_beta=True, on_nightly=False, on_esr=False, on_aurora=False) # Draft, completed, scheduled or cancelled JobFactory( status=models.Job.DRAFT, snippet__locale=',en,', targets=[target], ) JobFactory( status=models.Job.COMPLETED, snippet__locale=',en,', targets=[target], ) JobFactory( status=models.Job.SCHEDULED, snippet__locale=',en,', targets=[target], ) JobFactory( status=models.Job.CANCELED, snippet__locale=',en,', targets=[target], ) JobFactory( status=models.Job.PUBLISHED, snippet__locale=',en,', targets=[target], distribution__name='not-default', ) # Jobs to be included in the bundle published_job_1 = JobFactory( status=models.Job.PUBLISHED, snippet__locale=',en,', targets=[target], ) published_job_2 = JobFactory( status=models.Job.PUBLISHED, snippet__locale=',en,', targets=[target], distribution__name='other-distribution-part-of-default-bundle', ) # Add Distribution to the Default DistributionBundle models.DistributionBundle.objects.get( name='Default').distributions.add( models.Distribution.objects.get( name='other-distribution-part-of-default-bundle')) with patch.multiple( 'snippets.base.management.commands.generate_bundles', json=DEFAULT, product_details=DEFAULT, default_storage=DEFAULT) as mock: mock['json'].dumps.return_value = '' mock['product_details'].languages.keys.return_value = [ 'fr', 'en-us', 'en-au' ] call_command('generate_bundles', stdout=Mock()) self.assertEqual(mock['default_storage'].save.call_count, 4) mock['default_storage'].save.assert_has_calls([ call('pregen/Firefox/release/en-us/default.json', ANY), call('pregen/Firefox/release/en-au/default.json', ANY), call('pregen/Firefox/beta/en-us/default.json', ANY), call('pregen/Firefox/beta/en-au/default.json', ANY), ], any_order=True) # Check that there's only one job included in the bundle and that it's # the correct one. self.assertEqual( len(mock['json'].dumps.call_args_list[0][0][0]['messages']), 2) self.assertEqual( set([ mock['json'].dumps.call_args_list[0][0][0]['messages'][0] ['id'], mock['json'].dumps.call_args_list[0][0][0]['messages'][1]['id'] ]), set([str(published_job_1.id), str(published_job_2.id)]))
def test_base(self): job_running = JobFactory( status=models.Job.PUBLISHED, publish_start='2050-01-05 01:00', publish_end='2050-01-08 02:00', limit_impressions=1000, ) # Without end date job_running2 = JobFactory( status=models.Job.PUBLISHED, publish_start='2050-01-04 01:00', publish_end=None, limit_blocks=1000, ) request_data_first = { 'start_date': '2050-01-05', 'end_date': '2050-01-06', 'message_id': job_running.id, } request_data_second = { 'start_date': '2050-01-04', 'end_date': '2050-01-06', 'message_id': job_running2.id, } return_data_first = { 'query_result': { 'data': { 'rows': [{ 'event': 'IMPRESSION', 'counts': 100, }, { 'event': 'BLOCK', 'counts': 10, }, { 'event': 'CLICK', 'counts': 50, }, { 'event': 'CLICK_BUTTON', 'counts': 60, }] } } } return_data_second = { 'query_result': { 'data': { 'rows': [{ 'event': 'IMPRESSION', 'counts': 250, }, { 'event': 'BLOCK', 'counts': 100, }, { 'event': 'CLICK', 'counts': 25, }, { 'event': 'CLICK_BUTTON', 'counts': 10, }] } } } with patch( 'snippets.base.management.commands.fetch_metrics.RedashDynamicQuery' ) as rdq: with patch( 'snippets.base.management.commands.fetch_metrics.datetime', wraps=datetime) as datetime_mock: # noqa datetime_mock.utcnow.return_value = datetime(2050, 1, 6) rdq.return_value.query.side_effect = [ return_data_first, return_data_second ] call_command('fetch_metrics', stdout=Mock()) rdq.return_value.query.assert_has_calls([ call(settings.REDASH_JOB_QUERY_BIGQUERY_ID, request_data_first), call(settings.REDASH_JOB_QUERY_BIGQUERY_ID, request_data_second), ]) job_running.refresh_from_db() self.assertEqual(job_running.metric_impressions, 100) self.assertEqual(job_running.metric_blocks, 10) self.assertEqual(job_running.metric_clicks, 110) job_running2.refresh_from_db() self.assertEqual(job_running2.metric_impressions, 250) self.assertEqual(job_running2.metric_blocks, 100) self.assertEqual(job_running2.metric_clicks, 35)
def test_base(self): JobFactory.create_batch(2) client = Client() response = client.get(reverse('ical-feed'), follow=True) self.assertEqual(response.status_code, 200)
def setUp(self): self.job1, self.job2 = JobFactory.create_batch(2)