summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/finders/members_finder_spec.rb44
-rw-r--r--spec/frontend/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js55
-rw-r--r--spec/javascripts/environments/environment_item_spec.js5
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_auto_merge_failed_spec.js47
-rw-r--r--spec/lib/gitlab/internal_post_receive/response_spec.rb121
-rw-r--r--spec/mailers/notify_spec.rb16
-rw-r--r--spec/requests/api/internal_spec.rb64
-rw-r--r--spec/requests/api/project_snippets_spec.rb42
-rw-r--r--spec/views/groups/edit.html.haml_spec.rb2
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