From 035d746786056ee4b2bf77a92ae852dcf969b096 Mon Sep 17 00:00:00 2001 From: Akash Srivastava Date: Sun, 17 Feb 2019 22:17:46 +0530 Subject: [PATCH] Group Boards API --- lib/gitlab/client.rb | 1 + lib/gitlab/client/group_boards.rb | 141 ++++++++++++++++++++++ spec/fixtures/group_board.json | 67 +++++++++++ spec/fixtures/group_board_list.json | 9 ++ spec/fixtures/group_board_lists.json | 29 +++++ spec/fixtures/group_boards.json | 69 +++++++++++ spec/fixtures/updated_group_board.json | 64 ++++++++++ spec/gitlab/client/group_boards_spec.rb | 152 ++++++++++++++++++++++++ spec/gitlab/shell_spec.rb | 2 +- 9 files changed, 533 insertions(+), 1 deletion(-) create mode 100644 lib/gitlab/client/group_boards.rb create mode 100644 spec/fixtures/group_board.json create mode 100644 spec/fixtures/group_board_list.json create mode 100644 spec/fixtures/group_board_lists.json create mode 100644 spec/fixtures/group_boards.json create mode 100644 spec/fixtures/updated_group_board.json create mode 100644 spec/gitlab/client/group_boards_spec.rb diff --git a/lib/gitlab/client.rb b/lib/gitlab/client.rb index d9ca9ba7d..fabaf7608 100644 --- a/lib/gitlab/client.rb +++ b/lib/gitlab/client.rb @@ -18,6 +18,7 @@ class Client < API include Environments include Events include Features + include GroupBoards include GroupLabels include GroupMilestones include Groups diff --git a/lib/gitlab/client/group_boards.rb b/lib/gitlab/client/group_boards.rb new file mode 100644 index 000000000..901228de3 --- /dev/null +++ b/lib/gitlab/client/group_boards.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +class Gitlab::Client + # Defines methods related to group issue boards. + # @see https://docs.gitlab.com/ee/api/group_boards.html + module GroupBoards + # Lists Issue Boards in the given group. + # + # @example + # Gitlab.group_boards(5) + # + # @param [Integer, String] group The ID or name of a group. + # @return [Array] List of issue boards of the group + def group_boards(group) + get("/groups/#{url_encode group}/boards") + end + + # Gets a single group issue board. + # + # @example + # Gitlab.group_board(5, 1) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] id The ID of the issue board. + # @return [Gitlab::ObjectifiedHash] Returns information about a group issue board + def group_board(group, id) + get("/groups/#{url_encode group}/boards/#{id}") + end + + # Creates a new group issue board. + # + # @example + # Gitlab.create_group_board(5, 'Documentcloud') + # + # @param [Integer, String] group The ID or name of a group. + # @param [String] name The name of the new board. + # @return [Gitlab::ObjectifiedHash] Information about created group issue board. + def create_group_board(group, name) + body = { name: name } + post("/groups/#{url_encode group}/boards", body: body) + end + + # Updates a group issue board. + # + # @example + # Gitlab.edit_group_board(5, 1, { name: 'DocumentCloud2' }) + # Gitlab.edit_group_board(5, 1, { name: 'DocumentCloud2', assignee_id: 3 }) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] id The ID of the issue board. + # @param [Hash] options A customizable set of options. + # @option options [String] :name(optional) The new name of the board. + # @option options [Integer] :assignee_id(optional) The assignee the board should be scoped to. + # @option options [Integer] :milestone_id(optional) The milestone the board should be scoped to. + # @option options [String] :labels(optional) Comma-separated list of label names which the board should be scoped to. + # @option options [Integer] :weight(optional) The weight range from 0 to 9, to which the board should be scoped to. + # @return [Gitlab::ObjectifiedHash] Information about updated group issue board. + def edit_group_board(group, id, options = {}) + put("/groups/#{url_encode group}/boards/#{id}", body: options) + end + + # Deletes a group issue board. + # + # @example + # Gitlab.delete_group_board(5, 1) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] id The ID of the issue board. + # @return [void] This API call returns an empty response body. + def delete_group_board(group, id) + delete("/groups/#{url_encode group}/boards/#{id}") + end + + # Get a list of the boards lists. Does not include open and closed lists + # + # @example + # Gitlab.group_board_lists(5, 1) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] board_id The ID of the group issue board. + # @return [Array] List of boards lists of the group + def group_board_lists(group, board_id) + get("/groups/#{url_encode group}/boards/#{board_id}/lists") + end + + # Get a single group issue board list. + # + # @example + # Gitlab.group_board_list(5, 1, 1) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] board_id The ID of the group issue board. + # @param [Integer] list_id The ID of a boards list. + # @return [Gitlab::ObjectifiedHash] Returns information about a single group issue board list + def group_board_list(group, board_id, id) + get("/groups/#{url_encode group}/boards/#{board_id}/lists/#{id}") + end + + # Creates a new group issue board list. + # + # @example + # Gitlab.create_group_board_list(5, 1) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] board_id The ID of the group issue board. + # @param [Integer] label_id The ID of a label. + # @return [Gitlab::ObjectifiedHash] Information about created group issue board list. + def create_group_board_list(group, board_id, label_id) + body = { label_id: label_id } + post("/groups/#{url_encode group}/boards/#{board_id}/lists", body: body) + end + + # Updates an existing group issue board list. This call is used to change list position. + # + # @example + # Gitlab.edit_group_board_list(5, 1, 1, { position: 1 }) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] board_id The ID of the group issue board. + # @param [Integer] list_id The ID of a boards list. + # @param [Hash] options A customizable set of options. + # @option options [String] :position(required) The position of the list. + # @return [Gitlab::ObjectifiedHash] Information about updated group issue board list. + def edit_group_board_list(group, board_id, id, options = {}) + put("/groups/#{url_encode group}/boards/#{board_id}/lists/#{id}", body: options) + end + + # Deletes a group issue board list. + # + # @example + # Gitlab.delete_group_board_list(5, 1, 1) + # + # @param [Integer, String] group The ID or name of a group. + # @param [Integer] board_id The ID of the group issue board. + # @param [Integer] list_id The ID of a boards list. + # @return [void] This API call returns an empty response body. + def delete_group_board_list(group, board_id, id) + delete("/groups/#{url_encode group}/boards/#{board_id}/lists/#{id}") + end + end +end diff --git a/spec/fixtures/group_board.json b/spec/fixtures/group_board.json new file mode 100644 index 000000000..af97a6ea6 --- /dev/null +++ b/spec/fixtures/group_board.json @@ -0,0 +1,67 @@ + { + "id": 1, + "name": "group issue board", + "group": { + "id": 5, + "name": "Documentcloud", + "path": "documentcloud", + "owner_id": null, + "created_at": "2018-05-07T06:52:45.788Z", + "updated_at": "2018-07-03T06:48:17.005Z", + "description": "Consequatur aut a aperiam ut.", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 20, + "request_access_enabled": false, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": null, + "shared_runners_minutes_limit": null, + "repository_size_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "plan_id": null, + "project_creation_level": 2, + "runners_token": "rgeeL-nv4wa9YdRvuMid" + }, + "milestone": { + "id": 12, + "title": "10.0" + }, + "lists" : [ + { + "id" : 1, + "label" : { + "name" : "Testing", + "color" : "#F0AD4E", + "description" : null + }, + "position" : 1 + }, + { + "id" : 2, + "label" : { + "name" : "Ready", + "color" : "#FF0000", + "description" : null + }, + "position" : 2 + }, + { + "id" : 3, + "label" : { + "name" : "Production", + "color" : "#FF5F00", + "description" : null + }, + "position" : 3 + } + ] + } diff --git a/spec/fixtures/group_board_list.json b/spec/fixtures/group_board_list.json new file mode 100644 index 000000000..bf518d2a3 --- /dev/null +++ b/spec/fixtures/group_board_list.json @@ -0,0 +1,9 @@ +{ + "id" : 1, + "label" : { + "name" : "Testing", + "color" : "#F0AD4E", + "description" : null + }, + "position" : 1 +} diff --git a/spec/fixtures/group_board_lists.json b/spec/fixtures/group_board_lists.json new file mode 100644 index 000000000..c3a2c4bd7 --- /dev/null +++ b/spec/fixtures/group_board_lists.json @@ -0,0 +1,29 @@ +[ + { + "id" : 1, + "label" : { + "name" : "Testing", + "color" : "#F0AD4E", + "description" : null + }, + "position" : 1 + }, + { + "id" : 2, + "label" : { + "name" : "Ready", + "color" : "#FF0000", + "description" : null + }, + "position" : 2 + }, + { + "id" : 3, + "label" : { + "name" : "Production", + "color" : "#FF5F00", + "description" : null + }, + "position" : 3 + } +] diff --git a/spec/fixtures/group_boards.json b/spec/fixtures/group_boards.json new file mode 100644 index 000000000..891b2e86e --- /dev/null +++ b/spec/fixtures/group_boards.json @@ -0,0 +1,69 @@ +[ + { + "id": 1, + "name": "group issue board", + "group": { + "id": 5, + "name": "Documentcloud", + "path": "documentcloud", + "owner_id": null, + "created_at": "2018-05-07T06:52:45.788Z", + "updated_at": "2018-07-03T06:48:17.005Z", + "description": "Consequatur aut a aperiam ut.", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 20, + "request_access_enabled": false, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": null, + "shared_runners_minutes_limit": null, + "repository_size_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "plan_id": null, + "project_creation_level": 2, + "runners_token": "rgeeL-nv4wa9YdRvuMid" + }, + "milestone": { + "id": 12, + "title": "10.0" + }, + "lists" : [ + { + "id" : 1, + "label" : { + "name" : "Testing", + "color" : "#F0AD4E", + "description" : null + }, + "position" : 1 + }, + { + "id" : 2, + "label" : { + "name" : "Ready", + "color" : "#FF0000", + "description" : null + }, + "position" : 2 + }, + { + "id" : 3, + "label" : { + "name" : "Production", + "color" : "#FF5F00", + "description" : null + }, + "position" : 3 + } + ] + } +] diff --git a/spec/fixtures/updated_group_board.json b/spec/fixtures/updated_group_board.json new file mode 100644 index 000000000..9cd4d3f8e --- /dev/null +++ b/spec/fixtures/updated_group_board.json @@ -0,0 +1,64 @@ + { + "id": 1, + "project": null, + "lists": [], + "name": "new_name", + "group": { + "id": 5, + "name": "Documentcloud", + "path": "documentcloud", + "owner_id": null, + "created_at": "2018-05-07T06:52:45.788Z", + "updated_at": "2018-07-03T06:48:17.005Z", + "description": "Consequatur aut a aperiam ut.", + "avatar": { + "url": null + }, + "membership_lock": false, + "share_with_group_lock": false, + "visibility_level": 20, + "request_access_enabled": false, + "ldap_sync_status": "ready", + "ldap_sync_error": null, + "ldap_sync_last_update_at": null, + "ldap_sync_last_successful_update_at": null, + "ldap_sync_last_sync_at": null, + "lfs_enabled": null, + "parent_id": null, + "shared_runners_minutes_limit": null, + "repository_size_limit": null, + "require_two_factor_authentication": false, + "two_factor_grace_period": 48, + "plan_id": null, + "project_creation_level": 2, + "runners_token": "rgeeL-nv3wa6YdRvuMid" + }, + "milestone": { + "id": 44, + "iid": 1, + "group_id": 5, + "title": "Group Milestone", + "description": "Group Milestone Desc", + "state": "active", + "created_at": "2018-07-03T07:15:19.271Z", + "updated_at": "2018-07-03T07:15:19.271Z", + "due_date": null, + "start_date": null, + "web_url": "http://example.com/groups/documentcloud/-/milestones/1" + }, + "assignee": { + "id": 1, + "name": "Administrator", + "username": "root", + "state": "active", + "avatar_url": "https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon", + "web_url": "http://example.com/root" + }, + "labels": [{ + "id": 11, + "name": "GroupLabel", + "color": "#428BCA", + "description": "" + }], + "weight": 4 + } diff --git a/spec/gitlab/client/group_boards_spec.rb b/spec/gitlab/client/group_boards_spec.rb new file mode 100644 index 000000000..53fc925f4 --- /dev/null +++ b/spec/gitlab/client/group_boards_spec.rb @@ -0,0 +1,152 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Client do + describe '.group_boards' do + before do + stub_get('/groups/5/boards', 'group_boards') + @group_boards = Gitlab.group_boards(5) + end + + it 'gets the correct resource' do + expect(a_get('/groups/5/boards')).to have_been_made + end + + it "returns a paginated response of group's boards" do + expect(@group_boards).to be_a Gitlab::PaginatedResponse + end + end + + describe '.group_board' do + before do + stub_get('/groups/5/boards/1', 'group_board') + @group_board = Gitlab.group_board(5, 1) + end + + it 'gets the correct resource' do + expect(a_get('/groups/5/boards/1')).to have_been_made + end + + it 'returns correct information about a group issue board' do + expect(@group_board.id).to eq 1 + end + end + + describe '.create_group_board' do + before do + stub_post('/groups/5/boards', 'group_board') + @group_board = Gitlab.create_group_board(5, 'group issue board') + end + + it 'gets the correct resource' do + expect(a_post('/groups/5/boards') + .with(body: { name: 'group issue board' })).to have_been_made + end + + it 'returns information about a created group issue board' do + expect(@group_board.name).to eq('group issue board') + end + end + + describe '.edit_group_board' do + before do + stub_put('/groups/5/boards/1', 'updated_group_board') + @group_board = Gitlab.edit_group_board(5, 1, assignee_id: 1, milestone_id: 44) + end + + it 'gets the correct resource' do + expect(a_put('/groups/5/boards/1') + .with(body: { assignee_id: 1, milestone_id: 44 })).to have_been_made + end + + it 'returns information about an edited group issue board' do + expect(@group_board.assignee.id).to eq(1) + expect(@group_board.milestone.id).to eq(44) + end + end + + describe '.delete_group_board' do + before do + stub_delete('/groups/5/boards/1', 'empty') + Gitlab.delete_group_board(5, 1) + end + + it 'gets the correct resource' do + expect(a_delete('/groups/5/boards/1')).to have_been_made + end + end + + describe '.group_board_lists' do + before do + stub_get('/groups/5/boards/1/lists', 'group_board_lists') + @group_board_lists = Gitlab.group_board_lists(5, 1) + end + + it 'gets the correct resource' do + expect(a_get('/groups/5/boards/1/lists')).to have_been_made + end + + it "returns a paginated response of group's board lists" do + expect(@group_board_lists).to be_a Gitlab::PaginatedResponse + end + end + + describe '.group_board_list' do + before do + stub_get('/groups/5/boards/1/lists/1', 'group_board_list') + @group_board_list = Gitlab.group_board_list(5, 1, 1) + end + + it 'gets the correct resource' do + expect(a_get('/groups/5/boards/1/lists/1')).to have_been_made + end + + it 'returns correct information about a group issue board list' do + expect(@group_board_list.id).to eq 1 + end + end + + describe '.create_group_board_list' do + before do + stub_post('/groups/5/boards/1/lists', 'group_board_list') + @group_board_list = Gitlab.create_group_board_list(5, 1, 5) + end + + it 'gets the correct resource' do + expect(a_post('/groups/5/boards/1/lists') + .with(body: { label_id: 5 })).to have_been_made + end + + it 'returns information about a created group issue board list' do + expect(@group_board_list.position).to eq(1) + end + end + + describe '.edit_group_board_list' do + before do + stub_put('/groups/5/boards/1/lists/1', 'group_board_list') + @group_board_list = Gitlab.edit_group_board_list(5, 1, 1, position: 1) + end + + it 'gets the correct resource' do + expect(a_put('/groups/5/boards/1/lists/1') + .with(body: { position: 1 })).to have_been_made + end + + it 'returns information about an edited group issue board list' do + expect(@group_board_list.position).to eq(1) + end + end + + describe '.delete_group_board_list' do + before do + stub_delete('/groups/5/boards/1/lists/1', 'empty') + Gitlab.delete_group_board_list(5, 1, 1) + end + + it 'gets the correct resource' do + expect(a_delete('/groups/5/boards/1/lists/1')).to have_been_made + end + end +end diff --git a/spec/gitlab/shell_spec.rb b/spec/gitlab/shell_spec.rb index e240e5caf..385e2434d 100644 --- a/spec/gitlab/shell_spec.rb +++ b/spec/gitlab/shell_spec.rb @@ -58,7 +58,7 @@ it 'returns an Array of matching commands' do completed_cmds = @comp.call 'group' expect(completed_cmds).to be_a Array - expect(completed_cmds.sort).to eq(%w[group group_access_requests group_issues group_labels group_member group_members group_milestone group_milestone_issues group_milestone_merge_requests group_milestones group_projects group_search group_subgroups group_variable group_variables groups]) + expect(completed_cmds.sort).to eq(%w[group group_access_requests group_board group_board_list group_board_lists group_boards group_issues group_labels group_member group_members group_milestone group_milestone_issues group_milestone_merge_requests group_milestones group_projects group_search group_subgroups group_variable group_variables groups]) end end end