示例#1
0
 def test_match_client_match_locale(self):
     params = {}
     snippet = ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['en-US'])
     ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['fr'])
     self._assert_client_matches_snippets(params, [snippet])
示例#2
0
    def test_job(self):
        nightly_snippets = JobFactory.create_batch(
            2, targets=[TargetFactory(on_release=False, on_nightly=True)])
        JobFactory.create_batch(2, targets=[TargetFactory(on_release=False, on_beta=True)])

        filtr = ChannelFilter(None, {'channel': 'on_nightly'}, Job, JobAdmin)
        result = filtr.queryset(None, Job.objects.all())

        self.assertTrue(result.count(), 2)
        self.assertEqual(set(result.all()), set(nightly_snippets))
    def test_save(self):
        data = self.data.copy()
        instance = TargetFactory()
        form = TargetAdminForm(data, instance=instance)

        self.assertTrue(form.is_valid())
        form.save()
        instance.refresh_from_db()
        self.assertEqual(instance.jexl_expr, 'isDefaultBrowser == true')
        self.assertTrue(instance.filtr_is_default_browser)
示例#4
0
    def test_save(self):
        data = self.data.copy()
        instance = TargetFactory()
        form = TargetAdminForm(data, instance=instance)

        self.assertTrue(form.is_valid())
        form.save()
        instance.refresh_from_db()
        self.assertEqual(instance.jexl_expr, 'isDefaultBrowser == true')
        self.assertTrue(instance.filtr_is_default_browser)
示例#5
0
    def test_nightly_includes_release(self):
        release_job = JobFactory(status=models.Job.PUBLISHED,
                                 snippet__locale=',en,',
                                 targets=[
                                     TargetFactory(on_release=True,
                                                   on_beta=True,
                                                   on_nightly=False,
                                                   on_esr=False,
                                                   on_aurora=False)
                                 ])
        nightly_job = JobFactory(status=models.Job.PUBLISHED,
                                 snippet__locale=',en,',
                                 targets=[
                                     TargetFactory(on_release=True,
                                                   on_beta=False,
                                                   on_nightly=True,
                                                   on_esr=False,
                                                   on_aurora=False)
                                 ])

        # Beta only job, not to be included
        JobFactory(status=models.Job.PUBLISHED,
                   snippet__locale=',en,',
                   targets=[
                       TargetFactory(on_release=False,
                                     on_beta=True,
                                     on_nightly=False,
                                     on_esr=False,
                                     on_aurora=False)
                   ])

        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 = ['en-us']
            call_command('generate_bundles', stdout=Mock())

        # Loop to find the nighlty bundle
        for arg_list in mock['json'].dumps.call_args_list:
            if arg_list[0][0]['metadata']['channel'] == 'nightly':
                self.assertEqual(len(arg_list[0][0]['messages']), 2)
                self.assertEqual(
                    set([
                        arg_list[0][0]['messages'][0]['id'],
                        arg_list[0][0]['messages'][1]['id']
                    ]), set([str(release_job.id),
                             str(nightly_job.id)]))
                self.assertEqual(
                    set([
                        arg_list[0][0]['messages'][0]['targeting'],
                        arg_list[0][0]['messages'][1]['targeting']
                    ]), set(['', 'false']))
示例#6
0
    def test_modified_date_updates_when_target_updates(self):
        new_target = TargetFactory()
        snippet = ASRSnippetFactory()
        snippet.targets.add(new_target)
        old_modified = snippet.modified

        new_target.name = 'new name'
        new_target.save()
        snippet.refresh_from_db()
        new_modified = snippet.modified

        self.assertNotEqual(old_modified, new_modified)
    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']))
示例#8
0
 def test_match_client_invalid_locale(self):
     """
     If client sends invalid locale return snippets with no locales
     specified.
     """
     params = {'locale': 'foo'}
     snippet = ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=[])
     ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['en-us'])
     self._assert_client_matches_snippets(params, [snippet])
