diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-26 15:09:15 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-03-26 15:09:15 +0300 |
commit | c0dd450008c1cee260905e54bbed202891158697 (patch) | |
tree | 0b034d5e4568303b77302325fc8656bb040b90b4 /spec | |
parent | 26bba9525deb5e9d05fd29cf5b286e7a65d1c791 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
12 files changed, 160 insertions, 54 deletions
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb index 6e4082d1391..bc60cdd2f8e 100644 --- a/spec/features/projects/settings/registry_settings_spec.rb +++ b/spec/features/projects/settings/registry_settings_spec.rb @@ -39,7 +39,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p select('7 days', from: 'Remove tags older than:') fill_in('Remove tags matching:', with: '.*-production') - submit_button = find('.btn.gl-button.btn-success') + submit_button = find('[data-testid="save-button"') expect(submit_button).not_to be_disabled submit_button.click end @@ -53,7 +53,7 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p within '#js-registry-policies' do fill_in('Remove tags matching:', with: '*-production') - submit_button = find('.btn.gl-button.btn-success') + submit_button = find('[data-testid="save-button"') expect(submit_button).not_to be_disabled submit_button.click end diff --git a/spec/features/projects/sub_group_issuables_spec.rb b/spec/features/projects/sub_group_issuables_spec.rb index 8c1d88276df..d7614201740 100644 --- a/spec/features/projects/sub_group_issuables_spec.rb +++ b/spec/features/projects/sub_group_issuables_spec.rb @@ -16,18 +16,18 @@ RSpec.describe 'Subgroup Issuables', :js do it 'shows the full subgroup title when issues index page is empty' do visit project_issues_path(project) - expect_to_have_full_subgroup_title + expect_to_have_breadcrumb_links end it 'shows the full subgroup title when merge requests index page is empty' do visit project_merge_requests_path(project) - expect_to_have_full_subgroup_title + expect_to_have_breadcrumb_links end - def expect_to_have_full_subgroup_title - title = find('.breadcrumbs-links') + def expect_to_have_breadcrumb_links + links = find('[data-testid="breadcrumb-links"]') - expect(title).to have_content 'group subgroup project' + expect(links).to have_content 'group subgroup project' end end diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js index f875e3bdb07..5523fe13cd6 100644 --- a/spec/frontend/api_spec.js +++ b/spec/frontend/api_spec.js @@ -264,18 +264,18 @@ describe('Api', () => { it('fetches group labels', (done) => { const options = { params: { search: 'foo' } }; const expectedGroup = 'gitlab-org'; - const expectedUrl = `${dummyUrlRoot}/groups/${expectedGroup}/-/labels`; + const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/groups/${expectedGroup}/labels`; mock.onGet(expectedUrl).reply(httpStatus.OK, [ { id: 1, - title: 'Foo Label', + name: 'Foo Label', }, ]); Api.groupLabels(expectedGroup, options) .then((res) => { expect(res.length).toBe(1); - expect(res[0].title).toBe('Foo Label'); + expect(res[0].name).toBe('Foo Label'); }) .then(done) .catch(done.fail); @@ -593,7 +593,7 @@ describe('Api', () => { }); describe('newLabel', () => { - it('creates a new label', (done) => { + it('creates a new project label', (done) => { const namespace = 'some namespace'; const project = 'some project'; const labelData = { some: 'data' }; @@ -618,26 +618,23 @@ describe('Api', () => { }); }); - it('creates a group label', (done) => { + it('creates a new group label', (done) => { const namespace = 'group/subgroup'; - const labelData = { some: 'data' }; + const labelData = { name: 'Foo', color: '#000000' }; const expectedUrl = Api.buildUrl(Api.groupLabelsPath).replace(':namespace_path', namespace); - const expectedData = { - label: labelData, - }; mock.onPost(expectedUrl).reply((config) => { - expect(config.data).toBe(JSON.stringify(expectedData)); + expect(config.data).toBe(JSON.stringify({ color: labelData.color })); return [ httpStatus.OK, { - name: 'test', + ...labelData, }, ]; }); Api.newLabel(namespace, undefined, labelData, (response) => { - expect(response.name).toBe('test'); + expect(response.name).toBe('Foo'); done(); }); }); diff --git a/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap b/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap index 5eb86d4f9cb..3cb48d7632f 100644 --- a/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap +++ b/spec/frontend/design_management/components/toolbar/__snapshots__/design_navigation_spec.js.snap @@ -13,6 +13,7 @@ exports[`Design management pagination component renders navigation buttons 1`] = class="gl-mx-5" > <gl-button-stub + aria-label="Go to previous design" buttontextclasses="" category="primary" class="js-previous-design" @@ -24,6 +25,7 @@ exports[`Design management pagination component renders navigation buttons 1`] = /> <gl-button-stub + aria-label="Go to next design" buttontextclasses="" category="primary" class="js-next-design" diff --git a/spec/frontend/registry/settings/components/settings_form_spec.js b/spec/frontend/registry/settings/components/settings_form_spec.js index 7527910ad59..ad94da6ca66 100644 --- a/spec/frontend/registry/settings/components/settings_form_spec.js +++ b/spec/frontend/registry/settings/components/settings_form_spec.js @@ -77,33 +77,47 @@ describe('Settings Form', () => { }); }; - const mountComponentWithApollo = ({ provide = defaultProvidedValues, resolver } = {}) => { + const mountComponentWithApollo = ({ + provide = defaultProvidedValues, + mutationResolver, + queryPayload = expirationPolicyPayload(), + } = {}) => { localVue.use(VueApollo); const requestHandlers = [ - [updateContainerExpirationPolicyMutation, resolver], - [expirationPolicyQuery, jest.fn().mockResolvedValue(expirationPolicyPayload())], + [updateContainerExpirationPolicyMutation, mutationResolver], + [expirationPolicyQuery, jest.fn().mockResolvedValue(queryPayload)], ]; fakeApollo = createMockApollo(requestHandlers); + // This component does not do the query directly, but we need a proper cache to update fakeApollo.defaultClient.cache.writeQuery({ query: expirationPolicyQuery, variables: { projectPath: provide.projectPath, }, - ...expirationPolicyPayload(), + ...queryPayload, }); + // we keep in sync what prop we pass to the component with the cache + const { + data: { + project: { containerExpirationPolicy: value }, + }, + } = queryPayload; + mountComponent({ provide, + props: { + ...defaultProps, + value, + }, config: { localVue, apolloProvider: fakeApollo, }, }); - - return requestHandlers.map((resolvers) => resolvers[1]); }; beforeEach(() => { @@ -253,19 +267,44 @@ describe('Settings Form', () => { expect(findSaveButton().attributes('type')).toBe('submit'); }); - it('dispatches the correct apollo mutation', async () => { - const [expirationPolicyMutationResolver] = mountComponentWithApollo({ - resolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()), + it('dispatches the correct apollo mutation', () => { + const mutationResolver = jest.fn().mockResolvedValue(expirationPolicyMutationPayload()); + mountComponentWithApollo({ + mutationResolver, }); findForm().trigger('submit'); - await expirationPolicyMutationResolver(); - expect(expirationPolicyMutationResolver).toHaveBeenCalled(); + + expect(mutationResolver).toHaveBeenCalled(); + }); + + it('saves the default values when a value is missing did not change the default options', async () => { + const mutationResolver = jest.fn().mockResolvedValue(expirationPolicyMutationPayload()); + mountComponentWithApollo({ + mutationResolver, + queryPayload: expirationPolicyPayload({ keepN: null, cadence: null, olderThan: null }), + }); + + await waitForPromises(); + + findForm().trigger('submit'); + + expect(mutationResolver).toHaveBeenCalledWith({ + input: { + cadence: 'EVERY_DAY', + enabled: true, + keepN: 'TEN_TAGS', + nameRegex: 'asdasdssssdfdf', + nameRegexKeep: 'sss', + olderThan: 'NINETY_DAYS', + projectPath: 'path', + }, + }); }); it('tracks the submit event', () => { mountComponentWithApollo({ - resolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()), + mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()), }); findForm().trigger('submit'); @@ -274,12 +313,12 @@ describe('Settings Form', () => { }); it('show a success toast when submit succeed', async () => { - const handlers = mountComponentWithApollo({ - resolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()), + mountComponentWithApollo({ + mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()), }); findForm().trigger('submit'); - await Promise.all(handlers); + await waitForPromises(); await wrapper.vm.$nextTick(); expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE, { @@ -290,14 +329,14 @@ describe('Settings Form', () => { describe('when submit fails', () => { describe('user recoverable errors', () => { it('when there is an error is shown in a toast', async () => { - const handlers = mountComponentWithApollo({ - resolver: jest + mountComponentWithApollo({ + mutationResolver: jest .fn() .mockResolvedValue(expirationPolicyMutationPayload({ errors: ['foo'] })), }); findForm().trigger('submit'); - await Promise.all(handlers); + await waitForPromises(); await wrapper.vm.$nextTick(); expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('foo', { @@ -308,13 +347,12 @@ describe('Settings Form', () => { describe('global errors', () => { it('shows an error', async () => { - const handlers = mountComponentWithApollo({ - resolver: jest.fn().mockRejectedValue(expirationPolicyMutationPayload()), + mountComponentWithApollo({ + mutationResolver: jest.fn().mockRejectedValue(expirationPolicyMutationPayload()), }); findForm().trigger('submit'); - await Promise.all(handlers); - await wrapper.vm.$nextTick(); + await waitForPromises(); await wrapper.vm.$nextTick(); expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE, { diff --git a/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap b/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap index 1bf757ea312..bab928318ce 100644 --- a/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap +++ b/spec/frontend/vue_shared/components/__snapshots__/clone_dropdown_spec.js.snap @@ -40,6 +40,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = ` tag="div" > <gl-button-stub + aria-label="Copy URL" buttontextclasses="" category="primary" class="d-inline-flex" @@ -82,6 +83,7 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = ` tag="div" > <gl-button-stub + aria-label="Copy URL" buttontextclasses="" category="primary" class="d-inline-flex" diff --git a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js index 7676ce10ce0..8528c062426 100644 --- a/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js +++ b/spec/frontend/vue_shared/components/filtered_search_bar/tokens/label_token_spec.js @@ -118,6 +118,22 @@ describe('LabelToken', () => { wrapper = createComponent(); }); + describe('getLabelName', () => { + it('returns value of `name` or `title` property present in provided label param', () => { + let mockLabel = { + title: 'foo', + }; + + expect(wrapper.vm.getLabelName(mockLabel)).toBe(mockLabel.title); + + mockLabel = { + name: 'foo', + }; + + expect(wrapper.vm.getLabelName(mockLabel)).toBe(mockLabel.name); + }); + }); + describe('fetchLabelBySearchTerm', () => { it('calls `config.fetchLabels` with provided searchTerm param', () => { jest.spyOn(wrapper.vm.config, 'fetchLabels'); diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb index 2063de691a3..351486ae801 100644 --- a/spec/models/namespace_spec.rb +++ b/spec/models/namespace_spec.rb @@ -1415,6 +1415,12 @@ RSpec.describe Namespace do end end + describe '#paid?' do + it 'returns false for a root namespace with a free plan' do + expect(namespace.paid?).to eq(false) + end + end + describe '#shared_runners_setting' do using RSpec::Parameterized::TableSyntax diff --git a/spec/requests/api/v3/github_spec.rb b/spec/requests/api/v3/github_spec.rb index 197c6cbb0eb..521187f0a81 100644 --- a/spec/requests/api/v3/github_spec.rb +++ b/spec/requests/api/v3/github_spec.rb @@ -3,10 +3,10 @@ require 'spec_helper' RSpec.describe API::V3::Github do - let(:user) { create(:user) } - let(:unauthorized_user) { create(:user) } - let(:admin) { create(:user, :admin) } - let(:project) { create(:project, :repository, creator: user) } + let_it_be(:user) { create(:user) } + let_it_be(:unauthorized_user) { create(:user) } + let_it_be(:admin) { create(:user, :admin) } + let_it_be(:project) { create(:project, :repository, creator: user) } before do project.add_maintainer(user) @@ -210,14 +210,14 @@ RSpec.describe API::V3::Github do end describe 'repo pulls' do - let(:project2) { create(:project, :repository, creator: user) } - let(:assignee) { create(:user) } - let(:assignee2) { create(:user) } - let!(:merge_request) do + let_it_be(:project2) { create(:project, :repository, creator: user) } + let_it_be(:assignee) { create(:user) } + let_it_be(:assignee2) { create(:user) } + let_it_be(:merge_request) do create(:merge_request, source_project: project, target_project: project, author: user, assignees: [assignee]) end - let!(:merge_request_2) do + let_it_be(:merge_request_2) do create(:merge_request, source_project: project2, target_project: project2, author: user, assignees: [assignee, assignee2]) end @@ -225,26 +225,54 @@ RSpec.describe API::V3::Github do project2.add_maintainer(user) end + def perform_request + jira_get v3_api(route, user) + end + describe 'GET /-/jira/pulls' do + let(:route) { '/repos/-/jira/pulls' } + it 'returns an array of merge requests with github format' do - jira_get v3_api('/repos/-/jira/pulls', user) + perform_request expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an(Array) expect(json_response.size).to eq(2) expect(response).to match_response_schema('entities/github/pull_requests') end + + it 'returns multiple merge requests without N + 1' do + perform_request + + control_count = ActiveRecord::QueryRecorder.new { perform_request }.count + + create(:merge_request, source_project: project, source_branch: 'fix') + + expect { perform_request }.not_to exceed_query_limit(control_count) + end end describe 'GET /repos/:namespace/:project/pulls' do + let(:route) { "/repos/#{project.namespace.path}/#{project.path}/pulls" } + it 'returns an array of merge requests for the proper project in github format' do - jira_get v3_api("/repos/#{project.namespace.path}/#{project.path}/pulls", user) + perform_request expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an(Array) expect(json_response.size).to eq(1) expect(response).to match_response_schema('entities/github/pull_requests') end + + it 'returns multiple merge requests without N + 1' do + perform_request + + control_count = ActiveRecord::QueryRecorder.new { perform_request }.count + + create(:merge_request, source_project: project, source_branch: 'fix') + + expect { perform_request }.not_to exceed_query_limit(control_count) + end end describe 'GET /repos/:namespace/:project/pulls/:id' do diff --git a/spec/serializers/pipeline_serializer_spec.rb b/spec/serializers/pipeline_serializer_spec.rb index bcaaa61eb04..7784f8f53ff 100644 --- a/spec/serializers/pipeline_serializer_spec.rb +++ b/spec/serializers/pipeline_serializer_spec.rb @@ -202,7 +202,7 @@ RSpec.describe PipelineSerializer do # Existing numbers are high and require performance optimization # Ongoing issue: # https://gitlab.com/gitlab-org/gitlab/-/issues/225156 - expected_queries = Gitlab.ee? ? 85 : 76 + expected_queries = Gitlab.ee? ? 82 : 76 expect(recorded.count).to be_within(2).of(expected_queries) expect(recorded.cached_count).to eq(0) diff --git a/spec/support/shared_examples/features/error_tracking_shared_example.rb b/spec/support/shared_examples/features/error_tracking_shared_example.rb index 92fc54ce0b0..1bdc5355408 100644 --- a/spec/support/shared_examples/features/error_tracking_shared_example.rb +++ b/spec/support/shared_examples/features/error_tracking_shared_example.rb @@ -2,7 +2,7 @@ RSpec.shared_examples 'error tracking index page' do it 'renders the error index page', quarantine: { issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/217810' } do - within('div.js-title-container') do + within('[data-testid="breadcrumb-links"]') do expect(page).to have_content(project.namespace.name) expect(page).to have_content(project.name) end diff --git a/spec/views/groups/settings/_remove.html.haml_spec.rb b/spec/views/groups/settings/_remove.html.haml_spec.rb new file mode 100644 index 00000000000..07fe900bc2d --- /dev/null +++ b/spec/views/groups/settings/_remove.html.haml_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'groups/settings/_remove.html.haml' do + describe 'render' do + it 'enables the Remove group button for a group' do + group = build(:group) + + render 'groups/settings/remove', group: group + + expect(rendered).to have_selector '[data-testid="remove-group-button"]' + expect(rendered).not_to have_selector '[data-testid="remove-group-button"].disabled' + expect(rendered).not_to have_selector '[data-testid="group-has-linked-subscription-alert"]' + end + end +end |