def post(self, **kw):
     self.form = ThemeForm(self.get_dict(**kw), request=self.request)
     return self.form
class TestThemeForm(TestCase):
    fixtures = ['base/user_2519']

    def setUp(self):
        super(TestThemeForm, self).setUp()
        self.populate()
        self.request = mock.Mock()
        self.request.user = mock.Mock()
        self.request.user.groups_list = []
        self.request.user.is_authenticated.return_value = True

    def populate(self):
        self.cat = Category.objects.create(application=amo.FIREFOX.id,
                                           type=amo.ADDON_PERSONA,
                                           db_name='xxxx')
        License.objects.create(id=amo.LICENSE_CC_BY.id)

    def get_dict(self, **kw):
        data = {
            'name': 'new name',
            'slug': 'special-slug',
            'category': self.cat.id,
            'accentcolor': '#003366',
            'textcolor': '#C0FFEE',
            'description': 'new description',
            'tags': 'tag1, tag2, tag3',
            'license': amo.LICENSE_CC_BY.id,
            'agreed': True,
            'header_hash': 'b4ll1n'
        }
        data.update(**kw)
        return data

    def post(self, **kw):
        self.form = ThemeForm(self.get_dict(**kw), request=self.request)
        return self.form

    def test_name_required(self):
        self.post(name='')
        assert not self.form.is_valid()
        assert self.form.errors == {'name': ['This field is required.']}

    def test_name_length(self):
        self.post(name='a' * 51)
        assert not self.form.is_valid()
        assert self.form.errors == {
            'name':
            ['Ensure this value has at most '
             '50 characters (it has 51).']
        }

    def test_slug_unique(self):
        # A theme cannot share the same slug as another theme's.
        Addon.objects.create(type=amo.ADDON_PERSONA, slug='harry-potter')
        for slug in ('Harry-Potter', '  harry-potter  ', 'harry-potter'):
            self.post(slug=slug)
            assert not self.form.is_valid()
            assert self.form.errors == {
                'slug':
                ['This slug is already in use. '
                 'Please choose another.']
            }

    def test_slug_required(self):
        self.post(slug='')
        assert not self.form.is_valid()
        assert self.form.errors == {'slug': ['This field is required.']}

    def test_slug_length(self):
        self.post(slug='a' * 31)
        assert not self.form.is_valid()
        assert self.form.errors == {
            'slug':
            ['Ensure this value has at most 30 characters '
             '(it has 31).']
        }

    def test_description_optional(self):
        self.post(description='')
        assert self.form.is_valid()

    def test_description_length(self):
        self.post(description='a' * 501)
        assert not self.form.is_valid()
        assert self.form.errors == ({
            'description':
            ['Ensure this value has at most '
             '500 characters (it has 501).']
        })

    def test_categories_required(self):
        self.post(category='')
        assert not self.form.is_valid()
        assert self.form.errors == {'category': ['This field is required.']}

    def test_license_required(self):
        self.post(license='')
        assert not self.form.is_valid()
        assert self.form.errors == {'license': ['A license must be selected.']}

    def test_header_hash_required(self):
        self.post(header_hash='')
        assert not self.form.is_valid()
        assert self.form.errors == {'header_hash': ['This field is required.']}

    def test_accentcolor_optional(self):
        self.post(accentcolor='')
        assert self.form.is_valid()

    def test_accentcolor_invalid(self):
        self.post(accentcolor='#BALLIN')
        assert not self.form.is_valid()
        assert self.form.errors == ({
            'accentcolor':
            ['This must be a valid hex color code, '
             'such as #000000.']
        })

    def test_textcolor_optional(self):
        self.post(textcolor='')
        assert self.form.is_valid(), self.form.errors

    def test_textcolor_invalid(self):
        self.post(textcolor='#BALLIN')
        assert not self.form.is_valid()
        assert self.form.errors == ({
            'textcolor':
            ['This must be a valid hex color code, '
             'such as #000000.']
        })

    def get_img_urls(self):
        return reverse('devhub.personas.upload_persona',
                       args=['persona_header'])

    def test_img_attrs(self):
        header_url = self.get_img_urls()

        self.post()
        assert self.form.fields['header'].widget.attrs == ({
            'data-allowed-types':
            amo.SUPPORTED_IMAGE_TYPES,
            'data-upload-url':
            header_url
        })

    @mock.patch('olympia.addons.tasks.make_checksum')
    @mock.patch('olympia.addons.tasks.create_persona_preview_images')
    @mock.patch('olympia.addons.tasks.save_persona_image')
    @pytest.mark.skipif(not hasattr(Image.core, 'jpeg_encoder'),
                        reason='Not having a jpeg encoder makes test sad')
    def test_success(self, save_persona_image_mock,
                     create_persona_preview_images_mock, make_checksum_mock):
        make_checksum_mock.return_value = 'hashyourselfbeforeyoucrashyourself'

        self.request.user = UserProfile.objects.get(pk=2519)

        data = self.get_dict()
        header_url = self.get_img_urls()

        # Upload header image.
        img = open(get_image_path('persona-header.jpg'), 'rb')
        r_ajax = self.client.post(header_url, {'upload_image': img})
        data.update(header_hash=json.loads(r_ajax.content)['upload_hash'])

        # Populate and save form.
        self.post()
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        addon = Addon.objects.filter(type=amo.ADDON_PERSONA).order_by('-id')[0]
        persona = addon.persona

        # Test for correct Addon and Persona values.
        assert unicode(addon.name) == data['name']
        assert addon.slug == data['slug']
        self.assertSetEqual(set(addon.categories.values_list('id', flat=True)),
                            {self.cat.id})
        self.assertSetEqual(set(addon.tags.values_list('tag_text', flat=True)),
                            set(data['tags'].split(', ')))
        assert persona.persona_id == 0
        assert persona.license == data['license']
        assert persona.accentcolor == data['accentcolor'].lstrip('#')
        assert persona.textcolor == data['textcolor'].lstrip('#')
        assert persona.author == self.request.user.username
        assert persona.display_username == self.request.user.name
        assert not persona.dupe_persona

        v = addon.versions.all()
        assert len(v) == 1
        assert v[0].version == '0'

        # Test for header and preview images.
        dst = os.path.join(user_media_path('addons'), str(addon.id))

        header_src = os.path.join(settings.TMP_PATH, 'persona_header',
                                  u'b4ll1n')

        assert save_persona_image_mock.mock_calls == ([
            mock.call(src=header_src, full_dst=os.path.join(dst, 'header.png'))
        ])

        create_persona_preview_images_mock.assert_called_with(
            src=header_src,
            full_dst=[
                os.path.join(dst, 'preview.png'),
                os.path.join(dst, 'icon.png')
            ],
            set_modified_on=addon.serializable_reference())

    @mock.patch('olympia.addons.tasks.create_persona_preview_images')
    @mock.patch('olympia.addons.tasks.save_persona_image')
    @mock.patch('olympia.addons.tasks.make_checksum')
    def test_dupe_persona(self, make_checksum_mock, mock1, mock2):
        """
        Submitting persona with checksum already in db should be marked
        duplicate.
        """
        make_checksum_mock.return_value = 'cornhash'

        self.request.user = UserProfile.objects.get(pk=2519)

        self.post()
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        self.post(name='whatsinaname', slug='metalslug')
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        personas = Persona.objects.order_by('addon__name')
        assert personas[0].checksum == personas[1].checksum
        assert personas[1].dupe_persona == personas[0]
        assert personas[0].dupe_persona is None
