def build_form_data(self, data): """Build dict containing data that would be submitted by clients.""" rval = {} license_data = { 'builtin': self.version.license.builtin, 'text': str(self.version.license.text) } if self.version and self.version.license else {} authors_data = [ {'id': author.id, 'role': author.role, 'listed': author.listed, 'position': author.position} for author in AddonUser.objects.filter( addon=self.addon).order_by('position')] authors_pending_confirmation_data = [ {'id': author.id, 'role': author.role, 'listed': author.listed} for author in AddonUserPendingConfirmation.objects.filter( addon=self.addon).order_by('id')] rval.update( **license_data, **formset( *authors_data, prefix='user_form', initial_count=len(authors_data), total_count=len(authors_data), ), **formset( *authors_pending_confirmation_data, prefix='authors_pending_confirmation', initial_count=len(authors_pending_confirmation_data), total_count=len(authors_pending_confirmation_data), ), ) rval.update(data) # Separate .update() call to allow overrides. return rval
def test_no_changing_platform(self): ctx = self.client.get(self.url).context compat = initial(ctx['compat_form'].forms[0]) files = initial(ctx['file_form'].forms[0]) files['platform'] = amo.PLATFORM_LINUX.id self.initial = formset(compat, **formset(files, prefix='files')) response = self.client.post(self.url, self.formset()) assert response.status_code == 302 file_ = self.get_version().files.all()[0] assert amo.PLATFORM_ALL.id == file_.platform
def test_insert_long_blurb(self): dupe = initial(self.f) dupe.update(id='', blurb='x' * 201, locale='en-US') data = formset(initial(self.f), dupe, initial_count=1) r = self.client.post(self.url, data) assert r.context['form'].errors[1]['blurb'][0] == ( 'Ensure this value has at most 200 characters (it has 201).')
def test_insert_no_image(self): dupe = initial(self.f) dupe.update(id='', image='', locale='en-US') data = formset(initial(self.f), dupe, initial_count=1) self.client.post(self.url, data) assert MonthlyPick.objects.count() == 2 assert MonthlyPick.objects.all()[1].image == ''
def test_add_user_that_was_already_invited(self): AddonUserPendingConfirmation.objects.create( addon=self.addon, user=UserProfile.objects.get(email='*****@*****.**'), role=amo.AUTHOR_ROLE_DEV, listed=True, ) additional_data = formset( { 'id': AddonUserPendingConfirmation.objects.get().pk, 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, }, { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, }, prefix='authors_pending_confirmation', total_count=2, initial_count=1, ) data = self.build_form_data(additional_data) response = self.client.post(self.url, data) assert response.status_code == 200 form = response.context['authors_pending_confirmation_form'] assert form.non_form_errors() == ([ 'An author can only be present once.' ])
def test_required_collection(self): data = initial(self.f) del data['collection'] response = self.client.post(self.url, formset(data, initial_count=1)) assert response.context['form'].errors[0]['collection'] == ([ 'This field is required.' ])
def test_bad_collection(self): data = initial(self.f) data['collection'] = 999 response = self.client.post(self.url, formset(data, initial_count=1)) assert response.context['form'].errors[0]['collection'] == ([ 'Invalid collection for this application.' ])
def test_impossible_to_add_to_authors_directly(self): additional_data = formset( { 'id': AddonUser.objects.get().pk, 'user': '******', 'role': amo.AUTHOR_ROLE_OWNER, 'listed': True, 'position': 0, }, { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, 'position': 1, }, prefix='user_form', # Add to the actual list of users directly. total_count=2, initial_count=1) data = self.build_form_data(additional_data) response = self.client.post(self.url, data) assert response.status_code == 200 form = response.context['user_form'] assert not form.is_valid() # This form tampering shouldn't have worked, the new user should not # have been added anywhere. expected_authors = ['*****@*****.**'] assert list(AddonUser.objects.filter(addon=self.addon).values_list( 'user__email', flat=True).order_by('position')) == expected_authors expected_pending = [] assert list(AddonUserPendingConfirmation.objects.filter( addon=self.addon).values_list( 'user__email', flat=True)) == expected_pending
def test_bad_locale(self): data = initial(self.f) data['locale'] = 'klingon' response = self.client.post(self.url, formset(data, initial_count=1)) assert response.context['form'].errors[0]['locale'] == ( ['Select a valid choice. klingon is not one of the available ' 'choices.'])
def test_cant_add_if_display_name_is_not_ok_for_a_developer(self): regular = UserProfile.objects.get(email='*****@*****.**') regular.update(display_name='1') additional_data = formset( { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, }, prefix='authors_pending_confirmation', total_count=1, initial_count=0, ) data = self.build_form_data(additional_data) response = self.client.post(self.url, data) assert response.status_code == 200 form = response.context['authors_pending_confirmation_form'] assert not form.is_valid() assert form.errors == [ { 'user': [ 'The account needs a display name before it can be ' 'added as an author.' ] } ]
def test_bad_app(self): data = initial(self.f) data['application'] = 999 response = self.client.post(self.url, formset(data, initial_count=1)) assert response.context['form'].errors[0]['application'] == [ 'Select a valid choice. 999 is not one of the available choices.' ]
def test_disabled_autocomplete_errors(self): """If any collection errors, autocomplete field should be enabled.""" data = initial(self.f) data['collection'] = 999 response = self.client.post(self.url, formset(data, initial_count=1)) doc = pq(response.content) assert not doc('#features .collection-ac[disabled]')
def test_success_add_user(self): additional_data = formset( { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, }, prefix='authors_pending_confirmation', total_count=1, initial_count=0, ) data = self.build_form_data(additional_data) assert not ActivityLog.objects.filter( action=amo.LOG.ADD_USER_WITH_ROLE.id ).exists() assert len(mail.outbox) == 0 response = self.client.post(self.url, data) self.assert3xx(response, self.url, 302) # New author is pending confirmation, hasn't been added to the # actual author list yet. expected_authors = ['*****@*****.**'] assert ( list( AddonUser.objects.filter(addon=self.addon) .values_list('user__email', flat=True) .order_by('position') ) == expected_authors ) expected_pending = ['*****@*****.**'] assert ( list( AddonUserPendingConfirmation.objects.filter( addon=self.addon ).values_list('user__email', flat=True) ) == expected_pending ) # A new ActivityLog has been added for this action. assert ActivityLog.objects.filter(action=amo.LOG.ADD_USER_WITH_ROLE.id).exists() # An email has been sent to the authors to warn them. invitation_url = absolutify( reverse('devhub.addons.invitation', args=(self.addon.slug,)) ) assert len(mail.outbox) == 2 author_added_email = mail.outbox[0] assert author_added_email.subject == ('An author has been added to your add-on') assert '*****@*****.**' in author_added_email.to # The original author. author_confirmation_email = mail.outbox[1] assert author_confirmation_email.subject == ( 'Author invitation for Delicious Bookmarks' ) assert '*****@*****.**' in author_confirmation_email.to assert invitation_url in author_confirmation_email.body assert settings.DOMAIN in author_confirmation_email.body
def test_success_insert_no_locale(self): dupe = initial(self.f) del dupe['id'] del dupe['locale'] data = formset(initial(self.f), dupe, initial_count=1) self.client.post(self.url, data) assert MonthlyPick.objects.count() == 2 assert MonthlyPick.objects.all()[1].locale == ''
def test_success_insert(self): dupe = initial(self.f) del dupe['id'] dupe['locale'] = 'fr' data = formset(initial(self.f), dupe, initial_count=1) self.client.post(self.url, data) assert FeaturedCollection.objects.count() == 2 assert FeaturedCollection.objects.all()[1].locale == 'fr'
def test_required_app(self): data = initial(self.f) del data['application'] response = self.client.post(self.url, formset(data, initial_count=1)) assert response.status_code == 200 assert response.context['form'].errors[0]['application'] == ( ['This field is required.']) assert response.context['form'].errors[0]['collection'] == ( ['Invalid collection for this application.'])
def test_failure_add_non_existing_user(self): additional_data = formset( { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True }, prefix='authors_pending_confirmation', total_count=1, initial_count=0) data = self.build_form_data(additional_data) response = self.client.post(self.url, data) assert response.status_code == 200 form = response.context['authors_pending_confirmation_form'] assert form.errors == [{'user': ['No user with that email.']}]
def test_can_edit_with_collections_edit_permission(self): collection = Collection.objects.create(slug='floob') addon = addon_factory() addon2 = addon_factory() collection_addon = CollectionAddon.objects.create( addon=addon, collection=collection ) self.detail_url = reverse( 'admin:bandwagon_collection_change', args=(collection.pk,) ) user = user_factory(email='*****@*****.**') self.grant_permission(user, 'Collections:Edit') self.client.login(email=user.email) response = self.client.get(self.detail_url, follow=True) assert response.status_code == 200 content = response.content.decode('utf-8') assert collection.slug in content assert str(addon.name) in content post_data = { # Django wants the whole form to be submitted, unfortunately. 'application': amo.FIREFOX.id, 'type': collection.type, 'default_locale': collection.default_locale, 'author': user.pk, } post_data['slug'] = 'bar' post_data.update( formset( { 'addon': addon2.pk, 'id': collection_addon.pk, 'collection': collection.pk, 'ordering': 1, }, prefix='collectionaddon_set', ) ) response = self.client.post(self.detail_url, post_data, follow=True) assert response.status_code == 200 collection.reload() collection_addon.reload() assert collection.slug == 'bar' assert collection_addon.addon == addon2 assert collection_addon.collection == collection assert CollectionAddon.objects.count() == 1
def test_add_user_that_was_already_an_author(self): additional_data = formset( { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, }, prefix='authors_pending_confirmation', total_count=1, initial_count=0) data = self.build_form_data(additional_data) response = self.client.post(self.url, data) assert response.status_code == 200 form = response.context['authors_pending_confirmation_form'] assert form.errors == [ # This time the error can be attached directly to the field, so # it's not in non_form_errors(). {'user': ['An author can only be present once.']} ]
def test_add_user_twice_in_same_post(self): additional_data = formset( { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, }, { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True, }, prefix='authors_pending_confirmation', total_count=2, initial_count=0, ) data = self.build_form_data(additional_data) response = self.client.post(self.url, data) assert response.status_code == 200 form = response.context['authors_pending_confirmation_form'] assert form.non_form_errors() == (['An author can only be present once.'])
def test_failure_add_restricted_user(self): EmailUserRestriction.objects.create( email_pattern='*****@*****.**') additional_data = formset( { 'user': '******', 'role': amo.AUTHOR_ROLE_DEV, 'listed': True }, prefix='authors_pending_confirmation', total_count=1, initial_count=0) data = self.build_form_data(additional_data) response = self.client.post(self.url, data) assert response.status_code == 200 form = response.context['authors_pending_confirmation_form'] assert form.errors == [ { 'user': ['The email address used for your account is not ' 'allowed for add-on submission.'] } ]
def formset(self, *args, **kw): defaults = formset(prefix='files') defaults.update(kw) return super(TestVersionEditCompat, self).formset(*args, **defaults)
def formset(self, *args, **kw): compat = formset(self.compat, initial_count=1) compat.update(kw) return super(TestVersionEditFiles, self).formset(*args, **compat)
def setUp(self): super(TestVersionEditDetails, self).setUp() ctx = self.client.get(self.url).context compat = initial(ctx['compat_form'].forms[0]) files = initial(ctx['file_form'].forms[0]) self.initial = formset(compat, **formset(files, prefix='files'))
def formset(self, *args, **kw): defaults = {'approvalnotes': 'xxx'} defaults.update(kw) return formset(*args, **defaults)
def formset(self, *args, **kw): return formset(*args, **kw)
def formset(self, *args, **kw): defaults = {'builtin': 11} defaults.update(kw) return formset(*args, **defaults)
def formset(self, *args, **kw): defaults = {'builtin': License.OTHER, 'text': 'filler'} defaults.update(kw) return formset(*args, **defaults)
def setUp(self): super().setUp() ctx = self.client.get(self.url).context compat = initial(ctx['compat_form'].forms[0]) self.initial = formset(compat)
def formset(self, *args, **kw): defaults = formset(prefix='files') defaults.update(kw) return super().formset(*args, **defaults)