示例#9
0
 def test_match_client_match_channel_partially(self):
     """
     Client channels like "release-cck-mozilla14" should match
     "release".
     """
     params = {'channel': 'release-cck-mozilla14'}
     snippet = ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['en-US'])
     ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=False, on_startpage_6=True)],
         locales=['en-US'])
     self._assert_client_matches_snippets(params, [snippet])
示例#10
0
 def test_match_client_multiple_locales(self):
     """
     If there are multiple locales that should match the client's
     locale, include all of them.
     """
     params = {'locale': 'es-mx'}
     snippet_1 = ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['es'])
     snippet_2 = ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['es-mx'])
     self._assert_client_matches_snippets(params, [snippet_1, snippet_2])
示例#11
0
    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)
示例#12
0
    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)
示例#13
0
    def test_default_is_same_as_nightly(self):
        """ Make sure that default channel follows nightly. """
        # Snippets matching nightly (and therefor should match default).
        nightly_snippet = ASRSnippetFactory.create(targets=[TargetFactory(on_nightly=True)])

        # Snippets that don't match nightly
        ASRSnippetFactory.create(targets=[TargetFactory(on_beta=True)])

        nightly_client = self._build_client(channel='nightly')
        nightly_snippets = ASRSnippet.objects.match_client(nightly_client)

        default_client = self._build_client(channel='default')
        default_snippets = ASRSnippet.objects.match_client(default_client)

        # Assert that both the snippets returned from nightly and from default
        # are the same snippets. Just `nightly_snippet` in this case.
        self.assertEqual(set([nightly_snippet]), set(nightly_snippets))
        self.assertEqual(set([nightly_snippet]), set(default_snippets))
示例#14
0
 def test_match_client_multiple_locales_distinct(self):
     """
     If a snippet has multiple locales and a client matches more
     than one of them, the snippet should only be included in the
     queryset once.
     """
     params = {'locale': 'es-mx'}
     snippet = ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['es', 'es-mx'])
     self._assert_client_matches_snippets(params, [snippet])
示例#15
0
 def test_render(self):
     snippet = ASRSnippetFactory.create(
         template_relation__text=(
             'snippet id [[snippet_id]] and with '
             '<a href="https://example.com/[[snippet_id]]/foo">link</a>'),
         targets=[
             TargetFactory(jexl_expr='foo == bar'),
             TargetFactory(jexl_expr='lalo == true')
         ])
     self.maxDiff = None
     generated_result = snippet.render()
     expected_result = {
         'id': str(snippet.id),
         'template': snippet.template_ng.code_name,
         'template_version': snippet.template_ng.version,
         'campaign': snippet.campaign.slug,
         'weight': snippet.weight,
         'content': {
             'text':
             'snippet id {} and with <link0>link</link0>'.format(
                 snippet.id),
             'links': {
                 'link0': {
                     'url': 'https://example.com/{}/foo'.format(snippet.id),
                 }
             },
             'tall':
             False,
             'icon':
             snippet.template_ng.icon.url,
             'do_not_autoblock':
             False,
             'block_button_text':
             'Remove this',
         },
         'targeting': 'foo == bar && lalo == true'
     }
     self.assertEqual(generated_result, expected_result)
示例#16
0
 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')
示例#17
0
 def test_render_preview_only(self):
     snippet = ASRSnippetFactory.create(
         template_relation__text='snippet id [[snippet_id]]',
         targets=[TargetFactory(jexl_expr='foo == bar')])
     generated_result = snippet.render(preview=True)
     expected_result = {
         'id': 'preview-{}'.format(snippet.id),
         'template': snippet.template_ng.code_name,
         'template_version': snippet.template_ng.version,
         'campaign': 'preview-{}'.format(snippet.campaign.slug),
         'weight': 100,
         'content': {
             'do_not_autoblock': True,
             'text': 'snippet id {}'.format(snippet.id),
             'links': {},
             'tall': False,
             'icon': snippet.template_ng.icon.url,
             'block_button_text': 'Remove this',
         }
     }
     self.assertEqual(generated_result, expected_result)
