diff --git a/kuma/wiki/tests/test_forms.py b/kuma/wiki/tests/test_forms.py index d00ac7858e0..08814a07a18 100644 --- a/kuma/wiki/tests/test_forms.py +++ b/kuma/wiki/tests/test_forms.py @@ -342,10 +342,10 @@ def setup_form( mock_requests.post(CHECK_URL, content=is_spam) section_id = None - is_iframe_target = False + is_async_submit = False rev_form = RevisionForm(request=request, data=data, - is_iframe_target=is_iframe_target, + is_async_submit=is_async_submit, section_id=section_id) rev_form.instance.document = previous_revision.document return rev_form diff --git a/kuma/wiki/tests/test_templates.py b/kuma/wiki/tests/test_templates.py index cd9c84d51ef..c73e1805bd0 100644 --- a/kuma/wiki/tests/test_templates.py +++ b/kuma/wiki/tests/test_templates.py @@ -456,7 +456,7 @@ def test_new_revision_POST_document_with_current(self, get_current): 'slug': self.d.slug, 'toc_depth': 1, 'based_on': self.d.current_revision.id, - 'form': 'rev', + 'form-type': 'rev', } edit_url = reverse('wiki.edit', args=[self.d.slug]) response = self.client.post(edit_url, data) @@ -508,7 +508,7 @@ def test_new_revision_POST_document_without_current( self.d.save() tags = ['tag1', 'tag2', 'tag3'] data = new_document_data(tags) - data['form'] = 'rev' + data['form-type'] = 'rev' response = self.client.post(reverse('wiki.edit', args=[self.d.slug]), data) eq_(302, response.status_code) @@ -531,7 +531,7 @@ def test_new_revision_POST_removes_old_tags(self): eq_(tags, result_tags) tags = [u'tag1', u'tag4'] data = new_document_data(tags) - data['form'] = 'rev' + data['form-type'] = 'rev' self.client.post(reverse('wiki.edit', args=[self.d.slug]), data) @@ -545,7 +545,7 @@ def test_new_form_maintains_based_on_rev(self): editing.""" _test_form_maintains_based_on_rev( self.client, self.d, 'wiki.edit', - {'summary': 'Windy', 'content': 'gerbils', 'form': 'rev', + {'summary': 'Windy', 'content': 'gerbils', 'form-type': 'rev', 'slug': self.d.slug, 'toc_depth': 1}, locale='en-US') @@ -572,7 +572,7 @@ def test_can_save_document_with_translations(self): data = new_document_data() new_title = 'A brand new title' data.update(title=new_title) - data.update(form='doc') + data['form-type'] = 'doc' data.update(is_localizable='True') response = self.client.post(reverse('wiki.edit', args=[self.d.slug]), data, follow=True) @@ -585,7 +585,7 @@ def test_change_slug_case(self): data = new_document_data() new_slug = 'Test-Document' data.update(slug=new_slug) - data.update(form='doc') + data['form-type'] = 'doc' response = self.client.post(reverse('wiki.edit', args=[self.d.slug]), data, follow=True) eq_(200, response.status_code) @@ -597,7 +597,7 @@ def test_change_title_case(self): data = new_document_data() new_title = 'TeST DoCuMent' data.update(title=new_title) - data.update(form='doc') + data['form-type'] = 'doc' response = self.client.post(reverse('wiki.edit', args=[self.d.slug]), data, follow=True) eq_(200, response.status_code) @@ -911,7 +911,7 @@ def test_translate_update_doc_only(self): data = _translation_data() new_title = 'Un nuevo titulo' data['title'] = new_title - data['form'] = 'doc' + data['form-type'] = 'doc' response = self.client.post(translate_uri, data) eq_(302, response.status_code) eq_('http://testserver/es/docs/un-test-articulo$edit' diff --git a/kuma/wiki/tests/test_views.py b/kuma/wiki/tests/test_views.py index 9aa0074c942..c185b148e82 100644 --- a/kuma/wiki/tests/test_views.py +++ b/kuma/wiki/tests/test_views.py @@ -500,7 +500,7 @@ def test_template_permissions(self): url = reverse('wiki.create', locale=locale) resp = self.client.post(url, data, follow=False) else: - data['form'] = 'rev' + data['form-type'] = 'rev' url = reverse('wiki.edit', args=(slug,), locale=locale) resp = self.client.post(url, data, follow=False) @@ -1240,7 +1240,7 @@ def test_retitling_solo_doc(self): old_title = doc.title data = new_document_data() data.update({'title': new_title, - 'form': 'rev'}) + 'form-type': 'rev'}) data['slug'] = '' url = reverse('wiki.edit', args=[doc.slug]) self.client.post(url, data) @@ -1274,7 +1274,7 @@ def test_retitling_parent_doc(self): new_title = 'Some New Title' data = new_document_data() data.update({'title': new_title, - 'form': 'rev'}) + 'form-type': 'rev'}) data['slug'] = '' url = reverse('wiki.edit', args=[d.slug]) self.client.post(url, data) @@ -1326,7 +1326,7 @@ def test_slug_collision_errors(self): # Now, post an update with duplicate slug data.update({ - 'form': 'rev', + 'form-type': 'rev', 'slug': exist_slug }) resp = self.client.post(reverse('wiki.edit', @@ -1357,7 +1357,7 @@ def test_redirect_can_be_clobbered(self): eq_(302, resp.status_code) # Change title and slug - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'title': changed_title, 'slug': changed_slug}) resp = self.client.post(reverse('wiki.edit', @@ -1366,7 +1366,7 @@ def test_redirect_can_be_clobbered(self): eq_(302, resp.status_code) # Change title and slug back to originals, clobbering the redirect - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'title': exist_title, 'slug': exist_slug}) resp = self.client.post(reverse('wiki.edit', @@ -1625,7 +1625,7 @@ def _run_translate_tests(translate_slug, translate_data, # ensure the slug stays the same (i.e. no parent prepending) def test_invalid_slug_translate(inv_slug, url, data): data['slug'] = inv_slug - data['form'] = 'both' + data['form-type'] = 'both' response = self.client.post(url, data) eq_(200, response.status_code) # 200 = bad, invalid data page = pq(response.content) @@ -1640,7 +1640,7 @@ def test_invalid_slug_translate(inv_slug, url, data): # Push a valid translation translate_data['slug'] = translate_slug - translate_data['form'] = 'both' + translate_data['form-type'] = 'both' response = self.client.post(foreign_url, translate_data) eq_(302, response.status_code) # Ensure no redirect @@ -1671,7 +1671,7 @@ def _run_translate_edit_tests(edit_slug, edit_data, edit_doc): # Attempt an invalid edit of the root, ensure the slug stays # the same (i.e. no parent prepending) edit_data['slug'] = invalid_slug - edit_data['form'] = 'both' + edit_data['form-type'] = 'both' response = self.client.post(reverse('wiki.edit', args=[edit_doc.slug], locale=foreign_locale), @@ -1707,7 +1707,7 @@ def _run_translate_edit_tests(edit_slug, edit_data, edit_doc): def _run_slug_edit_tests(edit_slug, edit_data, edit_doc, loc): edit_data['slug'] = edit_data['slug'] + '_Updated' - edit_data['form'] = 'rev' + edit_data['form-type'] = 'rev' response = self.client.post(reverse('wiki.edit', args=[edit_doc.slug], locale=loc), @@ -1758,7 +1758,7 @@ def _run_slug_edit_tests(edit_slug, edit_data, edit_doc, loc): locale=settings.WIKI_DEFAULT_LANGUAGE)) # Editing "length/length" document doesn't cause errors - child_data['form'] = 'rev' + child_data['form-type'] = 'rev' child_data['slug'] = '' edit_url = reverse('wiki.edit', args=['length/length'], locale=settings.WIKI_DEFAULT_LANGUAGE) @@ -1773,7 +1773,7 @@ def _run_slug_edit_tests(edit_slug, edit_data, edit_doc, loc): # Creating a new translation of "length" and "length/length" # doesn't cause errors - child_data['form'] = 'both' + child_data['form-type'] = 'both' child_data['slug'] = 'length' translate_url = reverse('wiki.document', args=[child_data['slug']], locale=settings.WIKI_DEFAULT_LANGUAGE) @@ -2030,7 +2030,7 @@ def test_restore_translation_source(self): ok_(pq(response.content)('li.metadata-choose-parent')) # Set the parent - data.update({'form': 'rev', 'parent_id': en_d.id}) + data.update({'form-type': 'rev', 'parent_id': en_d.id}) resp = self.client.post(url, data) eq_(302, resp.status_code) ok_('fr/docs/a-test-article' in resp['Location']) @@ -2116,7 +2116,7 @@ def assert_tag_state(yes_tags, no_tags): assert_tag_state(ts1, ts2) # Now, update the tags. - data.update({'form': 'rev', 'tags': ', '.join(ts2)}) + data.update({'form-type': 'rev', 'tags': ', '.join(ts2)}) self.client.post(reverse('wiki.edit', args=[path]), data) assert_tag_state(ts2, ts1) @@ -2142,7 +2142,7 @@ def test_review_tags(self, get_current): # Now, post an update with two tags data.update({ - 'form': 'rev', + 'form-type': 'rev', 'review_tags': ['editorial', 'technical'], }) response = self.client.post(reverse('wiki.edit', @@ -2189,7 +2189,7 @@ def test_review_tags(self, get_current): # Post an edit that removes one of the tags. data.update({ - 'form': 'rev', + 'form-type': 'rev', 'review_tags': ['editorial', ] }) response = self.client.post(reverse('wiki.edit', @@ -2307,7 +2307,7 @@ def test_edit_midair_collision(self): # Edit #2 submits successfully data.update({ - 'form': 'rev', + 'form-type': 'rev', 'content': 'This edit got there first', 'current_rev': rev_id2 }) @@ -2317,7 +2317,7 @@ def test_edit_midair_collision(self): # Edit #1 submits, but receives a mid-aired notification data.update({ - 'form': 'rev', + 'form-type': 'rev', 'content': 'This edit gets mid-aired', 'current_rev': rev_id1 }) @@ -2325,7 +2325,11 @@ def test_edit_midair_collision(self): args=[doc.slug]), data) eq_(200, resp.status_code) - ok_(unicode(MIDAIR_COLLISION).encode('utf-8') in resp.content, + history_url = reverse( + 'wiki.document_revisions', + kwargs={'document_path': doc.slug}, locale=doc.locale) + midair_collission_error = (unicode(MIDAIR_COLLISION) % {'url': history_url}).encode('utf-8') + ok_(midair_collission_error in resp.content, "Midair collision message should appear") @pytest.mark.toc @@ -2336,7 +2340,7 @@ def test_toc_toggle_off(self): doc = rev.document data = new_document_data() ok_(Document.objects.get(slug=doc.slug, locale=doc.locale).show_toc) - data['form'] = 'rev' + data['form-type'] = 'rev' data['toc_depth'] = 0 data['slug'] = doc.slug data['title'] = doc.title @@ -2356,7 +2360,7 @@ def test_toc_toggle_on(self): ok_(not Document.objects.get(slug=rev.document.slug, locale=rev.document.locale).show_toc) data = new_document_data() - data['form'] = 'rev' + data['form-type'] = 'rev' data['slug'] = rev.document.slug data['title'] = rev.document.title self.client.post(reverse('wiki.edit', args=[rev.document.slug]), @@ -2547,7 +2551,7 @@ def test_store_revision_ip(self): doc = Document.objects.get(locale=settings.WIKI_DEFAULT_LANGUAGE, slug=slug) - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'content': 'This revision should NOT record IP', 'comment': 'This revision should NOT record IP'}) @@ -2589,7 +2593,7 @@ def test_email_for_first_edits(self, get_current): doc = Document.objects.get( locale=settings.WIKI_DEFAULT_LANGUAGE, slug=slug) - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'content': 'This edit should not send an email', 'comment': 'This edit should not send an email'}) @@ -2632,7 +2636,7 @@ def test_email_for_watched_edits(self, get_current): testuser2 = get_user(username='testuser2') EditDocumentEvent.notify(testuser2, rev.document) - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'slug': rev.document.slug, 'title': rev.document.title, 'content': 'This edit should send an email', @@ -2656,7 +2660,7 @@ def test_email_for_watched_edits(self, get_current): testuser01 = get_user(username='testuser01') EditDocumentEvent.notify(testuser01, rev.document) - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'slug': rev.document.slug, 'content': 'This edit should send 2 emails', 'comment': 'This edit should send 2 emails'}) @@ -2689,7 +2693,7 @@ def test_email_for_child_edit_in_watched_tree(self, get_current): self.client.login(username='testuser', password='testpass') data = new_document_data() - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'slug': child_doc.slug, 'content': 'This edit should send an email', 'comment': 'This edit should send an email'}) @@ -2716,7 +2720,7 @@ def test_email_for_grandchild_edit_in_watched_tree(self, get_current): self.client.login(username='testuser', password='testpass') data = new_document_data() - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'slug': grandchild_doc.slug, 'content': 'This edit should send an email', 'comment': 'This edit should send an email'}) @@ -2745,7 +2749,7 @@ def test_single_email_when_watching_doc_and_tree(self, get_current): self.client.login(username='testuser', password='testpass') data = new_document_data() - data.update({'form': 'rev', + data.update({'form-type': 'rev', 'slug': child_doc.slug, 'content': 'This edit should send an email', 'comment': 'This edit should send an email'}) @@ -2931,7 +2935,7 @@ def test_raw_section_source(self): normalize_html(response.content)) @pytest.mark.midair - def test_raw_section_edit(self): + def test_raw_section_edit_ajax(self): self.client.login(username='admin', password='testpass') rev = revision(is_approved=True, save=True, content="""

s1

@@ -2950,20 +2954,16 @@ def test_raw_section_edit(self):

s2

replace

""" - expected = """ -

s2

-

replace

- """ response = self.client.post('%s?section=s2&raw=true' % reverse('wiki.edit', args=[rev.document.slug]), - {"form": "rev", + {"form-type": "rev", "slug": rev.document.slug, "content": replace}, follow=True, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - eq_(normalize_html(expected), - normalize_html(response.content)) + eq_({'error': False, 'new_revision_id': rev.id + 1}, + json.loads(response.content)) expected = """

s1

@@ -2985,7 +2985,7 @@ def test_raw_section_edit(self): normalize_html(response.content)) @pytest.mark.midair - def test_midair_section_merge(self): + def test_midair_section_merge_ajax(self): """If a page was changed while someone was editing, but the changes didn't affect the specific section being edited, then ignore the midair warning""" @@ -3024,7 +3024,7 @@ def test_midair_section_merge(self):

