summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/clusters/applications/helm.rb1
-rw-r--r--spec/factories/site_statistics.rb6
-rw-r--r--spec/features/explore/new_menu_spec.rb167
-rw-r--r--spec/features/signed_commits_spec.rb94
-rw-r--r--spec/helpers/tree_helper_spec.rb28
-rw-r--r--spec/javascripts/blob_edit/blob_bundle_spec.js30
-rw-r--r--spec/javascripts/clusters/stores/clusters_store_spec.js1
-rw-r--r--spec/javascripts/lib/utils/common_utils_spec.js18
-rw-r--r--spec/lib/gitlab/ci/trace/chunked_io_spec.rb63
-rw-r--r--spec/lib/gitlab/database_spec.rb22
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb13
-rw-r--r--spec/lib/gitlab/git_ref_validator_spec.rb1
-rw-r--r--spec/lib/gitlab/profiler_spec.rb42
-rw-r--r--spec/models/clusters/applications/ingress_spec.rb2
-rw-r--r--spec/models/clusters/applications/jupyter_spec.rb2
-rw-r--r--spec/models/clusters/applications/knative_spec.rb47
-rw-r--r--spec/models/clusters/applications/prometheus_spec.rb2
-rw-r--r--spec/models/clusters/applications/runner_spec.rb4
-rw-r--r--spec/models/project_spec.rb22
-rw-r--r--spec/models/site_statistic_spec.rb81
-rw-r--r--spec/models/user_spec.rb36
-rw-r--r--spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb38
-rw-r--r--spec/support/helpers/gpg_helpers.rb6
-rw-r--r--spec/support/shared_examples/services/check_ingress_ip_address_service_shared_examples.rb33
-rw-r--r--spec/tasks/gitlab/site_statistics_rake_spec.rb23
-rw-r--r--spec/views/layouts/header/_new_dropdown.haml_spec.rb134
-rw-r--r--spec/workers/every_sidekiq_worker_spec.rb6
27 files changed, 493 insertions, 429 deletions
diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb
index 7fc3d16e864..fe56ac5b71d 100644
--- a/spec/factories/clusters/applications/helm.rb
+++ b/spec/factories/clusters/applications/helm.rb
@@ -59,6 +59,7 @@ FactoryBot.define do
end
factory :clusters_applications_runner, class: Clusters::Applications::Runner do
+ runner factory: %i(ci_runner)
cluster factory: %i(cluster with_installed_helm provided_by_gcp)
end
diff --git a/spec/factories/site_statistics.rb b/spec/factories/site_statistics.rb
deleted file mode 100644
index 2533d0eecc2..00000000000
--- a/spec/factories/site_statistics.rb
+++ /dev/null
@@ -1,6 +0,0 @@
-FactoryBot.define do
- factory :site_statistics, class: 'SiteStatistic' do
- id 1
- repositories_count 999
- end
-end
diff --git a/spec/features/explore/new_menu_spec.rb b/spec/features/explore/new_menu_spec.rb
deleted file mode 100644
index 259f22139ef..00000000000
--- a/spec/features/explore/new_menu_spec.rb
+++ /dev/null
@@ -1,167 +0,0 @@
-require 'spec_helper'
-
-describe 'Top Plus Menu', :js do
- let(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:project) { create(:project, :repository, creator: user, namespace: user.namespace) }
- let(:public_project) { create(:project, :public) }
-
- before do
- group.add_owner(user)
- end
-
- context 'used by full user' do
- before do
- sign_in(user)
- end
-
- it 'click on New project shows new project page' do
- visit root_dashboard_path
-
- click_topmenuitem("New project")
-
- expect(page).to have_content('Project URL')
- expect(page).to have_content('Project name')
- end
-
- it 'click on New group shows new group page' do
- visit root_dashboard_path
-
- click_topmenuitem("New group")
-
- expect(page).to have_content('Group URL')
- expect(page).to have_content('Group name')
- end
-
- it 'click on New snippet shows new snippet page' do
- visit root_dashboard_path
-
- click_topmenuitem("New snippet")
-
- expect(page).to have_content('New Snippet')
- expect(page).to have_content('Title')
- end
-
- it 'click on New issue shows new issue page' do
- visit project_path(project)
-
- click_topmenuitem("New issue")
-
- expect(page).to have_content('New Issue')
- expect(page).to have_content('Title')
- end
-
- it 'click on New merge request shows new merge request page' do
- visit project_path(project)
-
- click_topmenuitem("New merge request")
-
- expect(page).to have_content('New Merge Request')
- expect(page).to have_content('Source branch')
- expect(page).to have_content('Target branch')
- end
-
- it 'click on New project snippet shows new snippet page' do
- visit project_path(project)
-
- page.within '.header-content' do
- find('.header-new-dropdown-toggle').click
- expect(page).to have_selector('.header-new.dropdown.show', count: 1)
- find('.header-new-project-snippet a').click
- end
-
- expect(page).to have_content('New Snippet')
- expect(page).to have_content('Title')
- end
-
- it 'Click on New subgroup shows new group page', :nested_groups do
- visit group_path(group)
-
- click_topmenuitem("New subgroup")
-
- expect(page).to have_content('Group URL')
- expect(page).to have_content('Group name')
- end
-
- it 'Click on New project in group shows new project page' do
- visit group_path(group)
-
- page.within '.header-content' do
- find('.header-new-dropdown-toggle').click
- expect(page).to have_selector('.header-new.dropdown.show', count: 1)
- find('.header-new-group-project a').click
- end
-
- expect(page).to have_content('Project URL')
- expect(page).to have_content('Project name')
- end
- end
-
- context 'used by guest user' do
- let(:guest_user) { create(:user) }
-
- before do
- group.add_guest(guest_user)
- project.add_guest(guest_user)
-
- sign_in(guest_user)
- end
-
- it 'click on New issue shows new issue page' do
- visit project_path(project)
-
- click_topmenuitem("New issue")
-
- expect(page).to have_content('New Issue')
- expect(page).to have_content('Title')
- end
-
- it 'has no New merge request menu item' do
- visit project_path(project)
-
- hasnot_topmenuitem("New merge request")
- end
-
- it 'has no New project snippet menu item' do
- visit project_path(project)
-
- expect(find('.header-new.dropdown')).not_to have_selector('.header-new-project-snippet')
- end
-
- it 'public project has no New merge request menu item' do
- visit project_path(public_project)
-
- hasnot_topmenuitem("New merge request")
- end
-
- it 'public project has no New project snippet menu item' do
- visit project_path(public_project)
-
- expect(find('.header-new.dropdown')).not_to have_selector('.header-new-project-snippet')
- end
-
- it 'has no New subgroup menu item' do
- visit group_path(group)
-
- hasnot_topmenuitem("New subgroup")
- end
-
- it 'has no New project for group menu item' do
- visit group_path(group)
-
- expect(find('.header-new.dropdown')).not_to have_selector('.header-new-group-project')
- end
- end
-
- def click_topmenuitem(item_name)
- page.within '.header-content' do
- find('.header-new-dropdown-toggle').click
- expect(page).to have_selector('.header-new.dropdown.show', count: 1)
- click_link item_name
- end
- end
-
- def hasnot_topmenuitem(item_name)
- expect(find('.header-new.dropdown')).not_to have_content(item_name)
- end
-end
diff --git a/spec/features/signed_commits_spec.rb b/spec/features/signed_commits_spec.rb
index ef0e55a1468..e2b3444272e 100644
--- a/spec/features/signed_commits_spec.rb
+++ b/spec/features/signed_commits_spec.rb
@@ -1,25 +1,22 @@
+# frozen_string_literal: true
+
require 'spec_helper'
-describe 'GPG signed commits', :js do
- set(:ref) { :'2d1096e3a0ecf1d2baf6dee036cc80775d4940ba' }
- let(:project) { create(:project, :repository) }
+describe 'GPG signed commits' do
+ let(:project) { create(:project, :public, :repository) }
it 'changes from unverified to verified when the user changes his email to match the gpg key' do
- user = create :user, email: 'unrelated.user@example.org'
- project.add_maintainer(user)
+ ref = GpgHelpers::SIGNED_AND_AUTHORED_SHA
+ user = create(:user, email: 'unrelated.user@example.org')
perform_enqueued_jobs do
create :gpg_key, key: GpgHelpers::User1.public_key, user: user
end
- sign_in(user)
-
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, ref)
- within '#commits-list' do
- expect(page).to have_content 'Unverified'
- expect(page).not_to have_content 'Verified'
- end
+ expect(page).to have_link 'Unverified'
+ expect(page).not_to have_link 'Verified'
# user changes his email which makes the gpg key verified
perform_enqueued_jobs do
@@ -27,41 +24,33 @@ describe 'GPG signed commits', :js do
user.update!(email: GpgHelpers::User1.emails.first)
end
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, ref)
- within '#commits-list' do
- expect(page).to have_content 'Unverified'
- expect(page).to have_content 'Verified'
- end
+ expect(page).not_to have_link 'Unverified'
+ expect(page).to have_link 'Verified'
end
it 'changes from unverified to verified when the user adds the missing gpg key' do
- user = create :user, email: GpgHelpers::User1.emails.first
- project.add_maintainer(user)
+ ref = GpgHelpers::SIGNED_AND_AUTHORED_SHA
+ user = create(:user, email: GpgHelpers::User1.emails.first)
- sign_in(user)
+ visit project_commit_path(project, ref)
- visit project_commits_path(project, ref)
-
- within '#commits-list' do
- expect(page).to have_content 'Unverified'
- expect(page).not_to have_content 'Verified'
- end
+ expect(page).to have_link 'Unverified'
+ expect(page).not_to have_link 'Verified'
# user adds the gpg key which makes the signature valid
perform_enqueued_jobs do
create :gpg_key, key: GpgHelpers::User1.public_key, user: user
end
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, ref)
- within '#commits-list' do
- expect(page).to have_content 'Unverified'
- expect(page).to have_content 'Verified'
- end
+ expect(page).not_to have_link 'Unverified'
+ expect(page).to have_link 'Verified'
end
- context 'shows popover badges' do
+ context 'shows popover badges', :js do
let(:user_1) do
create :user, email: GpgHelpers::User1.emails.first, username: 'nannie.bernhard', name: 'Nannie Bernhard'
end
@@ -85,19 +74,10 @@ describe 'GPG signed commits', :js do
end
end
- before do
- user = create :user
- project.add_maintainer(user)
-
- sign_in(user)
- end
-
it 'unverified signature' do
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA)
- within(find('.commit', text: 'signed commit by bette cartwright')) do
- click_on 'Unverified'
- end
+ click_on 'Unverified'
within '.popover' do
expect(page).to have_content 'This commit was signed with an unverified signature.'
@@ -108,11 +88,9 @@ describe 'GPG signed commits', :js do
it 'unverified signature: user email does not match the committer email, but is the same user' do
user_2_key
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, GpgHelpers::DIFFERING_EMAIL_SHA)
- within(find('.commit', text: 'signed and authored commit by bette cartwright, different email')) do
- click_on 'Unverified'
- end
+ click_on 'Unverified'
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature, but the committer email is not verified to belong to the same user.'
@@ -125,11 +103,9 @@ describe 'GPG signed commits', :js do
it 'unverified signature: user email does not match the committer email' do
user_2_key
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, GpgHelpers::SIGNED_COMMIT_SHA)
- within(find('.commit', text: 'signed commit by bette cartwright')) do
- click_on 'Unverified'
- end
+ click_on 'Unverified'
within '.popover' do
expect(page).to have_content "This commit was signed with a different user's verified signature."
@@ -142,11 +118,9 @@ describe 'GPG signed commits', :js do
it 'verified and the gpg user has a gitlab profile' do
user_1_key
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, GpgHelpers::SIGNED_AND_AUTHORED_SHA)
- within(find('.commit', text: 'signed and authored commit by nannie bernhard')) do
- click_on 'Verified'
- end
+ click_on 'Verified'
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature and the committer email is verified to belong to the same user.'
@@ -159,20 +133,16 @@ describe 'GPG signed commits', :js do
it "verified and the gpg user's profile doesn't exist anymore" do
user_1_key
- visit project_commits_path(project, ref)
+ visit project_commit_path(project, GpgHelpers::SIGNED_AND_AUTHORED_SHA)
# wait for the signature to get generated
- within(find('.commit', text: 'signed and authored commit by nannie bernhard')) do
- expect(page).to have_content 'Verified'
- end
+ expect(page).to have_link 'Verified'
user_1.destroy!
refresh
- within(find('.commit', text: 'signed and authored commit by nannie bernhard')) do
- click_on 'Verified'
- end
+ click_on 'Verified'
within '.popover' do
expect(page).to have_content 'This commit was signed with a verified signature and the committer email is verified to belong to the same user.'
diff --git a/spec/helpers/tree_helper_spec.rb b/spec/helpers/tree_helper_spec.rb
index ab4566e261b..4a62e696cd9 100644
--- a/spec/helpers/tree_helper_spec.rb
+++ b/spec/helpers/tree_helper_spec.rb
@@ -5,6 +5,16 @@ describe TreeHelper do
let(:repository) { project.repository }
let(:sha) { 'c1c67abbaf91f624347bb3ae96eabe3a1b742478' }
+ def create_file(filename)
+ project.repository.create_file(
+ project.creator,
+ filename,
+ 'test this',
+ message: "Automatically created file #{filename}",
+ branch_name: 'master'
+ )
+ end
+
describe '.render_tree' do
before do
@id = sha
@@ -57,6 +67,15 @@ describe TreeHelper do
expect(fast_path).to start_with('/gitlab/root')
end
+
+ it 'encodes files starting with #' do
+ filename = '#test-file'
+ create_file(filename)
+
+ fast_path = fast_project_blob_path(project, filename)
+
+ expect(fast_path).to end_with('%23test-file')
+ end
end
describe '.fast_project_tree_path' do
@@ -73,6 +92,15 @@ describe TreeHelper do
expect(fast_path).to start_with('/gitlab/root')
end
+
+ it 'encodes files starting with #' do
+ filename = '#test-file'
+ create_file(filename)
+
+ fast_path = fast_project_tree_path(project, filename)
+
+ expect(fast_path).to end_with('%23test-file')
+ end
end
describe 'flatten_tree' do
diff --git a/spec/javascripts/blob_edit/blob_bundle_spec.js b/spec/javascripts/blob_edit/blob_bundle_spec.js
new file mode 100644
index 00000000000..759d170af77
--- /dev/null
+++ b/spec/javascripts/blob_edit/blob_bundle_spec.js
@@ -0,0 +1,30 @@
+import blobBundle from '~/blob_edit/blob_bundle';
+import $ from 'jquery';
+
+window.ace = {
+ config: {
+ set: () => {},
+ loadModule: () => {},
+ },
+ edit: () => ({ focus: () => {} }),
+};
+
+describe('EditBlob', () => {
+ beforeEach(() => {
+ setFixtures(`
+ <div class="js-edit-blob-form">
+ <button class="js-commit-button"></button>
+ </div>`);
+ blobBundle();
+ });
+
+ it('sets the window beforeunload listener to a function returning a string', () => {
+ expect(window.onbeforeunload()).toBe('');
+ });
+
+ it('removes beforeunload listener if commit button is clicked', () => {
+ $('.js-commit-button').click();
+
+ expect(window.onbeforeunload).toBeNull();
+ });
+});
diff --git a/spec/javascripts/clusters/stores/clusters_store_spec.js b/spec/javascripts/clusters/stores/clusters_store_spec.js
index 6a08d08f33e..7ea0878ad45 100644
--- a/spec/javascripts/clusters/stores/clusters_store_spec.js
+++ b/spec/javascripts/clusters/stores/clusters_store_spec.js
@@ -107,6 +107,7 @@ describe('Clusters Store', () => {
requestStatus: null,
requestReason: null,
hostname: null,
+ externalIp: null,
},
cert_manager: {
title: 'Cert-Manager',
diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js
index 1c7691f865a..1ec1e8a8dd9 100644
--- a/spec/javascripts/lib/utils/common_utils_spec.js
+++ b/spec/javascripts/lib/utils/common_utils_spec.js
@@ -346,6 +346,24 @@ describe('common_utils', () => {
});
});
+ describe('parseBoolean', () => {
+ it('returns true for "true"', () => {
+ expect(commonUtils.parseBoolean('true')).toEqual(true);
+ });
+
+ it('returns false for "false"', () => {
+ expect(commonUtils.parseBoolean('false')).toEqual(false);
+ });
+
+ it('returns false for "something"', () => {
+ expect(commonUtils.parseBoolean('something')).toEqual(false);
+ });
+
+ it('returns false for null', () => {
+ expect(commonUtils.parseBoolean(null)).toEqual(false);
+ });
+ });
+
describe('convertPermissionToBoolean', () => {
it('should convert a boolean in a string to a boolean', () => {
expect(commonUtils.convertPermissionToBoolean('true')).toEqual(true);
diff --git a/spec/lib/gitlab/ci/trace/chunked_io_spec.rb b/spec/lib/gitlab/ci/trace/chunked_io_spec.rb
index 6259b952add..546a9e7d0cc 100644
--- a/spec/lib/gitlab/ci/trace/chunked_io_spec.rb
+++ b/spec/lib/gitlab/ci/trace/chunked_io_spec.rb
@@ -116,6 +116,19 @@ describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do
chunked_io.each_line { |line| }
end
end
+
+ context 'when buffer consist of many empty lines' do
+ let(:sample_trace_raw) { Array.new(10, " ").join("\n") }
+
+ before do
+ build.trace.set(sample_trace_raw)
+ end
+
+ it 'yields lines' do
+ expect { |b| chunked_io.each_line(&b) }
+ .to yield_successive_args(*string_io.each_line.to_a)
+ end
+ end
end
context "#read" do
@@ -143,6 +156,22 @@ describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do
end
end
+ context 'when chunk is missing data' do
+ let(:length) { nil }
+
+ before do
+ stub_buffer_size(1024)
+ build.trace.set(sample_trace_raw)
+
+ # make second chunk to not have data
+ build.trace_chunks.second.append('', 0)
+ end
+
+ it 'raises an error' do
+ expect { subject }.to raise_error described_class::FailedToGetChunkError
+ end
+ end
+
context 'when read only first 100 bytes' do
let(:length) { 100 }
@@ -266,6 +295,40 @@ describe Gitlab::Ci::Trace::ChunkedIO, :clean_gitlab_redis_cache do
expect(chunked_io.readline).to eq(string_io.readline)
end
end
+
+ context 'when chunk is missing data' do
+ let(:length) { nil }
+
+ before do
+ build.trace.set(sample_trace_raw)
+
+ # make first chunk to have invalid data
+ build.trace_chunks.first.append('data', 0)
+ end
+
+ it 'raises an error' do
+ expect { subject }.to raise_error described_class::FailedToGetChunkError
+ end
+ end
+
+ context 'when utf-8 is being used' do
+ let(:sample_trace_raw) { sample_trace_raw_utf8.force_encoding(Encoding::BINARY) }
+ let(:sample_trace_raw_utf8) { "😺\n😺\n😺\n😺" }
+
+ before do
+ stub_buffer_size(3) # the utf-8 character has 4 bytes
+
+ build.trace.set(sample_trace_raw_utf8)
+ end
+
+ it 'has known length' do
+ expect(sample_trace_raw_utf8.bytesize).to eq(4 * 4 + 3 * 1)
+ expect(sample_trace_raw.bytesize).to eq(4 * 4 + 3 * 1)
+ expect(chunked_io.size).to eq(4 * 4 + 3 * 1)
+ end
+
+ it_behaves_like 'all line matching'
+ end
end
context "#write" do
diff --git a/spec/lib/gitlab/database_spec.rb b/spec/lib/gitlab/database_spec.rb
index 7d76519dddd..fc295b2deff 100644
--- a/spec/lib/gitlab/database_spec.rb
+++ b/spec/lib/gitlab/database_spec.rb
@@ -443,11 +443,17 @@ describe Gitlab::Database do
end
end
+ describe '.read_only?' do
+ it 'returns false' do
+ expect(described_class.read_only?).to be_falsey
+ end
+ end
+
describe '.db_read_only?' do
context 'when using PostgreSQL' do
before do
allow(ActiveRecord::Base.connection).to receive(:execute).and_call_original
- expect(described_class).to receive(:postgresql?).and_return(true)
+ allow(described_class).to receive(:postgresql?).and_return(true)
end
it 'detects a read only database' do
@@ -456,11 +462,25 @@ describe Gitlab::Database do
expect(described_class.db_read_only?).to be_truthy
end
+ # TODO: remove rails5-only tag after removing rails4 tests
+ it 'detects a read only database', :rails5 do
+ allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => true }])
+
+ expect(described_class.db_read_only?).to be_truthy
+ end
+
it 'detects a read write database' do
allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => "f" }])
expect(described_class.db_read_only?).to be_falsey
end
+
+ # TODO: remove rails5-only tag after removing rails4 tests
+ it 'detects a read write database', :rails5 do
+ allow(ActiveRecord::Base.connection).to receive(:execute).with('SELECT pg_is_in_recovery()').and_return([{ "pg_is_in_recovery" => false }])
+
+ expect(described_class.db_read_only?).to be_falsey
+ end
end
context 'when using MySQL' do
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 1fe73c12fc0..852ee9c96af 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -1469,6 +1469,19 @@ describe Gitlab::Git::Repository, :seed_helper do
end
end
end
+
+ it 'writes the HEAD' do
+ repository.write_ref('HEAD', 'refs/heads/feature')
+
+ expect(repository.commit('HEAD')).to eq(repository.commit('feature'))
+ expect(repository.root_ref).to eq('feature')
+ end
+
+ it 'writes other refs' do
+ repository.write_ref('refs/heads/feature', SeedRepo::Commit::ID)
+
+ expect(repository.commit('feature').sha).to eq(SeedRepo::Commit::ID)
+ end
end
describe '#write_config' do
diff --git a/spec/lib/gitlab/git_ref_validator_spec.rb b/spec/lib/gitlab/git_ref_validator_spec.rb
index ba7fb168a3b..3ab04a1c46d 100644
--- a/spec/lib/gitlab/git_ref_validator_spec.rb
+++ b/spec/lib/gitlab/git_ref_validator_spec.rb
@@ -27,4 +27,5 @@ describe Gitlab::GitRefValidator do
it { expect(described_class.validate('-branch')).to be_falsey }
it { expect(described_class.validate('.tag')).to be_falsey }
it { expect(described_class.validate('my branch')).to be_falsey }
+ it { expect(described_class.validate("\xA0\u0000\xB0")).to be_falsey }
end
diff --git a/spec/lib/gitlab/profiler_spec.rb b/spec/lib/gitlab/profiler_spec.rb
index 4059188fba1..8bb0c1a0b8a 100644
--- a/spec/lib/gitlab/profiler_spec.rb
+++ b/spec/lib/gitlab/profiler_spec.rb
@@ -43,31 +43,16 @@ describe Gitlab::Profiler do
it 'uses the user for auth if given' do
user = double(:user)
- user_token = 'user'
- allow(user).to receive_message_chain(:personal_access_tokens, :active, :pluck, :first).and_return(user_token)
-
- expect(app).to receive(:get).with('/', nil, 'Private-Token' => user_token)
- expect(app).to receive(:get).with('/api/v4/users')
+ expect(described_class).to receive(:with_user).with(user)
described_class.profile('/', user: user)
end
- context 'when providing a user without a personal access token' do
- it 'raises an error' do
- user = double(:user)
- allow(user).to receive_message_chain(:personal_access_tokens, :active, :pluck).and_return([])
-
- expect { described_class.profile('/', user: user) }.to raise_error('Your user must have a personal_access_token')
- end
- end
-
it 'uses the private_token for auth if both it and user are set' do
user = double(:user)
- user_token = 'user'
-
- allow(user).to receive_message_chain(:personal_access_tokens, :active, :pluck, :first).and_return(user_token)
+ expect(described_class).to receive(:with_user).with(nil).and_call_original
expect(app).to receive(:get).with('/', nil, 'Private-Token' => private_token)
expect(app).to receive(:get).with('/api/v4/users')
@@ -210,6 +195,29 @@ describe Gitlab::Profiler do
end
end
+ describe '.with_user' do
+ context 'when the user is set' do
+ let(:user) { double(:user) }
+
+ it 'overrides auth in ApplicationController to use the given user' do
+ expect(described_class.with_user(user) { ApplicationController.new.current_user }).to eq(user)
+ end
+
+ it 'cleans up ApplicationController afterwards' do
+ expect { described_class.with_user(user) { } }
+ .to not_change { ActionController.instance_methods(false) }
+ end
+ end
+
+ context 'when the user is nil' do
+ it 'does not define methods on ApplicationController' do
+ expect(ApplicationController).not_to receive(:define_method)
+
+ described_class.with_user(nil) { }
+ end
+ end
+ end
+
describe '.log_load_times_by_model' do
it 'logs the model, query count, and time by slowest first' do
expect(null_logger).to receive(:load_times_by_model).and_return(
diff --git a/spec/models/clusters/applications/ingress_spec.rb b/spec/models/clusters/applications/ingress_spec.rb
index 6b0b23eeab3..cfe0e216c78 100644
--- a/spec/models/clusters/applications/ingress_spec.rb
+++ b/spec/models/clusters/applications/ingress_spec.rb
@@ -5,7 +5,7 @@ describe Clusters::Applications::Ingress do
include_examples 'cluster application core specs', :clusters_applications_ingress
include_examples 'cluster application status specs', :clusters_applications_ingress
- include_examples 'cluster application helm specs', :clusters_applications_knative
+ include_examples 'cluster application helm specs', :clusters_applications_ingress
before do
allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
diff --git a/spec/models/clusters/applications/jupyter_spec.rb b/spec/models/clusters/applications/jupyter_spec.rb
index faaabafddb7..a40edbf267b 100644
--- a/spec/models/clusters/applications/jupyter_spec.rb
+++ b/spec/models/clusters/applications/jupyter_spec.rb
@@ -2,7 +2,7 @@ require 'rails_helper'
describe Clusters::Applications::Jupyter do
include_examples 'cluster application core specs', :clusters_applications_jupyter
- include_examples 'cluster application helm specs', :clusters_applications_knative
+ include_examples 'cluster application helm specs', :clusters_applications_jupyter
it { is_expected.to belong_to(:oauth_application) }
diff --git a/spec/models/clusters/applications/knative_spec.rb b/spec/models/clusters/applications/knative_spec.rb
index be2a91d566b..d43d88c2924 100644
--- a/spec/models/clusters/applications/knative_spec.rb
+++ b/spec/models/clusters/applications/knative_spec.rb
@@ -7,6 +7,11 @@ describe Clusters::Applications::Knative do
include_examples 'cluster application status specs', :clusters_applications_knative
include_examples 'cluster application helm specs', :clusters_applications_knative
+ before do
+ allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_in)
+ allow(ClusterWaitForIngressIpAddressWorker).to receive(:perform_async)
+ end
+
describe '.installed' do
subject { described_class.installed }
@@ -45,6 +50,48 @@ describe Clusters::Applications::Knative do
it { is_expected.to contain_exactly(cluster) }
end
+ describe 'make_installed with external_ip' do
+ before do
+ application.make_installed!
+ end
+
+ let(:application) { create(:clusters_applications_knative, :installing) }
+
+ it 'schedules a ClusterWaitForIngressIpAddressWorker' do
+ expect(ClusterWaitForIngressIpAddressWorker).to have_received(:perform_in)
+ .with(Clusters::Applications::Knative::FETCH_IP_ADDRESS_DELAY, 'knative', application.id)
+ end
+ end
+
+ describe '#schedule_status_update with external_ip' do
+ let(:application) { create(:clusters_applications_knative, :installed) }
+
+ before do
+ application.schedule_status_update
+ end
+
+ it 'schedules a ClusterWaitForIngressIpAddressWorker' do
+ expect(ClusterWaitForIngressIpAddressWorker).to have_received(:perform_async)
+ .with('knative', application.id)
+ end
+
+ context 'when the application is not installed' do
+ let(:application) { create(:clusters_applications_knative, :installing) }
+
+ it 'does not schedule a ClusterWaitForIngressIpAddressWorker' do
+ expect(ClusterWaitForIngressIpAddressWorker).not_to have_received(:perform_async)
+ end
+ end
+
+ context 'when there is already an external_ip' do
+ let(:application) { create(:clusters_applications_knative, :installed, external_ip: '111.222.222.111') }
+
+ it 'does not schedule a ClusterWaitForIngressIpAddressWorker' do
+ expect(ClusterWaitForIngressIpAddressWorker).not_to have_received(:perform_in)
+ end
+ end
+ end
+
describe '#install_command' do
subject { knative.install_command }
diff --git a/spec/models/clusters/applications/prometheus_spec.rb b/spec/models/clusters/applications/prometheus_spec.rb
index b5aa1dcece5..893ed3e3f64 100644
--- a/spec/models/clusters/applications/prometheus_spec.rb
+++ b/spec/models/clusters/applications/prometheus_spec.rb
@@ -5,7 +5,7 @@ describe Clusters::Applications::Prometheus do
include_examples 'cluster application core specs', :clusters_applications_prometheus
include_examples 'cluster application status specs', :clusters_applications_prometheus
- include_examples 'cluster application helm specs', :clusters_applications_knative
+ include_examples 'cluster application helm specs', :clusters_applications_prometheus
describe '.installed' do
subject { described_class.installed }
diff --git a/spec/models/clusters/applications/runner_spec.rb b/spec/models/clusters/applications/runner_spec.rb
index a8b28a335d6..97e50809647 100644
--- a/spec/models/clusters/applications/runner_spec.rb
+++ b/spec/models/clusters/applications/runner_spec.rb
@@ -5,7 +5,7 @@ describe Clusters::Applications::Runner do
include_examples 'cluster application core specs', :clusters_applications_runner
include_examples 'cluster application status specs', :clusters_applications_runner
- include_examples 'cluster application helm specs', :clusters_applications_knative
+ include_examples 'cluster application helm specs', :clusters_applications_runner
it { is_expected.to belong_to(:runner) }
@@ -90,7 +90,7 @@ describe Clusters::Applications::Runner do
context 'without a runner' do
let(:project) { create(:project) }
let(:cluster) { create(:cluster, :with_installed_helm, projects: [project]) }
- let(:application) { create(:clusters_applications_runner, cluster: cluster) }
+ let(:application) { create(:clusters_applications_runner, runner: nil, cluster: cluster) }
it 'creates a runner' do
expect do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 51278836604..47c331fbc7a 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -109,22 +109,6 @@ describe Project do
end
end
- context 'Site Statistics' do
- context 'when creating a new project' do
- it 'tracks project in SiteStatistic' do
- expect { create(:project) }.to change { SiteStatistic.fetch.repositories_count }.by(1)
- end
- end
-
- context 'when deleting a project' do
- it 'untracks project in SiteStatistic' do
- project = create(:project)
-
- expect { project.destroy }.to change { SiteStatistic.fetch.repositories_count }.by(-1)
- end
- end
- end
-
context 'updating cd_cd_settings' do
it 'does not raise an error' do
project = create(:project)
@@ -2203,12 +2187,6 @@ describe Project do
project.change_head(project.default_branch)
end
- it 'creates the new reference with rugged' do
- expect(project.repository.raw_repository).to receive(:write_ref).with('HEAD', "refs/heads/#{project.default_branch}", shell: false)
-
- project.change_head(project.default_branch)
- end
-
it 'copies the gitattributes' do
expect(project.repository).to receive(:copy_gitattributes).with(project.default_branch)
project.change_head(project.default_branch)
diff --git a/spec/models/site_statistic_spec.rb b/spec/models/site_statistic_spec.rb
deleted file mode 100644
index 0e739900065..00000000000
--- a/spec/models/site_statistic_spec.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-require 'spec_helper'
-
-describe SiteStatistic do
- describe '.fetch' do
- context 'existing record' do
- it 'returns existing SiteStatistic model' do
- statistics = create(:site_statistics)
-
- expect(described_class.fetch).to be_a(described_class)
- expect(described_class.fetch).to eq(statistics)
- end
- end
-
- context 'non existing record' do
- it 'creates a new SiteStatistic model' do
- expect(described_class.first).to be_nil
- expect(described_class.fetch).to be_a(described_class)
- end
- end
- end
-
- describe '.track' do
- context 'with allowed attributes' do
- let(:statistics) { create(:site_statistics) }
-
- it 'increases the attribute counter' do
- expect { described_class.track('repositories_count') }.to change { statistics.reload.repositories_count }.by(1)
- end
-
- it 'doesnt increase the attribute counter when an exception happens during transaction' do
- expect do
- begin
- described_class.transaction do
- described_class.track('repositories_count')
-
- raise StandardError
- end
- rescue StandardError
- # no-op
- end
- end.not_to change { statistics.reload.repositories_count }
- end
- end
-
- context 'with not allowed attributes' do
- it 'returns error' do
- expect { described_class.track('something_else') }.to raise_error(ArgumentError).with_message(/Invalid attribute: \'something_else\' to \'track\' method/)
- end
- end
- end
-
- describe '.untrack' do
- context 'with allowed attributes' do
- let(:statistics) { create(:site_statistics) }
-
- it 'decreases the attribute counter' do
- expect { described_class.untrack('repositories_count') }.to change { statistics.reload.repositories_count }.by(-1)
- end
-
- it 'doesnt decrease the attribute counter when an exception happens during transaction' do
- expect do
- begin
- described_class.transaction do
- described_class.track('repositories_count')
-
- raise StandardError
- end
- rescue StandardError
- # no-op
- end
- end.not_to change { described_class.fetch.repositories_count }
- end
- end
-
- context 'with not allowed attributes' do
- it 'returns error' do
- expect { described_class.untrack('something_else') }.to raise_error(ArgumentError).with_message(/Invalid attribute: \'something_else\' to \'untrack\' method/)
- end
- end
- end
-end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 733c1c49f08..7bd6dccd0ad 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1137,12 +1137,38 @@ describe User do
expect(described_class.find_by_any_email(user.email.upcase, confirmed: true)).to eq user
end
- it 'finds by secondary email' do
- email = create(:email, email: 'foo@example.com')
- user = email.user
+ context 'finds by secondary email' do
+ let(:user) { email.user }
- expect(described_class.find_by_any_email(email.email)).to eq user
- expect(described_class.find_by_any_email(email.email, confirmed: true)).to eq user
+ context 'primary email confirmed' do
+ context 'secondary email confirmed' do
+ let!(:email) { create(:email, :confirmed, email: 'foo@example.com') }
+
+ it 'finds user respecting the confirmed flag' do
+ expect(described_class.find_by_any_email(email.email)).to eq user
+ expect(described_class.find_by_any_email(email.email, confirmed: true)).to eq user
+ end
+ end
+
+ context 'secondary email not confirmed' do
+ let!(:email) { create(:email, email: 'foo@example.com') }
+
+ it 'finds user respecting the confirmed flag' do
+ expect(described_class.find_by_any_email(email.email)).to eq user
+ expect(described_class.find_by_any_email(email.email, confirmed: true)).to be_nil
+ end
+ end
+ end
+
+ context 'primary email not confirmed' do
+ let(:user) { create(:user, confirmed_at: nil) }
+ let!(:email) { create(:email, :confirmed, user: user, email: 'foo@example.com') }
+
+ it 'finds user respecting the confirmed flag' do
+ expect(described_class.find_by_any_email(email.email)).to eq user
+ expect(described_class.find_by_any_email(email.email, confirmed: true)).to be_nil
+ end
+ end
end
it 'returns nil when nothing found' do
diff --git a/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb b/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
index eb0bdb61ee3..f3036fbcb0e 100644
--- a/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
+++ b/spec/services/clusters/applications/check_ingress_ip_address_service_spec.rb
@@ -28,41 +28,7 @@ describe Clusters::Applications::CheckIngressIpAddressService do
allow(application.cluster).to receive(:kubeclient).and_return(kubeclient)
end
- describe '#execute' do
- context 'when the ingress ip address is available' do
- it 'updates the external_ip for the app' do
- subject
+ include_examples 'check ingress ip executions', :clusters_applications_ingress
- expect(application.external_ip).to eq('111.222.111.222')
- end
- end
-
- context 'when the ingress ip address is not available' do
- let(:ingress) { nil }
-
- it 'does not error' do
- subject
- end
- end
-
- context 'when the exclusive lease cannot be obtained' do
- it 'does not call kubeclient' do
- stub_exclusive_lease_taken(lease_key, timeout: 15.seconds.to_i)
-
- subject
-
- expect(kubeclient).not_to have_received(:get_service)
- end
- end
-
- context 'when there is already an external_ip' do
- let(:application) { create(:clusters_applications_ingress, :installed, external_ip: '001.111.002.111') }
-
- it 'does not call kubeclient' do
- subject
-
- expect(kubeclient).not_to have_received(:get_service)
- end
- end
- end
+ include_examples 'check ingress ip executions', :clusters_applications_knative
end
diff --git a/spec/support/helpers/gpg_helpers.rb b/spec/support/helpers/gpg_helpers.rb
index 3f7279a50e0..8d1637228d0 100644
--- a/spec/support/helpers/gpg_helpers.rb
+++ b/spec/support/helpers/gpg_helpers.rb
@@ -1,5 +1,9 @@
+# frozen_string_literal: true
+
module GpgHelpers
- SIGNED_COMMIT_SHA = '8a852d50dda17cc8fd1408d2fd0c5b0f24c76ca4'.freeze
+ SIGNED_COMMIT_SHA = '8a852d50dda17cc8fd1408d2fd0c5b0f24c76ca4'
+ SIGNED_AND_AUTHORED_SHA = '3c1d9a0266cb0c62d926f4a6c649beed561846f5'
+ DIFFERING_EMAIL_SHA = 'a17a9f66543673edf0a3d1c6b93bdda3fe600f32'
module User1
extend self
diff --git a/spec/support/shared_examples/services/check_ingress_ip_address_service_shared_examples.rb b/spec/support/shared_examples/services/check_ingress_ip_address_service_shared_examples.rb
new file mode 100644
index 00000000000..14638a574a5
--- /dev/null
+++ b/spec/support/shared_examples/services/check_ingress_ip_address_service_shared_examples.rb
@@ -0,0 +1,33 @@
+shared_examples 'check ingress ip executions' do |app_name|
+ describe '#execute' do
+ let(:application) { create(app_name, :installed) }
+ let(:service) { described_class.new(application) }
+ let(:kubeclient) { double(::Kubeclient::Client, get_service: kube_service) }
+
+ context 'when the ingress ip address is available' do
+ it 'updates the external_ip for the app' do
+ subject
+
+ expect(application.external_ip).to eq('111.222.111.222')
+ end
+ end
+
+ context 'when the ingress ip address is not available' do
+ let(:ingress) { nil }
+
+ it 'does not error' do
+ subject
+ end
+ end
+
+ context 'when the exclusive lease cannot be obtained' do
+ it 'does not call kubeclient' do
+ stub_exclusive_lease_taken(lease_key, timeout: 15.seconds.to_i)
+
+ subject
+
+ expect(kubeclient).not_to have_received(:get_service)
+ end
+ end
+ end
+end
diff --git a/spec/tasks/gitlab/site_statistics_rake_spec.rb b/spec/tasks/gitlab/site_statistics_rake_spec.rb
deleted file mode 100644
index c43ce25a540..00000000000
--- a/spec/tasks/gitlab/site_statistics_rake_spec.rb
+++ /dev/null
@@ -1,23 +0,0 @@
-# frozen_string_literal: true
-require 'rake_helper'
-
-describe 'rake gitlab:refresh_site_statistics' do
- before do
- Rake.application.rake_require 'tasks/gitlab/site_statistics'
-
- create(:project)
- SiteStatistic.fetch.update(repositories_count: 0)
- end
-
- let(:task) { 'gitlab:refresh_site_statistics' }
-
- it 'recalculates existing counters' do
- run_rake_task(task)
-
- expect(SiteStatistic.fetch.repositories_count).to eq(1)
- end
-
- it 'displays message listing counters' do
- expect { run_rake_task(task) }.to output(/Updating Site Statistics counters:.* Repositories\.\.\. OK!/m).to_stdout
- end
-end
diff --git a/spec/views/layouts/header/_new_dropdown.haml_spec.rb b/spec/views/layouts/header/_new_dropdown.haml_spec.rb
new file mode 100644
index 00000000000..2e19d0cec26
--- /dev/null
+++ b/spec/views/layouts/header/_new_dropdown.haml_spec.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'layouts/header/_new_dropdown' do
+ let(:user) { create(:user) }
+
+ context 'group-specific links' do
+ let(:group) { create(:group) }
+
+ before do
+ stub_current_user(user)
+
+ assign(:group, group)
+ end
+
+ context 'as a Group owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'has a "New project" link' do
+ render
+
+ expect(rendered).to have_link(
+ 'New project',
+ href: new_project_path(namespace_id: group.id)
+ )
+ end
+
+ it 'has a "New subgroup" link', :nested_groups do
+ render
+
+ expect(rendered).to have_link(
+ 'New subgroup',
+ href: new_group_path(parent_id: group.id)
+ )
+ end
+ end
+ end
+
+ context 'project-specific links' do
+ let(:project) { create(:project, creator: user, namespace: user.namespace) }
+
+ before do
+ assign(:project, project)
+ end
+
+ context 'as a Project owner' do
+ before do
+ stub_current_user(user)
+ end
+
+ it 'has a "New issue" link' do
+ render
+
+ expect(rendered).to have_link(
+ 'New issue',
+ href: new_project_issue_path(project)
+ )
+ end
+
+ it 'has a "New merge request" link' do
+ render
+
+ expect(rendered).to have_link(
+ 'New merge request',
+ href: project_new_merge_request_path(project)
+ )
+ end
+
+ it 'has a "New snippet" link' do
+ render
+
+ expect(rendered).to have_link(
+ 'New snippet',
+ href: new_project_snippet_path(project)
+ )
+ end
+ end
+
+ context 'as a Project guest' do
+ let(:guest) { create(:user) }
+
+ before do
+ stub_current_user(guest)
+ project.add_guest(guest)
+ end
+
+ it 'has no "New merge request" link' do
+ render
+
+ expect(rendered).not_to have_link('New merge request')
+ end
+
+ it 'has no "New snippet" link' do
+ render
+
+ expect(rendered).not_to have_link(
+ 'New snippet',
+ href: new_project_snippet_path(project)
+ )
+ end
+ end
+ end
+
+ context 'global links' do
+ before do
+ stub_current_user(user)
+ end
+
+ it 'has a "New project" link' do
+ render
+
+ expect(rendered).to have_link('New project', href: new_project_path)
+ end
+
+ it 'has a "New group" link' do
+ render
+
+ expect(rendered).to have_link('New group', href: new_group_path)
+ end
+
+ it 'has a "New snippet" link' do
+ render
+
+ expect(rendered).to have_link('New snippet', href: new_snippet_path)
+ end
+ end
+
+ def stub_current_user(current_user)
+ allow(view).to receive(:current_user).and_return(current_user)
+ end
+end
diff --git a/spec/workers/every_sidekiq_worker_spec.rb b/spec/workers/every_sidekiq_worker_spec.rb
index 2106959e23c..ebe02373275 100644
--- a/spec/workers/every_sidekiq_worker_spec.rb
+++ b/spec/workers/every_sidekiq_worker_spec.rb
@@ -9,7 +9,7 @@ describe 'Every Sidekiq worker' do
expect(Gitlab::SidekiqConfig.cron_workers.map(&:queue)).to all(start_with('cronjob:'))
end
- it 'has its queue in app/workers/all_queues.yml', :aggregate_failures do
+ it 'has its queue in Gitlab::SidekiqConfig::QUEUE_CONFIG_PATHS', :aggregate_failures do
file_worker_queues = Gitlab::SidekiqConfig.worker_queues.to_set
worker_queues = Gitlab::SidekiqConfig.workers.map(&:queue).to_set
@@ -17,10 +17,10 @@ describe 'Every Sidekiq worker' do
worker_queues << 'default'
missing_from_file = worker_queues - file_worker_queues
- expect(missing_from_file).to be_empty, "expected #{missing_from_file.to_a.inspect} to be in app/workers/all_queues.yml"
+ expect(missing_from_file).to be_empty, "expected #{missing_from_file.to_a.inspect} to be in Gitlab::SidekiqConfig::QUEUE_CONFIG_PATHS"
unncessarily_in_file = file_worker_queues - worker_queues
- expect(unncessarily_in_file).to be_empty, "expected #{unncessarily_in_file.to_a.inspect} not to be in app/workers/all_queues.yml"
+ expect(unncessarily_in_file).to be_empty, "expected #{unncessarily_in_file.to_a.inspect} not to be in Gitlab::SidekiqConfig::QUEUE_CONFIG_PATHS"
end
it 'has its queue or namespace in config/sidekiq_queues.yml', :aggregate_failures do