def test_parse_as_slug(self): app = Webapp.objects.get(pk=337141) into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), slug_field='app_slug') field.field_from_native({'addon': app.app_slug}, None, 'addon', into) eq_(into, {'addon': app})
def test_render_as_slug(self): obj = Mock() obj.attached = self.app field = SlugOrPrimaryKeyRelatedField(render_as='slug', slug_field='app_slug') eq_(field.field_to_native(obj, 'attached'), self.app.app_slug)
def test_parse_as_slugs_many(self): app2 = app_factory(app_slug='foo') field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), slug_field='app_slug', many=True) eq_(field.to_internal_value([self.app.app_slug, app2.app_slug]), [self.app, app2])
def test_render_as_pks_many(self): obj = Mock() obj.attached = [self.app] field = SlugOrPrimaryKeyRelatedField(many=True, read_only=True) field.bind('attached', None) eq_(field.to_representation(field.get_attribute(obj)), [self.app.pk])
def test_parse_as_slugs(self): c1 = Category.objects.create(name="delicious", slug="foo", type=amo.ADDON_WEBAPP) c2 = Category.objects.create(name="scrumptious", slug="baz", type=amo.ADDON_WEBAPP) into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Category.objects.all(), many=True) field.field_from_native({"categories": [c1.slug, c2.slug]}, None, "categories", into) eq_(into, {"categories": [c1, c2]})
def test_render_as_slugs_many(self): obj = Mock() obj.attached = [self.app] field = SlugOrPrimaryKeyRelatedField(render_as='slug', slug_field='app_slug', many=True) eq_(field.field_to_native(obj, 'attached'), [self.app.app_slug])
def test_parse_as_slugs_many(self): app2 = amo.tests.app_factory(app_slug='foo') into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), slug_field='app_slug', many=True) field.field_from_native({'apps': [self.app.app_slug, app2.app_slug]}, None, 'apps', into) eq_(into, {'apps': [self.app, app2]})
def test_parse_as_pks_many(self): app2 = amo.tests.app_factory() into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), many=True) field.field_from_native({'apps': [self.app.pk, app2.pk]}, None, 'apps', into) eq_(into, {'apps': [self.app, app2]})
def test_parse_as_pks_many(self): app2 = app_factory() into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), many=True) field.field_from_native({'apps': [self.app.pk, app2.pk]}, None, 'apps', into) eq_(into, {'apps': [self.app, app2]})
def test_render_as_pks(self): app = Webapp.objects.get(pk=337141) c1 = Category.objects.create(name="delicious", slug="foo", type=amo.ADDON_WEBAPP) c2 = Category.objects.create(name="scrumptious", slug="baz", type=amo.ADDON_WEBAPP) AddonCategory.objects.create(addon=app, category=c1) AddonCategory.objects.create(addon=app, category=c2) field = SlugOrPrimaryKeyRelatedField(queryset=Category.objects.all(), many=True) eq_(field.field_to_native(app, "categories"), [c1.pk, c2.pk])
def test_parse_as_slugs_many(self): app2 = app_factory(app_slug='foo') into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), slug_field='app_slug', many=True) field.field_from_native({'apps': [self.app.app_slug, app2.app_slug]}, None, 'apps', into) eq_(into, {'apps': [self.app, app2]})
def test_render_as_slug(self): obj = Mock() obj.attached = self.app field = SlugOrPrimaryKeyRelatedField(render_as='slug', slug_field='app_slug', read_only=True) field.bind('attached', None) eq_(field.to_representation(field.get_attribute(obj)), self.app.app_slug)
def test_parse_as_slugs(self): c1 = Category.objects.create(name='delicious', slug='foo', type=amo.ADDON_WEBAPP) c2 = Category.objects.create(name='scrumptious', slug='baz', type=amo.ADDON_WEBAPP) into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Category.objects.all(), many=True) field.field_from_native({'categories': [c1.slug, c2.slug]}, None, 'categories', into) eq_(into, {'categories': [c1, c2]})
def test_render_as_pks(self): app = Webapp.objects.get(pk=337141) c1 = Category.objects.create(name='delicious', slug='foo', type=amo.ADDON_WEBAPP) c2 = Category.objects.create(name='scrumptious', slug='baz', type=amo.ADDON_WEBAPP) AddonCategory.objects.create(addon=app, category=c1) AddonCategory.objects.create(addon=app, category=c2) field = SlugOrPrimaryKeyRelatedField(queryset=Category.objects.all(), many=True) eq_(field.field_to_native(app, 'categories'), [c1.pk, c2.pk])
def test_render_as_slugs(self): app = Webapp.objects.get(pk=337141) c1 = Category.objects.create(name='delicious', slug='foo', type=amo.ADDON_WEBAPP) c2 = Category.objects.create(name='scrumptious', slug='baz', type=amo.ADDON_WEBAPP) AddonCategory.objects.create(addon=app, category=c1) AddonCategory.objects.create(addon=app, category=c2) field = SlugOrPrimaryKeyRelatedField(queryset=Category.objects.all(), render_as='slug', slug_field='slug', many=True) eq_(field.field_to_native(app, 'categories'), [c1.slug, c2.slug])
class AppAbuseSerializer(BaseAbuseSerializer): app = SplitField( SlugOrPrimaryKeyRelatedField(source='addon', slug_field='app_slug', queryset=Webapp.objects.all()), SimpleAppSerializer(source='addon')) class Meta(BaseAbuseSerializer.Meta): fields = BaseAbuseSerializer.Meta.fields + ('app',)
class ExtensionAbuseSerializer(BaseAbuseSerializer): extension = SplitField( SlugOrPrimaryKeyRelatedField( source='extension', slug_field='slug', queryset=Extension.objects.without_deleted().public()), ExtensionSerializer()) class Meta(BaseAbuseSerializer.Meta): fields = BaseAbuseSerializer.Meta.fields + ('extension',)
class AppAbuseSerializer(BaseAbuseSerializer): app = SplitField( SlugOrPrimaryKeyRelatedField(source='addon', slug_field='app_slug', queryset=Webapp.objects.all()), SimpleAppSerializer(source='addon')) class Meta: model = AbuseReport fields = ('text', 'ip_address', 'reporter', 'app')
def test_parse_as_pk(self): app = Webapp.objects.get(pk=337141) into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all()) field.field_from_native({"addon": 337141}, None, "addon", into) eq_(into, {"addon": app})
def test_render_as_pk(self): obj = Mock() obj.attached = self.app field = SlugOrPrimaryKeyRelatedField() eq_(field.field_to_native(obj, 'attached'), self.app.pk)
def test_parse_as_pk(self): into = {} field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all()) field.field_from_native({'addon': self.app.pk}, None, 'addon', into) eq_(into, {'addon': self.app})
def test_render_as_pks_many(self): obj = Mock() obj.attached = [self.app] field = SlugOrPrimaryKeyRelatedField(many=True) eq_(field.field_to_native(obj, 'attached'), [self.app.pk])
def test_parse_as_pks_many(self): app2 = app_factory() field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), many=True) eq_(field.to_internal_value([self.app.pk, app2.pk]), [self.app, app2])
def test_render_as_slug(self): v = Version.objects.get(pk=1268829) field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), render_as='slug', slug_field='app_slug') eq_(field.field_to_native(v, 'addon'), v.addon.app_slug)
class RatingSerializer(serializers.ModelSerializer): app = SplitField( SlugOrPrimaryKeyRelatedField(slug_field='app_slug', queryset=Webapp.objects.all(), source='addon'), serializers.HyperlinkedRelatedField(view_name='app-detail', read_only=True, source='addon')) body = serializers.CharField() user = AccountSerializer(read_only=True) report_spam = serializers.SerializerMethodField('get_report_spam_link') resource_uri = serializers.HyperlinkedIdentityField( view_name='ratings-detail') is_author = serializers.SerializerMethodField('get_is_author') has_flagged = serializers.SerializerMethodField('get_has_flagged') version = SimpleVersionSerializer(read_only=True) class Meta: model = Review fields = ('app', 'body', 'created', 'has_flagged', 'is_author', 'modified', 'rating', 'report_spam', 'resource_uri', 'user', 'version') def __init__(self, *args, **kwargs): super(RatingSerializer, self).__init__(*args, **kwargs) if 'request' in self.context: self.request = self.context['request'] else: self.request = None if not self.request or not self.request.amo_user: self.fields.pop('is_author') self.fields.pop('has_flagged') if self.request.method in ('PUT', 'PATCH'): # Don't let users modify 'app' field at edit time self.fields['app'].read_only = True def get_report_spam_link(self, obj): return reverse('ratings-flag', kwargs={'pk': obj.pk}) def get_is_author(self, obj): return obj.user.pk == self.request.amo_user.pk def get_has_flagged(self, obj): return (not self.get_is_author(obj) and obj.reviewflag_set.filter(user=self.request.amo_user).exists()) @classmethod def get_app_from_value(cls, value): try: app = Webapp.objects.valid().get(id=value) except (Webapp.DoesNotExist, ValueError): try: app = Webapp.objects.valid().get(app_slug=value) except Webapp.DoesNotExist: raise serializers.ValidationError('Invalid app') if not app.listed_in(region=REGIONS_DICT[get_region()]): raise serializers.ValidationError( 'App not available in this region') return app def validate(self, attrs): attrs['user'] = self.request.amo_user attrs['ip_address'] = self.request.META.get('REMOTE_ADDR', '') if not getattr(self, 'object'): if attrs['addon'].is_packaged: attrs['version'] = attrs['addon'].current_version # Return 409 if the user has already reviewed this app. app = attrs['addon'] amo_user = self.request.amo_user qs = self.context['view'].queryset.filter(addon=app, user=amo_user) if app.is_packaged: qs = qs.filter(version=attrs['version']) if qs.exists(): raise Conflict('You have already reviewed this app.') # Return 403 if the user is attempting to review their own app: if app.has_author(amo_user): raise PermissionDenied('You may not review your own app.') # Return 403 if not a free app and the user hasn't purchased it. if app.is_premium() and not app.is_purchased(amo_user): raise PermissionDenied("You may not review paid apps you " "haven't purchased.") return attrs def validate_app(self, attrs, source): if not getattr(self, 'object'): app = attrs[source] attrs[source] = RatingSerializer.get_app_from_value(app.pk) else: attrs[source] = self.object.addon return attrs
class RatingSerializer(serializers.ModelSerializer): app = SplitField( SlugOrPrimaryKeyRelatedField(slug_field='app_slug', queryset=Webapp.objects.all(), source='addon'), serializers.HyperlinkedRelatedField(view_name='app-detail', read_only=True, source='addon')) body = serializers.CharField() user = AccountSerializer(read_only=True) report_spam = serializers.SerializerMethodField('get_report_spam_link') resource_uri = serializers.HyperlinkedIdentityField( view_name='ratings-detail') is_author = serializers.SerializerMethodField('get_is_author') has_flagged = serializers.SerializerMethodField('get_has_flagged') version = SimpleVersionSerializer(read_only=True) class Meta: model = Review fields = ('app', 'body', 'created', 'has_flagged', 'is_author', 'modified', 'rating', 'report_spam', 'resource_uri', 'user', 'version') def __init__(self, *args, **kwargs): super(RatingSerializer, self).__init__(*args, **kwargs) if 'request' in self.context: self.request = self.context['request'] else: self.request = None if not self.request or not self.request.amo_user: self.fields.pop('is_author') self.fields.pop('has_flagged') if self.request and self.request.method in ('PUT', 'PATCH'): # Don't let users modify 'app' field at edit time self.fields['app'].read_only = True def get_report_spam_link(self, obj): return reverse('ratings-flag', kwargs={'pk': obj.pk}) def get_is_author(self, obj): return obj.user.pk == self.request.amo_user.pk def get_has_flagged(self, obj): return (not self.get_is_author(obj) and obj.reviewflag_set.filter(user=self.request.amo_user).exists()) def validate(self, attrs): if not getattr(self, 'object'): # If we are creating a rating, then we need to do various checks on # the app. Because these checks need the version as well, we have # to do them here and not in validate_app(). # Assign user and ip_address. It won't change once the review is # created. attrs['user'] = self.request.amo_user attrs['ip_address'] = self.request.META.get('REMOTE_ADDR', '') # If the app is packaged, add in the current version. if attrs['addon'].is_packaged: attrs['version'] = attrs['addon'].current_version # Return 409 if the user has already reviewed this app. app = attrs['addon'] amo_user = self.request.amo_user qs = self.context['view'].queryset.filter(addon=app, user=amo_user) if app.is_packaged: qs = qs.filter(version=attrs['version']) if qs.exists(): raise Conflict('You have already reviewed this app.') # Return 403 is the app is not public. if not app.is_public(): raise PermissionDenied('The app requested is not public.') # Return 403 if the user is attempting to review their own app. if app.has_author(amo_user): raise PermissionDenied('You may not review your own app.') # Return 403 if not a free app and the user hasn't purchased it. if app.is_premium() and not app.is_purchased(amo_user): raise PermissionDenied("You may not review paid apps you " "haven't purchased.") # Return 403 if the app is not available in the current region. current_region = get_region() if not app.listed_in(region=current_region): raise PermissionDenied('App not available in region "%s".' % current_region.slug) return attrs def validate_app(self, attrs, source): # Don't allow users to change the app on an existing rating. if getattr(self, 'object'): attrs[source] = self.object.addon return attrs
def test_render_as_pk(self): v = Version.objects.get(pk=1268829) field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all()) eq_(field.field_to_native(v, 'addon'), v.addon.pk)
class RatingSerializer(serializers.ModelSerializer): app = SplitField( SlugOrPrimaryKeyRelatedField(slug_field='app_slug', queryset=Webapp.objects.all(), source='addon'), serializers.HyperlinkedRelatedField(view_name='app-detail', read_only=True, source='addon')) body = serializers.CharField() user = UserSerializer(read_only=True) report_spam = serializers.SerializerMethodField('get_report_spam_link') resource_uri = serializers.HyperlinkedIdentityField( view_name='ratings-detail') is_author = serializers.SerializerMethodField('get_is_author') has_flagged = serializers.SerializerMethodField('get_has_flagged') version = SimpleVersionSerializer(read_only=True) lang = serializers.SerializerMethodField('get_lang') class Meta: model = Review fields = ('app', 'body', 'created', 'has_flagged', 'is_author', 'lang', 'modified', 'rating', 'report_spam', 'resource_uri', 'user', 'version') def __init__(self, *args, **kwargs): super(RatingSerializer, self).__init__(*args, **kwargs) if 'request' in self.context: self.request = self.context['request'] else: self.request = None if 'view' in self.context and hasattr(self.context['view'], 'app'): self.app = self.context['view'].app if not self.request or not self.request.user.is_authenticated(): self.fields.pop('is_author') self.fields.pop('has_flagged') if self.request and self.request.method in ('PUT', 'PATCH'): # Don't let users modify 'app' field at edit time self.fields['app'].read_only = True def to_native(self, obj): # When we have an `app` set on the serializer, we know it's because the # view was filtering on this app, so we can safely overwrite the # `addon` property on the instance with it, saving some costly queries. app = getattr(self, 'app', None) if app is not None: obj.addon = app return super(RatingSerializer, self).to_native(obj) def get_report_spam_link(self, obj): return reverse('ratings-flag', kwargs={'pk': obj.pk}) def get_is_author(self, obj): return obj.user.pk == self.request.user.pk def get_has_flagged(self, obj): return (not self.get_is_author(obj) and obj.reviewflag_set.filter(user=self.request.user).exists()) def get_lang(self, obj): if obj.pk is None: return self.request.LANG else: return obj.lang def validate(self, attrs): if not getattr(self, 'object'): # If we are creating a rating, then we need to do various checks on # the app. Because these checks need the version as well, we have # to do them here and not in validate_app(). # Assign user and ip_address. It won't change once the review is # created. user = self.request.user attrs['user'] = user attrs['ip_address'] = self.request.META.get('REMOTE_ADDR', '') guessed_lang = guess_language(attrs['body']) if guessed_lang is None: attrs['lang'] = user.lang else: attrs['lang'] = guessed_lang # If the app is packaged, add in the current version. if attrs['addon'].is_packaged: attrs['version'] = attrs['addon'].current_version # Return 409 if the user has already reviewed this app. app = attrs['addon'] qs = self.context['view'].queryset.filter(addon=app, user=user) if app.is_packaged: qs = qs.filter(version=attrs['version']) if qs.exists(): raise Conflict('You have already reviewed this app.') # Return 403 is the app is not public. if not app.is_public(): raise PermissionDenied('The app requested is not public.') # Return 403 if the user is attempting to review their own app. if app.has_author(user): raise PermissionDenied('You may not review your own app.') # Return 403 if not a free app and the user hasn't purchased it. if app.is_premium() and not app.is_purchased(user): raise PermissionDenied("You may not review paid apps you " "haven't purchased.") # Return 403 if the app is not available in the current region. current_region = get_region() if not app.listed_in(region=current_region): raise PermissionDenied('App not available in region "%s".' % current_region.slug) return attrs def validate_app(self, attrs, source): # Don't allow users to change the app on an existing rating. if getattr(self, 'object'): attrs[source] = self.object.addon return attrs def validate_rating(self, attrs, source): # Don't allow user to submit rating outside the range valid_ratings = [1, 2, 3, 4, 5] # ensure rating key is present if source not in attrs: raise serializers.ValidationError("Rating key is required") value = attrs[source] rating = int(value) if value else value # ensure rating is in desired range if rating not in valid_ratings: raise serializers.ValidationError("Rating must be between 1-5") return attrs
def test_parse_as_slug(self): field = SlugOrPrimaryKeyRelatedField(queryset=Webapp.objects.all(), slug_field='app_slug') eq_(field.to_internal_value(self.app.app_slug), self.app)