Esempio n. 3
0
class TestThemeForm(TestCase):
    fixtures = ['base/user_2519']

    def setUp(self):
        super(TestThemeForm, self).setUp()
        self.populate()
        self.request = mock.Mock()
        self.request.user = mock.Mock()
        self.request.user.groups_list = []
        self.request.user.is_authenticated.return_value = True

    def populate(self):
        self.cat = Category.objects.create(application=amo.FIREFOX.id,
                                           type=amo.ADDON_PERSONA, name='xxxx')
        License.objects.create(id=amo.LICENSE_CC_BY.id)

    def get_dict(self, **kw):
        data = {
            'name': 'new name',
            'slug': 'special-slug',
            'category': self.cat.id,
            'accentcolor': '#003366',
            'textcolor': '#C0FFEE',
            'description': 'new description',
            'tags': 'tag1, tag2, tag3',
            'license': amo.LICENSE_CC_BY.id,
            'agreed': True,
            'header_hash': 'b4ll1n',
            'footer_hash': '5w4g'
        }
        data.update(**kw)
        return data

    def post(self, **kw):
        self.form = ThemeForm(self.get_dict(**kw), request=self.request)
        return self.form

    def test_name_required(self):
        self.post(name='')
        assert not self.form.is_valid()
        assert self.form.errors == {'name': ['This field is required.']}

    def test_name_length(self):
        self.post(name='a' * 51)
        assert not self.form.is_valid()
        assert self.form.errors == {
            'name': ['Ensure this value has at most '
                     '50 characters (it has 51).']}

    def test_slug_unique(self):
        # A theme cannot share the same slug as another theme's.
        Addon.objects.create(type=amo.ADDON_PERSONA, slug='harry-potter')
        for slug in ('Harry-Potter', '  harry-potter  ', 'harry-potter'):
            self.post(slug=slug)
            assert not self.form.is_valid()
            assert self.form.errors == {
                'slug': ['This slug is already in use. '
                         'Please choose another.']}

    def test_slug_required(self):
        self.post(slug='')
        assert not self.form.is_valid()
        assert self.form.errors == {'slug': ['This field is required.']}

    def test_slug_length(self):
        self.post(slug='a' * 31)
        assert not self.form.is_valid()
        assert self.form.errors == {
            'slug': ['Ensure this value has at most 30 characters '
                     '(it has 31).']}

    def test_description_optional(self):
        self.post(description='')
        assert self.form.is_valid()

    def test_description_length(self):
        self.post(description='a' * 501)
        assert not self.form.is_valid()
        assert self.form.errors == (
            {'description': ['Ensure this value has at most '
                             '500 characters (it has 501).']})

    def test_categories_required(self):
        self.post(category='')
        assert not self.form.is_valid()
        assert self.form.errors == {'category': ['This field is required.']}

    def test_license_required(self):
        self.post(license='')
        assert not self.form.is_valid()
        assert self.form.errors == {'license': ['A license must be selected.']}

    def test_header_hash_required(self):
        self.post(header_hash='')
        assert not self.form.is_valid()
        assert self.form.errors == {'header_hash': ['This field is required.']}

    def test_footer_hash_optional(self):
        self.post(footer_hash='')
        assert self.form.is_valid()

    def test_accentcolor_optional(self):
        self.post(accentcolor='')
        assert self.form.is_valid()

    def test_accentcolor_invalid(self):
        self.post(accentcolor='#BALLIN')
        assert not self.form.is_valid()
        assert self.form.errors == (
            {'accentcolor': ['This must be a valid hex color code, '
                             'such as #000000.']})

    def test_textcolor_optional(self):
        self.post(textcolor='')
        assert self.form.is_valid(), self.form.errors

    def test_textcolor_invalid(self):
        self.post(textcolor='#BALLIN')
        assert not self.form.is_valid()
        assert self.form.errors == (
            {'textcolor': ['This must be a valid hex color code, '
                           'such as #000000.']})

    def get_img_urls(self):
        return (
            reverse('devhub.personas.upload_persona', args=['persona_header']),
            reverse('devhub.personas.upload_persona', args=['persona_footer'])
        )

    def test_img_attrs(self):
        header_url, footer_url = self.get_img_urls()

        self.post()
        assert self.form.fields['header'].widget.attrs == (
            {'data-allowed-types': 'image/jpeg|image/png',
             'data-upload-url': header_url})
        assert self.form.fields['footer'].widget.attrs == (
            {'data-allowed-types': 'image/jpeg|image/png',
             'data-upload-url': footer_url})

    @mock.patch('olympia.addons.tasks.make_checksum')
    @mock.patch('olympia.addons.tasks.create_persona_preview_images')
    @mock.patch('olympia.addons.tasks.save_persona_image')
    @pytest.mark.skipif(not hasattr(Image.core, 'jpeg_encoder'),
                        reason='Not having a jpeg encoder makes test sad')
    def test_success(self, save_persona_image_mock,
                     create_persona_preview_images_mock, make_checksum_mock):
        make_checksum_mock.return_value = 'hashyourselfbeforeyoucrashyourself'

        self.request.user = UserProfile.objects.get(pk=2519)

        data = self.get_dict()
        header_url, footer_url = self.get_img_urls()

        # Upload header image.
        img = open(get_image_path('persona-header.jpg'), 'rb')
        r_ajax = self.client.post(header_url, {'upload_image': img})
        data.update(header_hash=json.loads(r_ajax.content)['upload_hash'])

        # Upload footer image.
        img = open(get_image_path('persona-footer.jpg'), 'rb')
        r_ajax = self.client.post(footer_url, {'upload_image': img})
        data.update(footer_hash=json.loads(r_ajax.content)['upload_hash'])

        # Populate and save form.
        self.post()
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        addon = Addon.objects.filter(type=amo.ADDON_PERSONA).order_by('-id')[0]
        persona = addon.persona

        # Test for correct Addon and Persona values.
        assert unicode(addon.name) == data['name']
        assert addon.slug == data['slug']
        self.assertSetEqual(set(addon.categories.values_list('id', flat=True)),
                            {self.cat.id})
        self.assertSetEqual(set(addon.tags.values_list('tag_text', flat=True)),
                            set(data['tags'].split(', ')))
        assert persona.persona_id == 0
        assert persona.license == data['license']
        assert persona.accentcolor == data['accentcolor'].lstrip('#')
        assert persona.textcolor == data['textcolor'].lstrip('#')
        assert persona.author == self.request.user.username
        assert persona.display_username == self.request.user.name
        assert not persona.dupe_persona

        v = addon.versions.all()
        assert len(v) == 1
        assert v[0].version == '0'

        # Test for header, footer, and preview images.
        dst = os.path.join(user_media_path('addons'), str(addon.id))

        header_src = os.path.join(settings.TMP_PATH, 'persona_header',
                                  u'b4ll1n')
        footer_src = os.path.join(settings.TMP_PATH, 'persona_footer',
                                  u'5w4g')

        assert save_persona_image_mock.mock_calls == (
            [mock.call(src=header_src,
                       full_dst=os.path.join(dst, 'header.png')),
             mock.call(src=footer_src,
                       full_dst=os.path.join(dst, 'footer.png'))])

        create_persona_preview_images_mock.assert_called_with(
            src=header_src,
            full_dst=[os.path.join(dst, 'preview.png'),
                      os.path.join(dst, 'icon.png')],
            set_modified_on=[addon])

    @mock.patch('olympia.addons.tasks.create_persona_preview_images')
    @mock.patch('olympia.addons.tasks.save_persona_image')
    @mock.patch('olympia.addons.tasks.make_checksum')
    def test_dupe_persona(self, make_checksum_mock, mock1, mock2):
        """
        Submitting persona with checksum already in db should be marked
        duplicate.
        """
        make_checksum_mock.return_value = 'cornhash'

        self.request.user = UserProfile.objects.get(pk=2519)

        self.post()
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        self.post(name='whatsinaname', slug='metalslug')
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        personas = Persona.objects.order_by('addon__name')
        assert personas[0].checksum == personas[1].checksum
        assert personas[1].dupe_persona == personas[0]
        assert personas[0].dupe_persona is None