test

""" data = { - 'form': 'rev', + 'form-type': 'rev', 'content': rev.content, 'slug': '' } @@ -3046,7 +3046,7 @@ def test_midair_section_merge(self): # Edit #2 submits successfully data.update({ - 'form': 'rev', + 'form-type': 'rev', 'content': replace_2, 'current_rev': rev_id2, 'slug': rev.document.slug @@ -3055,12 +3055,13 @@ def test_midair_section_merge(self): reverse('wiki.edit', args=[rev.document.slug]), data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - eq_(302, resp.status_code) + + eq_(json.loads(resp.content)['error'], False) # Edit #1 submits, but since it's a different section, there's no # mid-air collision data.update({ - 'form': 'rev', + 'form-type': 'rev', 'content': replace_1, 'current_rev': rev_id1 }) @@ -3087,7 +3088,7 @@ def test_midair_section_merge(self): unicode(response['x-kuma-revision'])) @pytest.mark.midair - def test_midair_section_collision(self): + def test_midair_section_collision_ajax(self): """If both a revision and the edited section has changed, then a section edit is a collision.""" self.client.login(username='admin', password='testpass') @@ -3114,7 +3115,7 @@ def test_midair_section_collision(self):

first replace

""" data = { - 'form': 'rev', + 'form-type': 'rev', 'content': rev.content } @@ -3134,7 +3135,7 @@ def test_midair_section_collision(self): # Edit #2 submits successfully data.update({ - 'form': 'rev', + 'form-type': 'rev', 'content': replace_2, 'slug': rev.document.slug, 'current_rev': rev_id2 @@ -3142,7 +3143,7 @@ def test_midair_section_collision(self): resp = self.client.post('%s?section=s2&raw=true' % reverse('wiki.edit', args=[rev.document.slug]), data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') - eq_(302, resp.status_code) + eq_(False, json.loads(resp.content)['error']) # Edit #1 submits, but since it's the same section, there's a collision data.update({ @@ -3155,6 +3156,13 @@ def test_midair_section_collision(self): data, HTTP_X_REQUESTED_WITH='XMLHttpRequest') # With the raw API, we should get a 409 Conflict on collision. eq_(409, resp.status_code) + # We receive the midair collission message + history_url = reverse( + 'wiki.document_revisions', + kwargs={'document_path': rev.document.slug}, locale=rev.document.locale) + midair_collission_error = (unicode(MIDAIR_COLLISION) % {'url': history_url}).encode('utf-8') + ok_(midair_collission_error in json.loads(resp.content)['error_message'], + "Midair collision message should appear") def test_raw_include_option(self): doc_src = u""" @@ -3209,7 +3217,7 @@ def test_section_edit_toc(self): """ self.client.post('%s?section=s2&raw=true' % reverse('wiki.edit', args=[rev.document.slug]), - {"form": "rev", "slug": rev.document.slug, "content": replace}, + {"form-type": "rev", "slug": rev.document.slug, "content": replace}, follow=True, HTTP_X_REQUESTED_WITH='XMLHttpRequest') changed = Document.objects.get(pk=rev.document.id).current_revision ok_(rev.id != changed.id) @@ -3242,7 +3250,7 @@ def test_section_edit_review_tags(self): """ self.client.post('%s?section=s2&raw=true' % reverse('wiki.edit', args=[rev.document.slug]), - {"form": "rev", "slug": rev.document.slug, "content": replace}, + {"form-type": "rev", "slug": rev.document.slug, "content": replace}, follow=True, HTTP_X_REQUESTED_WITH='XMLHttpRequest') changed = Document.objects.get(pk=rev.document.id).current_revision ok_(rev.id != changed.id) @@ -3691,7 +3699,7 @@ def test_schedule_rendering(self, mock_kumascript_get, data = new_document_data() data.update({ - 'form': 'rev', + 'form-type': 'rev', 'content': 'This is an update', }) @@ -3703,7 +3711,7 @@ def test_schedule_rendering(self, mock_kumascript_get, mock_document_schedule_rendering.reset_mock() data.update({ - 'form': 'both', + 'form-type': 'both', 'content': 'This is a translation', }) translate_url = (reverse('wiki.translate', args=[data['slug']], diff --git a/kuma/wiki/views/edit.py b/kuma/wiki/views/edit.py index c344fe97f6b..f101086bac8 100644 --- a/kuma/wiki/views/edit.py +++ b/kuma/wiki/views/edit.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -import textwrap -import json from urllib import urlencode import newrelic.agent @@ -172,9 +170,11 @@ def edit(request, document_slug, document_locale, revision_id=None): # save-and-edit button if is_async_submit: + # This is the most recent revision id + new_rev_id = rev.document.revisions.order_by('-id').first().id data = { - "error" : False, - "new_revision_id" : rev.document.revisions.order_by('-id').first().id # This is the most recent revision id + "error": False, + "new_revision_id": new_rev_id } return JsonResponse(data) @@ -250,9 +250,11 @@ def edit(request, document_slug, document_locale, revision_id=None): response.status_code = 205 return response # This must be an Ajax POST, but no need to refresh + # This is the most recent revision id + new_rev_id = rev.document.revisions.order_by('-id').first().id data = { - "error" : False, - "new_revision_id" : rev.document.revisions.order_by('-id').first().id # This is the most recent revision id + "error": False, + "new_revision_id": new_rev_id } return JsonResponse(data) diff --git a/kuma/wiki/views/translate.py b/kuma/wiki/views/translate.py index da0edc778af..1ca4edfde90 100644 --- a/kuma/wiki/views/translate.py +++ b/kuma/wiki/views/translate.py @@ -3,6 +3,7 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied from django.http import JsonResponse from django.shortcuts import get_object_or_404, redirect, render +from django.utils.safestring import mark_safe from django.utils.translation import ugettext_lazy as _ import kuma.wiki.content @@ -201,6 +202,7 @@ def translate(request, document_slug, document_locale, revision_id=None): parent_slug=slug_dict['parent']) rev_form.instance.document = doc # for rev_form.clean() +# import ipdb;ipdb.set_trace() if rev_form.is_valid() and not doc_form_invalid: parent_id = request.POST.get('parent_id', '') @@ -227,8 +229,6 @@ def translate(request, document_slug, document_locale, revision_id=None): else: # If this is an Ajax POST, then return a JsonResponse with error if request.is_ajax(): - import ipdb;ipdb.set_trace() - from django.utils.safestring import mark_safe data = { "error": True, "error_message": mark_safe(rev_form.errors['current_rev'][0]),