def test_translations(self): translated_descriptions = { 'en-US': u'My Addôn description in english', 'fr': u'Description de mon Addôn', } translated_homepages = { 'en-US': u'http://www.google.com/', 'fr': u'http://www.googlé.fr/', } self.addon = addon_factory() self.addon.description = translated_descriptions self.addon.homepage = translated_homepages self.addon.save() result = self.serialize() assert result['description'] == translated_descriptions assert result['homepage'] != translated_homepages assert result['homepage'] == { 'en-US': get_outgoing_url(translated_homepages['en-US']), 'fr': get_outgoing_url(translated_homepages['fr']) } # Try a single translation. The locale activation is normally done by # LocaleAndAppURLMiddleware, but since we're directly calling the # serializer we need to do it ourselves. self.request = APIRequestFactory().get('/', {'lang': 'fr'}) with override('fr'): result = self.serialize() assert result['description'] == translated_descriptions['fr'] assert result['homepage'] == get_outgoing_url( translated_homepages['fr'])
def to_representation(self, value): data = super().to_representation(value) request = self.context.get('request', None) if request and is_gate_active(request, 'wrap-outgoing-parameter'): if data and 'wrap_outgoing_links' in request.GET: if isinstance(data, str): return get_outgoing_url(data) elif isinstance(data, dict): return { key: get_outgoing_url(value) if value else None for key, value in data.items() } # None or empty string... don't bother. return data if not data: return None if isinstance(data, dict): outgoing = { key: value if key == '_default' else get_outgoing_url(value) if value else None for key, value in data.items() } else: outgoing = get_outgoing_url(str(data)) return {'url': data, 'outgoing': outgoing}
def test_outgoing_url(): redirect_url = settings.REDIRECT_URL secretkey = settings.REDIRECT_SECRET_KEY exceptions = settings.REDIRECT_URL_ALLOW_LIST settings.REDIRECT_URL = 'http://example.net' settings.REDIRECT_SECRET_KEY = 'sekrit' settings.REDIRECT_URL_ALLOW_LIST = ['nicedomain.com'] try: myurl = 'http://example.com' s = urlresolvers.get_outgoing_url(myurl) # Regular URLs must be escaped. assert s == ( 'http://example.net/bc7d4bb262c9f0b0f6d3412ede7d3252c2e311bb1d55f6' '2315f636cb8a70913b/' 'http%3A//example.com') # No double-escaping of outgoing URLs. s2 = urlresolvers.get_outgoing_url(s) assert s == s2 evil = settings.REDIRECT_URL.rstrip('/') + '.evildomain.com' s = urlresolvers.get_outgoing_url(evil) assert s != evil # 'No subdomain abuse of double-escaping protection.' nice = 'http://nicedomain.com/lets/go/go/go' assert nice == urlresolvers.get_outgoing_url(nice) finally: settings.REDIRECT_URL = redirect_url settings.REDIRECT_SECRET_KEY = secretkey settings.REDIRECT_URL_ALLOW_LIST = exceptions
def test_outgoing_url(): redirect_url = settings.REDIRECT_URL secretkey = settings.REDIRECT_SECRET_KEY exceptions = settings.REDIRECT_URL_WHITELIST settings.REDIRECT_URL = "http://example.net" settings.REDIRECT_SECRET_KEY = "sekrit" settings.REDIRECT_URL_WHITELIST = ["nicedomain.com"] try: myurl = "http://example.com" s = urlresolvers.get_outgoing_url(myurl) # Regular URLs must be escaped. eq_( s, "http://example.net/bc7d4bb262c9f0b0f6d3412ede7d3252c2e311bb1d55f6" "2315f636cb8a70913b/" "http%3A//example.com", ) # No double-escaping of outgoing URLs. s2 = urlresolvers.get_outgoing_url(s) eq_(s, s2) evil = settings.REDIRECT_URL.rstrip("/") + ".evildomain.com" s = urlresolvers.get_outgoing_url(evil) assert_not_equal(s, evil, "No subdomain abuse of double-escaping protection.") nice = "http://nicedomain.com/lets/go/go/go" eq_(nice, urlresolvers.get_outgoing_url(nice)) finally: settings.REDIRECT_URL = redirect_url settings.REDIRECT_SECRET_KEY = secretkey settings.REDIRECT_URL_WHITELIST = exceptions
def test_outgoing_url(): redirect_url = settings.REDIRECT_URL secretkey = settings.REDIRECT_SECRET_KEY exceptions = settings.REDIRECT_URL_WHITELIST settings.REDIRECT_URL = 'http://example.net' settings.REDIRECT_SECRET_KEY = 'sekrit' settings.REDIRECT_URL_WHITELIST = ['nicedomain.com'] try: myurl = 'http://example.com' s = urlresolvers.get_outgoing_url(myurl) # Regular URLs must be escaped. assert s == ( 'http://example.net/bc7d4bb262c9f0b0f6d3412ede7d3252c2e311bb1d55f6' '2315f636cb8a70913b/' 'http%3A//example.com') # No double-escaping of outgoing URLs. s2 = urlresolvers.get_outgoing_url(s) assert s == s2 evil = settings.REDIRECT_URL.rstrip('/') + '.evildomain.com' s = urlresolvers.get_outgoing_url(evil) assert s != evil # 'No subdomain abuse of double-escaping protection.' nice = 'http://nicedomain.com/lets/go/go/go' assert nice == urlresolvers.get_outgoing_url(nice) finally: settings.REDIRECT_URL = redirect_url settings.REDIRECT_SECRET_KEY = secretkey settings.REDIRECT_URL_WHITELIST = exceptions
def outgoingify(self, data): if isinstance(data, basestring): return get_outgoing_url(data) elif isinstance(data, dict): return {key: get_outgoing_url(value) if value else None for key, value in data.items()} # Probably None... don't bother. return data
def outgoingify(self, data): if data: if isinstance(data, str): return get_outgoing_url(data) elif isinstance(data, dict): return {key: get_outgoing_url(value) if value else None for key, value in data.items()} # None or empty string... don't bother. return data
def outgoingify(self, data): if data: if isinstance(data, six.string_types): return get_outgoing_url(data) elif isinstance(data, dict): return {key: get_outgoing_url(value) if value else None for key, value in data.items()} # None or empty string... don't bother. return data
def test_outgoing_url_query_params(): url = 'http://xx.com?q=1&v=2' fixed = urlresolvers.get_outgoing_url(url) assert fixed.endswith('http%3A//xx.com%3Fq=1&v=2'), fixed url = 'http://xx.com?q=1&v=2' fixed = urlresolvers.get_outgoing_url(url) assert fixed.endswith('http%3A//xx.com%3Fq=1&v=2'), fixed # Check XSS vectors. url = 'http://xx.com?q=1&v=2" style="123"' fixed = urlresolvers.get_outgoing_url(url) assert fixed.endswith('%3A//xx.com%3Fq=1&v=2%22%20style=%22123%22'), fixed
def test_url_and_addons_collections(self): data = self.serialize(self.collections_shelf) assert data['url'] == self._get_result_url(self.collections_shelf) assert data['addons'][0]['name'] == {'en-US': 'test addon privacy01'} assert data['footer']['url'] == 'https://blog.mozilla.org/addons' assert data['footer']['outgoing'] == get_outgoing_url( 'https://blog.mozilla.org/addons')
def test_external_addon(self): addon = addon_factory( summary='Summary', homepage='https://foo.baa', version_kw={'channel': amo.RELEASE_CHANNEL_UNLISTED}, ) hero = PrimaryHero.objects.create( promoted_addon=PromotedAddon.objects.create(addon=addon), select_image=self.phi, gradient_color='#008787', is_external=True, ) assert PrimaryHeroShelfSerializer(instance=hero).data == { 'featured_image': self.image, 'description': {'en-US': 'Summary'}, 'gradient': {'start': GRADIENT_START_COLOR[1], 'end': 'color-green-70'}, 'external': ExternalAddonSerializer(instance=addon).data, } assert ExternalAddonSerializer(instance=addon).data == { 'id': addon.id, 'guid': addon.guid, 'homepage': { 'url': {'en-US': str(addon.homepage)}, 'outgoing': {'en-US': get_outgoing_url(str(addon.homepage))}, }, 'name': {'en-US': str(addon.name)}, 'type': 'extension', }
def test_url(self): response = self.client.get(self.url) assert response.status_code == 200 assert response.json()['url'] == { 'url': self.block.url, 'outgoing': get_outgoing_url(self.block.url), }
def test_basic(self): hero = SecondaryHero.objects.create( headline='Its a héadline!', description='description' ) data = SecondaryHeroShelfSerializer(instance=hero).data assert data == { 'headline': {'en-US': 'Its a héadline!'}, 'description': {'en-US': 'description'}, 'cta': None, 'modules': [], } hero.update(cta_url='/extensions/', cta_text='Go here') data = SecondaryHeroShelfSerializer(instance=hero).data assert data == { 'headline': {'en-US': 'Its a héadline!'}, 'description': {'en-US': 'description'}, 'cta': { 'url': 'http://testserver/extensions/', 'outgoing': 'http://testserver/extensions/', 'text': {'en-US': 'Go here'}, }, 'modules': [], } hero.update(cta_url='https://goo.gl/stuff/', cta_text='Googl here') data = SecondaryHeroShelfSerializer(instance=hero).data assert data == { 'headline': {'en-US': 'Its a héadline!'}, 'description': {'en-US': 'description'}, 'cta': { 'url': 'https://goo.gl/stuff/', 'outgoing': get_outgoing_url('https://goo.gl/stuff/'), 'text': {'en-US': 'Googl here'}, }, 'modules': [], }
def to_representation(self, obj): data = super().to_representation(obj) if ('request' in self.context and 'wrap_outgoing_links' in self.context['request'].GET and data.get('url')): data['url'] = get_outgoing_url(data['url']) return data
def test_adds_outgoing(self): field = OutgoingURLField() assert field.to_representation('/foo/baa/') == { 'url': '/foo/baa/', 'outgoing': '/', } assert field.to_representation('http://foo/baa/') == { 'url': 'http://foo/baa/', 'outgoing': get_outgoing_url('http://foo/baa/'), }
def test_absolutifys(self): field = AbsoluteOutgoingURLField() assert field.to_representation('/foo/baa/') == { 'url': f'{settings.EXTERNAL_SITE_URL}/foo/baa/', 'outgoing': f'{settings.EXTERNAL_SITE_URL}/foo/baa/', } assert field.to_representation('http://foo/baa/') == { 'url': 'http://foo/baa/', 'outgoing': get_outgoing_url('http://foo/baa/'), }
def get_cta(self, obj): if obj.cta_url and obj.cta_text: url = absolutify(obj.cta_url) should_wrap = ('request' in self.context and 'wrap_outgoing_links' in self.context['request'].GET) return { 'url': get_outgoing_url(url) if should_wrap else url, 'text': ugettext(obj.cta_text), } else: return None
def test_wrap_outgoing_links(self): request = APIRequestFactory().get('/', {'wrap_outgoing_links': 1}) serializer = BlockSerializer(instance=self.block, context={'request': request}) assert serializer.data['url'] == get_outgoing_url(self.block.url) self.block.update(url='') serializer = BlockSerializer(instance=self.block, context={'request': request}) assert serializer.data['url'] == ''
def test_external_url(): redirect_url = settings.REDIRECT_URL secretkey = settings.REDIRECT_SECRET_KEY settings.REDIRECT_URL = 'http://example.net' settings.REDIRECT_SECRET_KEY = 'sekrit' try: myurl = 'http://example.com' s = render('{{ "%s"|external_url }}' % myurl) assert s == urlresolvers.get_outgoing_url(myurl) finally: settings.REDIRECT_URL = redirect_url settings.REDIRECT_SECRET_KEY = secretkey
def test_external_url(): redirect_url = settings.REDIRECT_URL secretkey = settings.REDIRECT_SECRET_KEY settings.REDIRECT_URL = 'http://example.net' settings.REDIRECT_SECRET_KEY = 'sekrit' try: myurl = 'http://example.com' s = render('{{ "%s"|external_url }}' % myurl) eq_(s, urlresolvers.get_outgoing_url(myurl)) finally: settings.REDIRECT_URL = redirect_url settings.REDIRECT_SECRET_KEY = secretkey
def test_with_addons_and_wrap_outgoing_links_and_lang(self): addon = addon_factory(support_url='http://support.example.com', homepage='http://homepage.example.com') self.collection.add_addon(addon) response = self.client.get( self.url + '?with_addons&lang=en-US&wrap_outgoing_links') assert response.status_code == 200 assert response.data['id'] == self.collection.id addon_data = response.data['addons'][0]['addon'] assert addon_data['id'] == addon.id assert isinstance(addon_data['name']['en-US'], str) assert addon_data['name'] == {'en-US': str(addon.name)} assert isinstance(addon_data['homepage']['en-US'], str) assert addon_data['homepage'] == { 'en-US': get_outgoing_url(str(addon.homepage)) } assert isinstance(addon_data['support_url']['en-US'], str) assert addon_data['support_url'] == { 'en-US': get_outgoing_url(str(addon.support_url)) } overridden_api_gates = {'v5': ('l10n_flat_input_output', )} with override_settings(DRF_API_GATES=overridden_api_gates): response = self.client.get( self.url + '?with_addons&lang=en-US&wrap_outgoing_links') assert response.status_code == 200 assert response.data['id'] == self.collection.id addon_data = response.data['addons'][0]['addon'] assert addon_data['id'] == addon.id assert isinstance(addon_data['name'], str) assert addon_data['name'] == str(addon.name) assert isinstance(addon_data['homepage'], str) assert addon_data['homepage'] == get_outgoing_url( str(addon.homepage)) assert isinstance(addon_data['support_url'], str) assert addon_data['support_url'] == get_outgoing_url( str(addon.support_url))
def test_with_addons_and_wrap_outgoing_links_and_lang(self): addon = addon_factory( support_url='http://support.example.com', homepage='http://homepage.example.com') self.collection.add_addon(addon) response = self.client.get( self.url + '?with_addons&lang=en-US&wrap_outgoing_links') assert response.status_code == 200 assert response.data['id'] == self.collection.id addon_data = response.data['addons'][0]['addon'] assert addon_data['id'] == addon.id assert isinstance(addon_data['name']['en-US'], six.string_types) assert addon_data['name'] == {'en-US': six.text_type(addon.name)} assert isinstance(addon_data['homepage']['en-US'], six.string_types) assert addon_data['homepage'] == { 'en-US': get_outgoing_url(six.text_type(addon.homepage))} assert isinstance(addon_data['support_url']['en-US'], six.string_types) assert addon_data['support_url'] == { 'en-US': get_outgoing_url(six.text_type(addon.support_url))} overridden_api_gates = { 'v4dev': ('l10n_flat_input_output',)} with override_settings(DRF_API_GATES=overridden_api_gates): response = self.client.get( self.url + '?with_addons&lang=en-US&wrap_outgoing_links') assert response.status_code == 200 assert response.data['id'] == self.collection.id addon_data = response.data['addons'][0]['addon'] assert addon_data['id'] == addon.id assert isinstance(addon_data['name'], six.string_types) assert addon_data['name'] == six.text_type(addon.name) assert isinstance(addon_data['homepage'], six.string_types) assert addon_data['homepage'] == get_outgoing_url( six.text_type(addon.homepage)) assert isinstance(addon_data['support_url'], six.string_types) assert addon_data['support_url'] == get_outgoing_url( six.text_type(addon.support_url))
def find_replacement_addon(request): guid = request.GET.get('guid') if not guid: raise http.Http404 try: replacement = ReplacementAddon.objects.get(guid=guid) path = replacement.path except ReplacementAddon.DoesNotExist: path = DEFAULT_FIND_REPLACEMENT_PATH else: if replacement.has_external_url(): # It's an external URL: return redirect(get_outgoing_url(path)) replace_url = '%s%s?src=%s' % ( ('/' if not path.startswith('/') else ''), path, FIND_REPLACEMENT_SRC) return redirect(replace_url, permanent=False)
def test_basic_no_addon(self): serializer = BlockSerializer(instance=self.block) assert serializer.data == { 'id': self.block.id, 'addon_name': None, 'guid': 'foo@baa', 'min_version': '45', 'max_version': '*', 'reason': 'something happened', 'url': { 'url': 'https://goo.gol', 'outgoing': get_outgoing_url('https://goo.gol'), }, 'created': self.block.created.isoformat()[:-7] + 'Z', 'modified': self.block.modified.isoformat()[:-7] + 'Z', }
def external_url(url): """Bounce a URL off outgoing.prod.mozaws.net.""" return urlresolvers.get_outgoing_url(unicode(url))
def test_outgoing_url_javascript_scheme(): url = 'javascript://addons.mozilla.org/%0Aalert(location.href)' fixed = urlresolvers.get_outgoing_url(url) assert fixed == '/'
def external_url(url): """Bounce a URL off outgoing.mozilla.org.""" return urlresolvers.get_outgoing_url(unicode(url))
def test_outgoing_url_dirty_unicode(): bad = (u'http://chupakabr.ru/\u043f\u0440\u043e\u0435\u043a\u0442\u044b/' u'\u043c\u0443\u0437\u044b\u043a\u0430-vkontakteru/') urlresolvers.get_outgoing_url(bad) # bug 564057
def test_basic(self): cat1 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['bookmarks']) cat1.save() self.addon = addon_factory( average_daily_users=4242, average_rating=4.21, bayesian_rating=4.22, category=cat1, description=u'My Addôn description', file_kw={ 'hash': 'fakehash', 'is_restart_required': False, 'is_webextension': True, 'platform': amo.PLATFORM_WIN.id, 'size': 42, }, guid=generate_addon_guid(), homepage=u'https://www.example.org/', icon_type='image/png', name=u'My Addôn', public_stats=True, slug='my-addon', summary=u'My Addôn summary', support_email=u'*****@*****.**', support_url=u'https://support.example.org/support/my-addon/', tags=['some_tag', 'some_other_tag'], total_reviews=666, weekly_downloads=2147483647, ) AddonUser.objects.create(user=user_factory(username='******'), addon=self.addon, listed=False) second_author = user_factory(username='******', display_name=u'Secönd Author') first_author = user_factory(username='******', display_name=u'First Authôr') AddonUser.objects.create(user=second_author, addon=self.addon, position=2) AddonUser.objects.create(user=first_author, addon=self.addon, position=1) second_preview = Preview.objects.create(addon=self.addon, position=2, caption={ 'en-US': u'My câption', 'fr': u'Mön tîtré' }) first_preview = Preview.objects.create(addon=self.addon, position=1) av_min = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='2.0.99')[0] av_max = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='3.0.99')[0] ApplicationsVersions.objects.get_or_create( application=amo.THUNDERBIRD.id, version=self.addon.current_version, min=av_min, max=av_max) # Reset current_version.compatible_apps now that we've added an app. del self.addon.current_version.compatible_apps cat2 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['alerts-updates']) cat2.save() AddonCategory.objects.create(addon=self.addon, category=cat2) cat3 = Category.from_static_category( CATEGORIES[amo.THUNDERBIRD.id][amo.ADDON_EXTENSION]['calendar']) cat3.save() AddonCategory.objects.create(addon=self.addon, category=cat3) result = self.serialize() assert result['id'] == self.addon.pk assert result['average_daily_users'] == self.addon.average_daily_users assert result['categories'] == { 'firefox': ['alerts-updates', 'bookmarks'], 'thunderbird': ['calendar'] } assert result['current_beta_version'] is None # In this serializer latest_unlisted_version is omitted. assert 'latest_unlisted_version' not in result assert result['current_version'] self._test_version(self.addon.current_version, result['current_version']) assert result['current_version']['url'] == absolutify( reverse('addons.versions', args=[self.addon.slug, self.addon.current_version.version])) assert result['authors'] assert len(result['authors']) == 2 self.check_author(first_author, result['authors'][0]) self.check_author(second_author, result['authors'][1]) assert result['edit_url'] == absolutify(self.addon.get_dev_url()) assert result['default_locale'] == self.addon.default_locale assert result['description'] == {'en-US': self.addon.description} assert result['guid'] == self.addon.guid assert result['has_eula'] is False assert result['has_privacy_policy'] is False assert result['homepage'] == { 'en-US': get_outgoing_url(unicode(self.addon.homepage)) } assert result['icon_url'] == absolutify(self.addon.get_icon_url(64)) assert result['is_disabled'] == self.addon.is_disabled assert result['is_experimental'] == self.addon.is_experimental is False assert result['is_featured'] == self.addon.is_featured() is False assert result['is_source_public'] == self.addon.view_source assert result['last_updated'] == ( self.addon.last_updated.replace(microsecond=0).isoformat() + 'Z') assert result['name'] == {'en-US': self.addon.name} assert result['previews'] assert len(result['previews']) == 2 result_preview = result['previews'][0] assert result_preview['id'] == first_preview.pk assert result_preview['caption'] is None assert result_preview['image_url'] == absolutify( first_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( first_preview.thumbnail_url) result_preview = result['previews'][1] assert result_preview['id'] == second_preview.pk assert result_preview['caption'] == { 'en-US': u'My câption', 'fr': u'Mön tîtré' } assert result_preview['image_url'] == absolutify( second_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( second_preview.thumbnail_url) assert result['ratings'] == { 'average': self.addon.average_rating, 'bayesian_average': self.addon.bayesian_rating, 'count': self.addon.total_reviews, } assert result['public_stats'] == self.addon.public_stats assert result['requires_payment'] == self.addon.requires_payment assert result['review_url'] == absolutify( reverse('editors.review', args=[self.addon.pk])) assert result['slug'] == self.addon.slug assert result['status'] == 'public' assert result['summary'] == {'en-US': self.addon.summary} assert result['support_email'] == {'en-US': self.addon.support_email} assert result['support_url'] == { 'en-US': get_outgoing_url(unicode(self.addon.support_url)) } assert 'theme_data' not in result assert set(result['tags']) == set(['some_tag', 'some_other_tag']) assert result['type'] == 'extension' assert result['url'] == absolutify(self.addon.get_url_path()) assert result['weekly_downloads'] == self.addon.weekly_downloads return result
def test_wrap_outgoing_links(self): url = reverse_ns('blocklist-block-detail', args=(self.block.guid, )) response = self.client.get(url + '?wrap_outgoing_links') assert response.status_code == 200 assert response.json()['url'] == get_outgoing_url(self.block.url)
def test_basic(self): cat1 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['bookmarks']) cat1.save() license = License.objects.create( name={ 'en-US': u'My License', 'fr': u'Mä Licence', }, text={ 'en-US': u'Lorem ipsum dolor sit amet, has nemore patrioqué', }, url='http://license.example.com/' ) self.addon = addon_factory( average_daily_users=4242, average_rating=4.21, bayesian_rating=4.22, category=cat1, contributions=u'https://paypal.me/foobar/', description=u'My Addôn description', developer_comments=u'Dévelopers Addôn comments', file_kw={ 'hash': 'fakehash', 'is_restart_required': False, 'is_webextension': True, 'platform': amo.PLATFORM_WIN.id, 'size': 42, }, guid=generate_addon_guid(), homepage=u'https://www.example.org/', icon_type='image/png', name=u'My Addôn', public_stats=True, slug='my-addon', summary=u'My Addôn summary', support_email=u'*****@*****.**', support_url=u'https://support.example.org/support/my-addon/', tags=['some_tag', 'some_other_tag'], total_ratings=666, text_ratings_count=555, version_kw={ 'license': license, 'releasenotes': { 'en-US': u'Release notes in english', 'fr': u'Notes de version en français', }, }, weekly_downloads=2147483647, ) AddonUser.objects.create(user=user_factory(username='******'), addon=self.addon, listed=False) second_author = user_factory( username='******', display_name=u'Secönd Author') first_author = user_factory( username='******', display_name=u'First Authôr') AddonUser.objects.create( user=second_author, addon=self.addon, position=2) AddonUser.objects.create( user=first_author, addon=self.addon, position=1) second_preview = Preview.objects.create( addon=self.addon, position=2, caption={'en-US': u'My câption', 'fr': u'Mön tîtré'}, sizes={'thumbnail': [199, 99], 'image': [567, 780]}) first_preview = Preview.objects.create(addon=self.addon, position=1) av_min = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='2.0.99')[0] av_max = AppVersion.objects.get_or_create( application=amo.THUNDERBIRD.id, version='3.0.99')[0] ApplicationsVersions.objects.get_or_create( application=amo.THUNDERBIRD.id, version=self.addon.current_version, min=av_min, max=av_max) # Reset current_version.compatible_apps now that we've added an app. del self.addon.current_version._compatible_apps cat2 = Category.from_static_category( CATEGORIES[amo.FIREFOX.id][amo.ADDON_EXTENSION]['alerts-updates']) cat2.save() AddonCategory.objects.create(addon=self.addon, category=cat2) cat3 = Category.from_static_category( CATEGORIES[amo.THUNDERBIRD.id][amo.ADDON_EXTENSION]['calendar']) cat3.save() AddonCategory.objects.create(addon=self.addon, category=cat3) result = self.serialize() assert result['id'] == self.addon.pk assert result['average_daily_users'] == self.addon.average_daily_users assert result['categories'] == { 'firefox': ['alerts-updates', 'bookmarks'], 'thunderbird': ['calendar']} assert result['current_beta_version'] is None # In this serializer latest_unlisted_version is omitted. assert 'latest_unlisted_version' not in result assert result['current_version'] self._test_version( self.addon.current_version, result['current_version']) assert result['current_version']['url'] == absolutify( reverse('addons.versions', args=[self.addon.slug, self.addon.current_version.version]) ) self._test_version_license_and_release_notes( self.addon.current_version, result['current_version']) assert result['authors'] assert len(result['authors']) == 2 self._test_author(first_author, result['authors'][0]) self._test_author(second_author, result['authors'][1]) assert result['contributions_url'] == self.addon.contributions assert result['edit_url'] == absolutify(self.addon.get_dev_url()) assert result['default_locale'] == self.addon.default_locale assert result['description'] == {'en-US': self.addon.description} assert result['developer_comments'] == { 'en-US': self.addon.developer_comments} assert result['guid'] == self.addon.guid assert result['has_eula'] is False assert result['has_privacy_policy'] is False assert result['homepage'] == { 'en-US': get_outgoing_url(unicode(self.addon.homepage)) } assert result['icon_url'] == absolutify(self.addon.get_icon_url(64)) assert result['is_disabled'] == self.addon.is_disabled assert result['is_experimental'] == self.addon.is_experimental is False assert result['is_featured'] == self.addon.is_featured() is False assert result['is_source_public'] == self.addon.view_source assert result['last_updated'] == ( self.addon.last_updated.replace(microsecond=0).isoformat() + 'Z') assert result['name'] == {'en-US': self.addon.name} assert result['previews'] assert len(result['previews']) == 2 result_preview = result['previews'][0] assert result_preview['id'] == first_preview.pk assert result_preview['caption'] is None assert result_preview['image_url'] == absolutify( first_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( first_preview.thumbnail_url) assert result_preview['image_size'] == first_preview.image_size assert result_preview['thumbnail_size'] == first_preview.thumbnail_size result_preview = result['previews'][1] assert result_preview['id'] == second_preview.pk assert result_preview['caption'] == { 'en-US': u'My câption', 'fr': u'Mön tîtré' } assert result_preview['image_url'] == absolutify( second_preview.image_url) assert result_preview['thumbnail_url'] == absolutify( second_preview.thumbnail_url) assert (result_preview['image_size'] == second_preview.image_size == [567, 780]) assert (result_preview['thumbnail_size'] == second_preview.thumbnail_size == [199, 99]) assert result['ratings'] == { 'average': self.addon.average_rating, 'bayesian_average': self.addon.bayesian_rating, 'count': self.addon.total_ratings, 'text_count': self.addon.text_ratings_count, } assert result['public_stats'] == self.addon.public_stats assert result['requires_payment'] == self.addon.requires_payment assert result['review_url'] == absolutify( reverse('reviewers.review', args=[self.addon.pk])) assert result['slug'] == self.addon.slug assert result['status'] == 'public' assert result['summary'] == {'en-US': self.addon.summary} assert result['support_email'] == {'en-US': self.addon.support_email} assert result['support_url'] == { 'en-US': get_outgoing_url(unicode(self.addon.support_url)) } assert 'theme_data' not in result assert set(result['tags']) == set(['some_tag', 'some_other_tag']) assert result['type'] == 'extension' assert result['url'] == absolutify(self.addon.get_url_path()) assert result['weekly_downloads'] == self.addon.weekly_downloads return result