Skip to content

Commit ee5ffd0

Browse files
authored
Merge pull request readthedocs#5404 from saadmk11/subproject-alias
Don't allow to create subprojects with same alias
2 parents 511741c + d173aa9 commit ee5ffd0

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

readthedocs/projects/forms.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,17 @@ def clean_child(self):
378378
)
379379
return child
380380

381+
def clean_alias(self):
382+
alias = self.cleaned_data['alias']
383+
subproject = self.project.subprojects.filter(
384+
alias=alias).exclude(id=self.instance.pk)
385+
386+
if subproject.exists():
387+
raise forms.ValidationError(
388+
_('A subproject with this alias already exists'),
389+
)
390+
return alias
391+
381392
def get_subproject_queryset(self):
382393
"""
383394
Return scrubbed subproject choice queryset.

readthedocs/rtd_tests/tests/test_subprojects.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ def test_adding_subproject_fails_when_user_is_not_admin(self):
6565
form.errors['child'][0],
6666
r'Select a valid choice.',
6767
)
68+
self.assertEqual(
69+
[proj_id for (proj_id, __) in form.fields['child'].choices],
70+
[''],
71+
)
6872

6973
def test_adding_subproject_passes_when_user_is_admin(self):
7074
user = fixture.get(User)
@@ -161,6 +165,45 @@ def test_exclude_self_project_as_subproject(self):
161165
[proj_id for (proj_id, __) in form.fields['child'].choices],
162166
)
163167

168+
def test_alias_already_exists_for_a_project(self):
169+
user = fixture.get(User)
170+
project = fixture.get(Project, users=[user])
171+
subproject = fixture.get(Project, users=[user])
172+
subproject_2 = fixture.get(Project, users=[user])
173+
relation = fixture.get(
174+
ProjectRelationship, parent=project, child=subproject,
175+
alias='subproject'
176+
)
177+
form = ProjectRelationshipForm(
178+
{
179+
'child': subproject_2.id,
180+
'alias': 'subproject'
181+
},
182+
project=project,
183+
user=user,
184+
)
185+
self.assertFalse(form.is_valid())
186+
error_msg = 'A subproject with this alias already exists'
187+
self.assertDictEqual(form.errors, {'alias': [error_msg]})
188+
189+
def test_edit_only_lists_instance_project_in_child_choices(self):
190+
user = fixture.get(User)
191+
project = fixture.get(Project, users=[user])
192+
subproject = fixture.get(Project, users=[user])
193+
relation = fixture.get(
194+
ProjectRelationship, parent=project, child=subproject,
195+
alias='subproject'
196+
)
197+
form = ProjectRelationshipForm(
198+
instance=relation,
199+
project=project,
200+
user=user,
201+
)
202+
self.assertEqual(
203+
[proj_id for (proj_id, __) in form.fields['child'].choices],
204+
['', relation.child.id],
205+
)
206+
164207

165208
@override_settings(PUBLIC_DOMAIN='readthedocs.org')
166209
class ResolverBase(TestCase):
@@ -172,12 +215,12 @@ def setUp(self):
172215
self.pip = fixture.get(Project, slug='pip', users=[self.owner], main_language_project=None)
173216
self.subproject = fixture.get(
174217
Project, slug='sub', language='ja',
175-
users=[ self.owner],
218+
users=[self.owner],
176219
main_language_project=None,
177220
)
178221
self.translation = fixture.get(
179222
Project, slug='trans', language='ja',
180-
users=[ self.owner],
223+
users=[self.owner],
181224
main_language_project=None,
182225
)
183226
self.pip.add_subproject(self.subproject)

0 commit comments

Comments
 (0)