Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-10 15:08:16 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-10 15:08:16 +0300
commit1fa79760ad2d4bd67f5c5a27f372a7533b9b7c69 (patch)
treeffdfbd9113743831ff4f1290959a62cf6567fde5 /spec
parent82fa8a3d1e8466ef36b58604d20fcc145ea12118 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb3
-rw-r--r--spec/features/projects/container_registry_spec.rb11
-rw-r--r--spec/features/projects/snippets/create_snippet_spec.rb23
-rw-r--r--spec/features/snippets/user_creates_snippet_spec.rb23
-rw-r--r--spec/frontend/blob/3d_viewer/mesh_object_spec.js (renamed from spec/javascripts/blob/3d_viewer/mesh_object_spec.js)0
-rw-r--r--spec/frontend/blob/viewer/index_spec.js (renamed from spec/javascripts/blob/viewer/index_spec.js)39
-rw-r--r--spec/frontend/registry/explorer/pages/details_spec.js2
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap94
-rw-r--r--spec/frontend/snippets/components/snippet_visibility_edit_spec.js94
-rw-r--r--spec/helpers/submodule_helper_spec.rb20
-rw-r--r--spec/lib/gitlab/ci/config/entry/inherit/default_spec.rb42
-rw-r--r--spec/lib/gitlab/ci/config/entry/inherit/variables_spec.rb42
-rw-r--r--spec/lib/gitlab/ci/config/entry/job_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/config/entry/processable_spec.rb57
-rw-r--r--spec/lib/gitlab/ci/yaml_processor_spec.rb48
-rw-r--r--spec/lib/gitlab/middleware/go_spec.rb11
-rw-r--r--spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb11
-rw-r--r--spec/lib/sentry/client/issue_spec.rb28
-rw-r--r--spec/models/snippet_repository_spec.rb50
-rw-r--r--spec/services/notification_recipients/build_service_spec.rb (renamed from spec/services/notification_recipient_service_spec.rb)2
-rw-r--r--spec/services/notification_recipients/builder/default_spec.rb44
-rw-r--r--spec/services/notification_service_spec.rb2
-rw-r--r--spec/services/snippets/create_service_spec.rb10
23 files changed, 569 insertions, 89 deletions
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index c6345a2153c..a224a2101d3 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -23,7 +23,6 @@ describe Projects::ClustersController do
describe 'functionality' do
context 'when project has one or more clusters' do
- let(:project) { create(:project) }
let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
@@ -53,8 +52,6 @@ describe Projects::ClustersController do
end
context 'when project does not have a cluster' do
- let(:project) { create(:project) }
-
it 'returns an empty state page' do
go
diff --git a/spec/features/projects/container_registry_spec.rb b/spec/features/projects/container_registry_spec.rb
index b99dab39c34..de17d831fbd 100644
--- a/spec/features/projects/container_registry_spec.rb
+++ b/spec/features/projects/container_registry_spec.rb
@@ -126,6 +126,7 @@ describe 'Container Registry', :js do
describe 'image repo details' do
before do
+ stub_container_registry_tags(repository: %r{my/image}, tags: ('1'..'20').to_a, with_manifest: true)
visit_container_registry_details 'my/image'
end
@@ -140,12 +141,18 @@ describe 'Container Registry', :js do
it 'user removes a specific tag from container repository' do
service = double('service')
expect(service).to receive(:execute).with(container_repository) { { status: :success } }
- expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['latest']) { service }
+ expect(Projects::ContainerRepository::DeleteTagsService).to receive(:new).with(container_repository.project, user, tags: ['1']) { service }
- click_on(class: 'js-delete-registry')
+ first('.js-delete-registry').click
expect(find('.modal .modal-title')).to have_content _('Remove tag')
find('.modal .modal-footer .btn-danger').click
end
+
+ it('pagination navigate to the second page') do
+ pagination = find('.gl-pagination')
+ pagination.click_link('2')
+ expect(page).to have_content '20'
+ end
end
end
end
diff --git a/spec/features/projects/snippets/create_snippet_spec.rb b/spec/features/projects/snippets/create_snippet_spec.rb
index ee312a5811d..28d24073b79 100644
--- a/spec/features/projects/snippets/create_snippet_spec.rb
+++ b/spec/features/projects/snippets/create_snippet_spec.rb
@@ -95,6 +95,29 @@ shared_examples_for 'snippet editor' do
link = find('a.no-attachment-icon img[alt="banana_sample"]')['src']
expect(link).to match(%r{/#{Regexp.escape(project.full_path)}/uploads/\h{32}/banana_sample\.gif\z})
end
+
+ context 'when the git operation fails' do
+ let(:error) { 'This is a git error' }
+
+ before do
+ allow_next_instance_of(Snippets::CreateService) do |instance|
+ allow(instance).to receive(:create_commit).and_raise(StandardError, error)
+ end
+
+ fill_form
+
+ click_button('Create snippet')
+ wait_for_requests
+ end
+
+ it 'displays the error' do
+ expect(page).to have_content(error)
+ end
+
+ it 'renders new page' do
+ expect(page).to have_content('New Snippet')
+ end
+ end
end
context 'when a user is not authenticated' do
diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb
index 88f7896bfa6..f200355c6d2 100644
--- a/spec/features/snippets/user_creates_snippet_spec.rb
+++ b/spec/features/snippets/user_creates_snippet_spec.rb
@@ -78,6 +78,29 @@ shared_examples_for 'snippet editor' do
expect(reqs.first.status_code).to eq(200)
end
+ context 'when the git operation fails' do
+ let(:error) { 'This is a git error' }
+
+ before do
+ allow_next_instance_of(Snippets::CreateService) do |instance|
+ allow(instance).to receive(:create_commit).and_raise(StandardError, error)
+ end
+
+ fill_form
+
+ click_button('Create snippet')
+ wait_for_requests
+ end
+
+ it 'displays the error' do
+ expect(page).to have_content(error)
+ end
+
+ it 'renders new page' do
+ expect(page).to have_content('New Snippet')
+ end
+ end
+
it 'validation fails for the first time' do
fill_in 'personal_snippet_title', with: 'My Snippet Title'
click_button('Create snippet')
diff --git a/spec/javascripts/blob/3d_viewer/mesh_object_spec.js b/spec/frontend/blob/3d_viewer/mesh_object_spec.js
index 60be285039f..60be285039f 100644
--- a/spec/javascripts/blob/3d_viewer/mesh_object_spec.js
+++ b/spec/frontend/blob/3d_viewer/mesh_object_spec.js
diff --git a/spec/javascripts/blob/viewer/index_spec.js b/spec/frontend/blob/viewer/index_spec.js
index 06c06613887..7239f59c6fa 100644
--- a/spec/javascripts/blob/viewer/index_spec.js
+++ b/spec/frontend/blob/viewer/index_spec.js
@@ -9,9 +9,14 @@ describe('Blob viewer', () => {
let blob;
let mock;
+ const jQueryMock = {
+ tooltip: jest.fn(),
+ };
+
preloadFixtures('snippets/show.html');
beforeEach(() => {
+ $.fn.extend(jQueryMock);
mock = new MockAdapter(axios);
loadFixtures('snippets/show.html');
@@ -27,7 +32,7 @@ describe('Blob viewer', () => {
html: '<div>testing</div>',
});
- spyOn(axios, 'get').and.callThrough();
+ jest.spyOn(axios, 'get');
});
afterEach(() => {
@@ -38,7 +43,7 @@ describe('Blob viewer', () => {
it('loads source file after switching views', done => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
- setTimeout(() => {
+ setImmediate(() => {
expect(
document
.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
@@ -54,7 +59,7 @@ describe('Blob viewer', () => {
new BlobViewer();
- setTimeout(() => {
+ setImmediate(() => {
expect(
document
.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
@@ -65,26 +70,20 @@ describe('Blob viewer', () => {
});
});
- it('doesnt reload file if already loaded', done => {
+ it('doesnt reload file if already loaded', () => {
const asyncClick = () =>
new Promise(resolve => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
- setTimeout(resolve);
+ setImmediate(resolve);
});
- asyncClick()
+ return asyncClick()
.then(() => asyncClick())
.then(() => {
expect(
document.querySelector('.blob-viewer[data-type="simple"]').getAttribute('data-loaded'),
).toBe('true');
-
- done();
- })
- .catch(() => {
- fail();
- done();
});
});
@@ -100,13 +99,13 @@ describe('Blob viewer', () => {
});
it('has tooltip when disabled', () => {
- expect(copyButton.getAttribute('data-original-title')).toBe(
+ expect(copyButton.getAttribute('title')).toBe(
'Switch to the source to copy the file contents',
);
});
it('is blurred when clicked and disabled', () => {
- spyOn(copyButton, 'blur');
+ jest.spyOn(copyButton, 'blur').mockImplementation(() => {});
copyButton.click();
@@ -114,7 +113,7 @@ describe('Blob viewer', () => {
});
it('is not blurred when clicked and not disabled', () => {
- spyOn(copyButton, 'blur');
+ jest.spyOn(copyButton, 'blur').mockImplementation(() => {});
copyButton.classList.remove('disabled');
copyButton.click();
@@ -125,7 +124,7 @@ describe('Blob viewer', () => {
it('enables after switching to simple view', done => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
- setTimeout(() => {
+ setImmediate(() => {
expect(copyButton.classList.contains('disabled')).toBeFalsy();
done();
@@ -135,8 +134,8 @@ describe('Blob viewer', () => {
it('updates tooltip after switching to simple view', done => {
document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]').click();
- setTimeout(() => {
- expect(copyButton.getAttribute('data-original-title')).toBe('Copy file contents');
+ setImmediate(() => {
+ expect(copyButton.getAttribute('title')).toBe('Copy file contents');
done();
});
@@ -155,7 +154,7 @@ describe('Blob viewer', () => {
it('adds active class to new viewer button', () => {
const simpleBtn = document.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]');
- spyOn(simpleBtn, 'blur');
+ jest.spyOn(simpleBtn, 'blur').mockImplementation(() => {});
blob.switchToViewer('simple');
@@ -174,7 +173,7 @@ describe('Blob viewer', () => {
blob.switchToViewer('simple');
blob.switchToViewer('rich');
- expect(axios.get.calls.count()).toBe(1);
+ expect(axios.get.mock.calls.length).toBe(1);
});
});
});
diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js
index 2b83f7e7351..15c6b36af03 100644
--- a/spec/frontend/registry/explorer/pages/details_spec.js
+++ b/spec/frontend/registry/explorer/pages/details_spec.js
@@ -219,7 +219,7 @@ describe('Details Page', () => {
dispatchSpy.mockResolvedValue();
wrapper.setData({ currentPage: 2 });
expect(store.dispatch).toHaveBeenCalledWith('requestTagsList', {
- id: wrapper.vm.$route.params.id,
+ params: wrapper.vm.$route.params.id,
pagination: { page: 2 },
});
});
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap
new file mode 100644
index 00000000000..4f1d46dffef
--- /dev/null
+++ b/spec/frontend/snippets/components/__snapshots__/snippet_visibility_edit_spec.js.snap
@@ -0,0 +1,94 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Snippet Visibility Edit component rendering matches the snapshot 1`] = `
+<div
+ class="form-group"
+>
+ <label>
+
+ Visibility level
+
+ <gl-link-stub
+ href="/foo/bar"
+ target="_blank"
+ >
+ <gl-icon-stub
+ name="question"
+ size="12"
+ />
+ </gl-link-stub>
+ </label>
+
+ <gl-form-group-stub
+ id="visibility-level-setting"
+ >
+ <gl-form-radio-group-stub
+ checked="0"
+ disabledfield="disabled"
+ htmlfield="html"
+ options=""
+ stacked=""
+ textfield="text"
+ valuefield="value"
+ >
+ <gl-form-radio-stub
+ class="mb-3"
+ value="0"
+ >
+ <div
+ class="d-flex align-items-center"
+ >
+ <gl-icon-stub
+ name="lock"
+ size="16"
+ />
+
+ <span
+ class="font-weight-bold ml-1"
+ >
+ Private
+ </span>
+ </div>
+ </gl-form-radio-stub>
+ <gl-form-radio-stub
+ class="mb-3"
+ value="1"
+ >
+ <div
+ class="d-flex align-items-center"
+ >
+ <gl-icon-stub
+ name="shield"
+ size="16"
+ />
+
+ <span
+ class="font-weight-bold ml-1"
+ >
+ Internal
+ </span>
+ </div>
+ </gl-form-radio-stub>
+ <gl-form-radio-stub
+ class="mb-3"
+ value="2"
+ >
+ <div
+ class="d-flex align-items-center"
+ >
+ <gl-icon-stub
+ name="earth"
+ size="16"
+ />
+
+ <span
+ class="font-weight-bold ml-1"
+ >
+ Public
+ </span>
+ </div>
+ </gl-form-radio-stub>
+ </gl-form-radio-group-stub>
+ </gl-form-group-stub>
+</div>
+`;
diff --git a/spec/frontend/snippets/components/snippet_visibility_edit_spec.js b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js
new file mode 100644
index 00000000000..5104d742bb3
--- /dev/null
+++ b/spec/frontend/snippets/components/snippet_visibility_edit_spec.js
@@ -0,0 +1,94 @@
+import SnippetVisibilityEdit from '~/snippets/components/snippet_visibility_edit.vue';
+import { GlFormRadio } from '@gitlab/ui';
+import { SNIPPET_VISIBILITY } from '~/snippets/constants';
+import { mount, shallowMount } from '@vue/test-utils';
+
+describe('Snippet Visibility Edit component', () => {
+ let wrapper;
+ let radios;
+ const defaultHelpLink = '/foo/bar';
+ const defaultVisibilityLevel = '0';
+
+ function findElements(sel) {
+ return wrapper.findAll(sel);
+ }
+
+ function createComponent(
+ {
+ helpLink = defaultHelpLink,
+ isProjectSnippet = false,
+ visibilityLevel = defaultVisibilityLevel,
+ } = {},
+ deep = false,
+ ) {
+ const method = deep ? mount : shallowMount;
+ wrapper = method.call(this, SnippetVisibilityEdit, {
+ propsData: {
+ helpLink,
+ isProjectSnippet,
+ visibilityLevel,
+ },
+ });
+ radios = findElements(GlFormRadio);
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('rendering', () => {
+ it('matches the snapshot', () => {
+ createComponent();
+ expect(wrapper.element).toMatchSnapshot();
+ });
+
+ it.each`
+ label | value
+ ${SNIPPET_VISIBILITY.private.label} | ${`0`}
+ ${SNIPPET_VISIBILITY.internal.label} | ${`1`}
+ ${SNIPPET_VISIBILITY.public.label} | ${`2`}
+ `('should render correct $label label', ({ label, value }) => {
+ createComponent();
+ const radio = radios.at(parseInt(value, 10));
+
+ expect(radio.attributes('value')).toBe(value);
+ expect(radio.text()).toContain(label);
+ });
+
+ describe('rendered help-text', () => {
+ it.each`
+ description | value | label
+ ${SNIPPET_VISIBILITY.private.description} | ${`0`} | ${SNIPPET_VISIBILITY.private.label}
+ ${SNIPPET_VISIBILITY.internal.description} | ${`1`} | ${SNIPPET_VISIBILITY.internal.label}
+ ${SNIPPET_VISIBILITY.public.description} | ${`2`} | ${SNIPPET_VISIBILITY.public.label}
+ `('should render correct $label description', ({ description, value }) => {
+ createComponent({}, true);
+
+ const help = findElements('.help-text').at(parseInt(value, 10));
+
+ expect(help.text()).toBe(description);
+ });
+
+ it('renders correct Private description for a project snippet', () => {
+ createComponent({ isProjectSnippet: true }, true);
+
+ const helpText = findElements('.help-text')
+ .at(0)
+ .text();
+
+ expect(helpText).not.toContain(SNIPPET_VISIBILITY.private.description);
+ expect(helpText).toBe(SNIPPET_VISIBILITY.private.description_project);
+ });
+ });
+ });
+
+ describe('functionality', () => {
+ it('pre-selects correct option in the list', () => {
+ const pos = 1;
+
+ createComponent({ visibilityLevel: `${pos}` }, true);
+ const radio = radios.at(pos);
+ expect(radio.find('input[type="radio"]').element.checked).toBe(true);
+ });
+ });
+});
diff --git a/spec/helpers/submodule_helper_spec.rb b/spec/helpers/submodule_helper_spec.rb
index d229753a0f0..7db45c05cb5 100644
--- a/spec/helpers/submodule_helper_spec.rb
+++ b/spec/helpers/submodule_helper_spec.rb
@@ -23,14 +23,30 @@ describe SubmoduleHelper do
it 'detects ssh on standard port' do
allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(22) # set this just to be sure
allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
- stub_url([config.user, '@', config.host, ':gitlab-org/gitlab-foss.git'].join(''))
+ stub_url([config.ssh_user, '@', config.host, ':gitlab-org/gitlab-foss.git'].join(''))
+ expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-foss'), namespace_project_tree_path('gitlab-org', 'gitlab-foss', 'hash')])
+ end
+
+ it 'detects ssh on standard port without a username' do
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(22) # set this just to be sure
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_user).and_return('')
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
+ stub_url([config.host, ':gitlab-org/gitlab-foss.git'].join(''))
expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-foss'), namespace_project_tree_path('gitlab-org', 'gitlab-foss', 'hash')])
end
it 'detects ssh on non-standard port' do
allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(2222)
allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
- stub_url(['ssh://', config.user, '@', config.host, ':2222/gitlab-org/gitlab-foss.git'].join(''))
+ stub_url(['ssh://', config.ssh_user, '@', config.host, ':2222/gitlab-org/gitlab-foss.git'].join(''))
+ expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-foss'), namespace_project_tree_path('gitlab-org', 'gitlab-foss', 'hash')])
+ end
+
+ it 'detects ssh on non-standard port without a username' do
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_port).and_return(2222)
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_user).and_return('')
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_path_prefix).and_return(Settings.send(:build_gitlab_shell_ssh_path_prefix))
+ stub_url(['ssh://', config.host, ':2222/gitlab-org/gitlab-foss.git'].join(''))
expect(subject).to eq([namespace_project_path('gitlab-org', 'gitlab-foss'), namespace_project_tree_path('gitlab-org', 'gitlab-foss', 'hash')])
end
diff --git a/spec/lib/gitlab/ci/config/entry/inherit/default_spec.rb b/spec/lib/gitlab/ci/config/entry/inherit/default_spec.rb
new file mode 100644
index 00000000000..073f93ce542
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/inherit/default_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ::Gitlab::Ci::Config::Entry::Inherit::Default do
+ using RSpec::Parameterized::TableSyntax
+
+ subject { described_class.new(config) }
+
+ context 'validations' do
+ where(:config, :valid) do
+ true | true
+ false | true
+ %w[image] | true
+ %w[unknown] | false
+ %i[image] | false
+ [true] | false
+ "string" | false
+ end
+
+ with_them do
+ it do
+ expect(subject.valid?).to eq(valid)
+ end
+ end
+ end
+
+ describe '#inherit?' do
+ where(:config, :inherit) do
+ true | true
+ false | false
+ %w[image] | true
+ %w[before_script] | false
+ end
+
+ with_them do
+ it do
+ expect(subject.inherit?('image')).to eq(inherit)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/entry/inherit/variables_spec.rb b/spec/lib/gitlab/ci/config/entry/inherit/variables_spec.rb
new file mode 100644
index 00000000000..06deed11c15
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/entry/inherit/variables_spec.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ::Gitlab::Ci::Config::Entry::Inherit::Variables do
+ using RSpec::Parameterized::TableSyntax
+
+ subject { described_class.new(config) }
+
+ context 'validations' do
+ where(:config, :valid) do
+ true | true
+ false | true
+ %w[A] | true
+ %w[A B] | true
+ %i[image] | true
+ [true] | false
+ "string" | false
+ end
+
+ with_them do
+ it do
+ expect(subject.valid?).to eq(valid)
+ end
+ end
+ end
+
+ describe '#inherit?' do
+ where(:config, :inherit) do
+ true | true
+ false | false
+ %w[A] | true
+ %w[B] | false
+ end
+
+ with_them do
+ it do
+ expect(subject.inherit?('A')).to eq(inherit)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/config/entry/job_spec.rb b/spec/lib/gitlab/ci/config/entry/job_spec.rb
index 7df0eccb3ed..b6279485426 100644
--- a/spec/lib/gitlab/ci/config/entry/job_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/job_spec.rb
@@ -18,7 +18,7 @@ describe Gitlab::Ci::Config::Entry::Job do
end
before do
- allow(entry).to receive_message_chain(:inherit_entry, :default_value).and_return(true)
+ allow(entry).to receive_message_chain(:inherit_entry, :default_entry, :inherit?).and_return(true)
end
end
diff --git a/spec/lib/gitlab/ci/config/entry/processable_spec.rb b/spec/lib/gitlab/ci/config/entry/processable_spec.rb
index 5c2c6520f25..8447a29c772 100644
--- a/spec/lib/gitlab/ci/config/entry/processable_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/processable_spec.rb
@@ -269,13 +269,13 @@ describe Gitlab::Ci::Config::Entry::Processable do
context 'when root yaml variables are used' do
let(:variables) do
Gitlab::Ci::Config::Entry::Variables.new(
- A: 'root', C: 'root'
+ A: 'root', C: 'root', D: 'root'
).value
end
it 'does return all variables and overwrite them' do
expect(entry.value).to include(
- variables: { 'A' => 'job', 'B' => 'job', 'C' => 'root' }
+ variables: { 'A' => 'job', 'B' => 'job', 'C' => 'root', 'D' => 'root' }
)
end
@@ -293,32 +293,61 @@ describe Gitlab::Ci::Config::Entry::Processable do
)
end
end
+
+ context 'when inherit of only specific variable is enabled' do
+ let(:config) do
+ {
+ variables: { A: 'job', B: 'job' },
+ inherit: { variables: ['D'] }
+ }
+ end
+
+ it 'does return only job variables' do
+ expect(entry.value).to include(
+ variables: { 'A' => 'job', 'B' => 'job', 'D' => 'root' }
+ )
+ end
+ end
end
end
context 'of default:tags' do
using RSpec::Parameterized::TableSyntax
- where(:default_tags, :tags, :inherit_default, :result) do
- nil | %w[a b] | nil | %w[a b]
- nil | %w[a b] | true | %w[a b]
- nil | %w[a b] | false | %w[a b]
- %w[b c] | %w[a b] | nil | %w[a b]
- %w[b c] | %w[a b] | true | %w[a b]
- %w[b c] | %w[a b] | false | %w[a b]
- %w[b c] | nil | nil | %w[b c]
- %w[b c] | nil | true | %w[b c]
- %w[b c] | nil | false | nil
+ where(:name, :default_tags, :tags, :inherit_default, :result) do
+ "only local tags" | nil | %w[a b] | nil | %w[a b]
+ "only local tags" | nil | %w[a b] | true | %w[a b]
+ "only local tags" | nil | %w[a b] | false | %w[a b]
+ "global and local tags" | %w[b c] | %w[a b] | nil | %w[a b]
+ "global and local tags" | %w[b c] | %w[a b] | true | %w[a b]
+ "global and local tags" | %w[b c] | %w[a b] | false | %w[a b]
+ "only global tags" | %w[b c] | nil | nil | %w[b c]
+ "only global tags" | %w[b c] | nil | true | %w[b c]
+ "only global tags" | %w[b c] | nil | false | nil
+ "only global tags" | %w[b c] | nil | %w[image] | nil
+ "only global tags" | %w[b c] | nil | %w[tags] | %w[b c]
end
with_them do
- let(:config) { { tags: tags, inherit: { default: inherit_default } } }
- let(:default_specified_tags) { double('tags', 'specified?' => true, 'valid?' => true, 'value' => default_tags) }
+ let(:config) do
+ { tags: tags,
+ inherit: { default: inherit_default } }
+ end
+
+ let(:default_specified_tags) do
+ double('tags',
+ 'specified?' => true,
+ 'valid?' => true,
+ 'value' => default_tags,
+ 'errors' => [])
+ end
before do
allow(default).to receive('[]').with(:tags).and_return(default_specified_tags)
entry.compose!(deps)
+
+ expect(entry).to be_valid
end
it { expect(entry.tags_value).to eq(result) }
diff --git a/spec/lib/gitlab/ci/yaml_processor_spec.rb b/spec/lib/gitlab/ci/yaml_processor_spec.rb
index 5c85a136972..af0a85f6c4e 100644
--- a/spec/lib/gitlab/ci/yaml_processor_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor_spec.rb
@@ -515,6 +515,8 @@ module Gitlab
nil | ["global script"]
{ default: false } | nil
{ default: true } | ["global script"]
+ { default: %w[before_script] } | ["global script"]
+ { default: %w[image] } | nil
end
with_them do
@@ -527,26 +529,28 @@ module Gitlab
it { expect(subject[:options][:before_script]).to eq(result) }
end
- end
- context "in default context" do
- using RSpec::Parameterized::TableSyntax
+ context "in default context" do
+ using RSpec::Parameterized::TableSyntax
- where(:inherit, :result) do
- nil | ["global script"]
- { default: false } | nil
- { default: true } | ["global script"]
- end
-
- with_them do
- let(:config) do
- {
- default: { before_script: ["global script"] },
- test: { script: ["script"], inherit: inherit }
- }
+ where(:inherit, :result) do
+ nil | ["global script"]
+ { default: false } | nil
+ { default: true } | ["global script"]
+ { default: %w[before_script] } | ["global script"]
+ { default: %w[image] } | nil
end
- it { expect(subject[:options][:before_script]).to eq(result) }
+ with_them do
+ let(:config) do
+ {
+ default: { before_script: ["global script"] },
+ test: { script: ["script"], inherit: inherit }
+ }
+ end
+
+ it { expect(subject[:options][:before_script]).to eq(result) }
+ end
end
end
@@ -845,6 +849,18 @@ module Gitlab
)
end
end
+
+ context 'when specific variables are to inherited' do
+ let(:inherit) { { variables: %w[VAR1 VAR4] } }
+
+ it 'returns all unique variables and inherits only specified variables' do
+ expect(subject).to contain_exactly(
+ { key: 'VAR4', value: 'global4', public: true },
+ { key: 'VAR1', value: 'value1', public: true },
+ { key: 'VAR2', value: 'value2', public: true }
+ )
+ end
+ end
end
context 'when job variables are defined' do
diff --git a/spec/lib/gitlab/middleware/go_spec.rb b/spec/lib/gitlab/middleware/go_spec.rb
index 99c2a364dfc..43a489f6df0 100644
--- a/spec/lib/gitlab/middleware/go_spec.rb
+++ b/spec/lib/gitlab/middleware/go_spec.rb
@@ -89,6 +89,13 @@ describe Gitlab::Middleware::Go do
it 'returns the full project path' do
expect_response_with_path(go, enabled_protocol, project.full_path, project.default_branch)
end
+
+ context 'with an empty ssh_user' do
+ it 'returns the full project path' do
+ allow(Gitlab.config.gitlab_shell).to receive(:ssh_user).and_return('')
+ expect_response_with_path(go, enabled_protocol, project.full_path, project.default_branch)
+ end
+ end
end
context 'without access to the project' do
@@ -234,7 +241,9 @@ describe Gitlab::Middleware::Go do
def expect_response_with_path(response, protocol, path, branch)
repository_url = case protocol
when :ssh
- "ssh://#{Gitlab.config.gitlab.user}@#{Gitlab.config.gitlab.host}/#{path}.git"
+ shell = Gitlab.config.gitlab_shell
+ user = "#{shell.ssh_user}@" unless shell.ssh_user.empty?
+ "ssh://#{user}#{shell.ssh_host}/#{path}.git"
when :http, nil
"http://#{Gitlab.config.gitlab.host}/#{path}.git"
end
diff --git a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
index 47442f4ee86..d815534e873 100644
--- a/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
+++ b/spec/lib/gitlab/sidekiq_middleware/server_metrics_spec.rb
@@ -20,6 +20,8 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
let(:queue_duration_seconds) { double('queue duration seconds metric') }
let(:completion_seconds_metric) { double('completion seconds metric') }
let(:user_execution_seconds_metric) { double('user execution seconds metric') }
+ let(:db_seconds_metric) { double('db seconds metric') }
+ let(:gitaly_seconds_metric) { double('gitaly seconds metric') }
let(:failed_total_metric) { double('failed total metric') }
let(:retried_total_metric) { double('retried total metric') }
let(:running_jobs_metric) { double('running jobs metric') }
@@ -28,6 +30,8 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_queue_duration_seconds, anything, anything, anything).and_return(queue_duration_seconds)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_completion_seconds, anything, anything, anything).and_return(completion_seconds_metric)
allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_cpu_seconds, anything, anything, anything).and_return(user_execution_seconds_metric)
+ allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_db_seconds, anything, anything, anything).and_return(db_seconds_metric)
+ allow(Gitlab::Metrics).to receive(:histogram).with(:sidekiq_jobs_gitaly_seconds, anything, anything, anything).and_return(gitaly_seconds_metric)
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_failed_total, anything).and_return(failed_total_metric)
allow(Gitlab::Metrics).to receive(:counter).with(:sidekiq_jobs_retried_total, anything).and_return(retried_total_metric)
allow(Gitlab::Metrics).to receive(:gauge).with(:sidekiq_running_jobs, anything, {}, :all).and_return(running_jobs_metric)
@@ -55,16 +59,23 @@ describe Gitlab::SidekiqMiddleware::ServerMetrics do
let(:queue_duration_for_job) { 0.01 }
+ let(:db_duration) { 3 }
+ let(:gitaly_duration) { 4 }
+
before do
allow(subject).to receive(:get_thread_cputime).and_return(thread_cputime_before, thread_cputime_after)
allow(Gitlab::Metrics::System).to receive(:monotonic_time).and_return(monotonic_time_before, monotonic_time_after)
allow(Gitlab::InstrumentationHelper).to receive(:queue_duration_for_job).with(job).and_return(queue_duration_for_job)
+ allow(ActiveRecord::LogSubscriber).to receive(:runtime).and_return(db_duration * 1000)
+ allow(Gitlab::GitalyClient).to receive(:query_time).and_return(gitaly_duration)
expect(running_jobs_metric).to receive(:increment).with(labels, 1)
expect(running_jobs_metric).to receive(:increment).with(labels, -1)
expect(queue_duration_seconds).to receive(:observe).with(labels, queue_duration_for_job) if queue_duration_for_job
expect(user_execution_seconds_metric).to receive(:observe).with(labels_with_job_status, thread_cputime_duration)
+ expect(db_seconds_metric).to receive(:observe).with(labels_with_job_status, db_duration)
+ expect(gitaly_seconds_metric).to receive(:observe).with(labels_with_job_status, gitaly_duration)
expect(completion_seconds_metric).to receive(:observe).with(labels_with_job_status, monotonic_time_duration)
end
diff --git a/spec/lib/sentry/client/issue_spec.rb b/spec/lib/sentry/client/issue_spec.rb
index 62cbfbf0b30..0f57d38d290 100644
--- a/spec/lib/sentry/client/issue_spec.rb
+++ b/spec/lib/sentry/client/issue_spec.rb
@@ -254,6 +254,34 @@ describe Sentry::Client::Issue do
expect(subject.gitlab_issue).to eq('https://gitlab.com/gitlab-org/gitlab/issues/1')
end
+ context 'when issue annotations exist' do
+ before do
+ issue_sample_response['annotations'] = [
+ nil,
+ '',
+ "<a href=\"http://github.com/issues/6\">github-issue-6</a>",
+ "<div>annotation</a>",
+ "<a href=\"http://localhost/gitlab-org/gitlab/issues/2\">gitlab-org/gitlab#2</a>"
+ ]
+ stub_sentry_request(sentry_request_url, body: issue_sample_response)
+ end
+
+ it 'has a correct GitLab issue url' do
+ expect(subject.gitlab_issue).to eq('http://localhost/gitlab-org/gitlab/issues/2')
+ end
+ end
+
+ context 'when no GitLab issue is linked' do
+ before do
+ issue_sample_response['pluginIssues'] = []
+ stub_sentry_request(sentry_request_url, body: issue_sample_response)
+ end
+
+ it 'does not find a GitLab issue' do
+ expect(subject.gitlab_issue).to be_nil
+ end
+ end
+
it 'has the correct tags' do
expect(subject.tags).to eq({ level: issue_sample_response['level'], logger: issue_sample_response['logger'] })
end
diff --git a/spec/models/snippet_repository_spec.rb b/spec/models/snippet_repository_spec.rb
index 120175fdd05..088d37725aa 100644
--- a/spec/models/snippet_repository_spec.rb
+++ b/spec/models/snippet_repository_spec.rb
@@ -168,34 +168,42 @@ describe SnippetRepository do
end
end
- context 'when files are not named' do
- let(:data) do
- [
- {
- file_path: '',
- content: 'foo',
- action: :create
- },
- {
- file_path: '',
- content: 'bar',
- action: :create
- },
- {
- file_path: 'foo.txt',
- content: 'bar',
- action: :create
- }
- ]
+ shared_examples 'snippet repository with file names' do |*filenames|
+ it 'sets a name for unnamed files' do
+ ls_files = snippet.repository.ls_files(nil)
+ expect(ls_files).to include(*filenames)
end
+ end
+
+ let_it_be(:named_snippet) { { file_path: 'fee.txt', content: 'bar', action: :create } }
+ let_it_be(:unnamed_snippet) { { file_path: '', content: 'dummy', action: :create } }
- it 'sets a name for non named files' do
+ context 'when some files are not named' do
+ let(:data) { [named_snippet] + Array.new(2) { unnamed_snippet.clone } }
+
+ before do
expect do
snippet_repository.multi_files_action(user, data, commit_opts)
end.not_to raise_error
+ end
+
+ it_behaves_like 'snippet repository with file names', 'snippetfile1.txt', 'snippetfile2.txt'
+ end
- expect(snippet.repository.ls_files(nil)).to include('snippetfile1.txt', 'snippetfile2.txt', 'foo.txt')
+ context 'repository already has 10 unnamed snippets' do
+ let(:pre_populate_data) { Array.new(10) { unnamed_snippet.clone } }
+ let(:data) { [named_snippet] + Array.new(2) { unnamed_snippet.clone } }
+
+ before do
+ # Pre-populate repository with 9 unnamed snippets.
+ snippet_repository.multi_files_action(user, pre_populate_data, commit_opts)
+
+ expect do
+ snippet_repository.multi_files_action(user, data, commit_opts)
+ end.not_to raise_error
end
+
+ it_behaves_like 'snippet repository with file names', 'snippetfile10.txt', 'snippetfile11.txt'
end
end
diff --git a/spec/services/notification_recipient_service_spec.rb b/spec/services/notification_recipients/build_service_spec.rb
index 9c2283f555b..2e848c2f04d 100644
--- a/spec/services/notification_recipient_service_spec.rb
+++ b/spec/services/notification_recipients/build_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe NotificationRecipientService do
+describe NotificationRecipients::BuildService do
let(:service) { described_class }
let(:assignee) { create(:user) }
let(:project) { create(:project, :public) }
diff --git a/spec/services/notification_recipients/builder/default_spec.rb b/spec/services/notification_recipients/builder/default_spec.rb
new file mode 100644
index 00000000000..307ca40248e
--- /dev/null
+++ b/spec/services/notification_recipients/builder/default_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe NotificationRecipients::Builder::Default do
+ describe '#build!' do
+ let_it_be(:group) { create(:group, :public) }
+ let_it_be(:project) { create(:project, :public, group: group).tap { |p| p.add_developer(project_watcher) } }
+ let_it_be(:issue) { create(:issue, project: project) }
+
+ let_it_be(:current_user) { create(:user) }
+ let_it_be(:other_user) { create(:user) }
+ let_it_be(:participant) { create(:user) }
+ let_it_be(:group_watcher) { create(:user) }
+ let_it_be(:project_watcher) { create(:user) }
+
+ let_it_be(:notification_setting_project_w) { create(:notification_setting, source: project, user: project_watcher, level: 2) }
+ let_it_be(:notification_setting_group_w) { create(:notification_setting, source: group, user: group_watcher, level: 2) }
+
+ subject { described_class.new(issue, current_user, action: :new).tap { |s| s.build! } }
+
+ context 'participants and project watchers' do
+ before do
+ expect(issue).to receive(:participants).and_return([participant, current_user])
+ end
+
+ it 'adds all participants and watchers' do
+ expect(subject.recipients.map(&:user)).to include(participant, project_watcher, group_watcher)
+ expect(subject.recipients.map(&:user)).not_to include(other_user)
+ end
+ end
+
+ context 'subscribers' do
+ it 'adds all subscribers' do
+ subscriber = create(:user)
+ non_subscriber = create(:user)
+ create(:subscription, project: project, user: subscriber, subscribable: issue, subscribed: true)
+ create(:subscription, project: project, user: non_subscriber, subscribable: issue, subscribed: false)
+
+ expect(subject.recipients.map(&:user)).to include(subscriber)
+ end
+ end
+ end
+end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index d2680606738..96906b4ca3c 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -710,7 +710,7 @@ describe NotificationService, :mailer do
user_3 = create(:user)
recipient_1 = NotificationRecipient.new(user_1, :custom, custom_action: :new_release)
recipient_2 = NotificationRecipient.new(user_2, :custom, custom_action: :new_release)
- allow(NotificationRecipientService).to receive(:build_new_release_recipients).and_return([recipient_1, recipient_2])
+ allow(NotificationRecipients::BuildService).to receive(:build_new_release_recipients).and_return([recipient_1, recipient_2])
release
diff --git a/spec/services/snippets/create_service_spec.rb b/spec/services/snippets/create_service_spec.rb
index 5c853f8b7d7..ffad3c8b8e5 100644
--- a/spec/services/snippets/create_service_spec.rb
+++ b/spec/services/snippets/create_service_spec.rb
@@ -185,12 +185,10 @@ describe Snippets::CreateService do
expect { subject }.not_to change { Snippet.count }
end
- it 'does not create the repository' do
- expect(snippet.repository_exists?).to be_falsey
- end
-
- it 'destroys the existing repository' do
- expect(Repositories::DestroyService).to receive(:new).and_call_original
+ it 'destroys the created repository' do
+ expect_next_instance_of(Repository) do |instance|
+ expect(instance).to receive(:remove).and_call_original
+ end
subject
end