diff options
Diffstat (limited to 'spec')
18 files changed, 271 insertions, 34 deletions
diff --git a/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js b/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js index 4bb244df8ac..2537b8fb816 100644 --- a/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js +++ b/spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js @@ -78,6 +78,8 @@ describe('ProjectsDropdownFilter component', () => { const selectDropdownItemAtIndex = (index) => findDropdownAtIndex(index).find('button').trigger('click'); + const selectedIds = () => wrapper.vm.selectedProjects.map(({ id }) => id); + describe('queryParams are applied when fetching data', () => { beforeEach(() => { createComponent({ @@ -238,14 +240,15 @@ describe('ProjectsDropdownFilter component', () => { selectDropdownItemAtIndex(0); selectDropdownItemAtIndex(1); - expect(wrapper.emitted().selected).toEqual([[[projects[0]]], [[projects[0], projects[1]]]]); + expect(selectedIds()).toEqual([projects[0].id, projects[1].id]); }); it('should remove from selection when clicked again', () => { selectDropdownItemAtIndex(0); - selectDropdownItemAtIndex(0); + expect(selectedIds()).toEqual([projects[0].id]); - expect(wrapper.emitted().selected).toEqual([[[projects[0]]], [[]]]); + selectDropdownItemAtIndex(0); + expect(selectedIds()).toEqual([]); }); it('renders the correct placeholder text when multiple projects are selected', async () => { diff --git a/spec/frontend/boards/stores/mutations_spec.js b/spec/frontend/boards/stores/mutations_spec.js index 5b38f04e77b..37f0969a39a 100644 --- a/spec/frontend/boards/stores/mutations_spec.js +++ b/spec/frontend/boards/stores/mutations_spec.js @@ -35,6 +35,7 @@ describe('Board Store Mutations', () => { describe('SET_INITIAL_BOARD_DATA', () => { it('Should set initial Boards data to state', () => { + const allowSubEpics = true; const boardId = 1; const fullPath = 'gitlab-org'; const boardType = 'group'; @@ -45,6 +46,7 @@ describe('Board Store Mutations', () => { const issuableType = issuableTypes.issue; mutations[types.SET_INITIAL_BOARD_DATA](state, { + allowSubEpics, boardId, fullPath, boardType, @@ -53,6 +55,7 @@ describe('Board Store Mutations', () => { issuableType, }); + expect(state.allowSubEpics).toBe(allowSubEpics); expect(state.boardId).toEqual(boardId); expect(state.fullPath).toEqual(fullPath); expect(state.boardType).toEqual(boardType); diff --git a/spec/frontend/branches/components/delete_branch_button_spec.js b/spec/frontend/branches/components/delete_branch_button_spec.js index acbc83a9bdc..b029f34c3d7 100644 --- a/spec/frontend/branches/components/delete_branch_button_spec.js +++ b/spec/frontend/branches/components/delete_branch_button_spec.js @@ -34,7 +34,7 @@ describe('Delete branch button', () => { expect(findDeleteButton().attributes()).toMatchObject({ title: 'Delete branch', - variant: 'danger', + variant: 'default', icon: 'remove', }); }); @@ -44,7 +44,7 @@ describe('Delete branch button', () => { expect(findDeleteButton().attributes()).toMatchObject({ title: 'Delete protected branch', - variant: 'danger', + variant: 'default', icon: 'remove', }); }); @@ -78,7 +78,7 @@ describe('Delete branch button', () => { expect(findDeleteButton().attributes()).toMatchObject({ title: 'Delete branch', - variant: 'danger', + variant: 'default', }); }); diff --git a/spec/frontend/content_editor/components/toolbar_image_button_spec.js b/spec/frontend/content_editor/components/toolbar_image_button_spec.js new file mode 100644 index 00000000000..701dcf83476 --- /dev/null +++ b/spec/frontend/content_editor/components/toolbar_image_button_spec.js @@ -0,0 +1,78 @@ +import { GlButton, GlFormInputGroup } from '@gitlab/ui'; +import { mountExtended } from 'helpers/vue_test_utils_helper'; +import ToolbarImageButton from '~/content_editor/components/toolbar_image_button.vue'; +import { configure as configureImageExtension } from '~/content_editor/extensions/image'; +import { createTestEditor, mockChainedCommands } from '../test_utils'; + +describe('content_editor/components/toolbar_image_button', () => { + let wrapper; + let editor; + + const buildWrapper = () => { + wrapper = mountExtended(ToolbarImageButton, { + propsData: { + tiptapEditor: editor, + }, + }); + }; + + const findImageURLInput = () => + wrapper.findComponent(GlFormInputGroup).find('input[type="text"]'); + const findApplyImageButton = () => wrapper.findComponent(GlButton); + + const selectFile = async (file) => { + const input = wrapper.find({ ref: 'fileSelector' }); + + // override the property definition because `input.files` isn't directly modifyable + Object.defineProperty(input.element, 'files', { value: [file], writable: true }); + await input.trigger('change'); + }; + + beforeEach(() => { + const { tiptapExtension: Image } = configureImageExtension({ + renderMarkdown: jest.fn(), + uploadsPath: '/uploads/', + }); + + editor = createTestEditor({ + extensions: [Image], + }); + + buildWrapper(); + }); + + afterEach(() => { + editor.destroy(); + wrapper.destroy(); + }); + + it('sets the image to the value in the URL input when "Insert" button is clicked', async () => { + const commands = mockChainedCommands(editor, ['focus', 'setImage', 'run']); + + await findImageURLInput().setValue('https://example.com/img.jpg'); + await findApplyImageButton().trigger('click'); + + expect(commands.focus).toHaveBeenCalled(); + expect(commands.setImage).toHaveBeenCalledWith({ + alt: 'img', + src: 'https://example.com/img.jpg', + canonicalSrc: 'https://example.com/img.jpg', + }); + expect(commands.run).toHaveBeenCalled(); + + expect(wrapper.emitted().execute[0]).toEqual([{ contentType: 'image', value: 'url' }]); + }); + + it('uploads the selected image when file input changes', async () => { + const commands = mockChainedCommands(editor, ['focus', 'uploadImage', 'run']); + const file = new File(['foo'], 'foo.png', { type: 'image/png' }); + + await selectFile(file); + + expect(commands.focus).toHaveBeenCalled(); + expect(commands.uploadImage).toHaveBeenCalledWith({ file }); + expect(commands.run).toHaveBeenCalled(); + + expect(wrapper.emitted().execute[0]).toEqual([{ contentType: 'image', value: 'upload' }]); + }); +}); diff --git a/spec/frontend/content_editor/components/toolbar_link_button_spec.js b/spec/frontend/content_editor/components/toolbar_link_button_spec.js index 7dcf3ac659b..576a2912f72 100644 --- a/spec/frontend/content_editor/components/toolbar_link_button_spec.js +++ b/spec/frontend/content_editor/components/toolbar_link_button_spec.js @@ -76,15 +76,17 @@ describe('content_editor/components/toolbar_link_button', () => { expect(commands.unsetLink).toHaveBeenCalled(); expect(commands.setLink).toHaveBeenCalledWith({ href: 'https://example', - 'data-canonical-src': 'https://example', + canonicalSrc: 'https://example', }); expect(commands.run).toHaveBeenCalled(); + + expect(wrapper.emitted().execute[0]).toEqual([{ contentType: 'link' }]); }); describe('on selection update', () => { it('updates link input box with canonical-src if present', async () => { jest.spyOn(editor, 'getAttributes').mockReturnValueOnce({ - 'data-canonical-src': 'uploads/my-file.zip', + canonicalSrc: 'uploads/my-file.zip', href: '/username/my-project/uploads/abcdefgh133535/my-file.zip', }); @@ -130,9 +132,11 @@ describe('content_editor/components/toolbar_link_button', () => { expect(commands.focus).toHaveBeenCalled(); expect(commands.setLink).toHaveBeenCalledWith({ href: 'https://example', - 'data-canonical-src': 'https://example', + canonicalSrc: 'https://example', }); expect(commands.run).toHaveBeenCalled(); + + expect(wrapper.emitted().execute[0]).toEqual([{ contentType: 'link' }]); }); }); diff --git a/spec/frontend/content_editor/components/top_toolbar_spec.js b/spec/frontend/content_editor/components/top_toolbar_spec.js index a5d9a626a04..5411793cd5e 100644 --- a/spec/frontend/content_editor/components/top_toolbar_spec.js +++ b/spec/frontend/content_editor/components/top_toolbar_spec.js @@ -51,6 +51,7 @@ describe('content_editor/components/top_toolbar', () => { ${'code-block'} | ${{ contentType: 'codeBlock', iconName: 'doc-code', label: 'Insert a code block', editorCommand: 'toggleCodeBlock' }} ${'text-styles'} | ${{}} ${'link'} | ${{}} + ${'image'} | ${{}} `('given a $testId toolbar control', ({ testId, controlProps }) => { beforeEach(() => { buildWrapper(); diff --git a/spec/frontend/import_entities/components/group_dropdown_spec.js b/spec/frontend/import_entities/components/group_dropdown_spec.js new file mode 100644 index 00000000000..f7aa0e889ea --- /dev/null +++ b/spec/frontend/import_entities/components/group_dropdown_spec.js @@ -0,0 +1,44 @@ +import { GlSearchBoxByType, GlDropdown } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; +import GroupDropdown from '~/import_entities/components/group_dropdown.vue'; + +describe('Import entities group dropdown component', () => { + let wrapper; + let namespacesTracker; + + const createComponent = (propsData) => { + namespacesTracker = jest.fn(); + + wrapper = shallowMount(GroupDropdown, { + scopedSlots: { + default: namespacesTracker, + }, + stubs: { GlDropdown }, + propsData, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + it('passes namespaces from props to default slot', () => { + const namespaces = ['ns1', 'ns2']; + createComponent({ namespaces }); + + expect(namespacesTracker).toHaveBeenCalledWith({ namespaces }); + }); + + it('filters namespaces based on user input', async () => { + const namespaces = ['match1', 'some unrelated', 'match2']; + createComponent({ namespaces }); + + namespacesTracker.mockReset(); + wrapper.find(GlSearchBoxByType).vm.$emit('input', 'match'); + + await nextTick(); + + expect(namespacesTracker).toHaveBeenCalledWith({ namespaces: ['match1', 'match2'] }); + }); +}); diff --git a/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js b/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js index aa6a40cad18..654a8fd00d3 100644 --- a/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js +++ b/spec/frontend/import_entities/import_groups/components/import_table_row_spec.js @@ -1,8 +1,9 @@ -import { GlButton, GlDropdown, GlDropdownItem, GlLink, GlFormInput } from '@gitlab/ui'; +import { GlButton, GlDropdownItem, GlLink, GlFormInput } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import Vue, { nextTick } from 'vue'; import VueApollo from 'vue-apollo'; import createMockApollo from 'helpers/mock_apollo_helper'; +import ImportGroupDropdown from '~/import_entities/components/group_dropdown.vue'; import { STATUSES } from '~/import_entities/constants'; import ImportTableRow from '~/import_entities/import_groups/components/import_table_row.vue'; import addValidationErrorMutation from '~/import_entities/import_groups/graphql/mutations/add_validation_error.mutation.graphql'; @@ -41,7 +42,7 @@ describe('import table row', () => { }; const findImportButton = () => findByText(GlButton, 'Import'); const findNameInput = () => wrapper.find(GlFormInput); - const findNamespaceDropdown = () => wrapper.find(GlDropdown); + const findNamespaceDropdown = () => wrapper.find(ImportGroupDropdown); const createComponent = (props) => { apolloProvider = createMockApollo([ @@ -65,6 +66,7 @@ describe('import table row', () => { wrapper = shallowMount(ImportTableRow, { apolloProvider, + stubs: { ImportGroupDropdown }, propsData: { availableNamespaces: availableNamespacesFixture, groupPathRegex: /.*/, diff --git a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js index d9f4168f1a5..0e748baa313 100644 --- a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js +++ b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js @@ -11,6 +11,8 @@ import state from '~/import_entities/import_projects/store/state'; describe('ImportProjectsTable', () => { let wrapper; + const USER_NAMESPACE = 'root'; + const findFilterField = () => wrapper .findAllComponents(GlFormInput) @@ -48,7 +50,7 @@ describe('ImportProjectsTable', () => { localVue.use(Vuex); const store = new Vuex.Store({ - state: { ...state(), ...initialState }, + state: { ...state(), defaultTargetNamespace: USER_NAMESPACE, ...initialState }, getters: { ...getters, ...customGetters, diff --git a/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js b/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js index e15389be53a..72640f3d601 100644 --- a/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js +++ b/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js @@ -1,11 +1,11 @@ -import { GlBadge, GlButton } from '@gitlab/ui'; +import { GlBadge, GlButton, GlDropdown } from '@gitlab/ui'; import { createLocalVue, shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; import Vuex from 'vuex'; import { STATUSES } from '~/import_entities//constants'; +import ImportGroupDropdown from '~/import_entities/components/group_dropdown.vue'; import ImportStatus from '~/import_entities/components/import_status.vue'; import ProviderRepoTableRow from '~/import_entities/import_projects/components/provider_repo_table_row.vue'; -import Select2Select from '~/vue_shared/components/select2_select.vue'; describe('ProviderRepoTableRow', () => { let wrapper; @@ -16,10 +16,8 @@ describe('ProviderRepoTableRow', () => { newName: 'newName', }; - const availableNamespaces = [ - { text: 'Groups', children: [{ id: 'test', text: 'test' }] }, - { text: 'Users', children: [{ id: 'root', text: 'root' }] }, - ]; + const availableNamespaces = ['test']; + const userNamespace = 'root'; function initStore(initialState) { const store = new Vuex.Store({ @@ -48,7 +46,7 @@ describe('ProviderRepoTableRow', () => { wrapper = shallowMount(ProviderRepoTableRow, { localVue, store, - propsData: { availableNamespaces, ...props }, + propsData: { availableNamespaces, userNamespace, ...props }, }); } @@ -81,9 +79,8 @@ describe('ProviderRepoTableRow', () => { expect(wrapper.find(ImportStatus).props().status).toBe(STATUSES.NONE); }); - it('renders a select2 namespace select', () => { - expect(wrapper.find(Select2Select).exists()).toBe(true); - expect(wrapper.find(Select2Select).props().options.data).toBe(availableNamespaces); + it('renders a group namespace select', () => { + expect(wrapper.find(ImportGroupDropdown).props().namespaces).toBe(availableNamespaces); }); it('renders import button', () => { @@ -133,7 +130,7 @@ describe('ProviderRepoTableRow', () => { }); it('does not renders a namespace select', () => { - expect(wrapper.find(Select2Select).exists()).toBe(false); + expect(wrapper.find(GlDropdown).exists()).toBe(false); }); it('does not render import button', () => { diff --git a/spec/frontend/pipeline_editor/components/editor/ci_config_merged_preview_spec.js b/spec/frontend/pipeline_editor/components/editor/ci_config_merged_preview_spec.js index 7dd8a77d055..b797a664b75 100644 --- a/spec/frontend/pipeline_editor/components/editor/ci_config_merged_preview_spec.js +++ b/spec/frontend/pipeline_editor/components/editor/ci_config_merged_preview_spec.js @@ -1,10 +1,12 @@ -import { GlIcon } from '@gitlab/ui'; +import { GlIcon, GlAlert } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { EDITOR_READY_EVENT } from '~/editor/constants'; import CiConfigMergedPreview from '~/pipeline_editor/components/editor/ci_config_merged_preview.vue'; import { mockLintResponse, mockCiConfigPath } from '../../mock_data'; +const DEFAULT_BRANCH = 'main'; + describe('Text editor component', () => { let wrapper; @@ -16,7 +18,7 @@ describe('Text editor component', () => { }, }; - const createComponent = ({ props = {} } = {}) => { + const createComponent = ({ props = {}, currentBranch = DEFAULT_BRANCH } = {}) => { wrapper = shallowMount(CiConfigMergedPreview, { propsData: { ciConfigData: mockLintResponse, @@ -24,20 +26,45 @@ describe('Text editor component', () => { }, provide: { ciConfigPath: mockCiConfigPath, + defaultBranch: DEFAULT_BRANCH, }, stubs: { SourceEditor: MockSourceEditor, }, + data() { + return { + currentBranch, + }; + }, }); }; const findIcon = () => wrapper.findComponent(GlIcon); + const findAlert = () => wrapper.findComponent(GlAlert); const findEditor = () => wrapper.findComponent(MockSourceEditor); afterEach(() => { wrapper.destroy(); }); + // This is testing a temporary feature. + // It may be slightly hacky code that doesn't follow best practice. + // See the related MR for more information. + // https://gitlab.com/gitlab-org/gitlab/-/merge_requests/65972#note_626095644 + describe('on a non-default branch', () => { + beforeEach(() => { + createComponent({ currentBranch: 'feature' }); + }); + + it('does not load the editor', () => { + expect(findEditor().exists()).toBe(false); + }); + + it('renders an informational alert', () => { + expect(findAlert().exists()).toBe(true); + }); + }); + describe('when status is valid', () => { beforeEach(() => { createComponent(); diff --git a/spec/frontend/repository/components/tree_content_spec.js b/spec/frontend/repository/components/tree_content_spec.js index 96c19776513..1d1ec58100f 100644 --- a/spec/frontend/repository/components/tree_content_spec.js +++ b/spec/frontend/repository/components/tree_content_spec.js @@ -19,6 +19,11 @@ function factory(path, data = () => ({})) { mocks: { $apollo, }, + provide: { + glFeatures: { + increasePageSizeExponentially: true, + }, + }, }); } diff --git a/spec/lib/api/entities/job_request/image_spec.rb b/spec/lib/api/entities/ci/job_request/image_spec.rb index f13eab6a752..55aade03129 100644 --- a/spec/lib/api/entities/job_request/image_spec.rb +++ b/spec/lib/api/entities/ci/job_request/image_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe API::Entities::JobRequest::Image do +RSpec.describe API::Entities::Ci::JobRequest::Image do let(:ports) { [{ number: 80, protocol: 'http', name: 'name' }]} let(:image) { double(name: 'image_name', entrypoint: ['foo'], ports: ports)} let(:entity) { described_class.new(image) } diff --git a/spec/lib/api/entities/job_request/port_spec.rb b/spec/lib/api/entities/ci/job_request/port_spec.rb index 4820c4a691b..8e0d2cabcfc 100644 --- a/spec/lib/api/entities/job_request/port_spec.rb +++ b/spec/lib/api/entities/ci/job_request/port_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe ::API::Entities::JobRequest::Port do +RSpec.describe ::API::Entities::Ci::JobRequest::Port do let(:port) { double(number: 80, protocol: 'http', name: 'name')} let(:entity) { described_class.new(port) } diff --git a/spec/models/integrations/datadog_spec.rb b/spec/models/integrations/datadog_spec.rb index aa4d3dd47f3..00b7a19ab05 100644 --- a/spec/models/integrations/datadog_spec.rb +++ b/spec/models/integrations/datadog_spec.rb @@ -10,13 +10,13 @@ RSpec.describe Integrations::Datadog do let(:active) { true } let(:dd_site) { 'datadoghq.com' } - let(:default_url) { 'https://webhooks-http-intake.logs.datadoghq.com/v1/input/' } + let(:default_url) { 'https://webhooks-http-intake.logs.datadoghq.com/api/v2/webhook' } let(:api_url) { '' } let(:api_key) { SecureRandom.hex(32) } let(:dd_env) { 'ci' } let(:dd_service) { 'awesome-gitlab' } - let(:expected_hook_url) { default_url + api_key + "?env=#{dd_env}&service=#{dd_service}" } + let(:expected_hook_url) { default_url + "?dd-api-key=#{api_key}&env=#{dd_env}&service=#{dd_service}" } let(:instance) do described_class.new( @@ -65,7 +65,7 @@ RSpec.describe Integrations::Datadog do context 'with custom api_url' do let(:dd_site) { '' } - let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/v1/input/' } + let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/api/v2/webhook' } it { is_expected.not_to validate_presence_of(:datadog_site) } it { is_expected.to validate_presence_of(:api_url) } @@ -107,9 +107,9 @@ RSpec.describe Integrations::Datadog do end context 'with custom URL' do - let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/v1/input/' } + let(:api_url) { 'https://webhooks-http-intake.logs.datad0g.com/api/v2/webhook' } - it { is_expected.to eq(api_url + api_key + "?env=#{dd_env}&service=#{dd_service}") } + it { is_expected.to eq(api_url + "?dd-api-key=#{api_key}&env=#{dd_env}&service=#{dd_service}") } context 'blank' do let(:api_url) { '' } @@ -122,7 +122,7 @@ RSpec.describe Integrations::Datadog do let(:dd_service) { '' } let(:dd_env) { '' } - it { is_expected.to eq(default_url + api_key) } + it { is_expected.to eq(default_url + "?dd-api-key=#{api_key}") } end end diff --git a/spec/rubocop/cop/database/multiple_databases_spec.rb b/spec/rubocop/cop/database/multiple_databases_spec.rb new file mode 100644 index 00000000000..16b916d61db --- /dev/null +++ b/spec/rubocop/cop/database/multiple_databases_spec.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' +require_relative '../../../../rubocop/cop/database/multiple_databases' + +RSpec.describe RuboCop::Cop::Database::MultipleDatabases do + subject(:cop) { described_class.new } + + it 'flags the use of ActiveRecord::Base.connection' do + expect_offense(<<~SOURCE) + ActiveRecord::Base.connection.inspect + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Do not use methods from ActiveRecord::Base, [...] + SOURCE + end +end diff --git a/spec/services/service_ping/submit_service_ping_service_spec.rb b/spec/services/service_ping/submit_service_ping_service_spec.rb index ded6194a586..8a3065e6bc6 100644 --- a/spec/services/service_ping/submit_service_ping_service_spec.rb +++ b/spec/services/service_ping/submit_service_ping_service_spec.rb @@ -245,11 +245,63 @@ RSpec.describe ServicePing::SubmitService do context 'and usage data is nil' do before do + allow(ServicePing::BuildPayloadService).to receive(:execute).and_return(nil) allow(Gitlab::UsageData).to receive(:data).and_return(nil) end it_behaves_like 'does not send a blank usage ping payload' end + + context 'if payload service fails' do + before do + stub_response(body: with_dev_ops_score_params) + allow(ServicePing::BuildPayloadService).to receive(:execute).and_raise(described_class::SubmissionError, 'SubmissionError') + end + + it 'calls UsageData .data method' do + usage_data = build_usage_data + + expect(Gitlab::UsageData).to receive(:data).and_return(usage_data) + + subject.execute + end + end + + context 'calls BuildPayloadService first' do + before do + stub_response(body: with_dev_ops_score_params) + end + + it 'returns usage data' do + usage_data = build_usage_data + + expect_next_instance_of(ServicePing::BuildPayloadService) do |service| + expect(service).to receive(:execute).and_return(usage_data) + end + + subject.execute + end + end + + context 'if version app response fails' do + before do + stub_response(body: with_dev_ops_score_params, status: 404) + + usage_data = build_usage_data + allow_next_instance_of(ServicePing::BuildPayloadService) do |service| + allow(service).to receive(:execute).and_return(usage_data) + end + end + + it 'calls UsageData .data method' do + usage_data = build_usage_data + + expect(Gitlab::UsageData).to receive(:data).and_return(usage_data) + + # SubmissionError is raised as a result of 404 in response from HTTP Request + expect { subject.execute }.to raise_error(described_class::SubmissionError) + end + end end def stub_response(body:, status: 201) @@ -260,4 +312,8 @@ RSpec.describe ServicePing::SubmitService do status: status ) end + + def build_usage_data + { uuid: 'uuid', recorded_at: Time.current } + end end diff --git a/spec/tooling/danger/project_helper_spec.rb b/spec/tooling/danger/project_helper_spec.rb index 9c4e9407f90..36142a1676d 100644 --- a/spec/tooling/danger/project_helper_spec.rb +++ b/spec/tooling/danger/project_helper_spec.rb @@ -221,7 +221,7 @@ RSpec.describe Tooling::Danger::ProjectHelper do describe '.local_warning_message' do it 'returns an informational message with rules that can run' do - expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, database, datateam, documentation, duplicate_yarn_dependencies, eslint, gitaly, karma, pajamas, pipeline, prettier, product_intelligence, utility_css') + expect(described_class.local_warning_message).to eq('==> Only the following Danger rules can be run locally: changelog, database, documentation, duplicate_yarn_dependencies, eslint, gitaly, karma, pajamas, pipeline, prettier, product_intelligence, utility_css') end end |