Esempio n. 4
0
 def post(self, **kw):
     self.form = ThemeForm(self.get_dict(**kw), request=self.request)
     return self.form
Esempio n. 5
0
class TestThemeForm(TestCase):
    fixtures = ["base/user_2519"]

    def setUp(self):
        super(TestThemeForm, self).setUp()
        self.populate()
        self.request = mock.Mock()
        self.request.user = mock.Mock()
        self.request.user.groups_list = []
        self.request.user.is_authenticated.return_value = True

    def populate(self):
        self.cat = Category.objects.create(application=amo.FIREFOX.id, type=amo.ADDON_PERSONA, name="xxxx")
        License.objects.create(id=amo.LICENSE_CC_BY.id)

    def get_dict(self, **kw):
        data = {
            "name": "new name",
            "slug": "special-slug",
            "category": self.cat.id,
            "accentcolor": "#003366",
            "textcolor": "#C0FFEE",
            "description": "new description",
            "tags": "tag1, tag2, tag3",
            "license": amo.LICENSE_CC_BY.id,
            "agreed": True,
            "header_hash": "b4ll1n",
            "footer_hash": "5w4g",
        }
        data.update(**kw)
        return data

    def post(self, **kw):
        self.form = ThemeForm(self.get_dict(**kw), request=self.request)
        return self.form

    def test_name_unique(self):
        # A theme cannot share the same name as another theme's.
        Addon.objects.create(type=amo.ADDON_PERSONA, name="harry-potter")
        for name in ("Harry-Potter", "  harry-potter  ", "harry-potter"):
            self.post(name=name)
            assert not self.form.is_valid()
            assert self.form.errors == ({"name": ["This name is already in use. " "Please choose another."]})

    def test_name_required(self):
        self.post(name="")
        assert not self.form.is_valid()
        assert self.form.errors == {"name": ["This field is required."]}

    def test_name_length(self):
        self.post(name="a" * 51)
        assert not self.form.is_valid()
        assert self.form.errors == {"name": ["Ensure this value has at most " "50 characters (it has 51)."]}

    def test_slug_unique(self):
        # A theme cannot share the same slug as another theme's.
        Addon.objects.create(type=amo.ADDON_PERSONA, slug="harry-potter")
        for slug in ("Harry-Potter", "  harry-potter  ", "harry-potter"):
            self.post(slug=slug)
            assert not self.form.is_valid()
            assert self.form.errors == {"slug": ["This slug is already in use. " "Please choose another."]}

    def test_slug_required(self):
        self.post(slug="")
        assert not self.form.is_valid()
        assert self.form.errors == {"slug": ["This field is required."]}

    def test_slug_length(self):
        self.post(slug="a" * 31)
        assert not self.form.is_valid()
        assert self.form.errors == {"slug": ["Ensure this value has at most 30 characters " "(it has 31)."]}

    def test_description_optional(self):
        self.post(description="")
        assert self.form.is_valid()

    def test_description_length(self):
        self.post(description="a" * 501)
        assert not self.form.is_valid()
        assert self.form.errors == ({"description": ["Ensure this value has at most " "500 characters (it has 501)."]})

    def test_categories_required(self):
        self.post(category="")
        assert not self.form.is_valid()
        assert self.form.errors == {"category": ["This field is required."]}

    def test_license_required(self):
        self.post(license="")
        assert not self.form.is_valid()
        assert self.form.errors == {"license": ["A license must be selected."]}

    def test_header_hash_required(self):
        self.post(header_hash="")
        assert not self.form.is_valid()
        assert self.form.errors == {"header_hash": ["This field is required."]}

    def test_footer_hash_optional(self):
        self.post(footer_hash="")
        assert self.form.is_valid()

    def test_accentcolor_optional(self):
        self.post(accentcolor="")
        assert self.form.is_valid()

    def test_accentcolor_invalid(self):
        self.post(accentcolor="#BALLIN")
        assert not self.form.is_valid()
        assert self.form.errors == ({"accentcolor": ["This must be a valid hex color code, " "such as #000000."]})

    def test_textcolor_optional(self):
        self.post(textcolor="")
        assert self.form.is_valid(), self.form.errors

    def test_textcolor_invalid(self):
        self.post(textcolor="#BALLIN")
        assert not self.form.is_valid()
        assert self.form.errors == ({"textcolor": ["This must be a valid hex color code, " "such as #000000."]})

    def get_img_urls(self):
        return (
            reverse("devhub.personas.upload_persona", args=["persona_header"]),
            reverse("devhub.personas.upload_persona", args=["persona_footer"]),
        )

    def test_img_attrs(self):
        header_url, footer_url = self.get_img_urls()

        self.post()
        assert self.form.fields["header"].widget.attrs == (
            {"data-allowed-types": "image/jpeg|image/png", "data-upload-url": header_url}
        )
        assert self.form.fields["footer"].widget.attrs == (
            {"data-allowed-types": "image/jpeg|image/png", "data-upload-url": footer_url}
        )

    @mock.patch("olympia.addons.tasks.make_checksum")
    @mock.patch("olympia.addons.tasks.create_persona_preview_images")
    @mock.patch("olympia.addons.tasks.save_persona_image")
    @pytest.mark.skipif(not hasattr(Image.core, "jpeg_encoder"), reason="Not having a jpeg encoder makes test sad")
    def test_success(self, save_persona_image_mock, create_persona_preview_images_mock, make_checksum_mock):
        make_checksum_mock.return_value = "hashyourselfbeforeyoucrashyourself"

        self.request.user = UserProfile.objects.get(pk=2519)

        data = self.get_dict()
        header_url, footer_url = self.get_img_urls()

        # Upload header image.
        img = open(get_image_path("persona-header.jpg"), "rb")
        r_ajax = self.client.post(header_url, {"upload_image": img})
        data.update(header_hash=json.loads(r_ajax.content)["upload_hash"])

        # Upload footer image.
        img = open(get_image_path("persona-footer.jpg"), "rb")
        r_ajax = self.client.post(footer_url, {"upload_image": img})
        data.update(footer_hash=json.loads(r_ajax.content)["upload_hash"])

        # Populate and save form.
        self.post()
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        addon = Addon.objects.filter(type=amo.ADDON_PERSONA).order_by("-id")[0]
        persona = addon.persona

        # Test for correct Addon and Persona values.
        assert unicode(addon.name) == data["name"]
        assert addon.slug == data["slug"]
        self.assertSetEqual(addon.categories.values_list("id", flat=True), [self.cat.id])
        self.assertSetEqual(addon.tags.values_list("tag_text", flat=True), data["tags"].split(", "))
        assert persona.persona_id == 0
        assert persona.license == data["license"]
        assert persona.accentcolor == data["accentcolor"].lstrip("#")
        assert persona.textcolor == data["textcolor"].lstrip("#")
        assert persona.author == self.request.user.username
        assert persona.display_username == self.request.user.name
        assert not persona.dupe_persona

        v = addon.versions.all()
        assert len(v) == 1
        assert v[0].version == "0"

        # Test for header, footer, and preview images.
        dst = os.path.join(user_media_path("addons"), str(addon.id))

        header_src = os.path.join(settings.TMP_PATH, "persona_header", u"b4ll1n")
        footer_src = os.path.join(settings.TMP_PATH, "persona_footer", u"5w4g")

        assert save_persona_image_mock.mock_calls == (
            [
                mock.call(src=header_src, full_dst=os.path.join(dst, "header.png")),
                mock.call(src=footer_src, full_dst=os.path.join(dst, "footer.png")),
            ]
        )

        create_persona_preview_images_mock.assert_called_with(
            src=header_src,
            full_dst=[os.path.join(dst, "preview.png"), os.path.join(dst, "icon.png")],
            set_modified_on=[addon],
        )

    @mock.patch("olympia.addons.tasks.create_persona_preview_images")
    @mock.patch("olympia.addons.tasks.save_persona_image")
    @mock.patch("olympia.addons.tasks.make_checksum")
    def test_dupe_persona(self, make_checksum_mock, mock1, mock2):
        """
        Submitting persona with checksum already in db should be marked
        duplicate.
        """
        make_checksum_mock.return_value = "cornhash"

        self.request.user = UserProfile.objects.get(pk=2519)

        self.post()
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        self.post(name="whatsinaname", slug="metalslug")
        assert self.form.is_valid(), self.form.errors
        self.form.save()

        personas = Persona.objects.order_by("addon__name")
        assert personas[0].checksum == personas[1].checksum
        assert personas[1].dupe_persona == personas[0]
        assert personas[0].dupe_persona is None