示例#18
0
    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()
示例#19
0
    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()
示例#20
0
    def test_match_client_base(self):
        client_match_rule_pass_1 = ClientMatchRuleFactory(channel='nightly')
        client_match_rule_pass_2 = ClientMatchRuleFactory(channel='/(beta|nightly)/')
        client_match_rule_fail = ClientMatchRuleFactory(channel='release')

        # Matching snippets.
        snippet_1 = ASRSnippetFactory.create(
            targets=[
                TargetFactory(on_release=False, on_nightly=True,
                              client_match_rules=[client_match_rule_pass_1])
            ])
        snippet_2 = ASRSnippetFactory.create(
            targets=[
                TargetFactory(on_release=False, on_beta=True, on_nightly=True,
                              client_match_rules=[client_match_rule_pass_2])
            ])
        snippet_3 = ASRSnippetFactory.create(
            targets=[TargetFactory(on_release=False, on_nightly=True)])

        # Not matching snippets.
        ASRSnippetFactory.create(targets=[TargetFactory(on_release=False, on_beta=True)])

        ASRSnippetFactory.create(
            targets=[
                TargetFactory(on_nightly=True, client_match_rules=[client_match_rule_fail])
            ])
        ASRSnippetFactory.create(
            targets=[
                TargetFactory(on_nightly=True,
                              client_match_rules=[client_match_rule_fail, client_match_rule_pass_2])
            ])
        client = self._build_client(channel='nightly')

        snippets = ASRSnippet.objects.match_client(client)

        self.assertEqual(set(snippets), set([snippet_1, snippet_2, snippet_3]))
示例#21
0
 def test_is_custom(self):
     target = TargetFactory(on_release=True)
     self.assertTrue(target.is_custom)
     not_custom_target = TargetFactory(on_release=True,
                                       filtr_is_default_browser='true')
     self.assertFalse(not_custom_target.is_custom)
示例#22
0
 def test_match_client_not_matching_startpage(self):
     params = {'startpage_version': '0'}
     snippet = ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=['en-US'])
     self._assert_client_matches_snippets(params, [snippet])
示例#23
0
 def test_match_client_not_matching_locale(self):
     params = {'locale': 'en-US'}
     ASRSnippetFactory.create(
         targets=[TargetFactory(on_release=True, on_startpage_6=True)],
         locales=[])
     self._assert_client_matches_snippets(params, [])
示例#24
0
    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)]))
示例#25
0
 def test_set_initial_jexl(self):
     data = self.data.copy()
     instance = TargetFactory(jexl={'filtr_is_default_browser': 'false'})
     form = TargetAdminForm(data, instance=instance)
     self.assertEqual(form.fields['filtr_is_default_browser'].initial,
                      'false')
