← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~jcsackett/launchpad/no-questions-on-disabled into lp:launchpad

 

j.c.sackett has proposed merging lp:~jcsackett/launchpad/no-questions-on-disabled into lp:launchpad.

Commit message:
Updates addquestion UI to indicate when questions is not enabled.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~jcsackett/launchpad/no-questions-on-disabled/+merge/138360

Summary
=======
We don't want questions to be asked on private products, because there is no
concept of a private question and answers cannot be enabled for private
projects. The addquestion UI is not aware of service usage, and can still be
accessed via simply hacking together the +addquestion url.

We should do the same thing +filebug does, and indicate that answers is not
enabled, and if the user has the permission to do, let them go change that.

As LAUNCHPAD is not an option for private projects, this will still not allow
a user to create a leak.

Preimp
======
Spoke with Rick Harding.

Implementation
==============
The addquestion view gets a new method that checks if answes is enabled. If
its not, the ui is altered to display a message similar to the one shown by
+filebug if malone is not enabled.

Tests
=====
bin/test -vvct test_context_uses_answers

QA
==
Go to +addquestion on a product with answers disabled. You should see the
message indicating you cannot ask a question.

LoC
===
Part of private projects.

Lint
====

Checking for conflicts and issues in changed files.

Linting changed files:
  lib/lp/answers/browser/tests/test_question.py
  lib/lp/answers/templates/question-add-search.pt
  lib/lp/answers/browser/question.py
-- 
https://code.launchpad.net/~jcsackett/launchpad/no-questions-on-disabled/+merge/138360
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~jcsackett/launchpad/no-questions-on-disabled into lp:launchpad.
=== modified file 'lib/lp/answers/browser/question.py'
--- lib/lp/answers/browser/question.py	2012-11-26 08:40:20 +0000
+++ lib/lp/answers/browser/question.py	2012-12-06 02:17:22 +0000
@@ -85,11 +85,15 @@
     safe_action,
     )
 from lp.app.browser.stringformatter import FormattersAPI
+from lp.app.enums import ServiceUsage
 from lp.app.errors import (
     NotFoundError,
     UnexpectedFormData,
     )
-from lp.app.interfaces.launchpad import ILaunchpadCelebrities
+from lp.app.interfaces.launchpad import (
+    ILaunchpadCelebrities,
+    IServiceUsage,
+    )
 from lp.app.widgets.itemswidgets import LaunchpadRadioWidget
 from lp.app.widgets.launchpadtarget import LaunchpadTargetWidget
 from lp.app.widgets.project import ProjectScopeWidget
@@ -641,6 +645,14 @@
         """Return True if similar FAQs or questions were found."""
         return self.similar_questions or self.similar_faqs
 
+    @property
+    def context_uses_answers(self):
+        """Return True if the context uses launchpad as an answer forum."""
+        if IServiceUsage.providedBy(self.context):
+            return self.context.answers_usage == ServiceUsage.LAUNCHPAD
+        else:
+            return False
+
     @action(_('Continue'))
     def continue_action(self, action, data):
         """Search for questions and FAQs similar to the entered summary."""

=== modified file 'lib/lp/answers/browser/tests/test_question.py'
--- lib/lp/answers/browser/tests/test_question.py	2012-01-01 02:58:52 +0000
+++ lib/lp/answers/browser/tests/test_question.py	2012-12-06 02:17:22 +0000
@@ -7,12 +7,16 @@
 
 __all__ = []
 
+from zope.security.proxy import removeSecurityProxy
 from lp.answers.browser.question import QuestionTargetWidget
 from lp.answers.interfaces.question import IQuestion
 from lp.answers.publisher import AnswersLayer
+from lp.app.enums import ServiceUsage
 from lp.services.webapp.servers import LaunchpadTestRequest
 from lp.testing import (
     login_person,
+    logout,
+    person_logged_in,
     TestCaseWithFactory,
     )
 from lp.testing.layers import DatabaseFunctionalLayer
@@ -55,6 +59,20 @@
         self.assertEqual(
             'The summary cannot exceed 250 characters.', view.errors[0])
 
+    def test_context_uses_answers(self):
+        # If a target doesn't use answers, it doesn't provide the form.
+        #logout()
+        owner = removeSecurityProxy(self.question_target).owner
+        with person_logged_in(owner):
+            self.question_target.answers_usage = ServiceUsage.NOT_APPLICABLE
+        login_person(self.user)
+        view = create_initialized_view(
+            self.question_target, name='+addquestion', layer=AnswersLayer,
+            principal=self.user)
+        self.assertFalse(view.context_uses_answers)
+        contents = view.render()
+        msg = "<strong>does not use</strong> Launchpad as its answer forum"
+        self.assertIn(msg, contents)
 
 class QuestionEditViewTestCase(TestCaseWithFactory):
     """Verify the behavior of the QuestionEditView."""

=== modified file 'lib/lp/answers/templates/question-add-search.pt'
--- lib/lp/answers/templates/question-add-search.pt	2009-08-19 16:48:37 +0000
+++ lib/lp/answers/templates/question-add-search.pt	2012-12-06 02:17:22 +0000
@@ -13,6 +13,7 @@
 <body>
 
 <metal:main fill-slot="main">
+  <tal:answers_enabled condition="view/context_uses_answers">
   <metal:form use-macro="context/@@launchpad_form/form">
 
     <div metal:fill-slot="extra_info">
@@ -38,6 +39,18 @@
     </div>
 
   </metal:form>
+  </tal:answers_enabled>
+
+  <tal:answers_disabled condition="not: view/context_uses_answers">
+      <div class="highlight-message">
+        <a tal:replace="structure context/fmt:link">Alsa Utils</a>
+        <strong>does not use</strong> Launchpad as its answer forum.
+        <a tal:attributes="href context/menu:overview/configure_answers/fmt:url"
+           tal:condition="context/required:launchpad.Edit">
+          Change this <span class="sprite edit action-icon">Edit</span>
+        </a>
+      </div>
+  </tal:answers_disabled>
 </metal:main>
 
 </body>


Follow ups