summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGauvain Pocentek <gauvain@pocentek.net>2018-05-27 18:27:48 +0200
committerGauvain Pocentek <gauvain@pocentek.net>2018-05-27 18:27:48 +0200
commit4461139b4ace84368ccd595a459d51f9fd81b7a1 (patch)
tree6dbaff8dd7a15e887f3e9720ef2c346186ae5777
parent660f0cf546d18b28883e97c1182984593bbae643 (diff)
downloadgitlab-4461139b4ace84368ccd595a459d51f9fd81b7a1.tar.gz
Add support for the discussions API
Fixes #501
-rw-r--r--docs/api-objects.rst1
-rw-r--r--gitlab/v4/objects.py121
-rw-r--r--tools/python_test_v4.py55
3 files changed, 175 insertions, 2 deletions
diff --git a/docs/api-objects.rst b/docs/api-objects.rst
index 3c221c6..bcdfccf 100644
--- a/docs/api-objects.rst
+++ b/docs/api-objects.rst
@@ -14,6 +14,7 @@ API examples
gl_objects/commits
gl_objects/deploy_keys
gl_objects/deployments
+ gl_objects/discussions
gl_objects/environments
gl_objects/events
gl_objects/features
diff --git a/gitlab/v4/objects.py b/gitlab/v4/objects.py
index 6f40dc8..3372d47 100644
--- a/gitlab/v4/objects.py
+++ b/gitlab/v4/objects.py
@@ -1159,10 +1159,39 @@ class ProjectCommitCommentManager(ListMixin, CreateMixin, RESTManager):
_create_attrs = (('note', ), ('path', 'line', 'line_type'))
+class ProjectCommitDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject):
+ pass
+
+
+class ProjectCommitDiscussionNoteManager(GetMixin, CreateMixin, UpdateMixin,
+ DeleteMixin, RESTManager):
+ _path = ('/projects/%(project_id)s/repository/commits/%(commit_id)s/'
+ 'discussions/%(discussion_id)s/notes')
+ _obj_cls = ProjectCommitDiscussionNote
+ _from_parent_attrs = {'project_id': 'project_id',
+ 'commit_id': 'commit_id',
+ 'discussion_id': 'id'}
+ _create_attrs = (('body',), ('created_at', 'position'))
+ _update_attrs = (('body',), tuple())
+
+
+class ProjectCommitDiscussion(RESTObject):
+ _managers = (('notes', 'ProjectCommitDiscussionNoteManager'),)
+
+
+class ProjectCommitDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
+ _path = ('/projects/%(project_id)s/repository/commits/%(commit_id)s/'
+ 'discussions')
+ _obj_cls = ProjectCommitDiscussion
+ _from_parent_attrs = {'project_id': 'project_id', 'commit_id': 'id'}
+ _create_attrs = (('body',), ('created_at',))
+
+
class ProjectCommit(RESTObject):
_short_print_attr = 'title'
_managers = (
('comments', 'ProjectCommitCommentManager'),
+ ('discussions', 'ProjectCommitDiscussionManager'),
('statuses', 'ProjectCommitStatusManager'),
)
@@ -1330,13 +1359,41 @@ class ProjectIssueNoteManager(CRUDMixin, RESTManager):
_update_attrs = (('body', ), tuple())
+class ProjectIssueDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject):
+ pass
+
+
+class ProjectIssueDiscussionNoteManager(GetMixin, CreateMixin, UpdateMixin,
+ DeleteMixin, RESTManager):
+ _path = ('/projects/%(project_id)s/issues/%(issue_iid)s/'
+ 'discussions/%(discussion_id)s/notes')
+ _obj_cls = ProjectIssueDiscussionNote
+ _from_parent_attrs = {'project_id': 'project_id',
+ 'issue_iid': 'issue_iid',
+ 'discussion_id': 'id'}
+ _create_attrs = (('body',), ('created_at',))
+ _update_attrs = (('body',), tuple())
+
+
+class ProjectIssueDiscussion(RESTObject):
+ _managers = (('notes', 'ProjectIssueDiscussionNoteManager'),)
+
+
+class ProjectIssueDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
+ _path = '/projects/%(project_id)s/issues/%(issue_iid)s/discussions'
+ _obj_cls = ProjectIssueDiscussion
+ _from_parent_attrs = {'project_id': 'project_id', 'issue_iid': 'iid'}
+ _create_attrs = (('body',), ('created_at',))
+
+
class ProjectIssue(SubscribableMixin, TodoMixin, TimeTrackingMixin, SaveMixin,
ObjectDeleteMixin, RESTObject):
_short_print_attr = 'title'
_id_attr = 'iid'
_managers = (
- ('notes', 'ProjectIssueNoteManager'),
('awardemojis', 'ProjectIssueAwardEmojiManager'),
+ ('discussions', 'ProjectIssueDiscussionManager'),
+ ('notes', 'ProjectIssueNoteManager'),
)
@cli.register_custom_action('ProjectIssue')
@@ -1510,7 +1567,7 @@ class ProjectMergeRequestNoteAwardEmojiManager(NoUpdateMixin, RESTManager):
'/notes/%(note_id)s/award_emoji')
_obj_cls = ProjectMergeRequestNoteAwardEmoji
_from_parent_attrs = {'project_id': 'project_id',
- 'mr_iid': 'issue_iid',
+ 'mr_iid': 'mr_iid',
'note_id': 'id'}
_create_attrs = (('name', ), tuple())
@@ -1527,6 +1584,37 @@ class ProjectMergeRequestNoteManager(CRUDMixin, RESTManager):
_update_attrs = (('body', ), tuple())
+class ProjectMergeRequestDiscussionNote(SaveMixin, ObjectDeleteMixin,
+ RESTObject):
+ pass
+
+
+class ProjectMergeRequestDiscussionNoteManager(GetMixin, CreateMixin,
+ UpdateMixin, DeleteMixin,
+ RESTManager):
+ _path = ('/projects/%(project_id)s/merge_requests/%(mr_iid)s/'
+ 'discussions/%(discussion_id)s/notes')
+ _obj_cls = ProjectMergeRequestDiscussionNote
+ _from_parent_attrs = {'project_id': 'project_id',
+ 'mr_iid': 'mr_iid',
+ 'discussion_id': 'id'}
+ _create_attrs = (('body',), ('created_at',))
+ _update_attrs = (('body',), tuple())
+
+
+class ProjectMergeRequestDiscussion(SaveMixin, RESTObject):
+ _managers = (('notes', 'ProjectMergeRequestDiscussionNoteManager'),)
+
+
+class ProjectMergeRequestDiscussionManager(RetrieveMixin, CreateMixin,
+ UpdateMixin, RESTManager):
+ _path = '/projects/%(project_id)s/merge_requests/%(mr_iid)s/discussions'
+ _obj_cls = ProjectMergeRequestDiscussion
+ _from_parent_attrs = {'project_id': 'project_id', 'mr_iid': 'iid'}
+ _create_attrs = (('body',), ('created_at', 'position'))
+ _update_attrs = (('resolved',), tuple())
+
+
class ProjectMergeRequest(SubscribableMixin, TodoMixin, TimeTrackingMixin,
SaveMixin, ObjectDeleteMixin, RESTObject):
_id_attr = 'iid'
@@ -1534,6 +1622,7 @@ class ProjectMergeRequest(SubscribableMixin, TodoMixin, TimeTrackingMixin,
_managers = (
('awardemojis', 'ProjectMergeRequestAwardEmojiManager'),
('diffs', 'ProjectMergeRequestDiffManager'),
+ ('discussions', 'ProjectMergeRequestDiscussionManager'),
('notes', 'ProjectMergeRequestNoteManager'),
)
@@ -2175,11 +2264,39 @@ class ProjectSnippetAwardEmojiManager(NoUpdateMixin, RESTManager):
_create_attrs = (('name', ), tuple())
+class ProjectSnippetDiscussionNote(SaveMixin, ObjectDeleteMixin, RESTObject):
+ pass
+
+
+class ProjectSnippetDiscussionNoteManager(GetMixin, CreateMixin, UpdateMixin,
+ DeleteMixin, RESTManager):
+ _path = ('/projects/%(project_id)s/snippets/%(snippet_id)s/'
+ 'discussions/%(discussion_id)s/notes')
+ _obj_cls = ProjectSnippetDiscussionNote
+ _from_parent_attrs = {'project_id': 'project_id',
+ 'snippet_id': 'snippet_id',
+ 'discussion_id': 'id'}
+ _create_attrs = (('body',), ('created_at',))
+ _update_attrs = (('body',), tuple())
+
+
+class ProjectSnippetDiscussion(RESTObject):
+ _managers = (('notes', 'ProjectSnippetDiscussionNoteManager'),)
+
+
+class ProjectSnippetDiscussionManager(RetrieveMixin, CreateMixin, RESTManager):
+ _path = '/projects/%(project_id)s/snippets/%(snippet_id)s/discussions'
+ _obj_cls = ProjectSnippetDiscussion
+ _from_parent_attrs = {'project_id': 'project_id', 'snippet_id': 'id'}
+ _create_attrs = (('body',), ('created_at',))
+
+
class ProjectSnippet(SaveMixin, ObjectDeleteMixin, RESTObject):
_url = '/projects/%(project_id)s/snippets'
_short_print_attr = 'title'
_managers = (
('awardemojis', 'ProjectSnippetAwardEmojiManager'),
+ ('discussions', 'ProjectSnippetDiscussionManager'),
('notes', 'ProjectSnippetNoteManager'),
)
diff --git a/tools/python_test_v4.py b/tools/python_test_v4.py
index 01de5bd..5cec8d3 100644
--- a/tools/python_test_v4.py
+++ b/tools/python_test_v4.py
@@ -379,6 +379,20 @@ assert(len(commit.statuses.list()) == 1)
commit.comments.create({'note': 'This is a commit comment'})
assert(len(commit.comments.list()) == 1)
+# commit discussion
+count = len(commit.discussions.list())
+discussion = commit.discussions.create({'body': 'Discussion body'})
+assert(len(commit.discussions.list()) == (count + 1))
+d_note = discussion.notes.create({'body': 'first note'})
+d_note_from_get = discussion.notes.get(d_note.id)
+d_note_from_get.body = 'updated body'
+d_note_from_get.save()
+discussion = commit.discussions.get(discussion.id)
+assert(discussion.attributes['notes'][-1]['body'] == 'updated body')
+d_note_from_get.delete()
+discussion = commit.discussions.get(discussion.id)
+assert(len(discussion.attributes['notes']) == 1)
+
# housekeeping
admin_project.housekeeping()
@@ -492,6 +506,18 @@ note.delete()
assert(len(issue1.notes.list()) == 0)
assert(isinstance(issue1.user_agent_detail(), dict))
+discussion = issue1.discussions.create({'body': 'Discussion body'})
+assert(len(issue1.discussions.list()) == 1)
+d_note = discussion.notes.create({'body': 'first note'})
+d_note_from_get = discussion.notes.get(d_note.id)
+d_note_from_get.body = 'updated body'
+d_note_from_get.save()
+discussion = issue1.discussions.get(discussion.id)
+assert(discussion.attributes['notes'][-1]['body'] == 'updated body')
+d_note_from_get.delete()
+discussion = issue1.discussions.get(discussion.id)
+assert(len(discussion.attributes['notes']) == 1)
+
# tags
tag1 = admin_project.tags.create({'tag_name': 'v1.0', 'ref': 'master'})
assert(len(admin_project.tags.list()) == 1)
@@ -507,6 +533,19 @@ snippet = admin_project.snippets.create(
{'title': 'snip1', 'file_name': 'foo.py', 'code': 'initial content',
'visibility': gitlab.v4.objects.VISIBILITY_PRIVATE}
)
+
+discussion = snippet.discussions.create({'body': 'Discussion body'})
+assert(len(snippet.discussions.list()) == 1)
+d_note = discussion.notes.create({'body': 'first note'})
+d_note_from_get = discussion.notes.get(d_note.id)
+d_note_from_get.body = 'updated body'
+d_note_from_get.save()
+discussion = snippet.discussions.get(discussion.id)
+assert(discussion.attributes['notes'][-1]['body'] == 'updated body')
+d_note_from_get.delete()
+discussion = snippet.discussions.get(discussion.id)
+assert(len(discussion.attributes['notes']) == 1)
+
snippet.file_name = 'bar.py'
snippet.save()
snippet = admin_project.snippets.get(snippet.id)
@@ -541,6 +580,19 @@ mr = admin_project.mergerequests.create({'source_branch': 'branch1',
'target_branch': 'master',
'title': 'MR readme2'})
+# discussion
+discussion = mr.discussions.create({'body': 'Discussion body'})
+assert(len(mr.discussions.list()) == 1)
+d_note = discussion.notes.create({'body': 'first note'})
+d_note_from_get = discussion.notes.get(d_note.id)
+d_note_from_get.body = 'updated body'
+d_note_from_get.save()
+discussion = mr.discussions.get(discussion.id)
+assert(discussion.attributes['notes'][-1]['body'] == 'updated body')
+d_note_from_get.delete()
+discussion = mr.discussions.get(discussion.id)
+assert(len(discussion.attributes['notes']) == 1)
+
# basic testing: only make sure that the methods exist
mr.commits()
mr.changes()
@@ -646,7 +698,10 @@ snippet = gl.snippets.get(snippet.id)
assert(snippet.title == 'updated_title')
content = snippet.content()
assert(content == 'import gitlab')
+
snippet.delete()
+snippets = gl.snippets.list(all=True)
+assert(len(snippets) == 0)
# user activities
gl.user_activities.list()