示例#26
0
    def test_publish_permission_check_asr(self):
        user = User.objects.create_user(username='******',
                                        email='*****@*****.**',
                                        password='******')

        perm_beta = Permission.objects.get(codename='publish_on_beta',
                                           content_type__model='asrsnippet')
        user.user_permissions.add(perm_beta)

        perm_nightly = Permission.objects.get(codename='publish_on_nightly',
                                              content_type__model='asrsnippet')
        user.user_permissions.add(perm_nightly)

        target_release = TargetFactory(on_release=True,
                                       on_beta=False,
                                       on_esr=False,
                                       on_nightly=False,
                                       on_aurora=False)

        target_beta = TargetFactory(on_release=False,
                                    on_beta=True,
                                    on_esr=False,
                                    on_nightly=False,
                                    on_aurora=False)

        target_nightly = TargetFactory(on_release=False,
                                       on_beta=False,
                                       on_esr=False,
                                       on_nightly=True,
                                       on_aurora=False)

        asrsnippet = ASRSnippetFactory(targets=[])

        data = {
            'name': 'Test',
            'weight': 100,
        }

        # User should get an error trying to publish on Release
        new_data = data.copy()
        new_data['status'] = STATUS_CHOICES['Published']
        new_data['targets'] = [target_release]
        form = ASRSnippetAdminForm(new_data, instance=asrsnippet)
        form.current_user = user
        self.assertFalse(form.is_valid())
        self.assertTrue(
            'You are not allowed to edit or publish on Release channel.' in
            form.errors['__all__'][0])

        # User should get an error trying to edit or publish on Release even though Beta
        # is selected too.
        new_data = data.copy()
        new_data['status'] = STATUS_CHOICES['Published']
        new_data['targets'] = [target_release, target_beta]
        form = ASRSnippetAdminForm(new_data, instance=asrsnippet)
        form.current_user = user

        self.assertFalse(form.is_valid())
        self.assertTrue(
            'You are not allowed to edit or publish on Release channel.' in
            form.errors['__all__'][0])

        # Form is valid if user tries to edit or publish on Beta.
        new_data = data.copy()
        new_data['status'] = STATUS_CHOICES['Published']
        new_data['targets'] = [target_beta]
        form = ASRSnippetAdminForm(new_data, instance=asrsnippet)
        form.current_user = user
        self.assertTrue(form.is_valid())

        # Form is valid if user tries to publish or edit on Beta and Nightly.
        new_data = data.copy()
        new_data['status'] = STATUS_CHOICES['Published']
        new_data['targets'] = [target_beta, target_nightly]
        form = ASRSnippetAdminForm(new_data, instance=asrsnippet)
        form.current_user = user
        self.assertTrue(form.is_valid())

        # Form is invalid if user tries edit published Snippet on Release.
        instance = ASRSnippetFactory.create(
            status=STATUS_CHOICES['Published'],
            targets=[TargetFactory(on_release=True)])
        new_data = data.copy()
        new_data['targets'] = [target_release, target_beta, target_nightly]
        form = ASRSnippetAdminForm(new_data, instance=instance)
        form.current_user = user
        self.assertFalse(form.is_valid())
        self.assertTrue(
            'You are not allowed to edit or publish on Release channel.' in
            form.errors['__all__'][0])

        # User cannot unset Release channel and save.
        instance = ASRSnippetFactory.create(
            status=STATUS_CHOICES['Published'],
            targets=[TargetFactory(on_release=True)])
        new_data = data.copy()
        new_data['targets'] = [target_beta, target_nightly]
        form = ASRSnippetAdminForm(new_data, instance=instance)
        form.current_user = user
        self.assertFalse(form.is_valid())
        self.assertTrue(
            'You are not allowed to edit or publish on Release channel.' in
            form.errors['__all__'][0])

        # User can un-publish if they have permission on all channels.
        instance = ASRSnippetFactory.create(status=STATUS_CHOICES['Published'],
                                            targets=[
                                                TargetFactory(on_release=False,
                                                              on_beta=True,
                                                              on_nightly=True)
                                            ])
        new_data = data.copy()
        new_data['status'] = STATUS_CHOICES['Approved']
        new_data['targets'] = [target_beta, target_nightly]
        form = ASRSnippetAdminForm(new_data, instance=instance)
        form.current_user = user
        self.assertTrue(form.is_valid())

        # User cannot un-publish if they don't have permission on all channels.
        instance = ASRSnippetFactory.create(
            status=STATUS_CHOICES['Published'],
            targets=[TargetFactory(on_release=True, on_nightly=True)])
        new_data = data.copy()
        new_data['status'] = STATUS_CHOICES['Approved']
        new_data['targets'] = [target_release, target_nightly]
        form = ASRSnippetAdminForm(new_data, instance=instance)
        form.current_user = user
        self.assertFalse(form.is_valid())
        self.assertTrue(
            'You are not allowed to edit or publish on Release channel.' in
            form.errors['__all__'][0])