summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/application_controller_spec.rb26
-rw-r--r--spec/controllers/projects/alert_management_controller_spec.rb30
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb40
-rw-r--r--spec/factories/ci/job_artifacts.rb9
-rw-r--r--spec/factories/usage_data.rb11
-rw-r--r--spec/fixtures/lsif.json.zipbin0 -> 2178 bytes
-rw-r--r--spec/frontend/alert_management/components/alert_management_list_spec.js21
-rw-r--r--spec/frontend/ide/components/commit_sidebar/form_spec.js111
-rw-r--r--spec/javascripts/monitoring/components/dashboard_resize_browser_spec.js (renamed from spec/javascripts/monitoring/components/dashboard_resize_spec.js)7
-rw-r--r--spec/lib/gitlab/application_context_spec.rb14
-rw-r--r--spec/lib/gitlab/lograge/custom_options_spec.rb23
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb1
-rw-r--r--spec/models/issue_spec.rb12
-rw-r--r--spec/models/service_spec.rb14
-rw-r--r--spec/requests/jwt_controller_spec.rb1
15 files changed, 222 insertions, 98 deletions
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 1935d05b470..b406c184b88 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -530,6 +530,14 @@ describe ApplicationController do
expect(controller.last_payload).to include('correlation_id' => 'new-id')
end
+
+ it 'adds context metadata to the payload' do
+ sign_in user
+
+ get :index
+
+ expect(controller.last_payload[:metadata]).to include('meta.user' => user.username)
+ end
end
describe '#access_denied' do
@@ -891,7 +899,7 @@ describe ApplicationController do
end
it 'sets the group if it was available' do
- group = build(:group)
+ group = build_stubbed(:group)
controller.instance_variable_set(:@group, group)
get :index, format: :json
@@ -900,7 +908,7 @@ describe ApplicationController do
end
it 'sets the project if one was available' do
- project = build(:project)
+ project = build_stubbed(:project)
controller.instance_variable_set(:@project, project)
get :index, format: :json
@@ -913,6 +921,20 @@ describe ApplicationController do
expect(json_response['meta.caller_id']).to eq('AnonymousController#index')
end
+
+ it 'assigns the context to a variable for logging' do
+ get :index, format: :json
+
+ expect(assigns(:current_context)).to include('meta.user' => user.username)
+ end
+
+ it 'assigns the context when the action caused an error' do
+ allow(controller).to receive(:index) { raise 'Broken' }
+
+ expect { get :index, format: :json }.to raise_error('Broken')
+
+ expect(assigns(:current_context)).to include('meta.user' => user.username)
+ end
end
describe '#current_user' do
diff --git a/spec/controllers/projects/alert_management_controller_spec.rb b/spec/controllers/projects/alert_management_controller_spec.rb
index 8fc2319ff88..b84376db33d 100644
--- a/spec/controllers/projects/alert_management_controller_spec.rb
+++ b/spec/controllers/projects/alert_management_controller_spec.rb
@@ -32,35 +32,17 @@ describe Projects::AlertManagementController do
end
describe 'GET #details' do
- context 'when alert_management_detail is enabled' do
- before do
- stub_feature_flags(alert_management_detail: true)
- end
-
- it 'shows the page' do
- get :details, params: { namespace_id: project.namespace, project_id: project, id: id }
-
- expect(response).to have_gitlab_http_status(:ok)
- end
-
- context 'when user is unauthorized' do
- let(:role) { :reporter }
-
- it 'shows 404' do
- get :index, params: { namespace_id: project.namespace, project_id: project }
+ it 'shows the page' do
+ get :details, params: { namespace_id: project.namespace, project_id: project, id: id }
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
+ expect(response).to have_gitlab_http_status(:ok)
end
- context 'when alert_management_detail is disabled' do
- before do
- stub_feature_flags(alert_management_detail: false)
- end
+ context 'when user is unauthorized' do
+ let(:role) { :reporter }
it 'shows 404' do
- get :details, params: { namespace_id: project.namespace, project_id: project, id: id }
+ get :index, params: { namespace_id: project.namespace, project_id: project }
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
index aa3371f7ddf..be616b566dd 100644
--- a/spec/controllers/projects/artifacts_controller_spec.rb
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -308,10 +308,13 @@ describe Projects::ArtifactsController do
end
describe 'GET raw' do
- subject { get(:raw, params: { namespace_id: project.namespace, project_id: project, job_id: job, path: path }) }
+ let(:query_params) { { namespace_id: project.namespace, project_id: project, job_id: job, path: path } }
+
+ subject { get(:raw, params: query_params) }
context 'when the file exists' do
let(:path) { 'ci_artifacts.txt' }
+ let(:archive_matcher) { /build_artifacts.zip(\?[^?]+)?$/ }
shared_examples 'a valid file' do
it 'serves the file using workhorse' do
@@ -323,8 +326,8 @@ describe Projects::ArtifactsController do
expect(params.keys).to eq(%w(Archive Entry))
expect(params['Archive']).to start_with(archive_path)
# On object storage, the URL can end with a query string
- expect(params['Archive']).to match(/build_artifacts.zip(\?[^?]+)?$/)
- expect(params['Entry']).to eq(Base64.encode64('ci_artifacts.txt'))
+ expect(params['Archive']).to match(archive_matcher)
+ expect(params['Entry']).to eq(Base64.encode64(path))
end
def send_data
@@ -359,6 +362,37 @@ describe Projects::ArtifactsController do
let(:archive_path) { 'https://' }
end
end
+
+ context 'fetching an artifact of different type' do
+ before do
+ job.job_artifacts.each(&:destroy)
+ end
+
+ context 'when the artifact is zip' do
+ let!(:artifact) { create(:ci_job_artifact, :lsif, job: job, file_path: Rails.root.join("spec/fixtures/#{file_name}")) }
+ let(:path) { 'lsif/main.go.json' }
+ let(:file_name) { 'lsif.json.zip' }
+ let(:archive_matcher) { file_name }
+ let(:query_params) { super().merge(file_type: :lsif, path: path) }
+
+ it_behaves_like 'a valid file' do
+ let(:store) { ObjectStorage::Store::LOCAL }
+ let(:archive_path) { JobArtifactUploader.root }
+ end
+ end
+
+ context 'when the artifact is not zip' do
+ let(:query_params) { super().merge(file_type: :junit, path: '') }
+
+ it 'responds with not found' do
+ create(:ci_job_artifact, :junit, job: job)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
end
end
diff --git a/spec/factories/ci/job_artifacts.rb b/spec/factories/ci/job_artifacts.rb
index da82ab67f1f..61091514822 100644
--- a/spec/factories/ci/job_artifacts.rb
+++ b/spec/factories/ci/job_artifacts.rb
@@ -231,11 +231,14 @@ FactoryBot.define do
trait :lsif do
file_type { :lsif }
- file_format { :gzip }
+ file_format { :zip }
+
+ transient do
+ file_path { Rails.root.join('spec/fixtures/lsif.json.gz') }
+ end
after(:build) do |artifact, evaluator|
- artifact.file = fixture_file_upload(
- Rails.root.join('spec/fixtures/lsif.json.gz'), 'application/x-gzip')
+ artifact.file = fixture_file_upload(evaluator.file_path, 'application/x-gzip')
end
end
diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb
index bdc4ca6fc6e..8fe0018b5a6 100644
--- a/spec/factories/usage_data.rb
+++ b/spec/factories/usage_data.rb
@@ -28,11 +28,10 @@ FactoryBot.define do
create(:project_error_tracking_setting, project: projects[1], enabled: false)
create(:alerts_service, project: projects[0])
create(:alerts_service, :inactive, project: projects[1])
- create_list(:issue, 2, project: projects[0], author: User.alert_bot)
+ alert_bot_issues = create_list(:issue, 2, project: projects[0], author: User.alert_bot)
create_list(:issue, 2, project: projects[1], author: User.alert_bot)
- create_list(:issue, 4, project: projects[0])
- create(:prometheus_alert, project: projects[0])
- create(:prometheus_alert, project: projects[0])
+ issues = create_list(:issue, 4, project: projects[0])
+ create_list(:prometheus_alert, 2, project: projects[0])
create(:prometheus_alert, project: projects[1])
create(:zoom_meeting, project: projects[0], issue: projects[0].issues[0], issue_status: :added)
create_list(:zoom_meeting, 2, project: projects[0], issue: projects[0].issues[1], issue_status: :removed)
@@ -50,6 +49,10 @@ FactoryBot.define do
create(:labeled_issue, project: projects[1], labels: [incident_label_scoped_to_project])
create(:labeled_issue, project: projects[1], labels: [incident_label_scoped_to_group])
+ # Alert Issues
+ create(:alert_management_alert, issue: issues[0], project: projects[0])
+ create(:alert_management_alert, issue: alert_bot_issues[0], project: projects[0])
+
# Enabled clusters
gcp_cluster = create(:cluster_provider_gcp, :created).cluster
create(:cluster_provider_aws, :created)
diff --git a/spec/fixtures/lsif.json.zip b/spec/fixtures/lsif.json.zip
new file mode 100644
index 00000000000..a65457664b9
--- /dev/null
+++ b/spec/fixtures/lsif.json.zip
Binary files differ
diff --git a/spec/frontend/alert_management/components/alert_management_list_spec.js b/spec/frontend/alert_management/components/alert_management_list_spec.js
index cb8e25c537c..c80b132eab9 100644
--- a/spec/frontend/alert_management/components/alert_management_list_spec.js
+++ b/spec/frontend/alert_management/components/alert_management_list_spec.js
@@ -5,9 +5,9 @@ import {
GlAlert,
GlLoadingIcon,
GlDropdown,
+ GlDropdownItem,
GlIcon,
GlTab,
- GlDropdownItem,
} from '@gitlab/ui';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import createFlash from '~/flash';
@@ -49,7 +49,9 @@ describe('AlertManagementList', () => {
...props,
},
provide: {
- glFeatures: { alertListStatusFilteringEnabled },
+ glFeatures: {
+ alertListStatusFilteringEnabled,
+ },
},
data() {
return data;
@@ -211,6 +213,21 @@ describe('AlertManagementList', () => {
).toBe('Critical');
});
+ it('navigates to the detail page when alert row is clicked', () => {
+ mountComponent({
+ props: { alertManagementEnabled: true, userCanEnableAlertManagement: true },
+ data: { alerts: mockAlerts, errored: false },
+ loading: false,
+ });
+
+ window.location.assign = jest.fn();
+
+ findAlerts()
+ .at(0)
+ .trigger('click');
+ expect(window.location.assign).toHaveBeenCalledWith('/1527542/details');
+ });
+
describe('handle date fields', () => {
it('should display time ago dates when values provided', () => {
mountComponent({
diff --git a/spec/frontend/ide/components/commit_sidebar/form_spec.js b/spec/frontend/ide/components/commit_sidebar/form_spec.js
index dfde69ab2df..129180bb46e 100644
--- a/spec/frontend/ide/components/commit_sidebar/form_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/form_spec.js
@@ -1,6 +1,5 @@
import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import waitForPromises from 'helpers/wait_for_promises';
import { projectData } from 'jest/ide/mock_data';
import store from '~/ide/stores';
import CommitForm from '~/ide/components/commit_sidebar/form.vue';
@@ -31,10 +30,10 @@ describe('IDE commit form', () => {
});
describe('compact', () => {
- beforeEach(done => {
+ beforeEach(() => {
vm.isCompact = true;
- vm.$nextTick(done);
+ return vm.$nextTick();
});
it('renders commit button in compact mode', () => {
@@ -46,95 +45,84 @@ describe('IDE commit form', () => {
expect(vm.$el.querySelector('form')).toBeNull();
});
- it('renders overview text', done => {
+ it('renders overview text', () => {
vm.$store.state.stagedFiles.push('test');
- vm.$nextTick(() => {
+ return vm.$nextTick(() => {
expect(vm.$el.querySelector('p').textContent).toContain('1 changed file');
- done();
});
});
- it('shows form when clicking commit button', done => {
+ it('shows form when clicking commit button', () => {
vm.$el.querySelector('.btn-primary').click();
- vm.$nextTick(() => {
+ return vm.$nextTick(() => {
expect(vm.$el.querySelector('form')).not.toBeNull();
-
- done();
});
});
- it('toggles activity bar view when clicking commit button', done => {
+ it('toggles activity bar view when clicking commit button', () => {
vm.$el.querySelector('.btn-primary').click();
- vm.$nextTick(() => {
+ return vm.$nextTick(() => {
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
-
- done();
});
});
- it('collapses if lastCommitMsg is set to empty and current view is not commit view', done => {
+ it('collapses if lastCommitMsg is set to empty and current view is not commit view', () => {
store.state.lastCommitMsg = 'abc';
store.state.currentActivityView = leftSidebarViews.edit.name;
- vm.$nextTick(() => {
- // if commit message is set, form is uncollapsed
- expect(vm.isCompact).toBe(false);
+ return vm
+ .$nextTick()
+ .then(() => {
+ // if commit message is set, form is uncollapsed
+ expect(vm.isCompact).toBe(false);
- store.state.lastCommitMsg = '';
+ store.state.lastCommitMsg = '';
- vm.$nextTick(() => {
+ return vm.$nextTick();
+ })
+ .then(() => {
// collapsed when set to empty
expect(vm.isCompact).toBe(true);
-
- done();
});
- });
});
});
describe('full', () => {
- beforeEach(done => {
+ beforeEach(() => {
vm.isCompact = false;
- vm.$nextTick(done);
+ return vm.$nextTick();
});
- it('updates commitMessage in store on input', done => {
+ it('updates commitMessage in store on input', () => {
const textarea = vm.$el.querySelector('textarea');
textarea.value = 'testing commit message';
textarea.dispatchEvent(new Event('input'));
- waitForPromises()
- .then(() => {
- expect(vm.$store.state.commit.commitMessage).toBe('testing commit message');
- })
- .then(done)
- .catch(done.fail);
+ return vm.$nextTick().then(() => {
+ expect(vm.$store.state.commit.commitMessage).toBe('testing commit message');
+ });
});
- it('updating currentActivityView not to commit view sets compact mode', done => {
+ it('updating currentActivityView not to commit view sets compact mode', () => {
store.state.currentActivityView = 'a';
- vm.$nextTick(() => {
+ return vm.$nextTick(() => {
expect(vm.isCompact).toBe(true);
-
- done();
});
});
- it('always opens itself in full view current activity view is not commit view when clicking commit button', done => {
+ it('always opens itself in full view current activity view is not commit view when clicking commit button', () => {
vm.$el.querySelector('.btn-primary').click();
- vm.$nextTick(() => {
+ return vm.$nextTick(() => {
expect(store.state.currentActivityView).toBe(leftSidebarViews.commit.name);
expect(vm.isCompact).toBe(false);
-
- done();
});
});
@@ -143,41 +131,54 @@ describe('IDE commit form', () => {
expect(vm.$el.querySelector('.btn-default').textContent).toContain('Collapse');
});
- it('resets commitMessage when clicking discard button', done => {
+ it('resets commitMessage when clicking discard button', () => {
vm.$store.state.commit.commitMessage = 'testing commit message';
- waitForPromises()
+ return vm
+ .$nextTick()
.then(() => {
vm.$el.querySelector('.btn-default').click();
})
- .then(Vue.nextTick)
+ .then(() => vm.$nextTick())
.then(() => {
expect(vm.$store.state.commit.commitMessage).not.toBe('testing commit message');
- })
- .then(done)
- .catch(done.fail);
+ });
});
});
describe('when submitting', () => {
beforeEach(() => {
- jest.spyOn(vm, 'commitChanges').mockImplementation(() => {});
+ jest.spyOn(vm, 'commitChanges');
+
vm.$store.state.stagedFiles.push('test');
+ vm.$store.state.commit.commitMessage = 'testing commit message';
});
- it('calls commitChanges', done => {
- vm.$store.state.commit.commitMessage = 'testing commit message';
+ it('calls commitChanges', () => {
+ vm.commitChanges.mockResolvedValue({ success: true });
+
+ return vm.$nextTick().then(() => {
+ vm.$el.querySelector('.btn-success').click();
+
+ expect(vm.commitChanges).toHaveBeenCalled();
+ });
+ });
+
+ it('opens new branch modal if commitChanges throws an error', () => {
+ vm.commitChanges.mockRejectedValue({ success: false });
- waitForPromises()
+ jest.spyOn(vm.$refs.createBranchModal, 'show').mockImplementation();
+
+ return vm
+ .$nextTick()
.then(() => {
vm.$el.querySelector('.btn-success').click();
+
+ return vm.$nextTick();
})
- .then(Vue.nextTick)
.then(() => {
- expect(vm.commitChanges).toHaveBeenCalled();
- })
- .then(done)
- .catch(done.fail);
+ expect(vm.$refs.createBranchModal.show).toHaveBeenCalled();
+ });
});
});
});
diff --git a/spec/javascripts/monitoring/components/dashboard_resize_spec.js b/spec/javascripts/monitoring/components/dashboard_resize_browser_spec.js
index 0c3193940e6..4416dbd014a 100644
--- a/spec/javascripts/monitoring/components/dashboard_resize_spec.js
+++ b/spec/javascripts/monitoring/components/dashboard_resize_browser_spec.js
@@ -1,3 +1,10 @@
+/**
+ * This file should only contain browser specific specs.
+ * If you need to add or update a spec, please see spec/frontend/monitoring/components/*.js
+ * https://gitlab.com/gitlab-org/gitlab/-/issues/194244#note_343427737
+ * https://gitlab.com/groups/gitlab-org/-/epics/895#what-if-theres-a-karma-spec-which-is-simply-unmovable-to-jest-ie-it-is-dependent-on-a-running-browser-environment
+ */
+
import Vue from 'vue';
import { createLocalVue } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
diff --git a/spec/lib/gitlab/application_context_spec.rb b/spec/lib/gitlab/application_context_spec.rb
index 6674ea059a0..3be967ac8a4 100644
--- a/spec/lib/gitlab/application_context_spec.rb
+++ b/spec/lib/gitlab/application_context_spec.rb
@@ -55,10 +55,10 @@ describe Gitlab::ApplicationContext do
end
describe '#to_lazy_hash' do
- let(:user) { build(:user) }
- let(:project) { build(:project) }
- let(:namespace) { create(:group) }
- let(:subgroup) { create(:group, parent: namespace) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:namespace) { create(:group) }
+ let_it_be(:subgroup) { create(:group, parent: namespace) }
def result(context)
context.to_lazy_hash.transform_values { |v| v.respond_to?(:call) ? v.call : v }
@@ -106,5 +106,11 @@ describe Gitlab::ApplicationContext do
context.use {}
end
+
+ it 'does not cause queries' do
+ context = described_class.new(project: create(:project), namespace: create(:group, :nested), user: create(:user))
+
+ expect { context.use { Labkit::Context.current.to_h } }.not_to exceed_query_limit(0)
+ end
end
end
diff --git a/spec/lib/gitlab/lograge/custom_options_spec.rb b/spec/lib/gitlab/lograge/custom_options_spec.rb
index 3c014ae618b..7ae8baa31b5 100644
--- a/spec/lib/gitlab/lograge/custom_options_spec.rb
+++ b/spec/lib/gitlab/lograge/custom_options_spec.rb
@@ -23,7 +23,8 @@ describe Gitlab::Lograge::CustomOptions do
params: params,
user_id: 'test',
cf_ray: SecureRandom.hex,
- cf_request_id: SecureRandom.hex
+ cf_request_id: SecureRandom.hex,
+ metadata: { 'meta.user' => 'jane.doe' }
}
)
end
@@ -56,5 +57,25 @@ describe Gitlab::Lograge::CustomOptions do
expect(subject[:cf_ray]).to eq(event.payload[:cf_ray])
expect(subject[:cf_request_id]).to eq(event.payload[:cf_request_id])
end
+
+ it 'adds the metadata' do
+ expect(subject['meta.user']).to eq('jane.doe')
+ end
+
+ context 'when metadata is missing' do
+ let(:event) do
+ ActiveSupport::Notifications::Event.new(
+ 'test',
+ 1,
+ 2,
+ 'transaction_id',
+ { params: {} }
+ )
+ end
+
+ it 'does not break' do
+ expect { subject }.not_to raise_error
+ end
+ end
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 6a905c49ea9..9c6aab10083 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -62,6 +62,7 @@ describe Gitlab::UsageData, :aggregate_failures do
expect(count_data[:issues_using_zoom_quick_actions]).to eq(3)
expect(count_data[:issues_with_embedded_grafana_charts_approx]).to eq(2)
expect(count_data[:incident_issues]).to eq(4)
+ expect(count_data[:issues_created_gitlab_alerts]).to eq(1)
expect(count_data[:alert_bot_incident_issues]).to eq(4)
expect(count_data[:incident_labeled_issues]).to eq(3)
diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb
index 39d2eccc65e..dd5ff3dbdde 100644
--- a/spec/models/issue_spec.rb
+++ b/spec/models/issue_spec.rb
@@ -80,6 +80,18 @@ describe Issue do
end
end
+ describe '.with_alert_management_alerts' do
+ subject { described_class.with_alert_management_alerts }
+
+ it 'gets only issues with alerts' do
+ alert = create(:alert_management_alert, issue: create(:issue))
+ issue = create(:issue)
+
+ expect(subject).to contain_exactly(alert.issue)
+ expect(subject).not_to include(issue)
+ end
+ end
+
describe 'locking' do
using RSpec::Parameterized::TableSyntax
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index 9662ea31960..106f8def42d 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -87,6 +87,20 @@ describe Service do
end
end
+ describe '#operating?' do
+ it 'is false when the service is not active' do
+ expect(build(:service).operating?).to eq(false)
+ end
+
+ it 'is false when the service is not persisted' do
+ expect(build(:service, active: true).operating?).to eq(false)
+ end
+
+ it 'is true when the service is active and persisted' do
+ expect(create(:service, active: true).operating?).to eq(true)
+ end
+ end
+
describe '.confidential_note_hooks' do
it 'includes services where confidential_note_events is true' do
create(:service, active: true, confidential_note_events: true)
diff --git a/spec/requests/jwt_controller_spec.rb b/spec/requests/jwt_controller_spec.rb
index 5637a56b2a4..d860179f0a7 100644
--- a/spec/requests/jwt_controller_spec.rb
+++ b/spec/requests/jwt_controller_spec.rb
@@ -23,6 +23,7 @@ describe JwtController do
it 'logs username and ID' do
expect(log_data['username']).to eq(user.username)
expect(log_data['user_id']).to eq(user.id)
+ expect(log_data['meta.user']).to eq(user.username)
end
end