Repository: mdn/kuma

Issue:
Simplify display of contributors per page
To quote @atopal [from here](https://github.com/mozilla/kuma/issues/5669#issuecomment-525685343)

> let's just replace the whole section with "last edited on xx by MDN contributors" and that links to the revision history. If someone can come up with a good use case for having the full list on the article page itself, we should consider that, but nothing comes to mind.

@chrisdavidmills Are you OK with that?




Discussion:
I would suggest we only change the read-only site with this change. It makes the scope smaller and it makes more sense to have the list over on the wiki. 
I'm going to label this as performance-related because it would take a decent chunk of HTML and React state data out of the server-rendered pages. 
I think the original motivation for the list of contributors was to raise their visibility, give credit, and make readers aware that MDN is a wiki. However, I think it was a done as a quick hack and never optimized. I don't think the motivations are strong enough to outweigh any performance hits it's causing.
> raise their visibility, give credit, and make readers aware that MDN is a wiki

It's definitely a fair reason to have it. If someone has put hard work into an edit, they deserve credit for it. We're proud of our community! But, perhaps there are other ways to do that. The "Document Revision History" exists if an individual wants to demonstrate their contribution on a resume at least. Perhaps there are better ways to celebrate contributions but it's also a delicate thing because celebrations can turn into a gaming thing which is worse. 
For the record, yes, I'm OK with trying this. 
Okay, let's go ahead with this one
❤️ This is a great decision. It has always surprised me how much code we have on the server-side (involving caching, Celery, etc.) just to provide a list of contributors for each document page.

Resolving patch:
diff --git a/kuma/api/tasks.py b/kuma/api/tasks.py
--- a/kuma/api/tasks.py
+++ b/kuma/api/tasks.py
@@ -141,7 +141,7 @@ def publish(doc_pks, log=None, completion_message=None,
                 data = document_api_data(redirect_url=redirect_url)
                 kwargs.update(Body=json.dumps(data))
         else:
-            data = document_api_data(doc, ensure_contributors=True)
+            data = document_api_data(doc)
             kwargs.update(Body=json.dumps(data))
         s3_object = s3_bucket.put_object(**kwargs)
         log.info('Published {!r}'.format(s3_object))
diff --git a/kuma/api/v1/views.py b/kuma/api/v1/views.py
--- a/kuma/api/v1/views.py
+++ b/kuma/api/v1/views.py
@@ -14,7 +14,6 @@
 from kuma.api.v1.serializers import BCSignalSerializer
 from kuma.core.urlresolvers import reverse
 from kuma.users.templatetags.jinja_helpers import gravatar_url
-from kuma.wiki.jobs import DocumentContributorsJob
 from kuma.wiki.models import Document
 from kuma.wiki.search import WikiDocumentType
 from kuma.wiki.templatetags.jinja_helpers import absolutify
@@ -99,7 +98,7 @@ def get_content_based_redirect(document):
     return None
 
 
-def document_api_data(doc=None, ensure_contributors=False, redirect_url=None):
+def document_api_data(doc=None, redirect_url=None):
     """
     Returns the JSON data for the document for the document API.
     """
@@ -109,13 +108,6 @@ def document_api_data(doc=None, ensure_contributors=False, redirect_url=None):
             'redirectURL': redirect_url,
         }
 
-    job = DocumentContributorsJob()
-    # If "ensure_contributors" is True, we need the contributors since the
-    # result will likely be cached, so we'll set "fetch_on_miss" and wait
-    # for the result if it's not already available or stale.
-    job.fetch_on_miss = ensure_contributors
-    contributors = [c['username'] for c in job.get(doc.pk)]
-
     # The original english slug for this document, for google analytics
     if doc.locale == 'en-US':
         en_slug = doc.slug
@@ -129,6 +121,7 @@ def document_api_data(doc=None, ensure_contributors=False, redirect_url=None):
     available_locales = (
         set([doc.locale]) | set(t.locale for t in other_translations))
 
+    doc_absolute_url = doc.get_absolute_url()
     return {
         'documentData': {
             'locale': doc.locale,
@@ -139,8 +132,8 @@ def document_api_data(doc=None, ensure_contributors=False, redirect_url=None):
             'summary': doc.get_summary_html(),
             'language': doc.language,
             'hrefLang': doc.get_hreflang(available_locales),
-            'absoluteURL': doc.get_absolute_url(),
-            'editURL': absolutify(doc.get_edit_url(), for_wiki_site=True),
+            'absoluteURL': doc_absolute_url,
+            'wikiURL': absolutify(doc_absolute_url, for_wiki_site=True),
             'translateURL': (
                 absolutify(
                     reverse(
@@ -172,11 +165,8 @@ def document_api_data(doc=None, ensure_contributors=False, redirect_url=None):
                     'title': t.title
                 } for t in other_translations
             ],
-            'contributors': contributors,
             'lastModified': (doc.current_revision and
                              doc.current_revision.created.isoformat()),
-            'lastModifiedBy': (doc.current_revision and
-                               str(doc.current_revision.creator))
         },
         'redirectURL': None,
     }
diff --git a/kuma/wiki/views/document.py b/kuma/wiki/views/document.py
--- a/kuma/wiki/views/document.py
+++ b/kuma/wiki/views/document.py
@@ -858,7 +858,7 @@ def react_document(request, document_slug, document_locale):
     seo_parent_title = _get_seo_parent_title(doc, slug_dict, document_locale)
 
     # Get the JSON data for this document
-    doc_api_data = document_api_data(doc, ensure_contributors=True)
+    doc_api_data = document_api_data(doc)
     document_data = doc_api_data['documentData']
 
     # Bundle it all up and, finally, return.


Test patch:
diff --git a/kuma/api/tests/test_tasks.py b/kuma/api/tests/test_tasks.py
--- a/kuma/api/tests/test_tasks.py
+++ b/kuma/api/tests/test_tasks.py
@@ -86,7 +86,7 @@ def test_publish_standard(get_s3_bucket_mock, root_doc, invalidate_cdn_cache):
     s3_bucket_mock.put_object.assert_called_once_with(
         ACL='public-read',
         Key=get_s3_key(root_doc),
-        Body=json.dumps(document_api_data(root_doc, ensure_contributors=True)),
+        Body=json.dumps(document_api_data(root_doc)),
         ContentType='application/json',
         ContentLanguage=root_doc.locale
     )
@@ -170,7 +170,7 @@ def test_publish_multiple(get_s3_bucket_mock, root_doc, redirect_doc,
             ACL='public-read',
             Key=get_s3_key(root_doc),
             Body=json.dumps(
-                document_api_data(root_doc, ensure_contributors=True)),
+                document_api_data(root_doc)),
             ContentType='application/json',
             ContentLanguage=root_doc.locale
         ),
diff --git a/kuma/api/v1/tests/test_views.py b/kuma/api/v1/tests/test_views.py
--- a/kuma/api/v1/tests/test_views.py
+++ b/kuma/api/v1/tests/test_views.py
@@ -8,7 +8,6 @@
 from kuma.core.tests import assert_no_cache_header
 from kuma.core.urlresolvers import reverse
 from kuma.users.templatetags.jinja_helpers import gravatar_url
-from kuma.wiki.jobs import DocumentContributorsJob
 from kuma.wiki.templatetags.jinja_helpers import absolutify
 
 
@@ -71,15 +70,8 @@ def test_doc_api_404(client, api_settings, root_doc):
     assert_no_cache_header(response)
 
 
-@pytest.mark.parametrize('ensure_contributors', (True, False))
-def test_doc_api(client, api_settings, trans_doc, cleared_cacheback_cache,
-                 ensure_contributors):
+def test_doc_api(client, api_settings, trans_doc, cleared_cacheback_cache):
     """On success we get document details in a JSON response."""
-    if ensure_contributors:
-        # Pre-populate the cache for the call to document_api_data()
-        # made within the view that serves the "api.v1.doc" endpoint.
-        DocumentContributorsJob().refresh(trans_doc.pk)
-
     url = reverse('api.v1.doc', args=[trans_doc.locale, trans_doc.slug])
     response = client.get(url, HTTP_HOST=api_settings.BETA_HOST)
     assert response.status_code == 200
@@ -96,7 +88,7 @@ def test_doc_api(client, api_settings, trans_doc, cleared_cacheback_cache,
     assert doc_data['language'] == trans_doc.language
     assert doc_data['hrefLang'] == 'fr'
     assert doc_data['absoluteURL'] == trans_doc.get_absolute_url()
-    assert doc_data['editURL'] == absolutify(trans_doc.get_edit_url(),
+    assert doc_data['wikiURL'] == absolutify(trans_doc.get_absolute_url(),
                                              for_wiki_site=True)
     assert doc_data['translateURL'] is None
     assert doc_data['bodyHTML'] == trans_doc.get_body_html()
@@ -110,33 +102,15 @@ def test_doc_api(client, api_settings, trans_doc, cleared_cacheback_cache,
         'title': 'Root Document',
         'url': '/en-US/docs/Root'
     }]
-    assert doc_data['contributors'] == (
-        ['wiki_user'] if ensure_contributors else [])
     assert doc_data['lastModified'] == '2017-04-14T12:20:00'
-    assert doc_data['lastModifiedBy'] == 'wiki_user'
-
-    # Clear the cache for a clean slate when calling document_api_data().
-    DocumentContributorsJob().delete(trans_doc.pk)
-
-    # Also ensure that we get exactly the same data by calling
-    # the document_api_data() function directly
-    assert data == document_api_data(
-        trans_doc, ensure_contributors=ensure_contributors)
 
 
-@pytest.mark.parametrize('ensure_contributors', (True, False))
 def test_doc_api_for_redirect_to_doc(client, api_settings, root_doc,
-                                     redirect_doc, cleared_cacheback_cache,
-                                     ensure_contributors):
+                                     redirect_doc, cleared_cacheback_cache):
     """
     Test the document API when we're requesting data for a document that
     redirects to another document.
     """
-    if ensure_contributors:
-        # Pre-populate the cache for the call to document_api_data()
-        # made within the view that serves the "api.v1.doc" endpoint.
-        DocumentContributorsJob().refresh(root_doc.pk)
-
     url = reverse('api.v1.doc', args=[redirect_doc.locale, redirect_doc.slug])
     response = client.get(url, HTTP_HOST=api_settings.BETA_HOST, follow=True)
     assert response.status_code == 200
@@ -153,7 +127,7 @@ def test_doc_api_for_redirect_to_doc(client, api_settings, root_doc,
     assert doc_data['language'] == root_doc.language
     assert doc_data['hrefLang'] == 'en'
     assert doc_data['absoluteURL'] == root_doc.get_absolute_url()
-    assert doc_data['editURL'] == absolutify(root_doc.get_edit_url(),
+    assert doc_data['wikiURL'] == absolutify(root_doc.get_absolute_url(),
                                              for_wiki_site=True)
     assert doc_data['translateURL'] == absolutify(
         reverse(
@@ -167,18 +141,7 @@ def test_doc_api_for_redirect_to_doc(client, api_settings, root_doc,
     assert doc_data['quickLinksHTML'] == root_doc.get_quick_links_html()
     assert doc_data['tocHTML'] == root_doc.get_toc_html()
     assert doc_data['translations'] == []
-    assert doc_data['contributors'] == (
-        ['wiki_user'] if ensure_contributors else [])
     assert doc_data['lastModified'] == '2017-04-14T12:15:00'
-    assert doc_data['lastModifiedBy'] == 'wiki_user'
-
-    # Clear the cache for a clean slate when calling document_api_data().
-    DocumentContributorsJob().delete(root_doc.pk)
-
-    # Also ensure that we get exactly the same data by calling
-    # the document_api_data() function directly
-    assert data == document_api_data(
-        root_doc, ensure_contributors=ensure_contributors)
 
 
 @pytest.mark.parametrize('case', ('redirect-to-home', 'redirect-to-other'))
diff --git a/kuma/javascript/src/document.test.js b/kuma/javascript/src/document.test.js
--- a/kuma/javascript/src/document.test.js
+++ b/kuma/javascript/src/document.test.js
@@ -20,8 +20,8 @@ export const fakeDocumentData = {
     hrefLang: 'en',
     absoluteURL: '[fake absolute url]',
     translateURL: '[fake translate url]',
-    editURL:
-        'https://wiki.mdn.developer.mozilla.org/en-US/docs/Web/CSS/box-shadow$edit',
+    wikiURL:
+        'https://wiki.mdn.developer.mozilla.org/en-US/docs/Web/CSS/box-shadow',
     bodyHTML: '[fake body HTML]',
     quickLinksHTML: '[fake quicklinks HTML]',
     tocHTML: '[fake TOC HTML]',
@@ -45,9 +45,7 @@ export const fakeDocumentData = {
             title: '[fake spanish translation]'
         }
     ],
-    contributors: ['mike', 'ike'],
-    lastModified: '2019-01-02T03:04:05Z',
-    lastModifiedBy: 'ike'
+    lastModified: '2019-01-02T03:04:05Z'
 };
 
 describe('Document component renders all of its parts', () => {
@@ -106,12 +104,6 @@ describe('Document component renders all of its parts', () => {
         expect(snapshot).toContain(fakeDocumentData.quickLinksHTML);
         expect(snapshot).toContain(fakeDocumentData.bodyHTML);
     });
-
-    test('contributor names appear', () => {
-        for (let c of fakeDocumentData.contributors) {
-            expect(snapshot).toContain(c);
-        }
-    });
 });
 
 describe('DocumentRoute', () => {
diff --git a/kuma/javascript/src/titlebar.test.js b/kuma/javascript/src/titlebar.test.js
--- a/kuma/javascript/src/titlebar.test.js
+++ b/kuma/javascript/src/titlebar.test.js
@@ -51,7 +51,7 @@ describe('Titlebar', () => {
                     title="test"
                     document={{
                         ...fakeDocumentData,
-                        editURL: 'foobar$edit'
+                        wikiURL: 'foobar'
                     }}
                 />
             </UserProvider.context.Provider>
diff --git a/tests/headless/test_endpoints.py b/tests/headless/test_endpoints.py
--- a/tests/headless/test_endpoints.py
+++ b/tests/headless/test_endpoints.py
@@ -131,11 +131,9 @@ def test_hreflang_basic(base_url):
                                                       'tocHTML', 'bodyHTML',
                                                       'id', 'quickLinksHTML',
                                                       'parents', 'translations',
-                                                      'editURL', 'summary',
+                                                      'wikiURL', 'summary',
                                                       'language',
-                                                      'contributors',
                                                       'lastModified',
-                                                      'lastModifiedBy',
                                                       'absoluteURL')),
                                     'redirectURL'))],
     ids=('whoami', 'doc')