launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #26233
[Merge] ~pappacena/launchpad:snap-pillar-ui into launchpad:master
Thiago F. Pappacena has proposed merging ~pappacena/launchpad:snap-pillar-ui into launchpad:master with ~pappacena/launchpad:snap-pillar as a prerequisite.
Commit message:
UI to associate a project pillar to Snaps on +admin view
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
For more details, see:
https://code.launchpad.net/~pappacena/launchpad/+git/launchpad/+merge/397529
--
Your team Launchpad code reviewers is requested to review the proposed merge of ~pappacena/launchpad:snap-pillar-ui into launchpad:master.
diff --git a/lib/lp/snappy/browser/snap.py b/lib/lp/snappy/browser/snap.py
index 3b06a89..eeaecfc 100644
--- a/lib/lp/snappy/browser/snap.py
+++ b/lib/lp/snappy/browser/snap.py
@@ -1,4 +1,4 @@
-# Copyright 2015-2020 Canonical Ltd. This software is licensed under the
+# Copyright 2015-2021 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
"""Snap views."""
@@ -344,6 +344,7 @@ class ISnapEditSchema(Interface):
'owner',
'name',
'private',
+ 'project',
'require_virtualized',
'allow_internet',
'build_source_tarball',
@@ -613,6 +614,7 @@ class BaseSnapEditView(LaunchpadEditFormView, SnapAuthorizeMixin):
def validate(self, data):
super(BaseSnapEditView, self).validate(data)
if data.get('private', self.context.private) is False:
+ # These are the requirements for public snaps.
if 'private' in data or 'owner' in data:
owner = data.get('owner', self.context.owner)
if owner is not None and owner.private:
@@ -631,6 +633,14 @@ class BaseSnapEditView(LaunchpadEditFormView, SnapAuthorizeMixin):
self.setFieldError(
'private' if 'private' in data else 'git_ref',
'A public snap cannot have a private repository.')
+ else:
+ # These are the requirements for private snaps.
+ project = data.get('project', self.context.project)
+ private = data.get('private', self.context.private)
+ if private and project is None:
+ msg = ('Private Snap recipes should be associated '
+ 'with a project.')
+ self.setFieldError('project', msg)
def _needStoreReauth(self, data):
"""Does this change require reauthorizing to the store?"""
@@ -696,7 +706,8 @@ class SnapAdminView(BaseSnapEditView):
page_title = 'Administer'
- field_names = ['private', 'require_virtualized', 'allow_internet']
+ field_names = [
+ 'project', 'private', 'require_virtualized', 'allow_internet']
def validate(self, data):
super(SnapAdminView, self).validate(data)
diff --git a/lib/lp/snappy/browser/tests/test_snap.py b/lib/lp/snappy/browser/tests/test_snap.py
index 3e48162..d5f0c7d 100644
--- a/lib/lp/snappy/browser/tests/test_snap.py
+++ b/lib/lp/snappy/browser/tests/test_snap.py
@@ -661,6 +661,7 @@ class TestSnapAdminView(BaseTestSnapView):
browser = self.getViewBrowser(snap, user=commercial_admin)
browser.getLink("Administer snap package").click()
+ browser.getControl(name='field.project').value = "my-project"
browser.getControl("Require virtualized builders").selected = False
browser.getControl("Private").selected = True
browser.getControl("Allow external network access").selected = False
@@ -671,6 +672,21 @@ class TestSnapAdminView(BaseTestSnapView):
self.assertTrue(snap.private)
self.assertFalse(snap.allow_internet)
+ def test_admin_snap_private_without_project(self):
+ # Cannot make snap private if it doesn't have a project associated.
+ login_person(self.person)
+ snap = self.factory.makeSnap(registrant=self.person)
+ commercial_admin = self.factory.makePerson(
+ member_of=[getUtility(ILaunchpadCelebrities).commercial_admin])
+ browser = self.getViewBrowser(snap, user=commercial_admin)
+ browser.getLink("Administer snap package").click()
+ browser.getControl(name='field.project').value = ''
+ browser.getControl("Private").selected = True
+ browser.getControl("Update snap package").click()
+ self.assertEqual(
+ 'Private Snap recipes should be associated with a project.',
+ extract_text(find_tags_by_class(browser.contents, "message")[1]))
+
def test_admin_snap_privacy_mismatch(self):
# Cannot make snap public if it still contains private information.
login_person(self.person)
diff --git a/lib/lp/snappy/interfaces/snap.py b/lib/lp/snappy/interfaces/snap.py
index e17e224..8aa065c 100644
--- a/lib/lp/snappy/interfaces/snap.py
+++ b/lib/lp/snappy/interfaces/snap.py
@@ -670,7 +670,7 @@ class ISnapEditableAttributes(IHasOwner):
description=_("The owner of this snap package.")))
project = ReferenceChoice(
- title=_('The project that this Snap is associated with.'),
+ title=_('The project that this Snap is associated with'),
schema=IProduct, vocabulary='Product',
required=False, readonly=False)
@@ -884,7 +884,7 @@ class ISnapSet(Interface):
"git_repository", "git_repository_url", "git_path", "git_ref",
"auto_build", "auto_build_archive", "auto_build_pocket",
"private", "store_upload", "store_series", "store_name",
- "store_channels"])
+ "store_channels", "project"])
@operation_for_version("devel")
def new(registrant, owner, distro_series, name, description=None,
branch=None, git_repository=None, git_repository_url=None,
Follow ups