diff --git a/pagure/internal/__init__.py b/pagure/internal/__init__.py index f336a7b..6c881a9 100644 --- a/pagure/internal/__init__.py +++ b/pagure/internal/__init__.py @@ -688,3 +688,50 @@ def get_stats_commits_trend(): 'task_id': task.id, } ) + + +@PV.route('//family', methods=['POST']) +@PV.route('///family', methods=['POST']) +@PV.route('/fork///family', methods=['POST']) +@PV.route('/fork////family', + methods=['POST']) +def get_project_family(repo, namespace=None, username=None): + """ Return the family of projects for the specified project + + { + code: 'OK', + family: [ + ] + } + """ + form = pagure.forms.ConfirmationForm() + if not form.validate_on_submit(): + response = flask.jsonify({ + 'code': 'ERROR', + 'message': 'Invalid input submitted', + }) + response.status_code = 400 + return response + + repo = pagure.lib.get_authorized_project( + flask.g.session, repo, user=username, namespace=namespace) + + if not repo: + response = flask.jsonify({ + 'code': 'ERROR', + 'message': 'No repo found with the information provided', + }) + response.status_code = 404 + return response + + family = [ + p.url_path for p in + pagure.lib.get_project_family(flask.g.session, repo) + ] + + return flask.jsonify( + { + 'code': 'OK', + 'family': family + } + ) diff --git a/pagure/lib/__init__.py b/pagure/lib/__init__.py index ca25983..9fd79be 100644 --- a/pagure/lib/__init__.py +++ b/pagure/lib/__init__.py @@ -5004,6 +5004,10 @@ def get_project_family(session, project): model.Project.parent_id.in_(sub.subquery()), model.Project.parent_id == parent.id, ) + ).filter( + model.Project.user_id == model.User.id + ).order_by( + model.User.user ) - return query.all() + [parent] + return [parent] + query.all() diff --git a/tests/test_pagure_flask_internal.py b/tests/test_pagure_flask_internal.py index 49d7915..2492e08 100644 --- a/tests/test_pagure_flask_internal.py +++ b/tests/test_pagure_flask_internal.py @@ -1576,6 +1576,119 @@ class PagureFlaskInternaltests(tests.Modeltests): {u'results': [[str(today), 2]]} ) + def test_get_project_family_no_project(self): + ''' Test the get_project_family from the internal API. ''' + output = self.app.post('/pv/test/family') + self.assertEqual(output.status_code, 404) + + def test_get_project_family_no_csrf(self): + ''' Test the get_project_family from the internal API. ''' + tests.create_projects(self.session) + tests.create_projects_git( + os.path.join(self.path, 'repos'), bare=True) + tests.add_content_git_repo( + os.path.join(self.path, 'repos', 'test.git')) + + output = self.app.post('/pv/test/family') + self.assertEqual(output.status_code, 400) + js_data = json.loads(output.data.decode('utf-8')) + self.assertEqual( + sorted(js_data.keys()), + [u'code', u'message'] + ) + self.assertEqual(js_data['code'], u'ERROR') + self.assertEqual(js_data['message'], u'Invalid input submitted') + + def test_get_project_family(self): + ''' Test the get_project_family from the internal API. ''' + tests.create_projects(self.session) + tests.create_projects_git( + os.path.join(self.path, 'repos'), bare=True) + tests.add_content_git_repo( + os.path.join(self.path, 'repos', 'test.git')) + + user = tests.FakeUser() + user.username = 'pingou' + with tests.user_set(self.app.application, user): + csrf_token = self.get_csrf() + + data = { + 'csrf_token': csrf_token, + } + output = self.app.post('/pv/test/family', data=data) + self.assertEqual(output.status_code, 200) + js_data = json.loads(output.data.decode('utf-8')) + self.assertEqual( + sorted(js_data.keys()), + [u'code', u'family'] + ) + self.assertEqual(js_data['code'], 'OK') + self.assertEqual(js_data['family'], [u'test']) + + def test_get_project_larger_family(self): + ''' Test the get_project_family from the internal API. ''' + tests.create_projects(self.session) + tests.create_projects_git( + os.path.join(self.path, 'repos'), bare=True) + + # Create a 3rd user + item = pagure.lib.model.User( + user='ralph', + fullname='Ralph bar', + password='ralph_foo', + default_email='ralph@bar.com', + ) + self.session.add(item) + item = pagure.lib.model.UserEmail( + user_id=3, + email='ralph@bar.com') + self.session.add(item) + self.session.commit() + + # Create a couple of forks of the test project + item = pagure.lib.model.Project( + user_id=2, # foo + name='test', + is_fork=True, + parent_id=1, # test + description='test project #1', + hook_token='aaabbbcccddd', + ) + item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate'] + self.session.add(item) + item = pagure.lib.model.Project( + user_id=3, # Ralph + name='test', + is_fork=True, + parent_id=1, # test + description='test project #1', + hook_token='aaabbbccceee', + ) + item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate'] + self.session.add(item) + self.session.commit() + + # Get on with testing + user = tests.FakeUser() + user.username = 'pingou' + with tests.user_set(self.app.application, user): + csrf_token = self.get_csrf() + + data = { + 'csrf_token': csrf_token, + } + output = self.app.post('/pv/test/family', data=data) + self.assertEqual(output.status_code, 200) + js_data = json.loads(output.data.decode('utf-8')) + self.assertEqual( + sorted(js_data.keys()), + [u'code', u'family'] + ) + self.assertEqual(js_data['code'], 'OK') + self.assertEqual( + js_data['family'], + [u'test', u'fork/foo/test', u'fork/ralph/test']) + if __name__ == '__main__': unittest.main(verbosity=2)