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/snippets')
-rw-r--r--spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap3
-rw-r--r--spec/frontend/snippets/components/edit_spec.js209
-rw-r--r--spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js36
3 files changed, 171 insertions, 77 deletions
diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
index 2b26c306c68..fec300ddd7e 100644
--- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
+++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap
@@ -28,9 +28,9 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
data-uploads-path=""
>
<markdown-header-stub
- data-testid="markdownHeader"
enablepreview="true"
linecontent=""
+ restrictedtoolbaritems=""
suggestionstartindex="0"
/>
@@ -81,6 +81,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] =
canattachfile="true"
markdowndocspath="help/"
quickactionsdocspath=""
+ showcommenttoolbar="true"
/>
</div>
</div>
diff --git a/spec/frontend/snippets/components/edit_spec.js b/spec/frontend/snippets/components/edit_spec.js
index 9cfe136129a..8a767765149 100644
--- a/spec/frontend/snippets/components/edit_spec.js
+++ b/spec/frontend/snippets/components/edit_spec.js
@@ -1,5 +1,4 @@
-import { GlLoadingIcon } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { GlFormGroup, GlLoadingIcon } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import { merge } from 'lodash';
@@ -7,6 +6,7 @@ import VueApollo, { ApolloMutation } from 'vue-apollo';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import GetSnippetQuery from 'shared_queries/snippet/snippet.query.graphql';
import createFlash from '~/flash';
import * as urlUtils from '~/lib/utils/url_utility';
@@ -22,7 +22,6 @@ import {
import CreateSnippetMutation from '~/snippets/mutations/create_snippet.mutation.graphql';
import UpdateSnippetMutation from '~/snippets/mutations/update_snippet.mutation.graphql';
import FormFooterActions from '~/vue_shared/components/form/form_footer_actions.vue';
-import TitleField from '~/vue_shared/components/form/title.vue';
import { testEntries, createGQLSnippetsQueryResponse, createGQLSnippet } from '../test_utils';
jest.mock('~/flash');
@@ -112,19 +111,19 @@ describe('Snippet Edit app', () => {
gon.relative_url_root = originalRelativeUrlRoot;
});
- const findBlobActions = () => wrapper.find(SnippetBlobActionsEdit);
- const findSubmitButton = () => wrapper.find('[data-testid="snippet-submit-btn"]');
- const findCancelButton = () => wrapper.find('[data-testid="snippet-cancel-btn"]');
- const hasDisabledSubmit = () => Boolean(findSubmitButton().attributes('disabled'));
- const clickSubmitBtn = () => wrapper.find('[data-testid="snippet-edit-form"]').trigger('submit');
+ const findBlobActions = () => wrapper.findComponent(SnippetBlobActionsEdit);
+ const findCancelButton = () => wrapper.findByTestId('snippet-cancel-btn');
+ const clickSubmitBtn = () => wrapper.findByTestId('snippet-edit-form').trigger('submit');
+
const triggerBlobActions = (actions) => findBlobActions().vm.$emit('actions', actions);
const setUploadFilesHtml = (paths) => {
wrapper.vm.$el.innerHTML = paths
.map((path) => `<input name="files[]" value="${path}">`)
.join('');
};
- const setTitle = (val) => wrapper.find(TitleField).vm.$emit('input', val);
- const setDescription = (val) => wrapper.find(SnippetDescriptionEdit).vm.$emit('input', val);
+ const setTitle = (val) => wrapper.findByTestId('snippet-title-input').vm.$emit('input', val);
+ const setDescription = (val) =>
+ wrapper.findComponent(SnippetDescriptionEdit).vm.$emit('input', val);
const createComponent = ({ props = {}, selectedLevel = SNIPPET_VISIBILITY_PRIVATE } = {}) => {
if (wrapper) {
@@ -139,7 +138,7 @@ describe('Snippet Edit app', () => {
];
const apolloProvider = createMockApollo(requestHandlers);
- wrapper = shallowMount(SnippetEditApp, {
+ wrapper = shallowMountExtended(SnippetEditApp, {
apolloProvider,
stubs: {
ApolloMutation,
@@ -177,7 +176,7 @@ describe('Snippet Edit app', () => {
it('renders loader', () => {
createComponent();
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
+ expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
});
});
@@ -193,10 +192,10 @@ describe('Snippet Edit app', () => {
});
it('should render components', () => {
- expect(wrapper.find(TitleField).exists()).toBe(true);
- expect(wrapper.find(SnippetDescriptionEdit).exists()).toBe(true);
- expect(wrapper.find(SnippetVisibilityEdit).exists()).toBe(true);
- expect(wrapper.find(FormFooterActions).exists()).toBe(true);
+ expect(wrapper.findComponent(GlFormGroup).attributes('label')).toEqual('Title');
+ expect(wrapper.findComponent(SnippetDescriptionEdit).exists()).toBe(true);
+ expect(wrapper.findComponent(SnippetVisibilityEdit).exists()).toBe(true);
+ expect(wrapper.findComponent(FormFooterActions).exists()).toBe(true);
expect(findBlobActions().exists()).toBe(true);
});
@@ -207,25 +206,34 @@ describe('Snippet Edit app', () => {
describe('default', () => {
it.each`
- title | actions | shouldDisable
- ${''} | ${[]} | ${true}
- ${''} | ${[TEST_ACTIONS.VALID]} | ${true}
- ${'foo'} | ${[]} | ${false}
- ${'foo'} | ${[TEST_ACTIONS.VALID]} | ${false}
- ${'foo'} | ${[TEST_ACTIONS.VALID, TEST_ACTIONS.NO_CONTENT]} | ${true}
- ${'foo'} | ${[TEST_ACTIONS.VALID, TEST_ACTIONS.NO_PATH]} | ${false}
+ title | actions | titleHasErrors | blobActionsHasErrors
+ ${''} | ${[]} | ${true} | ${false}
+ ${''} | ${[TEST_ACTIONS.VALID]} | ${true} | ${false}
+ ${'foo'} | ${[]} | ${false} | ${false}
+ ${'foo'} | ${[TEST_ACTIONS.VALID]} | ${false} | ${false}
+ ${'foo'} | ${[TEST_ACTIONS.VALID, TEST_ACTIONS.NO_CONTENT]} | ${false} | ${true}
+ ${'foo'} | ${[TEST_ACTIONS.VALID, TEST_ACTIONS.NO_PATH]} | ${false} | ${false}
`(
- 'should handle submit disable (title="$title", actions="$actions", shouldDisable="$shouldDisable")',
- async ({ title, actions, shouldDisable }) => {
+ 'validates correctly (title="$title", actions="$actions", titleHasErrors="$titleHasErrors", blobActionsHasErrors="$blobActionsHasErrors")',
+ async ({ title, actions, titleHasErrors, blobActionsHasErrors }) => {
getSpy.mockResolvedValue(createQueryResponse({ title }));
await createComponentAndLoad();
triggerBlobActions(actions);
+ clickSubmitBtn();
+
await nextTick();
- expect(hasDisabledSubmit()).toBe(shouldDisable);
+ expect(wrapper.findComponent(GlFormGroup).exists()).toBe(true);
+ expect(Boolean(wrapper.findComponent(GlFormGroup).attributes('state'))).toEqual(
+ !titleHasErrors,
+ );
+
+ expect(wrapper.find(SnippetBlobActionsEdit).props('isValid')).toEqual(
+ !blobActionsHasErrors,
+ );
},
);
@@ -262,35 +270,64 @@ describe('Snippet Edit app', () => {
);
describe('form submission handling', () => {
- it.each`
- snippetGid | projectPath | uploadedFiles | input | mutationType
- ${''} | ${'project/path'} | ${[]} | ${{ ...getApiData(), projectPath: 'project/path', uploadedFiles: [] }} | ${'createSnippet'}
- ${''} | ${''} | ${[]} | ${{ ...getApiData(), projectPath: '', uploadedFiles: [] }} | ${'createSnippet'}
- ${''} | ${''} | ${TEST_UPLOADED_FILES} | ${{ ...getApiData(), projectPath: '', uploadedFiles: TEST_UPLOADED_FILES }} | ${'createSnippet'}
- ${TEST_SNIPPET_GID} | ${'project/path'} | ${[]} | ${getApiData(createSnippet())} | ${'updateSnippet'}
- ${TEST_SNIPPET_GID} | ${''} | ${[]} | ${getApiData(createSnippet())} | ${'updateSnippet'}
- `(
- 'should submit mutation $mutationType (snippetGid=$snippetGid, projectPath=$projectPath, uploadedFiles=$uploadedFiles)',
- async ({ snippetGid, projectPath, uploadedFiles, mutationType, input }) => {
- await createComponentAndLoad({
- props: {
- snippetGid,
- projectPath,
- },
- });
-
- setUploadFilesHtml(uploadedFiles);
-
- await nextTick();
-
- clickSubmitBtn();
+ describe('when creating a new snippet', () => {
+ it.each`
+ projectPath | uploadedFiles | input
+ ${''} | ${TEST_UPLOADED_FILES} | ${{ ...getApiData({ title: 'Title' }), projectPath: '', uploadedFiles: TEST_UPLOADED_FILES }}
+ ${'project/path'} | ${TEST_UPLOADED_FILES} | ${{ ...getApiData({ title: 'Title' }), projectPath: 'project/path', uploadedFiles: TEST_UPLOADED_FILES }}
+ `(
+ 'should submit a createSnippet mutation (projectPath=$projectPath, uploadedFiles=$uploadedFiles)',
+ async ({ projectPath, uploadedFiles, input }) => {
+ await createComponentAndLoad({
+ props: {
+ snippetGid: '',
+ projectPath,
+ },
+ });
+
+ setTitle(input.title);
+ setUploadFilesHtml(uploadedFiles);
+
+ await nextTick();
+
+ clickSubmitBtn();
+
+ expect(mutateSpy).toHaveBeenCalledTimes(1);
+ expect(mutateSpy).toHaveBeenCalledWith('createSnippet', {
+ input,
+ });
+ },
+ );
+ });
- expect(mutateSpy).toHaveBeenCalledTimes(1);
- expect(mutateSpy).toHaveBeenCalledWith(mutationType, {
- input,
- });
- },
- );
+ describe('when updating a snippet', () => {
+ it.each`
+ projectPath | uploadedFiles | input
+ ${''} | ${[]} | ${getApiData(createSnippet())}
+ ${'project/path'} | ${[]} | ${getApiData(createSnippet())}
+ `(
+ 'should submit an updateSnippet mutation (projectPath=$projectPath, uploadedFiles=$uploadedFiles)',
+ async ({ projectPath, uploadedFiles, input }) => {
+ await createComponentAndLoad({
+ props: {
+ snippetGid: TEST_SNIPPET_GID,
+ projectPath,
+ },
+ });
+
+ setUploadFilesHtml(uploadedFiles);
+
+ await nextTick();
+
+ clickSubmitBtn();
+
+ expect(mutateSpy).toHaveBeenCalledTimes(1);
+ expect(mutateSpy).toHaveBeenCalledWith('updateSnippet', {
+ input,
+ });
+ },
+ );
+ });
it('should redirect to snippet view on successful mutation', async () => {
await createComponentAndSubmit();
@@ -298,30 +335,55 @@ describe('Snippet Edit app', () => {
expect(urlUtils.redirectTo).toHaveBeenCalledWith(TEST_WEB_URL);
});
- it.each`
- snippetGid | projectPath | mutationRes | expectMessage
- ${''} | ${'project/path'} | ${createMutationResponseWithErrors('createSnippet')} | ${`Can't create snippet: ${TEST_MUTATION_ERROR}`}
- ${''} | ${''} | ${createMutationResponseWithErrors('createSnippet')} | ${`Can't create snippet: ${TEST_MUTATION_ERROR}`}
- ${TEST_SNIPPET_GID} | ${'project/path'} | ${createMutationResponseWithErrors('updateSnippet')} | ${`Can't update snippet: ${TEST_MUTATION_ERROR}`}
- ${TEST_SNIPPET_GID} | ${''} | ${createMutationResponseWithErrors('updateSnippet')} | ${`Can't update snippet: ${TEST_MUTATION_ERROR}`}
- `(
- 'should flash error with (snippet=$snippetGid, projectPath=$projectPath)',
- async ({ snippetGid, projectPath, mutationRes, expectMessage }) => {
- mutateSpy.mockResolvedValue(mutationRes);
-
- await createComponentAndSubmit({
- props: {
- projectPath,
- snippetGid,
- },
+ describe('when there are errors after creating a new snippet', () => {
+ it.each`
+ projectPath
+ ${'project/path'}
+ ${''}
+ `('should flash error (projectPath=$projectPath)', async ({ projectPath }) => {
+ mutateSpy.mockResolvedValue(createMutationResponseWithErrors('createSnippet'));
+
+ await createComponentAndLoad({
+ props: { projectPath, snippetGid: '' },
});
+ setTitle('Title');
+
+ clickSubmitBtn();
+
+ await waitForPromises();
+
expect(urlUtils.redirectTo).not.toHaveBeenCalled();
expect(createFlash).toHaveBeenCalledWith({
- message: expectMessage,
+ message: `Can't create snippet: ${TEST_MUTATION_ERROR}`,
});
- },
- );
+ });
+ });
+
+ describe('when there are errors after updating a snippet', () => {
+ it.each`
+ projectPath
+ ${'project/path'}
+ ${''}
+ `(
+ 'should flash error with (snippet=$snippetGid, projectPath=$projectPath)',
+ async ({ projectPath }) => {
+ mutateSpy.mockResolvedValue(createMutationResponseWithErrors('updateSnippet'));
+
+ await createComponentAndSubmit({
+ props: {
+ projectPath,
+ snippetGid: TEST_SNIPPET_GID,
+ },
+ });
+
+ expect(urlUtils.redirectTo).not.toHaveBeenCalled();
+ expect(createFlash).toHaveBeenCalledWith({
+ message: `Can't update snippet: ${TEST_MUTATION_ERROR}`,
+ });
+ },
+ );
+ });
describe('with apollo network error', () => {
beforeEach(async () => {
@@ -382,6 +444,7 @@ describe('Snippet Edit app', () => {
false,
() => {
triggerBlobActions([testEntries.updated.diff]);
+ setTitle('test');
clickSubmitBtn();
},
],
diff --git a/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js b/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
index 8174ba5c693..df98312b498 100644
--- a/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
+++ b/spec/frontend/snippets/components/snippet_blob_actions_edit_spec.js
@@ -1,6 +1,7 @@
-import { shallowMount } from '@vue/test-utils';
import { times } from 'lodash';
import { nextTick } from 'vue';
+import { GlFormGroup } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
import SnippetBlobActionsEdit from '~/snippets/components/snippet_blob_actions_edit.vue';
import SnippetBlobEdit from '~/snippets/components/snippet_blob_edit.vue';
import {
@@ -8,6 +9,7 @@ import {
SNIPPET_BLOB_ACTION_CREATE,
SNIPPET_BLOB_ACTION_MOVE,
} from '~/snippets/constants';
+import { s__ } from '~/locale';
import { testEntries, createBlobFromTestEntry } from '../test_utils';
const TEST_BLOBS = [
@@ -29,7 +31,7 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
});
};
- const findLabel = () => wrapper.find('label');
+ const findLabel = () => wrapper.findComponent(GlFormGroup);
const findBlobEdits = () => wrapper.findAll(SnippetBlobEdit);
const findBlobsData = () =>
findBlobEdits().wrappers.map((x) => ({
@@ -65,7 +67,7 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
});
it('renders label', () => {
- expect(findLabel().text()).toBe('Files');
+ expect(findLabel().attributes('label')).toBe('Files');
});
it(`renders delete button (show=true)`, () => {
@@ -280,4 +282,32 @@ describe('snippets/components/snippet_blob_actions_edit', () => {
expect(findAddButton().props('disabled')).toBe(true);
});
});
+
+ describe('isValid prop', () => {
+ const validationMessage = s__(
+ "Snippets|Snippets can't contain empty files. Ensure all files have content, or delete them.",
+ );
+
+ describe('when not present', () => {
+ it('sets the label validation state to true', () => {
+ createComponent();
+
+ const label = findLabel();
+
+ expect(Boolean(label.attributes('state'))).toEqual(true);
+ expect(label.attributes('invalid-feedback')).toEqual(validationMessage);
+ });
+ });
+
+ describe('when present', () => {
+ it('sets the label validation state to the value', () => {
+ createComponent({ isValid: false });
+
+ const label = findLabel();
+
+ expect(Boolean(label.attributes('state'))).toEqual(false);
+ expect(label.attributes('invalid-feedback')).toEqual(validationMessage);
+ });
+ });
+ });
});