Skip to content
Snippets Groups Projects
Commit 1fa79760 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 82fa8a3d
No related branches found
No related tags found
No related merge requests found
Showing
with 514 additions and 84 deletions
Loading
Loading
@@ -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');
Loading
Loading
@@ -27,7 +32,7 @@ describe('Blob viewer', () => {
html: '<div>testing</div>',
});
 
spyOn(axios, 'get').and.callThrough();
jest.spyOn(axios, 'get');
});
 
afterEach(() => {
Loading
Loading
@@ -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"]')
Loading
Loading
@@ -54,7 +59,7 @@ describe('Blob viewer', () => {
 
new BlobViewer();
 
setTimeout(() => {
setImmediate(() => {
expect(
document
.querySelector('.js-blob-viewer-switch-btn[data-viewer="simple"]')
Loading
Loading
@@ -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();
});
});
 
Loading
Loading
@@ -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();
 
Loading
Loading
@@ -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();
Loading
Loading
@@ -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();
Loading
Loading
@@ -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();
});
Loading
Loading
@@ -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');
 
Loading
Loading
@@ -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);
});
});
});
Loading
Loading
@@ -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 },
});
});
Loading
Loading
// 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>
`;
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);
});
});
});
Loading
Loading
@@ -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
 
Loading
Loading
# 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
# 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
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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) }
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
 
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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') }
Loading
Loading
@@ -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)
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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) }
Loading
Loading
# 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
Loading
Loading
@@ -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
 
Loading
Loading
Loading
Loading
@@ -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
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment