Merge ~pappacena/launchpad:ocirecipe-privacy-banners-ui into launchpad:master

Proposed by Thiago F. Pappacena
Status: Merged
Approved by: Thiago F. Pappacena
Approved revision: af9e3397acba20b15017ae373d10c963e685e042
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~pappacena/launchpad:ocirecipe-privacy-banners-ui
Merge into: launchpad:master
Prerequisite: ~pappacena/launchpad:ocirecipe-subscribe-removal-job
Diff against target: 148 lines (+64/-1)
5 files modified
lib/lp/oci/browser/configure.zcml (+6/-0)
lib/lp/oci/browser/ocirecipe.py (+8/-0)
lib/lp/oci/browser/tests/test_ocirecipe.py (+44/-1)
lib/lp/oci/interfaces/ocirecipe.py (+5/-0)
lib/lp/oci/templates/ocirecipe-index.pt (+1/-0)
Reviewer Review Type Date Requested Status
Colin Watson (community) Approve
Review via email: mp+399987@code.launchpad.net

Commit message

Showing private top banner on private OCI recipes pages

To post a comment you must log in.
Revision history for this message
Colin Watson (cjwatson) :
review: Approve
Revision history for this message
Thiago F. Pappacena (pappacena) :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/oci/browser/configure.zcml b/lib/lp/oci/browser/configure.zcml
2index 53db0d2..31dcbc9 100644
3--- a/lib/lp/oci/browser/configure.zcml
4+++ b/lib/lp/oci/browser/configure.zcml
5@@ -27,6 +27,12 @@
6 for="lp.oci.interfaces.ocirecipe.IOCIRecipe"
7 class="lp.oci.browser.ocirecipe.OCIRecipeView"
8 permission="launchpad.View"
9+ name="+portlet-privacy"
10+ template="../templates/ocirecipe-portlet-privacy.pt"/>
11+ <browser:page
12+ for="lp.oci.interfaces.ocirecipe.IOCIRecipe"
13+ class="lp.oci.browser.ocirecipe.OCIRecipeView"
14+ permission="launchpad.View"
15 name="+index"
16 template="../templates/ocirecipe-index.pt" />
17 <browser:page
18diff --git a/lib/lp/oci/browser/ocirecipe.py b/lib/lp/oci/browser/ocirecipe.py
19index 5eee7e3..4f0a3d9 100644
20--- a/lib/lp/oci/browser/ocirecipe.py
21+++ b/lib/lp/oci/browser/ocirecipe.py
22@@ -239,6 +239,10 @@ class OCIProjectRecipesView(LaunchpadView):
23 class OCIRecipeView(LaunchpadView):
24 """Default view of an OCI recipe."""
25
26+ @property
27+ def private(self):
28+ return self.context.private
29+
30 @cachedproperty
31 def builds(self):
32 return builds_for_recipe(self.context)
33@@ -958,6 +962,10 @@ class BaseOCIRecipeEditView(LaunchpadEditFormView):
34 schema = IOCIRecipeEditSchema
35
36 @property
37+ def private(self):
38+ return self.context.private
39+
40+ @property
41 def cancel_url(self):
42 """See `LaunchpadFormView`."""
43 return canonical_url(self.context)
44diff --git a/lib/lp/oci/browser/tests/test_ocirecipe.py b/lib/lp/oci/browser/tests/test_ocirecipe.py
45index cf16757..8d42903 100644
46--- a/lib/lp/oci/browser/tests/test_ocirecipe.py
47+++ b/lib/lp/oci/browser/tests/test_ocirecipe.py
48@@ -89,6 +89,7 @@ from lp.testing.matchers import (
49 from lp.testing.pages import (
50 extract_text,
51 find_main_content,
52+ find_tag_by_id,
53 find_tags_by_class,
54 )
55 from lp.testing.publication import test_traverse
56@@ -599,6 +600,19 @@ class TestOCIRecipeEditView(OCIConfigHelperMixin, BaseTestOCIRecipeView):
57 for name in disabled])
58 self.assertThat(processors_control.controls, MatchesSetwise(*matchers))
59
60+ def test_edit_private_recipe_shows_banner(self):
61+ recipe = self.factory.makeOCIRecipe(
62+ registrant=self.person, owner=self.person,
63+ information_type=InformationType.USERDATA)
64+ browser = self.getViewBrowser(recipe, user=self.person)
65+ browser.getLink("Edit OCI recipe").click()
66+ banners = find_tags_by_class(
67+ browser.contents, "private_banner_container")
68+ self.assertEqual(1, len(banners))
69+ self.assertEqual(
70+ 'The information on this page is private.',
71+ extract_text(banners[0]))
72+
73 def test_edit_recipe(self):
74 oci_project = self.factory.makeOCIProject()
75 oci_project_display = oci_project.display_name
76@@ -1187,6 +1201,9 @@ class TestOCIRecipeView(BaseTestOCIRecipeView):
77 build = self.makeBuild(
78 recipe=recipe, status=BuildStatus.FULLYBUILT,
79 duration=timedelta(minutes=30))
80+
81+ browser = self.getViewBrowser(build.recipe)
82+ login_person(self.person)
83 self.assertTextMatchesExpressionIgnoreWhitespace("""\
84 %s OCI project
85 recipe-name
86@@ -1204,7 +1221,33 @@ class TestOCIRecipeView(BaseTestOCIRecipeView):
87 Status When complete Architecture
88 Successfully built 30 minutes ago 386
89 """ % (oci_project_name, oci_project_display, recipe.build_path),
90- self.getMainText(build.recipe))
91+ extract_text(find_main_content(browser.contents)))
92+
93+ # Check portlet on side menu.
94+ privacy_tag = find_tag_by_id(browser.contents, "privacy")
95+ self.assertTextMatchesExpressionIgnoreWhitespace(
96+ "This OCI recipe contains Public information",
97+ extract_text(privacy_tag))
98+
99+ def test_index_for_private_recipe_shows_banner(self):
100+ recipe = self.factory.makeOCIRecipe(
101+ registrant=self.person, owner=self.person,
102+ information_type=InformationType.USERDATA)
103+ browser = self.getViewBrowser(recipe, user=self.person)
104+
105+ # Check top banner.
106+ banners = find_tags_by_class(
107+ browser.contents, "private_banner_container")
108+ self.assertEqual(1, len(banners))
109+ self.assertTextMatchesExpressionIgnoreWhitespace(
110+ 'The information on this page is private.',
111+ extract_text(banners[0]))
112+
113+ # Check portlet on side menu.
114+ privacy_tag = find_tag_by_id(browser.contents, "privacy")
115+ self.assertTextMatchesExpressionIgnoreWhitespace(
116+ "This OCI recipe contains Private information",
117+ extract_text(privacy_tag))
118
119 def test_index_with_build_args(self):
120 oci_project = self.factory.makeOCIProject(
121diff --git a/lib/lp/oci/interfaces/ocirecipe.py b/lib/lp/oci/interfaces/ocirecipe.py
122index 80db054..41e3ab4 100644
123--- a/lib/lp/oci/interfaces/ocirecipe.py
124+++ b/lib/lp/oci/interfaces/ocirecipe.py
125@@ -241,6 +241,11 @@ class IOCIRecipeView(Interface):
126 description=_("True if this recipe is official for its OCI project."),
127 readonly=True)
128
129+ private = Bool(
130+ title=_("Is this OCI recipe private?"),
131+ required=True, readonly=True,
132+ description=_("True if this recipe is private. False otherwise."))
133+
134 pillar = Attribute('The pillar of this OCI recipe.')
135
136 @call_with(check_permissions=True, user=REQUEST_USER)
137diff --git a/lib/lp/oci/templates/ocirecipe-index.pt b/lib/lp/oci/templates/ocirecipe-index.pt
138index 315973c..5a1f3c1 100644
139--- a/lib/lp/oci/templates/ocirecipe-index.pt
140+++ b/lib/lp/oci/templates/ocirecipe-index.pt
141@@ -18,6 +18,7 @@
142 </metal:registering>
143
144 <metal:side fill-slot="side">
145+ <div tal:replace="structure context/@@+portlet-privacy" />
146 <div tal:replace="structure context/@@+global-actions"/>
147 <tal:subscribers replace="structure context/@@+portlet-subscribers" />
148 </metal:side>