Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-08-10 18:11:53 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-08-10 18:11:53 +0300
commit0a412bceb98cd7acd46701d75dbad9683cb33baf (patch)
tree4bb45380d97ae2c12cf101b2f30bcc5a9f114d89 /spec
parent70eb0cf7518e1ccc2a26d9aaa9fc16e21c6de5f1 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/ci/variables.rb1
-rw-r--r--spec/features/boards/boards_spec.rb2
-rw-r--r--spec/features/runners_spec.rb6
-rw-r--r--spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js4
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js6
-rw-r--r--spec/frontend/integrations/overrides/components/integration_overrides_spec.js2
-rw-r--r--spec/frontend/notes/deprecated_notes_spec.js20
-rw-r--r--spec/frontend/pages/projects/graphs/code_coverage_spec.js4
-rw-r--r--spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js4
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js87
-rw-r--r--spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js5
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js45
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js64
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js64
-rw-r--r--spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb6
-rw-r--r--spec/lib/gitlab/ci/variables/collection_spec.rb32
-rw-r--r--spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb4
-rw-r--r--spec/models/data_list_spec.rb2
-rw-r--r--spec/models/integration_spec.rb2
-rw-r--r--spec/models/project_spec.rb6
-rw-r--r--spec/presenters/ci/build_runner_presenter_spec.rb61
-rw-r--r--spec/requests/api/members_spec.rb27
-rw-r--r--spec/requests/api/project_attributes.yml1
-rw-r--r--spec/requests/api/projects_spec.rb2
-rw-r--r--spec/services/bulk_update_integration_service_spec.rb2
-rw-r--r--spec/services/merge_requests/create_pipeline_service_spec.rb10
28 files changed, 298 insertions, 173 deletions
diff --git a/spec/factories/ci/variables.rb b/spec/factories/ci/variables.rb
index a4cbf873b0b..1f9c12ecbce 100644
--- a/spec/factories/ci/variables.rb
+++ b/spec/factories/ci/variables.rb
@@ -5,6 +5,7 @@ FactoryBot.define do
sequence(:key) { |n| "VARIABLE_#{n}" }
value { 'VARIABLE_VALUE' }
masked { false }
+ variable_type { :env_var }
trait(:protected) do
add_attribute(:protected) { true }
diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb
index 9ba7f809372..f279af90aa3 100644
--- a/spec/features/boards/boards_spec.rb
+++ b/spec/features/boards/boards_spec.rb
@@ -275,7 +275,7 @@ RSpec.describe 'Project issue boards', :js do
context 'issue card' do
it 'shows assignee' do
page.within(find('.board:nth-child(2)')) do
- expect(page).to have_selector('.avatar', count: 1)
+ expect(page).to have_selector('.gl-avatar', count: 1)
end
end
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index 534da71e39a..2600c00346e 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -268,7 +268,7 @@ RSpec.describe 'Runners' do
it 'group runners are not available' do
visit project_runners_path(project)
- expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).not_to have_content 'To register them, go to the group\'s Runners page.'
expect(page).to have_content 'Ask your group owner to set up a group runner'
end
end
@@ -287,7 +287,7 @@ RSpec.describe 'Runners' do
expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).to have_content 'To register them, go to the group\'s Runners page.'
expect(page).not_to have_content 'Ask your group owner to set up a group runner'
end
end
@@ -313,7 +313,7 @@ RSpec.describe 'Runners' do
expect(page).to have_content 'This group does not have any group runners yet.'
- expect(page).not_to have_content 'Group owners can register group runners in the group\'s CI/CD settings.'
+ expect(page).not_to have_content 'To register them, go to the group\'s Runners page.'
expect(page).to have_content 'Ask your group owner to set up a group runner.'
end
end
diff --git a/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js b/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js
index 9b93fd26fa0..bffadbde087 100644
--- a/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js
+++ b/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js
@@ -87,7 +87,7 @@ describe('AddContextCommitsModal', () => {
it('enabled ok button when atleast one row is selected', async () => {
wrapper.vm.$store.state.selectedCommits = [{ ...commit, isSelected: true }];
await nextTick();
- expect(findModal().attributes('ok-disabled')).toBeFalsy();
+ expect(findModal().attributes('ok-disabled')).toBe(undefined);
});
});
@@ -102,7 +102,7 @@ describe('AddContextCommitsModal', () => {
it('an enabled ok button when atleast one row is selected', async () => {
wrapper.vm.$store.state.selectedCommits = [{ ...commit, isSelected: true }];
await nextTick();
- expect(findModal().attributes('ok-disabled')).toBeFalsy();
+ expect(findModal().attributes('ok-disabled')).toBe(undefined);
});
it('a disabled ok button in first tab, when row is selected in second tab', () => {
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index c6de3ee69f3..985902b4a3b 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -238,7 +238,7 @@ describe('Board card component', () => {
});
it('renders assignee', () => {
- expect(wrapper.find('.board-card-assignee .avatar').exists()).toBe(true);
+ expect(wrapper.find('.board-card-assignee .gl-avatar').exists()).toBe(true);
});
it('sets title', () => {
@@ -336,7 +336,7 @@ describe('Board card component', () => {
});
it('renders all three assignees', () => {
- expect(wrapper.findAll('.board-card-assignee .avatar').length).toEqual(3);
+ expect(wrapper.findAll('.board-card-assignee .gl-avatar').length).toEqual(3);
});
describe('more than three assignees', () => {
@@ -362,7 +362,7 @@ describe('Board card component', () => {
});
it('renders two assignees', () => {
- expect(wrapper.findAll('.board-card-assignee .avatar').length).toEqual(2);
+ expect(wrapper.findAll('.board-card-assignee .gl-avatar').length).toEqual(2);
});
it('renders 99+ avatar counter', async () => {
diff --git a/spec/frontend/integrations/overrides/components/integration_overrides_spec.js b/spec/frontend/integrations/overrides/components/integration_overrides_spec.js
index 6aa3e661677..12d5674a705 100644
--- a/spec/frontend/integrations/overrides/components/integration_overrides_spec.js
+++ b/spec/frontend/integrations/overrides/components/integration_overrides_spec.js
@@ -90,7 +90,7 @@ describe('IntegrationOverrides', () => {
const table = findGlTable();
expect(table.exists()).toBe(true);
- expect(table.attributes('busy')).toBeFalsy();
+ expect(table.attributes('busy')).toBeUndefined();
});
it('renders IntegrationTabs with count', async () => {
diff --git a/spec/frontend/notes/deprecated_notes_spec.js b/spec/frontend/notes/deprecated_notes_spec.js
index 9378f4feb0c..d5e2a189afe 100644
--- a/spec/frontend/notes/deprecated_notes_spec.js
+++ b/spec/frontend/notes/deprecated_notes_spec.js
@@ -508,7 +508,7 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
notes.putEditFormInPlace($el);
- expect(notes.glForm.enableGFM).toBeTruthy();
+ expect(notes.glForm.enableGFM).toBe('');
});
});
@@ -781,21 +781,21 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
const sampleComment = '/wip\n/milestone %1.0\n/merge\n/unassign Merging this';
const hasQuickActions = notes.hasQuickActions(sampleComment);
- expect(hasQuickActions).toBeTruthy();
+ expect(hasQuickActions).toBe(true);
});
it('should return false when comment does NOT begin with a quick action', () => {
const sampleComment = 'Hey, /unassign Merging this';
const hasQuickActions = notes.hasQuickActions(sampleComment);
- expect(hasQuickActions).toBeFalsy();
+ expect(hasQuickActions).toBe(false);
});
it('should return false when comment does NOT have any quick actions', () => {
const sampleComment = 'Looking good, Awesome!';
const hasQuickActions = notes.hasQuickActions(sampleComment);
- expect(hasQuickActions).toBeFalsy();
+ expect(hasQuickActions).toBe(false);
});
});
@@ -885,14 +885,14 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
expect($tempNote.prop('nodeName')).toEqual('LI');
expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ expect($tempNote.hasClass('being-posted')).toBe(true);
+ expect($tempNote.hasClass('fade-in-half')).toBe(true);
$tempNote.find('.timeline-icon > a, .note-header-info > a').each((i, el) => {
expect(el.getAttribute('href')).toEqual(`/${currentUsername}`);
});
expect($tempNote.find('.timeline-icon .avatar').attr('src')).toEqual(currentUserAvatar);
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeFalsy();
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBe(false);
expect($tempNoteHeader.find('.d-none.d-sm-inline-block').text().trim()).toEqual(
currentUserFullname,
);
@@ -914,7 +914,7 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
});
expect($tempNote.prop('nodeName')).toEqual('LI');
- expect($tempNote.find('.timeline-content').hasClass('discussion')).toBeTruthy();
+ expect($tempNote.find('.timeline-content').hasClass('discussion')).toBe(true);
});
it('should return a escaped user name', () => {
@@ -952,8 +952,8 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
expect($tempNote.prop('nodeName')).toEqual('LI');
expect($tempNote.attr('id')).toEqual(uniqueId);
- expect($tempNote.hasClass('being-posted')).toBeTruthy();
- expect($tempNote.hasClass('fade-in-half')).toBeTruthy();
+ expect($tempNote.hasClass('being-posted')).toBe(true);
+ expect($tempNote.hasClass('fade-in-half')).toBe(true);
expect($tempNote.find('.timeline-content i').text().trim()).toEqual(sampleCommandDescription);
});
});
diff --git a/spec/frontend/pages/projects/graphs/code_coverage_spec.js b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
index 0457a5eb9a9..f272891919d 100644
--- a/spec/frontend/pages/projects/graphs/code_coverage_spec.js
+++ b/spec/frontend/pages/projects/graphs/code_coverage_spec.js
@@ -163,8 +163,8 @@ describe('Code Coverage', () => {
await nextTick();
- expect(findFirstDropdownItem().attributes('ischecked')).toBeFalsy();
- expect(findSecondDropdownItem().attributes('ischecked')).toBeTruthy();
+ expect(findFirstDropdownItem().attributes('ischecked')).toBe(undefined);
+ expect(findSecondDropdownItem().attributes('ischecked')).toBe('true');
});
it('updates the graph data when selecting a different option in dropdown', async () => {
diff --git a/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js b/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js
index f5f01b675b2..b8fbc2b2460 100644
--- a/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js
+++ b/spec/frontend/pipeline_editor/components/validate/ci_validate_spec.js
@@ -159,7 +159,7 @@ describe('Pipeline Editor Validate Tab', () => {
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
mutation: lintCIMutation,
variables: {
- dry_run: true,
+ dry: true,
content: mockCiYml,
endpoint: mockCiLintPath,
},
@@ -243,7 +243,7 @@ describe('Pipeline Editor Validate Tab', () => {
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
mutation: lintCIMutation,
variables: {
- dry_run: true,
+ dry: true,
content: 'new yaml content',
endpoint: mockCiLintPath,
},
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index 3f7d311060c..0f7cf4e61b2 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -21,12 +21,13 @@ import blobInfoQuery from '~/repository/queries/blob_info.query.graphql';
import userInfoQuery from '~/repository/queries/user_info.query.graphql';
import applicationInfoQuery from '~/repository/queries/application_info.query.graphql';
import CodeIntelligence from '~/code_navigation/components/app.vue';
-import { redirectTo } from '~/lib/utils/url_utility';
+import * as urlUtility from '~/lib/utils/url_utility';
import { isLoggedIn, handleLocationHash } from '~/lib/utils/common_utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import httpStatusCodes from '~/lib/utils/http_status';
import LineHighlighter from '~/blob/line_highlighter';
import { LEGACY_FILE_TYPES } from '~/repository/constants';
+import { SIMPLE_BLOB_VIEWER, RICH_BLOB_VIEWER } from '~/blob/components/constants';
import {
simpleViewerMock,
richViewerMock,
@@ -53,7 +54,12 @@ const mockAxios = new MockAdapter(axios);
const createMockStore = () =>
new Vuex.Store({ actions: { fetchData: jest.fn, setInitialData: jest.fn() } });
-const createComponent = async (mockData = {}, mountFn = shallowMount) => {
+const mockRouterPush = jest.fn();
+const mockRouter = {
+ push: mockRouterPush,
+};
+
+const createComponent = async (mockData = {}, mountFn = shallowMount, mockRoute = {}) => {
Vue.use(VueApollo);
const {
@@ -106,6 +112,10 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
apolloProvider: fakeApollo,
propsData: propsMock,
mixins: [{ data: () => ({ ref: refMock }) }],
+ mocks: {
+ $route: mockRoute,
+ $router: mockRouter,
+ },
provide: {
targetBranch: 'test',
originalBranch: 'default-ref',
@@ -158,10 +168,11 @@ describe('Blob content viewer component', () => {
it('renders a BlobHeader component', async () => {
await createComponent();
- expect(findBlobHeader().props('activeViewerType')).toEqual('simple');
+ expect(findBlobHeader().props('activeViewerType')).toEqual(SIMPLE_BLOB_VIEWER);
expect(findBlobHeader().props('hasRenderError')).toEqual(false);
expect(findBlobHeader().props('hideViewerSwitcher')).toEqual(true);
expect(findBlobHeader().props('blob')).toEqual(simpleViewerMock);
+ expect(mockRouterPush).not.toHaveBeenCalled();
});
it('copies blob text to clipboard', async () => {
@@ -179,7 +190,7 @@ describe('Blob content viewer component', () => {
expect(findBlobContent().props('activeViewer')).toEqual({
fileType: 'text',
tooLarge: false,
- type: 'simple',
+ type: SIMPLE_BLOB_VIEWER,
renderError: null,
});
});
@@ -247,10 +258,11 @@ describe('Blob content viewer component', () => {
it('renders a BlobHeader component', async () => {
await createComponent({ blob: richViewerMock });
- expect(findBlobHeader().props('activeViewerType')).toEqual('rich');
+ expect(findBlobHeader().props('activeViewerType')).toEqual(RICH_BLOB_VIEWER);
expect(findBlobHeader().props('hasRenderError')).toEqual(false);
expect(findBlobHeader().props('hideViewerSwitcher')).toEqual(false);
expect(findBlobHeader().props('blob')).toEqual(richViewerMock);
+ expect(mockRouterPush).not.toHaveBeenCalled();
});
it('renders a BlobContent component', async () => {
@@ -260,30 +272,49 @@ describe('Blob content viewer component', () => {
expect(findBlobContent().props('activeViewer')).toEqual({
fileType: 'markup',
tooLarge: false,
- type: 'rich',
+ type: RICH_BLOB_VIEWER,
renderError: null,
});
});
- it('updates viewer type when viewer changed is clicked', async () => {
+ it('changes to simple viewer when URL has code line hash', async () => {
+ jest.spyOn(urlUtility, 'getLocationHash').mockReturnValueOnce('L5');
+
await createComponent({ blob: richViewerMock });
expect(findBlobContent().props('activeViewer')).toEqual(
expect.objectContaining({
- type: 'rich',
+ type: SIMPLE_BLOB_VIEWER,
+ }),
+ );
+ expect(findBlobHeader().props('activeViewerType')).toEqual(SIMPLE_BLOB_VIEWER);
+ });
+
+ it('updates viewer type when viewer changed is clicked', async () => {
+ await createComponent({ blob: richViewerMock }, shallowMount, { path: '/mock_path' });
+
+ expect(findBlobContent().props('activeViewer')).toEqual(
+ expect.objectContaining({
+ type: RICH_BLOB_VIEWER,
}),
);
- expect(findBlobHeader().props('activeViewerType')).toEqual('rich');
+ expect(findBlobHeader().props('activeViewerType')).toEqual(RICH_BLOB_VIEWER);
- findBlobHeader().vm.$emit('viewer-changed', 'simple');
+ findBlobHeader().vm.$emit('viewer-changed', SIMPLE_BLOB_VIEWER);
await nextTick();
- expect(findBlobHeader().props('activeViewerType')).toEqual('simple');
+ expect(findBlobHeader().props('activeViewerType')).toEqual(SIMPLE_BLOB_VIEWER);
expect(findBlobContent().props('activeViewer')).toEqual(
expect.objectContaining({
- type: 'simple',
+ type: SIMPLE_BLOB_VIEWER,
}),
);
+ expect(mockRouterPush).toHaveBeenCalledWith({
+ path: '/mock_path',
+ query: {
+ plain: '1',
+ },
+ });
});
});
@@ -503,12 +534,12 @@ describe('Blob content viewer component', () => {
it('simple edit redirects to the simple editor', () => {
findWebIdeLink().vm.$emit('edit', 'simple');
- expect(redirectTo).toHaveBeenCalledWith(simpleViewerMock.editBlobPath);
+ expect(urlUtility.redirectTo).toHaveBeenCalledWith(simpleViewerMock.editBlobPath);
});
it('IDE edit redirects to the IDE editor', () => {
findWebIdeLink().vm.$emit('edit', 'ide');
- expect(redirectTo).toHaveBeenCalledWith(simpleViewerMock.ideEditPath);
+ expect(urlUtility.redirectTo).toHaveBeenCalledWith(simpleViewerMock.ideEditPath);
});
it.each`
@@ -543,4 +574,32 @@ describe('Blob content viewer component', () => {
},
);
});
+
+ describe('active viewer based on plain attribute', () => {
+ it.each`
+ hasRichViewer | plain | activeViewerType
+ ${true} | ${'0'} | ${RICH_BLOB_VIEWER}
+ ${true} | ${'1'} | ${SIMPLE_BLOB_VIEWER}
+ ${false} | ${'0'} | ${SIMPLE_BLOB_VIEWER}
+ ${false} | ${'1'} | ${SIMPLE_BLOB_VIEWER}
+ `(
+ 'activeViewerType is `$activeViewerType` when hasRichViewer is $hasRichViewer and plain is set to $plain',
+ async ({ hasRichViewer, plain, activeViewerType }) => {
+ await createComponent(
+ { blob: hasRichViewer ? richViewerMock : simpleViewerMock },
+ shallowMount,
+ { query: { plain } },
+ );
+
+ await nextTick();
+
+ expect(findBlobContent().props('activeViewer')).toEqual(
+ expect.objectContaining({
+ type: activeViewerType,
+ }),
+ );
+ expect(findBlobHeader().props('activeViewerType')).toEqual(activeViewerType);
+ },
+ );
+ });
});
diff --git a/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js b/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
index eb2eec92534..9a63f566dec 100644
--- a/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
+++ b/spec/frontend/vue_shared/components/source_viewer/components/chunk_line_spec.js
@@ -1,4 +1,3 @@
-import { GlLink } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ChunkLine from '~/vue_shared/components/source_viewer/components/chunk_line.vue';
import {
@@ -20,7 +19,7 @@ describe('Chunk Line component', () => {
wrapper = shallowMountExtended(ChunkLine, { propsData: { ...DEFAULT_PROPS, ...props } });
};
- const findLink = () => wrapper.findComponent(GlLink);
+ const findLink = () => wrapper.findByTestId('line-number-anchor');
const findContent = () => wrapper.findByTestId('content');
const findWrappedBidiChars = () => wrapper.findAllByTestId('bidi-wrapper');
@@ -50,7 +49,7 @@ describe('Chunk Line component', () => {
it('renders a line number', () => {
expect(findLink().attributes()).toMatchObject({
'data-line-number': `${DEFAULT_PROPS.number}`,
- to: `#L${DEFAULT_PROPS.number}`,
+ href: `#L${DEFAULT_PROPS.number}`,
id: `L${DEFAULT_PROPS.number}`,
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
index 5e05b54cb8c..f87737ca86a 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_new_spec.js
@@ -18,6 +18,8 @@ const PROVIDED_PROPS = {
describe('User Avatar Image Component', () => {
let wrapper;
+ const findAvatar = () => wrapper.findComponent(GlAvatar);
+
afterEach(() => {
wrapper.destroy();
});
@@ -28,21 +30,14 @@ describe('User Avatar Image Component', () => {
propsData: {
...PROVIDED_PROPS,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should render `GlAvatar` and provide correct properties to it', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.attributes('data-src')).toBe(
+ expect(findAvatar().attributes('data-src')).toBe(
`${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
);
- expect(avatar.props()).toMatchObject({
+ expect(findAvatar().props()).toMatchObject({
src: `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
alt: PROVIDED_PROPS.imgAlt,
size: PROVIDED_PROPS.size,
@@ -63,23 +58,28 @@ describe('User Avatar Image Component', () => {
...PROVIDED_PROPS,
lazy: true,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should add lazy attributes', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.classes()).toContain('lazy');
- expect(avatar.attributes()).toMatchObject({
+ expect(findAvatar().classes()).toContain('lazy');
+ expect(findAvatar().attributes()).toMatchObject({
src: placeholderImage,
'data-src': `${PROVIDED_PROPS.imgSrc}?width=${PROVIDED_PROPS.size}`,
});
});
+
+ it('should use maximum number when size is provided as an object', () => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ size: { default: 16, md: 64, lg: 24 },
+ lazy: true,
+ },
+ });
+
+ expect(findAvatar().attributes('data-src')).toBe(`${PROVIDED_PROPS.imgSrc}?width=${64}`);
+ });
});
describe('Initialization without src', () => {
@@ -89,18 +89,11 @@ describe('User Avatar Image Component', () => {
...PROVIDED_PROPS,
imgSrc: null,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
});
});
it('should have default avatar image', () => {
- const avatar = wrapper.findComponent(GlAvatar);
-
- expect(avatar.props('src')).toBe(`${defaultAvatarUrl}?width=${PROVIDED_PROPS.size}`);
+ expect(findAvatar().props('src')).toBe(`${defaultAvatarUrl}?width=${PROVIDED_PROPS.size}`);
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
index 75d2a936b34..6ad2ef226c2 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_image_spec.js
@@ -15,47 +15,37 @@ const PROVIDED_PROPS = {
describe('User Avatar Image Component', () => {
let wrapper;
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...PROVIDED_PROPS,
+ const createWrapper = (props = {}, { glAvatarForAllUserAvatars } = {}) => {
+ wrapper = shallowMount(UserAvatarImage, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ ...props,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
- });
+ },
});
+ };
- it('should render `UserAvatarImageNew` component', () => {
- expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(true);
- expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(false);
- });
+ afterEach(() => {
+ wrapper.destroy();
});
- describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarImage, {
- propsData: {
- ...PROVIDED_PROPS,
- },
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: false,
- },
- },
+ describe.each([
+ [false, true, true],
+ [true, false, true],
+ [true, true, true],
+ [false, false, false],
+ ])(
+ 'when glAvatarForAllUserAvatars=%s and enforceGlAvatar=%s',
+ (glAvatarForAllUserAvatars, enforceGlAvatar, isUsingNewVersion) => {
+ it(`will render ${isUsingNewVersion ? 'new' : 'old'} version`, () => {
+ createWrapper({ enforceGlAvatar }, { glAvatarForAllUserAvatars });
+ expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(isUsingNewVersion);
+ expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(!isUsingNewVersion);
});
- });
-
- it('should render `UserAvatarImageOld` component', () => {
- expect(wrapper.findComponent(UserAvatarImageNew).exists()).toBe(false);
- expect(wrapper.findComponent(UserAvatarImageOld).exists()).toBe(true);
- });
- });
+ },
+ );
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
index 5ba80b31b99..f485a14cfea 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_new_spec.js
@@ -54,6 +54,7 @@ describe('User Avatar Link Component', () => {
size: defaultProps.imgSize,
tooltipPlacement: defaultProps.tooltipPlacement,
tooltipText: '',
+ enforceGlAvatar: false,
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
index 2d513c46e77..cf7a1025dba 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_old_spec.js
@@ -54,6 +54,7 @@ describe('User Avatar Link Component', () => {
size: defaultProps.imgSize,
tooltipPlacement: defaultProps.tooltipPlacement,
tooltipText: '',
+ enforceGlAvatar: false,
});
});
diff --git a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
index b36b83d1fea..fd3f59008ec 100644
--- a/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
+++ b/spec/frontend/vue_shared/components/user_avatar/user_avatar_link_spec.js
@@ -15,47 +15,37 @@ const PROVIDED_PROPS = {
describe('User Avatar Link Component', () => {
let wrapper;
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('when `glAvatarForAllUserAvatars` feature flag enabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarLink, {
- propsData: {
- ...PROVIDED_PROPS,
+ const createWrapper = (props = {}, { glAvatarForAllUserAvatars } = {}) => {
+ wrapper = shallowMount(UserAvatarLink, {
+ propsData: {
+ ...PROVIDED_PROPS,
+ ...props,
+ },
+ provide: {
+ glFeatures: {
+ glAvatarForAllUserAvatars,
},
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: true,
- },
- },
- });
+ },
});
+ };
- it('should render `UserAvatarLinkNew` component', () => {
- expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(true);
- expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(false);
- });
+ afterEach(() => {
+ wrapper.destroy();
});
- describe('when `glAvatarForAllUserAvatars` feature flag disabled', () => {
- beforeEach(() => {
- wrapper = shallowMount(UserAvatarLink, {
- propsData: {
- ...PROVIDED_PROPS,
- },
- provide: {
- glFeatures: {
- glAvatarForAllUserAvatars: false,
- },
- },
+ describe.each([
+ [false, true, true],
+ [true, false, true],
+ [true, true, true],
+ [false, false, false],
+ ])(
+ 'when glAvatarForAllUserAvatars=%s and enforceGlAvatar=%s',
+ (glAvatarForAllUserAvatars, enforceGlAvatar, isUsingNewVersion) => {
+ it(`will render ${isUsingNewVersion ? 'new' : 'old'} version`, () => {
+ createWrapper({ enforceGlAvatar }, { glAvatarForAllUserAvatars });
+ expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(isUsingNewVersion);
+ expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(!isUsingNewVersion);
});
- });
-
- it('should render `UserAvatarLinkOld` component', () => {
- expect(wrapper.findComponent(UserAvatarLinkNew).exists()).toBe(false);
- expect(wrapper.findComponent(UserAvatarLinkOld).exists()).toBe(true);
- });
- });
+ },
+ );
});
diff --git a/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb b/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb
index 564d970280c..c090c1df424 100644
--- a/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb
+++ b/spec/lib/gitlab/background_migration/update_jira_tracker_data_deployment_type_based_on_url_spec.rb
@@ -49,9 +49,9 @@ RSpec.describe Gitlab::BackgroundMigration::UpdateJiraTrackerDataDeploymentTypeB
stub_const('CLOUD', 2)
end
- let!(:tracker_data_cloud) { JiraTrackerData.create!(id: 1, service_id: service_jira_cloud.id, url: "https://test-domain.atlassian.net", deployment_type: UNKNOWN) }
- let!(:tracker_data_server) { JiraTrackerData.create!(id: 2, service_id: service_jira_server.id, url: "http://totally-not-jira-server.company.org", deployment_type: UNKNOWN) }
- let!(:tracker_data_unknown) { JiraTrackerData.create!(id: 3, service_id: service_jira_unknown.id, url: "", deployment_type: UNKNOWN) }
+ let!(:tracker_data_cloud) { JiraTrackerData.create!(id: 1, integration_id: service_jira_cloud.id, url: "https://test-domain.atlassian.net", deployment_type: UNKNOWN) }
+ let!(:tracker_data_server) { JiraTrackerData.create!(id: 2, integration_id: service_jira_server.id, url: "http://totally-not-jira-server.company.org", deployment_type: UNKNOWN) }
+ let!(:tracker_data_unknown) { JiraTrackerData.create!(id: 3, integration_id: service_jira_unknown.id, url: "", deployment_type: UNKNOWN) }
it "changes unknown deployment_types based on URL" do
expect(JiraTrackerData.pluck(:deployment_type)).to match_array([UNKNOWN, UNKNOWN, UNKNOWN])
diff --git a/spec/lib/gitlab/ci/variables/collection_spec.rb b/spec/lib/gitlab/ci/variables/collection_spec.rb
index 26c560565e0..8ac03301322 100644
--- a/spec/lib/gitlab/ci/variables/collection_spec.rb
+++ b/spec/lib/gitlab/ci/variables/collection_spec.rb
@@ -302,6 +302,7 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
.append(key: 'CI_BUILD_ID', value: '1')
.append(key: 'RAW_VAR', value: '$TEST1', raw: true)
.append(key: 'TEST1', value: 'test-3')
+ .append(key: 'FILEVAR1', value: 'file value 1', file: true)
end
context 'table tests' do
@@ -311,28 +312,23 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
{
"empty value": {
value: '',
- result: '',
- keep_undefined: false
+ result: ''
},
"simple expansions": {
value: 'key$TEST1-$CI_BUILD_ID',
- result: 'keytest-3-1',
- keep_undefined: false
+ result: 'keytest-3-1'
},
"complex expansion": {
value: 'key${TEST1}-${CI_JOB_NAME}',
- result: 'keytest-3-test-1',
- keep_undefined: false
+ result: 'keytest-3-test-1'
},
"complex expansions with raw variable": {
value: 'key${RAW_VAR}-${CI_JOB_NAME}',
- result: 'key$TEST1-test-1',
- keep_undefined: false
+ result: 'key$TEST1-test-1'
},
"missing variable not keeping original": {
value: 'key${MISSING_VAR}-${CI_JOB_NAME}',
- result: 'key-test-1',
- keep_undefined: false
+ result: 'key-test-1'
},
"missing variable keeping original": {
value: 'key${MISSING_VAR}-${CI_JOB_NAME}',
@@ -341,14 +337,24 @@ RSpec.describe Gitlab::Ci::Variables::Collection do
},
"escaped characters are kept intact": {
value: 'key-$TEST1-%%HOME%%-$${HOME}',
- result: 'key-test-3-%%HOME%%-$${HOME}',
- keep_undefined: false
+ result: 'key-test-3-%%HOME%%-$${HOME}'
+ },
+ "file variable with expand_file_vars: true": {
+ value: 'key-$FILEVAR1-$TEST1',
+ result: 'key-file value 1-test-3'
+ },
+ "file variable with expand_file_vars: false": {
+ value: 'key-$FILEVAR1-$TEST1',
+ result: 'key-$FILEVAR1-test-3',
+ expand_file_vars: false
}
}
end
with_them do
- subject { collection.expand_value(value, keep_undefined: keep_undefined) }
+ let(:options) { { keep_undefined: keep_undefined, expand_file_vars: expand_file_vars }.compact }
+
+ subject(:result) { collection.expand_value(value, **options) }
it 'matches expected expansion' do
is_expected.to eq(result)
diff --git a/spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb b/spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb
index a471b00592c..2651e46ba53 100644
--- a/spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb
+++ b/spec/migrations/20220725150127_update_jira_tracker_data_deployment_type_based_on_url_spec.rb
@@ -34,8 +34,8 @@ RSpec.describe UpdateJiraTrackerDataDeploymentTypeBasedOnUrl, :migration do
# rubocop:disable Layout/LineLength
# rubocop:disable RSpec/ScatteredLet
- let!(:tracker_data_cloud) { JiraTrackerData.create!(id: 1, service_id: service_jira_cloud.id, url: "https://test-domain.atlassian.net", deployment_type: 0) }
- let!(:tracker_data_server) { JiraTrackerData.create!(id: 2, service_id: service_jira_server.id, url: "http://totally-not-jira-server.company.org", deployment_type: 0) }
+ let!(:tracker_data_cloud) { JiraTrackerData.create!(id: 1, integration_id: service_jira_cloud.id, url: "https://test-domain.atlassian.net", deployment_type: 0) }
+ let!(:tracker_data_server) { JiraTrackerData.create!(id: 2, integration_id: service_jira_server.id, url: "http://totally-not-jira-server.company.org", deployment_type: 0) }
# rubocop:enable Layout/LineLength
# rubocop:enable RSpec/ScatteredLet
diff --git a/spec/models/data_list_spec.rb b/spec/models/data_list_spec.rb
index 67db2730a78..6e01f4786ba 100644
--- a/spec/models/data_list_spec.rb
+++ b/spec/models/data_list_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe DataList do
let(:zentao_integration) { create(:zentao_integration) }
let(:cases) do
[
- [jira_integration, 'Integrations::JiraTrackerData', 'service_id'],
+ [jira_integration, 'Integrations::JiraTrackerData', 'integration_id'],
[zentao_integration, 'Integrations::ZentaoTrackerData', 'integration_id']
]
end
diff --git a/spec/models/integration_spec.rb b/spec/models/integration_spec.rb
index 66e2eaee181..647b1d5de7f 100644
--- a/spec/models/integration_spec.rb
+++ b/spec/models/integration_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Integration do
it { is_expected.to belong_to(:project).inverse_of(:integrations) }
it { is_expected.to belong_to(:group).inverse_of(:integrations) }
it { is_expected.to have_one(:issue_tracker_data).autosave(true).inverse_of(:integration).with_foreign_key(:service_id).class_name('Integrations::IssueTrackerData') }
- it { is_expected.to have_one(:jira_tracker_data).autosave(true).inverse_of(:integration).with_foreign_key(:service_id).class_name('Integrations::JiraTrackerData') }
+ it { is_expected.to have_one(:jira_tracker_data).autosave(true).inverse_of(:integration).with_foreign_key(:integration_id).class_name('Integrations::JiraTrackerData') }
end
describe 'validations' do
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 2525b167d08..afb321c0777 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -873,6 +873,12 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#ci_allow_fork_pipelines_to_run_in_parent_project?' do
+ it_behaves_like 'a ci_cd_settings predicate method', prefix: 'ci_' do
+ let(:delegated_method) { :allow_fork_pipelines_to_run_in_parent_project? }
+ end
+ end
+
describe '#ci_job_token_scope_enabled?' do
it_behaves_like 'a ci_cd_settings predicate method', prefix: 'ci_' do
let(:delegated_method) { :job_token_scope_enabled? }
diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb
index ace65307321..fe2d8f0f670 100644
--- a/spec/presenters/ci/build_runner_presenter_spec.rb
+++ b/spec/presenters/ci/build_runner_presenter_spec.rb
@@ -309,25 +309,64 @@ RSpec.describe Ci::BuildRunnerPresenter do
end
describe '#runner_variables' do
- subject { presenter.runner_variables }
+ subject(:runner_variables) { presenter.runner_variables }
let_it_be(:project) { create(:project, :repository) }
- shared_examples 'returns an array with the expected variables' do
- it 'returns an array' do
- is_expected.to be_an_instance_of(Array)
+ let(:sha) { project.repository.commit.sha }
+ let(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+
+ it 'returns an array' do
+ is_expected.to be_an_instance_of(Array)
+ end
+
+ it 'returns the expected variables' do
+ is_expected.to eq(presenter.variables.to_runner_variables)
+ end
+
+ context 'when there are variables to expand' do
+ before_all do
+ create(:ci_variable, project: project,
+ key: 'regular_var',
+ value: 'value 1')
+ create(:ci_variable, project: project,
+ key: 'file_var',
+ value: 'value 2',
+ variable_type: :file)
+ create(:ci_variable, project: project,
+ key: 'var_with_variables',
+ value: 'value 3 and $regular_var and $file_var and $undefined_var')
end
- it 'returns the expected variables' do
- is_expected.to eq(presenter.variables.to_runner_variables)
+ it 'returns variables with expanded' do
+ expect(runner_variables).to include(
+ { key: 'regular_var', value: 'value 1',
+ public: false, masked: false },
+ { key: 'file_var', value: 'value 2',
+ public: false, masked: false, file: true },
+ { key: 'var_with_variables', value: 'value 3 and value 1 and $file_var and $undefined_var',
+ public: false, masked: false }
+ )
end
- end
- let(:sha) { project.repository.commit.sha }
- let(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }
- let(:build) { create(:ci_build, pipeline: pipeline) }
+ context 'when the FF ci_stop_expanding_file_vars_for_runners is disabled' do
+ before do
+ stub_feature_flags(ci_stop_expanding_file_vars_for_runners: false)
+ end
- it_behaves_like 'returns an array with the expected variables'
+ it 'returns variables with expanded' do
+ expect(runner_variables).to include(
+ { key: 'regular_var', value: 'value 1',
+ public: false, masked: false },
+ { key: 'file_var', value: 'value 2',
+ public: false, masked: false, file: true },
+ { key: 'var_with_variables', value: 'value 3 and value 1 and value 2 and $undefined_var',
+ public: false, masked: false }
+ )
+ end
+ end
+ end
end
describe '#runner_variables subset' do
diff --git a/spec/requests/api/members_spec.rb b/spec/requests/api/members_spec.rb
index ec6d7d4bfb4..9df9c75b020 100644
--- a/spec/requests/api/members_spec.rb
+++ b/spec/requests/api/members_spec.rb
@@ -231,6 +231,33 @@ RSpec.describe API::Members do
end
end
end
+
+ context 'with ancestral membership' do
+ shared_examples 'response with correct access levels' do
+ it do
+ get api("/#{source_type.pluralize}/#{source.id}/members/#{all ? 'all/' : ''}#{developer.id}", developer)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['access_level']).to eq(Member::MAINTAINER)
+ end
+ end
+
+ before do
+ source.add_maintainer(developer)
+ end
+
+ include_examples 'response with correct access levels'
+
+ context 'having email invite' do
+ before do
+ Member
+ .find_by(source: group, user: developer)
+ .update!(invite_email: 'email@email.com')
+ end
+
+ include_examples 'response with correct access levels'
+ end
+ end
end
end
diff --git a/spec/requests/api/project_attributes.yml b/spec/requests/api/project_attributes.yml
index af93c1b6de2..670035187cb 100644
--- a/spec/requests/api/project_attributes.yml
+++ b/spec/requests/api/project_attributes.yml
@@ -101,6 +101,7 @@ ci_cd_settings:
job_token_scope_enabled: ci_job_token_scope_enabled
separated_caches: ci_separated_caches
opt_in_jwt: ci_opt_in_jwt
+ allow_fork_pipelines_to_run_in_parent_project: ci_allow_fork_pipelines_to_run_in_parent_project
build_import_state: # import_state
unexposed_attributes:
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index d3c65e11ed7..94688833d88 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -2427,6 +2427,7 @@ RSpec.describe API::Projects do
expect(json_response['only_allow_merge_if_all_discussions_are_resolved']).to eq(project.only_allow_merge_if_all_discussions_are_resolved)
expect(json_response['ci_default_git_depth']).to eq(project.ci_default_git_depth)
expect(json_response['ci_forward_deployment_enabled']).to eq(project.ci_forward_deployment_enabled)
+ expect(json_response['ci_allow_fork_pipelines_to_run_in_parent_project']).to eq(project.ci_allow_fork_pipelines_to_run_in_parent_project)
expect(json_response['ci_separated_caches']).to eq(project.ci_separated_caches)
expect(json_response['merge_method']).to eq(project.merge_method.to_s)
expect(json_response['squash_option']).to eq(project.squash_option.to_s)
@@ -3692,6 +3693,7 @@ RSpec.describe API::Projects do
merge_method: 'ff',
ci_default_git_depth: 20,
ci_forward_deployment_enabled: false,
+ ci_allow_fork_pipelines_to_run_in_parent_project: false,
ci_separated_caches: false,
description: 'new description' }
diff --git a/spec/services/bulk_update_integration_service_spec.rb b/spec/services/bulk_update_integration_service_spec.rb
index e3e38aacaa2..7c5bd1db565 100644
--- a/spec/services/bulk_update_integration_service_spec.rb
+++ b/spec/services/bulk_update_integration_service_spec.rb
@@ -71,7 +71,7 @@ RSpec.describe BulkUpdateIntegrationService do
context 'with integration with data fields' do
let(:excluded_attributes) do
- %w[id service_id created_at updated_at encrypted_properties encrypted_properties_iv]
+ %w[id integration_id created_at updated_at encrypted_properties encrypted_properties_iv]
end
it 'updates the data fields from the integration', :aggregate_failures do
diff --git a/spec/services/merge_requests/create_pipeline_service_spec.rb b/spec/services/merge_requests/create_pipeline_service_spec.rb
index 03a37ea59a3..c443d758a77 100644
--- a/spec/services/merge_requests/create_pipeline_service_spec.rb
+++ b/spec/services/merge_requests/create_pipeline_service_spec.rb
@@ -74,6 +74,16 @@ RSpec.describe MergeRequests::CreatePipelineService do
expect(response.payload.project).to eq(project)
end
+ context 'when the feature is disabled in CI/CD settings' do
+ before do
+ project.update!(ci_allow_fork_pipelines_to_run_in_parent_project: false)
+ end
+
+ it 'creates a pipeline in the source project' do
+ expect(response.payload.project).to eq(source_project)
+ end
+ end
+
context 'when source branch is protected' do
context 'when actor does not have permission to update the protected branch in target project' do
let!(:protected_branch) { create(:protected_branch, name: '*', project: project) }