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/registry')
-rw-r--r--spec/frontend/registry/explorer/components/details_page/details_header_spec.js103
-rw-r--r--spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js79
-rw-r--r--spec/frontend/registry/explorer/components/details_page/tags_list_spec.js218
-rw-r--r--spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js47
-rw-r--r--spec/frontend/registry/explorer/mock_data.js25
-rw-r--r--spec/frontend/registry/explorer/pages/details_spec.js107
-rw-r--r--spec/frontend/registry/settings/__snapshots__/utils_spec.js.snap101
-rw-r--r--spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap64
-rw-r--r--spec/frontend/registry/settings/components/expiration_dropdown_spec.js86
-rw-r--r--spec/frontend/registry/settings/components/expiration_input_spec.js169
-rw-r--r--spec/frontend/registry/settings/components/expiration_run_text_spec.js62
-rw-r--r--spec/frontend/registry/settings/components/expiration_toggle_spec.js77
-rw-r--r--spec/frontend/registry/settings/components/registry_settings_app_spec.js164
-rw-r--r--spec/frontend/registry/settings/components/settings_form_spec.js460
-rw-r--r--spec/frontend/registry/settings/graphql/cache_updated_spec.js56
-rw-r--r--spec/frontend/registry/settings/mock_data.js40
-rw-r--r--spec/frontend/registry/settings/utils_spec.js37
17 files changed, 392 insertions, 1503 deletions
diff --git a/spec/frontend/registry/explorer/components/details_page/details_header_spec.js b/spec/frontend/registry/explorer/components/details_page/details_header_spec.js
index b50ed87a563..632f506f4ae 100644
--- a/spec/frontend/registry/explorer/components/details_page/details_header_spec.js
+++ b/spec/frontend/registry/explorer/components/details_page/details_header_spec.js
@@ -1,7 +1,10 @@
import { GlButton, GlIcon } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import VueApollo from 'vue-apollo';
import { useFakeDate } from 'helpers/fake_date';
+import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import waitForPromises from 'helpers/wait_for_promises';
import component from '~/registry/explorer/components/details_page/details_header.vue';
import {
UNSCHEDULED_STATUS,
@@ -16,15 +19,18 @@ import {
ROOT_IMAGE_TEXT,
ROOT_IMAGE_TOOLTIP,
} from '~/registry/explorer/constants';
+import getContainerRepositoryTagCountQuery from '~/registry/explorer/graphql/queries/get_container_repository_tags_count.query.graphql';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
+import { imageTagsCountMock } from '../../mock_data';
describe('Details Header', () => {
let wrapper;
+ let apolloProvider;
+ let localVue;
const defaultImage = {
name: 'foo',
updatedAt: '2020-11-03T13:29:21Z',
- tagsCount: 10,
canDelete: true,
project: {
visibility: 'public',
@@ -51,12 +57,31 @@ describe('Details Header', () => {
await wrapper.vm.$nextTick();
};
- const mountComponent = (propsData = { image: defaultImage }) => {
+ const mountComponent = ({
+ propsData = { image: defaultImage },
+ resolver = jest.fn().mockResolvedValue(imageTagsCountMock()),
+ $apollo = undefined,
+ } = {}) => {
+ const mocks = {};
+
+ if ($apollo) {
+ mocks.$apollo = $apollo;
+ } else {
+ localVue = createLocalVue();
+ localVue.use(VueApollo);
+
+ const requestHandlers = [[getContainerRepositoryTagCountQuery, resolver]];
+ apolloProvider = createMockApollo(requestHandlers);
+ }
+
wrapper = shallowMount(component, {
+ localVue,
+ apolloProvider,
propsData,
directives: {
GlTooltip: createMockDirective(),
},
+ mocks,
stubs: {
TitleArea,
},
@@ -64,41 +89,48 @@ describe('Details Header', () => {
};
afterEach(() => {
+ // if we want to mix createMockApollo and manual mocks we need to reset everything
wrapper.destroy();
+ apolloProvider = undefined;
+ localVue = undefined;
wrapper = null;
});
+
describe('image name', () => {
describe('missing image name', () => {
- it('root image ', () => {
- mountComponent({ image: { ...defaultImage, name: '' } });
+ beforeEach(() => {
+ mountComponent({ propsData: { image: { ...defaultImage, name: '' } } });
+
+ return waitForPromises();
+ });
+ it('root image ', () => {
expect(findTitle().text()).toBe(ROOT_IMAGE_TEXT);
});
it('has an icon', () => {
- mountComponent({ image: { ...defaultImage, name: '' } });
-
expect(findInfoIcon().exists()).toBe(true);
expect(findInfoIcon().props('name')).toBe('information-o');
});
it('has a tooltip', () => {
- mountComponent({ image: { ...defaultImage, name: '' } });
-
const tooltip = getBinding(findInfoIcon().element, 'gl-tooltip');
expect(tooltip.value).toBe(ROOT_IMAGE_TOOLTIP);
});
});
describe('with image name present', () => {
- it('shows image.name ', () => {
+ beforeEach(() => {
mountComponent();
+
+ return waitForPromises();
+ });
+
+ it('shows image.name ', () => {
expect(findTitle().text()).toContain('foo');
});
it('has no icon', () => {
- mountComponent();
-
expect(findInfoIcon().exists()).toBe(false);
});
});
@@ -111,16 +143,10 @@ describe('Details Header', () => {
expect(findDeleteButton().exists()).toBe(true);
});
- it('is hidden while loading', () => {
- mountComponent({ image: defaultImage, metadataLoading: true });
-
- expect(findDeleteButton().exists()).toBe(false);
- });
-
it('has the correct text', () => {
mountComponent();
- expect(findDeleteButton().text()).toBe('Delete');
+ expect(findDeleteButton().text()).toBe('Delete image repository');
});
it('has the correct props', () => {
@@ -149,7 +175,7 @@ describe('Details Header', () => {
`(
'when canDelete is $canDelete and disabled is $disabled is $isDisabled that the button is disabled',
({ canDelete, disabled, isDisabled }) => {
- mountComponent({ image: { ...defaultImage, canDelete }, disabled });
+ mountComponent({ propsData: { image: { ...defaultImage, canDelete }, disabled } });
expect(findDeleteButton().props('disabled')).toBe(isDisabled);
},
@@ -158,15 +184,32 @@ describe('Details Header', () => {
describe('metadata items', () => {
describe('tags count', () => {
+ it('displays "-- tags" while loading', async () => {
+ // here we are forced to mock apollo because `waitForMetadataItems` waits
+ // for two ticks, de facto allowing the promise to resolve, so there is
+ // no way to catch the component as both rendered and in loading state
+ mountComponent({ $apollo: { queries: { containerRepository: { loading: true } } } });
+
+ await waitForMetadataItems();
+
+ expect(findTagsCount().props('text')).toBe('-- tags');
+ });
+
it('when there is more than one tag has the correct text', async () => {
mountComponent();
+
+ await waitForPromises();
await waitForMetadataItems();
- expect(findTagsCount().props('text')).toBe('10 tags');
+ expect(findTagsCount().props('text')).toBe('13 tags');
});
it('when there is one tag has the correct text', async () => {
- mountComponent({ image: { ...defaultImage, tagsCount: 1 } });
+ mountComponent({
+ resolver: jest.fn().mockResolvedValue(imageTagsCountMock({ tagsCount: 1 })),
+ });
+
+ await waitForPromises();
await waitForMetadataItems();
expect(findTagsCount().props('text')).toBe('1 tag');
@@ -208,11 +251,13 @@ describe('Details Header', () => {
'when the status is $status the text is $text and the tooltip is $tooltip',
async ({ status, text, tooltip }) => {
mountComponent({
- image: {
- ...defaultImage,
- expirationPolicyCleanupStatus: status,
- project: {
- containerExpirationPolicy: { enabled: true, nextRunAt: '2021-01-03T14:29:21Z' },
+ propsData: {
+ image: {
+ ...defaultImage,
+ expirationPolicyCleanupStatus: status,
+ project: {
+ containerExpirationPolicy: { enabled: true, nextRunAt: '2021-01-03T14:29:21Z' },
+ },
},
},
});
@@ -242,7 +287,9 @@ describe('Details Header', () => {
expect(findLastUpdatedAndVisibility().props('icon')).toBe('eye');
});
it('shows an eye slashed when the project is not public', async () => {
- mountComponent({ image: { ...defaultImage, project: { visibility: 'private' } } });
+ mountComponent({
+ propsData: { image: { ...defaultImage, project: { visibility: 'private' } } },
+ });
await waitForMetadataItems();
expect(findLastUpdatedAndVisibility().props('icon')).toBe('eye-slash');
diff --git a/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js b/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js
index 8b70f84c1bd..dc9063bde2c 100644
--- a/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js
+++ b/spec/frontend/registry/explorer/components/details_page/tags_list_row_spec.js
@@ -1,5 +1,6 @@
import { GlFormCheckbox, GlSprintf, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+import { nextTick } from 'vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import DeleteButton from '~/registry/explorer/components/delete_button.vue';
@@ -72,8 +73,15 @@ describe('tags list row', () => {
expect(findCheckbox().exists()).toBe(false);
});
- it('is disabled when the digest is missing', () => {
- mountComponent({ tag: { ...tag, digest: null } });
+ it.each`
+ digest | disabled
+ ${'foo'} | ${true}
+ ${null} | ${false}
+ ${null} | ${true}
+ ${'foo'} | ${true}
+ `('is disabled when the digest $digest and disabled is $disabled', ({ digest, disabled }) => {
+ mountComponent({ tag: { ...tag, digest }, disabled });
+
expect(findCheckbox().attributes('disabled')).toBe('true');
});
@@ -141,6 +149,12 @@ describe('tags list row', () => {
title: tag.location,
});
});
+
+ it('is disabled when the component is disabled', () => {
+ mountComponent({ ...defaultProps, disabled: true });
+
+ expect(findClipboardButton().attributes('disabled')).toBe('true');
+ });
});
describe('warning icon', () => {
@@ -266,15 +280,19 @@ describe('tags list row', () => {
});
it.each`
- canDelete | digest
- ${true} | ${null}
- ${false} | ${'foo'}
- ${false} | ${null}
- `('is disabled when canDelete is $canDelete and digest is $digest', ({ canDelete, digest }) => {
- mountComponent({ ...defaultProps, tag: { ...tag, canDelete, digest } });
-
- expect(findDeleteButton().attributes('disabled')).toBe('true');
- });
+ canDelete | digest | disabled
+ ${true} | ${null} | ${true}
+ ${false} | ${'foo'} | ${true}
+ ${false} | ${null} | ${true}
+ ${true} | ${'foo'} | ${true}
+ `(
+ 'is disabled when canDelete is $canDelete and digest is $digest and disabled is $disabled',
+ ({ canDelete, digest, disabled }) => {
+ mountComponent({ ...defaultProps, tag: { ...tag, canDelete, digest }, disabled });
+
+ expect(findDeleteButton().attributes('disabled')).toBe('true');
+ },
+ );
it('delete event emits delete', () => {
mountComponent();
@@ -287,13 +305,10 @@ describe('tags list row', () => {
describe('details rows', () => {
describe('when the tag has a digest', () => {
- beforeEach(() => {
+ it('has 3 details rows', async () => {
mountComponent();
+ await nextTick();
- return wrapper.vm.$nextTick();
- });
-
- it('has 3 details rows', () => {
expect(findDetailsRows().length).toBe(3);
});
@@ -303,17 +318,37 @@ describe('tags list row', () => {
${'manifest detail'} | ${findManifestDetail} | ${'Manifest digest: sha256:2cf3d2fdac1b04a14301d47d51cb88dcd26714c74f91440eeee99ce399089062'} | ${'log'} | ${true}
${'configuration detail'} | ${findConfigurationDetail} | ${'Configuration digest: sha256:c2613843ab33aabf847965442b13a8b55a56ae28837ce182627c0716eb08c02b'} | ${'cloud-gear'} | ${true}
`('$name details row', ({ finderFunction, text, icon, clipboard }) => {
- it(`has ${text} as text`, () => {
+ it(`has ${text} as text`, async () => {
+ mountComponent();
+ await nextTick();
+
expect(finderFunction().text()).toMatchInterpolatedText(text);
});
- it(`has the ${icon} icon`, () => {
+ it(`has the ${icon} icon`, async () => {
+ mountComponent();
+ await nextTick();
+
expect(finderFunction().props('icon')).toBe(icon);
});
- it(`is ${clipboard} that clipboard button exist`, () => {
- expect(finderFunction().find(ClipboardButton).exists()).toBe(clipboard);
- });
+ if (clipboard) {
+ it(`clipboard button exist`, async () => {
+ mountComponent();
+ await nextTick();
+
+ expect(finderFunction().find(ClipboardButton).exists()).toBe(clipboard);
+ });
+
+ it('is disabled when the component is disabled', async () => {
+ mountComponent({ ...defaultProps, disabled: true });
+ await nextTick();
+
+ expect(finderFunction().findComponent(ClipboardButton).attributes('disabled')).toBe(
+ 'true',
+ );
+ });
+ }
});
});
@@ -321,7 +356,7 @@ describe('tags list row', () => {
it('hides the details rows', async () => {
mountComponent({ tag: { ...tag, digest: null } });
- await wrapper.vm.$nextTick();
+ await nextTick();
expect(findDetailsRows().length).toBe(0);
});
});
diff --git a/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js
index dc6760a17bd..51934cd074d 100644
--- a/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js
+++ b/spec/frontend/registry/explorer/components/details_page/tags_list_spec.js
@@ -1,22 +1,55 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
+import { GlButton, GlKeysetPagination } from '@gitlab/ui';
+import { shallowMount, createLocalVue } from '@vue/test-utils';
+import { nextTick } from 'vue';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import EmptyTagsState from '~/registry/explorer/components/details_page/empty_state.vue';
import component from '~/registry/explorer/components/details_page/tags_list.vue';
import TagsListRow from '~/registry/explorer/components/details_page/tags_list_row.vue';
+import TagsLoader from '~/registry/explorer/components/details_page/tags_loader.vue';
import { TAGS_LIST_TITLE, REMOVE_TAGS_BUTTON_TITLE } from '~/registry/explorer/constants/index';
-import { tagsMock } from '../../mock_data';
+import getContainerRepositoryTagsQuery from '~/registry/explorer/graphql/queries/get_container_repository_tags.query.graphql';
+import { tagsMock, imageTagsMock, tagsPageInfo } from '../../mock_data';
+
+const localVue = createLocalVue();
describe('Tags List', () => {
let wrapper;
+ let apolloProvider;
const tags = [...tagsMock];
const readOnlyTags = tags.map((t) => ({ ...t, canDelete: false }));
const findTagsListRow = () => wrapper.findAll(TagsListRow);
const findDeleteButton = () => wrapper.find(GlButton);
const findListTitle = () => wrapper.find('[data-testid="list-title"]');
+ const findPagination = () => wrapper.find(GlKeysetPagination);
+ const findEmptyState = () => wrapper.find(EmptyTagsState);
+ const findTagsLoader = () => wrapper.find(TagsLoader);
+
+ const waitForApolloRequestRender = async () => {
+ await waitForPromises();
+ await nextTick();
+ };
+
+ const mountComponent = ({
+ propsData = { isMobile: false, id: 1 },
+ resolver = jest.fn().mockResolvedValue(imageTagsMock()),
+ } = {}) => {
+ localVue.use(VueApollo);
+
+ const requestHandlers = [[getContainerRepositoryTagsQuery, resolver]];
- const mountComponent = (propsData = { tags, isMobile: false }) => {
+ apolloProvider = createMockApollo(requestHandlers);
wrapper = shallowMount(component, {
+ localVue,
+ apolloProvider,
propsData,
+ provide() {
+ return {
+ config: {},
+ };
+ },
});
};
@@ -26,15 +59,19 @@ describe('Tags List', () => {
});
describe('List title', () => {
- it('exists', () => {
+ it('exists', async () => {
mountComponent();
+ await waitForApolloRequestRender();
+
expect(findListTitle().exists()).toBe(true);
});
- it('has the correct text', () => {
+ it('has the correct text', async () => {
mountComponent();
+ await waitForApolloRequestRender();
+
expect(findListTitle().text()).toBe(TAGS_LIST_TITLE);
});
});
@@ -48,21 +85,29 @@ describe('Tags List', () => {
${readOnlyTags} | ${true} | ${false}
`(
'is $isVisible that delete button exists when tags is $inputTags and isMobile is $isMobile',
- ({ inputTags, isMobile, isVisible }) => {
- mountComponent({ tags: inputTags, isMobile });
+ async ({ inputTags, isMobile, isVisible }) => {
+ mountComponent({
+ propsData: { tags: inputTags, isMobile, id: 1 },
+ resolver: jest.fn().mockResolvedValue(imageTagsMock(inputTags)),
+ });
+
+ await waitForApolloRequestRender();
expect(findDeleteButton().exists()).toBe(isVisible);
},
);
- it('has the correct text', () => {
+ it('has the correct text', async () => {
mountComponent();
+ await waitForApolloRequestRender();
+
expect(findDeleteButton().text()).toBe(REMOVE_TAGS_BUTTON_TITLE);
});
- it('has the correct props', () => {
+ it('has the correct props', async () => {
mountComponent();
+ await waitForApolloRequestRender();
expect(findDeleteButton().attributes()).toMatchObject({
category: 'secondary',
@@ -79,35 +124,44 @@ describe('Tags List', () => {
`(
'is $buttonDisabled that the button is disabled when the component disabled state is $disabled and is $doSelect that the user selected a tag',
async ({ disabled, buttonDisabled, doSelect }) => {
- mountComponent({ tags, disabled, isMobile: false });
+ mountComponent({ propsData: { tags, disabled, isMobile: false, id: 1 } });
+
+ await waitForApolloRequestRender();
if (doSelect) {
findTagsListRow().at(0).vm.$emit('select');
- await wrapper.vm.$nextTick();
+ await nextTick();
}
expect(findDeleteButton().attributes('disabled')).toBe(buttonDisabled);
},
);
- it('click event emits a deleted event with selected items', () => {
+ it('click event emits a deleted event with selected items', async () => {
mountComponent();
- findTagsListRow().at(0).vm.$emit('select');
+ await waitForApolloRequestRender();
+
+ findTagsListRow().at(0).vm.$emit('select');
findDeleteButton().vm.$emit('click');
- expect(wrapper.emitted('delete')).toEqual([[{ 'beta-24753': true }]]);
+
+ expect(wrapper.emitted('delete')[0][0][0].name).toBe(tags[0].name);
});
});
describe('list rows', () => {
- it('one row exist for each tag', () => {
+ it('one row exist for each tag', async () => {
mountComponent();
+ await waitForApolloRequestRender();
+
expect(findTagsListRow()).toHaveLength(tags.length);
});
- it('the correct props are bound to it', () => {
- mountComponent({ tags, disabled: true });
+ it('the correct props are bound to it', async () => {
+ mountComponent({ propsData: { disabled: true, id: 1 } });
+
+ await waitForApolloRequestRender();
const rows = findTagsListRow();
@@ -120,16 +174,138 @@ describe('Tags List', () => {
describe('events', () => {
it('select event update the selected items', async () => {
mountComponent();
+
+ await waitForApolloRequestRender();
+
findTagsListRow().at(0).vm.$emit('select');
- await wrapper.vm.$nextTick();
+
+ await nextTick();
+
expect(findTagsListRow().at(0).attributes('selected')).toBe('true');
});
- it('delete event emit a delete event', () => {
+ it('delete event emit a delete event', async () => {
mountComponent();
+
+ await waitForApolloRequestRender();
+
findTagsListRow().at(0).vm.$emit('delete');
- expect(wrapper.emitted('delete')).toEqual([[{ 'beta-24753': true }]]);
+ expect(wrapper.emitted('delete')[0][0][0].name).toBe(tags[0].name);
+ });
+ });
+ });
+
+ describe('when the list of tags is empty', () => {
+ const resolver = jest.fn().mockResolvedValue(imageTagsMock([]));
+
+ it('has the empty state', async () => {
+ mountComponent({ resolver });
+
+ await waitForApolloRequestRender();
+
+ expect(findEmptyState().exists()).toBe(true);
+ });
+
+ it('does not show the loader', async () => {
+ mountComponent({ resolver });
+
+ await waitForApolloRequestRender();
+
+ expect(findTagsLoader().exists()).toBe(false);
+ });
+
+ it('does not show the list', async () => {
+ mountComponent({ resolver });
+
+ await waitForApolloRequestRender();
+
+ expect(findTagsListRow().exists()).toBe(false);
+ expect(findListTitle().exists()).toBe(false);
+ });
+ });
+
+ describe('pagination', () => {
+ it('exists', async () => {
+ mountComponent();
+
+ await waitForApolloRequestRender();
+
+ expect(findPagination().exists()).toBe(true);
+ });
+
+ it('is hidden when loading', () => {
+ mountComponent();
+
+ expect(findPagination().exists()).toBe(false);
+ });
+
+ it('is hidden when there are no more pages', async () => {
+ mountComponent({ resolver: jest.fn().mockResolvedValue(imageTagsMock([])) });
+
+ await waitForApolloRequestRender();
+
+ expect(findPagination().exists()).toBe(false);
+ });
+
+ it('is wired to the correct pagination props', async () => {
+ mountComponent();
+
+ await waitForApolloRequestRender();
+
+ expect(findPagination().props()).toMatchObject({
+ hasNextPage: tagsPageInfo.hasNextPage,
+ hasPreviousPage: tagsPageInfo.hasPreviousPage,
});
});
+
+ it('fetch next page when user clicks next', async () => {
+ const resolver = jest.fn().mockResolvedValue(imageTagsMock());
+ mountComponent({ resolver });
+
+ await waitForApolloRequestRender();
+
+ findPagination().vm.$emit('next');
+
+ expect(resolver).toHaveBeenCalledWith(
+ expect.objectContaining({ after: tagsPageInfo.endCursor }),
+ );
+ });
+
+ it('fetch previous page when user clicks prev', async () => {
+ const resolver = jest.fn().mockResolvedValue(imageTagsMock());
+ mountComponent({ resolver });
+
+ await waitForApolloRequestRender();
+
+ findPagination().vm.$emit('prev');
+
+ expect(resolver).toHaveBeenCalledWith(
+ expect.objectContaining({ first: null, before: tagsPageInfo.startCursor }),
+ );
+ });
+ });
+
+ describe('loading state', () => {
+ it.each`
+ isImageLoading | queryExecuting | loadingVisible
+ ${true} | ${true} | ${true}
+ ${true} | ${false} | ${true}
+ ${false} | ${true} | ${true}
+ ${false} | ${false} | ${false}
+ `(
+ 'when the isImageLoading is $isImageLoading, and is $queryExecuting that the query is still executing is $loadingVisible that the loader is shown',
+ async ({ isImageLoading, queryExecuting, loadingVisible }) => {
+ mountComponent({ propsData: { isImageLoading, isMobile: false, id: 1 } });
+
+ if (!queryExecuting) {
+ await waitForApolloRequestRender();
+ }
+
+ expect(findTagsLoader().exists()).toBe(loadingVisible);
+ expect(findTagsListRow().exists()).toBe(!loadingVisible);
+ expect(findListTitle().exists()).toBe(!loadingVisible);
+ expect(findPagination().exists()).toBe(!loadingVisible);
+ },
+ );
});
});
diff --git a/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
index 6c897b983f7..323d7b177e7 100644
--- a/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
+++ b/spec/frontend/registry/explorer/components/list_page/image_list_row_spec.js
@@ -25,10 +25,11 @@ describe('Image List Row', () => {
const findDetailsLink = () => wrapper.find('[data-testid="details-link"]');
const findTagsCount = () => wrapper.find('[data-testid="tags-count"]');
- const findDeleteBtn = () => wrapper.find(DeleteButton);
- const findClipboardButton = () => wrapper.find(ClipboardButton);
+ const findDeleteBtn = () => wrapper.findComponent(DeleteButton);
+ const findClipboardButton = () => wrapper.findComponent(ClipboardButton);
const findWarningIcon = () => wrapper.find('[data-testid="warning-icon"]');
- const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
+ const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
+ const findListItemComponent = () => wrapper.findComponent(ListItem);
const mountComponent = (props) => {
wrapper = shallowMount(Component, {
@@ -52,20 +53,28 @@ describe('Image List Row', () => {
wrapper = null;
});
- describe('main tooltip', () => {
- it(`the title is ${ROW_SCHEDULED_FOR_DELETION}`, () => {
- mountComponent();
+ describe('list item component', () => {
+ describe('tooltip', () => {
+ it(`the title is ${ROW_SCHEDULED_FOR_DELETION}`, () => {
+ mountComponent();
+
+ const tooltip = getBinding(wrapper.element, 'gl-tooltip');
+ expect(tooltip).toBeDefined();
+ expect(tooltip.value.title).toBe(ROW_SCHEDULED_FOR_DELETION);
+ });
- const tooltip = getBinding(wrapper.element, 'gl-tooltip');
- expect(tooltip).toBeDefined();
- expect(tooltip.value.title).toBe(ROW_SCHEDULED_FOR_DELETION);
+ it('is disabled when item is being deleted', () => {
+ mountComponent({ item: { ...item, status: IMAGE_DELETE_SCHEDULED_STATUS } });
+
+ const tooltip = getBinding(wrapper.element, 'gl-tooltip');
+ expect(tooltip.value.disabled).toBe(false);
+ });
});
- it('is disabled when item is being deleted', () => {
+ it('is disabled when the item is in deleting status', () => {
mountComponent({ item: { ...item, status: IMAGE_DELETE_SCHEDULED_STATUS } });
- const tooltip = getBinding(wrapper.element, 'gl-tooltip');
- expect(tooltip.value.disabled).toBe(false);
+ expect(findListItemComponent().props('disabled')).toBe(true);
});
});
@@ -118,6 +127,20 @@ describe('Image List Row', () => {
},
);
});
+
+ describe('when the item is deleting', () => {
+ beforeEach(() => {
+ mountComponent({ item: { ...item, status: IMAGE_DELETE_SCHEDULED_STATUS } });
+ });
+
+ it('the router link is disabled', () => {
+ // we check the event prop as is the only workaround to disable a router link
+ expect(findDetailsLink().props('event')).toBe('');
+ });
+ it('the clipboard button is disabled', () => {
+ expect(findClipboardButton().attributes('disabled')).toBe('true');
+ });
+ });
});
describe('delete button', () => {
diff --git a/spec/frontend/registry/explorer/mock_data.js b/spec/frontend/registry/explorer/mock_data.js
index f4453912db4..fe258dcd4e8 100644
--- a/spec/frontend/registry/explorer/mock_data.js
+++ b/spec/frontend/registry/explorer/mock_data.js
@@ -113,7 +113,6 @@ export const containerRepositoryMock = {
canDelete: true,
createdAt: '2020-11-03T13:29:21Z',
updatedAt: '2020-11-03T13:29:21Z',
- tagsCount: 13,
expirationPolicyStartedAt: null,
expirationPolicyCleanupStatus: 'UNSCHEDULED',
project: {
@@ -161,6 +160,30 @@ export const tagsMock = [
},
];
+export const imageTagsMock = (nodes = tagsMock) => ({
+ data: {
+ containerRepository: {
+ id: containerRepositoryMock.id,
+ tags: {
+ nodes,
+ pageInfo: { ...tagsPageInfo },
+ __typename: 'ContainerRepositoryTagConnection',
+ },
+ __typename: 'ContainerRepositoryDetails',
+ },
+ },
+});
+
+export const imageTagsCountMock = (override) => ({
+ data: {
+ containerRepository: {
+ id: containerRepositoryMock.id,
+ tagsCount: 13,
+ ...override,
+ },
+ },
+});
+
export const graphQLImageDetailsMock = (override) => ({
data: {
containerRepository: {
diff --git a/spec/frontend/registry/explorer/pages/details_spec.js b/spec/frontend/registry/explorer/pages/details_spec.js
index 76baf4f72c9..022f6e71fe6 100644
--- a/spec/frontend/registry/explorer/pages/details_spec.js
+++ b/spec/frontend/registry/explorer/pages/details_spec.js
@@ -28,12 +28,10 @@ import Tracking from '~/tracking';
import {
graphQLImageDetailsMock,
- graphQLImageDetailsEmptyTagsMock,
graphQLDeleteImageRepositoryTagsMock,
containerRepositoryMock,
graphQLEmptyImageDetailsMock,
tagsMock,
- tagsPageInfo,
} from '../mock_data';
import { DeleteModal } from '../stubs';
@@ -72,12 +70,6 @@ describe('Details Page', () => {
await wrapper.vm.$nextTick();
};
- const tagsArrayToSelectedTags = (tags) =>
- tags.reduce((acc, c) => {
- acc[c.name] = true;
- return acc;
- }, {});
-
const mountComponent = ({
resolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock()),
mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock),
@@ -138,12 +130,6 @@ describe('Details Page', () => {
expect(findTagsList().exists()).toBe(false);
});
-
- it('does not show pagination', () => {
- mountComponent();
-
- expect(findPagination().exists()).toBe(false);
- });
});
describe('when the image does not exist', () => {
@@ -167,34 +153,6 @@ describe('Details Page', () => {
});
});
- describe('when the list of tags is empty', () => {
- const resolver = jest.fn().mockResolvedValue(graphQLImageDetailsEmptyTagsMock);
-
- it('has the empty state', async () => {
- mountComponent({ resolver });
-
- await waitForApolloRequestRender();
-
- expect(findEmptyState().exists()).toBe(true);
- });
-
- it('does not show the loader', async () => {
- mountComponent({ resolver });
-
- await waitForApolloRequestRender();
-
- expect(findTagsLoader().exists()).toBe(false);
- });
-
- it('does not show the list', async () => {
- mountComponent({ resolver });
-
- await waitForApolloRequestRender();
-
- expect(findTagsList().exists()).toBe(false);
- });
- });
-
describe('list', () => {
it('exists', async () => {
mountComponent();
@@ -211,7 +169,6 @@ describe('Details Page', () => {
expect(findTagsList().props()).toMatchObject({
isMobile: false,
- tags: cleanTags,
});
});
@@ -224,7 +181,7 @@ describe('Details Page', () => {
await waitForApolloRequestRender();
[tagToBeDeleted] = cleanTags;
- findTagsList().vm.$emit('delete', { [tagToBeDeleted.name]: true });
+ findTagsList().vm.$emit('delete', [tagToBeDeleted]);
});
it('open the modal', async () => {
@@ -244,7 +201,7 @@ describe('Details Page', () => {
await waitForApolloRequestRender();
- findTagsList().vm.$emit('delete', tagsArrayToSelectedTags(cleanTags));
+ findTagsList().vm.$emit('delete', cleanTags);
});
it('open the modal', () => {
@@ -260,61 +217,6 @@ describe('Details Page', () => {
});
});
- describe('pagination', () => {
- it('exists', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findPagination().exists()).toBe(true);
- });
-
- it('is hidden when there are no more pages', async () => {
- mountComponent({ resolver: jest.fn().mockResolvedValue(graphQLImageDetailsEmptyTagsMock) });
-
- await waitForApolloRequestRender();
-
- expect(findPagination().exists()).toBe(false);
- });
-
- it('is wired to the correct pagination props', async () => {
- mountComponent();
-
- await waitForApolloRequestRender();
-
- expect(findPagination().props()).toMatchObject({
- hasNextPage: tagsPageInfo.hasNextPage,
- hasPreviousPage: tagsPageInfo.hasPreviousPage,
- });
- });
-
- it('fetch next page when user clicks next', async () => {
- const resolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock());
- mountComponent({ resolver });
-
- await waitForApolloRequestRender();
-
- findPagination().vm.$emit('next');
-
- expect(resolver).toHaveBeenCalledWith(
- expect.objectContaining({ after: tagsPageInfo.endCursor }),
- );
- });
-
- it('fetch previous page when user clicks prev', async () => {
- const resolver = jest.fn().mockResolvedValue(graphQLImageDetailsMock());
- mountComponent({ resolver });
-
- await waitForApolloRequestRender();
-
- findPagination().vm.$emit('prev');
-
- expect(resolver).toHaveBeenCalledWith(
- expect.objectContaining({ first: null, before: tagsPageInfo.startCursor }),
- );
- });
- });
-
describe('modal', () => {
it('exists', async () => {
mountComponent();
@@ -349,7 +251,7 @@ describe('Details Page', () => {
});
describe('when one item is selected to be deleted', () => {
it('calls apollo mutation with the right parameters', async () => {
- findTagsList().vm.$emit('delete', { [cleanTags[0].name]: true });
+ findTagsList().vm.$emit('delete', [cleanTags[0]]);
await wrapper.vm.$nextTick();
@@ -363,7 +265,7 @@ describe('Details Page', () => {
describe('when more than one item is selected to be deleted', () => {
it('calls apollo mutation with the right parameters', async () => {
- findTagsList().vm.$emit('delete', { ...tagsArrayToSelectedTags(tagsMock) });
+ findTagsList().vm.$emit('delete', tagsMock);
await wrapper.vm.$nextTick();
@@ -390,7 +292,6 @@ describe('Details Page', () => {
await waitForApolloRequestRender();
expect(findDetailsHeader().props()).toMatchObject({
- metadataLoading: false,
image: {
name: containerRepositoryMock.name,
project: {
diff --git a/spec/frontend/registry/settings/__snapshots__/utils_spec.js.snap b/spec/frontend/registry/settings/__snapshots__/utils_spec.js.snap
deleted file mode 100644
index 7062773b46b..00000000000
--- a/spec/frontend/registry/settings/__snapshots__/utils_spec.js.snap
+++ /dev/null
@@ -1,101 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Utils formOptionsGenerator returns an object containing cadence 1`] = `
-Array [
- Object {
- "default": true,
- "key": "EVERY_DAY",
- "label": "Every day",
- },
- Object {
- "default": false,
- "key": "EVERY_WEEK",
- "label": "Every week",
- },
- Object {
- "default": false,
- "key": "EVERY_TWO_WEEKS",
- "label": "Every two weeks",
- },
- Object {
- "default": false,
- "key": "EVERY_MONTH",
- "label": "Every month",
- },
- Object {
- "default": false,
- "key": "EVERY_THREE_MONTHS",
- "label": "Every three months",
- },
-]
-`;
-
-exports[`Utils formOptionsGenerator returns an object containing keepN 1`] = `
-Array [
- Object {
- "default": false,
- "key": "ONE_TAG",
- "label": "1 tag per image name",
- "variable": 1,
- },
- Object {
- "default": false,
- "key": "FIVE_TAGS",
- "label": "5 tags per image name",
- "variable": 5,
- },
- Object {
- "default": true,
- "key": "TEN_TAGS",
- "label": "10 tags per image name",
- "variable": 10,
- },
- Object {
- "default": false,
- "key": "TWENTY_FIVE_TAGS",
- "label": "25 tags per image name",
- "variable": 25,
- },
- Object {
- "default": false,
- "key": "FIFTY_TAGS",
- "label": "50 tags per image name",
- "variable": 50,
- },
- Object {
- "default": false,
- "key": "ONE_HUNDRED_TAGS",
- "label": "100 tags per image name",
- "variable": 100,
- },
-]
-`;
-
-exports[`Utils formOptionsGenerator returns an object containing olderThan 1`] = `
-Array [
- Object {
- "default": false,
- "key": "SEVEN_DAYS",
- "label": "7 days",
- "variable": 7,
- },
- Object {
- "default": false,
- "key": "FOURTEEN_DAYS",
- "label": "14 days",
- "variable": 14,
- },
- Object {
- "default": false,
- "key": "THIRTY_DAYS",
- "label": "30 days",
- "variable": 30,
- },
- Object {
- "default": true,
- "key": "NINETY_DAYS",
- "label": "90 days",
- "variable": 90,
- },
-]
-`;
diff --git a/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap b/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
deleted file mode 100644
index 7a52b4a5d0f..00000000000
--- a/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
+++ /dev/null
@@ -1,64 +0,0 @@
-// Jest Snapshot v1, https://goo.gl/fbAQLP
-
-exports[`Settings Form Cadence matches snapshot 1`] = `
-<expiration-dropdown-stub
- class="gl-mr-7 gl-mb-0!"
- data-testid="cadence-dropdown"
- formoptions="[object Object],[object Object],[object Object],[object Object],[object Object]"
- label="Run cleanup:"
- name="cadence"
- value="EVERY_DAY"
-/>
-`;
-
-exports[`Settings Form Enable matches snapshot 1`] = `
-<expiration-toggle-stub
- class="gl-mb-0!"
- data-testid="enable-toggle"
- value="true"
-/>
-`;
-
-exports[`Settings Form Keep N matches snapshot 1`] = `
-<expiration-dropdown-stub
- data-testid="keep-n-dropdown"
- formoptions="[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]"
- label="Keep the most recent:"
- name="keep-n"
- value="TEN_TAGS"
-/>
-`;
-
-exports[`Settings Form Keep Regex matches snapshot 1`] = `
-<expiration-input-stub
- data-testid="keep-regex-input"
- description="Tags with names that match this regex pattern are kept. %{linkStart}View regex examples.%{linkEnd}"
- error=""
- label="Keep tags matching:"
- name="keep-regex"
- placeholder=""
- value="sss"
-/>
-`;
-
-exports[`Settings Form OlderThan matches snapshot 1`] = `
-<expiration-dropdown-stub
- data-testid="older-than-dropdown"
- formoptions="[object Object],[object Object],[object Object],[object Object]"
- label="Remove tags older than:"
- name="older-than"
- value="FOURTEEN_DAYS"
-/>
-`;
-
-exports[`Settings Form Remove regex matches snapshot 1`] = `
-<expiration-input-stub
- data-testid="remove-regex-input"
- description="Tags with names that match this regex pattern are removed. %{linkStart}View regex examples.%{linkEnd}"
- error=""
- label="Remove tags matching:"
- name="remove-regex"
- placeholder=".*"
- value="asdasdssssdfdf"
-/>
-`;
diff --git a/spec/frontend/registry/settings/components/expiration_dropdown_spec.js b/spec/frontend/registry/settings/components/expiration_dropdown_spec.js
deleted file mode 100644
index f777f7ec9de..00000000000
--- a/spec/frontend/registry/settings/components/expiration_dropdown_spec.js
+++ /dev/null
@@ -1,86 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { GlFormGroup, GlFormSelect } from 'jest/registry/shared/stubs';
-import component from '~/registry/settings/components/expiration_dropdown.vue';
-
-describe('ExpirationDropdown', () => {
- let wrapper;
-
- const defaultProps = {
- name: 'foo',
- label: 'label-bar',
- formOptions: [
- { key: 'foo', label: 'bar' },
- { key: 'baz', label: 'zab' },
- ],
- };
-
- const findFormSelect = () => wrapper.find(GlFormSelect);
- const findFormGroup = () => wrapper.find(GlFormGroup);
- const findOptions = () => wrapper.findAll('[data-testid="option"]');
-
- const mountComponent = (props) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlFormGroup,
- GlFormSelect,
- },
- propsData: {
- ...defaultProps,
- ...props,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('structure', () => {
- it('has a form-select component', () => {
- mountComponent();
- expect(findFormSelect().exists()).toBe(true);
- });
-
- it('has the correct options', () => {
- mountComponent();
-
- expect(findOptions()).toHaveLength(defaultProps.formOptions.length);
- });
- });
-
- describe('model', () => {
- it('assign the right props to the form-select component', () => {
- const value = 'foobar';
- const disabled = true;
-
- mountComponent({ value, disabled });
-
- expect(findFormSelect().props()).toMatchObject({
- value,
- disabled,
- });
- expect(findFormSelect().attributes('id')).toBe(defaultProps.name);
- });
-
- it('assign the right props to the form-group component', () => {
- mountComponent();
-
- expect(findFormGroup().attributes()).toMatchObject({
- id: `${defaultProps.name}-form-group`,
- 'label-for': defaultProps.name,
- label: defaultProps.label,
- });
- });
-
- it('emits input event when form-select emits input', () => {
- const emittedValue = 'barfoo';
-
- mountComponent();
-
- findFormSelect().vm.$emit('input', emittedValue);
-
- expect(wrapper.emitted('input')).toEqual([[emittedValue]]);
- });
- });
-});
diff --git a/spec/frontend/registry/settings/components/expiration_input_spec.js b/spec/frontend/registry/settings/components/expiration_input_spec.js
deleted file mode 100644
index b91599a2789..00000000000
--- a/spec/frontend/registry/settings/components/expiration_input_spec.js
+++ /dev/null
@@ -1,169 +0,0 @@
-import { GlSprintf, GlFormInput, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { GlFormGroup } from 'jest/registry/shared/stubs';
-import component from '~/registry/settings/components/expiration_input.vue';
-import { NAME_REGEX_LENGTH } from '~/registry/settings/constants';
-
-describe('ExpirationInput', () => {
- let wrapper;
-
- const defaultProps = {
- name: 'foo',
- label: 'label-bar',
- placeholder: 'placeholder-baz',
- description: '%{linkStart}description-foo%{linkEnd}',
- };
-
- const tagsRegexHelpPagePath = 'fooPath';
-
- const findInput = () => wrapper.find(GlFormInput);
- const findFormGroup = () => wrapper.find(GlFormGroup);
- const findLabel = () => wrapper.find('[data-testid="label"]');
- const findDescription = () => wrapper.find('[data-testid="description"]');
- const findDescriptionLink = () => wrapper.find(GlLink);
-
- const mountComponent = (props) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlSprintf,
- GlFormGroup,
- },
- provide: {
- tagsRegexHelpPagePath,
- },
- propsData: {
- ...defaultProps,
- ...props,
- },
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('structure', () => {
- it('has a label', () => {
- mountComponent();
-
- expect(findLabel().text()).toBe(defaultProps.label);
- });
-
- it('has a textarea component', () => {
- mountComponent();
-
- expect(findInput().exists()).toBe(true);
- });
-
- it('has a description', () => {
- mountComponent();
-
- expect(findDescription().text()).toMatchInterpolatedText(defaultProps.description);
- });
-
- it('has a description link', () => {
- mountComponent();
-
- const link = findDescriptionLink();
- expect(link.exists()).toBe(true);
- expect(link.attributes('href')).toBe(tagsRegexHelpPagePath);
- });
- });
-
- describe('model', () => {
- it('assigns the right props to the textarea component', () => {
- const value = 'foobar';
- const disabled = true;
-
- mountComponent({ value, disabled });
-
- expect(findInput().attributes()).toMatchObject({
- id: defaultProps.name,
- value,
- placeholder: defaultProps.placeholder,
- disabled: `${disabled}`,
- trim: '',
- });
- });
-
- it('emits input event when textarea emits input', () => {
- const emittedValue = 'barfoo';
-
- mountComponent();
-
- findInput().vm.$emit('input', emittedValue);
- expect(wrapper.emitted('input')).toEqual([[emittedValue]]);
- });
- });
-
- describe('regex textarea validation', () => {
- const invalidString = new Array(NAME_REGEX_LENGTH + 2).join(',');
-
- describe('when error contains an error message', () => {
- const errorMessage = 'something went wrong';
-
- it('shows the error message on the relevant field', () => {
- mountComponent({ error: errorMessage });
-
- expect(findFormGroup().attributes('invalid-feedback')).toBe(errorMessage);
- });
-
- it('gives precedence to API errors compared to local ones', () => {
- mountComponent({
- error: errorMessage,
- value: invalidString,
- });
-
- expect(findFormGroup().attributes('invalid-feedback')).toBe(errorMessage);
- });
- });
-
- describe('when error is empty', () => {
- describe('if the user did not type', () => {
- it('validation is not emitted', () => {
- mountComponent();
-
- expect(wrapper.emitted('validation')).toBeUndefined();
- });
-
- it('no error message is shown', () => {
- mountComponent();
-
- expect(findFormGroup().props('state')).toBe(true);
- expect(findFormGroup().attributes('invalid-feedback')).toBe('');
- });
- });
-
- describe('when the user typed something', () => {
- describe(`when name regex is longer than ${NAME_REGEX_LENGTH}`, () => {
- beforeEach(() => {
- // since the component has no state we both emit the event and set the prop
- mountComponent({ value: invalidString });
-
- findInput().vm.$emit('input', invalidString);
- });
-
- it('textAreaValidation state is false', () => {
- expect(findFormGroup().props('state')).toBe(false);
- expect(findInput().attributes('state')).toBeUndefined();
- });
-
- it('emits the @validation event with false payload', () => {
- expect(wrapper.emitted('validation')).toEqual([[false]]);
- });
- });
-
- it(`when user input is less than ${NAME_REGEX_LENGTH} state is "true"`, () => {
- mountComponent();
-
- findInput().vm.$emit('input', 'foo');
-
- expect(findFormGroup().props('state')).toBe(true);
- expect(findInput().attributes('state')).toBe('true');
- expect(wrapper.emitted('validation')).toEqual([[true]]);
- });
- });
- });
- });
-});
diff --git a/spec/frontend/registry/settings/components/expiration_run_text_spec.js b/spec/frontend/registry/settings/components/expiration_run_text_spec.js
deleted file mode 100644
index 753bb10ad08..00000000000
--- a/spec/frontend/registry/settings/components/expiration_run_text_spec.js
+++ /dev/null
@@ -1,62 +0,0 @@
-import { GlFormInput } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { GlFormGroup } from 'jest/registry/shared/stubs';
-import component from '~/registry/settings/components/expiration_run_text.vue';
-import { NEXT_CLEANUP_LABEL, NOT_SCHEDULED_POLICY_TEXT } from '~/registry/settings/constants';
-
-describe('ExpirationToggle', () => {
- let wrapper;
- const value = 'foo';
-
- const findInput = () => wrapper.find(GlFormInput);
- const findFormGroup = () => wrapper.find(GlFormGroup);
-
- const mountComponent = (propsData) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlFormGroup,
- },
- propsData,
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('structure', () => {
- it('has an input component', () => {
- mountComponent();
-
- expect(findInput().exists()).toBe(true);
- });
- });
-
- describe('model', () => {
- it('assigns the right props to the form-group component', () => {
- mountComponent();
-
- expect(findFormGroup().attributes()).toMatchObject({
- label: NEXT_CLEANUP_LABEL,
- });
- });
- });
-
- describe('formattedValue', () => {
- it.each`
- valueProp | enabled | expected
- ${value} | ${true} | ${value}
- ${value} | ${false} | ${NOT_SCHEDULED_POLICY_TEXT}
- ${undefined} | ${false} | ${NOT_SCHEDULED_POLICY_TEXT}
- ${undefined} | ${true} | ${NOT_SCHEDULED_POLICY_TEXT}
- `(
- 'when value is $valueProp and enabled is $enabled the input value is $expected',
- ({ valueProp, enabled, expected }) => {
- mountComponent({ value: valueProp, enabled });
-
- expect(findInput().attributes('value')).toBe(expected);
- },
- );
- });
-});
diff --git a/spec/frontend/registry/settings/components/expiration_toggle_spec.js b/spec/frontend/registry/settings/components/expiration_toggle_spec.js
deleted file mode 100644
index 7598f6adc89..00000000000
--- a/spec/frontend/registry/settings/components/expiration_toggle_spec.js
+++ /dev/null
@@ -1,77 +0,0 @@
-import { GlToggle, GlSprintf } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { GlFormGroup } from 'jest/registry/shared/stubs';
-import component from '~/registry/settings/components/expiration_toggle.vue';
-import {
- ENABLED_TOGGLE_DESCRIPTION,
- DISABLED_TOGGLE_DESCRIPTION,
-} from '~/registry/settings/constants';
-
-describe('ExpirationToggle', () => {
- let wrapper;
-
- const findToggle = () => wrapper.find(GlToggle);
- const findDescription = () => wrapper.find('[data-testid="description"]');
-
- const mountComponent = (propsData) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlFormGroup,
- GlSprintf,
- },
- propsData,
- });
- };
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- describe('structure', () => {
- it('has a toggle component', () => {
- mountComponent();
-
- expect(findToggle().props('label')).toBe(component.i18n.toggleLabel);
- });
-
- it('has a description', () => {
- mountComponent();
-
- expect(findDescription().exists()).toBe(true);
- });
- });
-
- describe('model', () => {
- it('assigns the right props to the toggle component', () => {
- mountComponent({ value: true, disabled: true });
-
- expect(findToggle().props()).toMatchObject({
- value: true,
- disabled: true,
- });
- });
-
- it('emits input event when toggle is updated', () => {
- mountComponent();
-
- findToggle().vm.$emit('change', false);
-
- expect(wrapper.emitted('input')).toEqual([[false]]);
- });
- });
-
- describe('toggle description', () => {
- it('says enabled when the toggle is on', () => {
- mountComponent({ value: true });
-
- expect(findDescription().text()).toMatchInterpolatedText(ENABLED_TOGGLE_DESCRIPTION);
- });
-
- it('says disabled when the toggle is off', () => {
- mountComponent({ value: false });
-
- expect(findDescription().text()).toMatchInterpolatedText(DISABLED_TOGGLE_DESCRIPTION);
- });
- });
-});
diff --git a/spec/frontend/registry/settings/components/registry_settings_app_spec.js b/spec/frontend/registry/settings/components/registry_settings_app_spec.js
deleted file mode 100644
index fd53efa884f..00000000000
--- a/spec/frontend/registry/settings/components/registry_settings_app_spec.js
+++ /dev/null
@@ -1,164 +0,0 @@
-import { GlAlert, GlSprintf, GlLink } from '@gitlab/ui';
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import component from '~/registry/settings/components/registry_settings_app.vue';
-import SettingsForm from '~/registry/settings/components/settings_form.vue';
-import {
- FETCH_SETTINGS_ERROR_MESSAGE,
- UNAVAILABLE_FEATURE_INTRO_TEXT,
- UNAVAILABLE_USER_FEATURE_TEXT,
-} from '~/registry/settings/constants';
-import expirationPolicyQuery from '~/registry/settings/graphql/queries/get_expiration_policy.query.graphql';
-
-import {
- expirationPolicyPayload,
- emptyExpirationPolicyPayload,
- containerExpirationPolicyData,
-} from '../mock_data';
-
-const localVue = createLocalVue();
-
-describe('Registry Settings App', () => {
- let wrapper;
- let fakeApollo;
-
- const defaultProvidedValues = {
- projectPath: 'path',
- isAdmin: false,
- adminSettingsPath: 'settingsPath',
- enableHistoricEntries: false,
- };
-
- const findSettingsComponent = () => wrapper.find(SettingsForm);
- const findAlert = () => wrapper.find(GlAlert);
-
- const mountComponent = (provide = defaultProvidedValues, config) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlSprintf,
- },
- mocks: {
- $toast: {
- show: jest.fn(),
- },
- },
- provide,
- ...config,
- });
- };
-
- const mountComponentWithApollo = ({ provide = defaultProvidedValues, resolver } = {}) => {
- localVue.use(VueApollo);
-
- const requestHandlers = [[expirationPolicyQuery, resolver]];
-
- fakeApollo = createMockApollo(requestHandlers);
- mountComponent(provide, {
- localVue,
- apolloProvider: fakeApollo,
- });
-
- return requestHandlers.map((request) => request[1]);
- };
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('isEdited status', () => {
- it.each`
- description | apiResponse | workingCopy | result
- ${'empty response and no changes from user'} | ${emptyExpirationPolicyPayload()} | ${{}} | ${false}
- ${'empty response and changes from user'} | ${emptyExpirationPolicyPayload()} | ${{ enabled: true }} | ${true}
- ${'response and no changes'} | ${expirationPolicyPayload()} | ${containerExpirationPolicyData()} | ${false}
- ${'response and changes'} | ${expirationPolicyPayload()} | ${{ ...containerExpirationPolicyData(), nameRegex: '12345' }} | ${true}
- ${'response and empty'} | ${expirationPolicyPayload()} | ${{}} | ${true}
- `('$description', async ({ apiResponse, workingCopy, result }) => {
- const requests = mountComponentWithApollo({
- provide: { ...defaultProvidedValues, enableHistoricEntries: true },
- resolver: jest.fn().mockResolvedValue(apiResponse),
- });
- await Promise.all(requests);
-
- findSettingsComponent().vm.$emit('input', workingCopy);
-
- await wrapper.vm.$nextTick();
-
- expect(findSettingsComponent().props('isEdited')).toBe(result);
- });
- });
-
- it('renders the setting form', async () => {
- const requests = mountComponentWithApollo({
- resolver: jest.fn().mockResolvedValue(expirationPolicyPayload()),
- });
- await Promise.all(requests);
-
- expect(findSettingsComponent().exists()).toBe(true);
- });
-
- describe('the form is disabled', () => {
- it('the form is hidden', () => {
- mountComponent();
-
- expect(findSettingsComponent().exists()).toBe(false);
- });
-
- it('shows an alert', () => {
- mountComponent();
-
- const text = findAlert().text();
- expect(text).toContain(UNAVAILABLE_FEATURE_INTRO_TEXT);
- expect(text).toContain(UNAVAILABLE_USER_FEATURE_TEXT);
- });
-
- describe('an admin is visiting the page', () => {
- it('shows the admin part of the alert message', () => {
- mountComponent({ ...defaultProvidedValues, isAdmin: true });
-
- const sprintf = findAlert().find(GlSprintf);
- expect(sprintf.text()).toBe('administration settings');
- expect(sprintf.find(GlLink).attributes('href')).toBe(
- defaultProvidedValues.adminSettingsPath,
- );
- });
- });
- });
-
- describe('fetchSettingsError', () => {
- beforeEach(() => {
- const requests = mountComponentWithApollo({
- resolver: jest.fn().mockRejectedValue(new Error('GraphQL error')),
- });
- return Promise.all(requests);
- });
-
- it('the form is hidden', () => {
- expect(findSettingsComponent().exists()).toBe(false);
- });
-
- it('shows an alert', () => {
- expect(findAlert().html()).toContain(FETCH_SETTINGS_ERROR_MESSAGE);
- });
- });
-
- describe('empty API response', () => {
- it.each`
- enableHistoricEntries | isShown
- ${true} | ${true}
- ${false} | ${false}
- `('is $isShown that the form is shown', async ({ enableHistoricEntries, isShown }) => {
- const requests = mountComponentWithApollo({
- provide: {
- ...defaultProvidedValues,
- enableHistoricEntries,
- },
- resolver: jest.fn().mockResolvedValue(emptyExpirationPolicyPayload()),
- });
- await Promise.all(requests);
-
- expect(findSettingsComponent().exists()).toBe(isShown);
- });
- });
-});
diff --git a/spec/frontend/registry/settings/components/settings_form_spec.js b/spec/frontend/registry/settings/components/settings_form_spec.js
deleted file mode 100644
index ad94da6ca66..00000000000
--- a/spec/frontend/registry/settings/components/settings_form_spec.js
+++ /dev/null
@@ -1,460 +0,0 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import component from '~/registry/settings/components/settings_form.vue';
-import {
- UPDATE_SETTINGS_ERROR_MESSAGE,
- UPDATE_SETTINGS_SUCCESS_MESSAGE,
-} from '~/registry/settings/constants';
-import updateContainerExpirationPolicyMutation from '~/registry/settings/graphql/mutations/update_container_expiration_policy.mutation.graphql';
-import expirationPolicyQuery from '~/registry/settings/graphql/queries/get_expiration_policy.query.graphql';
-import Tracking from '~/tracking';
-import { GlCard, GlLoadingIcon } from '../../shared/stubs';
-import { expirationPolicyPayload, expirationPolicyMutationPayload } from '../mock_data';
-
-const localVue = createLocalVue();
-
-describe('Settings Form', () => {
- let wrapper;
- let fakeApollo;
-
- const defaultProvidedValues = {
- projectPath: 'path',
- };
-
- const {
- data: {
- project: { containerExpirationPolicy },
- },
- } = expirationPolicyPayload();
-
- const defaultProps = {
- value: { ...containerExpirationPolicy },
- };
-
- const trackingPayload = {
- label: 'docker_container_retention_and_expiration_policies',
- };
-
- const findForm = () => wrapper.find({ ref: 'form-element' });
-
- const findCancelButton = () => wrapper.find('[data-testid="cancel-button"');
- const findSaveButton = () => wrapper.find('[data-testid="save-button"');
- const findEnableToggle = () => wrapper.find('[data-testid="enable-toggle"]');
- const findCadenceDropdown = () => wrapper.find('[data-testid="cadence-dropdown"]');
- const findKeepNDropdown = () => wrapper.find('[data-testid="keep-n-dropdown"]');
- const findKeepRegexInput = () => wrapper.find('[data-testid="keep-regex-input"]');
- const findOlderThanDropdown = () => wrapper.find('[data-testid="older-than-dropdown"]');
- const findRemoveRegexInput = () => wrapper.find('[data-testid="remove-regex-input"]');
-
- const mountComponent = ({
- props = defaultProps,
- data,
- config,
- provide = defaultProvidedValues,
- mocks,
- } = {}) => {
- wrapper = shallowMount(component, {
- stubs: {
- GlCard,
- GlLoadingIcon,
- },
- propsData: { ...props },
- provide,
- data() {
- return {
- ...data,
- };
- },
- mocks: {
- $toast: {
- show: jest.fn(),
- },
- ...mocks,
- },
- ...config,
- });
- };
-
- const mountComponentWithApollo = ({
- provide = defaultProvidedValues,
- mutationResolver,
- queryPayload = expirationPolicyPayload(),
- } = {}) => {
- localVue.use(VueApollo);
-
- const requestHandlers = [
- [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,
- },
- ...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,
- },
- });
- };
-
- beforeEach(() => {
- jest.spyOn(Tracking, 'event');
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe.each`
- model | finder | fieldName | type | defaultValue
- ${'enabled'} | ${findEnableToggle} | ${'Enable'} | ${'toggle'} | ${false}
- ${'cadence'} | ${findCadenceDropdown} | ${'Cadence'} | ${'dropdown'} | ${'EVERY_DAY'}
- ${'keepN'} | ${findKeepNDropdown} | ${'Keep N'} | ${'dropdown'} | ${'TEN_TAGS'}
- ${'nameRegexKeep'} | ${findKeepRegexInput} | ${'Keep Regex'} | ${'textarea'} | ${''}
- ${'olderThan'} | ${findOlderThanDropdown} | ${'OlderThan'} | ${'dropdown'} | ${'NINETY_DAYS'}
- ${'nameRegex'} | ${findRemoveRegexInput} | ${'Remove regex'} | ${'textarea'} | ${''}
- `('$fieldName', ({ model, finder, type, defaultValue }) => {
- it('matches snapshot', () => {
- mountComponent();
-
- expect(finder().element).toMatchSnapshot();
- });
-
- it('input event triggers a model update', () => {
- mountComponent();
-
- finder().vm.$emit('input', 'foo');
- expect(wrapper.emitted('input')[0][0]).toMatchObject({
- [model]: 'foo',
- });
- });
-
- it('shows the default option when none are selected', () => {
- mountComponent({ props: { value: {} } });
- expect(finder().props('value')).toEqual(defaultValue);
- });
-
- if (type !== 'toggle') {
- it.each`
- isLoading | mutationLoading | enabledValue
- ${false} | ${false} | ${false}
- ${true} | ${false} | ${false}
- ${true} | ${true} | ${true}
- ${false} | ${true} | ${true}
- ${false} | ${false} | ${false}
- `(
- 'is disabled when is loading is $isLoading, mutationLoading is $mutationLoading and enabled is $enabledValue',
- ({ isLoading, mutationLoading, enabledValue }) => {
- mountComponent({
- props: { isLoading, value: { enabled: enabledValue } },
- data: { mutationLoading },
- });
- expect(finder().props('disabled')).toEqual(true);
- },
- );
- } else {
- it.each`
- isLoading | mutationLoading
- ${true} | ${false}
- ${true} | ${true}
- ${false} | ${true}
- `(
- 'is disabled when is loading is $isLoading and mutationLoading is $mutationLoading',
- ({ isLoading, mutationLoading }) => {
- mountComponent({
- props: { isLoading, value: {} },
- data: { mutationLoading },
- });
- expect(finder().props('disabled')).toEqual(true);
- },
- );
- }
-
- if (type === 'textarea') {
- it('input event updates the api error property', async () => {
- const apiErrors = { [model]: 'bar' };
- mountComponent({ data: { apiErrors } });
-
- finder().vm.$emit('input', 'foo');
- expect(finder().props('error')).toEqual('bar');
-
- await wrapper.vm.$nextTick();
-
- expect(finder().props('error')).toEqual('');
- });
-
- it('validation event updates buttons disabled state', async () => {
- mountComponent();
-
- expect(findSaveButton().props('disabled')).toBe(false);
-
- finder().vm.$emit('validation', false);
-
- await wrapper.vm.$nextTick();
-
- expect(findSaveButton().props('disabled')).toBe(true);
- });
- }
-
- if (type === 'dropdown') {
- it('has the correct formOptions', () => {
- mountComponent();
- expect(finder().props('formOptions')).toEqual(wrapper.vm.$options.formOptions[model]);
- });
- }
- });
-
- describe('form', () => {
- describe('form reset event', () => {
- it('calls the appropriate function', () => {
- mountComponent();
-
- findForm().trigger('reset');
-
- expect(wrapper.emitted('reset')).toEqual([[]]);
- });
-
- it('tracks the reset event', () => {
- mountComponent();
-
- findForm().trigger('reset');
-
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'reset_form', trackingPayload);
- });
-
- it('resets the errors objects', async () => {
- mountComponent({
- data: { apiErrors: { nameRegex: 'bar' }, localErrors: { nameRegexKeep: false } },
- });
-
- findForm().trigger('reset');
-
- await wrapper.vm.$nextTick();
-
- expect(findKeepRegexInput().props('error')).toBe('');
- expect(findRemoveRegexInput().props('error')).toBe('');
- expect(findSaveButton().props('disabled')).toBe(false);
- });
- });
-
- describe('form submit event ', () => {
- it('save has type submit', () => {
- mountComponent();
-
- expect(findSaveButton().attributes('type')).toBe('submit');
- });
-
- it('dispatches the correct apollo mutation', () => {
- const mutationResolver = jest.fn().mockResolvedValue(expirationPolicyMutationPayload());
- mountComponentWithApollo({
- mutationResolver,
- });
-
- findForm().trigger('submit');
-
- 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({
- mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()),
- });
-
- findForm().trigger('submit');
-
- expect(Tracking.event).toHaveBeenCalledWith(undefined, 'submit_form', trackingPayload);
- });
-
- it('show a success toast when submit succeed', async () => {
- mountComponentWithApollo({
- mutationResolver: jest.fn().mockResolvedValue(expirationPolicyMutationPayload()),
- });
-
- findForm().trigger('submit');
- await waitForPromises();
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_SUCCESS_MESSAGE, {
- type: 'success',
- });
- });
-
- describe('when submit fails', () => {
- describe('user recoverable errors', () => {
- it('when there is an error is shown in a toast', async () => {
- mountComponentWithApollo({
- mutationResolver: jest
- .fn()
- .mockResolvedValue(expirationPolicyMutationPayload({ errors: ['foo'] })),
- });
-
- findForm().trigger('submit');
- await waitForPromises();
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith('foo', {
- type: 'error',
- });
- });
- });
-
- describe('global errors', () => {
- it('shows an error', async () => {
- mountComponentWithApollo({
- mutationResolver: jest.fn().mockRejectedValue(expirationPolicyMutationPayload()),
- });
-
- findForm().trigger('submit');
- await waitForPromises();
- await wrapper.vm.$nextTick();
-
- expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(UPDATE_SETTINGS_ERROR_MESSAGE, {
- type: 'error',
- });
- });
-
- it('parses the error messages', async () => {
- const mutate = jest.fn().mockRejectedValue({
- graphQLErrors: [
- {
- extensions: {
- problems: [{ path: ['nameRegexKeep'], message: 'baz' }],
- },
- },
- ],
- });
- mountComponent({ mocks: { $apollo: { mutate } } });
-
- findForm().trigger('submit');
- await waitForPromises();
- await wrapper.vm.$nextTick();
-
- expect(findKeepRegexInput().props('error')).toEqual('baz');
- });
- });
- });
- });
- });
-
- describe('form actions', () => {
- describe('cancel button', () => {
- it('has type reset', () => {
- mountComponent();
-
- expect(findCancelButton().attributes('type')).toBe('reset');
- });
-
- it.each`
- isLoading | isEdited | mutationLoading
- ${true} | ${true} | ${true}
- ${false} | ${true} | ${true}
- ${false} | ${false} | ${true}
- ${true} | ${false} | ${false}
- ${false} | ${false} | ${false}
- `(
- 'when isLoading is $isLoading, isEdited is $isEdited and mutationLoading is $mutationLoading is disabled',
- ({ isEdited, isLoading, mutationLoading }) => {
- mountComponent({
- props: { ...defaultProps, isEdited, isLoading },
- data: { mutationLoading },
- });
-
- expect(findCancelButton().props('disabled')).toBe(true);
- },
- );
- });
-
- describe('submit button', () => {
- it('has type submit', () => {
- mountComponent();
-
- expect(findSaveButton().attributes('type')).toBe('submit');
- });
-
- it.each`
- isLoading | localErrors | mutationLoading
- ${true} | ${{}} | ${true}
- ${true} | ${{}} | ${false}
- ${false} | ${{}} | ${true}
- ${false} | ${{ foo: false }} | ${true}
- ${true} | ${{ foo: false }} | ${false}
- ${false} | ${{ foo: false }} | ${false}
- `(
- 'when isLoading is $isLoading, localErrors is $localErrors and mutationLoading is $mutationLoading is disabled',
- ({ localErrors, isLoading, mutationLoading }) => {
- mountComponent({
- props: { ...defaultProps, isLoading },
- data: { mutationLoading, localErrors },
- });
-
- expect(findSaveButton().props('disabled')).toBe(true);
- },
- );
-
- it.each`
- isLoading | mutationLoading | showLoading
- ${true} | ${true} | ${true}
- ${true} | ${false} | ${true}
- ${false} | ${true} | ${true}
- ${false} | ${false} | ${false}
- `(
- 'when isLoading is $isLoading and mutationLoading is $mutationLoading is $showLoading that the loading icon is shown',
- ({ isLoading, mutationLoading, showLoading }) => {
- mountComponent({
- props: { ...defaultProps, isLoading },
- data: { mutationLoading },
- });
-
- expect(findSaveButton().props('loading')).toBe(showLoading);
- },
- );
- });
- });
-});
diff --git a/spec/frontend/registry/settings/graphql/cache_updated_spec.js b/spec/frontend/registry/settings/graphql/cache_updated_spec.js
deleted file mode 100644
index 73655b6917b..00000000000
--- a/spec/frontend/registry/settings/graphql/cache_updated_spec.js
+++ /dev/null
@@ -1,56 +0,0 @@
-import expirationPolicyQuery from '~/registry/settings/graphql/queries/get_expiration_policy.query.graphql';
-import { updateContainerExpirationPolicy } from '~/registry/settings/graphql/utils/cache_update';
-
-describe('Registry settings cache update', () => {
- let client;
-
- const payload = {
- data: {
- updateContainerExpirationPolicy: {
- containerExpirationPolicy: {
- enabled: true,
- },
- },
- },
- };
-
- const cacheMock = {
- project: {
- containerExpirationPolicy: {
- enabled: false,
- },
- },
- };
-
- const queryAndVariables = {
- query: expirationPolicyQuery,
- variables: { projectPath: 'foo' },
- };
-
- beforeEach(() => {
- client = {
- readQuery: jest.fn().mockReturnValue(cacheMock),
- writeQuery: jest.fn(),
- };
- });
- describe('Registry settings cache update', () => {
- it('calls readQuery', () => {
- updateContainerExpirationPolicy('foo')(client, payload);
- expect(client.readQuery).toHaveBeenCalledWith(queryAndVariables);
- });
-
- it('writes the correct result in the cache', () => {
- updateContainerExpirationPolicy('foo')(client, payload);
- expect(client.writeQuery).toHaveBeenCalledWith({
- ...queryAndVariables,
- data: {
- project: {
- containerExpirationPolicy: {
- enabled: true,
- },
- },
- },
- });
- });
- });
-});
diff --git a/spec/frontend/registry/settings/mock_data.js b/spec/frontend/registry/settings/mock_data.js
deleted file mode 100644
index 9778f409010..00000000000
--- a/spec/frontend/registry/settings/mock_data.js
+++ /dev/null
@@ -1,40 +0,0 @@
-export const containerExpirationPolicyData = () => ({
- cadence: 'EVERY_DAY',
- enabled: true,
- keepN: 'TEN_TAGS',
- nameRegex: 'asdasdssssdfdf',
- nameRegexKeep: 'sss',
- olderThan: 'FOURTEEN_DAYS',
- nextRunAt: '2020-11-19T07:37:03.941Z',
-});
-
-export const expirationPolicyPayload = (override) => ({
- data: {
- project: {
- containerExpirationPolicy: {
- ...containerExpirationPolicyData(),
- ...override,
- },
- },
- },
-});
-
-export const emptyExpirationPolicyPayload = () => ({
- data: {
- project: {
- containerExpirationPolicy: {},
- },
- },
-});
-
-export const expirationPolicyMutationPayload = ({ override, errors = [] } = {}) => ({
- data: {
- updateContainerExpirationPolicy: {
- containerExpirationPolicy: {
- ...containerExpirationPolicyData(),
- ...override,
- },
- errors,
- },
- },
-});
diff --git a/spec/frontend/registry/settings/utils_spec.js b/spec/frontend/registry/settings/utils_spec.js
deleted file mode 100644
index 7bc627908af..00000000000
--- a/spec/frontend/registry/settings/utils_spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import {
- formOptionsGenerator,
- optionLabelGenerator,
- olderThanTranslationGenerator,
-} from '~/registry/settings/utils';
-
-describe('Utils', () => {
- describe('optionLabelGenerator', () => {
- it('returns an array with a set label', () => {
- const result = optionLabelGenerator(
- [{ variable: 1 }, { variable: 2 }],
- olderThanTranslationGenerator,
- );
- expect(result).toEqual([
- { variable: 1, label: '1 day' },
- { variable: 2, label: '2 days' },
- ]);
- });
- });
-
- describe('formOptionsGenerator', () => {
- it('returns an object containing olderThan', () => {
- expect(formOptionsGenerator().olderThan).toBeDefined();
- expect(formOptionsGenerator().olderThan).toMatchSnapshot();
- });
-
- it('returns an object containing cadence', () => {
- expect(formOptionsGenerator().cadence).toBeDefined();
- expect(formOptionsGenerator().cadence).toMatchSnapshot();
- });
-
- it('returns an object containing keepN', () => {
- expect(formOptionsGenerator().keepN).toBeDefined();
- expect(formOptionsGenerator().keepN).toMatchSnapshot();
- });
- });
-});