diff options
Diffstat (limited to 'spec')
| -rw-r--r-- | spec/controllers/application_controller_spec.rb | 26 | ||||
| -rw-r--r-- | spec/controllers/projects/alert_management_controller_spec.rb | 30 | ||||
| -rw-r--r-- | spec/controllers/projects/artifacts_controller_spec.rb | 40 | ||||
| -rw-r--r-- | spec/factories/ci/job_artifacts.rb | 9 | ||||
| -rw-r--r-- | spec/factories/usage_data.rb | 11 | ||||
| -rw-r--r-- | spec/fixtures/lsif.json.zip | bin | 0 -> 2178 bytes | |||
| -rw-r--r-- | spec/frontend/alert_management/components/alert_management_list_spec.js | 21 | ||||
| -rw-r--r-- | spec/frontend/ide/components/commit_sidebar/form_spec.js | 111 | ||||
| -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.rb | 14 | ||||
| -rw-r--r-- | spec/lib/gitlab/lograge/custom_options_spec.rb | 23 | ||||
| -rw-r--r-- | spec/lib/gitlab/usage_data_spec.rb | 1 | ||||
| -rw-r--r-- | spec/models/issue_spec.rb | 12 | ||||
| -rw-r--r-- | spec/models/service_spec.rb | 14 | ||||
| -rw-r--r-- | spec/requests/jwt_controller_spec.rb | 1 |
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 Binary files differnew file mode 100644 index 00000000000..a65457664b9 --- /dev/null +++ b/spec/fixtures/lsif.json.zip 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 |
