From fb5a4202062d07d2dbca544f4cfb475a65411716 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 11:42:37 -0300 Subject: Allow projects to have many boards --- app/models/project.rb | 3 +-- spec/models/project_spec.rb | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 74d54e69648..795a456b094 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -65,8 +65,7 @@ class Project < ActiveRecord::Base belongs_to :namespace has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id' - - has_one :board, dependent: :destroy + has_many :boards, dependent: :destroy # Project services has_many :services diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index dae546a0cdc..3748b1c7f5f 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -24,7 +24,7 @@ describe Project, models: true do it { is_expected.to have_one(:slack_service).dependent(:destroy) } it { is_expected.to have_one(:pushover_service).dependent(:destroy) } it { is_expected.to have_one(:asana_service).dependent(:destroy) } - it { is_expected.to have_one(:board).dependent(:destroy) } + it { is_expected.to have_many(:boards).dependent(:destroy) } it { is_expected.to have_one(:campfire_service).dependent(:destroy) } it { is_expected.to have_one(:drone_ci_service).dependent(:destroy) } it { is_expected.to have_one(:emails_on_push_service).dependent(:destroy) } -- cgit v1.2.1 From 95a5cc9285a8583988ece697ebdb948730b5db55 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 6 Oct 2016 15:58:28 -0300 Subject: Restrict the number of permitted boards per project to one --- app/models/project.rb | 7 ++++++- spec/models/project_spec.rb | 9 +++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/models/project.rb b/app/models/project.rb index 795a456b094..30db7ed50b3 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -16,6 +16,7 @@ class Project < ActiveRecord::Base extend Gitlab::ConfigHelper + NUMBER_OF_PERMITTED_BOARDS = 1 UNKNOWN_IMPORT_URL = 'http://unknown.git' cache_markdown_field :description, pipeline: :description @@ -65,7 +66,7 @@ class Project < ActiveRecord::Base belongs_to :namespace has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id' - has_many :boards, dependent: :destroy + has_many :boards, before_add: :validate_board_limit, dependent: :destroy # Project services has_many :services @@ -1338,4 +1339,8 @@ class Project < ActiveRecord::Base shared_projects.any? end + + def validate_board_limit(board) + raise StandardError, 'Number of permitted boards exceeded' if boards.size >= NUMBER_OF_PERMITTED_BOARDS + end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 3748b1c7f5f..1b13f1be477 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -94,6 +94,15 @@ describe Project, models: true do end end end + + describe '#boards' do + it 'raises an error when attempting to add more than one board to the project' do + subject.boards.build + + expect { subject.boards.build }.to raise_error(StandardError, 'Number of permitted boards exceeded') + expect(subject.boards.size).to eq 1 + end + end end describe 'modules' do -- cgit v1.2.1 From e46a4aabd925e0182c31976b5d28c38b9a8a0872 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 6 Oct 2016 16:20:21 -0300 Subject: Update Boards::CreateService to handle with the has_many association --- app/services/boards/create_service.rb | 15 ++++++++++----- spec/factories/boards.rb | 5 +++++ spec/factories/projects.rb | 8 -------- spec/services/boards/create_service_spec.rb | 22 ++++++++++------------ 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/app/services/boards/create_service.rb b/app/services/boards/create_service.rb index 072a0749285..a9dbd76a44a 100644 --- a/app/services/boards/create_service.rb +++ b/app/services/boards/create_service.rb @@ -1,16 +1,21 @@ module Boards class CreateService < Boards::BaseService def execute - create_board! unless project.board.present? - project.board + if project.boards.empty? + create_board! + else + project.boards.first + end end private def create_board! - project.create_board - project.board.lists.create(list_type: :backlog) - project.board.lists.create(list_type: :done) + board = project.boards.create + board.lists.create(list_type: :backlog) + board.lists.create(list_type: :done) + + board end end end diff --git a/spec/factories/boards.rb b/spec/factories/boards.rb index 35c4a0b6f08..ec46146d9b5 100644 --- a/spec/factories/boards.rb +++ b/spec/factories/boards.rb @@ -1,5 +1,10 @@ FactoryGirl.define do factory :board do project factory: :empty_project + + after(:create) do |board| + board.lists.create(list_type: :backlog) + board.lists.create(list_type: :done) + end end end diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 331172445e4..719ef17f57e 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -124,12 +124,4 @@ FactoryGirl.define do ) end end - - factory :project_with_board, parent: :empty_project do - after(:create) do |project| - project.create_board - project.board.lists.create(list_type: :backlog) - project.board.lists.create(list_type: :done) - end - end end diff --git a/spec/services/boards/create_service_spec.rb b/spec/services/boards/create_service_spec.rb index a1a4dd4c57c..fde807cc410 100644 --- a/spec/services/boards/create_service_spec.rb +++ b/spec/services/boards/create_service_spec.rb @@ -2,33 +2,31 @@ require 'spec_helper' describe Boards::CreateService, services: true do describe '#execute' do + let(:project) { create(:empty_project) } + subject(:service) { described_class.new(project, double) } context 'when project does not have a board' do - let(:project) { create(:empty_project, board: nil) } - it 'creates a new board' do expect { service.execute }.to change(Board, :count).by(1) end it 'creates default lists' do - service.execute + board = service.execute - expect(project.board.lists.size).to eq 2 - expect(project.board.lists.first).to be_backlog - expect(project.board.lists.last).to be_done + expect(board.lists.size).to eq 2 + expect(board.lists.first).to be_backlog + expect(board.lists.last).to be_done end end context 'when project has a board' do - let!(:project) { create(:project_with_board) } - - it 'does not create a new board' do - expect { service.execute }.not_to change(Board, :count) + before do + create(:board, project: project) end - it 'does not create board lists' do - expect { service.execute }.not_to change(project.board.lists, :count) + it 'does not create a new board' do + expect { service.execute }.not_to change(project.boards, :count) end end end -- cgit v1.2.1 From a2c485473a142a5aad2f03abefb4bfafed645995 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 13:54:46 -0300 Subject: Add Boards::Lists::ListService to list lists for a specific board --- app/services/boards/lists/list_service.rb | 9 +++++++++ spec/services/boards/lists/list_service_spec.rb | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 app/services/boards/lists/list_service.rb create mode 100644 spec/services/boards/lists/list_service_spec.rb diff --git a/app/services/boards/lists/list_service.rb b/app/services/boards/lists/list_service.rb new file mode 100644 index 00000000000..ff739bc7d9c --- /dev/null +++ b/app/services/boards/lists/list_service.rb @@ -0,0 +1,9 @@ +module Boards + module Lists + class ListService < Boards::BaseService + def execute(board) + board.lists + end + end + end +end diff --git a/spec/services/boards/lists/list_service_spec.rb b/spec/services/boards/lists/list_service_spec.rb new file mode 100644 index 00000000000..4464f80f796 --- /dev/null +++ b/spec/services/boards/lists/list_service_spec.rb @@ -0,0 +1,18 @@ +require 'spec_helper' + +describe Boards::Lists::ListService, services: true do + describe '#execute' do + it "returns board's lists" do + project = create(:empty_project) + board = create(:board, project: project) + label = create(:label, project: project) + backlog_list = create(:backlog_list, board: board) + list = create(:list, board: board, label: label) + done_list = create(:done_list, board: board) + + service = described_class.new(project, double) + + expect(service.execute(board)).to eq [backlog_list, list, done_list] + end + end +end -- cgit v1.2.1 From 9110746370c9759402af5087a612cbcfdf667c3c Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 14:00:18 -0300 Subject: Update Boards::Lists::CreateService to create lists for a specific board --- app/services/boards/base_service.rb | 1 - app/services/boards/lists/create_service.rb | 10 +++++----- spec/services/boards/lists/create_service_spec.rb | 14 +++++++------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/app/services/boards/base_service.rb b/app/services/boards/base_service.rb index b2069ca825a..7eacacbaf7e 100644 --- a/app/services/boards/base_service.rb +++ b/app/services/boards/base_service.rb @@ -1,5 +1,4 @@ module Boards class BaseService < ::BaseService - delegate :board, to: :project end end diff --git a/app/services/boards/lists/create_service.rb b/app/services/boards/lists/create_service.rb index b1887820bd4..da6f59c0399 100644 --- a/app/services/boards/lists/create_service.rb +++ b/app/services/boards/lists/create_service.rb @@ -1,23 +1,23 @@ module Boards module Lists class CreateService < Boards::BaseService - def execute + def execute(board) List.transaction do label = project.labels.find(params[:label_id]) - position = next_position + position = next_position(board) - create_list(label, position) + create_list(board, label, position) end end private - def next_position + def next_position(board) max_position = board.lists.movable.maximum(:position) max_position.nil? ? 0 : max_position.succ end - def create_list(label, position) + def create_list(board, label, position) board.lists.create(label: label, list_type: :label, position: position) end end diff --git a/spec/services/boards/lists/create_service_spec.rb b/spec/services/boards/lists/create_service_spec.rb index bff9c1fd1fe..e7806add916 100644 --- a/spec/services/boards/lists/create_service_spec.rb +++ b/spec/services/boards/lists/create_service_spec.rb @@ -2,8 +2,8 @@ require 'spec_helper' describe Boards::Lists::CreateService, services: true do describe '#execute' do - let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } let(:label) { create(:label, project: project, name: 'in-progress') } @@ -11,7 +11,7 @@ describe Boards::Lists::CreateService, services: true do context 'when board lists is empty' do it 'creates a new list at beginning of the list' do - list = service.execute + list = service.execute(board) expect(list.position).to eq 0 end @@ -19,7 +19,7 @@ describe Boards::Lists::CreateService, services: true do context 'when board lists has backlog, and done lists' do it 'creates a new list at beginning of the list' do - list = service.execute + list = service.execute(board) expect(list.position).to eq 0 end @@ -30,7 +30,7 @@ describe Boards::Lists::CreateService, services: true do create(:list, board: board, position: 0) create(:list, board: board, position: 1) - list = service.execute + list = service.execute(board) expect(list.position).to eq 2 end @@ -40,7 +40,7 @@ describe Boards::Lists::CreateService, services: true do it 'creates a new list at end of the label lists' do list1 = create(:list, board: board, position: 0) - list2 = service.execute + list2 = service.execute(board) expect(list1.reload.position).to eq 0 expect(list2.reload.position).to eq 1 @@ -52,7 +52,7 @@ describe Boards::Lists::CreateService, services: true do label = create(:label, name: 'in-development') service = described_class.new(project, user, label_id: label.id) - expect { service.execute }.to raise_error(ActiveRecord::RecordNotFound) + expect { service.execute(board) }.to raise_error(ActiveRecord::RecordNotFound) end end end -- cgit v1.2.1 From af87cf7c6ee1778b283ed285cdd7edbaaffc5fa5 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 14:06:34 -0300 Subject: Update Boards::Lists::GenerateService to generate for a specific board --- app/services/boards/lists/generate_service.rb | 8 ++++---- spec/services/boards/lists/generate_service_spec.rb | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/services/boards/lists/generate_service.rb b/app/services/boards/lists/generate_service.rb index 830e386c98b..686e4e4b336 100644 --- a/app/services/boards/lists/generate_service.rb +++ b/app/services/boards/lists/generate_service.rb @@ -1,11 +1,11 @@ module Boards module Lists class GenerateService < Boards::BaseService - def execute + def execute(board) return false unless board.lists.movable.empty? List.transaction do - label_params.each { |params| create_list(params) } + label_params.each { |params| create_list(board, params) } end true @@ -13,9 +13,9 @@ module Boards private - def create_list(params) + def create_list(board, params) label = find_or_create_label(params) - Lists::CreateService.new(project, current_user, label_id: label.id).execute + Lists::CreateService.new(project, current_user, label_id: label.id).execute(board) end def find_or_create_label(params) diff --git a/spec/services/boards/lists/generate_service_spec.rb b/spec/services/boards/lists/generate_service_spec.rb index 4171e4d816c..8b2f5e81338 100644 --- a/spec/services/boards/lists/generate_service_spec.rb +++ b/spec/services/boards/lists/generate_service_spec.rb @@ -2,15 +2,15 @@ require 'spec_helper' describe Boards::Lists::GenerateService, services: true do describe '#execute' do - let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } subject(:service) { described_class.new(project, user) } context 'when board lists is empty' do it 'creates the default lists' do - expect { service.execute }.to change(board.lists, :count).by(2) + expect { service.execute(board) }.to change(board.lists, :count).by(2) end end @@ -18,13 +18,13 @@ describe Boards::Lists::GenerateService, services: true do it 'does not creates the default lists' do create(:list, board: board) - expect { service.execute }.not_to change(board.lists, :count) + expect { service.execute(board) }.not_to change(board.lists, :count) end end context 'when project labels does not contains any list label' do it 'creates labels' do - expect { service.execute }.to change(project.labels, :count).by(2) + expect { service.execute(board) }.to change(project.labels, :count).by(2) end end @@ -32,7 +32,7 @@ describe Boards::Lists::GenerateService, services: true do it 'creates the missing labels' do create(:label, project: project, name: 'Doing') - expect { service.execute }.to change(project.labels, :count).by(1) + expect { service.execute(board) }.to change(project.labels, :count).by(1) end end end -- cgit v1.2.1 From 1a4b1e9735c8b3502d54f1e9ecbce0c3f235f5c7 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 14:13:43 -0300 Subject: Update Boards::Lists::MoveService to move lists inside a specific board --- app/services/boards/lists/move_service.rb | 3 ++- spec/services/boards/lists/move_service_spec.rb | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/services/boards/lists/move_service.rb b/app/services/boards/lists/move_service.rb index 020ff69f4a7..7d0730e8332 100644 --- a/app/services/boards/lists/move_service.rb +++ b/app/services/boards/lists/move_service.rb @@ -2,6 +2,7 @@ module Boards module Lists class MoveService < Boards::BaseService def execute(list) + @board = list.board @old_position = list.position @new_position = params[:position] @@ -16,7 +17,7 @@ module Boards private - attr_reader :old_position, :new_position + attr_reader :board, :old_position, :new_position def valid_move? new_position.present? && new_position != old_position && diff --git a/spec/services/boards/lists/move_service_spec.rb b/spec/services/boards/lists/move_service_spec.rb index 102ed67449d..63fa0bb8c5f 100644 --- a/spec/services/boards/lists/move_service_spec.rb +++ b/spec/services/boards/lists/move_service_spec.rb @@ -2,16 +2,16 @@ require 'spec_helper' describe Boards::Lists::MoveService, services: true do describe '#execute' do - let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } - let!(:backlog) { project.board.backlog_list } + let!(:backlog) { create(:backlog_list, board: board) } let!(:planning) { create(:list, board: board, position: 0) } let!(:development) { create(:list, board: board, position: 1) } let!(:review) { create(:list, board: board, position: 2) } let!(:staging) { create(:list, board: board, position: 3) } - let!(:done) { project.board.done_list } + let!(:done) { create(:done_list, board: board) } context 'when list type is set to label' do it 'keeps position of lists when new position is nil' do -- cgit v1.2.1 From 1fa3f30811c3599a2f060803b201441046926b87 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 14:26:28 -0300 Subject: Update Boards::Issues::ListService to list issues for a board list --- app/services/boards/issues/list_service.rb | 4 +++ spec/services/boards/issues/list_service_spec.rb | 31 ++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 435a8c6e681..782dbf0db1a 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -10,6 +10,10 @@ module Boards private + def board + @board ||= project.boards.find(params[:board_id]) + end + def list @list ||= board.lists.find(params[:id]) end diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb index 5b9f454fd2d..cc96fd05189 100644 --- a/spec/services/boards/issues/list_service_spec.rb +++ b/spec/services/boards/issues/list_service_spec.rb @@ -4,7 +4,7 @@ describe Boards::Issues::ListService, services: true do describe '#execute' do let(:user) { create(:user) } let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:board) { create(:board, project: project) } let(:bug) { create(:label, project: project, name: 'Bug') } let(:development) { create(:label, project: project, name: 'Development') } @@ -13,10 +13,10 @@ describe Boards::Issues::ListService, services: true do let(:p2) { create(:label, title: 'P2', project: project, priority: 2) } let(:p3) { create(:label, title: 'P3', project: project, priority: 3) } - let!(:backlog) { project.board.backlog_list } + let!(:backlog) { create(:backlog_list, board: board) } let!(:list1) { create(:list, board: board, label: development, position: 0) } let!(:list2) { create(:list, board: board, label: testing, position: 1) } - let!(:done) { project.board.done_list } + let!(:done) { create(:done_list, board: board) } let!(:opened_issue1) { create(:labeled_issue, project: project, labels: [bug]) } let!(:opened_issue2) { create(:labeled_issue, project: project, labels: [p2]) } @@ -37,7 +37,7 @@ describe Boards::Issues::ListService, services: true do end it 'delegates search to IssuesFinder' do - params = { id: list1.id } + params = { board_id: board.id, id: list1.id } expect_any_instance_of(IssuesFinder).to receive(:execute).once.and_call_original @@ -46,7 +46,7 @@ describe Boards::Issues::ListService, services: true do context 'sets default order to priority' do it 'returns opened issues when listing issues from Backlog' do - params = { id: backlog.id } + params = { board_id: board.id, id: backlog.id } issues = described_class.new(project, user, params).execute @@ -54,7 +54,7 @@ describe Boards::Issues::ListService, services: true do end it 'returns closed issues when listing issues from Done' do - params = { id: done.id } + params = { board_id: board.id, id: done.id } issues = described_class.new(project, user, params).execute @@ -62,12 +62,29 @@ describe Boards::Issues::ListService, services: true do end it 'returns opened issues that have label list applied when listing issues from a label list' do - params = { id: list1.id } + params = { board_id: board.id, id: list1.id } issues = described_class.new(project, user, params).execute expect(issues).to eq [list1_issue3, list1_issue1, list1_issue2] end end + + context 'with list that does not belongs to the board' do + it 'raises an error' do + list = create(:list) + service = described_class.new(project, user, board_id: board.id, id: list.id) + + expect { service.execute }.to raise_error(ActiveRecord::RecordNotFound) + end + end + + context 'with invalid list id' do + it 'raises an error' do + service = described_class.new(project, user, board_id: board.id, id: nil) + + expect { service.execute }.to raise_error(ActiveRecord::RecordNotFound) + end + end end end -- cgit v1.2.1 From 104c4f88cdc5aaa40334c83112f7c994ff7128c6 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 14:32:53 -0300 Subject: Update Boards::Issues::MoveService to move issues on a specific board --- app/services/boards/issues/move_service.rb | 4 ++++ spec/services/boards/issues/move_service_spec.rb | 24 ++++++++++++------------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/services/boards/issues/move_service.rb b/app/services/boards/issues/move_service.rb index 84dc3f70e76..24f6f2c7025 100644 --- a/app/services/boards/issues/move_service.rb +++ b/app/services/boards/issues/move_service.rb @@ -10,6 +10,10 @@ module Boards private + def board + @board ||= project.boards.find(params[:board_id]) + end + def valid_move? moving_from_list.present? && moving_to_list.present? && moving_from_list != moving_to_list diff --git a/spec/services/boards/issues/move_service_spec.rb b/spec/services/boards/issues/move_service_spec.rb index 180f1b08631..9cf5a17e128 100644 --- a/spec/services/boards/issues/move_service_spec.rb +++ b/spec/services/boards/issues/move_service_spec.rb @@ -3,17 +3,17 @@ require 'spec_helper' describe Boards::Issues::MoveService, services: true do describe '#execute' do let(:user) { create(:user) } - let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:bug) { create(:label, project: project, name: 'Bug') } let(:development) { create(:label, project: project, name: 'Development') } let(:testing) { create(:label, project: project, name: 'Testing') } - let!(:backlog) { project.board.backlog_list } + let!(:backlog) { create(:backlog_list, board: board) } let!(:list1) { create(:list, board: board, label: development, position: 0) } let!(:list2) { create(:list, board: board, label: testing, position: 1) } - let!(:done) { project.board.done_list } + let!(:done) { create(:done_list, board: board) } before do project.team << [user, :developer] @@ -22,7 +22,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from backlog' do it 'adds the label of the list it goes to' do issue = create(:labeled_issue, project: project, labels: [bug]) - params = { from_list_id: backlog.id, to_list_id: list1.id } + params = { board_id: board.id, from_list_id: backlog.id, to_list_id: list1.id } described_class.new(project, user, params).execute(issue) @@ -33,7 +33,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving to backlog' do it 'removes all list-labels' do issue = create(:labeled_issue, project: project, labels: [bug, development, testing]) - params = { from_list_id: list1.id, to_list_id: backlog.id } + params = { board_id: board.id, from_list_id: list1.id, to_list_id: backlog.id } described_class.new(project, user, params).execute(issue) @@ -44,7 +44,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from backlog to done' do it 'closes the issue' do issue = create(:labeled_issue, project: project, labels: [bug]) - params = { from_list_id: backlog.id, to_list_id: done.id } + params = { board_id: board.id, from_list_id: backlog.id, to_list_id: done.id } described_class.new(project, user, params).execute(issue) issue.reload @@ -56,7 +56,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving an issue between lists' do let(:issue) { create(:labeled_issue, project: project, labels: [bug, development]) } - let(:params) { { from_list_id: list1.id, to_list_id: list2.id } } + let(:params) { { board_id: board.id, from_list_id: list1.id, to_list_id: list2.id } } it 'delegates the label changes to Issues::UpdateService' do expect_any_instance_of(Issues::UpdateService).to receive(:execute).with(issue).once @@ -73,7 +73,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving to done' do let(:issue) { create(:labeled_issue, project: project, labels: [bug, development, testing]) } - let(:params) { { from_list_id: list2.id, to_list_id: done.id } } + let(:params) { { board_id: board.id, from_list_id: list2.id, to_list_id: done.id } } it 'delegates the close proceedings to Issues::CloseService' do expect_any_instance_of(Issues::CloseService).to receive(:execute).with(issue).once @@ -92,7 +92,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from done' do let(:issue) { create(:labeled_issue, :closed, project: project, labels: [bug]) } - let(:params) { { from_list_id: done.id, to_list_id: list2.id } } + let(:params) { { board_id: board.id, from_list_id: done.id, to_list_id: list2.id } } it 'delegates the re-open proceedings to Issues::ReopenService' do expect_any_instance_of(Issues::ReopenService).to receive(:execute).with(issue).once @@ -112,7 +112,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from done to backlog' do it 'reopens the issue' do issue = create(:labeled_issue, :closed, project: project, labels: [bug]) - params = { from_list_id: done.id, to_list_id: backlog.id } + params = { board_id: board.id, from_list_id: done.id, to_list_id: backlog.id } described_class.new(project, user, params).execute(issue) issue.reload @@ -124,7 +124,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving to same list' do let(:issue) { create(:labeled_issue, project: project, labels: [bug, development]) } - let(:params) { { from_list_id: list1.id, to_list_id: list1.id } } + let(:params) { { board_id: board.id, from_list_id: list1.id, to_list_id: list1.id } } it 'returns false' do expect(described_class.new(project, user, params).execute(issue)).to eq false -- cgit v1.2.1 From 8b15e328a60f050d4ff24c0c7203461ae2724a30 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 14:50:44 -0300 Subject: Removes all labels from project boards when moving and issue to done --- app/services/boards/issues/move_service.rb | 2 +- spec/services/boards/issues/move_service_spec.rb | 34 +++++++++++++----------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/app/services/boards/issues/move_service.rb b/app/services/boards/issues/move_service.rb index 24f6f2c7025..9a16609a8b5 100644 --- a/app/services/boards/issues/move_service.rb +++ b/app/services/boards/issues/move_service.rb @@ -53,7 +53,7 @@ module Boards if moving_to_list.movable? moving_from_list.label_id else - board.lists.movable.pluck(:label_id) + project.boards.joins(:lists).merge(List.movable).pluck(:label_id) end Array(label_ids).compact diff --git a/spec/services/boards/issues/move_service_spec.rb b/spec/services/boards/issues/move_service_spec.rb index 9cf5a17e128..c43b2aec490 100644 --- a/spec/services/boards/issues/move_service_spec.rb +++ b/spec/services/boards/issues/move_service_spec.rb @@ -4,16 +4,16 @@ describe Boards::Issues::MoveService, services: true do describe '#execute' do let(:user) { create(:user) } let(:project) { create(:empty_project) } - let(:board) { create(:board, project: project) } + let(:board1) { create(:board, project: project) } let(:bug) { create(:label, project: project, name: 'Bug') } let(:development) { create(:label, project: project, name: 'Development') } let(:testing) { create(:label, project: project, name: 'Testing') } - let!(:backlog) { create(:backlog_list, board: board) } - let!(:list1) { create(:list, board: board, label: development, position: 0) } - let!(:list2) { create(:list, board: board, label: testing, position: 1) } - let!(:done) { create(:done_list, board: board) } + let!(:backlog) { create(:backlog_list, board: board1) } + let!(:list1) { create(:list, board: board1, label: development, position: 0) } + let!(:list2) { create(:list, board: board1, label: testing, position: 1) } + let!(:done) { create(:done_list, board: board1) } before do project.team << [user, :developer] @@ -22,7 +22,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from backlog' do it 'adds the label of the list it goes to' do issue = create(:labeled_issue, project: project, labels: [bug]) - params = { board_id: board.id, from_list_id: backlog.id, to_list_id: list1.id } + params = { board_id: board1.id, from_list_id: backlog.id, to_list_id: list1.id } described_class.new(project, user, params).execute(issue) @@ -33,7 +33,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving to backlog' do it 'removes all list-labels' do issue = create(:labeled_issue, project: project, labels: [bug, development, testing]) - params = { board_id: board.id, from_list_id: list1.id, to_list_id: backlog.id } + params = { board_id: board1.id, from_list_id: list1.id, to_list_id: backlog.id } described_class.new(project, user, params).execute(issue) @@ -44,7 +44,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from backlog to done' do it 'closes the issue' do issue = create(:labeled_issue, project: project, labels: [bug]) - params = { board_id: board.id, from_list_id: backlog.id, to_list_id: done.id } + params = { board_id: board1.id, from_list_id: backlog.id, to_list_id: done.id } described_class.new(project, user, params).execute(issue) issue.reload @@ -56,7 +56,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving an issue between lists' do let(:issue) { create(:labeled_issue, project: project, labels: [bug, development]) } - let(:params) { { board_id: board.id, from_list_id: list1.id, to_list_id: list2.id } } + let(:params) { { board_id: board1.id, from_list_id: list1.id, to_list_id: list2.id } } it 'delegates the label changes to Issues::UpdateService' do expect_any_instance_of(Issues::UpdateService).to receive(:execute).with(issue).once @@ -72,8 +72,12 @@ describe Boards::Issues::MoveService, services: true do end context 'when moving to done' do - let(:issue) { create(:labeled_issue, project: project, labels: [bug, development, testing]) } - let(:params) { { board_id: board.id, from_list_id: list2.id, to_list_id: done.id } } + let(:board2) { create(:board, project: project) } + let(:regression) { create(:label, project: project, name: 'Regression') } + let!(:list3) { create(:list, board: board2, label: regression, position: 1) } + + let(:issue) { create(:labeled_issue, project: project, labels: [bug, development, testing, regression]) } + let(:params) { { board_id: board1.id, from_list_id: list2.id, to_list_id: done.id } } it 'delegates the close proceedings to Issues::CloseService' do expect_any_instance_of(Issues::CloseService).to receive(:execute).with(issue).once @@ -81,7 +85,7 @@ describe Boards::Issues::MoveService, services: true do described_class.new(project, user, params).execute(issue) end - it 'removes all list-labels and close the issue' do + it 'removes all list-labels from project boards and close the issue' do described_class.new(project, user, params).execute(issue) issue.reload @@ -92,7 +96,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from done' do let(:issue) { create(:labeled_issue, :closed, project: project, labels: [bug]) } - let(:params) { { board_id: board.id, from_list_id: done.id, to_list_id: list2.id } } + let(:params) { { board_id: board1.id, from_list_id: done.id, to_list_id: list2.id } } it 'delegates the re-open proceedings to Issues::ReopenService' do expect_any_instance_of(Issues::ReopenService).to receive(:execute).with(issue).once @@ -112,7 +116,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving from done to backlog' do it 'reopens the issue' do issue = create(:labeled_issue, :closed, project: project, labels: [bug]) - params = { board_id: board.id, from_list_id: done.id, to_list_id: backlog.id } + params = { board_id: board1.id, from_list_id: done.id, to_list_id: backlog.id } described_class.new(project, user, params).execute(issue) issue.reload @@ -124,7 +128,7 @@ describe Boards::Issues::MoveService, services: true do context 'when moving to same list' do let(:issue) { create(:labeled_issue, project: project, labels: [bug, development]) } - let(:params) { { board_id: board.id, from_list_id: list1.id, to_list_id: list1.id } } + let(:params) { { board_id: board1.id, from_list_id: list1.id, to_list_id: list1.id } } it 'returns false' do expect(described_class.new(project, user, params).execute(issue)).to eq false -- cgit v1.2.1 From b4b8e0ec9405c4b5d17b53552612397e847e734d Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 16:01:06 -0300 Subject: Add Boards::ListService service to list project boards --- app/services/boards/list_service.rb | 14 ++++++++++++ spec/services/boards/list_service_spec.rb | 37 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 app/services/boards/list_service.rb create mode 100644 spec/services/boards/list_service_spec.rb diff --git a/app/services/boards/list_service.rb b/app/services/boards/list_service.rb new file mode 100644 index 00000000000..cca4bdd82a2 --- /dev/null +++ b/app/services/boards/list_service.rb @@ -0,0 +1,14 @@ +module Boards + class ListService < Boards::BaseService + def execute + create_board! if project.boards.empty? + project.boards + end + + private + + def create_board! + Boards::CreateService.new(project, current_user).execute + end + end +end diff --git a/spec/services/boards/list_service_spec.rb b/spec/services/boards/list_service_spec.rb new file mode 100644 index 00000000000..dff33e4bcbb --- /dev/null +++ b/spec/services/boards/list_service_spec.rb @@ -0,0 +1,37 @@ +require 'spec_helper' + +describe Boards::ListService, services: true do + describe '#execute' do + let(:project) { create(:empty_project) } + + subject(:service) { described_class.new(project, double) } + + context 'when project does not have a board' do + it 'creates a new project board' do + expect { service.execute }.to change(project.boards, :count).by(1) + end + + it 'delegates the project board creation to Boards::CreateService' do + expect_any_instance_of(Boards::CreateService).to receive(:execute).once + + service.execute + end + end + + context 'when project has a board' do + before do + create(:board, project: project) + end + + it 'does not create a new board' do + expect { service.execute }.not_to change(project.boards, :count) + end + end + + it 'returns project boards' do + board = create(:board, project: project) + + expect(service.execute).to match_array [board] + end + end +end -- cgit v1.2.1 From ecf4c10e9c395604583820ad01167db34d09d4aa Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 16:24:29 -0300 Subject: Add index action to Projects::BoardsController to return project boards --- app/controllers/projects/boards_controller.rb | 15 +++++-- app/views/projects/boards/index.html.haml | 0 config/routes/project.rb | 2 +- .../controllers/projects/boards_controller_spec.rb | 47 ++++++++++++++++++++++ spec/fixtures/api/schemas/board.json | 12 ++++++ spec/fixtures/api/schemas/boards.json | 4 ++ 6 files changed, 76 insertions(+), 4 deletions(-) create mode 100644 app/views/projects/boards/index.html.haml create mode 100644 spec/fixtures/api/schemas/board.json create mode 100644 spec/fixtures/api/schemas/boards.json diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 0035633b774..56bc54fbd1c 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -1,9 +1,18 @@ class Projects::BoardsController < Projects::ApplicationController include IssuableCollections - - respond_to :html - before_action :authorize_read_board!, only: [:show] + before_action :authorize_read_board!, only: [:index, :show] + + def index + @boards = ::Boards::ListService.new(project, current_user).execute + + respond_to do |format| + format.html + format.json do + render json: @boards.as_json(only: [:id, :name]) + end + end + end def show ::Boards::CreateService.new(project, current_user).execute diff --git a/app/views/projects/boards/index.html.haml b/app/views/projects/boards/index.html.haml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/config/routes/project.rb b/config/routes/project.rb index e8807ef06a7..3a7c4f86301 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -416,7 +416,7 @@ resources :namespaces, path: '/', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: end end - resource :board, only: [:show] do + resources :boards, only: [:index, :show] do scope module: :boards do resources :issues, only: [:update] diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb index 6f6e608e1f3..d7698afd141 100644 --- a/spec/controllers/projects/boards_controller_spec.rb +++ b/spec/controllers/projects/boards_controller_spec.rb @@ -9,6 +9,53 @@ describe Projects::BoardsController do sign_in(user) end + describe 'GET index' do + it 'creates a new project board when project does not have one' do + expect { list_boards }.to change(project.boards, :count).by(1) + end + + context 'when format is HTML' do + it 'renders template' do + list_boards + + expect(response).to render_template :index + expect(response.content_type).to eq 'text/html' + end + end + + context 'when format is JSON' do + it 'returns a list of project boards' do + create_list(:board, 2, project: project) + + list_boards format: :json + + parsed_response = JSON.parse(response.body) + + expect(response).to match_response_schema('boards') + expect(parsed_response.length).to eq 2 + end + end + + context 'with unauthorized user' do + before do + allow(Ability).to receive(:allowed?).with(user, :read_project, project).and_return(true) + allow(Ability).to receive(:allowed?).with(user, :read_board, project).and_return(false) + end + + it 'returns a not found 404 response' do + list_boards + + expect(response).to have_http_status(404) + end + end + + def list_boards(format: :html) + get :index, namespace_id: project.namespace.to_param, + project_id: project.to_param, + format: format + end + end + describe 'GET show' do it 'creates a new board when project does not have one' do expect { read_board }.to change(Board, :count).by(1) diff --git a/spec/fixtures/api/schemas/board.json b/spec/fixtures/api/schemas/board.json new file mode 100644 index 00000000000..6c6e2bee8cb --- /dev/null +++ b/spec/fixtures/api/schemas/board.json @@ -0,0 +1,12 @@ +{ + "type": "object", + "required" : [ + "id", + "name" + ], + "properties" : { + "id": { "type": "integer" }, + "name": { "type": "string" } + }, + "additionalProperties": false +} diff --git a/spec/fixtures/api/schemas/boards.json b/spec/fixtures/api/schemas/boards.json new file mode 100644 index 00000000000..117564ef77a --- /dev/null +++ b/spec/fixtures/api/schemas/boards.json @@ -0,0 +1,4 @@ +{ + "type": "array", + "items": { "$ref": "board.json" } +} -- cgit v1.2.1 From 723ed9cc3a76f7ce0e2d1b358a33d05fb05865c9 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 17:08:55 -0300 Subject: Update Projects::BoardsController#show to look up for a specific board --- app/controllers/projects/boards_controller.rb | 15 +++++++-- .../controllers/projects/boards_controller_spec.rb | 37 ++++++++++++++++------ 2 files changed, 41 insertions(+), 11 deletions(-) diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index 56bc54fbd1c..bbb1b1bf1e1 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -9,13 +9,20 @@ class Projects::BoardsController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: @boards.as_json(only: [:id, :name]) + render json: serialize_as_json(@boards) end end end def show - ::Boards::CreateService.new(project, current_user).execute + @board = project.boards.find(params[:id]) + + respond_to do |format| + format.html + format.json do + render json: serialize_as_json(@board) + end + end end private @@ -23,4 +30,8 @@ class Projects::BoardsController < Projects::ApplicationController def authorize_read_board! return access_denied! unless can?(current_user, :read_board, project) end + + def serialize_as_json(resource) + resource.as_json(only: [:id, :name]) + end end diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb index d7698afd141..cc19035740e 100644 --- a/spec/controllers/projects/boards_controller_spec.rb +++ b/spec/controllers/projects/boards_controller_spec.rb @@ -57,15 +57,23 @@ describe Projects::BoardsController do end describe 'GET show' do - it 'creates a new board when project does not have one' do - expect { read_board }.to change(Board, :count).by(1) + let!(:board) { create(:board, project: project) } + + context 'when format is HTML' do + it 'renders template' do + read_board board: board + + expect(response).to render_template :show + expect(response.content_type).to eq 'text/html' + end end - it 'renders HTML template' do - read_board + context 'when format is JSON' do + it 'returns project board' do + read_board board: board, format: :json - expect(response).to render_template :show - expect(response.content_type).to eq 'text/html' + expect(response).to match_response_schema('board') + end end context 'with unauthorized user' do @@ -74,16 +82,27 @@ describe Projects::BoardsController do allow(Ability).to receive(:allowed?).with(user, :read_board, project).and_return(false) end - it 'returns a successful 404 response' do - read_board + it 'returns a not found 404 response' do + read_board board: board + + expect(response).to have_http_status(404) + end + end + + context 'when board does not belong to project' do + it 'returns a not found 404 response' do + another_board = create(:board) + + read_board board: another_board expect(response).to have_http_status(404) end end - def read_board(format: :html) + def read_board(board:, format: :html) get :show, namespace_id: project.namespace.to_param, project_id: project.to_param, + id: board.to_param, format: format end end -- cgit v1.2.1 From 5de4fba6e34ebf31dc6e737bf96dbd65d3daf958 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 19:24:42 -0300 Subject: Update Boards::Lists::DestroyService to remove list on a specic board --- app/services/boards/lists/destroy_service.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/services/boards/lists/destroy_service.rb b/app/services/boards/lists/destroy_service.rb index 25da3bfb56d..d75c5fd3dc6 100644 --- a/app/services/boards/lists/destroy_service.rb +++ b/app/services/boards/lists/destroy_service.rb @@ -4,6 +4,8 @@ module Boards def execute(list) return false unless list.destroyable? + @board = list.board + list.with_lock do decrement_higher_lists(list) remove_list(list) @@ -12,6 +14,8 @@ module Boards private + attr_reader :board + def decrement_higher_lists(list) board.lists.movable.where('position > ?', list.position) .update_all('position = position - 1') -- cgit v1.2.1 From e1f889df6463203e5bd899fca8e98de6b705cd43 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 19:25:29 -0300 Subject: Update endpoints to handle with board list changes --- .../projects/boards/lists_controller.rb | 18 ++++--- .../projects/boards/lists_controller_spec.rb | 57 ++++++++++++---------- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/app/controllers/projects/boards/lists_controller.rb b/app/controllers/projects/boards/lists_controller.rb index b995f586737..76ae41319c4 100644 --- a/app/controllers/projects/boards/lists_controller.rb +++ b/app/controllers/projects/boards/lists_controller.rb @@ -5,11 +5,11 @@ module Projects before_action :authorize_read_list!, only: [:index] def index - render json: serialize_as_json(project.board.lists) + render json: serialize_as_json(board.lists) end def create - list = ::Boards::Lists::CreateService.new(project, current_user, list_params).execute + list = ::Boards::Lists::CreateService.new(project, current_user, list_params).execute(board) if list.valid? render json: serialize_as_json(list) @@ -19,7 +19,7 @@ module Projects end def update - list = project.board.lists.movable.find(params[:id]) + list = board.lists.movable.find(params[:id]) service = ::Boards::Lists::MoveService.new(project, current_user, move_params) if service.execute(list) @@ -30,8 +30,8 @@ module Projects end def destroy - list = project.board.lists.destroyable.find(params[:id]) - service = ::Boards::Lists::DestroyService.new(project, current_user, params) + list = board.lists.destroyable.find(params[:id]) + service = ::Boards::Lists::DestroyService.new(project, current_user) if service.execute(list) head :ok @@ -43,8 +43,8 @@ module Projects def generate service = ::Boards::Lists::GenerateService.new(project, current_user) - if service.execute - render json: serialize_as_json(project.board.lists.movable) + if service.execute(board) + render json: serialize_as_json(board.lists.movable) else head :unprocessable_entity end @@ -60,6 +60,10 @@ module Projects return render_403 unless can?(current_user, :read_list, project) end + def board + @board ||= project.boards.find(params[:board_id]) + end + def list_params params.require(:list).permit(:label_id) end diff --git a/spec/controllers/projects/boards/lists_controller_spec.rb b/spec/controllers/projects/boards/lists_controller_spec.rb index 709006a3601..a53a5feef44 100644 --- a/spec/controllers/projects/boards/lists_controller_spec.rb +++ b/spec/controllers/projects/boards/lists_controller_spec.rb @@ -13,7 +13,7 @@ describe Projects::Boards::ListsController do describe 'GET index' do it 'returns a successful 200 response' do - read_board_list user: user + read_board_list user: user, board: board expect(response).to have_http_status(200) expect(response.content_type).to eq 'application/json' @@ -22,7 +22,7 @@ describe Projects::Boards::ListsController do it 'returns a list of board lists' do create(:list, board: board) - read_board_list user: user + read_board_list user: user, board: board parsed_response = JSON.parse(response.body) @@ -37,17 +37,18 @@ describe Projects::Boards::ListsController do end it 'returns a forbidden 403 response' do - read_board_list user: user + read_board_list user: user, board: board expect(response).to have_http_status(403) end end - def read_board_list(user:) + def read_board_list(user:, board:) sign_in(user) get :index, namespace_id: project.namespace.to_param, project_id: project.to_param, + board_id: board.to_param, format: :json end end @@ -57,13 +58,13 @@ describe Projects::Boards::ListsController do let(:label) { create(:label, project: project, name: 'Development') } it 'returns a successful 200 response' do - create_board_list user: user, label_id: label.id + create_board_list user: user, board: board, label_id: label.id expect(response).to have_http_status(200) end it 'returns the created list' do - create_board_list user: user, label_id: label.id + create_board_list user: user, board: board, label_id: label.id expect(response).to match_response_schema('list') end @@ -72,7 +73,7 @@ describe Projects::Boards::ListsController do context 'with invalid params' do context 'when label is nil' do it 'returns a not found 404 response' do - create_board_list user: user, label_id: nil + create_board_list user: user, board: board, label_id: nil expect(response).to have_http_status(404) end @@ -82,7 +83,7 @@ describe Projects::Boards::ListsController do it 'returns a not found 404 response' do label = create(:label, name: 'Development') - create_board_list user: user, label_id: label.id + create_board_list user: user, board: board, label_id: label.id expect(response).to have_http_status(404) end @@ -93,17 +94,18 @@ describe Projects::Boards::ListsController do it 'returns a forbidden 403 response' do label = create(:label, project: project, name: 'Development') - create_board_list user: guest, label_id: label.id + create_board_list user: guest, board: board, label_id: label.id expect(response).to have_http_status(403) end end - def create_board_list(user:, label_id:) + def create_board_list(user:, board:, label_id:) sign_in(user) post :create, namespace_id: project.namespace.to_param, project_id: project.to_param, + board_id: board.to_param, list: { label_id: label_id }, format: :json end @@ -115,13 +117,13 @@ describe Projects::Boards::ListsController do context 'with valid position' do it 'returns a successful 200 response' do - move user: user, list: planning, position: 1 + move user: user, board: board, list: planning, position: 1 expect(response).to have_http_status(200) end it 'moves the list to the desired position' do - move user: user, list: planning, position: 1 + move user: user, board: board, list: planning, position: 1 expect(planning.reload.position).to eq 1 end @@ -129,7 +131,7 @@ describe Projects::Boards::ListsController do context 'with invalid position' do it 'returns an unprocessable entity 422 response' do - move user: user, list: planning, position: 6 + move user: user, board: board, list: planning, position: 6 expect(response).to have_http_status(422) end @@ -137,7 +139,7 @@ describe Projects::Boards::ListsController do context 'with invalid list id' do it 'returns a not found 404 response' do - move user: user, list: 999, position: 1 + move user: user, board: board, list: 999, position: 1 expect(response).to have_http_status(404) end @@ -145,17 +147,18 @@ describe Projects::Boards::ListsController do context 'with unauthorized user' do it 'returns a forbidden 403 response' do - move user: guest, list: planning, position: 6 + move user: guest, board: board, list: planning, position: 6 expect(response).to have_http_status(403) end end - def move(user:, list:, position:) + def move(user:, board:, list:, position:) sign_in(user) patch :update, namespace_id: project.namespace.to_param, project_id: project.to_param, + board_id: board.to_param, id: list.to_param, list: { position: position }, format: :json @@ -167,19 +170,19 @@ describe Projects::Boards::ListsController do context 'with valid list id' do it 'returns a successful 200 response' do - remove_board_list user: user, list: planning + remove_board_list user: user, board: board, list: planning expect(response).to have_http_status(200) end it 'removes list from board' do - expect { remove_board_list user: user, list: planning }.to change(board.lists, :size).by(-1) + expect { remove_board_list user: user, board: board, list: planning }.to change(board.lists, :size).by(-1) end end context 'with invalid list id' do it 'returns a not found 404 response' do - remove_board_list user: user, list: 999 + remove_board_list user: user, board: board, list: 999 expect(response).to have_http_status(404) end @@ -187,17 +190,18 @@ describe Projects::Boards::ListsController do context 'with unauthorized user' do it 'returns a forbidden 403 response' do - remove_board_list user: guest, list: planning + remove_board_list user: guest, board: board, list: planning expect(response).to have_http_status(403) end end - def remove_board_list(user:, list:) + def remove_board_list(user:, board:, list:) sign_in(user) delete :destroy, namespace_id: project.namespace.to_param, project_id: project.to_param, + board_id: board.to_param, id: list.to_param, format: :json end @@ -206,13 +210,13 @@ describe Projects::Boards::ListsController do describe 'POST generate' do context 'when board lists is empty' do it 'returns a successful 200 response' do - generate_default_board_lists user: user + generate_default_lists user: user, board: board expect(response).to have_http_status(200) end it 'returns the defaults lists' do - generate_default_board_lists user: user + generate_default_lists user: user, board: board expect(response).to match_response_schema('lists') end @@ -222,7 +226,7 @@ describe Projects::Boards::ListsController do it 'returns an unprocessable entity 422 response' do create(:list, board: board) - generate_default_board_lists user: user + generate_default_lists user: user, board: board expect(response).to have_http_status(422) end @@ -230,17 +234,18 @@ describe Projects::Boards::ListsController do context 'with unauthorized user' do it 'returns a forbidden 403 response' do - generate_default_board_lists user: guest + generate_default_lists user: guest, board: board expect(response).to have_http_status(403) end end - def generate_default_board_lists(user:) + def generate_default_lists(user:, board: board) sign_in(user) post :generate, namespace_id: project.namespace.to_param, project_id: project.to_param, + board_id: board.to_param, format: :json end end -- cgit v1.2.1 From 67515098657704505935119503ef23e45f0fda04 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 23:44:44 -0300 Subject: Update endpoints to handle with board issues --- .../projects/boards/issues_controller.rb | 4 +- .../projects/boards/issues_controller_spec.rb | 53 ++++++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/app/controllers/projects/boards/issues_controller.rb b/app/controllers/projects/boards/issues_controller.rb index 095af6c35eb..82c99e4e8d9 100644 --- a/app/controllers/projects/boards/issues_controller.rb +++ b/app/controllers/projects/boards/issues_controller.rb @@ -60,11 +60,11 @@ module Projects end def filter_params - params.merge(id: params[:list_id]) + params.merge(board_id: params[:board_id], id: params[:list_id]) end def move_params - params.permit(:id, :from_list_id, :to_list_id) + params.permit(:board_id, :id, :from_list_id, :to_list_id) end def issue_params diff --git a/spec/controllers/projects/boards/issues_controller_spec.rb b/spec/controllers/projects/boards/issues_controller_spec.rb index 566658b508d..92e77291da9 100644 --- a/spec/controllers/projects/boards/issues_controller_spec.rb +++ b/spec/controllers/projects/boards/issues_controller_spec.rb @@ -1,15 +1,16 @@ require 'spec_helper' describe Projects::Boards::IssuesController do - let(:project) { create(:project_with_board) } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } let(:guest) { create(:user) } let(:planning) { create(:label, project: project, name: 'Planning') } let(:development) { create(:label, project: project, name: 'Development') } - let!(:list1) { create(:list, board: project.board, label: planning, position: 0) } - let!(:list2) { create(:list, board: project.board, label: development, position: 1) } + let!(:list1) { create(:list, board: board, label: planning, position: 0) } + let!(:list2) { create(:list, board: board, label: development, position: 1) } before do project.team << [user, :master] @@ -24,7 +25,7 @@ describe Projects::Boards::IssuesController do create(:labeled_issue, project: project, labels: [development]) create(:labeled_issue, project: project, labels: [development], assignee: johndoe) - list_issues user: user, list_id: list2 + list_issues user: user, board: board, list: list2 parsed_response = JSON.parse(response.body) @@ -33,9 +34,17 @@ describe Projects::Boards::IssuesController do end end + context 'with invalid board id' do + it 'returns a not found 404 response' do + list_issues user: user, board: 999, list: list2 + + expect(response).to have_http_status(404) + end + end + context 'with invalid list id' do it 'returns a not found 404 response' do - list_issues user: user, list_id: 999 + list_issues user: user, board: board, list: 999 expect(response).to have_http_status(404) end @@ -47,19 +56,20 @@ describe Projects::Boards::IssuesController do allow(Ability).to receive(:allowed?).with(user, :read_issue, project).and_return(false) end - it 'returns a successful 403 response' do - list_issues user: user, list_id: list2 + it 'returns a forbidden 403 response' do + list_issues user: user, board: board, list: list2 expect(response).to have_http_status(403) end end - def list_issues(user:, list_id:) + def list_issues(user:, board:, list:) sign_in(user) get :index, namespace_id: project.namespace.to_param, project_id: project.to_param, - list_id: list_id.to_param + board_id: board.to_param, + list_id: list.to_param end end @@ -122,13 +132,13 @@ describe Projects::Boards::IssuesController do context 'with valid params' do it 'returns a successful 200 response' do - move user: user, issue: issue, from_list_id: list1.id, to_list_id: list2.id + move user: user, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id expect(response).to have_http_status(200) end it 'moves issue to the desired list' do - move user: user, issue: issue, from_list_id: list1.id, to_list_id: list2.id + move user: user, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id expect(issue.reload.labels).to contain_exactly(development) end @@ -136,31 +146,44 @@ describe Projects::Boards::IssuesController do context 'with invalid params' do it 'returns a unprocessable entity 422 response for invalid lists' do - move user: user, issue: issue, from_list_id: nil, to_list_id: nil + move user: user, board: board, issue: issue, from_list_id: nil, to_list_id: nil expect(response).to have_http_status(422) end + it 'returns a not found 404 response for invalid board id' do + move user: user, board: 999, issue: issue, from_list_id: list1.id, to_list_id: list2.id + + expect(response).to have_http_status(404) + end + it 'returns a not found 404 response for invalid issue id' do - move user: user, issue: 999, from_list_id: list1.id, to_list_id: list2.id + move user: user, board: board, issue: 999, from_list_id: list1.id, to_list_id: list2.id expect(response).to have_http_status(404) end end context 'with unauthorized user' do + let(:guest) { create(:user) } + + before do + project.team << [guest, :guest] + end + it 'returns a forbidden 403 response' do - move user: guest, issue: issue, from_list_id: list1.id, to_list_id: list2.id + move user: guest, board: board, issue: issue, from_list_id: list1.id, to_list_id: list2.id expect(response).to have_http_status(403) end end - def move(user:, issue:, from_list_id:, to_list_id:) + def move(user:, board:, issue:, from_list_id:, to_list_id:) sign_in(user) patch :update, namespace_id: project.namespace.to_param, project_id: project.to_param, + board_id: board.to_param, id: issue.to_param, from_list_id: from_list_id, to_list_id: to_list_id, -- cgit v1.2.1 From a88ed81fb97cdd04b3ca222a534f8319319d7091 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 23:45:54 -0300 Subject: Remove unused Projects::BoardListsController controller --- app/controllers/projects/board_lists_controller.rb | 65 ---------------------- 1 file changed, 65 deletions(-) delete mode 100644 app/controllers/projects/board_lists_controller.rb diff --git a/app/controllers/projects/board_lists_controller.rb b/app/controllers/projects/board_lists_controller.rb deleted file mode 100644 index 3cfb08d5822..00000000000 --- a/app/controllers/projects/board_lists_controller.rb +++ /dev/null @@ -1,65 +0,0 @@ -class Projects::BoardListsController < Projects::ApplicationController - respond_to :json - - before_action :authorize_admin_list! - - rescue_from ActiveRecord::RecordNotFound, with: :record_not_found - - def create - list = Boards::Lists::CreateService.new(project, current_user, list_params).execute - - if list.valid? - render json: list.as_json(only: [:id, :list_type, :position], methods: [:title], include: { label: { only: [:id, :title, :description, :color, :priority] } }) - else - render json: list.errors, status: :unprocessable_entity - end - end - - def update - service = Boards::Lists::MoveService.new(project, current_user, move_params) - - if service.execute - head :ok - else - head :unprocessable_entity - end - end - - def destroy - service = Boards::Lists::DestroyService.new(project, current_user, params) - - if service.execute - head :ok - else - head :unprocessable_entity - end - end - - def generate - service = Boards::Lists::GenerateService.new(project, current_user) - - if service.execute - render json: project.board.lists.label.as_json(only: [:id, :list_type, :position], methods: [:title], include: { label: { only: [:id, :title, :description, :color, :priority] } }) - else - head :unprocessable_entity - end - end - - private - - def authorize_admin_list! - return render_403 unless can?(current_user, :admin_list, project) - end - - def list_params - params.require(:list).permit(:label_id) - end - - def move_params - params.require(:list).permit(:position).merge(id: params[:id]) - end - - def record_not_found(exception) - render json: { error: exception.message }, status: :not_found - end -end -- cgit v1.2.1 From 38cece495715df191fcb0c4ec0c5c2e44da2debf Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Wed, 5 Oct 2016 23:50:35 -0300 Subject: Fix rubocop offenses --- .../projects/boards/lists_controller_spec.rb | 2 +- spec/services/boards/issues/list_service_spec.rb | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/controllers/projects/boards/lists_controller_spec.rb b/spec/controllers/projects/boards/lists_controller_spec.rb index a53a5feef44..afede0191dc 100644 --- a/spec/controllers/projects/boards/lists_controller_spec.rb +++ b/spec/controllers/projects/boards/lists_controller_spec.rb @@ -240,7 +240,7 @@ describe Projects::Boards::ListsController do end end - def generate_default_lists(user:, board: board) + def generate_default_lists(user:, board:) sign_in(user) post :generate, namespace_id: project.namespace.to_param, diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb index cc96fd05189..218a6d2bc2f 100644 --- a/spec/services/boards/issues/list_service_spec.rb +++ b/spec/services/boards/issues/list_service_spec.rb @@ -70,21 +70,21 @@ describe Boards::Issues::ListService, services: true do end end - context 'with list that does not belongs to the board' do - it 'raises an error' do - list = create(:list) - service = described_class.new(project, user, board_id: board.id, id: list.id) + context 'with list that does not belongs to the board' do + it 'raises an error' do + list = create(:list) + service = described_class.new(project, user, board_id: board.id, id: list.id) - expect { service.execute }.to raise_error(ActiveRecord::RecordNotFound) - end + expect { service.execute }.to raise_error(ActiveRecord::RecordNotFound) end + end - context 'with invalid list id' do - it 'raises an error' do - service = described_class.new(project, user, board_id: board.id, id: nil) + context 'with invalid list id' do + it 'raises an error' do + service = described_class.new(project, user, board_id: board.id, id: nil) - expect { service.execute }.to raise_error(ActiveRecord::RecordNotFound) - end + expect { service.execute }.to raise_error(ActiveRecord::RecordNotFound) end + end end end -- cgit v1.2.1 From 9dc4ebc8ea5cd223b17cbc1d772348bebc50cdeb Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 6 Oct 2016 14:35:58 -0300 Subject: Fix links to issue boards --- app/views/layouts/nav/_project.html.haml | 2 +- app/views/projects/boards/show.html.haml | 2 +- app/views/projects/issues/_head.html.haml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml index e44a2bfed9d..99a58bbb676 100644 --- a/app/views/layouts/nav/_project.html.haml +++ b/app/views/layouts/nav/_project.html.haml @@ -116,4 +116,4 @@ -# Shortcut to issue boards %li.hidden - = link_to 'Issue Boards', namespace_project_board_path(@project.namespace, @project), title: 'Issue Boards', class: 'shortcuts-issue-boards' + = link_to 'Issue Boards', namespace_project_boards_path(@project.namespace, @project), title: 'Issue Boards', class: 'shortcuts-issue-boards' diff --git a/app/views/projects/boards/show.html.haml b/app/views/projects/boards/show.html.haml index edbbd3f3d2a..5b441b48caf 100644 --- a/app/views/projects/boards/show.html.haml +++ b/app/views/projects/boards/show.html.haml @@ -11,7 +11,7 @@ = render 'shared/issuable/filter', type: :boards .boards-list#board-app{ "v-cloak" => true, - "data-endpoint" => "#{namespace_project_board_path(@project.namespace, @project)}", + "data-endpoint" => "#{namespace_project_boards_path(@project.namespace, @project)}", "data-disabled" => "#{!can?(current_user, :admin_list, @project)}", "data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" } .boards-app-loading.text-center{ "v-if" => "loading" } diff --git a/app/views/projects/issues/_head.html.haml b/app/views/projects/issues/_head.html.haml index 509b01c548a..4825820c4d9 100644 --- a/app/views/projects/issues/_head.html.haml +++ b/app/views/projects/issues/_head.html.haml @@ -10,7 +10,7 @@ Issues = nav_link(controller: :boards) do - = link_to namespace_project_board_path(@project.namespace, @project), title: 'Board' do + = link_to namespace_project_boards_path(@project.namespace, @project), title: 'Board' do %span Board -- cgit v1.2.1 From 81c253ded12c96bfa3f5cf27f0e23c61619ad914 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 6 Oct 2016 14:37:41 -0300 Subject: Add Project#boards to import/export configuration file --- spec/lib/gitlab/import_export/all_models.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 006569254a6..5d5836e9bee 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -118,7 +118,7 @@ project: - creator - group - namespace -- board +- boards - last_event - services - campfire_service -- cgit v1.2.1 From 2c2a1dea67ef41a6e283c4816865645fba318a16 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 6 Oct 2016 17:13:33 -0300 Subject: Refactoring service to create a new issue in a board list --- app/controllers/projects/boards/issues_controller.rb | 5 ++--- app/services/boards/issues/create_service.rb | 15 +++++++++++---- .../controllers/projects/boards/issues_controller_spec.rb | 13 +++++++------ spec/services/boards/issues/create_service_spec.rb | 12 ++++++------ 4 files changed, 26 insertions(+), 19 deletions(-) diff --git a/app/controllers/projects/boards/issues_controller.rb b/app/controllers/projects/boards/issues_controller.rb index 82c99e4e8d9..71eb56aed0b 100644 --- a/app/controllers/projects/boards/issues_controller.rb +++ b/app/controllers/projects/boards/issues_controller.rb @@ -16,9 +16,8 @@ module Projects end def create - list = project.board.lists.find(params[:list_id]) service = ::Boards::Issues::CreateService.new(project, current_user, issue_params) - issue = service.execute(list) + issue = service.execute if issue.valid? render json: serialize_as_json(issue) @@ -68,7 +67,7 @@ module Projects end def issue_params - params.require(:issue).permit(:title).merge(request: request) + params.require(:issue).permit(:title).merge(board_id: params[:board_id], list_id: params[:list_id], request: request) end def serialize_as_json(resource) diff --git a/app/services/boards/issues/create_service.rb b/app/services/boards/issues/create_service.rb index 3701afd441f..a181e74043b 100644 --- a/app/services/boards/issues/create_service.rb +++ b/app/services/boards/issues/create_service.rb @@ -1,14 +1,21 @@ module Boards module Issues class CreateService < Boards::BaseService - def execute(list) - params.merge!(label_ids: [list.label_id]) - create_issue + def execute + create_issue(params.merge(label_ids: [list.label_id])) end private - def create_issue + def board + @board ||= project.boards.find(params.delete(:board_id)) + end + + def list + @list ||= board.lists.find(params.delete(:list_id)) + end + + def create_issue(params) ::Issues::CreateService.new(project, current_user, params).execute end end diff --git a/spec/controllers/projects/boards/issues_controller_spec.rb b/spec/controllers/projects/boards/issues_controller_spec.rb index 92e77291da9..da59642f24d 100644 --- a/spec/controllers/projects/boards/issues_controller_spec.rb +++ b/spec/controllers/projects/boards/issues_controller_spec.rb @@ -76,13 +76,13 @@ describe Projects::Boards::IssuesController do describe 'POST create' do context 'with valid params' do it 'returns a successful 200 response' do - create_issue user: user, list: list1, title: 'New issue' + create_issue user: user, board: board, list: list1, title: 'New issue' expect(response).to have_http_status(200) end it 'returns the created issue' do - create_issue user: user, list: list1, title: 'New issue' + create_issue user: user, board: board, list: list1, title: 'New issue' expect(response).to match_response_schema('issue') end @@ -91,7 +91,7 @@ describe Projects::Boards::IssuesController do context 'with invalid params' do context 'when title is nil' do it 'returns an unprocessable entity 422 response' do - create_issue user: user, list: list1, title: nil + create_issue user: user, board: board, list: list1, title: nil expect(response).to have_http_status(422) end @@ -101,7 +101,7 @@ describe Projects::Boards::IssuesController do it 'returns a not found 404 response' do list = create(:list) - create_issue user: user, list: list, title: 'New issue' + create_issue user: user, board: board, list: list, title: 'New issue' expect(response).to have_http_status(404) end @@ -110,17 +110,18 @@ describe Projects::Boards::IssuesController do context 'with unauthorized user' do it 'returns a forbidden 403 response' do - create_issue user: guest, list: list1, title: 'New issue' + create_issue user: guest, board: board, list: list1, title: 'New issue' expect(response).to have_http_status(403) end end - def create_issue(user:, list:, title:) + def create_issue(user:, board:, list:, title:) sign_in(user) post :create, namespace_id: project.namespace.to_param, project_id: project.to_param, + board_id: board.to_param, list_id: list.to_param, issue: { title: title }, format: :json diff --git a/spec/services/boards/issues/create_service_spec.rb b/spec/services/boards/issues/create_service_spec.rb index 33e10e79f6d..360ee398f77 100644 --- a/spec/services/boards/issues/create_service_spec.rb +++ b/spec/services/boards/issues/create_service_spec.rb @@ -2,13 +2,13 @@ require 'spec_helper' describe Boards::Issues::CreateService, services: true do describe '#execute' do - let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } let(:label) { create(:label, project: project, name: 'in-progress') } let!(:list) { create(:list, board: board, label: label, position: 0) } - subject(:service) { described_class.new(project, user, title: 'New issue') } + subject(:service) { described_class.new(project, user, board_id: board.id, list_id: list.id, title: 'New issue') } before do project.team << [user, :developer] @@ -17,15 +17,15 @@ describe Boards::Issues::CreateService, services: true do it 'delegates the create proceedings to Issues::CreateService' do expect_any_instance_of(Issues::CreateService).to receive(:execute).once - service.execute(list) + service.execute end it 'creates a new issue' do - expect { service.execute(list) }.to change(project.issues, :count).by(1) + expect { service.execute }.to change(project.issues, :count).by(1) end it 'adds the label of the list to the issue' do - issue = service.execute(list) + issue = service.execute expect(issue.labels).to eq [label] end -- cgit v1.2.1 From 1a2002d9084db71d5a0a2631985012b4544c4037 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 6 Oct 2016 17:14:39 -0300 Subject: Update board specs to use board factory instead of project_with_board --- spec/controllers/projects/boards/lists_controller_spec.rb | 4 ++-- spec/features/boards/boards_spec.rb | 5 +++-- spec/features/boards/new_issue_spec.rb | 3 ++- spec/services/boards/issues/list_service_spec.rb | 2 +- spec/services/boards/lists/destroy_service_spec.rb | 12 ++++++------ spec/services/boards/lists/list_service_spec.rb | 4 +--- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/spec/controllers/projects/boards/lists_controller_spec.rb b/spec/controllers/projects/boards/lists_controller_spec.rb index afede0191dc..34d6119429d 100644 --- a/spec/controllers/projects/boards/lists_controller_spec.rb +++ b/spec/controllers/projects/boards/lists_controller_spec.rb @@ -1,8 +1,8 @@ require 'spec_helper' describe Projects::Boards::ListsController do - let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } let(:guest) { create(:user) } diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 470e2bdbb9b..f79b6a77696 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -4,7 +4,8 @@ describe 'Issue Boards', feature: true, js: true do include WaitForAjax include WaitForVueResource - let(:project) { create(:project_with_board, :public) } + let(:project) { create(:empty_project, :public) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } let!(:user2) { create(:user) } @@ -468,7 +469,7 @@ describe 'Issue Boards', feature: true, js: true do it 'removes filtered labels' do wait_for_vue_resource - + page.within '.labels-filter' do click_button('Label') wait_for_ajax diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index c046e6b8d79..1ceb60d5297 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -4,7 +4,8 @@ describe 'Issue Boards new issue', feature: true, js: true do include WaitForAjax include WaitForVueResource - let(:project) { create(:project_with_board, :public) } + let(:project) { create(:empty_project, :public) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } context 'authorized user' do diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb index 218a6d2bc2f..d9eb757f986 100644 --- a/spec/services/boards/issues/list_service_spec.rb +++ b/spec/services/boards/issues/list_service_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe Boards::Issues::ListService, services: true do describe '#execute' do let(:user) { create(:user) } - let(:project) { create(:project_with_board) } + let(:project) { create(:empty_project) } let(:board) { create(:board, project: project) } let(:bug) { create(:label, project: project, name: 'Bug') } diff --git a/spec/services/boards/lists/destroy_service_spec.rb b/spec/services/boards/lists/destroy_service_spec.rb index 474c4512471..628caf03476 100644 --- a/spec/services/boards/lists/destroy_service_spec.rb +++ b/spec/services/boards/lists/destroy_service_spec.rb @@ -2,8 +2,8 @@ require 'spec_helper' describe Boards::Lists::DestroyService, services: true do describe '#execute' do - let(:project) { create(:project_with_board) } - let(:board) { project.board } + let(:project) { create(:empty_project) } + let(:board) { create(:board, project: project) } let(:user) { create(:user) } context 'when list type is label' do @@ -15,11 +15,11 @@ describe Boards::Lists::DestroyService, services: true do end it 'decrements position of higher lists' do - backlog = project.board.backlog_list + backlog = board.backlog_list development = create(:list, board: board, position: 0) review = create(:list, board: board, position: 1) staging = create(:list, board: board, position: 2) - done = project.board.done_list + done = board.done_list described_class.new(project, user).execute(development) @@ -31,14 +31,14 @@ describe Boards::Lists::DestroyService, services: true do end it 'does not remove list from board when list type is backlog' do - list = project.board.backlog_list + list = board.backlog_list service = described_class.new(project, user) expect { service.execute(list) }.not_to change(board.lists, :count) end it 'does not remove list from board when list type is done' do - list = project.board.done_list + list = board.done_list service = described_class.new(project, user) expect { service.execute(list) }.not_to change(board.lists, :count) diff --git a/spec/services/boards/lists/list_service_spec.rb b/spec/services/boards/lists/list_service_spec.rb index 4464f80f796..334cee3f06d 100644 --- a/spec/services/boards/lists/list_service_spec.rb +++ b/spec/services/boards/lists/list_service_spec.rb @@ -6,13 +6,11 @@ describe Boards::Lists::ListService, services: true do project = create(:empty_project) board = create(:board, project: project) label = create(:label, project: project) - backlog_list = create(:backlog_list, board: board) list = create(:list, board: board, label: label) - done_list = create(:done_list, board: board) service = described_class.new(project, double) - expect(service.execute(board)).to eq [backlog_list, list, done_list] + expect(service.execute(board)).to eq [board.backlog_list, list, board.done_list] end end end -- cgit v1.2.1 From e171c1d80debd88d1aa3a3c74d1937b68a7f0f18 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Thu, 6 Oct 2016 17:36:46 -0300 Subject: Update Issue Board API to handle with has_many association --- lib/api/boards.rb | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/api/boards.rb b/lib/api/boards.rb index 4d5d144a02e..9b71d335128 100644 --- a/lib/api/boards.rb +++ b/lib/api/boards.rb @@ -7,13 +7,14 @@ module API # Get the project board get ':id/boards' do authorize!(:read_board, user_project) - present [user_project.board], with: Entities::Board + present user_project.boards, with: Entities::Board end segment ':id/boards/:board_id' do helpers do def project_board - board = user_project.board + board = user_project.boards.first + if params[:board_id].to_i == board.id board else @@ -55,8 +56,10 @@ module API authorize!(:admin_list, user_project) - list = ::Boards::Lists::CreateService.new(user_project, current_user, - { label_id: params[:label_id] }).execute + service = ::Boards::Lists::CreateService.new(user_project, current_user, + { label_id: params[:label_id] }) + + list = service.execute(project_board) if list.valid? present list, with: Entities::List @@ -78,10 +81,10 @@ module API authorize!(:admin_list, user_project) - moved = ::Boards::Lists::MoveService.new(user_project, current_user, - { position: params[:position].to_i }).execute(list) + service = ::Boards::Lists::MoveService.new(user_project, current_user, + { position: params[:position].to_i }) - if moved + if service.execute(list) present list, with: Entities::List else render_api_error!({ error: "List could not be moved!" }, 400) @@ -97,16 +100,16 @@ module API # Example Request: # DELETE /projects/:id/boards/:board_id/lists/:list_id delete "/lists/:list_id" do - list = board_lists.find_by(id: params[:list_id]) - authorize!(:admin_list, user_project) - if list - destroyed_list = ::Boards::Lists::DestroyService.new( - user_project, current_user).execute(list) - present destroyed_list, with: Entities::List + list = board_lists.find(params[:list_id]) + + service = ::Boards::Lists::DestroyService.new(user_project, current_user) + + if service.execute(list) + present list, with: Entities::List else - not_found!('List') + render_api_error!({ error: 'List could not be deleted!' }, 400) end end end -- cgit v1.2.1 From 478b3d64f8cc7a47c5d1fc0507036590417b8aa8 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Fri, 7 Oct 2016 16:46:32 -0300 Subject: Remove Boards::BaseService --- app/services/boards/base_service.rb | 4 ---- app/services/boards/create_service.rb | 2 +- app/services/boards/issues/create_service.rb | 2 +- app/services/boards/issues/list_service.rb | 2 +- app/services/boards/issues/move_service.rb | 2 +- app/services/boards/list_service.rb | 2 +- app/services/boards/lists/create_service.rb | 2 +- app/services/boards/lists/destroy_service.rb | 2 +- app/services/boards/lists/generate_service.rb | 2 +- app/services/boards/lists/list_service.rb | 2 +- app/services/boards/lists/move_service.rb | 2 +- 11 files changed, 10 insertions(+), 14 deletions(-) delete mode 100644 app/services/boards/base_service.rb diff --git a/app/services/boards/base_service.rb b/app/services/boards/base_service.rb deleted file mode 100644 index 7eacacbaf7e..00000000000 --- a/app/services/boards/base_service.rb +++ /dev/null @@ -1,4 +0,0 @@ -module Boards - class BaseService < ::BaseService - end -end diff --git a/app/services/boards/create_service.rb b/app/services/boards/create_service.rb index a9dbd76a44a..9bdd7b6f0cf 100644 --- a/app/services/boards/create_service.rb +++ b/app/services/boards/create_service.rb @@ -1,5 +1,5 @@ module Boards - class CreateService < Boards::BaseService + class CreateService < BaseService def execute if project.boards.empty? create_board! diff --git a/app/services/boards/issues/create_service.rb b/app/services/boards/issues/create_service.rb index a181e74043b..c0d7ff5b585 100644 --- a/app/services/boards/issues/create_service.rb +++ b/app/services/boards/issues/create_service.rb @@ -1,6 +1,6 @@ module Boards module Issues - class CreateService < Boards::BaseService + class CreateService < BaseService def execute create_issue(params.merge(label_ids: [list.label_id])) end diff --git a/app/services/boards/issues/list_service.rb b/app/services/boards/issues/list_service.rb index 782dbf0db1a..fd4a462c7b2 100644 --- a/app/services/boards/issues/list_service.rb +++ b/app/services/boards/issues/list_service.rb @@ -1,6 +1,6 @@ module Boards module Issues - class ListService < Boards::BaseService + class ListService < BaseService def execute issues = IssuesFinder.new(current_user, filter_params).execute issues = without_board_labels(issues) unless list.movable? diff --git a/app/services/boards/issues/move_service.rb b/app/services/boards/issues/move_service.rb index 9a16609a8b5..96554a92a02 100644 --- a/app/services/boards/issues/move_service.rb +++ b/app/services/boards/issues/move_service.rb @@ -1,6 +1,6 @@ module Boards module Issues - class MoveService < Boards::BaseService + class MoveService < BaseService def execute(issue) return false unless can?(current_user, :update_issue, issue) return false unless valid_move? diff --git a/app/services/boards/list_service.rb b/app/services/boards/list_service.rb index cca4bdd82a2..84f1fc3a4e2 100644 --- a/app/services/boards/list_service.rb +++ b/app/services/boards/list_service.rb @@ -1,5 +1,5 @@ module Boards - class ListService < Boards::BaseService + class ListService < BaseService def execute create_board! if project.boards.empty? project.boards diff --git a/app/services/boards/lists/create_service.rb b/app/services/boards/lists/create_service.rb index da6f59c0399..abc7aeece39 100644 --- a/app/services/boards/lists/create_service.rb +++ b/app/services/boards/lists/create_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class CreateService < Boards::BaseService + class CreateService < BaseService def execute(board) List.transaction do label = project.labels.find(params[:label_id]) diff --git a/app/services/boards/lists/destroy_service.rb b/app/services/boards/lists/destroy_service.rb index d75c5fd3dc6..f986e05944c 100644 --- a/app/services/boards/lists/destroy_service.rb +++ b/app/services/boards/lists/destroy_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class DestroyService < Boards::BaseService + class DestroyService < BaseService def execute(list) return false unless list.destroyable? diff --git a/app/services/boards/lists/generate_service.rb b/app/services/boards/lists/generate_service.rb index 686e4e4b336..d8048f1c67e 100644 --- a/app/services/boards/lists/generate_service.rb +++ b/app/services/boards/lists/generate_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class GenerateService < Boards::BaseService + class GenerateService < BaseService def execute(board) return false unless board.lists.movable.empty? diff --git a/app/services/boards/lists/list_service.rb b/app/services/boards/lists/list_service.rb index ff739bc7d9c..c579ed4c869 100644 --- a/app/services/boards/lists/list_service.rb +++ b/app/services/boards/lists/list_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class ListService < Boards::BaseService + class ListService < BaseService def execute(board) board.lists end diff --git a/app/services/boards/lists/move_service.rb b/app/services/boards/lists/move_service.rb index 7d0730e8332..f2a68865f7b 100644 --- a/app/services/boards/lists/move_service.rb +++ b/app/services/boards/lists/move_service.rb @@ -1,6 +1,6 @@ module Boards module Lists - class MoveService < Boards::BaseService + class MoveService < BaseService def execute(list) @board = list.board @old_position = list.position -- cgit v1.2.1 From 7be133aa36c4160c31010dc74af002320e9070b8 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Fri, 7 Oct 2016 17:06:27 -0300 Subject: Fix typo on Boards::Issues::ListService spec --- spec/services/boards/issues/list_service_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/services/boards/issues/list_service_spec.rb b/spec/services/boards/issues/list_service_spec.rb index d9eb757f986..7c206cf3ce7 100644 --- a/spec/services/boards/issues/list_service_spec.rb +++ b/spec/services/boards/issues/list_service_spec.rb @@ -70,7 +70,7 @@ describe Boards::Issues::ListService, services: true do end end - context 'with list that does not belongs to the board' do + context 'with list that does not belong to the board' do it 'raises an error' do list = create(:list) service = described_class.new(project, user, board_id: board.id, id: list.id) -- cgit v1.2.1 From c5ea58b63007b404a725f28eaae33f5f11d8d925 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Mon, 10 Oct 2016 14:36:09 +0100 Subject: Update endpoint path for the frontend --- app/views/projects/boards/index.html.haml | 19 +++++++++++++++++++ app/views/projects/boards/show.html.haml | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/app/views/projects/boards/index.html.haml b/app/views/projects/boards/index.html.haml index e69de29bb2d..7a1f0ee4428 100644 --- a/app/views/projects/boards/index.html.haml +++ b/app/views/projects/boards/index.html.haml @@ -0,0 +1,19 @@ +- @no_container = true +- @content_class = "issue-boards-content" +- page_title "Boards" + +- content_for :page_specific_javascripts do + = page_specific_javascript_tag('boards/boards_bundle.js') + = page_specific_javascript_tag('boards/test_utils/simulate_drag.js') if Rails.env.test? + += render "projects/issues/head" + += render 'shared/issuable/filter', type: :boards + +.boards-list#board-app{ "v-cloak" => true, + "data-endpoint" => "#{namespace_project_board_path(@project.namespace, @project, @boards.first)}", + "data-disabled" => "#{!can?(current_user, :admin_list, @project)}", + "data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" } + .boards-app-loading.text-center{ "v-if" => "loading" } + = icon("spinner spin") + = render "projects/boards/components/board" diff --git a/app/views/projects/boards/show.html.haml b/app/views/projects/boards/show.html.haml index 5b441b48caf..7bc476264b1 100644 --- a/app/views/projects/boards/show.html.haml +++ b/app/views/projects/boards/show.html.haml @@ -11,7 +11,7 @@ = render 'shared/issuable/filter', type: :boards .boards-list#board-app{ "v-cloak" => true, - "data-endpoint" => "#{namespace_project_boards_path(@project.namespace, @project)}", + "data-endpoint" => "#{namespace_project_board_path(@project.namespace, @project, @board)}", "data-disabled" => "#{!can?(current_user, :admin_list, @project)}", "data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" } .boards-app-loading.text-center{ "v-if" => "loading" } -- cgit v1.2.1 From 2ad531f5e279bcd278600d1f95ff9d4e4988b034 Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Mon, 10 Oct 2016 11:22:30 -0300 Subject: Add Project::BoardLimitExcedeed error class --- app/models/project.rb | 4 +++- spec/models/project_spec.rb | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/models/project.rb b/app/models/project.rb index 30db7ed50b3..758927edd5c 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -16,6 +16,8 @@ class Project < ActiveRecord::Base extend Gitlab::ConfigHelper + class BoardLimitExceeded < StandardError; end + NUMBER_OF_PERMITTED_BOARDS = 1 UNKNOWN_IMPORT_URL = 'http://unknown.git' @@ -1341,6 +1343,6 @@ class Project < ActiveRecord::Base end def validate_board_limit(board) - raise StandardError, 'Number of permitted boards exceeded' if boards.size >= NUMBER_OF_PERMITTED_BOARDS + raise BoardLimitExceeded, 'Number of permitted boards exceeded' if boards.size >= NUMBER_OF_PERMITTED_BOARDS end end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 1b13f1be477..308a00db9cd 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -99,7 +99,7 @@ describe Project, models: true do it 'raises an error when attempting to add more than one board to the project' do subject.boards.build - expect { subject.boards.build }.to raise_error(StandardError, 'Number of permitted boards exceeded') + expect { subject.boards.build }.to raise_error(Project::BoardLimitExceeded, 'Number of permitted boards exceeded') expect(subject.boards.size).to eq 1 end end -- cgit v1.2.1 From 53f50edf4dac5133ff4d67a67ba5071e3eb7e78a Mon Sep 17 00:00:00 2001 From: Douglas Barbosa Alexandre Date: Mon, 10 Oct 2016 23:29:20 -0300 Subject: Fix board relates specs --- app/controllers/projects/boards_controller.rb | 2 +- spec/features/boards/boards_spec.rb | 16 ++++++++-------- spec/features/boards/keyboard_shortcut_spec.rb | 4 +--- spec/features/boards/new_issue_spec.rb | 4 ++-- spec/fixtures/api/schemas/board.json | 3 +-- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/app/controllers/projects/boards_controller.rb b/app/controllers/projects/boards_controller.rb index bbb1b1bf1e1..808affa4f98 100644 --- a/app/controllers/projects/boards_controller.rb +++ b/app/controllers/projects/boards_controller.rb @@ -32,6 +32,6 @@ class Projects::BoardsController < Projects::ApplicationController end def serialize_as_json(resource) - resource.as_json(only: [:id, :name]) + resource.as_json(only: [:id]) end end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index f79b6a77696..0fb1608a0a3 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -18,7 +18,7 @@ describe 'Issue Boards', feature: true, js: true do context 'no lists' do before do - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource expect(page).to have_selector('.board', count: 3) end @@ -61,8 +61,8 @@ describe 'Issue Boards', feature: true, js: true do let!(:done) { create(:label, project: project, name: 'Done') } let!(:accepting) { create(:label, project: project, name: 'Accepting Merge Requests') } - let!(:list1) { create(:list, board: project.board, label: planning, position: 0) } - let!(:list2) { create(:list, board: project.board, label: development, position: 1) } + let!(:list1) { create(:list, board: board, label: planning, position: 0) } + let!(:list2) { create(:list, board: board, label: development, position: 1) } let!(:confidential_issue) { create(:issue, :confidential, project: project, author: user) } let!(:issue1) { create(:issue, project: project, assignee: user) } @@ -76,7 +76,7 @@ describe 'Issue Boards', feature: true, js: true do let!(:issue9) { create(:labeled_issue, project: project, labels: [testing, bug, accepting]) } before do - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource @@ -170,7 +170,7 @@ describe 'Issue Boards', feature: true, js: true do create(:issue, project: project) end - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource page.within(find('.board', match: :first)) do @@ -604,7 +604,7 @@ describe 'Issue Boards', feature: true, js: true do context 'keyboard shortcuts' do before do - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource end @@ -617,7 +617,7 @@ describe 'Issue Boards', feature: true, js: true do context 'signed out user' do before do logout - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource end @@ -633,7 +633,7 @@ describe 'Issue Boards', feature: true, js: true do project.team << [user_guest, :guest] logout login_as(user_guest) - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource end diff --git a/spec/features/boards/keyboard_shortcut_spec.rb b/spec/features/boards/keyboard_shortcut_spec.rb index 7ef68e9eb8d..a5fc766401f 100644 --- a/spec/features/boards/keyboard_shortcut_spec.rb +++ b/spec/features/boards/keyboard_shortcut_spec.rb @@ -6,9 +6,7 @@ describe 'Issue Boards shortcut', feature: true, js: true do let(:project) { create(:empty_project) } before do - project.create_board - project.board.lists.create(list_type: :backlog) - project.board.lists.create(list_type: :done) + create(:board, project: project) login_as :admin diff --git a/spec/features/boards/new_issue_spec.rb b/spec/features/boards/new_issue_spec.rb index 1ceb60d5297..67d6da5f39a 100644 --- a/spec/features/boards/new_issue_spec.rb +++ b/spec/features/boards/new_issue_spec.rb @@ -14,7 +14,7 @@ describe 'Issue Boards new issue', feature: true, js: true do login_as(user) - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource expect(page).to have_selector('.board', count: 3) @@ -70,7 +70,7 @@ describe 'Issue Boards new issue', feature: true, js: true do context 'unauthorized user' do before do - visit namespace_project_board_path(project.namespace, project) + visit namespace_project_board_path(project.namespace, project, board) wait_for_vue_resource end diff --git a/spec/fixtures/api/schemas/board.json b/spec/fixtures/api/schemas/board.json index 6c6e2bee8cb..03aca4a3cc0 100644 --- a/spec/fixtures/api/schemas/board.json +++ b/spec/fixtures/api/schemas/board.json @@ -1,8 +1,7 @@ { "type": "object", "required" : [ - "id", - "name" + "id" ], "properties" : { "id": { "type": "integer" }, -- cgit v1.2.1 From dc49ee6247e041020e96c5d5be292e3f92926c4d Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 11 Oct 2016 09:29:47 +0100 Subject: Updated to pass the board ID with the boards root to save conflicts with EE --- app/assets/javascripts/boards/boards_bundle.js.es6 | 3 ++- app/assets/javascripts/boards/services/board_service.js.es6 | 10 +++++----- app/views/projects/boards/index.html.haml | 3 ++- app/views/projects/boards/show.html.haml | 3 ++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/assets/javascripts/boards/boards_bundle.js.es6 b/app/assets/javascripts/boards/boards_bundle.js.es6 index 91c12570e09..d4f8f4b9420 100644 --- a/app/assets/javascripts/boards/boards_bundle.js.es6 +++ b/app/assets/javascripts/boards/boards_bundle.js.es6 @@ -28,12 +28,13 @@ $(() => { state: Store.state, loading: true, endpoint: $boardApp.dataset.endpoint, + boardId: $boardApp.dataset.boardId, disabled: $boardApp.dataset.disabled === 'true', issueLinkBase: $boardApp.dataset.issueLinkBase }, init: Store.create.bind(Store), created () { - gl.boardService = new BoardService(this.endpoint); + gl.boardService = new BoardService(this.endpoint, this.boardId); }, ready () { Store.disabled = this.disabled; diff --git a/app/assets/javascripts/boards/services/board_service.js.es6 b/app/assets/javascripts/boards/services/board_service.js.es6 index 2b825c3949f..b9c91cbf31e 100644 --- a/app/assets/javascripts/boards/services/board_service.js.es6 +++ b/app/assets/javascripts/boards/services/board_service.js.es6 @@ -1,15 +1,15 @@ class BoardService { - constructor (root) { + constructor (root, boardId) { Vue.http.options.root = root; - this.lists = Vue.resource(`${root}/lists{/id}`, {}, { + this.lists = Vue.resource(`${root}/${boardId}/lists{/id}`, {}, { generate: { method: 'POST', - url: `${root}/lists/generate.json` + url: `${root}/${boardId}/lists/generate.json` } }); - this.issue = Vue.resource(`${root}/issues{/id}`, {}); - this.issues = Vue.resource(`${root}/lists{/id}/issues`, {}); + this.issue = Vue.resource(`${root}/${boardId}/issues{/id}`, {}); + this.issues = Vue.resource(`${root}/${boardId}/lists{/id}/issues`, {}); Vue.http.interceptors.push((request, next) => { request.headers['X-CSRF-Token'] = $.rails.csrfToken(); diff --git a/app/views/projects/boards/index.html.haml b/app/views/projects/boards/index.html.haml index 7a1f0ee4428..9252bbc08c1 100644 --- a/app/views/projects/boards/index.html.haml +++ b/app/views/projects/boards/index.html.haml @@ -11,7 +11,8 @@ = render 'shared/issuable/filter', type: :boards .boards-list#board-app{ "v-cloak" => true, - "data-endpoint" => "#{namespace_project_board_path(@project.namespace, @project, @boards.first)}", + "data-endpoint" => "#{namespace_project_boards_path(@project.namespace, @project)}", + "data-board-id" => "#{@boards.first.id}", "data-disabled" => "#{!can?(current_user, :admin_list, @project)}", "data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" } .boards-app-loading.text-center{ "v-if" => "loading" } diff --git a/app/views/projects/boards/show.html.haml b/app/views/projects/boards/show.html.haml index 7bc476264b1..d6e1ac5f3cf 100644 --- a/app/views/projects/boards/show.html.haml +++ b/app/views/projects/boards/show.html.haml @@ -11,7 +11,8 @@ = render 'shared/issuable/filter', type: :boards .boards-list#board-app{ "v-cloak" => true, - "data-endpoint" => "#{namespace_project_board_path(@project.namespace, @project, @board)}", + "data-endpoint" => "#{namespace_project_boards_path(@project.namespace, @project)}", + "data-board-id" => "#{@board.id}", "data-disabled" => "#{!can?(current_user, :admin_list, @project)}", "data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" } .boards-app-loading.text-center{ "v-if" => "loading" } -- cgit v1.2.1 From 53b3c62e0f889d077ee5b19703c3e04384c85c03 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Tue, 11 Oct 2016 16:07:53 +0100 Subject: Fixed JS tests --- spec/javascripts/boards/boards_store_spec.js.es6 | 2 +- spec/javascripts/boards/issue_spec.js.es6 | 2 +- spec/javascripts/boards/list_spec.js.es6 | 2 +- spec/javascripts/boards/mock_data.js.es6 | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/spec/javascripts/boards/boards_store_spec.js.es6 b/spec/javascripts/boards/boards_store_spec.js.es6 index 078e4b00023..15c305ce321 100644 --- a/spec/javascripts/boards/boards_store_spec.js.es6 +++ b/spec/javascripts/boards/boards_store_spec.js.es6 @@ -14,7 +14,7 @@ (() => { beforeEach(() => { - gl.boardService = new BoardService('/test/issue-boards/board'); + gl.boardService = new BoardService('/test/issue-boards/board', '1'); gl.issueBoards.BoardsStore.create(); $.cookie('issue_board_welcome_hidden', 'false'); diff --git a/spec/javascripts/boards/issue_spec.js.es6 b/spec/javascripts/boards/issue_spec.js.es6 index 3569d1b98bd..328c6f82ab5 100644 --- a/spec/javascripts/boards/issue_spec.js.es6 +++ b/spec/javascripts/boards/issue_spec.js.es6 @@ -16,7 +16,7 @@ describe('Issue model', () => { let issue; beforeEach(() => { - gl.boardService = new BoardService('/test/issue-boards/board'); + gl.boardService = new BoardService('/test/issue-boards/board', '1'); gl.issueBoards.BoardsStore.create(); issue = new ListIssue({ diff --git a/spec/javascripts/boards/list_spec.js.es6 b/spec/javascripts/boards/list_spec.js.es6 index 1688b996162..ec78d82e919 100644 --- a/spec/javascripts/boards/list_spec.js.es6 +++ b/spec/javascripts/boards/list_spec.js.es6 @@ -16,7 +16,7 @@ describe('List model', () => { let list; beforeEach(() => { - gl.boardService = new BoardService('/test/issue-boards/board'); + gl.boardService = new BoardService('/test/issue-boards/board', '1'); gl.issueBoards.BoardsStore.create(); list = new List(listObj); diff --git a/spec/javascripts/boards/mock_data.js.es6 b/spec/javascripts/boards/mock_data.js.es6 index f3797ed44d4..052455f2ca6 100644 --- a/spec/javascripts/boards/mock_data.js.es6 +++ b/spec/javascripts/boards/mock_data.js.es6 @@ -26,7 +26,7 @@ const listObjDuplicate = { const BoardsMockData = { 'GET': { - '/test/issue-boards/board/lists{/id}/issues': { + '/test/issue-boards/board/1/lists{/id}/issues': { issues: [{ title: 'Testing', iid: 1, @@ -37,13 +37,13 @@ const BoardsMockData = { } }, 'POST': { - '/test/issue-boards/board/lists{/id}': listObj + '/test/issue-boards/board/1/lists{/id}': listObj }, 'PUT': { - '/test/issue-boards/board/lists{/id}': {} + '/test/issue-boards/board/1/lists{/id}': {} }, 'DELETE': { - '/test/issue-boards/board/lists{/id}': {} + '/test/issue-boards/board/1/lists{/id}': {} } }; -- cgit v1.2.1 From f76f569bb87803b14c763427fc2875cca7dda892 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 12 Oct 2016 12:50:47 +0100 Subject: Moved data attribute values into helper method --- app/helpers/boards_helper.rb | 12 ++++++++++++ app/views/projects/boards/index.html.haml | 6 +----- app/views/projects/boards/show.html.haml | 6 +----- 3 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 app/helpers/boards_helper.rb diff --git a/app/helpers/boards_helper.rb b/app/helpers/boards_helper.rb new file mode 100644 index 00000000000..b7247ffa8b2 --- /dev/null +++ b/app/helpers/boards_helper.rb @@ -0,0 +1,12 @@ +module BoardsHelper + def board_data + board = @board || @boards.first + + { + endpoint: namespace_project_boards_path(@project.namespace, @project), + board_id: board.id, + disabled: !can?(current_user, :admin_list, @project), + issue_link_base: namespace_project_issues_path(@project.namespace, @project) + } + end +end diff --git a/app/views/projects/boards/index.html.haml b/app/views/projects/boards/index.html.haml index 9252bbc08c1..885f8e34b55 100644 --- a/app/views/projects/boards/index.html.haml +++ b/app/views/projects/boards/index.html.haml @@ -10,11 +10,7 @@ = render 'shared/issuable/filter', type: :boards -.boards-list#board-app{ "v-cloak" => true, - "data-endpoint" => "#{namespace_project_boards_path(@project.namespace, @project)}", - "data-board-id" => "#{@boards.first.id}", - "data-disabled" => "#{!can?(current_user, :admin_list, @project)}", - "data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" } +.boards-list#board-app{ "v-cloak" => true, data: board_data } .boards-app-loading.text-center{ "v-if" => "loading" } = icon("spinner spin") = render "projects/boards/components/board" diff --git a/app/views/projects/boards/show.html.haml b/app/views/projects/boards/show.html.haml index d6e1ac5f3cf..885f8e34b55 100644 --- a/app/views/projects/boards/show.html.haml +++ b/app/views/projects/boards/show.html.haml @@ -10,11 +10,7 @@ = render 'shared/issuable/filter', type: :boards -.boards-list#board-app{ "v-cloak" => true, - "data-endpoint" => "#{namespace_project_boards_path(@project.namespace, @project)}", - "data-board-id" => "#{@board.id}", - "data-disabled" => "#{!can?(current_user, :admin_list, @project)}", - "data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" } +.boards-list#board-app{ "v-cloak" => true, data: board_data } .boards-app-loading.text-center{ "v-if" => "loading" } = icon("spinner spin") = render "projects/boards/components/board" -- cgit v1.2.1 From 25c82c6faf067a82e99bad590357ad57618475d9 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Wed, 12 Oct 2016 17:43:20 +0100 Subject: Updated JS to work with issue index & show --- app/assets/javascripts/dispatcher.js | 1 + app/assets/javascripts/labels_select.js | 4 ++-- app/assets/javascripts/milestone_select.js | 2 +- app/assets/javascripts/users_select.js | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js index adff73af79c..f3ef13ce20e 100644 --- a/app/assets/javascripts/dispatcher.js +++ b/app/assets/javascripts/dispatcher.js @@ -21,6 +21,7 @@ shortcut_handler = null; switch (page) { case 'projects:boards:show': + case 'projects:boards:index': shortcut_handler = new ShortcutsNavigation(); break; case 'projects:merge_requests:index': diff --git a/app/assets/javascripts/labels_select.js b/app/assets/javascripts/labels_select.js index e356872624a..f1e719937c7 100644 --- a/app/assets/javascripts/labels_select.js +++ b/app/assets/javascripts/labels_select.js @@ -292,7 +292,7 @@ return; } - if (page === 'projects:boards:show') { + if ($('html').hasClass('issue-boards-page')) { return; } if ($dropdown.hasClass('js-multiselect')) { @@ -334,7 +334,7 @@ page = $('body').data('page'); isIssueIndex = page === 'projects:issues:index'; isMRIndex = page === 'projects:merge_requests:index'; - if (page === 'projects:boards:show') { + if ($('html').hasClass('issue-boards-page')) { if (label.isAny) { gl.issueBoards.BoardsStore.state.filters['label_name'] = []; } diff --git a/app/assets/javascripts/milestone_select.js b/app/assets/javascripts/milestone_select.js index 26cc6eb0e96..cee42633c79 100644 --- a/app/assets/javascripts/milestone_select.js +++ b/app/assets/javascripts/milestone_select.js @@ -110,7 +110,7 @@ e.preventDefault(); return; } - if (page === 'projects:boards:show') { + if ($('html').hasClass('issue-boards-page')) { gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = selected.name; gl.issueBoards.BoardsStore.updateFiltersUrl(); e.preventDefault(); diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js index bcabda3ceb2..4c071f334fd 100644 --- a/app/assets/javascripts/users_select.js +++ b/app/assets/javascripts/users_select.js @@ -160,7 +160,7 @@ selectedId = user.id; return; } - if (page === 'projects:boards:show') { + if ($('html').hasClass('issue-boards-page')) { selectedId = user.id; gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = user.id; gl.issueBoards.BoardsStore.updateFiltersUrl(); -- cgit v1.2.1