Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
74015980b5
commit
a4aa229f76
14 changed files with 244 additions and 94 deletions
26
CHANGELOG.md
26
CHANGELOG.md
|
@ -954,6 +954,17 @@ entry.
|
|||
- [Cleanup bigint conversion for ci_builds](gitlab-org/gitlab@176992aa2b2e76b22637a07d5bafbd6541324a7d) ([merge request](gitlab-org/gitlab!70351))
|
||||
- [Drop support for data-track-event](gitlab-org/gitlab@ac6027fbef6adf41643412a84945fda6f15c9666) ([merge request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70234))
|
||||
|
||||
## 14.3.5 (2021-11-26)
|
||||
|
||||
### Fixed (6 changes)
|
||||
|
||||
- [Allow SSO callbacks through maintenance mode](gitlab-org/gitlab@f9b250145ac3db5fb01698839f1b5f3d9d349945) ([merge request](gitlab-org/gitlab!75145)) **GitLab Enterprise Edition**
|
||||
- [Geo - Fix no repo error message for group-level wikis](gitlab-org/gitlab@5560e012bd6f35431d4d1cea389807ca475c2ce5) ([merge request](gitlab-org/gitlab!75145)) **GitLab Enterprise Edition**
|
||||
- [Prevent Git operations from checking replication lag on non-Geo-secondary sites](gitlab-org/gitlab@35344d81d5e07bfb4db997be6c4f99f39a16562e) ([merge request](gitlab-org/gitlab!75145)) **GitLab Enterprise Edition**
|
||||
- [Fix error 500 loading branch with UTF-8 characters with performance bar](gitlab-org/gitlab@08b47c2870cc338021bb3f945ac6736e46abf376) ([merge request](gitlab-org/gitlab!75145))
|
||||
- [Remove defaultAuthors from MR Analytics and VSA](gitlab-org/gitlab@be95c921623056d31e2cbc0a7bc96de3aa66ca65) ([merge request](gitlab-org/gitlab!75145))
|
||||
- [Allow SSO callbacks through maintenance mode](gitlab-org/gitlab@0727751512d41537356b295d6b889e05c6a07480) ([merge request](gitlab-org/gitlab!74706)) **GitLab Enterprise Edition**
|
||||
|
||||
## 14.3.4 (2021-10-28)
|
||||
|
||||
### Security (13 changes)
|
||||
|
@ -1520,6 +1531,21 @@ entry.
|
|||
- [Remove the FF ci_reset_bridge_with_subsequent_jobs](gitlab-org/gitlab@a4a75095b9b0250d0b1bdadea90c8a4cd24449b2) ([merge request](gitlab-org/gitlab!68295))
|
||||
- [Removes ci_same_stage_job_needs ff](gitlab-org/gitlab@5e509cf7aa90041a541b19dda563120a359f0bf9) ([merge request](gitlab-org/gitlab!68041))
|
||||
|
||||
## 14.2.7 (2021-11-26)
|
||||
|
||||
### Fixed (3 changes)
|
||||
|
||||
- [Prevent Git operations from checking replication lag on non-Geo-secondary sites](gitlab-org/gitlab@84734dab92e0bf9e304ee7bf1579346cc48d26c3) ([merge request](gitlab-org/gitlab!75119)) **GitLab Enterprise Edition**
|
||||
- [Remove defaultAuthors from MR Analytics and VSA](gitlab-org/gitlab@1a15d4d1be939a9e38124827f563ed9ec2612a75) ([merge request](gitlab-org/gitlab!75119))
|
||||
- [Let non-members set confidential flag when creating an issue in public project](gitlab-org/gitlab@d093cc62e6263629b36a449c9464d9b8644d4d74) ([merge request](gitlab-org/gitlab!75119))
|
||||
|
||||
### Changed (4 changes)
|
||||
|
||||
- [Geo: Alternate redownload and normal design sync attempts](gitlab-org/gitlab@d401e3ec94e6dba9ea76a9682893352f28d446cb) ([merge request](gitlab-org/gitlab!75119)) **GitLab Enterprise Edition**
|
||||
- [Geo: Alternate redownload and normal SSF sync attempts](gitlab-org/gitlab@00eeff14a9bfeabe9107fc38ce9d7d2eee06384b) ([merge request](gitlab-org/gitlab!75119)) **GitLab Enterprise Edition**
|
||||
- [Geo: Alternate redownload and normal project syncs](gitlab-org/gitlab@fac9bb8c11db13d34b311f4ebd18f84fa7a575d3) ([merge request](gitlab-org/gitlab!75119)) **GitLab Enterprise Edition**
|
||||
- [Geo: Reduce frequency of redownload attempts](gitlab-org/gitlab@d18381e4788a8652d3e36cec5d4bce343c48209c) ([merge request](gitlab-org/gitlab!75119)) **GitLab Enterprise Edition**
|
||||
|
||||
## 14.2.6 (2021-10-28)
|
||||
|
||||
### Security (13 changes)
|
||||
|
|
|
@ -87,7 +87,7 @@ export default {
|
|||
try {
|
||||
const {
|
||||
data: {
|
||||
commitCreate: { errors },
|
||||
commitCreate: { errors, commitPipelinePath: pipelineEtag },
|
||||
},
|
||||
} = await this.$apollo.mutate({
|
||||
mutation: commitCIFile,
|
||||
|
@ -101,14 +101,12 @@ export default {
|
|||
content: this.ciFileContent,
|
||||
lastCommitId: this.commitSha,
|
||||
},
|
||||
update(_, { data }) {
|
||||
const pipelineEtag = data?.commitCreate?.commit?.commitPipelinePath;
|
||||
if (pipelineEtag) {
|
||||
this.$apollo.mutate({ mutation: updatePipelineEtag, variables: pipelineEtag });
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
if (pipelineEtag) {
|
||||
this.updatePipelineEtag(pipelineEtag);
|
||||
}
|
||||
|
||||
if (errors?.length) {
|
||||
this.$emit('showError', { type: COMMIT_FAILURE, reasons: errors });
|
||||
} else if (openMergeRequest) {
|
||||
|
@ -139,6 +137,9 @@ export default {
|
|||
variables: { lastCommitBranch },
|
||||
});
|
||||
},
|
||||
updatePipelineEtag(pipelineEtag) {
|
||||
this.$apollo.mutate({ mutation: updatePipelineEtag, variables: { pipelineEtag } });
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -19,7 +19,9 @@ mutation commitCIFile(
|
|||
]
|
||||
}
|
||||
) {
|
||||
__typename
|
||||
commit {
|
||||
__typename
|
||||
sha
|
||||
}
|
||||
commitPipelinePath
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { GlTab, GlTabs, GlSprintf, GlLink, GlAlert } from '@gitlab/ui';
|
||||
import { __, s__ } from '~/locale';
|
||||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import LocalStorageSync from '~/vue_shared/components/local_storage_sync.vue';
|
||||
import UserCalloutDismisser from '~/vue_shared/components/user_callout_dismisser.vue';
|
||||
import AutoDevOpsAlert from './auto_dev_ops_alert.vue';
|
||||
|
@ -23,6 +24,8 @@ export const i18n = {
|
|||
any subsequent feature branch you create will include the scan.`,
|
||||
),
|
||||
securityConfiguration: __('Security Configuration'),
|
||||
vulnerabilityManagement: s__('SecurityConfiguration|Vulnerability Management'),
|
||||
securityTraining: s__('SecurityConfiguration|Security training'),
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -41,6 +44,7 @@ export default {
|
|||
UpgradeBanner,
|
||||
UserCalloutDismisser,
|
||||
},
|
||||
mixins: [glFeatureFlagsMixin()],
|
||||
inject: ['projectPath'],
|
||||
props: {
|
||||
augmentedSecurityFeatures: {
|
||||
|
@ -231,6 +235,13 @@ export default {
|
|||
</template>
|
||||
</section-layout>
|
||||
</gl-tab>
|
||||
<gl-tab
|
||||
v-if="glFeatures.secureVulnerabilityTraining"
|
||||
data-testid="vulnerability-management-tab"
|
||||
:title="$options.i18n.vulnerabilityManagement"
|
||||
>
|
||||
<section-layout :heading="$options.i18n.securityTraining" />
|
||||
</gl-tab>
|
||||
</gl-tabs>
|
||||
</article>
|
||||
</template>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: secure_vulnerability_training
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346074
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/346308
|
||||
milestone: '14.6'
|
||||
type: development
|
||||
group: group::threat insights
|
||||
default_enabled: false
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveTestReportRequirementIssueConstraint < Gitlab::Database::Migration[1.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
TARGET_TABLE = :requirements_management_test_reports
|
||||
CONSTRAINT_NAME = 'requirements_test_reports_requirement_id_xor_issue_id'
|
||||
|
||||
def up
|
||||
remove_check_constraint TARGET_TABLE, CONSTRAINT_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
add_check_constraint(TARGET_TABLE, 'num_nonnulls(requirement_id, issue_id) = 1', CONSTRAINT_NAME)
|
||||
end
|
||||
end
|
1
db/schema_migrations/20211119170805
Normal file
1
db/schema_migrations/20211119170805
Normal file
|
@ -0,0 +1 @@
|
|||
adb95bc78104382fb1d3af2c2775b4b5bd23394b4260c3a97667b4bd7917e0da
|
|
@ -18888,8 +18888,7 @@ CREATE TABLE requirements_management_test_reports (
|
|||
author_id bigint,
|
||||
state smallint NOT NULL,
|
||||
build_id bigint,
|
||||
issue_id bigint,
|
||||
CONSTRAINT requirements_test_reports_requirement_id_xor_issue_id CHECK ((num_nonnulls(requirement_id, issue_id) = 1))
|
||||
issue_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE requirements_management_test_reports_id_seq
|
||||
|
|
|
@ -30836,6 +30836,9 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Security testing"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Security training"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|The status of the tools only applies to the default branch and is based on the %{linkStart}latest pipeline%{linkEnd}."
|
||||
msgstr ""
|
||||
|
||||
|
@ -30845,6 +30848,9 @@ msgstr ""
|
|||
msgid "SecurityConfiguration|Using custom settings. You won't receive automatic updates on this variable. %{anchorStart}Restore to default%{anchorEnd}"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Vulnerability Management"
|
||||
msgstr ""
|
||||
|
||||
msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
|
||||
msgstr ""
|
||||
|
||||
|
@ -37493,6 +37499,9 @@ msgstr ""
|
|||
msgid "UsageQuota|Packages"
|
||||
msgstr ""
|
||||
|
||||
msgid "UsageQuota|Pending Members"
|
||||
msgstr ""
|
||||
|
||||
msgid "UsageQuota|Pipeline artifacts and job artifacts, created with CI/CD."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -10,8 +10,11 @@ module Gitlab
|
|||
link :buy_ci_minutes, text: 'Buy additional minutes'
|
||||
link :buy_storage, text: /Purchase more storage/
|
||||
strong :additional_minutes, text: 'Additional minutes'
|
||||
div :purchased_usage, 'data-testid': 'purchased-usage'
|
||||
div(:additional_minutes_usage) { additional_minutes_element.following_sibling.span }
|
||||
div :purchase_successful_alert, text: /You have successfully purchased CI minutes/
|
||||
div :ci_purchase_successful_alert, text: /You have successfully purchased CI minutes/
|
||||
div :storage_purchase_successful_alert, text: /You have successfully purchased a storage/
|
||||
h4 :storage_available_alert, text: /purchased storage is available/
|
||||
|
||||
def plan_minutes_limits
|
||||
plan_minutes_usage[%r{([^/ ]+)$}]
|
||||
|
@ -20,6 +23,23 @@ module Gitlab
|
|||
def additional_limits
|
||||
additional_minutes_usage[%r{([^/ ]+)$}]
|
||||
end
|
||||
|
||||
# Waits and Checks if storage available alert presents on the page
|
||||
#
|
||||
# @return [Boolean] True if the alert presents, false if not after 5 second wait
|
||||
def purchased_storage_available?
|
||||
storage_available_alert_element.wait_until(timeout: 5, &:present?)
|
||||
rescue Watir::Wait::TimeoutError
|
||||
false
|
||||
end
|
||||
|
||||
# Returns total purchased storage value once it's ready on page
|
||||
#
|
||||
# @return [Float] Total purchased storage value in GiB
|
||||
def total_purchased_storage
|
||||
storage_available_alert_element.wait_until(&:present?)
|
||||
purchased_usage_element.p.spans[3].text.to_f
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { GlFormInput, GlFormTextarea } from '@gitlab/ui';
|
||||
import { shallowMount, mount } from '@vue/test-utils';
|
||||
|
||||
|
@ -32,7 +33,6 @@ describe('Pipeline Editor | Commit Form', () => {
|
|||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
wrapper = null;
|
||||
});
|
||||
|
||||
describe('when the form is displayed', () => {
|
||||
|
@ -121,7 +121,7 @@ describe('Pipeline Editor | Commit Form', () => {
|
|||
beforeEach(async () => {
|
||||
createComponent();
|
||||
wrapper.setProps({ scrollToCommitForm: true });
|
||||
await wrapper.vm.$nextTick();
|
||||
await nextTick();
|
||||
});
|
||||
|
||||
it('scrolls into view', () => {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import VueApollo from 'vue-apollo';
|
||||
import { GlFormTextarea, GlFormInput, GlLoadingIcon } from '@gitlab/ui';
|
||||
import { mount } from '@vue/test-utils';
|
||||
import { createLocalVue, mount } from '@vue/test-utils';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import { objectToQuery, redirectTo } from '~/lib/utils/url_utility';
|
||||
import CommitForm from '~/pipeline_editor/components/commit/commit_form.vue';
|
||||
|
@ -10,18 +12,22 @@ import {
|
|||
COMMIT_SUCCESS,
|
||||
} from '~/pipeline_editor/constants';
|
||||
import commitCreate from '~/pipeline_editor/graphql/mutations/commit_ci_file.mutation.graphql';
|
||||
import updatePipelineEtag from '~/pipeline_editor/graphql/mutations/update_pipeline_etag.mutation.graphql';
|
||||
|
||||
import {
|
||||
mockCiConfigPath,
|
||||
mockCiYml,
|
||||
mockCommitCreateResponse,
|
||||
mockCommitCreateResponseNewEtag,
|
||||
mockCommitSha,
|
||||
mockCommitNextSha,
|
||||
mockCommitMessage,
|
||||
mockDefaultBranch,
|
||||
mockProjectFullPath,
|
||||
mockNewMergeRequestPath,
|
||||
} from '../../mock_data';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
|
||||
jest.mock('~/lib/utils/url_utility', () => ({
|
||||
redirectTo: jest.fn(),
|
||||
refreshCurrentPage: jest.fn(),
|
||||
|
@ -47,7 +53,8 @@ const mockProvide = {
|
|||
|
||||
describe('Pipeline Editor | Commit section', () => {
|
||||
let wrapper;
|
||||
let mockMutate;
|
||||
let mockApollo;
|
||||
const mockMutateCommitData = jest.fn();
|
||||
|
||||
const defaultProps = {
|
||||
ciFileContent: mockCiYml,
|
||||
|
@ -55,18 +62,7 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
isNewCiConfigFile: false,
|
||||
};
|
||||
|
||||
const createComponent = ({ props = {}, options = {}, provide = {} } = {}) => {
|
||||
mockMutate = jest.fn().mockResolvedValue({
|
||||
data: {
|
||||
commitCreate: {
|
||||
errors: [],
|
||||
commit: {
|
||||
sha: mockCommitNextSha,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const createComponent = ({ apolloConfig = {}, props = {}, options = {}, provide = {} } = {}) => {
|
||||
wrapper = mount(CommitSection, {
|
||||
propsData: { ...defaultProps, ...props },
|
||||
provide: { ...mockProvide, ...provide },
|
||||
|
@ -75,16 +71,25 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
currentBranch: mockDefaultBranch,
|
||||
};
|
||||
},
|
||||
mocks: {
|
||||
$apollo: {
|
||||
mutate: mockMutate,
|
||||
},
|
||||
},
|
||||
attachTo: document.body,
|
||||
...apolloConfig,
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
const createComponentWithApollo = (options) => {
|
||||
const handlers = [[commitCreate, mockMutateCommitData]];
|
||||
localVue.use(VueApollo);
|
||||
mockApollo = createMockApollo(handlers);
|
||||
|
||||
const apolloConfig = {
|
||||
localVue,
|
||||
apolloProvider: mockApollo,
|
||||
};
|
||||
|
||||
createComponent({ ...options, apolloConfig });
|
||||
};
|
||||
|
||||
const findCommitForm = () => wrapper.findComponent(CommitForm);
|
||||
const findCommitBtnLoadingIcon = () =>
|
||||
wrapper.find('[type="submit"]').findComponent(GlLoadingIcon);
|
||||
|
@ -104,66 +109,53 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
};
|
||||
|
||||
afterEach(() => {
|
||||
mockMutate.mockReset();
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
describe('when the user commits a new file', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent({ props: { isNewCiConfigFile: true } });
|
||||
mockMutateCommitData.mockResolvedValue(mockCommitCreateResponse);
|
||||
createComponentWithApollo({ props: { isNewCiConfigFile: true } });
|
||||
await submitCommit();
|
||||
});
|
||||
|
||||
it('calls the mutation with the CREATE action', () => {
|
||||
// the extra calls are for updating client queries (currentBranch and lastCommitBranch)
|
||||
expect(mockMutate).toHaveBeenCalledTimes(3);
|
||||
expect(mockMutate).toHaveBeenCalledWith({
|
||||
mutation: commitCreate,
|
||||
update: expect.any(Function),
|
||||
variables: {
|
||||
...mockVariables,
|
||||
action: COMMIT_ACTION_CREATE,
|
||||
branch: mockDefaultBranch,
|
||||
},
|
||||
expect(mockMutateCommitData).toHaveBeenCalledTimes(1);
|
||||
expect(mockMutateCommitData).toHaveBeenCalledWith({
|
||||
...mockVariables,
|
||||
action: COMMIT_ACTION_CREATE,
|
||||
branch: mockDefaultBranch,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the user commits an update to an existing file', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent();
|
||||
createComponentWithApollo();
|
||||
await submitCommit();
|
||||
});
|
||||
|
||||
it('calls the mutation with the UPDATE action', () => {
|
||||
expect(mockMutate).toHaveBeenCalledTimes(3);
|
||||
expect(mockMutate).toHaveBeenCalledWith({
|
||||
mutation: commitCreate,
|
||||
update: expect.any(Function),
|
||||
variables: {
|
||||
...mockVariables,
|
||||
action: COMMIT_ACTION_UPDATE,
|
||||
branch: mockDefaultBranch,
|
||||
},
|
||||
expect(mockMutateCommitData).toHaveBeenCalledTimes(1);
|
||||
expect(mockMutateCommitData).toHaveBeenCalledWith({
|
||||
...mockVariables,
|
||||
action: COMMIT_ACTION_UPDATE,
|
||||
branch: mockDefaultBranch,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the user commits changes to the current branch', () => {
|
||||
beforeEach(async () => {
|
||||
createComponent();
|
||||
createComponentWithApollo();
|
||||
await submitCommit();
|
||||
});
|
||||
|
||||
it('calls the mutation with the current branch', () => {
|
||||
expect(mockMutate).toHaveBeenCalledTimes(3);
|
||||
expect(mockMutate).toHaveBeenCalledWith({
|
||||
mutation: commitCreate,
|
||||
update: expect.any(Function),
|
||||
variables: {
|
||||
...mockVariables,
|
||||
branch: mockDefaultBranch,
|
||||
},
|
||||
expect(mockMutateCommitData).toHaveBeenCalledTimes(1);
|
||||
expect(mockMutateCommitData).toHaveBeenCalledWith({
|
||||
...mockVariables,
|
||||
branch: mockDefaultBranch,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -183,14 +175,10 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
it('a second commit submits the latest sha, keeping the form updated', async () => {
|
||||
await submitCommit();
|
||||
|
||||
expect(mockMutate).toHaveBeenCalledTimes(6);
|
||||
expect(mockMutate).toHaveBeenCalledWith({
|
||||
mutation: commitCreate,
|
||||
update: expect.any(Function),
|
||||
variables: {
|
||||
...mockVariables,
|
||||
branch: mockDefaultBranch,
|
||||
},
|
||||
expect(mockMutateCommitData).toHaveBeenCalledTimes(2);
|
||||
expect(mockMutateCommitData).toHaveBeenCalledWith({
|
||||
...mockVariables,
|
||||
branch: mockDefaultBranch,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -199,20 +187,16 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
const newBranch = 'new-branch';
|
||||
|
||||
beforeEach(async () => {
|
||||
createComponent();
|
||||
createComponentWithApollo();
|
||||
await submitCommit({
|
||||
branch: newBranch,
|
||||
});
|
||||
});
|
||||
|
||||
it('calls the mutation with the new branch', () => {
|
||||
expect(mockMutate).toHaveBeenCalledWith({
|
||||
mutation: commitCreate,
|
||||
update: expect.any(Function),
|
||||
variables: {
|
||||
...mockVariables,
|
||||
branch: newBranch,
|
||||
},
|
||||
expect(mockMutateCommitData).toHaveBeenCalledWith({
|
||||
...mockVariables,
|
||||
branch: newBranch,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -225,7 +209,7 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
const newBranch = 'new-branch';
|
||||
|
||||
beforeEach(async () => {
|
||||
createComponent();
|
||||
createComponentWithApollo();
|
||||
await submitCommit({
|
||||
branch: newBranch,
|
||||
openMergeRequest: true,
|
||||
|
@ -244,11 +228,11 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
|
||||
describe('when the commit is ocurring', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
createComponentWithApollo();
|
||||
});
|
||||
|
||||
it('shows a saving state', async () => {
|
||||
mockMutate.mockImplementationOnce(() => {
|
||||
mockMutateCommitData.mockImplementationOnce(() => {
|
||||
expect(findCommitBtnLoadingIcon().exists()).toBe(true);
|
||||
return Promise.resolve();
|
||||
});
|
||||
|
@ -261,6 +245,26 @@ describe('Pipeline Editor | Commit section', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('when the commit returns a different etag path', () => {
|
||||
beforeEach(async () => {
|
||||
createComponentWithApollo();
|
||||
jest.spyOn(wrapper.vm.$apollo, 'mutate');
|
||||
mockMutateCommitData.mockResolvedValue(mockCommitCreateResponseNewEtag);
|
||||
await submitCommit();
|
||||
});
|
||||
|
||||
it('calls the client mutation to update the etag', () => {
|
||||
// 1:Commit submission, 2:etag update, 3:currentBranch update, 4:lastCommit update
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledTimes(4);
|
||||
expect(wrapper.vm.$apollo.mutate).toHaveBeenNthCalledWith(2, {
|
||||
mutation: updatePipelineEtag,
|
||||
variables: {
|
||||
pipelineEtag: mockCommitCreateResponseNewEtag.data.commitCreate.commitPipelinePath,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('sets listeners on commit form', () => {
|
||||
const handler = jest.fn();
|
||||
createComponent({ options: { listeners: { event: handler } } });
|
||||
|
|
|
@ -453,3 +453,31 @@ export const mockErrors = [
|
|||
export const mockWarnings = [
|
||||
'"jobs:multi_project_job may allow multiple pipelines to run for a single action due to `rules:when` clause with no `workflow:rules` - read more: https://docs.gitlab.com/ee/ci/troubleshooting.html#pipeline-warnings"',
|
||||
];
|
||||
|
||||
export const mockCommitCreateResponse = {
|
||||
data: {
|
||||
commitCreate: {
|
||||
__typename: 'CommitCreatePayload',
|
||||
errors: [],
|
||||
commit: {
|
||||
__typename: 'Commit',
|
||||
sha: mockCommitNextSha,
|
||||
},
|
||||
commitPipelinePath: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const mockCommitCreateResponseNewEtag = {
|
||||
data: {
|
||||
commitCreate: {
|
||||
__typename: 'CommitCreatePayload',
|
||||
errors: [],
|
||||
commit: {
|
||||
__typename: 'Commit',
|
||||
sha: mockCommitNextSha,
|
||||
},
|
||||
commitPipelinePath: '/api/graphql:pipelines/sha/550ceace1acd373c84d02bd539cb9d4614f786db',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -39,7 +39,11 @@ describe('App component', () => {
|
|||
let wrapper;
|
||||
let userCalloutDismissSpy;
|
||||
|
||||
const createComponent = ({ shouldShowCallout = true, ...propsData }) => {
|
||||
const createComponent = ({
|
||||
shouldShowCallout = true,
|
||||
secureVulnerabilityTraining = true,
|
||||
...propsData
|
||||
}) => {
|
||||
userCalloutDismissSpy = jest.fn();
|
||||
|
||||
wrapper = extendedWrapper(
|
||||
|
@ -50,6 +54,9 @@ describe('App component', () => {
|
|||
autoDevopsHelpPagePath,
|
||||
autoDevopsPath,
|
||||
projectPath,
|
||||
glFeatures: {
|
||||
secureVulnerabilityTraining,
|
||||
},
|
||||
},
|
||||
stubs: {
|
||||
...stubChildren(SecurityConfigurationApp),
|
||||
|
@ -138,20 +145,20 @@ describe('App component', () => {
|
|||
expect(mainHeading.text()).toContain('Security Configuration');
|
||||
});
|
||||
|
||||
it('renders GlTab Component ', () => {
|
||||
expect(findTab().exists()).toBe(true);
|
||||
});
|
||||
describe('tabs', () => {
|
||||
const expectedTabs = ['security-testing', 'compliance-testing', 'vulnerability-management'];
|
||||
|
||||
it('renders right amount of tabs with correct title ', () => {
|
||||
expect(findTabs()).toHaveLength(2);
|
||||
});
|
||||
it('renders GlTab Component', () => {
|
||||
expect(findTab().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders security-testing tab', () => {
|
||||
expect(findByTestId('security-testing-tab').exists()).toBe(true);
|
||||
});
|
||||
it('renders correct amount of tabs', () => {
|
||||
expect(findTabs()).toHaveLength(expectedTabs.length);
|
||||
});
|
||||
|
||||
it('renders compliance-testing tab', () => {
|
||||
expect(findByTestId('compliance-testing-tab').exists()).toBe(true);
|
||||
it.each(expectedTabs)('renders the %s tab', (tabName) => {
|
||||
expect(findByTestId(`${tabName}-tab`).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders right amount of feature cards for given props with correct props', () => {
|
||||
|
@ -418,4 +425,22 @@ describe('App component', () => {
|
|||
expect(findSecurityViewHistoryLink().attributes('href')).toBe('test/historyPath');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when secureVulnerabilityTraining feature flag is disabled', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
augmentedSecurityFeatures: securityFeaturesMock,
|
||||
augmentedComplianceFeatures: complianceFeaturesMock,
|
||||
secureVulnerabilityTraining: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('renders correct amount of tabs', () => {
|
||||
expect(findTabs()).toHaveLength(2);
|
||||
});
|
||||
|
||||
it('does not render the vulnerability-management tab', () => {
|
||||
expect(wrapper.findByTestId('vulnerability-management-tab').exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue