diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-27 12:07:43 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-03-27 12:07:43 +0000 |
commit | 39fa7d1eeb2dba52f0601128f3ac91f57d19866e (patch) | |
tree | da042d34ff762dd1957e51666a34202295a081b9 /spec | |
parent | 6ac4a6713ed3196af899011f7e18658e16ebaac0 (diff) | |
download | gitlab-ce-39fa7d1eeb2dba52f0601128f3ac91f57d19866e.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
30 files changed, 604 insertions, 51 deletions
diff --git a/spec/factories/services.rb b/spec/factories/services.rb index 2d6d8d71917..c011a9e3bb4 100644 --- a/spec/factories/services.rb +++ b/spec/factories/services.rb @@ -126,6 +126,26 @@ FactoryBot.define do end end + factory :open_project_service do + project + active { true } + + transient do + url { 'http://openproject.example.com' } + api_url { 'http://openproject.example.com/issues/:id' } + token { 'supersecret' } + closed_status_id { '15' } + project_identifier_code { 'PRJ-1' } + end + + after(:build) do |service, evaluator| + create(:open_project_tracker_data, service: service, + url: evaluator.url, api_url: evaluator.api_url, token: evaluator.token, + closed_status_id: evaluator.closed_status_id, project_identifier_code: evaluator.project_identifier_code + ) + end + end + trait :jira_cloud_service do url { 'https://mysite.atlassian.net' } username { 'jira_user' } diff --git a/spec/factories/services_data.rb b/spec/factories/services_data.rb index 5a3639895b6..c62fff2af55 100644 --- a/spec/factories/services_data.rb +++ b/spec/factories/services_data.rb @@ -9,4 +9,12 @@ FactoryBot.define do factory :issue_tracker_data do service end + + factory :open_project_tracker_data do + service + url { 'http://openproject.example.com'} + token { 'supersecret' } + project_identifier_code { 'PRJ-1' } + closed_status_id { '15' } + end end diff --git a/spec/factories/terraform/state.rb b/spec/factories/terraform/state.rb new file mode 100644 index 00000000000..4b83128ff6e --- /dev/null +++ b/spec/factories/terraform/state.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :terraform_state, class: 'Terraform::State' do + project { create(:project) } + + trait :with_file do + file { fixture_file_upload('spec/fixtures/terraform/terraform.tfstate') } + end + end +end diff --git a/spec/fixtures/terraform/terraform.tfstate b/spec/fixtures/terraform/terraform.tfstate new file mode 100644 index 00000000000..3384d9eb005 --- /dev/null +++ b/spec/fixtures/terraform/terraform.tfstate @@ -0,0 +1,8 @@ +{ + "version": 4, + "terraform_version": "0.12.21", + "serial": 1, + "lineage": "25e05991-243d-28d6-ebe3-ee0baae462cf", + "outputs": {}, + "resources": [] +}
\ No newline at end of file diff --git a/spec/frontend/__mocks__/@gitlab/ui.js b/spec/frontend/__mocks__/@gitlab/ui.js index ef97cb11424..7f893bf7ed7 100644 --- a/spec/frontend/__mocks__/@gitlab/ui.js +++ b/spec/frontend/__mocks__/@gitlab/ui.js @@ -17,3 +17,20 @@ export const GlTooltip = { return h('div', this.$attrs, this.$slots.default); }, }; + +export const GlPopoverDirective = { + bind() {}, +}; + +export const GlPopover = { + props: { + cssClasses: { + type: Array, + required: false, + default: () => [], + }, + }, + render(h) { + return h('div', this.$attrs, this.$slots.default); + }, +}; diff --git a/spec/frontend/monitoring/components/charts/bar_spec.js b/spec/frontend/monitoring/components/charts/bar_spec.js new file mode 100644 index 00000000000..e39e6e7e2c2 --- /dev/null +++ b/spec/frontend/monitoring/components/charts/bar_spec.js @@ -0,0 +1,54 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlBarChart } from '@gitlab/ui/dist/charts'; +import Bar from '~/monitoring/components/charts/bar.vue'; +import { barMockData } from '../../mock_data'; + +jest.mock('~/lib/utils/icon_utils', () => ({ + getSvgIconPathContent: jest.fn().mockResolvedValue('mockSvgPathContent'), +})); + +describe('Bar component', () => { + let barChart; + let store; + + beforeEach(() => { + barChart = shallowMount(Bar, { + propsData: { + graphData: barMockData, + }, + store, + }); + }); + + afterEach(() => { + barChart.destroy(); + }); + + describe('wrapped components', () => { + describe('GitLab UI bar chart', () => { + let glbarChart; + let chartData; + + beforeEach(() => { + glbarChart = barChart.find(GlBarChart); + chartData = barChart.vm.chartData[barMockData.metrics[0].label]; + }); + + it('is a Vue instance', () => { + expect(glbarChart.isVueInstance()).toBe(true); + }); + + it('should display a label on the x axis', () => { + expect(glbarChart.vm.xAxisTitle).toBe(barMockData.xLabel); + }); + + it('should return chartData as array of arrays', () => { + expect(chartData).toBeInstanceOf(Array); + + chartData.forEach(item => { + expect(item).toBeInstanceOf(Array); + }); + }); + }); + }); +}); diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js index c98b6a9592f..284b7a0997f 100644 --- a/spec/frontend/monitoring/mock_data.js +++ b/spec/frontend/monitoring/mock_data.js @@ -703,3 +703,50 @@ export const stackedColumnMockedData = { }, ], }; + +export const barMockData = { + title: 'SLA Trends - Primary Services', + type: 'bar-chart', + xLabel: 'service', + y_label: 'percentile', + metrics: [ + { + id: 'sla_trends_primary_services', + series_name: 'group 1', + metric_id: 'undefined_sla_trends_primary_services', + metricId: 'undefined_sla_trends_primary_services', + query_range: + 'avg(avg_over_time(slo_observation_status{environment="gprd", stage=~"main|", type=~"api|web|git|registry|sidekiq|ci-runners"}[1d])) by (type)', + unit: 'Percentile', + label: 'SLA', + prometheus_endpoint_path: + '/gitlab-com/metrics-dogfooding/-/environments/266/prometheus/api/v1/query_range?query=clamp_min%28clamp_max%28avg%28avg_over_time%28slo_observation_status%7Benvironment%3D%22gprd%22%2C+stage%3D~%22main%7C%22%2C+type%3D~%22api%7Cweb%7Cgit%7Cregistry%7Csidekiq%7Cci-runners%22%7D%5B1d%5D%29%29+by+%28type%29%2C1%29%2C0%29', + result: [ + { + metric: { type: 'api' }, + values: [[1583995208, '0.9935198135198128']], + }, + { + metric: { type: 'git' }, + values: [[1583995208, '0.9975296513504401']], + }, + { + metric: { type: 'registry' }, + values: [[1583995208, '0.9994716394716395']], + }, + { + metric: { type: 'sidekiq' }, + values: [[1583995208, '0.9948251748251747']], + }, + { + metric: { type: 'web' }, + values: [[1583995208, '0.9535664335664336']], + }, + { + metric: { type: 'postgresql_database' }, + values: [[1583995208, '0.9335664335664336']], + }, + ], + }, + ], +}; diff --git a/spec/frontend/monitoring/store/utils_spec.js b/spec/frontend/monitoring/store/utils_spec.js index 1e5bbc9c113..4bbbe33647c 100644 --- a/spec/frontend/monitoring/store/utils_spec.js +++ b/spec/frontend/monitoring/store/utils_spec.js @@ -25,6 +25,10 @@ describe('mapToDashboardViewModel', () => { panels: [ { title: 'Title A', + xLabel: '', + xAxis: { + name: '', + }, type: 'chart-type', y_label: 'Y Label A', metrics: [], @@ -44,6 +48,10 @@ describe('mapToDashboardViewModel', () => { { title: 'Title A', type: 'chart-type', + xLabel: '', + xAxis: { + name: '', + }, y_label: 'Y Label A', yAxis: { name: 'Y Label A', @@ -114,6 +122,28 @@ describe('mapToDashboardViewModel', () => { const getMappedPanel = () => mapToDashboardViewModel(dashboard).panelGroups[0].panels[0]; + it('panel with x_label', () => { + setupWithPanel({ + title: panelTitle, + x_label: 'x label', + }); + + expect(getMappedPanel()).toEqual({ + title: panelTitle, + xLabel: 'x label', + xAxis: { + name: 'x label', + }, + y_label: '', + yAxis: { + name: '', + format: SUPPORTED_FORMATS.number, + precision: 2, + }, + metrics: [], + }); + }); + it('group y_axis defaults', () => { setupWithPanel({ title: panelTitle, @@ -121,7 +151,11 @@ describe('mapToDashboardViewModel', () => { expect(getMappedPanel()).toEqual({ title: panelTitle, + xLabel: '', y_label: '', + xAxis: { + name: '', + }, yAxis: { name: '', format: SUPPORTED_FORMATS.number, diff --git a/spec/frontend/monitoring/utils_spec.js b/spec/frontend/monitoring/utils_spec.js index 2d9417bf971..262b8b985cc 100644 --- a/spec/frontend/monitoring/utils_spec.js +++ b/spec/frontend/monitoring/utils_spec.js @@ -6,6 +6,7 @@ import { graphDataPrometheusQuery, graphDataPrometheusQueryRange, anomalyMockGraphData, + barMockData, } from './mock_data'; jest.mock('~/lib/utils/url_utility'); @@ -210,4 +211,67 @@ describe('monitoring/utils', () => { expect(mergeUrlParams).toHaveBeenCalledWith({ duration_seconds: `${seconds}` }, fromUrl); }); }); + + describe('barChartsDataParser', () => { + const singleMetricExpected = { + SLA: [ + ['0.9935198135198128', 'api'], + ['0.9975296513504401', 'git'], + ['0.9994716394716395', 'registry'], + ['0.9948251748251747', 'sidekiq'], + ['0.9535664335664336', 'web'], + ['0.9335664335664336', 'postgresql_database'], + ], + }; + + const multipleMetricExpected = { + ...singleMetricExpected, + SLA_2: Object.values(singleMetricExpected)[0], + }; + + const barMockDataWithMultipleMetrics = { + ...barMockData, + metrics: [ + barMockData.metrics[0], + { + ...barMockData.metrics[0], + label: 'SLA_2', + }, + ], + }; + + [ + { + input: { metrics: undefined }, + output: {}, + testCase: 'barChartsDataParser returns {} with undefined', + }, + { + input: { metrics: null }, + output: {}, + testCase: 'barChartsDataParser returns {} with null', + }, + { + input: { metrics: [] }, + output: {}, + testCase: 'barChartsDataParser returns {} with []', + }, + { + input: barMockData, + output: singleMetricExpected, + testCase: 'barChartsDataParser returns single series object with single metrics', + }, + { + input: barMockDataWithMultipleMetrics, + output: multipleMetricExpected, + testCase: 'barChartsDataParser returns multiple series object with multiple metrics', + }, + ].forEach(({ input, output, testCase }) => { + it(testCase, () => { + expect(monitoringUtils.barChartsDataParser(input.metrics)).toEqual( + expect.objectContaining(output), + ); + }); + }); + }); }); diff --git a/spec/lib/gitlab/auth/current_user_mode_spec.rb b/spec/lib/gitlab/auth/current_user_mode_spec.rb index 8863f26fbf2..26e44fa7cc8 100644 --- a/spec/lib/gitlab/auth/current_user_mode_spec.rb +++ b/spec/lib/gitlab/auth/current_user_mode_spec.rb @@ -196,7 +196,7 @@ describe Gitlab::Auth::CurrentUserMode, :do_not_mock_admin_mode, :request_store subject.request_admin_mode! subject.enable_admin_mode!(password: user.password) - expect(session).to include(expected_session_entry(be_within(1.second).of Time.now)) + expect(session).to include(expected_session_entry(be_within(1.second).of(Time.now))) end end diff --git a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb index 243c6f06324..7a413a7aeac 100644 --- a/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb +++ b/spec/lib/gitlab/ci/build/artifacts/metadata/entry_spec.rb @@ -66,7 +66,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do describe '#children' do subject { |example| path(example).children } - it { is_expected.to all(be_an_instance_of described_class) } + it { is_expected.to all(be_an_instance_of(described_class)) } it do is_expected.to contain_exactly entry('path/dir_1/file_1'), entry('path/dir_1/file_b'), @@ -78,7 +78,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do subject { |example| path(example).files } it { is_expected.to all(be_file) } - it { is_expected.to all(be_an_instance_of described_class) } + it { is_expected.to all(be_an_instance_of(described_class)) } it do is_expected.to contain_exactly entry('path/dir_1/file_1'), entry('path/dir_1/file_b') @@ -90,7 +90,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do subject { |example| path(example).directories } it { is_expected.to all(be_directory) } - it { is_expected.to all(be_an_instance_of described_class) } + it { is_expected.to all(be_an_instance_of(described_class)) } it { is_expected.to contain_exactly entry('path/dir_1/subdir/') } end @@ -98,7 +98,7 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do subject { |example| path(example).directories(parent: true) } it { is_expected.to all(be_directory) } - it { is_expected.to all(be_an_instance_of described_class) } + it { is_expected.to all(be_an_instance_of(described_class)) } it do is_expected.to contain_exactly entry('path/dir_1/subdir/'), entry('path/') diff --git a/spec/lib/gitlab/email/message/repository_push_spec.rb b/spec/lib/gitlab/email/message/repository_push_spec.rb index b57764bceef..9e95d31f41c 100644 --- a/spec/lib/gitlab/email/message/repository_push_spec.rb +++ b/spec/lib/gitlab/email/message/repository_push_spec.rb @@ -69,7 +69,7 @@ describe Gitlab::Email::Message::RepositoryPush do describe '#diffs' do subject { message.diffs } - it { is_expected.to all(be_an_instance_of Gitlab::Diff::File) } + it { is_expected.to all(be_an_instance_of(Gitlab::Diff::File)) } end describe '#diffs_count' do diff --git a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb index ebd7c7af265..0bf46217d60 100644 --- a/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb +++ b/spec/lib/gitlab/gfm/uploads_rewriter_spec.rb @@ -74,7 +74,7 @@ describe Gitlab::Gfm::UploadsRewriter do end it 'throw an error' do - expect { rewriter.rewrite(new_project) }.to raise_error(an_instance_of(StandardError).and having_attributes(message: "Invalid path")) + expect { rewriter.rewrite(new_project) }.to raise_error(an_instance_of(StandardError).and(having_attributes(message: "Invalid path"))) end end diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index 0ed5a1e7b49..9abc8a5d88f 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -252,6 +252,7 @@ services: - service_hook - jira_tracker_data - issue_tracker_data +- open_project_tracker_data hooks: - project - web_hook_logs diff --git a/spec/lib/gitlab/import_formatter_spec.rb b/spec/lib/gitlab/import_formatter_spec.rb new file mode 100644 index 00000000000..e9f63ba5777 --- /dev/null +++ b/spec/lib/gitlab/import_formatter_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::ImportFormatter do + let(:formatter) { Gitlab::ImportFormatter.new } + + describe '#comment' do + it 'creates the correct string' do + expect(formatter.comment('Name', '2020-02-02', 'some text')).to eq( + "\n\n*By Name on 2020-02-02*\n\nsome text" + ) + end + end + + describe '#author_line' do + it 'returns the correct string with provided author name' do + expect(formatter.author_line('Name')).to eq("*Created by: Name*\n\n") + end + + it 'returns the correct string with Anonymous name if author not provided' do + expect(formatter.author_line(nil)).to eq("*Created by: Anonymous*\n\n") + end + end + + describe '#assignee_line' do + it 'returns the correct string with provided author name' do + expect(formatter.assignee_line('Name')).to eq("*Assigned to: Name*\n\n") + end + + it 'returns the correct string with Anonymous name if author not provided' do + expect(formatter.assignee_line(nil)).to eq("*Assigned to: Anonymous*\n\n") + end + end +end diff --git a/spec/lib/gitlab/jira_import/issue_serializer_spec.rb b/spec/lib/gitlab/jira_import/issue_serializer_spec.rb new file mode 100644 index 00000000000..03631a3e941 --- /dev/null +++ b/spec/lib/gitlab/jira_import/issue_serializer_spec.rb @@ -0,0 +1,89 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::JiraImport::IssueSerializer do + describe '#execute' do + let_it_be(:project) { create(:project) } + + let(:iid) { 5 } + let(:key) { 'PROJECT-5' } + let(:summary) { 'some title' } + let(:description) { 'basic description' } + let(:created_at) { '2020-01-01 20:00:00' } + let(:updated_at) { '2020-01-10 20:00:00' } + let(:assignee) { double(displayName: 'Solver') } + let(:jira_status) { 'new' } + let(:jira_issue) do + double( + id: '1234', + key: key, + summary: summary, + description: description, + created: created_at, + updated: updated_at, + assignee: assignee, + reporter: double(displayName: 'Reporter'), + status: double(statusCategory: { 'key' => jira_status }) + ) + end + let(:params) { { iid: iid } } + + let(:expected_description) do + <<~MD + *Created by: Reporter* + + *Assigned to: Solver* + + basic description + MD + end + + subject { described_class.new(project, jira_issue, params).execute } + + context 'attributes setting' do + it 'sets the basic attributes' do + expect(subject).to eq( + iid: iid, + project_id: project.id, + description: expected_description.strip, + title: "[#{key}] #{summary}", + state_id: 1, + updated_at: updated_at, + created_at: created_at, + author_id: project.creator_id + ) + end + end + + context 'with done status' do + let(:jira_status) { 'done' } + + it 'maps the status to closed' do + expect(subject[:state_id]).to eq(2) + end + end + + context 'without the assignee' do + let(:assignee) { nil } + + it 'does not include assignee in the description' do + expected_description = <<~MD + *Created by: Reporter* + + basic description + MD + + expect(subject[:description]).to eq(expected_description.strip) + end + end + + context 'without the iid' do + let(:params) { {} } + + it 'does not set the iid' do + expect(subject[:iid]).to be_nil + end + end + end +end diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb index c574cc91a59..d21efe2e1fe 100644 --- a/spec/mailers/notify_spec.rb +++ b/spec/mailers/notify_spec.rb @@ -230,7 +230,7 @@ describe Notify do is_expected.to have_referable_subject(issue, reply: true) is_expected.to have_body_text(status) is_expected.to have_body_text(current_user_sanitized) - is_expected.to have_body_text(project_issue_path project, issue) + is_expected.to have_body_text(project_issue_path(project, issue)) end end end diff --git a/spec/models/project_services/jira_tracker_data_spec.rb b/spec/models/project_services/jira_tracker_data_spec.rb index 6cd3eb33d9b..12f6b99e8a7 100644 --- a/spec/models/project_services/jira_tracker_data_spec.rb +++ b/spec/models/project_services/jira_tracker_data_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' describe JiraTrackerData do - let(:service) { create(:jira_service, active: false, properties: {}) } + let(:service) { create(:jira_service, active: false) } describe 'Associations' do it { is_expected.to belong_to(:service) } diff --git a/spec/models/project_services/open_project_service_spec.rb b/spec/models/project_services/open_project_service_spec.rb new file mode 100644 index 00000000000..8e373a31e62 --- /dev/null +++ b/spec/models/project_services/open_project_service_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe OpenProjectService do + describe 'Validations' do + context 'when service is active' do + before do + subject.active = true + end + + it { is_expected.to validate_presence_of(:url) } + it { is_expected.to validate_presence_of(:token) } + it { is_expected.to validate_presence_of(:project_identifier_code) } + + it_behaves_like 'issue tracker service URL attribute', :url + it_behaves_like 'issue tracker service URL attribute', :api_url + end + + context 'when service is inactive' do + before do + subject.active = false + end + + it { is_expected.not_to validate_presence_of(:url) } + it { is_expected.not_to validate_presence_of(:token) } + it { is_expected.not_to validate_presence_of(:project_identifier_code) } + end + end + + describe 'Associations' do + it { is_expected.to belong_to :project } + it { is_expected.to have_one :service_hook } + end +end diff --git a/spec/models/project_services/open_project_tracker_data_spec.rb b/spec/models/project_services/open_project_tracker_data_spec.rb new file mode 100644 index 00000000000..0d387bbf69b --- /dev/null +++ b/spec/models/project_services/open_project_tracker_data_spec.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe OpenProjectTrackerData do + describe 'Associations' do + it { is_expected.to belong_to(:service) } + end + + describe 'closed_status_id' do + it 'returns the set value' do + expect(build(:open_project_tracker_data).closed_status_id).to eq('15') + end + + it 'returns the default value if not set' do + expect(build(:open_project_tracker_data, closed_status_id: nil).closed_status_id).to eq('13') + end + end +end diff --git a/spec/models/terraform/state_spec.rb b/spec/models/terraform/state_spec.rb new file mode 100644 index 00000000000..1d677e7ece5 --- /dev/null +++ b/spec/models/terraform/state_spec.rb @@ -0,0 +1,52 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Terraform::State do + subject { create(:terraform_state, :with_file) } + + it { is_expected.to belong_to(:project) } + + it { is_expected.to validate_presence_of(:project_id) } + + before do + stub_terraform_state_object_storage(Terraform::StateUploader) + end + + describe '#file_store' do + context 'when no value is set' do + it 'returns the default store of the uploader' do + [ObjectStorage::Store::LOCAL, ObjectStorage::Store::REMOTE].each do |store| + expect(Terraform::StateUploader).to receive(:default_store).and_return(store) + expect(described_class.new.file_store).to eq(store) + end + end + end + + context 'when a value is set' do + it 'returns the value' do + [ObjectStorage::Store::LOCAL, ObjectStorage::Store::REMOTE].each do |store| + expect(build(:terraform_state, file_store: store).file_store).to eq(store) + end + end + end + end + + describe '#update_file_store' do + context 'when file is stored in object storage' do + it 'sets file_store to remote' do + expect(subject.file_store).to eq(ObjectStorage::Store::REMOTE) + end + end + + context 'when file is stored locally' do + before do + stub_terraform_state_object_storage(Terraform::StateUploader, enabled: false) + end + + it 'sets file_store to local' do + expect(subject.file_store).to eq(ObjectStorage::Store::LOCAL) + end + end + end +end diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb index d8fac47d6f6..a3fd365771b 100644 --- a/spec/requests/api/merge_requests_spec.rb +++ b/spec/requests/api/merge_requests_spec.rb @@ -910,13 +910,13 @@ describe API::MergeRequests do get api("/projects/#{project.id}/merge_requests/#{merge_request.reload.iid}", user) expect(json_response['merged_by']['id']).to eq(merge_request.metrics.merged_by_id) - expect(Time.parse json_response['merged_at']).to be_like_time(merge_request.metrics.merged_at) + expect(Time.parse(json_response['merged_at'])).to be_like_time(merge_request.metrics.merged_at) expect(json_response['closed_by']['id']).to eq(merge_request.metrics.latest_closed_by_id) - expect(Time.parse json_response['closed_at']).to be_like_time(merge_request.metrics.latest_closed_at) + expect(Time.parse(json_response['closed_at'])).to be_like_time(merge_request.metrics.latest_closed_at) expect(json_response['pipeline']['id']).to eq(merge_request.metrics.pipeline_id) - expect(Time.parse json_response['latest_build_started_at']).to be_like_time(merge_request.metrics.latest_build_started_at) - expect(Time.parse json_response['latest_build_finished_at']).to be_like_time(merge_request.metrics.latest_build_finished_at) - expect(Time.parse json_response['first_deployed_to_production_at']).to be_like_time(merge_request.metrics.first_deployed_to_production_at) + expect(Time.parse(json_response['latest_build_started_at'])).to be_like_time(merge_request.metrics.latest_build_started_at) + expect(Time.parse(json_response['latest_build_finished_at'])).to be_like_time(merge_request.metrics.latest_build_finished_at) + expect(Time.parse(json_response['first_deployed_to_production_at'])).to be_like_time(merge_request.metrics.first_deployed_to_production_at) end end diff --git a/spec/services/merge_requests/after_create_service_spec.rb b/spec/services/merge_requests/after_create_service_spec.rb index 974f72fa376..4aefe5f7dae 100644 --- a/spec/services/merge_requests/after_create_service_spec.rb +++ b/spec/services/merge_requests/after_create_service_spec.rb @@ -53,19 +53,5 @@ describe MergeRequests::AfterCreateService do after_create_service.execute(merge_request) end - - # https://gitlab.com/gitlab-org/gitlab/issues/208813 - context 'when the create_merge_request_pipelines_in_sidekiq flag is disabled' do - before do - stub_feature_flags(create_merge_request_pipelines_in_sidekiq: false) - end - - it 'does not create a pipeline or update the HEAD pipeline' do - expect(after_create_service).not_to receive(:create_pipeline_for) - expect(merge_request).not_to receive(:update_head_pipeline) - - after_create_service.execute(merge_request) - end - end end end diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb index 2514fda5053..dc34546a599 100644 --- a/spec/services/merge_requests/create_service_spec.rb +++ b/spec/services/merge_requests/create_service_spec.rb @@ -129,22 +129,6 @@ describe MergeRequests::CreateService, :clean_gitlab_redis_shared_state do end end - # https://gitlab.com/gitlab-org/gitlab/issues/208813 - context 'when the create_merge_request_pipelines_in_sidekiq flag is disabled' do - before do - stub_feature_flags(create_merge_request_pipelines_in_sidekiq: false) - end - - it 'creates a pipeline and updates the HEAD pipeline' do - expect(service).to receive(:create_pipeline_for) - expect_next_instance_of(MergeRequest) do |merge_request| - expect(merge_request).to receive(:update_head_pipeline) - end - - service.execute - end - end - context 'when head pipelines already exist for merge request source branch', :sidekiq_inline do let(:shas) { project.repository.commits(opts[:source_branch], limit: 2).map(&:id) } let!(:pipeline_1) { create(:ci_pipeline, project: project, ref: opts[:source_branch], project_id: project.id, sha: shas[1]) } diff --git a/spec/services/projects/group_links/create_service_spec.rb b/spec/services/projects/group_links/create_service_spec.rb index 6ded57f961c..92667184be8 100644 --- a/spec/services/projects/group_links/create_service_spec.rb +++ b/spec/services/projects/group_links/create_service_spec.rb @@ -27,6 +27,6 @@ describe Projects::GroupLinks::CreateService, '#execute' do end it 'returns error if user is not allowed to share with a group' do - expect { subject.execute(create :group) }.not_to change { project.project_group_links.count } + expect { subject.execute(create(:group)) }.not_to change { project.project_group_links.count } end end diff --git a/spec/services/releases/create_service_spec.rb b/spec/services/releases/create_service_spec.rb index b624b9475e3..255f044db90 100644 --- a/spec/services/releases/create_service_spec.rb +++ b/spec/services/releases/create_service_spec.rb @@ -160,7 +160,7 @@ describe Releases::CreateService do context 'when no milestone is passed in' do it 'creates a release without a milestone tied to it' do - expect(params.key? :milestones).to be_falsey + expect(params.key?(:milestones)).to be_falsey service.execute release = project.releases.last diff --git a/spec/services/spam/spam_check_service_spec.rb b/spec/services/spam/spam_check_service_spec.rb index 732b64b52a0..8ae6764c5d5 100644 --- a/spec/services/spam/spam_check_service_spec.rb +++ b/spec/services/spam/spam_check_service_spec.rb @@ -103,7 +103,7 @@ describe Spam::SpamCheckService do issue.description = 'SPAM!' end - context 'when indicated as spam by akismet' do + context 'when indicated as spam by Akismet' do before do allow(Spam::AkismetService).to receive(:new).and_return(double(spam?: true)) end @@ -115,7 +115,7 @@ describe Spam::SpamCheckService do it_behaves_like 'akismet spam' - it 'checks as spam' do + it 'marks as spam' do subject expect(issue.reload.spam).to be_truthy @@ -125,7 +125,7 @@ describe Spam::SpamCheckService do context 'when allow_possible_spam feature flag is true' do it_behaves_like 'akismet spam' - it 'does not check as spam' do + it 'does not mark as spam' do subject expect(issue.spam).to be_falsey @@ -133,7 +133,7 @@ describe Spam::SpamCheckService do end end - context 'when not indicated as spam by akismet' do + context 'when not indicated as spam by Akismet' do before do allow(Spam::AkismetService).to receive(:new).and_return(double(spam?: false)) end diff --git a/spec/services/wiki_pages/update_service_spec.rb b/spec/services/wiki_pages/update_service_spec.rb index 3eb486833e6..ece714ee8e5 100644 --- a/spec/services/wiki_pages/update_service_spec.rb +++ b/spec/services/wiki_pages/update_service_spec.rb @@ -94,7 +94,7 @@ describe WikiPages::UpdateService do end it 'reports the error' do - expect(service.execute page).to be_invalid + expect(service.execute(page)).to be_invalid .and have_attributes(errors: be_present) end end diff --git a/spec/support/helpers/stub_object_storage.rb b/spec/support/helpers/stub_object_storage.rb index 392300a4436..d4ac286e959 100644 --- a/spec/support/helpers/stub_object_storage.rb +++ b/spec/support/helpers/stub_object_storage.rb @@ -70,6 +70,13 @@ module StubObjectStorage **params) end + def stub_terraform_state_object_storage(uploader = described_class, **params) + stub_object_storage_uploader(config: Gitlab.config.terraform_state.object_store, + uploader: uploader, + remote_directory: 'terraform_state', + **params) + end + def stub_object_storage_multipart_init(endpoint, upload_id = "upload_id") stub_request(:post, %r{\A#{endpoint}tmp/uploads/[a-z0-9-]*\?uploads\z}) .to_return status: 200, body: <<-EOS.strip_heredoc diff --git a/spec/uploaders/terraform/state_uploader_spec.rb b/spec/uploaders/terraform/state_uploader_spec.rb new file mode 100644 index 00000000000..4577a2c4738 --- /dev/null +++ b/spec/uploaders/terraform/state_uploader_spec.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Terraform::StateUploader do + subject { terraform_state.file } + + let(:terraform_state) { create(:terraform_state, file: fixture_file_upload('spec/fixtures/terraform/terraform.tfstate')) } + + before do + stub_terraform_state_object_storage + end + + describe '#filename' do + it 'contains the ID of the terraform state record' do + expect(subject.filename).to include(terraform_state.id.to_s) + end + end + + describe '#store_dir' do + it 'contains the ID of the project' do + expect(subject.store_dir).to include(terraform_state.project_id.to_s) + end + end + + describe '#key' do + it 'creates a digest with a secret key and the project id' do + expect(OpenSSL::HMAC) + .to receive(:digest) + .with('SHA256', Gitlab::Application.secrets.db_key_base, terraform_state.project_id.to_s) + .and_return('digest') + + expect(subject.key).to eq('digest') + end + end + + describe 'encryption' do + it 'encrypts the stored file' do + expect(subject.file.read).not_to eq(fixture_file('terraform/terraform.tfstate')) + end + + it 'decrypts the file when reading' do + expect(subject.read).to eq(fixture_file('terraform/terraform.tfstate')) + end + end + + describe '.direct_upload_enabled?' do + it 'returns false' do + expect(described_class.direct_upload_enabled?).to eq(false) + end + end + + describe '.background_upload_enabled?' do + it 'returns false' do + expect(described_class.background_upload_enabled?).to eq(false) + end + end + + describe '.proxy_download_enabled?' do + it 'returns true' do + expect(described_class.proxy_download_enabled?).to eq(true) + end + end + + describe '.default_store' do + context 'when object storage is enabled' do + it 'returns REMOTE' do + expect(described_class.default_store).to eq(ObjectStorage::Store::REMOTE) + end + end + + context 'when object storage is disabled' do + before do + stub_terraform_state_object_storage(enabled: false) + end + + it 'returns LOCAL' do + expect(described_class.default_store).to eq(ObjectStorage::Store::LOCAL) + end + end + end +end |