diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-15 21:08:10 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-15 21:08:10 +0300 |
commit | 7f08e6916d8259a8ed1549cb54460f0b746d9d8b (patch) | |
tree | 40853e994af97de42bd68076bd0bffa6be5c2814 /spec | |
parent | cb7f766437db0c483adf3c128e35c64237a2ef53 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
29 files changed, 426 insertions, 238 deletions
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb index f21e00b5522..cf8f02ea17e 100644 --- a/spec/controllers/projects_controller_spec.rb +++ b/spec/controllers/projects_controller_spec.rb @@ -1602,59 +1602,6 @@ RSpec.describe ProjectsController do end end - describe 'GET resolve' do - shared_examples 'resolvable endpoint' do - it 'redirects to the project page' do - get :resolve, params: { id: project.id } - - expect(response).to have_gitlab_http_status(:found) - expect(response).to redirect_to(project_path(project)) - end - end - - context 'with an authenticated user' do - before do - sign_in(user) - end - - context 'when user has access to the project' do - before do - project.add_developer(user) - end - - it_behaves_like 'resolvable endpoint' - end - - context 'when user has no access to the project' do - it 'gives 404 for existing project' do - get :resolve, params: { id: project.id } - - expect(response).to have_gitlab_http_status(:not_found) - end - end - - it 'gives 404 for non-existing project' do - get :resolve, params: { id: '0' } - - expect(response).to have_gitlab_http_status(:not_found) - end - end - - context 'non authenticated user' do - context 'with a public project' do - let(:project) { public_project } - - it_behaves_like 'resolvable endpoint' - end - - it 'gives 404 for private project' do - get :resolve, params: { id: project.id } - - expect(response).to have_gitlab_http_status(:not_found) - end - end - end - it 'updates Service Desk attributes' do project.add_maintainer(user) sign_in(user) diff --git a/spec/frontend/environments/new_environments_app_spec.js b/spec/frontend/environments/new_environments_app_spec.js index d903e1e2d56..cb9535da363 100644 --- a/spec/frontend/environments/new_environments_app_spec.js +++ b/spec/frontend/environments/new_environments_app_spec.js @@ -70,8 +70,9 @@ describe('~/environments/components/new_environments_app.vue', () => { previousPage: 1, __typename: 'LocalPageInfo', }, + location = '?scope=available&page=2', }) => { - setWindowLocation('?scope=available&page=2'); + setWindowLocation(location); environmentAppMock.mockReturnValue(environmentsApp); environmentFolderMock.mockReturnValue(folder); paginationMock.mockReturnValue(pageInfo); @@ -98,6 +99,21 @@ describe('~/environments/components/new_environments_app.vue', () => { wrapper.destroy(); }); + it('should request available environments if the scope is invalid', async () => { + await createWrapperWithMocked({ + environmentsApp: resolvedEnvironmentsApp, + folder: resolvedFolder, + location: '?scope=bad&page=2', + }); + + expect(environmentAppMock).toHaveBeenCalledWith( + expect.anything(), + expect.objectContaining({ scope: 'available', page: 2 }), + expect.anything(), + expect.anything(), + ); + }); + it('should show all the folders that are fetched', async () => { await createWrapperWithMocked({ environmentsApp: resolvedEnvironmentsApp, diff --git a/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js b/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js index ee2fbbe57b9..b692eea4aa5 100644 --- a/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js +++ b/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js @@ -1,12 +1,14 @@ -import { GlFilteredSearchToken } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import Vue from 'vue'; import Vuex from 'vuex'; import setWindowLocation from 'helpers/set_window_location_helper'; import { redirectTo } from '~/lib/utils/url_utility'; import MembersFilteredSearchBar from '~/members/components/filter_sort/members_filtered_search_bar.vue'; -import { MEMBER_TYPES } from '~/members/constants'; -import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants'; +import { + MEMBER_TYPES, + FILTERED_SEARCH_TOKEN_TWO_FACTOR, + FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS, +} from '~/members/constants'; import FilteredSearchBar from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue'; jest.mock('~/lib/utils/url_utility', () => { @@ -32,7 +34,7 @@ describe('MembersFilteredSearchBar', () => { state: { filteredSearchBar: { show: true, - tokens: ['two_factor'], + tokens: [FILTERED_SEARCH_TOKEN_TWO_FACTOR.type], searchParam: 'search', placeholder: 'Filter members', recentSearchesStorageKey: 'group_members', @@ -70,21 +72,7 @@ describe('MembersFilteredSearchBar', () => { it('includes tokens set in `filteredSearchBar.tokens`', () => { createComponent(); - expect(findFilteredSearchBar().props('tokens')).toEqual([ - { - type: 'two_factor', - icon: 'lock', - title: '2FA', - token: GlFilteredSearchToken, - unique: true, - operators: OPERATOR_IS_ONLY, - options: [ - { value: 'enabled', title: 'Enabled' }, - { value: 'disabled', title: 'Disabled' }, - ], - requiredPermissions: 'canManageMembers', - }, - ]); + expect(findFilteredSearchBar().props('tokens')).toEqual([FILTERED_SEARCH_TOKEN_TWO_FACTOR]); }); describe('when `canManageMembers` is false', () => { @@ -93,7 +81,10 @@ describe('MembersFilteredSearchBar', () => { state: { filteredSearchBar: { show: true, - tokens: ['two_factor', 'with_inherited_permissions'], + tokens: [ + FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, + FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS.type, + ], searchParam: 'search', placeholder: 'Filter members', recentSearchesStorageKey: 'group_members', @@ -105,18 +96,7 @@ describe('MembersFilteredSearchBar', () => { }); expect(findFilteredSearchBar().props('tokens')).toEqual([ - { - type: 'with_inherited_permissions', - icon: 'group', - title: 'Membership', - token: GlFilteredSearchToken, - unique: true, - operators: OPERATOR_IS_ONLY, - options: [ - { value: 'exclude', title: 'Direct' }, - { value: 'only', title: 'Inherited' }, - ], - }, + FILTERED_SEARCH_TOKEN_WITH_INHERITED_PERMISSIONS, ]); }); }); @@ -134,7 +114,7 @@ describe('MembersFilteredSearchBar', () => { expect(findFilteredSearchBar().props('initialFilterValue')).toEqual([ { - type: 'two_factor', + type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=', @@ -183,7 +163,7 @@ describe('MembersFilteredSearchBar', () => { createComponent(); findFilteredSearchBar().vm.$emit('onFilter', [ - { type: 'two_factor', value: { data: 'enabled', operator: '=' } }, + { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } }, ]); expect(redirectTo).toHaveBeenCalledWith('https://localhost/?two_factor=enabled'); @@ -193,7 +173,7 @@ describe('MembersFilteredSearchBar', () => { createComponent(); findFilteredSearchBar().vm.$emit('onFilter', [ - { type: 'two_factor', value: { data: 'enabled', operator: '=' } }, + { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } }, { type: 'filtered-search-term', value: { data: 'foobar' } }, ]); @@ -206,7 +186,7 @@ describe('MembersFilteredSearchBar', () => { createComponent(); findFilteredSearchBar().vm.$emit('onFilter', [ - { type: 'two_factor', value: { data: 'enabled', operator: '=' } }, + { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } }, { type: 'filtered-search-term', value: { data: 'foo bar baz' } }, ]); @@ -221,7 +201,7 @@ describe('MembersFilteredSearchBar', () => { createComponent(); findFilteredSearchBar().vm.$emit('onFilter', [ - { type: 'two_factor', value: { data: 'enabled', operator: '=' } }, + { type: FILTERED_SEARCH_TOKEN_TWO_FACTOR.type, value: { data: 'enabled', operator: '=' } }, { type: 'filtered-search-term', value: { data: 'foobar' } }, ]); diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap index 86ccaa43786..62cf769cffd 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap +++ b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap @@ -137,9 +137,7 @@ exports[`Learn GitLab renders correctly 1`] = ` class="gl-link" data-testid="uncompleted-learn-gitlab-link" data-track-action="click_link" - data-track-experiment="change_continuous_onboarding_link_urls" data-track-label="Set up CI/CD" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" href="http://example.com/" target="_self" > @@ -157,9 +155,7 @@ exports[`Learn GitLab renders correctly 1`] = ` class="gl-link" data-testid="uncompleted-learn-gitlab-link" data-track-action="click_link" - data-track-experiment="change_continuous_onboarding_link_urls" data-track-label="Start a free Ultimate trial" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" href="http://example.com/" target="_self" > @@ -177,9 +173,7 @@ exports[`Learn GitLab renders correctly 1`] = ` class="gl-link" data-testid="uncompleted-learn-gitlab-link" data-track-action="click_link" - data-track-experiment="change_continuous_onboarding_link_urls" data-track-label="Add code owners" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" href="http://example.com/" target="_self" > @@ -204,9 +198,7 @@ exports[`Learn GitLab renders correctly 1`] = ` class="gl-link" data-testid="uncompleted-learn-gitlab-link" data-track-action="click_link" - data-track-experiment="change_continuous_onboarding_link_urls" data-track-label="Add merge request approval" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" href="http://example.com/" target="_self" > @@ -267,9 +259,7 @@ exports[`Learn GitLab renders correctly 1`] = ` class="gl-link" data-testid="uncompleted-learn-gitlab-link" data-track-action="click_link" - data-track-experiment="change_continuous_onboarding_link_urls" data-track-label="Create an issue" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" href="http://example.com/" target="_self" > @@ -287,9 +277,7 @@ exports[`Learn GitLab renders correctly 1`] = ` class="gl-link" data-testid="uncompleted-learn-gitlab-link" data-track-action="click_link" - data-track-experiment="change_continuous_onboarding_link_urls" data-track-label="Submit a merge request" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" href="http://example.com/" target="_self" > @@ -343,9 +331,7 @@ exports[`Learn GitLab renders correctly 1`] = ` class="gl-link" data-testid="uncompleted-learn-gitlab-link" data-track-action="click_link" - data-track-experiment="change_continuous_onboarding_link_urls" data-track-label="Run a Security scan using CI/CD" - data-track-property="Growth::Conversion::Experiment::LearnGitLab" href="https://docs.gitlab.com/ee/foobar/" rel="noopener noreferrer" target="_blank" diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js index 3b113f4dcd7..e21371123e8 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js +++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js @@ -12,8 +12,9 @@ const defaultProps = { completed: false, }; -const docLinkProps = { +const openInNewTabProps = { url: 'https://docs.gitlab.com/ee/user/application_security/security_dashboard/', + openInNewTab: true, }; describe('Learn GitLab Section Link', () => { @@ -59,9 +60,9 @@ describe('Learn GitLab Section Link', () => { expect(wrapper.find('[data-testid="trial-only"]').exists()).toBe(true); }); - describe('doc links', () => { + describe('links marked with openInNewTab', () => { beforeEach(() => { - createWrapper('securityScanEnabled', docLinkProps); + createWrapper('securityScanEnabled', openInNewTabProps); }); it('renders links with blank target', () => { @@ -78,7 +79,6 @@ describe('Learn GitLab Section Link', () => { expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_link', { label: 'Run a Security scan using CI/CD', - property: 'Growth::Conversion::Experiment::LearnGitLab', }); unmockTracking(); diff --git a/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js b/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js index b21965e8f48..5dc64097d81 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js +++ b/spec/frontend/pages/projects/learn_gitlab/components/mock_data.js @@ -38,6 +38,7 @@ export const testActions = { url: 'https://docs.gitlab.com/ee/foobar/', completed: false, svg: 'http://example.com/images/illustration.svg', + openInNewTab: true, }, issueCreated: { url: 'http://example.com/', diff --git a/spec/graphql/resolvers/base_resolver_spec.rb b/spec/graphql/resolvers/base_resolver_spec.rb index d77a0b6242e..39b00c14161 100644 --- a/spec/graphql/resolvers/base_resolver_spec.rb +++ b/spec/graphql/resolvers/base_resolver_spec.rb @@ -239,16 +239,16 @@ RSpec.describe Resolvers::BaseResolver do it 'increases complexity based on arguments' do field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 1) - expect(field.to_graphql.complexity.call({}, { sort: 'foo' }, 1)).to eq 3 - expect(field.to_graphql.complexity.call({}, { search: 'foo' }, 1)).to eq 7 + expect(field.complexity.call({}, { sort: 'foo' }, 1)).to eq 3 + expect(field.complexity.call({}, { search: 'foo' }, 1)).to eq 7 end it 'does not increase complexity when filtering by iids' do field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 100) - expect(field.to_graphql.complexity.call({}, { sort: 'foo' }, 1)).to eq 6 - expect(field.to_graphql.complexity.call({}, { sort: 'foo', iid: 1 }, 1)).to eq 3 - expect(field.to_graphql.complexity.call({}, { sort: 'foo', iids: [1, 2, 3] }, 1)).to eq 3 + expect(field.complexity.call({}, { sort: 'foo' }, 1)).to eq 6 + expect(field.complexity.call({}, { sort: 'foo', iid: 1 }, 1)).to eq 3 + expect(field.complexity.call({}, { sort: 'foo', iids: [1, 2, 3] }, 1)).to eq 3 end end diff --git a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb index 38f5a644985..4c4aa4f53e1 100644 --- a/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb +++ b/spec/graphql/resolvers/concerns/resolves_pipelines_spec.rb @@ -106,9 +106,9 @@ RSpec.describe ResolvesPipelines do it 'increases field complexity based on arguments' do field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: false, max_page_size: 1) - expect(field.to_graphql.complexity.call({}, {}, 1)).to eq 2 - expect(field.to_graphql.complexity.call({}, { sha: 'foo' }, 1)).to eq 4 - expect(field.to_graphql.complexity.call({}, { sha: 'ref' }, 1)).to eq 4 + expect(field.complexity.call({}, {}, 1)).to eq 2 + expect(field.complexity.call({}, { sha: 'foo' }, 1)).to eq 4 + expect(field.complexity.call({}, { sha: 'ref' }, 1)).to eq 4 end def resolve_pipelines(args = {}, context = { current_user: current_user }) diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb index dc717b113c1..326c105a358 100644 --- a/spec/graphql/resolvers/issues_resolver_spec.rb +++ b/spec/graphql/resolvers/issues_resolver_spec.rb @@ -618,8 +618,8 @@ RSpec.describe Resolvers::IssuesResolver do it 'increases field complexity based on arguments' do field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 100) - expect(field.to_graphql.complexity.call({}, {}, 1)).to eq 4 - expect(field.to_graphql.complexity.call({}, { labelName: 'foo' }, 1)).to eq 8 + expect(field.complexity.call({}, {}, 1)).to eq 4 + expect(field.complexity.call({}, { labelName: 'foo' }, 1)).to eq 8 end def create_issue_with_severity(project, severity:) diff --git a/spec/graphql/resolvers/namespace_projects_resolver_spec.rb b/spec/graphql/resolvers/namespace_projects_resolver_spec.rb index b1f50a4a4a5..eb4d0ab6f37 100644 --- a/spec/graphql/resolvers/namespace_projects_resolver_spec.rb +++ b/spec/graphql/resolvers/namespace_projects_resolver_spec.rb @@ -147,8 +147,8 @@ RSpec.describe Resolvers::NamespaceProjectsResolver do it 'has an high complexity regardless of arguments' do field = Types::BaseField.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: described_class, null: false, max_page_size: 100) - expect(field.to_graphql.complexity.call({}, {}, 1)).to eq 24 - expect(field.to_graphql.complexity.call({}, { include_subgroups: true }, 1)).to eq 24 + expect(field.complexity.call({}, {}, 1)).to eq 24 + expect(field.complexity.call({}, { include_subgroups: true }, 1)).to eq 24 end def resolve_projects(args = { include_subgroups: false, sort: nil, search: nil, ids: nil }, context = { current_user: current_user }) diff --git a/spec/graphql/resolvers/project_resolver_spec.rb b/spec/graphql/resolvers/project_resolver_spec.rb index cd3fdc788e6..dec9d4701e1 100644 --- a/spec/graphql/resolvers/project_resolver_spec.rb +++ b/spec/graphql/resolvers/project_resolver_spec.rb @@ -36,8 +36,8 @@ RSpec.describe Resolvers::ProjectResolver do field1 = Types::BaseField.new(name: 'test', type: GraphQL::Types::String, resolver_class: described_class, null: false, max_page_size: 100) field2 = Types::BaseField.new(name: 'test', type: GraphQL::Types::String, resolver_class: described_class, null: false, max_page_size: 1) - expect(field1.to_graphql.complexity.call({}, {}, 1)).to eq 2 - expect(field2.to_graphql.complexity.call({}, {}, 1)).to eq 2 + expect(field1.complexity.call({}, {}, 1)).to eq 2 + expect(field2.complexity.call({}, {}, 1)).to eq 2 end def resolve_project(full_path) diff --git a/spec/graphql/types/base_enum_spec.rb b/spec/graphql/types/base_enum_spec.rb index 64524f3ffcd..65a345052c7 100644 --- a/spec/graphql/types/base_enum_spec.rb +++ b/spec/graphql/types/base_enum_spec.rb @@ -136,7 +136,7 @@ RSpec.describe Types::BaseEnum do value 'TEST_VALUE', **args end - enum.to_graphql.values['TEST_VALUE'] + enum.values['TEST_VALUE'] end end end diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb index 31d07f701e8..9d02f061435 100644 --- a/spec/graphql/types/base_field_spec.rb +++ b/spec/graphql/types/base_field_spec.rb @@ -19,7 +19,7 @@ RSpec.describe Types::BaseField do it 'defaults to 1' do field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true) - expect(field.to_graphql.complexity).to eq 1 + expect(field.complexity).to eq 1 end describe '#base_complexity' do @@ -43,7 +43,7 @@ RSpec.describe Types::BaseField do it 'has specified value' do field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12) - expect(field.to_graphql.complexity).to eq 12 + expect(field.complexity).to eq 12 end context 'when field has a resolver' do @@ -51,7 +51,7 @@ RSpec.describe Types::BaseField do let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: resolver, complexity: 2, max_page_size: 100, null: true) } it 'uses this complexity' do - expect(field.to_graphql.complexity).to eq 2 + expect(field.complexity).to eq 2 end end @@ -59,13 +59,13 @@ RSpec.describe Types::BaseField do let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: resolver, max_page_size: 100, null: true) } it 'sets complexity depending on arguments for resolvers' do - expect(field.to_graphql.complexity.call({}, {}, 2)).to eq 4 - expect(field.to_graphql.complexity.call({}, { first: 50 }, 2)).to eq 3 + expect(field.complexity.call({}, {}, 2)).to eq 4 + expect(field.complexity.call({}, { first: 50 }, 2)).to eq 3 end it 'sets complexity depending on number load limits for resolvers' do - expect(field.to_graphql.complexity.call({}, { first: 1 }, 2)).to eq 2 - expect(field.to_graphql.complexity.call({}, { first: 1, foo: true }, 2)).to eq 4 + expect(field.complexity.call({}, { first: 1 }, 2)).to eq 2 + expect(field.complexity.call({}, { first: 1, foo: true }, 2)).to eq 4 end end @@ -73,8 +73,8 @@ RSpec.describe Types::BaseField do it 'sets complexity as normal' do field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, max_page_size: 100, null: true) - expect(field.to_graphql.complexity.call({}, {}, 2)).to eq 2 - expect(field.to_graphql.complexity.call({}, { first: 50 }, 2)).to eq 2 + expect(field.complexity.call({}, {}, 2)).to eq 2 + expect(field.complexity.call({}, { first: 50 }, 2)).to eq 2 end end end @@ -84,9 +84,9 @@ RSpec.describe Types::BaseField do it 'adds 1 if true' do with_gitaly_field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: true, calls_gitaly: true) without_gitaly_field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: true) - base_result = without_gitaly_field.to_graphql.complexity.call({}, {}, 2) + base_result = without_gitaly_field.complexity.call({}, {}, 2) - expect(with_gitaly_field.to_graphql.complexity.call({}, {}, 2)).to eq base_result + 1 + expect(with_gitaly_field.complexity.call({}, {}, 2)).to eq base_result + 1 end end @@ -94,7 +94,7 @@ RSpec.describe Types::BaseField do it 'adds 1 if true' do field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, calls_gitaly: true) - expect(field.to_graphql.complexity).to eq 2 + expect(field.complexity).to eq 2 end end @@ -108,14 +108,14 @@ RSpec.describe Types::BaseField do it 'has complexity set to that constant' do field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12) - expect(field.to_graphql.complexity).to eq 12 + expect(field.complexity).to eq 12 end it 'does not raise an error even with Gitaly calls' do allow(Gitlab::GitalyClient).to receive(:get_request_count).and_return([0, 1]) field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12) - expect(field.to_graphql.complexity).to eq 12 + expect(field.complexity).to eq 12 end end end diff --git a/spec/graphql/types/global_id_type_spec.rb b/spec/graphql/types/global_id_type_spec.rb index f9391efdf08..8df92c818fc 100644 --- a/spec/graphql/types/global_id_type_spec.rb +++ b/spec/graphql/types/global_id_type_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Types::GlobalIDType do let(:gid) { project.to_global_id } it 'is has the correct name' do - expect(described_class.to_graphql.name).to eq('GlobalID') + expect(described_class.graphql_name).to eq('GlobalID') end describe '.coerce_result' do @@ -63,7 +63,7 @@ RSpec.describe Types::GlobalIDType do let(:type) { ::Types::GlobalIDType[::Project] } it 'is has the correct name' do - expect(type.to_graphql.name).to eq('ProjectID') + expect(type.graphql_name).to eq('ProjectID') end context 'the GID is appropriate' do @@ -126,7 +126,7 @@ RSpec.describe Types::GlobalIDType do let(:deprecating_gid) { Gitlab::GlobalId.build(model_name: 'Issue', id: issue.id) } it 'appends the description with a deprecation notice for the old Global ID' do - expect(type.to_graphql.description).to include('The older format `"gid://gitlab/OldIssue/1"` was deprecated in 10.0') + expect(type.description).to include('The older format `"gid://gitlab/OldIssue/1"` was deprecated in 10.0') end describe 'coercing input against the type (parsing the Global ID string when supplied as an argument)' do @@ -242,7 +242,7 @@ RSpec.describe Types::GlobalIDType do let(:type) { ::Types::GlobalIDType[::Ci::Build] } it 'is has a valid GraphQL identifier for a name' do - expect(type.to_graphql.name).to eq('CiBuildID') + expect(type.graphql_name).to eq('CiBuildID') end end diff --git a/spec/helpers/learn_gitlab_helper_spec.rb b/spec/helpers/learn_gitlab_helper_spec.rb index ffc2bb31b8f..9fce7495b5a 100644 --- a/spec/helpers/learn_gitlab_helper_spec.rb +++ b/spec/helpers/learn_gitlab_helper_spec.rb @@ -97,29 +97,29 @@ RSpec.describe LearnGitlabHelper do trial_started: a_hash_including( url: a_string_matching(%r{/learn_gitlab/-/issues/2\z}) ), - issue_created: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues/4\z}) - ), - git_write: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues/6\z}) - ), pipeline_created: a_hash_including( url: a_string_matching(%r{/learn_gitlab/-/issues/7\z}) ), - user_added: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues/8\z}) - ), - merge_request_created: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues/9\z}) - ), code_owners_enabled: a_hash_including( url: a_string_matching(%r{/learn_gitlab/-/issues/10\z}) ), required_mr_approvals_enabled: a_hash_including( url: a_string_matching(%r{/learn_gitlab/-/issues/11\z}) ), + issue_created: a_hash_including( + url: a_string_matching(%r{/learn_gitlab/-/issues\z}) + ), + git_write: a_hash_including( + url: a_string_matching(%r{/learn_gitlab\z}) + ), + user_added: a_hash_including( + url: a_string_matching(%r{/learn_gitlab/-/project_members\z}) + ), + merge_request_created: a_hash_including( + url: a_string_matching(%r{/learn_gitlab/-/merge_requests\z}) + ), security_scan_enabled: a_hash_including( - url: a_string_matching(%r{docs\.gitlab\.com/ee/user/application_security/security_dashboard/#gitlab-security-dashboard-security-center-and-vulnerability-reports\z}) + url: a_string_matching(%r{/learn_gitlab/-/security/configuration\z}) ) }) end @@ -137,58 +137,5 @@ RSpec.describe LearnGitlabHelper do security_scan_enabled: a_hash_including(completed: false) }) end - - context 'when in the new action URLs experiment' do - before do - stub_experiments(change_continuous_onboarding_link_urls: :candidate) - end - - it_behaves_like 'has all data' - - it 'sets mostly new paths' do - expect(onboarding_actions_data).to match({ - trial_started: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues/2\z}) - ), - issue_created: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues\z}) - ), - git_write: a_hash_including( - url: a_string_matching(%r{/learn_gitlab\z}) - ), - pipeline_created: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/pipelines\z}) - ), - user_added: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/project_members\z}) - ), - merge_request_created: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/merge_requests\z}) - ), - code_owners_enabled: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues/10\z}) - ), - required_mr_approvals_enabled: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/issues/11\z}) - ), - security_scan_enabled: a_hash_including( - url: a_string_matching(%r{/learn_gitlab/-/security/configuration\z}) - ) - }) - end - - it 'calls experiment with expected context & options' do - allow(helper).to receive(:current_user).and_return(user) - - expect(helper).to receive(:experiment).with( - :change_continuous_onboarding_link_urls, - namespace: namespace, - actor: user, - sticky_to: namespace - ) - - learn_gitlab_data - end - end end end diff --git a/spec/lib/backup/manager_spec.rb b/spec/lib/backup/manager_spec.rb index bf1a039f354..9cf78a11bc7 100644 --- a/spec/lib/backup/manager_spec.rb +++ b/spec/lib/backup/manager_spec.rb @@ -71,7 +71,7 @@ RSpec.describe Backup::Manager do end before do - allow(YAML).to receive(:load_file).with('backup_information.yml') + allow(YAML).to receive(:load_file).with(File.join(Gitlab.config.backup.path, 'backup_information.yml')) .and_return(backup_information) end @@ -171,7 +171,8 @@ RSpec.describe Backup::Manager do before do allow(ActiveRecord::Base.connection).to receive(:reconnect!) allow(Kernel).to receive(:system).and_return(true) - allow(YAML).to receive(:load_file).and_return(backup_information) + allow(YAML).to receive(:load_file).with(File.join(Gitlab.config.backup.path, 'backup_information.yml')) + .and_return(backup_information) allow(subject).to receive(:backup_information).and_return(backup_information) allow(task1).to receive(:dump).with(File.join(Gitlab.config.backup.path, 'task1.tar.gz')) @@ -571,7 +572,8 @@ RSpec.describe Backup::Manager do allow(task1).to receive(:restore).with(File.join(Gitlab.config.backup.path, 'task1.tar.gz')) allow(task2).to receive(:restore).with(File.join(Gitlab.config.backup.path, 'task2.tar.gz')) - allow(YAML).to receive(:load_file).and_return(backup_information) + allow(YAML).to receive(:load_file).with(File.join(Gitlab.config.backup.path, 'backup_information.yml')) + .and_return(backup_information) allow(Rake::Task['gitlab:shell:setup']).to receive(:invoke) allow(Rake::Task['cache:clear']).to receive(:invoke) end diff --git a/spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb b/spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb new file mode 100644 index 00000000000..588f53150ff --- /dev/null +++ b/spec/lib/gitlab/ci/config/entry/reports/coverage_report_spec.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +require 'fast_spec_helper' + +RSpec.describe Gitlab::Ci::Config::Entry::Reports::CoverageReport do + let(:entry) { described_class.new(config) } + + describe 'validations' do + context 'when it is valid' do + let(:config) { { coverage_format: 'cobertura', path: 'cobertura-coverage.xml' } } + + it { expect(entry).to be_valid } + + it { expect(entry.value).to eq(config) } + end + + context 'with unsupported coverage format' do + let(:config) { { coverage_format: 'jacoco', path: 'jacoco.xml' } } + + it { expect(entry).not_to be_valid } + + it { expect(entry.errors).to include /format must be one of supported formats/ } + end + + context 'without coverage format' do + let(:config) { { path: 'cobertura-coverage.xml' } } + + it { expect(entry).not_to be_valid } + + it { expect(entry.errors).to include /format can't be blank/ } + end + + context 'without path' do + let(:config) { { coverage_format: 'cobertura' } } + + it { expect(entry).not_to be_valid } + + it { expect(entry.errors).to include /path can't be blank/ } + end + + context 'with invalid path' do + let(:config) { { coverage_format: 'cobertura', path: 123 } } + + it { expect(entry).not_to be_valid } + + it { expect(entry.errors).to include /path should be a string/ } + end + + context 'with unknown keys' do + let(:config) { { coverage_format: 'cobertura', path: 'cobertura-coverage.xml', foo: :bar } } + + it { expect(entry).not_to be_valid } + + it { expect(entry.errors).to include /contains unknown keys/ } + end + end +end diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb index 12b8960eb32..061d8f34c8d 100644 --- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb +++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb @@ -6,12 +6,8 @@ RSpec.describe Gitlab::Ci::Config::Entry::Reports do let(:entry) { described_class.new(config) } describe 'validates ALLOWED_KEYS' do - let(:artifact_file_types) { Ci::JobArtifact.file_types } - - described_class::ALLOWED_KEYS.each do |keyword, _| - it "expects #{keyword} to be an artifact file_type" do - expect(artifact_file_types).to include(keyword) - end + it "expects ALLOWED_KEYS to be an artifact file_type or coverage_report" do + expect(Ci::JobArtifact.file_types.keys.map(&:to_sym) + [:coverage_report]).to include(*described_class::ALLOWED_KEYS) end end @@ -68,6 +64,45 @@ RSpec.describe Gitlab::Ci::Config::Entry::Reports do it_behaves_like 'a valid entry', params[:keyword], params[:file] end end + + context 'when coverage_report is specified' do + let(:coverage_format) { :cobertura } + let(:filename) { 'cobertura-coverage.xml' } + let(:coverage_report) { { path: filename, coverage_format: coverage_format } } + let(:config) { { coverage_report: coverage_report } } + + it 'is valid' do + expect(entry).to be_valid + end + + it 'returns artifacts configuration' do + expect(entry.value).to eq(config) + end + + context 'and another report is specified' do + let(:config) { { coverage_report: coverage_report, dast: 'gl-dast-report.json' } } + + it 'is valid' do + expect(entry).to be_valid + end + + it 'returns artifacts configuration' do + expect(entry.value).to eq({ coverage_report: coverage_report, dast: ['gl-dast-report.json'] }) + end + end + + context 'and a direct coverage report format is specified' do + let(:config) { { coverage_report: coverage_report, cobertura: 'cobertura-coverage.xml' } } + + it 'is not valid' do + expect(entry).not_to be_valid + end + + it 'reports error' do + expect(entry.errors).to include /please use only one the following keys: coverage_report, cobertura/ + end + end + end end context 'when entry value is not correct' do diff --git a/spec/lib/gitlab/config/entry/validators_spec.rb b/spec/lib/gitlab/config/entry/validators_spec.rb new file mode 100644 index 00000000000..cbc09aac586 --- /dev/null +++ b/spec/lib/gitlab/config/entry/validators_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Config::Entry::Validators do + let(:klass) do + Class.new do + include ActiveModel::Validations + include Gitlab::Config::Entry::Validators + end + end + + let(:instance) { klass.new } + + describe described_class::MutuallyExclusiveKeysValidator do + using RSpec::Parameterized::TableSyntax + + before do + klass.instance_eval do + validates :config, mutually_exclusive_keys: [:foo, :bar] + end + + allow(instance).to receive(:config).and_return(config) + end + + where(:context, :config, :valid_result) do + 'with mutually exclusive keys' | { foo: 1, bar: 2 } | false + 'without mutually exclusive keys' | { foo: 1 } | true + 'without mutually exclusive keys' | { bar: 1 } | true + 'with other keys' | { foo: 1, baz: 2 } | true + end + + with_them do + it 'validates the instance' do + expect(instance.valid?).to be(valid_result) + + unless valid_result + expect(instance.errors.messages_for(:config)).to include /please use only one the following keys: foo, bar/ + end + end + end + end +end diff --git a/spec/lib/gitlab/graphql/markdown_field_spec.rb b/spec/lib/gitlab/graphql/markdown_field_spec.rb index c2253811e91..ed3f19d8cf2 100644 --- a/spec/lib/gitlab/graphql/markdown_field_spec.rb +++ b/spec/lib/gitlab/graphql/markdown_field_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Gitlab::Graphql::MarkdownField do expect(field.name).to eq('testHtml') expect(field.description).to eq('The GitLab Flavored Markdown rendering of `hello`') expect(field.type).to eq(GraphQL::Types::String) - expect(field.to_graphql.complexity).to eq(5) + expect(field.complexity).to eq(5) end context 'developer warnings' do @@ -43,7 +43,7 @@ RSpec.describe Gitlab::Graphql::MarkdownField do let(:field) { type_class.fields['noteHtml'] } it 'renders markdown from the same property as the field name without the `_html` suffix' do - expect(field.to_graphql.resolve(type_instance, {}, context)).to eq(expected_markdown) + expect(field.resolve(type_instance, {}, context)).to eq(expected_markdown) end context 'when a `method` argument is passed' do @@ -51,7 +51,7 @@ RSpec.describe Gitlab::Graphql::MarkdownField do let(:field) { type_class.fields['testHtml'] } it 'renders markdown from a specific property' do - expect(field.to_graphql.resolve(type_instance, {}, context)).to eq(expected_markdown) + expect(field.resolve(type_instance, {}, context)).to eq(expected_markdown) end end @@ -62,21 +62,21 @@ RSpec.describe Gitlab::Graphql::MarkdownField do let(:note) { build(:note, note: "Referencing #{issue.to_reference(full: true)}") } it 'renders markdown correctly' do - expect(field.to_graphql.resolve(type_instance, {}, context)).to include(issue_path(issue)) + expect(field.resolve(type_instance, {}, context)).to include(issue_path(issue)) end context 'when the issue is not publicly accessible' do let_it_be(:project) { create(:project, :private) } it 'hides the references from users that are not allowed to see the reference' do - expect(field.to_graphql.resolve(type_instance, {}, context)).not_to include(issue_path(issue)) + expect(field.resolve(type_instance, {}, context)).not_to include(issue_path(issue)) end it 'shows the reference to users that are allowed to see it' do context = GraphQL::Query::Context.new(query: query, values: { current_user: project.first_owner }, object: nil) type_instance = type_class.authorized_new(note, context) - expect(field.to_graphql.resolve(type_instance, {}, context)).to include(issue_path(issue)) + expect(field.resolve(type_instance, {}, context)).to include(issue_path(issue)) end end end diff --git a/spec/lib/gitlab/graphql/mount_mutation_spec.rb b/spec/lib/gitlab/graphql/mount_mutation_spec.rb index fe25e923506..09fd9eac714 100644 --- a/spec/lib/gitlab/graphql/mount_mutation_spec.rb +++ b/spec/lib/gitlab/graphql/mount_mutation_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Gitlab::Graphql::MountMutation do f.mount_mutation(mutation) end - mutation_type.get_field('testMutation').to_graphql + mutation_type.get_field('testMutation') end it 'mounts a mutation' do @@ -31,7 +31,7 @@ RSpec.describe Gitlab::Graphql::MountMutation do f.mount_aliased_mutation('MyAlias', mutation) end - mutation_type.get_field('myAlias').to_graphql + mutation_type.get_field('myAlias') end it 'mounts a mutation' do @@ -43,11 +43,11 @@ RSpec.describe Gitlab::Graphql::MountMutation do end it 'has a correct type' do - expect(field.type.name).to eq('MyAliasPayload') + expect(field.type.to_type_signature).to eq('MyAliasPayload') end it 'has a correct input argument' do - expect(field.arguments['input'].type.unwrap.name).to eq('MyAliasInput') + expect(field.arguments['input'].type.unwrap.to_type_signature).to eq('MyAliasInput') end end diff --git a/spec/lib/learn_gitlab/onboarding_spec.rb b/spec/lib/learn_gitlab/onboarding_spec.rb index 6b4be65f3b2..8c7284ed7f5 100644 --- a/spec/lib/learn_gitlab/onboarding_spec.rb +++ b/spec/lib/learn_gitlab/onboarding_spec.rb @@ -9,7 +9,7 @@ RSpec.describe LearnGitlab::Onboarding do let(:namespace) { build(:namespace) } let_it_be(:tracked_action_columns) do - tracked_actions = described_class::ACTION_ISSUE_IDS.keys + described_class::ACTION_DOC_URLS.keys + tracked_actions = described_class::ACTION_ISSUE_IDS.keys + described_class::ACTION_PATHS tracked_actions.map { |key| OnboardingProgress.column_name(key) } end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index d58b91e675a..f3c4f5a4f6f 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -8026,14 +8026,6 @@ RSpec.describe Project, factory_default: :keep do let(:object) { build(:project) } it_behaves_like 'blocks unsafe serialization' - - context 'when feature flag block_project_serialization is disabled' do - before do - stub_feature_flags(block_project_serialization: false) - end - - it_behaves_like 'allows unsafe serialization' - end end private diff --git a/spec/requests/api/graphql/group/issues_spec.rb b/spec/requests/api/graphql/group/issues_spec.rb index 332bf242e9c..26338f46611 100644 --- a/spec/requests/api/graphql/group/issues_spec.rb +++ b/spec/requests/api/graphql/group/issues_spec.rb @@ -44,6 +44,31 @@ RSpec.describe 'getting an issue list for a group' do end end + context 'when there are archived projects' do + let_it_be(:archived_project) { create(:project, :archived, group: group1) } + let_it_be(:archived_issue) { create(:issue, project: archived_project) } + + before_all do + group1.add_developer(current_user) + end + + it 'excludes issues from archived projects by default' do + post_graphql(query, current_user: current_user) + + expect(issues_ids).to contain_exactly(issue1_gid, issue2_gid) + end + + context 'when include_archived is true' do + let(:issue_filter_params) { { include_archived: true } } + + it 'includes issues from archived projects' do + post_graphql(query, current_user: current_user) + + expect(issues_ids).to contain_exactly(issue1_gid, issue2_gid, archived_issue.to_global_id.to_s) + end + end + end + context 'when there is a confidential issue' do let_it_be(:confidential_issue1) { create(:issue, :confidential, project: project1) } let_it_be(:confidential_issue2) { create(:issue, :confidential, project: project2) } diff --git a/spec/requests/api/graphql/group/merge_requests_spec.rb b/spec/requests/api/graphql/group/merge_requests_spec.rb index e9a5e558b1d..c0faff11c8d 100644 --- a/spec/requests/api/graphql/group/merge_requests_spec.rb +++ b/spec/requests/api/graphql/group/merge_requests_spec.rb @@ -16,6 +16,9 @@ RSpec.describe 'Query.group.mergeRequests' do let_it_be(:project_x) { create(:project, :repository) } let_it_be(:user) { create(:user, developer_projects: [project_x]) } + let_it_be(:archived_project) { create(:project, :archived, :repository, group: group) } + let_it_be(:archived_mr) { create(:merge_request, source_project: archived_project) } + let_it_be(:mr_attrs) do { target_branch: 'master' } end @@ -119,4 +122,22 @@ RSpec.describe 'Query.group.mergeRequests' do expect(mrs_data).to match_array(expected_mrs(mrs_a + mrs_b + mrs_c)) end end + + describe 'passing include_archived: true' do + let(:query) do + <<~GQL + query($path: ID!) { + group(fullPath: $path) { + mergeRequests(includeArchived: true) { nodes { id } } + } + } + GQL + end + + it 'can find all merge requests in the group, including from archived projects' do + post_graphql(query, current_user: user, variables: { path: group.full_path }) + + expect(mrs_data).to match_array(expected_mrs(mrs_a + mrs_b + [archived_mr])) + end + end end diff --git a/spec/requests/projects/redirect_controller_spec.rb b/spec/requests/projects/redirect_controller_spec.rb new file mode 100644 index 00000000000..3bbca3ca32b --- /dev/null +++ b/spec/requests/projects/redirect_controller_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe "Projects::RedirectController requests" do + using RSpec::Parameterized::TableSyntax + + let_it_be(:private_project) { create(:project, :private) } + let_it_be(:public_project) { create(:project, :public) } + let_it_be(:user) { create(:user) } + + before_all do + private_project.add_developer(user) + end + + describe 'GET redirect_from_id' do + where(:authenticated, :project, :is_found) do + true | ref(:private_project) | true + false | ref(:private_project) | false + true | ref(:public_project) | true + false | ref(:public_project) | true + true | build(:project, id: 0) | false + end + + with_them do + before do + sign_in(user) if authenticated + + get "/projects/#{project.id}" + end + + if params[:is_found] + it 'redirects to the project page' do + expect(response).to have_gitlab_http_status(:found) + expect(response).to redirect_to(project_path(project)) + end + else + it 'gives 404' do + expect(response).to have_gitlab_http_status(:not_found) + end + end + end + end + + # This is a regression test for https://gitlab.com/gitlab-org/gitlab/-/issues/351058 + context 'with sourcegraph enabled' do + let_it_be(:sourcegraph_url) { 'https://sourcegraph.test' } + + before do + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url).and_return(sourcegraph_url) + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_enabled).and_return(true) + + sign_in(user) + end + + context 'with projects/:id route' do + subject { get "/projects/#{public_project.id}" } + + it 'redirects successfully' do + subject + + expect(response).to redirect_to(project_path(public_project)) + end + end + end +end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 3a935ddbdd8..65772895826 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -70,9 +70,11 @@ RSpec.describe 'project routing' do route_to('projects#preview_markdown', namespace_id: 'gitlab', id: 'gitlabhq') ) end + end - it 'to #resolve' do - expect(get('/projects/1')).to route_to('projects#resolve', id: '1') + describe Projects::RedirectController, 'routing' do + it 'to #redirect_from_id' do + expect(get('/projects/1')).to route_to('projects/redirect#redirect_from_id', id: '1') end end diff --git a/spec/services/ci/create_pipeline_service/artifacts_spec.rb b/spec/services/ci/create_pipeline_service/artifacts_spec.rb new file mode 100644 index 00000000000..1ec30d68666 --- /dev/null +++ b/spec/services/ci/create_pipeline_service/artifacts_spec.rb @@ -0,0 +1,67 @@ +# frozen_string_literal: true +require 'spec_helper' + +RSpec.describe Ci::CreatePipelineService do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:user) { project.first_owner } + + let(:ref) { 'refs/heads/master' } + let(:source) { :push } + + let(:service) { described_class.new(project, user, { ref: ref }) } + let(:pipeline) { service.execute(source).payload } + + describe 'artifacts:' do + before do + stub_ci_pipeline_yaml_file(config) + allow_next_instance_of(Ci::BuildScheduleWorker) do |instance| + allow(instance).to receive(:perform).and_return(true) + end + end + + describe 'reports:' do + context 'with valid config' do + let(:config) do + <<~YAML + test-job: + script: "echo 'hello world' > cobertura.xml" + artifacts: + reports: + coverage_report: + coverage_format: 'cobertura' + path: 'cobertura.xml' + + dependency-scanning-job: + script: "echo 'hello world' > gl-dependency-scanning-report.json" + artifacts: + reports: + dependency_scanning: 'gl-dependency-scanning-report.json' + YAML + end + + it 'creates pipeline with builds' do + expect(pipeline).to be_persisted + expect(pipeline).not_to have_yaml_errors + expect(pipeline.builds.pluck(:name)).to contain_exactly('test-job', 'dependency-scanning-job') + end + end + + context 'with invalid config' do + let(:config) do + <<~YAML + test-job: + script: "echo 'hello world' > cobertura.xml" + artifacts: + reports: + foo: 'bar' + YAML + end + + it 'creates pipeline with yaml errors' do + expect(pipeline).to be_persisted + expect(pipeline).to have_yaml_errors + end + end + end + end +end diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb index b895e9ba67e..399b2b4be2d 100644 --- a/spec/services/notification_service_spec.rb +++ b/spec/services/notification_service_spec.rb @@ -1072,6 +1072,7 @@ RSpec.describe NotificationService, :mailer do end before do + project.reload add_user_subscriptions(issue) reset_delivered_emails! update_custom_notification(:new_issue, @u_guest_custom, resource: project) |