diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/finders/members_finder_spec.rb | 44 | ||||
-rw-r--r-- | spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js | 55 | ||||
-rw-r--r-- | spec/javascripts/environments/environment_item_spec.js | 5 | ||||
-rw-r--r-- | spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js | 47 | ||||
-rw-r--r-- | spec/lib/gitlab/internal_post_receive/response_spec.rb | 121 | ||||
-rw-r--r-- | spec/mailers/notify_spec.rb | 16 | ||||
-rw-r--r-- | spec/requests/api/internal_spec.rb | 64 | ||||
-rw-r--r-- | spec/requests/api/project_snippets_spec.rb | 42 | ||||
-rw-r--r-- | spec/views/groups/edit.html.haml_spec.rb | 2 |
9 files changed, 315 insertions, 81 deletions
diff --git a/spec/finders/members_finder_spec.rb b/spec/finders/members_finder_spec.rb index 4203f58fe81..6920fb4e572 100644 --- a/spec/finders/members_finder_spec.rb +++ b/spec/finders/members_finder_spec.rb @@ -17,11 +17,10 @@ describe MembersFinder, '#execute' do result = described_class.new(project, user2).execute - expect(result.to_a).to match_array([member1, member2, member3]) + expect(result).to contain_exactly(member1, member2, member3) end - it 'includes nested group members if asked' do - project = create(:project, namespace: group) + it 'includes nested group members if asked', :nested_groups do nested_group.request_access(user1) member1 = group.add_maintainer(user2) member2 = nested_group.add_maintainer(user3) @@ -29,7 +28,28 @@ describe MembersFinder, '#execute' do result = described_class.new(project, user2).execute(include_descendants: true) - expect(result.to_a).to match_array([member1, member2, member3]) + expect(result).to contain_exactly(member1, member2, member3) + end + + it 'returns the members.access_level when the user is invited', :nested_groups do + member_invite = create(:project_member, :invited, project: project, invite_email: create(:user).email) + member1 = group.add_maintainer(user2) + + result = described_class.new(project, user2).execute(include_descendants: true) + + expect(result).to contain_exactly(member1, member_invite) + expect(result.last.access_level).to eq(member_invite.access_level) + end + + it 'returns the highest access_level for the user', :nested_groups do + member1 = project.add_guest(user1) + group.add_developer(user1) + nested_group.add_reporter(user1) + + result = described_class.new(project, user1).execute(include_descendants: true) + + expect(result).to contain_exactly(member1) + expect(result.first.access_level).to eq(Gitlab::Access::DEVELOPER) end context 'when include_invited_groups_members == true' do @@ -37,8 +57,8 @@ describe MembersFinder, '#execute' do set(:linked_group) { create(:group, :public, :access_requestable) } set(:nested_linked_group) { create(:group, parent: linked_group) } - set(:linked_group_member) { linked_group.add_developer(user1) } - set(:nested_linked_group_member) { nested_linked_group.add_developer(user2) } + set(:linked_group_member) { linked_group.add_guest(user1) } + set(:nested_linked_group_member) { nested_linked_group.add_guest(user2) } it 'includes all the invited_groups members including members inherited from ancestor groups' do create(:project_group_link, project: project, group: nested_linked_group) @@ -60,5 +80,17 @@ describe MembersFinder, '#execute' do expect(subject).to contain_exactly(linked_group_member) end + + context 'when the user is a member of invited group and ancestor groups' do + it 'returns the highest access_level for the user limited by project_group_link.group_access', :nested_groups do + create(:project_group_link, project: project, group: nested_linked_group, group_access: Gitlab::Access::REPORTER) + nested_linked_group.add_developer(user1) + + result = subject + + expect(result).to contain_exactly(linked_group_member, nested_linked_group_member) + expect(result.first.access_level).to eq(Gitlab::Access::REPORTER) + end + end end end diff --git a/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js new file mode 100644 index 00000000000..1f4d1e17ea0 --- /dev/null +++ b/spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js @@ -0,0 +1,55 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlLoadingIcon } from '@gitlab/ui'; +import AutoMergeFailedComponent from '~/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue'; +import eventHub from '~/vue_merge_request_widget/event_hub'; + +describe('MRWidgetAutoMergeFailed', () => { + let wrapper; + const mergeError = 'This is the merge error'; + const findButton = () => wrapper.find('button'); + + const createComponent = (props = {}) => { + wrapper = shallowMount(AutoMergeFailedComponent, { + sync: false, + propsData: { ...props }, + }); + }; + + beforeEach(() => { + createComponent({ + mr: { mergeError }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders failed message', () => { + expect(wrapper.text()).toContain('This merge request failed to be merged automatically'); + }); + + it('renders merge error provided', () => { + expect(wrapper.text()).toContain(mergeError); + }); + + it('render refresh button', () => { + expect(findButton().text()).toEqual('Refresh'); + }); + + it('emits event and shows loading icon when button is clicked', () => { + jest.spyOn(eventHub, '$emit'); + findButton().trigger('click'); + + expect(eventHub.$emit.mock.calls[0][0]).toBe('MRWidgetUpdateRequested'); + + return wrapper.vm.$nextTick(() => { + expect(findButton().attributes('disabled')).toEqual('disabled'); + expect( + findButton() + .find(GlLoadingIcon) + .exists(), + ).toBe(true); + }); + }); +}); diff --git a/spec/javascripts/environments/environment_item_spec.js b/spec/javascripts/environments/environment_item_spec.js index 388d7063d13..f9ee4648128 100644 --- a/spec/javascripts/environments/environment_item_spec.js +++ b/spec/javascripts/environments/environment_item_spec.js @@ -106,6 +106,7 @@ describe('Environment item', () => { play_path: '/play', }, ], + deployed_at: '2016-11-29T18:11:58.430Z', }, has_stop_action: true, environment_path: 'root/ci-folders/environments/31', @@ -139,9 +140,7 @@ describe('Environment item', () => { it('should render last deployment date', () => { const timeagoInstance = new timeago(); // eslint-disable-line - const formatedDate = timeagoInstance.format( - environment.last_deployment.deployable.created_at, - ); + const formatedDate = timeagoInstance.format(environment.last_deployment.deployed_at); expect( component.$el.querySelector('.environment-created-date-timeago').textContent, diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js deleted file mode 100644 index 55a11a72551..00000000000 --- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js +++ /dev/null @@ -1,47 +0,0 @@ -import Vue from 'vue'; -import autoMergeFailedComponent from '~/vue_merge_request_widget/components/states/mr_widget_auto_merge_failed.vue'; -import eventHub from '~/vue_merge_request_widget/event_hub'; -import mountComponent from 'spec/helpers/vue_mount_component_helper'; - -describe('MRWidgetAutoMergeFailed', () => { - let vm; - const mergeError = 'This is the merge error'; - - beforeEach(() => { - const Component = Vue.extend(autoMergeFailedComponent); - vm = mountComponent(Component, { - mr: { mergeError }, - }); - }); - - afterEach(() => { - vm.$destroy(); - }); - - it('renders failed message', () => { - expect(vm.$el.textContent).toContain('This merge request failed to be merged automatically'); - }); - - it('renders merge error provided', () => { - expect(vm.$el.innerText).toContain(mergeError); - }); - - it('render refresh button', () => { - expect(vm.$el.querySelector('button').textContent.trim()).toEqual('Refresh'); - }); - - it('emits event and shows loading icon when button is clicked', done => { - spyOn(eventHub, '$emit'); - vm.$el.querySelector('button').click(); - - expect(eventHub.$emit.calls.argsFor(0)[0]).toEqual('MRWidgetUpdateRequested'); - - Vue.nextTick(() => { - expect(vm.$el.querySelector('button').getAttribute('disabled')).toEqual('disabled'); - expect(vm.$el.querySelector('button .loading-container span').classList).toContain( - 'gl-spinner', - ); - done(); - }); - }); -}); diff --git a/spec/lib/gitlab/internal_post_receive/response_spec.rb b/spec/lib/gitlab/internal_post_receive/response_spec.rb new file mode 100644 index 00000000000..f43762c9248 --- /dev/null +++ b/spec/lib/gitlab/internal_post_receive/response_spec.rb @@ -0,0 +1,121 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::InternalPostReceive::Response do + subject { described_class.new } + + describe '#add_merge_request_urls' do + context 'when there are urls_data' do + it 'adds a message for each merge request URL' do + urls_data = [ + { new_merge_request: false, branch_name: 'foo', url: 'http://example.com/foo/bar/merge_requests/1' }, + { new_merge_request: true, branch_name: 'bar', url: 'http://example.com/foo/bar/merge_requests/new?merge_request%5Bsource_branch%5D=bar' } + ] + + subject.add_merge_request_urls(urls_data) + + expected = [a_kind_of(described_class::Message), a_kind_of(described_class::Message)] + expect(subject.messages).to match(expected) + end + end + end + + describe '#add_merge_request_url' do + context 'when :new_merge_request is false' do + it 'adds a basic message to view the existing merge request' do + url_data = { new_merge_request: false, branch_name: 'foo', url: 'http://example.com/foo/bar/merge_requests/1' } + + subject.add_merge_request_url(url_data) + + message = <<~MESSAGE.strip + View merge request for foo: + http://example.com/foo/bar/merge_requests/1 + MESSAGE + + expect(subject.messages.first.message).to eq(message) + expect(subject.messages.first.type).to eq(:basic) + end + end + + context 'when :new_merge_request is true' do + it 'adds a basic message to create a new merge request' do + url_data = { new_merge_request: true, branch_name: 'bar', url: 'http://example.com/foo/bar/merge_requests/new?merge_request%5Bsource_branch%5D=bar' } + + subject.add_merge_request_url(url_data) + + message = <<~MESSAGE.strip + To create a merge request for bar, visit: + http://example.com/foo/bar/merge_requests/new?merge_request%5Bsource_branch%5D=bar + MESSAGE + + expect(subject.messages.first.message).to eq(message) + expect(subject.messages.first.type).to eq(:basic) + end + end + end + + describe '#add_basic_message' do + context 'when text is present' do + it 'adds a basic message' do + subject.add_basic_message('hello') + + expect(subject.messages.first.message).to eq('hello') + expect(subject.messages.first.type).to eq(:basic) + end + end + + context 'when text is blank' do + it 'does not add a message' do + subject.add_basic_message(' ') + + expect(subject.messages).to be_blank + end + end + end + + describe '#add_alert_message' do + context 'when text is present' do + it 'adds a alert message' do + subject.add_alert_message('hello') + + expect(subject.messages.first.message).to eq('hello') + expect(subject.messages.first.type).to eq(:alert) + end + end + + context 'when text is blank' do + it 'does not add a message' do + subject.add_alert_message(' ') + + expect(subject.messages).to be_blank + end + end + end + + describe '#reference_counter_decreased' do + context 'initially' do + it 'reference_counter_decreased is set to false' do + expect(subject.reference_counter_decreased).to eq(false) + end + end + end + + describe '#reference_counter_decreased=' do + context 'when the argument is truthy' do + it 'reference_counter_decreased is truthy' do + subject.reference_counter_decreased = true + + expect(subject.reference_counter_decreased).to be_truthy + end + end + + context 'when the argument is falsey' do + it 'reference_counter_decreased is falsey' do + subject.reference_counter_decreased = false + + expect(subject.reference_counter_decreased).to be_falsey + end + end + end +end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index 6cba7df114c..56fa26d5f23 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -187,6 +187,22 @@ describe Notify do end end + describe 'that are due soon' do + subject { described_class.issue_due_email(recipient.id, issue.id) } + + before do + issue.update(due_date: Date.tomorrow) + end + + it_behaves_like 'an answer to an existing thread with reply-by-email enabled' do + let(:model) { issue } + end + it_behaves_like 'it should show Gmail Actions View Issue link' + it_behaves_like 'an unsubscribeable thread' + it_behaves_like 'appearance header and footer enabled' + it_behaves_like 'appearance header and footer not enabled' + end + describe 'status changed' do let(:status) { 'closed' } subject { described_class.issue_status_changed_email(recipient.id, issue.id, status, current_user.id) } diff --git a/spec/requests/api/internal_spec.rb b/spec/requests/api/internal_spec.rb index 3ab1818bebb..c94f6d22e74 100644 --- a/spec/requests/api/internal_spec.rb +++ b/spec/requests/api/internal_spec.rb @@ -925,19 +925,20 @@ describe API::Internal do it 'returns link to create new merge request' do post api('/internal/post_receive'), params: valid_params - expect(json_response['merge_request_urls']).to match [{ - "branch_name" => branch_name, - "url" => "http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name}", - "new_merge_request" => true - }] + message = <<~MESSAGE.strip + To create a merge request for #{branch_name}, visit: + http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/new?merge_request%5Bsource_branch%5D=#{branch_name} + MESSAGE + + expect(json_response['messages']).to include(build_basic_message(message)) end - it 'returns empty array if printing_merge_request_link_enabled is false' do + it 'returns no merge request messages if printing_merge_request_link_enabled is false' do project.update!(printing_merge_request_link_enabled: false) post api('/internal/post_receive'), params: valid_params - expect(json_response['merge_request_urls']).to eq([]) + expect(json_response['messages']).to be_blank end it 'does not invoke MergeRequests::PushOptionsHandlerService' do @@ -968,11 +969,12 @@ describe API::Internal do it 'links to the newly created merge request' do post api('/internal/post_receive'), params: valid_params - expect(json_response['merge_request_urls']).to match [{ - 'branch_name' => branch_name, - 'url' => "http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/1", - 'new_merge_request' => false - }] + message = <<~MESSAGE.strip + View merge request for #{branch_name}: + http://#{Gitlab.config.gitlab.host}/#{project.full_path}/merge_requests/1 + MESSAGE + + expect(json_response['messages']).to include(build_basic_message(message)) end it 'adds errors on the service instance to warnings' do @@ -982,7 +984,8 @@ describe API::Internal do post api('/internal/post_receive'), params: valid_params - expect(json_response['warnings']).to eq('Error encountered with push options \'merge_request.create\': my error') + message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error" + expect(json_response['messages']).to include(build_alert_message(message)) end it 'adds ActiveRecord errors on invalid MergeRequest records to warnings' do @@ -995,38 +998,39 @@ describe API::Internal do post api('/internal/post_receive'), params: valid_params - expect(json_response['warnings']).to eq('Error encountered with push options \'merge_request.create\': my error') + message = "WARNINGS:\nError encountered with push options 'merge_request.create': my error" + expect(json_response['messages']).to include(build_alert_message(message)) end end context 'broadcast message exists' do let!(:broadcast_message) { create(:broadcast_message, starts_at: 1.day.ago, ends_at: 1.day.from_now ) } - it 'returns one broadcast message' do + it 'outputs a broadcast message' do post api('/internal/post_receive'), params: valid_params expect(response).to have_gitlab_http_status(200) - expect(json_response['broadcast_message']).to eq(broadcast_message.message) + expect(json_response['messages']).to include(build_alert_message(broadcast_message.message)) end end context 'broadcast message does not exist' do - it 'returns empty string' do + it 'does not output a broadcast message' do post api('/internal/post_receive'), params: valid_params expect(response).to have_gitlab_http_status(200) - expect(json_response['broadcast_message']).to eq(nil) + expect(has_alert_messages?(json_response['messages'])).to be_falsey end end context 'nil broadcast message' do - it 'returns empty string' do + it 'does not output a broadcast message' do allow(BroadcastMessage).to receive(:current).and_return(nil) post api('/internal/post_receive'), params: valid_params expect(response).to have_gitlab_http_status(200) - expect(json_response['broadcast_message']).to eq(nil) + expect(has_alert_messages?(json_response['messages'])).to be_falsey end end @@ -1038,8 +1042,7 @@ describe API::Internal do post api('/internal/post_receive'), params: valid_params expect(response).to have_gitlab_http_status(200) - expect(json_response["redirected_message"]).to be_present - expect(json_response["redirected_message"]).to eq(project_moved.message) + expect(json_response['messages']).to include(build_basic_message(project_moved.message)) end end @@ -1051,8 +1054,7 @@ describe API::Internal do post api('/internal/post_receive'), params: valid_params expect(response).to have_gitlab_http_status(200) - expect(json_response["project_created_message"]).to be_present - expect(json_response["project_created_message"]).to eq(project_created.message) + expect(json_response['messages']).to include(build_basic_message(project_created.message)) end end @@ -1172,4 +1174,18 @@ describe API::Internal do } ) end + + def build_alert_message(message) + { 'type' => 'alert', 'message' => message } + end + + def build_basic_message(message) + { 'type' => 'basic', 'message' => message } + end + + def has_alert_messages?(messages) + messages.any? do |message| + message['type'] == 'alert' + end + end end diff --git a/spec/requests/api/project_snippets_spec.rb b/spec/requests/api/project_snippets_spec.rb index a543ef8de78..58a28e636f1 100644 --- a/spec/requests/api/project_snippets_spec.rb +++ b/spec/requests/api/project_snippets_spec.rb @@ -130,6 +130,29 @@ describe API::ProjectSnippets do expect(snippet.visibility_level).to eq(Snippet::PUBLIC) end + it 'creates a new snippet with content parameter' do + params[:content] = params.delete(:code) + + post api("/projects/#{project.id}/snippets/", admin), params: params + + expect(response).to have_gitlab_http_status(201) + snippet = ProjectSnippet.find(json_response['id']) + expect(snippet.content).to eq(params[:content]) + expect(snippet.description).to eq(params[:description]) + expect(snippet.title).to eq(params[:title]) + expect(snippet.file_name).to eq(params[:file_name]) + expect(snippet.visibility_level).to eq(Snippet::PUBLIC) + end + + it 'returns 400 when both code and content parameters specified' do + params[:content] = params[:code] + + post api("/projects/#{project.id}/snippets/", admin), params: params + + expect(response).to have_gitlab_http_status(400) + expect(json_response['error']).to eq('code, content are mutually exclusive') + end + it 'returns 400 for missing parameters' do params.delete(:title) @@ -198,6 +221,25 @@ describe API::ProjectSnippets do expect(snippet.visibility).to eq('private') end + it 'updates snippet with content parameter' do + new_content = 'New content' + new_description = 'New description' + + put api("/projects/#{snippet.project.id}/snippets/#{snippet.id}/", admin), params: { content: new_content, description: new_description } + + expect(response).to have_gitlab_http_status(200) + snippet.reload + expect(snippet.content).to eq(new_content) + expect(snippet.description).to eq(new_description) + end + + it 'returns 400 when both code and content parameters specified' do + put api("/projects/#{snippet.project.id}/snippets/1234", admin), params: { code: 'some content', content: 'other content' } + + expect(response).to have_gitlab_http_status(400) + expect(json_response['error']).to eq('code, content are mutually exclusive') + end + it 'returns 404 for invalid snippet id' do put api("/projects/#{snippet.project.id}/snippets/1234", admin), params: { title: 'foo' } diff --git a/spec/views/groups/edit.html.haml_spec.rb b/spec/views/groups/edit.html.haml_spec.rb index 47804411b9d..0da3470433c 100644 --- a/spec/views/groups/edit.html.haml_spec.rb +++ b/spec/views/groups/edit.html.haml_spec.rb @@ -23,7 +23,7 @@ describe 'groups/edit.html.haml' do render expect(rendered).to have_content("Prevent sharing a project within #{test_group.name} with other groups") - expect(rendered).to have_css('.descr', text: 'help text here') + expect(rendered).to have_css('.js-descr', text: 'help text here') expect(rendered).to have_field('group_share_with_group_lock', checkbox_options) end end |