Merge lp:~cjwatson/launchpad/codeimport-git-configure-code into lp:launchpad
- codeimport-git-configure-code
- Merge into devel
Proposed by
Colin Watson
Status: | Merged |
---|---|
Merged at revision: | 18260 |
Proposed branch: | lp:~cjwatson/launchpad/codeimport-git-configure-code |
Merge into: | lp:launchpad |
Prerequisite: | lp:~cjwatson/launchpad/codeimport-git-refactor-name-validation |
Diff against target: |
745 lines (+335/-120) 6 files modified
lib/lp/code/javascript/productseries-setbranch.js (+26/-16) lib/lp/code/javascript/tests/test_productseries-setbranch.html (+1/-1) lib/lp/code/templates/configure-code.pt (+41/-14) lib/lp/registry/browser/product.py (+197/-83) lib/lp/registry/browser/tests/productseries-setbranch-view.txt (+3/-3) lib/lp/registry/browser/tests/test_product.py (+67/-3) |
To merge this branch: | bzr merge lp:~cjwatson/launchpad/codeimport-git-configure-code |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
William Grant | code | Approve | |
Review via email: mp+308577@code.launchpad.net |
Commit message
Extend Product:
Description of the change
To post a comment you must log in.
Revision history for this message
William Grant (wgrant) : | # |
review:
Approve
(code)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/code/javascript/productseries-setbranch.js' | |||
2 | --- lib/lp/code/javascript/productseries-setbranch.js 2015-06-25 07:39:40 +0000 | |||
3 | +++ lib/lp/code/javascript/productseries-setbranch.js 2016-11-11 14:59:36 +0000 | |||
4 | @@ -87,32 +87,39 @@ | |||
5 | 87 | module.onclick_branch_type = function(e) { | 87 | module.onclick_branch_type = function(e) { |
6 | 88 | /* Which branch type radio button was selected? */ | 88 | /* Which branch type radio button was selected? */ |
7 | 89 | var selectedRCS = module._get_selected_rcs(); | 89 | var selectedRCS = module._get_selected_rcs(); |
17 | 90 | var types = document.getElementsByName('field.branch_type'); | 90 | var type_node = Y.one('input[name="field.branch_type"]:checked'); |
18 | 91 | var type = 'None'; | 91 | var type = (type_node === null) ? 'None' : type_node.get('value'); |
10 | 92 | var i; | ||
11 | 93 | for (i = 0; i < types.length; i++) { | ||
12 | 94 | if (types[i].checked) { | ||
13 | 95 | type = types[i].value; | ||
14 | 96 | break; | ||
15 | 97 | } | ||
16 | 98 | } | ||
19 | 99 | // Linked | 92 | // Linked |
24 | 100 | module.set_enabled('field.branch_location', type === 'link-lp-bzr'); | 93 | module.set_enabled('field.branch_location', type === 'link-lp'); |
25 | 101 | module.set_enabled('field.branch_name', type !== 'link-lp-bzr'); | 94 | module.set_enabled('field.branch_name', type !== 'link-lp'); |
26 | 102 | module.set_enabled('field.branch_owner', type !== 'link-lp-bzr'); | 95 | module.set_enabled('field.branch_owner', type !== 'link-lp'); |
23 | 103 | // New, empty branch. | ||
27 | 104 | // Import | 96 | // Import |
28 | 105 | var is_external = (type === 'import-external'); | 97 | var is_external = (type === 'import-external'); |
29 | 106 | module.set_enabled('field.repo_url', is_external); | 98 | module.set_enabled('field.repo_url', is_external); |
30 | 107 | module.set_enabled('field.cvs_module', | 99 | module.set_enabled('field.cvs_module', |
31 | 108 | (is_external & selectedRCS === 'CVS')); | 100 | (is_external & selectedRCS === 'CVS')); |
32 | 109 | var rcs_types = module._rcs_types(); | 101 | var rcs_types = module._rcs_types(); |
36 | 110 | var j; | 102 | var i; |
37 | 111 | for (j = 0; j < rcs_types.length; j++) { | 103 | for (i = 0; i < rcs_types.length; i++) { |
38 | 112 | rcs_types[j].disabled = !is_external; | 104 | rcs_types[i].disabled = !is_external; |
39 | 113 | } | 105 | } |
40 | 114 | }; | 106 | }; |
41 | 115 | 107 | ||
42 | 108 | module.onclick_git_repository_type = function(e) { | ||
43 | 109 | /* Which Git repository type radio button was selected? */ | ||
44 | 110 | var type_node = Y.one( | ||
45 | 111 | 'input[name="field.git_repository_type"]:checked'); | ||
46 | 112 | var type = (type_node === null) ? 'None' : type_node.get('value'); | ||
47 | 113 | // Linked | ||
48 | 114 | module.set_enabled( | ||
49 | 115 | 'field.git_repository_location', type === 'link-lp'); | ||
50 | 116 | module.set_enabled('field.git_repository_name', type !== 'link-lp'); | ||
51 | 117 | module.set_enabled('field.git_repository_owner', type !== 'link-lp'); | ||
52 | 118 | // Import | ||
53 | 119 | var is_external = (type === 'import-external'); | ||
54 | 120 | module.set_enabled('field.git_repository_url', is_external); | ||
55 | 121 | }; | ||
56 | 122 | |||
57 | 116 | module.setup = function() { | 123 | module.setup = function() { |
58 | 117 | Y.all('input[name="field.rcs_type"]').on( | 124 | Y.all('input[name="field.rcs_type"]').on( |
59 | 118 | 'click', module.onclick_rcs_type); | 125 | 'click', module.onclick_rcs_type); |
60 | @@ -120,6 +127,8 @@ | |||
61 | 120 | 'click', module.onclick_branch_type); | 127 | 'click', module.onclick_branch_type); |
62 | 121 | Y.all('input[name="field.default_vcs"]').on( | 128 | Y.all('input[name="field.default_vcs"]').on( |
63 | 122 | 'click', module.onclick_default_vcs); | 129 | 'click', module.onclick_default_vcs); |
64 | 130 | Y.all('input[name="field.git_repository_type"]').on( | ||
65 | 131 | 'click', module.onclick_git_repository_type); | ||
66 | 123 | 132 | ||
67 | 124 | // Set the initial state. | 133 | // Set the initial state. |
68 | 125 | module.onclick_rcs_type(); | 134 | module.onclick_rcs_type(); |
69 | @@ -128,6 +137,7 @@ | |||
70 | 128 | if (document.getElementById('default_vcs')) { | 137 | if (document.getElementById('default_vcs')) { |
71 | 129 | module.setup_expanders(); | 138 | module.setup_expanders(); |
72 | 130 | module.onclick_default_vcs(); | 139 | module.onclick_default_vcs(); |
73 | 140 | module.onclick_git_repository_type(); | ||
74 | 131 | } | 141 | } |
75 | 132 | }; | 142 | }; |
76 | 133 | 143 | ||
77 | 134 | 144 | ||
78 | === modified file 'lib/lp/code/javascript/tests/test_productseries-setbranch.html' | |||
79 | --- lib/lp/code/javascript/tests/test_productseries-setbranch.html 2012-10-26 09:54:28 +0000 | |||
80 | +++ lib/lp/code/javascript/tests/test_productseries-setbranch.html 2016-11-11 14:59:36 +0000 | |||
81 | @@ -61,7 +61,7 @@ | |||
82 | 61 | <label> | 61 | <label> |
83 | 62 | <input class="radioType" checked="checked" | 62 | <input class="radioType" checked="checked" |
84 | 63 | id="field.branch_type.0" | 63 | id="field.branch_type.0" |
86 | 64 | name="field.branch_type" type="radio" value="link-lp-bzr" /> | 64 | name="field.branch_type" type="radio" value="link-lp" /> |
87 | 65 | Link to a Bazaar branch already in Launchpad | 65 | Link to a Bazaar branch already in Launchpad |
88 | 66 | </label> | 66 | </label> |
89 | 67 | <table> | 67 | <table> |
90 | 68 | 68 | ||
91 | === modified file 'lib/lp/code/templates/configure-code.pt' | |||
92 | --- lib/lp/code/templates/configure-code.pt 2016-04-28 02:09:21 +0000 | |||
93 | +++ lib/lp/code/templates/configure-code.pt 2016-11-11 14:59:36 +0000 | |||
94 | @@ -51,10 +51,10 @@ | |||
95 | 51 | <div metal:use-macro="context/@@+configure-code-macros/no-keys"></div> | 51 | <div metal:use-macro="context/@@+configure-code-macros/no-keys"></div> |
96 | 52 | </div> | 52 | </div> |
97 | 53 | 53 | ||
98 | 54 | <h3>Link or import an existing branch</h3> | ||
99 | 54 | <table id="form_bzr" class="form"> | 55 | <table id="form_bzr" class="form"> |
100 | 55 | <tr> | 56 | <tr> |
101 | 56 | <td> | 57 | <td> |
102 | 57 | <h3>Link or import an existing branch</h3> | ||
103 | 58 | <label tal:replace="structure view/branch_type_link"> | 58 | <label tal:replace="structure view/branch_type_link"> |
104 | 59 | Link to a Bazaar branch already on Launchpad | 59 | Link to a Bazaar branch already on Launchpad |
105 | 60 | </label> | 60 | </label> |
106 | @@ -133,20 +133,47 @@ | |||
107 | 133 | <span class="sprite gitbranch">Git settings</span> | 133 | <span class="sprite gitbranch">Git settings</span> |
108 | 134 | </a> | 134 | </a> |
109 | 135 | <div id="git-expander-content"> | 135 | <div id="git-expander-content"> |
123 | 136 | <div id="form_git" class="form"> | 136 | <div class="push-instructions"> |
124 | 137 | <div class="push-instructions"> | 137 | <div metal:use-macro="context/@@+configure-code-macros/push-instructions-git"></div> |
125 | 138 | <div metal:use-macro="context/@@+configure-code-macros/push-instructions-git"></div> | 138 | <div metal:use-macro="context/@@+configure-code-macros/no-keys"></div> |
113 | 139 | <div metal:use-macro="context/@@+configure-code-macros/no-keys"></div> | ||
114 | 140 | </div> | ||
115 | 141 | |||
116 | 142 | <h3>Link an existing repository</h3> | ||
117 | 143 | <p>Link to an existing Git repository already on Launchpad</p> | ||
118 | 144 | <table> | ||
119 | 145 | <tal:widget define="widget nocall:view/widgets/git_repository_location"> | ||
120 | 146 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> | ||
121 | 147 | </tal:widget> | ||
122 | 148 | </table> | ||
126 | 149 | </div> | 139 | </div> |
127 | 140 | |||
128 | 141 | <h3>Link or import an existing repository</h3> | ||
129 | 142 | <table id="form_git" class="form"> | ||
130 | 143 | <tr> | ||
131 | 144 | <td> | ||
132 | 145 | <label tal:replace="structure view/git_repository_type_link"> | ||
133 | 146 | Link to a Git repository already on Launchpad | ||
134 | 147 | </label> | ||
135 | 148 | <table class="subordinate"> | ||
136 | 149 | <tal:widget define="widget nocall:view/widgets/git_repository_location"> | ||
137 | 150 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> | ||
138 | 151 | </tal:widget> | ||
139 | 152 | </table> | ||
140 | 153 | </td> | ||
141 | 154 | </tr> | ||
142 | 155 | |||
143 | 156 | <tr id="git_mirror" | ||
144 | 157 | tal:condition="request/features/code.import.git_target"> | ||
145 | 158 | <td> | ||
146 | 159 | <label tal:replace="structure view/git_repository_type_import"> | ||
147 | 160 | Import a repository hosted somewhere else | ||
148 | 161 | </label> | ||
149 | 162 | <table class="subordinate"> | ||
150 | 163 | <tal:widget define="widget nocall:view/widgets/git_repository_name"> | ||
151 | 164 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> | ||
152 | 165 | </tal:widget> | ||
153 | 166 | <tal:widget define="widget nocall:view/widgets/git_repository_owner"> | ||
154 | 167 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> | ||
155 | 168 | </tal:widget> | ||
156 | 169 | |||
157 | 170 | <tal:widget define="widget nocall:view/widgets/git_repository_url"> | ||
158 | 171 | <metal:block use-macro="context/@@launchpad_form/widget_row" /> | ||
159 | 172 | </tal:widget> | ||
160 | 173 | </table> | ||
161 | 174 | </td> | ||
162 | 175 | </tr> | ||
163 | 176 | </table> | ||
164 | 150 | </div> | 177 | </div> |
165 | 151 | </div> | 178 | </div> |
166 | 152 | </tal:block> | 179 | </tal:block> |
167 | 153 | 180 | ||
168 | === modified file 'lib/lp/registry/browser/product.py' | |||
169 | --- lib/lp/registry/browser/product.py 2016-10-15 13:41:19 +0000 | |||
170 | +++ lib/lp/registry/browser/product.py 2016-11-11 14:59:36 +0000 | |||
171 | @@ -151,14 +151,20 @@ | |||
172 | 151 | RevisionControlSystems, | 151 | RevisionControlSystems, |
173 | 152 | TargetRevisionControlSystems, | 152 | TargetRevisionControlSystems, |
174 | 153 | ) | 153 | ) |
176 | 154 | from lp.code.errors import BranchExists | 154 | from lp.code.errors import ( |
177 | 155 | BranchExists, | ||
178 | 156 | GitRepositoryExists, | ||
179 | 157 | ) | ||
180 | 155 | from lp.code.interfaces.branch import IBranch | 158 | from lp.code.interfaces.branch import IBranch |
181 | 156 | from lp.code.interfaces.branchjob import IRosettaUploadJobSource | 159 | from lp.code.interfaces.branchjob import IRosettaUploadJobSource |
182 | 157 | from lp.code.interfaces.codeimport import ( | 160 | from lp.code.interfaces.codeimport import ( |
183 | 158 | ICodeImport, | 161 | ICodeImport, |
184 | 159 | ICodeImportSet, | 162 | ICodeImportSet, |
185 | 160 | ) | 163 | ) |
187 | 161 | from lp.code.interfaces.gitrepository import IGitRepositorySet | 164 | from lp.code.interfaces.gitrepository import ( |
188 | 165 | IGitRepository, | ||
189 | 166 | IGitRepositorySet, | ||
190 | 167 | ) | ||
191 | 162 | from lp.registry.browser import ( | 168 | from lp.registry.browser import ( |
192 | 163 | add_subscribe_link, | 169 | add_subscribe_link, |
193 | 164 | BaseRdfView, | 170 | BaseRdfView, |
194 | @@ -1658,18 +1664,26 @@ | |||
195 | 1658 | return BatchNavigator(decorated_result, self.request) | 1664 | return BatchNavigator(decorated_result, self.request) |
196 | 1659 | 1665 | ||
197 | 1660 | 1666 | ||
199 | 1661 | LINK_LP_BZR = 'link-lp-bzr' | 1667 | LINK_LP = 'link-lp' |
200 | 1662 | IMPORT_EXTERNAL = 'import-external' | 1668 | IMPORT_EXTERNAL = 'import-external' |
201 | 1663 | 1669 | ||
202 | 1664 | 1670 | ||
203 | 1665 | BRANCH_TYPE_VOCABULARY = SimpleVocabulary(( | 1671 | BRANCH_TYPE_VOCABULARY = SimpleVocabulary(( |
205 | 1666 | SimpleTerm(LINK_LP_BZR, LINK_LP_BZR, | 1672 | SimpleTerm(LINK_LP, LINK_LP, |
206 | 1667 | _("Link to a Bazaar branch already on Launchpad")), | 1673 | _("Link to a Bazaar branch already on Launchpad")), |
207 | 1668 | SimpleTerm(IMPORT_EXTERNAL, IMPORT_EXTERNAL, | 1674 | SimpleTerm(IMPORT_EXTERNAL, IMPORT_EXTERNAL, |
208 | 1669 | _("Import a branch hosted somewhere else")), | 1675 | _("Import a branch hosted somewhere else")), |
209 | 1670 | )) | 1676 | )) |
210 | 1671 | 1677 | ||
211 | 1672 | 1678 | ||
212 | 1679 | GIT_REPOSITORY_TYPE_VOCABULARY = SimpleVocabulary(( | ||
213 | 1680 | SimpleTerm(LINK_LP, LINK_LP, | ||
214 | 1681 | _("Link to a Git repository already on Launchpad")), | ||
215 | 1682 | SimpleTerm(IMPORT_EXTERNAL, IMPORT_EXTERNAL, | ||
216 | 1683 | _("Import a Git repository hosted somewhere else")), | ||
217 | 1684 | )) | ||
218 | 1685 | |||
219 | 1686 | |||
220 | 1673 | class SetBranchForm(Interface): | 1687 | class SetBranchForm(Interface): |
221 | 1674 | """The fields presented on the form for setting a branch.""" | 1688 | """The fields presented on the form for setting a branch.""" |
222 | 1675 | 1689 | ||
223 | @@ -1696,7 +1710,7 @@ | |||
224 | 1696 | 1710 | ||
225 | 1697 | branch_type = Choice( | 1711 | branch_type = Choice( |
226 | 1698 | title=_('Import type'), vocabulary=BRANCH_TYPE_VOCABULARY, | 1712 | title=_('Import type'), vocabulary=BRANCH_TYPE_VOCABULARY, |
228 | 1699 | description=_("The type of import"), required=True) | 1713 | description=_("Whether the branch is imported"), required=True) |
229 | 1700 | 1714 | ||
230 | 1701 | branch_name = copy_field( | 1715 | branch_name = copy_field( |
231 | 1702 | IBranch['name'], __name__='branch_name', title=_('Branch name'), | 1716 | IBranch['name'], __name__='branch_name', title=_('Branch name'), |
232 | @@ -1706,23 +1720,37 @@ | |||
233 | 1706 | IBranch['owner'], __name__='branch_owner', title=_('Branch owner'), | 1720 | IBranch['owner'], __name__='branch_owner', title=_('Branch owner'), |
234 | 1707 | description=_(''), required=True) | 1721 | description=_(''), required=True) |
235 | 1708 | 1722 | ||
253 | 1709 | 1723 | default_vcs = Choice( | |
254 | 1710 | def create_git_fields(): | 1724 | title=_("Project VCS"), required=True, vocabulary=VCSType, |
255 | 1711 | return form.Fields( | 1725 | description=_("The version control system for this project.")) |
256 | 1712 | Choice(__name__='default_vcs', | 1726 | |
257 | 1713 | title=_("Project VCS"), | 1727 | git_repository_location = Choice( |
258 | 1714 | required=True, vocabulary=VCSType, | 1728 | title=_('Git repository'), required=False, |
259 | 1715 | description=_("The version control system for " | 1729 | vocabulary='GitRepositoryRestrictedOnProduct', |
260 | 1716 | "this project.")), | 1730 | description=_( |
261 | 1717 | Choice(__name__='git_repository_location', | 1731 | "The Git repository for this project in Launchpad, " |
262 | 1718 | title=_('Git repository'), | 1732 | "if one exists, in the form: " |
263 | 1719 | required=False, | 1733 | "~user/project-name/+git/repo-name")) |
264 | 1720 | vocabulary='GitRepositoryRestrictedOnProduct', | 1734 | |
265 | 1721 | description=_( | 1735 | git_repository_type = Choice( |
266 | 1722 | "The Git repository for this project in Launchpad, " | 1736 | title=_('Import type'), required=True, |
267 | 1723 | "if one exists, in the form: " | 1737 | vocabulary=GIT_REPOSITORY_TYPE_VOCABULARY, |
268 | 1724 | "~user/project-name/+git/repo-name")) | 1738 | description=_('Whether the repository is imported')) |
269 | 1725 | ) | 1739 | |
270 | 1740 | git_repository_name = copy_field( | ||
271 | 1741 | IGitRepository['name'], __name__='git_repository_name', | ||
272 | 1742 | title=_('Git repository name'), description=_(''), required=True) | ||
273 | 1743 | |||
274 | 1744 | git_repository_owner = copy_field( | ||
275 | 1745 | IGitRepository['owner'], __name__='git_repository_owner', | ||
276 | 1746 | title=_('Git repository owner'), description=_(''), required=True) | ||
277 | 1747 | |||
278 | 1748 | git_repository_url = URIField( | ||
279 | 1749 | title=_('Git repository URL'), required=True, | ||
280 | 1750 | description=_('The URL of the Git repository.'), | ||
281 | 1751 | allowed_schemes=["git", "http", "https"], | ||
282 | 1752 | allow_userinfo=True, allow_port=True, allow_query=False, | ||
283 | 1753 | allow_fragment=False, trailing_slash=False) | ||
284 | 1726 | 1754 | ||
285 | 1727 | 1755 | ||
286 | 1728 | class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView, | 1756 | class ProductSetBranchView(ReturnToReferrerMixin, LaunchpadFormView, |
287 | @@ -1740,6 +1768,7 @@ | |||
288 | 1740 | custom_widget('rcs_type', LaunchpadRadioWidget) | 1768 | custom_widget('rcs_type', LaunchpadRadioWidget) |
289 | 1741 | custom_widget('branch_type', LaunchpadRadioWidget) | 1769 | custom_widget('branch_type', LaunchpadRadioWidget) |
290 | 1742 | custom_widget('default_vcs', LaunchpadRadioWidget) | 1770 | custom_widget('default_vcs', LaunchpadRadioWidget) |
291 | 1771 | custom_widget('git_repository_type', LaunchpadRadioWidget) | ||
292 | 1743 | 1772 | ||
293 | 1744 | errors_in_action = False | 1773 | errors_in_action = False |
294 | 1745 | is_series = False | 1774 | is_series = False |
295 | @@ -1754,8 +1783,9 @@ | |||
296 | 1754 | return dict( | 1783 | return dict( |
297 | 1755 | rcs_type=RevisionControlSystems.BZR, | 1784 | rcs_type=RevisionControlSystems.BZR, |
298 | 1756 | default_vcs=(self.context.pillar.inferred_vcs or VCSType.BZR), | 1785 | default_vcs=(self.context.pillar.inferred_vcs or VCSType.BZR), |
300 | 1757 | branch_type=LINK_LP_BZR, | 1786 | branch_type=LINK_LP, |
301 | 1758 | branch_location=self.series.branch, | 1787 | branch_location=self.series.branch, |
302 | 1788 | git_repository_type=LINK_LP, | ||
303 | 1759 | git_repository_location=repository_set.getDefaultRepository( | 1789 | git_repository_location=repository_set.getDefaultRepository( |
304 | 1760 | self.context.pillar)) | 1790 | self.context.pillar)) |
305 | 1761 | 1791 | ||
306 | @@ -1781,8 +1811,11 @@ | |||
307 | 1781 | def setUpFields(self): | 1811 | def setUpFields(self): |
308 | 1782 | """See `LaunchpadFormView`.""" | 1812 | """See `LaunchpadFormView`.""" |
309 | 1783 | super(ProductSetBranchView, self).setUpFields() | 1813 | super(ProductSetBranchView, self).setUpFields() |
312 | 1784 | if not self.is_series: | 1814 | if self.is_series: |
313 | 1785 | self.form_fields = (self.form_fields + create_git_fields()) | 1815 | self.form_fields = self.form_fields.omit( |
314 | 1816 | 'default_vcs', 'git_repository_location', | ||
315 | 1817 | 'git_repository_type', 'git_repository_name', | ||
316 | 1818 | 'git_repository_owner', 'git_repository_url') | ||
317 | 1786 | 1819 | ||
318 | 1787 | def setUpWidgets(self): | 1820 | def setUpWidgets(self): |
319 | 1788 | """See `LaunchpadFormView`.""" | 1821 | """See `LaunchpadFormView`.""" |
320 | @@ -1803,11 +1836,9 @@ | |||
321 | 1803 | widget = self.widgets['branch_type'] | 1836 | widget = self.widgets['branch_type'] |
322 | 1804 | current_value = widget._getFormValue() | 1837 | current_value = widget._getFormValue() |
323 | 1805 | vocab = widget.vocabulary | 1838 | vocab = widget.vocabulary |
327 | 1806 | 1839 | self.branch_type_link, self.branch_type_import = [ | |
325 | 1807 | (self.branch_type_link, | ||
326 | 1808 | self.branch_type_import) = [ | ||
328 | 1809 | render_radio_widget_part(widget, value, current_value) | 1840 | render_radio_widget_part(widget, value, current_value) |
330 | 1810 | for value in (LINK_LP_BZR, IMPORT_EXTERNAL)] | 1841 | for value in (LINK_LP, IMPORT_EXTERNAL)] |
331 | 1811 | 1842 | ||
332 | 1812 | if not self.is_series: | 1843 | if not self.is_series: |
333 | 1813 | widget = self.widgets['default_vcs'] | 1844 | widget = self.widgets['default_vcs'] |
334 | @@ -1818,14 +1849,21 @@ | |||
335 | 1818 | self.default_vcs_bzr = render_radio_widget_part( | 1849 | self.default_vcs_bzr = render_radio_widget_part( |
336 | 1819 | widget, vocab.BZR, current_value, 'Bazaar') | 1850 | widget, vocab.BZR, current_value, 'Bazaar') |
337 | 1820 | 1851 | ||
338 | 1852 | widget = self.widgets['git_repository_type'] | ||
339 | 1853 | current_value = widget._getFormValue() | ||
340 | 1854 | vocab = widget.vocabulary | ||
341 | 1855 | self.git_repository_type_link, self.git_repository_type_import = [ | ||
342 | 1856 | render_radio_widget_part(widget, value, current_value) | ||
343 | 1857 | for value in (LINK_LP, IMPORT_EXTERNAL)] | ||
344 | 1858 | |||
345 | 1821 | def _validateLinkLpBzr(self, data): | 1859 | def _validateLinkLpBzr(self, data): |
347 | 1822 | """Validate data for link-lp-bzr case.""" | 1860 | """Validate data for link-lp bzr case.""" |
348 | 1823 | if 'branch_location' not in data: | 1861 | if 'branch_location' not in data: |
349 | 1824 | self.setFieldError( | 1862 | self.setFieldError( |
350 | 1825 | 'branch_location', 'The branch location must be set.') | 1863 | 'branch_location', 'The branch location must be set.') |
351 | 1826 | 1864 | ||
352 | 1827 | def _validateLinkLpGit(self, data): | 1865 | def _validateLinkLpGit(self, data): |
354 | 1828 | """Validate data for link-lp-git case.""" | 1866 | """Validate data for link-lp git case.""" |
355 | 1829 | if data.get('git_repository_location'): | 1867 | if data.get('git_repository_location'): |
356 | 1830 | repo = data.get('git_repository_location') | 1868 | repo = data.get('git_repository_location') |
357 | 1831 | if not repo: | 1869 | if not repo: |
358 | @@ -1833,8 +1871,8 @@ | |||
359 | 1833 | 'git_repository_location', | 1871 | 'git_repository_location', |
360 | 1834 | 'The repository does not exist.') | 1872 | 'The repository does not exist.') |
361 | 1835 | 1873 | ||
364 | 1836 | def _validateImportExternal(self, data): | 1874 | def _validateImportExternalBzr(self, data): |
365 | 1837 | """Validate data for import external case.""" | 1875 | """Validate data for import-external bzr case.""" |
366 | 1838 | rcs_type = data.get('rcs_type') | 1876 | rcs_type = data.get('rcs_type') |
367 | 1839 | repo_url = data.get('repo_url') | 1877 | repo_url = data.get('repo_url') |
368 | 1840 | 1878 | ||
369 | @@ -1864,15 +1902,41 @@ | |||
370 | 1864 | elif rcs_type == RevisionControlSystems.CVS: | 1902 | elif rcs_type == RevisionControlSystems.CVS: |
371 | 1865 | if 'cvs_module' not in data: | 1903 | if 'cvs_module' not in data: |
372 | 1866 | self.setFieldError('cvs_module', 'The CVS module must be set.') | 1904 | self.setFieldError('cvs_module', 'The CVS module must be set.') |
373 | 1867 | self._validateBranch(data) | ||
374 | 1868 | 1905 | ||
375 | 1869 | def _validateBranch(self, data): | ||
376 | 1870 | """Validate that branch name and owner are set.""" | ||
377 | 1871 | if 'branch_name' not in data: | 1906 | if 'branch_name' not in data: |
378 | 1872 | self.setFieldError('branch_name', 'The branch name must be set.') | 1907 | self.setFieldError('branch_name', 'The branch name must be set.') |
379 | 1873 | if 'branch_owner' not in data: | 1908 | if 'branch_owner' not in data: |
380 | 1874 | self.setFieldError('branch_owner', 'The branch owner must be set.') | 1909 | self.setFieldError('branch_owner', 'The branch owner must be set.') |
381 | 1875 | 1910 | ||
382 | 1911 | def _validateImportExternalGit(self, data): | ||
383 | 1912 | """Validate data for import-external git case.""" | ||
384 | 1913 | git_repository_url = data.get('git_repository_url') | ||
385 | 1914 | |||
386 | 1915 | # Private teams are forbidden from owning code imports. | ||
387 | 1916 | git_repository_owner = data.get('git_repository_owner') | ||
388 | 1917 | if git_repository_owner is not None and git_repository_owner.private: | ||
389 | 1918 | self.setFieldError( | ||
390 | 1919 | 'git_repository_owner', | ||
391 | 1920 | 'Private teams are forbidden from owning external imports.') | ||
392 | 1921 | |||
393 | 1922 | if git_repository_url is None: | ||
394 | 1923 | self.setFieldError( | ||
395 | 1924 | 'git_repository_url', | ||
396 | 1925 | 'You must set the external repository URL.') | ||
397 | 1926 | else: | ||
398 | 1927 | reason = validate_import_url( | ||
399 | 1928 | git_repository_url, RevisionControlSystems.GIT, | ||
400 | 1929 | TargetRevisionControlSystems.GIT) | ||
401 | 1930 | if reason: | ||
402 | 1931 | self.setFieldError('git_repository_url', reason) | ||
403 | 1932 | |||
404 | 1933 | if 'git_repository_name' not in data: | ||
405 | 1934 | self.setFieldError( | ||
406 | 1935 | 'git_repository_name', 'The repository name must be set.') | ||
407 | 1936 | if 'git_repository_owner' not in data: | ||
408 | 1937 | self.setFieldError( | ||
409 | 1938 | 'git_repository_owner', 'The repository owner must be set.') | ||
410 | 1939 | |||
411 | 1876 | def _setRequired(self, names, value): | 1940 | def _setRequired(self, names, value): |
412 | 1877 | """Mark the widget field as optional.""" | 1941 | """Mark the widget field as optional.""" |
413 | 1878 | for name in names: | 1942 | for name in names: |
414 | @@ -1897,11 +1961,25 @@ | |||
415 | 1897 | 1961 | ||
416 | 1898 | def validate_widgets(self, data, names=None): | 1962 | def validate_widgets(self, data, names=None): |
417 | 1899 | """See `LaunchpadFormView`.""" | 1963 | """See `LaunchpadFormView`.""" |
419 | 1900 | names = ['branch_type', 'rcs_type', 'default_vcs'] | 1964 | names = [ |
420 | 1965 | 'branch_type', 'rcs_type', 'default_vcs', 'git_repository_type'] | ||
421 | 1901 | super(ProductSetBranchView, self).validate_widgets(data, names) | 1966 | super(ProductSetBranchView, self).validate_widgets(data, names) |
422 | 1967 | |||
423 | 1968 | if not self.is_series: | ||
424 | 1969 | git_repository_type = data.get('git_repository_type') | ||
425 | 1970 | if git_repository_type == LINK_LP: | ||
426 | 1971 | # Mark other widgets as non-required. | ||
427 | 1972 | self._setRequired(['git_repository_url', 'git_repository_name', | ||
428 | 1973 | 'git_repository_owner'], False) | ||
429 | 1974 | elif git_repository_type == IMPORT_EXTERNAL: | ||
430 | 1975 | # The repository location is not required for validation. | ||
431 | 1976 | self._setRequired(['git_repository_location'], False) | ||
432 | 1977 | else: | ||
433 | 1978 | raise AssertionError( | ||
434 | 1979 | "Unknown Git repository type %s" % git_repository_type) | ||
435 | 1980 | |||
436 | 1902 | branch_type = data.get('branch_type') | 1981 | branch_type = data.get('branch_type') |
439 | 1903 | 1982 | if branch_type == LINK_LP: | |
438 | 1904 | if branch_type == LINK_LP_BZR: | ||
440 | 1905 | # Mark other widgets as non-required. | 1983 | # Mark other widgets as non-required. |
441 | 1906 | self._setRequired(['rcs_type', 'repo_url', 'cvs_module', | 1984 | self._setRequired(['rcs_type', 'repo_url', 'cvs_module', |
442 | 1907 | 'branch_name', 'branch_owner'], False) | 1985 | 'branch_name', 'branch_owner'], False) |
443 | @@ -1918,6 +1996,7 @@ | |||
444 | 1918 | self._setRequired(['cvs_module'], True) | 1996 | self._setRequired(['cvs_module'], True) |
445 | 1919 | else: | 1997 | else: |
446 | 1920 | raise AssertionError("Unknown branch type %s" % branch_type) | 1998 | raise AssertionError("Unknown branch type %s" % branch_type) |
447 | 1999 | |||
448 | 1921 | # Perform full validation now. | 2000 | # Perform full validation now. |
449 | 1922 | super(ProductSetBranchView, self).validate_widgets(data) | 2001 | super(ProductSetBranchView, self).validate_widgets(data) |
450 | 1923 | 2002 | ||
451 | @@ -1927,13 +2006,22 @@ | |||
452 | 1927 | # continue as we'd likely just override the errors reported there. | 2006 | # continue as we'd likely just override the errors reported there. |
453 | 1928 | if len(self.errors) > 0: | 2007 | if len(self.errors) > 0: |
454 | 1929 | return | 2008 | return |
455 | 2009 | |||
456 | 2010 | if not self.is_series: | ||
457 | 2011 | git_repository_type = data.get('git_repository_type') | ||
458 | 2012 | if git_repository_type == LINK_LP: | ||
459 | 2013 | self._validateLinkLpGit(data) | ||
460 | 2014 | elif git_repository_type == IMPORT_EXTERNAL: | ||
461 | 2015 | self._validateImportExternalGit(data) | ||
462 | 2016 | else: | ||
463 | 2017 | raise AssertionError( | ||
464 | 2018 | "Unknown Git repository type %s" % git_repository_type) | ||
465 | 2019 | |||
466 | 1930 | branch_type = data.get('branch_type') | 2020 | branch_type = data.get('branch_type') |
472 | 1931 | if not self.is_series: | 2021 | if branch_type == LINK_LP: |
468 | 1932 | self._validateLinkLpGit(data) | ||
469 | 1933 | if branch_type == IMPORT_EXTERNAL: | ||
470 | 1934 | self._validateImportExternal(data) | ||
471 | 1935 | elif branch_type == LINK_LP_BZR: | ||
473 | 1936 | self._validateLinkLpBzr(data) | 2022 | self._validateLinkLpBzr(data) |
474 | 2023 | elif branch_type == IMPORT_EXTERNAL: | ||
475 | 2024 | self._validateImportExternalBzr(data) | ||
476 | 1937 | else: | 2025 | else: |
477 | 1938 | raise AssertionError("Unknown branch type %s" % branch_type) | 2026 | raise AssertionError("Unknown branch type %s" % branch_type) |
478 | 1939 | 2027 | ||
479 | @@ -1959,54 +2047,80 @@ | |||
480 | 1959 | if default_vcs: | 2047 | if default_vcs: |
481 | 1960 | self.context.vcs = default_vcs | 2048 | self.context.vcs = default_vcs |
482 | 1961 | 2049 | ||
487 | 1962 | repo = data.get('git_repository_location') | 2050 | git_repository_type = data.get('git_repository_type') |
488 | 1963 | getUtility(IGitRepositorySet).setDefaultRepository( | 2051 | |
489 | 1964 | self.context, repo) | 2052 | if git_repository_type == LINK_LP: |
490 | 1965 | if branch_type == LINK_LP_BZR: | 2053 | repo = data.get('git_repository_location') |
491 | 2054 | repository_set = getUtility(IGitRepositorySet) | ||
492 | 2055 | if repository_set.getDefaultRepository(self.context) != repo: | ||
493 | 2056 | repository_set.setDefaultRepository(self.context, repo) | ||
494 | 2057 | self.add_update_notification() | ||
495 | 2058 | elif git_repository_type == IMPORT_EXTERNAL: | ||
496 | 2059 | name = data.get('git_repository_name') | ||
497 | 2060 | owner = data.get('git_repository_owner') | ||
498 | 2061 | url = data.get('git_repository_url') | ||
499 | 2062 | try: | ||
500 | 2063 | code_import = getUtility(ICodeImportSet).new( | ||
501 | 2064 | owner=owner, | ||
502 | 2065 | registrant=self.user, | ||
503 | 2066 | context=self.context, | ||
504 | 2067 | branch_name=name, | ||
505 | 2068 | rcs_type=RevisionControlSystems.GIT, | ||
506 | 2069 | target_rcs_type=TargetRevisionControlSystems.GIT, | ||
507 | 2070 | url=url) | ||
508 | 2071 | except GitRepositoryExists as e: | ||
509 | 2072 | self._setBranchExists( | ||
510 | 2073 | e.existing_repository, 'git_repository_name') | ||
511 | 2074 | self.abort_update() | ||
512 | 2075 | return | ||
513 | 2076 | getUtility(IGitRepositorySet).setDefaultRepository( | ||
514 | 2077 | self.context, code_import.git_repository) | ||
515 | 2078 | self.request.response.addInfoNotification( | ||
516 | 2079 | 'Code import created and repository set as default.') | ||
517 | 2080 | else: | ||
518 | 2081 | raise UnexpectedFormData(git_repository_type) | ||
519 | 2082 | |||
520 | 2083 | if branch_type == LINK_LP: | ||
521 | 1966 | branch_location = data.get('branch_location') | 2084 | branch_location = data.get('branch_location') |
522 | 1967 | if branch_location != self.series.branch: | 2085 | if branch_location != self.series.branch: |
523 | 1968 | self.series.branch = branch_location | 2086 | self.series.branch = branch_location |
524 | 1969 | # Request an initial upload of translation files. | 2087 | # Request an initial upload of translation files. |
525 | 1970 | getUtility(IRosettaUploadJobSource).create( | 2088 | getUtility(IRosettaUploadJobSource).create( |
526 | 1971 | self.series.branch, NULL_REVISION) | 2089 | self.series.branch, NULL_REVISION) |
531 | 1972 | else: | 2090 | self.add_update_notification() |
532 | 1973 | self.series.branch = branch_location | 2091 | elif branch_type == IMPORT_EXTERNAL: |
529 | 1974 | self.add_update_notification() | ||
530 | 1975 | else: | ||
533 | 1976 | branch_name = data.get('branch_name') | 2092 | branch_name = data.get('branch_name') |
534 | 1977 | branch_owner = data.get('branch_owner') | 2093 | branch_owner = data.get('branch_owner') |
565 | 1978 | 2094 | rcs_type = data.get('rcs_type') | |
566 | 1979 | if branch_type == IMPORT_EXTERNAL: | 2095 | if rcs_type == RevisionControlSystems.CVS: |
567 | 1980 | rcs_type = data.get('rcs_type') | 2096 | cvs_root = data.get('repo_url') |
568 | 1981 | if rcs_type == RevisionControlSystems.CVS: | 2097 | cvs_module = data.get('cvs_module') |
569 | 1982 | cvs_root = data.get('repo_url') | 2098 | url = None |
540 | 1983 | cvs_module = data.get('cvs_module') | ||
541 | 1984 | url = None | ||
542 | 1985 | else: | ||
543 | 1986 | cvs_root = None | ||
544 | 1987 | cvs_module = None | ||
545 | 1988 | url = data.get('repo_url') | ||
546 | 1989 | rcs_item = RevisionControlSystems.items[rcs_type.name] | ||
547 | 1990 | try: | ||
548 | 1991 | code_import = getUtility(ICodeImportSet).new( | ||
549 | 1992 | owner=branch_owner, | ||
550 | 1993 | registrant=self.user, | ||
551 | 1994 | context=self.context, | ||
552 | 1995 | branch_name=branch_name, | ||
553 | 1996 | rcs_type=rcs_item, | ||
554 | 1997 | target_rcs_type=TargetRevisionControlSystems.BZR, | ||
555 | 1998 | url=url, | ||
556 | 1999 | cvs_root=cvs_root, | ||
557 | 2000 | cvs_module=cvs_module) | ||
558 | 2001 | except BranchExists as e: | ||
559 | 2002 | self._setBranchExists(e.existing_branch, 'branch_name') | ||
560 | 2003 | self.abort_update() | ||
561 | 2004 | return | ||
562 | 2005 | self.series.branch = code_import.branch | ||
563 | 2006 | self.request.response.addInfoNotification( | ||
564 | 2007 | 'Code import created and branch linked to the series.') | ||
570 | 2008 | else: | 2099 | else: |
572 | 2009 | raise UnexpectedFormData(branch_type) | 2100 | cvs_root = None |
573 | 2101 | cvs_module = None | ||
574 | 2102 | url = data.get('repo_url') | ||
575 | 2103 | rcs_item = RevisionControlSystems.items[rcs_type.name] | ||
576 | 2104 | try: | ||
577 | 2105 | code_import = getUtility(ICodeImportSet).new( | ||
578 | 2106 | owner=branch_owner, | ||
579 | 2107 | registrant=self.user, | ||
580 | 2108 | context=self.context, | ||
581 | 2109 | branch_name=branch_name, | ||
582 | 2110 | rcs_type=rcs_item, | ||
583 | 2111 | target_rcs_type=TargetRevisionControlSystems.BZR, | ||
584 | 2112 | url=url, | ||
585 | 2113 | cvs_root=cvs_root, | ||
586 | 2114 | cvs_module=cvs_module) | ||
587 | 2115 | except BranchExists as e: | ||
588 | 2116 | self._setBranchExists(e.existing_branch, 'branch_name') | ||
589 | 2117 | self.abort_update() | ||
590 | 2118 | return | ||
591 | 2119 | self.series.branch = code_import.branch | ||
592 | 2120 | self.request.response.addInfoNotification( | ||
593 | 2121 | 'Code import created and branch linked to the series.') | ||
594 | 2122 | else: | ||
595 | 2123 | raise UnexpectedFormData(branch_type) | ||
596 | 2010 | 2124 | ||
597 | 2011 | 2125 | ||
598 | 2012 | class ProductRdfView(BaseRdfView): | 2126 | class ProductRdfView(BaseRdfView): |
599 | 2013 | 2127 | ||
600 | === modified file 'lib/lp/registry/browser/tests/productseries-setbranch-view.txt' | |||
601 | --- lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2016-10-15 13:41:19 +0000 | |||
602 | +++ lib/lp/registry/browser/tests/productseries-setbranch-view.txt 2016-11-11 14:59:36 +0000 | |||
603 | @@ -39,7 +39,7 @@ | |||
604 | 39 | must be provided. | 39 | must be provided. |
605 | 40 | 40 | ||
606 | 41 | >>> form = { | 41 | >>> form = { |
608 | 42 | ... 'field.branch_type': 'link-lp-bzr', | 42 | ... 'field.branch_type': 'link-lp', |
609 | 43 | ... 'field.actions.update': 'Update', | 43 | ... 'field.actions.update': 'Update', |
610 | 44 | ... } | 44 | ... } |
611 | 45 | >>> view = create_initialized_view( | 45 | >>> view = create_initialized_view( |
612 | @@ -52,7 +52,7 @@ | |||
613 | 52 | validation error. | 52 | validation error. |
614 | 53 | 53 | ||
615 | 54 | >>> form = { | 54 | >>> form = { |
617 | 55 | ... 'field.branch_type': 'link-lp-bzr', | 55 | ... 'field.branch_type': 'link-lp', |
618 | 56 | ... 'field.branch_location': 'foo', | 56 | ... 'field.branch_location': 'foo', |
619 | 57 | ... 'field.actions.update': 'Update', | 57 | ... 'field.actions.update': 'Update', |
620 | 58 | ... } | 58 | ... } |
621 | @@ -69,7 +69,7 @@ | |||
622 | 69 | >>> branch = factory.makeBranch( | 69 | >>> branch = factory.makeBranch( |
623 | 70 | ... name='impala-branch', owner=driver, product=product) | 70 | ... name='impala-branch', owner=driver, product=product) |
624 | 71 | >>> form = { | 71 | >>> form = { |
626 | 72 | ... 'field.branch_type': 'link-lp-bzr', | 72 | ... 'field.branch_type': 'link-lp', |
627 | 73 | ... 'field.branch_location': branch.unique_name, | 73 | ... 'field.branch_location': branch.unique_name, |
628 | 74 | ... 'field.actions.update': 'Update', | 74 | ... 'field.actions.update': 'Update', |
629 | 75 | ... } | 75 | ... } |
630 | 76 | 76 | ||
631 | === modified file 'lib/lp/registry/browser/tests/test_product.py' | |||
632 | --- lib/lp/registry/browser/tests/test_product.py 2016-09-19 11:47:33 +0000 | |||
633 | +++ lib/lp/registry/browser/tests/test_product.py 2016-11-11 14:59:36 +0000 | |||
634 | @@ -30,7 +30,10 @@ | |||
635 | 30 | InformationType, | 30 | InformationType, |
636 | 31 | ServiceUsage, | 31 | ServiceUsage, |
637 | 32 | ) | 32 | ) |
638 | 33 | from lp.code.enums import RevisionControlSystems | ||
639 | 34 | from lp.code.interfaces.codeimport import CODE_IMPORT_GIT_TARGET_FEATURE_FLAG | ||
640 | 33 | from lp.code.interfaces.gitrepository import IGitRepositorySet | 35 | from lp.code.interfaces.gitrepository import IGitRepositorySet |
641 | 36 | from lp.code.tests.helpers import GitHostingFixture | ||
642 | 34 | from lp.registry.browser.product import ( | 37 | from lp.registry.browser.product import ( |
643 | 35 | ProjectAddStepOne, | 38 | ProjectAddStepOne, |
644 | 36 | ProjectAddStepTwo, | 39 | ProjectAddStepTwo, |
645 | @@ -47,6 +50,7 @@ | |||
646 | 47 | from lp.registry.model.product import Product | 50 | from lp.registry.model.product import Product |
647 | 48 | from lp.services.config import config | 51 | from lp.services.config import config |
648 | 49 | from lp.services.database.interfaces import IStore | 52 | from lp.services.database.interfaces import IStore |
649 | 53 | from lp.services.features.testing import FeatureFixture | ||
650 | 50 | from lp.services.webapp.publisher import canonical_url | 54 | from lp.services.webapp.publisher import canonical_url |
651 | 51 | from lp.services.webapp.vhosts import allvhosts | 55 | from lp.services.webapp.vhosts import allvhosts |
652 | 52 | from lp.testing import ( | 56 | from lp.testing import ( |
653 | @@ -914,7 +918,7 @@ | |||
654 | 914 | # control defaults to empty. | 918 | # control defaults to empty. |
655 | 915 | project = self.factory.makeProduct() | 919 | project = self.factory.makeProduct() |
656 | 916 | browser = self.getBrowser(project, '+configure-code') | 920 | browser = self.getBrowser(project, '+configure-code') |
658 | 917 | self.assertEqual('', browser.getControl('Git repository').value) | 921 | self.assertEqual('', browser.getControl('Git repository:').value) |
659 | 918 | 922 | ||
660 | 919 | def test_initial_git_repository(self): | 923 | def test_initial_git_repository(self): |
661 | 920 | # If a project has a default Git repository, its "Git repository" | 924 | # If a project has a default Git repository, its "Git repository" |
662 | @@ -926,14 +930,16 @@ | |||
663 | 926 | unique_name = repo.unique_name | 930 | unique_name = repo.unique_name |
664 | 927 | browser = self.getBrowser(project, '+configure-code') | 931 | browser = self.getBrowser(project, '+configure-code') |
665 | 928 | self.assertEqual( | 932 | self.assertEqual( |
667 | 929 | unique_name, browser.getControl('Git repository').value) | 933 | unique_name, browser.getControl('Git repository:').value) |
668 | 930 | 934 | ||
669 | 931 | def test_link_existing_git_repository(self): | 935 | def test_link_existing_git_repository(self): |
670 | 932 | repo = removeSecurityProxy(self.factory.makeGitRepository( | 936 | repo = removeSecurityProxy(self.factory.makeGitRepository( |
671 | 933 | target=self.factory.makeProduct())) | 937 | target=self.factory.makeProduct())) |
672 | 934 | browser = self.getBrowser(repo.project, '+configure-code') | 938 | browser = self.getBrowser(repo.project, '+configure-code') |
673 | 935 | browser.getControl('Git', index=0).click() | 939 | browser.getControl('Git', index=0).click() |
675 | 936 | browser.getControl('Git repository').value = repo.shortened_path | 940 | self.assertTrue(browser.getControl( |
676 | 941 | 'Link to a Git repository already on Launchpad').selected) | ||
677 | 942 | browser.getControl('Git repository:').value = repo.shortened_path | ||
678 | 937 | browser.getControl('Update').click() | 943 | browser.getControl('Update').click() |
679 | 938 | 944 | ||
680 | 939 | tag = Tag( | 945 | tag = Tag( |
681 | @@ -941,6 +947,64 @@ | |||
682 | 941 | text='Project settings updated.') | 947 | text='Project settings updated.') |
683 | 942 | self.assertThat(browser.contents, HTMLContains(tag)) | 948 | self.assertThat(browser.contents, HTMLContains(tag)) |
684 | 943 | 949 | ||
685 | 950 | def test_import_git_repository_requires_feature_flag(self): | ||
686 | 951 | project = self.factory.makeProduct() | ||
687 | 952 | browser = self.getBrowser(project, '+configure-code') | ||
688 | 953 | self.assertRaises( | ||
689 | 954 | LookupError, browser.getControl, | ||
690 | 955 | 'Import a Git repository hosted somewhere else') | ||
691 | 956 | |||
692 | 957 | def test_import_git_repository(self): | ||
693 | 958 | self.useFixture( | ||
694 | 959 | FeatureFixture({CODE_IMPORT_GIT_TARGET_FEATURE_FLAG: u'on'})) | ||
695 | 960 | self.useFixture(GitHostingFixture()) | ||
696 | 961 | owner = self.factory.makePerson() | ||
697 | 962 | project = self.factory.makeProduct(owner=owner) | ||
698 | 963 | browser = self.getBrowser(project, '+configure-code') | ||
699 | 964 | browser.getControl('Git', index=0).click() | ||
700 | 965 | browser.getControl( | ||
701 | 966 | 'Import a Git repository hosted somewhere else').click() | ||
702 | 967 | browser.getControl('Git repository name').value = 'imported' | ||
703 | 968 | browser.getControl('Git repository URL').value = ( | ||
704 | 969 | 'https://git.example.org/imported') | ||
705 | 970 | browser.getControl('Update').click() | ||
706 | 971 | |||
707 | 972 | tag = Tag( | ||
708 | 973 | 'success-div', 'div', attrs={'class': 'informational message'}, | ||
709 | 974 | text='Code import created and repository set as default.') | ||
710 | 975 | self.assertThat(browser.contents, HTMLContains(tag)) | ||
711 | 976 | login_person(owner) | ||
712 | 977 | repo = getUtility(IGitRepositorySet).getDefaultRepository(project) | ||
713 | 978 | self.assertIsNotNone(repo.code_import) | ||
714 | 979 | self.assertEqual(RevisionControlSystems.GIT, repo.code_import.rcs_type) | ||
715 | 980 | self.assertEqual( | ||
716 | 981 | 'https://git.example.org/imported', repo.code_import.url) | ||
717 | 982 | |||
718 | 983 | def test_import_git_repository_bad_scheme(self): | ||
719 | 984 | self.useFixture( | ||
720 | 985 | FeatureFixture({CODE_IMPORT_GIT_TARGET_FEATURE_FLAG: u'on'})) | ||
721 | 986 | owner = self.factory.makePerson() | ||
722 | 987 | project = self.factory.makeProduct(owner=owner) | ||
723 | 988 | browser = self.getBrowser(project, '+configure-code') | ||
724 | 989 | browser.getControl('Git', index=0).click() | ||
725 | 990 | browser.getControl( | ||
726 | 991 | 'Import a Git repository hosted somewhere else').click() | ||
727 | 992 | browser.getControl('Git repository name').value = 'imported' | ||
728 | 993 | browser.getControl('Git repository URL').value = ( | ||
729 | 994 | 'svn://svn.example.org/imported') | ||
730 | 995 | browser.getControl('Update').click() | ||
731 | 996 | |||
732 | 997 | tag = Tag( | ||
733 | 998 | 'error', 'div', attrs={'class': 'message'}, | ||
734 | 999 | text=( | ||
735 | 1000 | 'The URI scheme "svn" is not allowed. ' | ||
736 | 1001 | 'Only URIs with the following schemes may be used: ' | ||
737 | 1002 | 'git, http, https')) | ||
738 | 1003 | self.assertThat(browser.contents, HTMLContains(tag)) | ||
739 | 1004 | login_person(owner) | ||
740 | 1005 | self.assertIsNone( | ||
741 | 1006 | getUtility(IGitRepositorySet).getDefaultRepository(project)) | ||
742 | 1007 | |||
743 | 944 | def test_editsshkeys_link_if_no_keys_registered(self): | 1008 | def test_editsshkeys_link_if_no_keys_registered(self): |
744 | 945 | project = self.factory.makeProduct() | 1009 | project = self.factory.makeProduct() |
745 | 946 | browser = self.getBrowser(project, '+configure-code') | 1010 | browser = self.getBrowser(project, '+configure-code') |