summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/analytics/shared/components/projects_dropdown_filter_spec.js9
-rw-r--r--spec/frontend/boards/stores/mutations_spec.js3
-rw-r--r--spec/frontend/branches/components/delete_branch_button_spec.js6
-rw-r--r--spec/frontend/content_editor/components/toolbar_image_button_spec.js78
-rw-r--r--spec/frontend/content_editor/components/toolbar_link_button_spec.js10
-rw-r--r--spec/frontend/content_editor/components/top_toolbar_spec.js1
-rw-r--r--spec/frontend/import_entities/components/group_dropdown_spec.js44
-rw-r--r--spec/frontend/import_entities/import_groups/components/import_table_row_spec.js6
-rw-r--r--spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js4
-rw-r--r--spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js19
-rw-r--r--spec/frontend/pipeline_editor/components/editor/ci_config_merged_preview_spec.js31
-rw-r--r--spec/frontend/repository/components/tree_content_spec.js5
-rw-r--r--spec/lib/api/entities/ci/job_request/image_spec.rb (renamed from spec/lib/api/entities/job_request/image_spec.rb)2
-rw-r--r--spec/lib/api/entities/ci/job_request/port_spec.rb (renamed from spec/lib/api/entities/job_request/port_spec.rb)2
-rw-r--r--spec/models/integrations/datadog_spec.rb12
-rw-r--r--spec/rubocop/cop/database/multiple_databases_spec.rb15
-rw-r--r--spec/services/service_ping/submit_service_ping_service_spec.rb56
-rw-r--r--spec/tooling/danger/project_helper_spec.rb2
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