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
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/editor')
-rw-r--r--spec/frontend/editor/schema/ci/ci_schema_spec.js10
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/negative_tests/auto_cancel_pipeline.yml4
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/negative_tests/image.yml38
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/negative_tests/services.yml14
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/all.yml4
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/none.yml4
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/positive_tests/image.yml41
-rw-r--r--spec/frontend/editor/schema/ci/yaml_tests/positive_tests/services.yml7
-rw-r--r--spec/frontend/editor/source_editor_security_policy_schema_ext_spec.js181
9 files changed, 303 insertions, 0 deletions
diff --git a/spec/frontend/editor/schema/ci/ci_schema_spec.js b/spec/frontend/editor/schema/ci/ci_schema_spec.js
index 0f380f13679..7986509074e 100644
--- a/spec/frontend/editor/schema/ci/ci_schema_spec.js
+++ b/spec/frontend/editor/schema/ci/ci_schema_spec.js
@@ -23,6 +23,7 @@ import RetryUnknownWhenJson from './json_tests/negative_tests/retry_unknown_when
// YAML POSITIVE TEST
import ArtifactsYaml from './yaml_tests/positive_tests/artifacts.yml';
+import ImageYaml from './yaml_tests/positive_tests/image.yml';
import CacheYaml from './yaml_tests/positive_tests/cache.yml';
import FilterYaml from './yaml_tests/positive_tests/filter.yml';
import IncludeYaml from './yaml_tests/positive_tests/include.yml';
@@ -37,9 +38,12 @@ import SecretsYaml from './yaml_tests/positive_tests/secrets.yml';
import ServicesYaml from './yaml_tests/positive_tests/services.yml';
import NeedsParallelMatrixYaml from './yaml_tests/positive_tests/needs_parallel_matrix.yml';
import ScriptYaml from './yaml_tests/positive_tests/script.yml';
+import AutoCancelPipelineOnJobFailureAllYaml from './yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/all.yml';
+import AutoCancelPipelineOnJobFailureNoneYaml from './yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/none.yml';
// YAML NEGATIVE TEST
import ArtifactsNegativeYaml from './yaml_tests/negative_tests/artifacts.yml';
+import ImageNegativeYaml from './yaml_tests/negative_tests/image.yml';
import CacheKeyNeative from './yaml_tests/negative_tests/cache.yml';
import IncludeNegativeYaml from './yaml_tests/negative_tests/include.yml';
import JobWhenNegativeYaml from './yaml_tests/negative_tests/job_when.yml';
@@ -62,6 +66,7 @@ import NeedsParallelMatrixNumericYaml from './yaml_tests/negative_tests/needs/pa
import NeedsParallelMatrixWrongParallelValueYaml from './yaml_tests/negative_tests/needs/parallel_matrix/wrong_parallel_value.yml';
import NeedsParallelMatrixWrongMatrixValueYaml from './yaml_tests/negative_tests/needs/parallel_matrix/wrong_matrix_value.yml';
import ScriptNegativeYaml from './yaml_tests/negative_tests/script.yml';
+import AutoCancelPipelineNegativeYaml from './yaml_tests/negative_tests/auto_cancel_pipeline.yml';
const ajv = new Ajv({
strictTypes: false,
@@ -90,6 +95,7 @@ describe('positive tests', () => {
// YAML
ArtifactsYaml,
+ ImageYaml,
CacheYaml,
FilterYaml,
IncludeYaml,
@@ -104,6 +110,8 @@ describe('positive tests', () => {
SecretsYaml,
NeedsParallelMatrixYaml,
ScriptYaml,
+ AutoCancelPipelineOnJobFailureAllYaml,
+ AutoCancelPipelineOnJobFailureNoneYaml,
}),
)('schema validates %s', (_, input) => {
// We construct a new "JSON" from each main key that is inside a
@@ -126,6 +134,7 @@ describe('negative tests', () => {
// YAML
ArtifactsNegativeYaml,
+ ImageNegativeYaml,
CacheKeyNeative,
HooksNegative,
IdTokensNegativeYaml,
@@ -148,6 +157,7 @@ describe('negative tests', () => {
NeedsParallelMatrixWrongParallelValueYaml,
NeedsParallelMatrixWrongMatrixValueYaml,
ScriptNegativeYaml,
+ AutoCancelPipelineNegativeYaml,
}),
)('schema validates %s', (_, input) => {
// We construct a new "JSON" from each main key that is inside a
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/auto_cancel_pipeline.yml b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/auto_cancel_pipeline.yml
new file mode 100644
index 00000000000..0ba3e5632e3
--- /dev/null
+++ b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/auto_cancel_pipeline.yml
@@ -0,0 +1,4 @@
+# invalid workflow:auto-cancel:on-job-failure
+workflow:
+ auto_cancel:
+ on_job_failure: unexpected_value
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/image.yml b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/image.yml
new file mode 100644
index 00000000000..ad37cd6c3ba
--- /dev/null
+++ b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/image.yml
@@ -0,0 +1,38 @@
+empty_image:
+ image:
+
+multi_image_array:
+ image:
+ - alpine:latest
+ - ubuntu:latest
+
+image_without_name:
+ image:
+ entrypoint: ["/bin/sh", "-c"]
+
+image_with_invalid_entrypoint:
+ image:
+ name: my-postgres:11.7
+ entrypoint: "/usr/local/bin/db-postgres" # must be array
+
+image_with_empty_pull_policy:
+ image:
+ name: postgres:11.6
+ pull_policy: []
+
+invalid_image_platform:
+ image:
+ name: alpine:latest
+ docker:
+ platform: ["arm64"] # The expected value is a string, not an array
+
+invalid_image_executor_opts:
+ image:
+ name: alpine:latest
+ docker:
+ unknown_key: test
+
+image_with_empty_executor_opts:
+ image:
+ name: alpine:latest
+ docker:
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/services.yml b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/services.yml
index 6761a603a0a..e14ac9ca86e 100644
--- a/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/services.yml
+++ b/spec/frontend/editor/schema/ci/yaml_tests/negative_tests/services.yml
@@ -36,3 +36,17 @@ empty_pull_policy:
services:
- name: postgres:11.6
pull_policy: []
+
+invalid_service_executor_opts:
+ script: echo "Specifying platform."
+ services:
+ - name: mysql:5.7
+ docker:
+ unknown_key: test
+
+invalid_service_platform:
+ script: echo "Specifying platform."
+ services:
+ - name: mysql:5.7
+ docker:
+ platform: ["arm64"] # The expected value is a string, not an array
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/all.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/all.yml
new file mode 100644
index 00000000000..bf84ff16f42
--- /dev/null
+++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/all.yml
@@ -0,0 +1,4 @@
+# valid workflow:auto-cancel:on-job-failure
+workflow:
+ auto_cancel:
+ on_job_failure: all
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/none.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/none.yml
new file mode 100644
index 00000000000..b99eb50e962
--- /dev/null
+++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/auto_cancel_pipeline/on_job_failure/none.yml
@@ -0,0 +1,4 @@
+# valid workflow:auto-cancel:on-job-failure
+workflow:
+ auto_cancel:
+ on_job_failure: none
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/image.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/image.yml
new file mode 100644
index 00000000000..4c2559d0800
--- /dev/null
+++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/image.yml
@@ -0,0 +1,41 @@
+valid_image:
+ image: alpine:latest
+
+valid_image_basic:
+ image:
+ name: alpine:latest
+
+valid_image_with_entrypoint:
+ image:
+ name: alpine:latest
+ entrypoint:
+ - /bin/sh
+ - -c
+
+valid_image_with_pull_policy:
+ image:
+ name: alpine:latest
+ pull_policy: always
+
+valid_image_with_pull_policies:
+ image:
+ name: alpine:latest
+ pull_policy:
+ - always
+ - if-not-present
+
+valid_image_with_docker:
+ image:
+ name: alpine:latest
+ docker:
+ platform: linux/amd64
+
+valid_image_full:
+ image:
+ name: alpine:latest
+ entrypoint:
+ - /bin/sh
+ - -c
+ docker:
+ platform: linux/amd64
+ pull_policy: if-not-present
diff --git a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/services.yml b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/services.yml
index 8a0f59d1dfd..1d19ee52cc3 100644
--- a/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/services.yml
+++ b/spec/frontend/editor/schema/ci/yaml_tests/positive_tests/services.yml
@@ -29,3 +29,10 @@ pull_policy_array:
services:
- name: postgres:11.6
pull_policy: [always, if-not-present]
+
+services_platform_string:
+ script: echo "Specifying platform."
+ services:
+ - name: mysql:5.7
+ docker:
+ platform: arm64
diff --git a/spec/frontend/editor/source_editor_security_policy_schema_ext_spec.js b/spec/frontend/editor/source_editor_security_policy_schema_ext_spec.js
new file mode 100644
index 00000000000..96c876b27c9
--- /dev/null
+++ b/spec/frontend/editor/source_editor_security_policy_schema_ext_spec.js
@@ -0,0 +1,181 @@
+import MockAdapter from 'axios-mock-adapter';
+import { registerSchema } from '~/ide/utils';
+import axios from '~/lib/utils/axios_utils';
+import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
+import { TEST_HOST } from 'helpers/test_constants';
+import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
+import {
+ getSecurityPolicyListUrl,
+ getSecurityPolicySchemaUrl,
+ getSinglePolicySchema,
+ SecurityPolicySchemaExtension,
+} from '~/editor/extensions/source_editor_security_policy_schema_ext';
+import SourceEditor from '~/editor/source_editor';
+
+jest.mock('~/ide/utils');
+
+const mockNamespacePath = 'mock-namespace';
+
+const mockSchema = {
+ $id: 1,
+ title: 'mockSchema',
+ description: 'mockDescriptions',
+ type: 'Object',
+ properties: {
+ scan_execution_policy: { items: { properties: { foo: 'bar' } } },
+ scan_result_policy: { items: { properties: { fizz: 'buzz' } } },
+ },
+};
+
+const createMockOutput = (policyType) => ({
+ $id: mockSchema.$id,
+ title: mockSchema.title,
+ description: mockSchema.description,
+ type: mockSchema.type,
+ properties: {
+ type: {
+ type: 'string',
+ description: 'Specifies the type of policy to be enforced.',
+ enum: policyType,
+ },
+ ...mockSchema.properties[policyType].items.properties,
+ },
+});
+
+describe('getSecurityPolicyListUrl', () => {
+ it.each`
+ input | output
+ ${{ namespacePath: '' }} | ${`${TEST_HOST}/groups/-/security/policies`}
+ ${{ namespacePath: 'test', namespaceType: 'group' }} | ${`${TEST_HOST}/groups/test/-/security/policies`}
+ ${{ namespacePath: '', namespaceType: 'project' }} | ${`${TEST_HOST}/-/security/policies`}
+ ${{ namespacePath: 'test', namespaceType: 'project' }} | ${`${TEST_HOST}/test/-/security/policies`}
+ ${{ namespacePath: undefined, namespaceType: 'project' }} | ${`${TEST_HOST}/-/security/policies`}
+ ${{ namespacePath: undefined, namespaceType: 'group' }} | ${`${TEST_HOST}/groups/-/security/policies`}
+ ${{ namespacePath: null, namespaceType: 'project' }} | ${`${TEST_HOST}/-/security/policies`}
+ ${{ namespacePath: null, namespaceType: 'group' }} | ${`${TEST_HOST}/groups/-/security/policies`}
+ `('returns `$output` when passed `$input`', ({ input, output }) => {
+ expect(getSecurityPolicyListUrl(input)).toBe(output);
+ });
+});
+
+describe('getSecurityPolicySchemaUrl', () => {
+ it.each`
+ namespacePath | namespaceType | output
+ ${'test'} | ${'project'} | ${`${TEST_HOST}/test/-/security/policies/schema`}
+ ${'test'} | ${'group'} | ${`${TEST_HOST}/groups/test/-/security/policies/schema`}
+ `(
+ 'returns $output when passed $namespacePath and $namespaceType',
+ ({ namespacePath, namespaceType, output }) => {
+ expect(getSecurityPolicySchemaUrl({ namespacePath, namespaceType })).toBe(output);
+ },
+ );
+});
+
+describe('getSinglePolicySchema', () => {
+ let mock;
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ mock.restore();
+ });
+
+ it.each`
+ policyType
+ ${'scan_execution_policy'}
+ ${'scan_result_policy'}
+ `('returns the appropriate schema on request success for $policyType', async ({ policyType }) => {
+ mock.onGet().reply(HTTP_STATUS_OK, mockSchema);
+
+ await expect(
+ getSinglePolicySchema({
+ namespacePath: mockNamespacePath,
+ namespaceType: 'project',
+ policyType,
+ }),
+ ).resolves.toStrictEqual(createMockOutput(policyType));
+ });
+
+ it('returns an empty schema on request failure', async () => {
+ await expect(
+ getSinglePolicySchema({
+ namespacePath: mockNamespacePath,
+ namespaceType: 'project',
+ policyType: 'scan_execution_policy',
+ }),
+ ).resolves.toStrictEqual({});
+ });
+
+ it('returns an empty schema on non-existing policy type', async () => {
+ await expect(
+ getSinglePolicySchema({
+ namespacePath: mockNamespacePath,
+ namespaceType: 'project',
+ policyType: 'non_existent_policy',
+ }),
+ ).resolves.toStrictEqual({});
+ });
+});
+
+describe('SecurityPolicySchemaExtension', () => {
+ let mock;
+ let editor;
+ let instance;
+ let editorEl;
+
+ const createMockEditor = ({ blobPath = '.gitlab/security-policies/policy.yml' } = {}) => {
+ setHTMLFixture('<div id="editor"></div>');
+ editorEl = document.getElementById('editor');
+ editor = new SourceEditor();
+ instance = editor.createInstance({ el: editorEl, blobPath, blobContent: '' });
+ instance.use({ definition: SecurityPolicySchemaExtension });
+ };
+
+ beforeEach(() => {
+ createMockEditor();
+ mock = new MockAdapter(axios);
+ mock.onGet().reply(HTTP_STATUS_OK, mockSchema);
+ });
+
+ afterEach(() => {
+ instance.dispose();
+ editorEl.remove();
+ resetHTMLFixture();
+ mock.restore();
+ });
+
+ describe('registerSecurityPolicyEditorSchema', () => {
+ describe('register validations options with monaco for yaml language', () => {
+ it('registers the schema', async () => {
+ const policyType = 'scan_execution_policy';
+ await instance.registerSecurityPolicyEditorSchema({
+ namespacePath: mockNamespacePath,
+ namespaceType: 'project',
+ policyType,
+ });
+
+ expect(registerSchema).toHaveBeenCalledTimes(1);
+ expect(registerSchema).toHaveBeenCalledWith({
+ uri: `${TEST_HOST}/${mockNamespacePath}/-/security/policies/schema`,
+ schema: createMockOutput(policyType),
+ fileMatch: ['policy.yml'],
+ });
+ });
+ });
+ });
+
+ describe('registerSecurityPolicySchema', () => {
+ describe('register validations options with monaco for yaml language', () => {
+ it('registers the schema', async () => {
+ await instance.registerSecurityPolicySchema(mockNamespacePath);
+ expect(registerSchema).toHaveBeenCalledTimes(1);
+ expect(registerSchema).toHaveBeenCalledWith({
+ uri: `${TEST_HOST}/${mockNamespacePath}/-/security/policies/schema`,
+ fileMatch: ['policy.yml'],
+ });
+ });
+ });
+ });
+});