diff options
author | Connor Shea <connor.james.shea@gmail.com> | 2016-08-17 12:10:09 -0600 |
---|---|---|
committer | Connor Shea <connor.james.shea@gmail.com> | 2016-08-17 12:10:09 -0600 |
commit | d8654744cd6c8fa4cbe4617c2428cd79d4bd5179 (patch) | |
tree | 159d92727944184792c939210b5b73aaf348336a /spec/controllers | |
parent | 4a13aa9f34ab4114bc485e1ca8fa0db8daa0394b (diff) | |
parent | 46dc00631aeae34c1964888625c5ccd04da6b4c1 (diff) | |
download | gitlab-ce-d8654744cd6c8fa4cbe4617c2428cd79d4bd5179.tar.gz |
Merge branch 'master' into diff-line-comment-vuejs
Diffstat (limited to 'spec/controllers')
4 files changed, 540 insertions, 0 deletions
diff --git a/spec/controllers/projects/boards/issues_controller_spec.rb b/spec/controllers/projects/boards/issues_controller_spec.rb new file mode 100644 index 00000000000..d0ad5e26dbd --- /dev/null +++ b/spec/controllers/projects/boards/issues_controller_spec.rb @@ -0,0 +1,120 @@ +require 'spec_helper' + +describe Projects::Boards::IssuesController do + let(:project) { create(:project_with_board) } + let(:user) { 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) } + + before do + project.team << [user, :master] + end + + describe 'GET index' do + context 'with valid list id' do + it 'returns issues that have the list label applied' do + johndoe = create(:user, avatar: fixture_file_upload(File.join(Rails.root, 'spec/fixtures/dk.png'))) + create(:labeled_issue, project: project, labels: [planning]) + create(:labeled_issue, project: project, labels: [development]) + create(:labeled_issue, project: project, labels: [development], assignee: johndoe) + + list_issues user: user, list_id: list2 + + parsed_response = JSON.parse(response.body) + + expect(response).to match_response_schema('issues') + expect(parsed_response.length).to eq 2 + end + end + + context 'with invalid list id' do + it 'returns a not found 404 response' do + list_issues user: user, list_id: 999 + + expect(response).to have_http_status(404) + end + end + + context 'with unauthorized user' do + before do + allow(Ability.abilities).to receive(:allowed?).with(user, :read_project, project).and_return(true) + allow(Ability.abilities).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 + + expect(response).to have_http_status(403) + end + end + + def list_issues(user:, list_id:) + sign_in(user) + + get :index, namespace_id: project.namespace.to_param, + project_id: project.to_param, + list_id: list_id.to_param + end + end + + describe 'PATCH update' do + let(:issue) { create(:labeled_issue, project: project, labels: [planning]) } + + 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 + + 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 + + expect(issue.reload.labels).to contain_exactly(development) + end + end + + 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 + + expect(response).to have_http_status(422) + 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 + + 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 successful 403 response' do + move user: guest, 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:) + sign_in(user) + + patch :update, namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: issue.to_param, + from_list_id: from_list_id, + to_list_id: to_list_id, + format: :json + end + end +end diff --git a/spec/controllers/projects/boards/lists_controller_spec.rb b/spec/controllers/projects/boards/lists_controller_spec.rb new file mode 100644 index 00000000000..9496636e3cc --- /dev/null +++ b/spec/controllers/projects/boards/lists_controller_spec.rb @@ -0,0 +1,241 @@ +require 'spec_helper' + +describe Projects::Boards::ListsController do + let(:project) { create(:project_with_board) } + let(:board) { project.board } + let(:user) { create(:user) } + let(:guest) { create(:user) } + + before do + project.team << [user, :master] + project.team << [guest, :guest] + end + + describe 'GET index' do + it 'returns a successful 200 response' do + read_board_list user: user + + expect(response).to have_http_status(200) + expect(response.content_type).to eq 'application/json' + end + + it 'returns a list of board lists' do + board = project.create_board + create(:backlog_list, board: board) + create(:list, board: board) + create(:done_list, board: board) + + read_board_list user: user + + parsed_response = JSON.parse(response.body) + + expect(response).to match_response_schema('lists') + expect(parsed_response.length).to eq 3 + end + + context 'with unauthorized user' do + before do + allow(Ability.abilities).to receive(:allowed?).with(user, :read_project, project).and_return(true) + allow(Ability.abilities).to receive(:allowed?).with(user, :read_list, project).and_return(false) + end + + it 'returns a successful 403 response' do + read_board_list user: user + + expect(response).to have_http_status(403) + end + end + + def read_board_list(user:) + sign_in(user) + + get :index, namespace_id: project.namespace.to_param, + project_id: project.to_param, + format: :json + end + end + + describe 'POST create' do + let(:label) { create(:label, project: project, name: 'Development') } + + context 'with valid params' do + it 'returns a successful 200 response' do + create_board_list user: user, 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 + + expect(response).to match_response_schema('list') + end + end + + context 'with invalid params' do + it 'returns an error' do + create_board_list user: user, label_id: nil + + parsed_response = JSON.parse(response.body) + + expect(parsed_response['label']).to contain_exactly "can't be blank" + expect(response).to have_http_status(422) + end + end + + context 'with unauthorized user' do + let(:label) { create(:label, project: project, name: 'Development') } + + it 'returns a successful 403 response' do + create_board_list user: guest, label_id: label.id + + expect(response).to have_http_status(403) + end + end + + def create_board_list(user:, label_id:) + sign_in(user) + + post :create, namespace_id: project.namespace.to_param, + project_id: project.to_param, + list: { label_id: label_id }, + format: :json + end + end + + describe 'PATCH update' do + let!(:planning) { create(:list, board: board, position: 0) } + let!(:development) { create(:list, board: board, position: 1) } + + context 'with valid position' do + it 'returns a successful 200 response' do + move user: user, 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 + + expect(planning.reload.position).to eq 1 + end + end + + context 'with invalid position' do + it 'returns a unprocessable entity 422 response' do + move user: user, list: planning, position: 6 + + expect(response).to have_http_status(422) + end + end + + context 'with invalid list id' do + it 'returns a not found 404 response' do + move user: user, list: 999, position: 1 + + expect(response).to have_http_status(404) + end + end + + context 'with unauthorized user' do + it 'returns a successful 403 response' do + move user: guest, list: planning, position: 6 + + expect(response).to have_http_status(403) + end + end + + def move(user:, list:, position:) + sign_in(user) + + patch :update, namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: list.to_param, + list: { position: position }, + format: :json + end + end + + describe 'DELETE destroy' do + let!(:planning) { create(:list, board: board, position: 0) } + + context 'with valid list id' do + it 'returns a successful 200 response' do + remove_board_list user: user, 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) + end + end + + context 'with invalid list id' do + it 'returns a not found 404 response' do + remove_board_list user: user, list: 999 + + expect(response).to have_http_status(404) + end + end + + context 'with unauthorized user' do + it 'returns a successful 403 response' do + remove_board_list user: guest, list: planning + + expect(response).to have_http_status(403) + end + end + + def remove_board_list(user:, list:) + sign_in(user) + + delete :destroy, namespace_id: project.namespace.to_param, + project_id: project.to_param, + id: list.to_param, + format: :json + end + end + + describe 'POST generate' do + context 'when board lists is empty' do + it 'returns a successful 200 response' do + generate_default_board_lists user: user + + expect(response).to have_http_status(200) + end + + it 'returns the defaults lists' do + generate_default_board_lists user: user + + expect(response).to match_response_schema('lists') + end + end + + context 'when board lists is not empty' do + it 'returns a unprocessable entity 422 response' do + create(:list, board: board) + + generate_default_board_lists user: user + + expect(response).to have_http_status(422) + end + end + + context 'with unauthorized user' do + it 'returns a successful 403 response' do + generate_default_board_lists user: guest + + expect(response).to have_http_status(403) + end + end + + def generate_default_board_lists(user:) + sign_in(user) + + post :generate, namespace_id: project.namespace.to_param, + project_id: project.to_param, + format: :json + end + end +end diff --git a/spec/controllers/projects/boards_controller_spec.rb b/spec/controllers/projects/boards_controller_spec.rb new file mode 100644 index 00000000000..75a6d39e82c --- /dev/null +++ b/spec/controllers/projects/boards_controller_spec.rb @@ -0,0 +1,43 @@ +require 'spec_helper' + +describe Projects::BoardsController do + let(:project) { create(:empty_project) } + let(:user) { create(:user) } + + before do + project.team << [user, :master] + sign_in(user) + 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) + end + + it 'renders HTML template' do + read_board + + expect(response).to render_template :show + expect(response.content_type).to eq 'text/html' + end + + context 'with unauthorized user' do + before do + allow(Ability.abilities).to receive(:allowed?).with(user, :read_project, project).and_return(true) + allow(Ability.abilities).to receive(:allowed?).with(user, :read_board, project).and_return(false) + end + + it 'returns a successful 404 response' do + read_board + + expect(response).to have_http_status(404) + end + end + + def read_board(format: :html) + get :show, namespace_id: project.namespace.to_param, + project_id: project.to_param, + format: format + end + end +end diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb index 69758494543..c64c2b075c5 100644 --- a/spec/controllers/projects/merge_requests_controller_spec.rb +++ b/spec/controllers/projects/merge_requests_controller_spec.rb @@ -4,6 +4,11 @@ describe Projects::MergeRequestsController do let(:project) { create(:project) } let(:user) { create(:user) } let(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } + let(:merge_request_with_conflicts) do + create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start', source_project: project) do |mr| + mr.mark_as_unmergeable + end + end before do sign_in(user) @@ -523,4 +528,135 @@ describe Projects::MergeRequestsController do end end end + + describe 'GET conflicts' do + let(:json_response) { JSON.parse(response.body) } + + context 'when the conflicts cannot be resolved in the UI' do + before do + allow_any_instance_of(Gitlab::Conflict::Parser). + to receive(:parse).and_raise(Gitlab::Conflict::Parser::UnexpectedDelimiter) + + get :conflicts, + namespace_id: merge_request_with_conflicts.project.namespace.to_param, + project_id: merge_request_with_conflicts.project.to_param, + id: merge_request_with_conflicts.iid, + format: 'json' + end + + it 'returns a 200 status code' do + expect(response).to have_http_status(:ok) + end + + it 'returns JSON with a message' do + expect(json_response.keys).to contain_exactly('message', 'type') + end + end + + context 'with valid conflicts' do + before do + get :conflicts, + namespace_id: merge_request_with_conflicts.project.namespace.to_param, + project_id: merge_request_with_conflicts.project.to_param, + id: merge_request_with_conflicts.iid, + format: 'json' + end + + it 'includes meta info about the MR' do + expect(json_response['commit_message']).to include('Merge branch') + expect(json_response['commit_sha']).to match(/\h{40}/) + expect(json_response['source_branch']).to eq(merge_request_with_conflicts.source_branch) + expect(json_response['target_branch']).to eq(merge_request_with_conflicts.target_branch) + end + + it 'includes each file that has conflicts' do + filenames = json_response['files'].map { |file| file['new_path'] } + + expect(filenames).to contain_exactly('files/ruby/popen.rb', 'files/ruby/regex.rb') + end + + it 'splits files into sections with lines' do + json_response['files'].each do |file| + file['sections'].each do |section| + expect(section).to include('conflict', 'lines') + + section['lines'].each do |line| + if section['conflict'] + expect(line['type']).to be_in(['old', 'new']) + expect(line.values_at('old_line', 'new_line')).to contain_exactly(nil, a_kind_of(Integer)) + else + if line['type'].nil? + expect(line['old_line']).not_to eq(nil) + expect(line['new_line']).not_to eq(nil) + else + expect(line['type']).to eq('match') + expect(line['old_line']).to eq(nil) + expect(line['new_line']).to eq(nil) + end + end + end + end + end + end + + it 'has unique section IDs across files' do + section_ids = json_response['files'].flat_map do |file| + file['sections'].map { |section| section['id'] }.compact + end + + expect(section_ids.uniq).to eq(section_ids) + end + end + end + + context 'POST resolve_conflicts' do + let(:json_response) { JSON.parse(response.body) } + let!(:original_head_sha) { merge_request_with_conflicts.diff_head_sha } + + def resolve_conflicts(sections) + post :resolve_conflicts, + namespace_id: merge_request_with_conflicts.project.namespace.to_param, + project_id: merge_request_with_conflicts.project.to_param, + id: merge_request_with_conflicts.iid, + format: 'json', + sections: sections, + commit_message: 'Commit message' + end + + context 'with valid params' do + before do + resolve_conflicts('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_14' => 'head', + '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9' => 'head', + '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_21_21' => 'origin', + '6eb14e00385d2fb284765eb1cd8d420d33d63fc9_49_49' => 'origin') + end + + it 'creates a new commit on the branch' do + expect(original_head_sha).not_to eq(merge_request_with_conflicts.source_branch_head.sha) + expect(merge_request_with_conflicts.source_branch_head.message).to include('Commit message') + end + + it 'returns an OK response' do + expect(response).to have_http_status(:ok) + end + end + + context 'when sections are missing' do + before do + resolve_conflicts('2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_14' => 'head') + end + + it 'returns a 400 error' do + expect(response).to have_http_status(:bad_request) + end + + it 'has a message with the name of the first missing section' do + expect(json_response['message']).to include('6eb14e00385d2fb284765eb1cd8d420d33d63fc9_9_9') + end + + it 'does not create a new commit' do + expect(original_head_sha).to eq(merge_request_with_conflicts.source_branch_head.sha) + end + end + end end |