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/access_tokens/components')
-rw-r--r--spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap17
-rw-r--r--spec/frontend/access_tokens/components/expires_at_field_spec.js9
-rw-r--r--spec/frontend/access_tokens/components/projects_field_spec.js131
-rw-r--r--spec/frontend/access_tokens/components/projects_token_selector_spec.js266
4 files changed, 15 insertions, 408 deletions
diff --git a/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap b/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap
index 36003154b58..2bd2b17a12d 100644
--- a/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap
+++ b/spec/frontend/access_tokens/components/__snapshots__/expires_at_field_spec.js.snap
@@ -11,22 +11,17 @@ exports[`~/access_tokens/components/expires_at_field should render datepicker wi
arialabel=""
autocomplete=""
container=""
+ data-qa-selector="expiry_date_field"
+ defaultdate="Wed Aug 05 2020 00:00:00 GMT+0000 (Greenwich Mean Time)"
displayfield="true"
firstday="0"
+ inputid="personal_access_token_expires_at"
inputlabel="Enter date"
+ inputname="personal_access_token[expires_at]"
mindate="Mon Jul 06 2020 00:00:00 GMT+0000 (Greenwich Mean Time)"
placeholder="YYYY-MM-DD"
+ showclearbutton="true"
theme=""
- >
- <gl-form-input-stub
- autocomplete="off"
- class="datepicker gl-datepicker-input"
- data-qa-selector="expiry_date_field"
- id="personal_access_token_expires_at"
- inputmode="none"
- name="personal_access_token[expires_at]"
- placeholder="YYYY-MM-DD"
- />
- </gl-datepicker-stub>
+ />
</gl-form-group-stub>
`;
diff --git a/spec/frontend/access_tokens/components/expires_at_field_spec.js b/spec/frontend/access_tokens/components/expires_at_field_spec.js
index cb899d10ba7..646dc0d703f 100644
--- a/spec/frontend/access_tokens/components/expires_at_field_spec.js
+++ b/spec/frontend/access_tokens/components/expires_at_field_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import { GlDatepicker } from '@gitlab/ui';
import ExpiresAtField from '~/access_tokens/components/expires_at_field.vue';
+import { getDateInFuture } from '~/lib/utils/datetime_utility';
describe('~/access_tokens/components/expires_at_field', () => {
let wrapper;
@@ -49,4 +50,12 @@ describe('~/access_tokens/components/expires_at_field', () => {
expect(findDatepicker().props('maxDate')).toStrictEqual(maxDate);
});
+
+ it('should set the default expiration date to be 30 days', () => {
+ const today = new Date();
+ const future = getDateInFuture(today, 30);
+ createComponent();
+
+ expect(findDatepicker().props('defaultDate')).toStrictEqual(future);
+ });
});
diff --git a/spec/frontend/access_tokens/components/projects_field_spec.js b/spec/frontend/access_tokens/components/projects_field_spec.js
deleted file mode 100644
index 1c4fe7bb168..00000000000
--- a/spec/frontend/access_tokens/components/projects_field_spec.js
+++ /dev/null
@@ -1,131 +0,0 @@
-import { nextTick } from 'vue';
-import { within, fireEvent } from '@testing-library/dom';
-import { mount } from '@vue/test-utils';
-import ProjectsField from '~/access_tokens/components/projects_field.vue';
-import ProjectsTokenSelector from '~/access_tokens/components/projects_token_selector.vue';
-
-describe('ProjectsField', () => {
- let wrapper;
-
- const createComponent = ({ inputAttrsValue = '' } = {}) => {
- wrapper = mount(ProjectsField, {
- propsData: {
- inputAttrs: {
- id: 'projects',
- name: 'projects',
- value: inputAttrsValue,
- },
- },
- });
- };
-
- const queryByLabelText = (text) => within(wrapper.element).queryByLabelText(text);
- const queryByText = (text) => within(wrapper.element).queryByText(text);
- const findAllProjectsRadio = () => queryByLabelText('All projects');
- const findSelectedProjectsRadio = () => queryByLabelText('Selected projects');
- const findProjectsTokenSelector = () => wrapper.findComponent(ProjectsTokenSelector);
- const findHiddenInput = () => wrapper.find('input[type="hidden"]');
-
- afterEach(() => {
- wrapper.destroy();
- wrapper = null;
- });
-
- it('renders label and sub-label', () => {
- createComponent();
-
- expect(queryByText('Projects')).not.toBe(null);
- expect(queryByText('Set access permissions for this token.')).not.toBe(null);
- });
-
- describe('when `inputAttrs.value` is empty', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders "All projects" radio as checked', () => {
- expect(findAllProjectsRadio().checked).toBe(true);
- });
-
- it('renders "Selected projects" radio as unchecked', () => {
- expect(findSelectedProjectsRadio().checked).toBe(false);
- });
-
- it('sets `projects-token-selector` `initialProjectIds` prop to an empty array', () => {
- expect(findProjectsTokenSelector().props('initialProjectIds')).toEqual([]);
- });
- });
-
- describe('when `inputAttrs.value` is a comma separated list of project IDs', () => {
- beforeEach(() => {
- createComponent({ inputAttrsValue: '1,2' });
- });
-
- it('renders "All projects" radio as unchecked', () => {
- expect(findAllProjectsRadio().checked).toBe(false);
- });
-
- it('renders "Selected projects" radio as checked', () => {
- expect(findSelectedProjectsRadio().checked).toBe(true);
- });
-
- it('sets `projects-token-selector` `initialProjectIds` prop to an array of project IDs', () => {
- expect(findProjectsTokenSelector().props('initialProjectIds')).toEqual(['1', '2']);
- });
- });
-
- it('renders `projects-token-selector` component', () => {
- createComponent();
-
- expect(findProjectsTokenSelector().exists()).toBe(true);
- });
-
- it('renders hidden input with correct `name` and `id` attributes', () => {
- createComponent();
-
- expect(findHiddenInput().attributes()).toEqual(
- expect.objectContaining({
- id: 'projects',
- name: 'projects',
- }),
- );
- });
-
- describe('when `projects-token-selector` is focused', () => {
- beforeEach(() => {
- createComponent();
-
- findProjectsTokenSelector().vm.$emit('focus');
- });
-
- it('auto selects the "Selected projects" radio', () => {
- expect(findSelectedProjectsRadio().checked).toBe(true);
- });
-
- describe('when `projects-token-selector` is changed', () => {
- beforeEach(() => {
- findProjectsTokenSelector().vm.$emit('input', [
- {
- id: 1,
- },
- {
- id: 2,
- },
- ]);
- });
-
- it('updates the hidden input value to a comma separated list of project IDs', () => {
- expect(findHiddenInput().attributes('value')).toBe('1,2');
- });
-
- describe('when radio is changed back to "All projects"', () => {
- it('removes the hidden input value', async () => {
- fireEvent.change(findAllProjectsRadio());
- await nextTick();
-
- expect(findHiddenInput().attributes('value')).toBe('');
- });
- });
- });
- });
-});
diff --git a/spec/frontend/access_tokens/components/projects_token_selector_spec.js b/spec/frontend/access_tokens/components/projects_token_selector_spec.js
deleted file mode 100644
index 40aaf16d41f..00000000000
--- a/spec/frontend/access_tokens/components/projects_token_selector_spec.js
+++ /dev/null
@@ -1,266 +0,0 @@
-import {
- GlAvatar,
- GlAvatarLabeled,
- GlIntersectionObserver,
- GlToken,
- GlTokenSelector,
- GlLoadingIcon,
-} from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import produce from 'immer';
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-
-import getProjectsQueryResponse from 'test_fixtures/graphql/projects/access_tokens/get_projects.query.graphql.json';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import ProjectsTokenSelector from '~/access_tokens/components/projects_token_selector.vue';
-import getProjectsQuery from '~/access_tokens/graphql/queries/get_projects.query.graphql';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-
-describe('ProjectsTokenSelector', () => {
- const getProjectsQueryResponsePage2 = produce(
- getProjectsQueryResponse,
- (getProjectsQueryResponseDraft) => {
- /* eslint-disable no-param-reassign */
- getProjectsQueryResponseDraft.data.projects.pageInfo.hasNextPage = false;
- getProjectsQueryResponseDraft.data.projects.pageInfo.endCursor = null;
- getProjectsQueryResponseDraft.data.projects.nodes.splice(1, 1);
- getProjectsQueryResponseDraft.data.projects.nodes[0].id = 'gid://gitlab/Project/100';
- /* eslint-enable no-param-reassign */
- },
- );
-
- const runDebounce = () => jest.runAllTimers();
-
- const { pageInfo, nodes: projects } = getProjectsQueryResponse.data.projects;
- const project1 = projects[0];
- const project2 = projects[1];
-
- let wrapper;
-
- let resolveGetProjectsQuery;
- let resolveGetInitialProjectsQuery;
- const getProjectsQueryRequestHandler = jest.fn(
- ({ ids }) =>
- new Promise((resolve) => {
- if (ids) {
- resolveGetInitialProjectsQuery = resolve;
- } else {
- resolveGetProjectsQuery = resolve;
- }
- }),
- );
-
- const createComponent = ({
- propsData = {},
- apolloProvider = createMockApollo([[getProjectsQuery, getProjectsQueryRequestHandler]]),
- resolveQueries = true,
- } = {}) => {
- Vue.use(VueApollo);
-
- wrapper = extendedWrapper(
- mount(ProjectsTokenSelector, {
- apolloProvider,
- propsData: {
- selectedProjects: [],
- initialProjectIds: [],
- ...propsData,
- },
- stubs: ['gl-intersection-observer'],
- }),
- );
-
- runDebounce();
-
- if (resolveQueries) {
- resolveGetProjectsQuery(getProjectsQueryResponse);
-
- return waitForPromises();
- }
-
- return Promise.resolve();
- };
-
- const findTokenSelector = () => wrapper.findComponent(GlTokenSelector);
- const findTokenSelectorInput = () => findTokenSelector().find('input[type="text"]');
- const findIntersectionObserver = () => wrapper.findComponent(GlIntersectionObserver);
-
- it('renders dropdown items with project avatars', async () => {
- await createComponent();
-
- wrapper.findAllComponents(GlAvatarLabeled).wrappers.forEach((avatarLabeledWrapper, index) => {
- const project = projects[index];
-
- expect(avatarLabeledWrapper.attributes()).toEqual(
- expect.objectContaining({
- 'entity-id': `${getIdFromGraphQLId(project.id)}`,
- 'entity-name': project.name,
- ...(project.avatarUrl && { src: project.avatarUrl }),
- }),
- );
-
- expect(avatarLabeledWrapper.props()).toEqual(
- expect.objectContaining({
- label: project.name,
- subLabel: project.nameWithNamespace,
- }),
- );
- });
- });
-
- it('renders tokens with project avatars', () => {
- createComponent({
- propsData: {
- selectedProjects: [{ ...project2, id: getIdFromGraphQLId(project2.id) }],
- },
- });
-
- const token = wrapper.findComponent(GlToken);
- const avatar = token.findComponent(GlAvatar);
-
- expect(token.text()).toContain(project2.nameWithNamespace);
- expect(avatar.attributes('src')).toBe(project2.avatarUrl);
- expect(avatar.props()).toEqual(
- expect.objectContaining({
- entityId: getIdFromGraphQLId(project2.id),
- entityName: project2.name,
- }),
- );
- });
-
- describe('when `enter` key is pressed', () => {
- it('calls `preventDefault` so form is not submitted when user selects a project from the dropdown', () => {
- createComponent();
-
- const event = {
- preventDefault: jest.fn(),
- };
-
- findTokenSelectorInput().trigger('keydown.enter', event);
-
- expect(event.preventDefault).toHaveBeenCalled();
- });
- });
-
- describe('when text input is typed in', () => {
- const searchTerm = 'foo bar';
-
- beforeEach(async () => {
- await createComponent();
-
- await findTokenSelectorInput().setValue(searchTerm);
- runDebounce();
- });
-
- it('makes GraphQL request with `search` variable set', async () => {
- expect(getProjectsQueryRequestHandler).toHaveBeenLastCalledWith({
- search: searchTerm,
- after: null,
- first: 20,
- ids: null,
- });
- });
-
- it('sets loading state while waiting for GraphQL request to resolve', async () => {
- expect(findTokenSelector().props('loading')).toBe(true);
-
- resolveGetProjectsQuery(getProjectsQueryResponse);
- await waitForPromises();
-
- expect(findTokenSelector().props('loading')).toBe(false);
- });
- });
-
- describe('when there is a next page of projects and user scrolls to the bottom of the dropdown', () => {
- beforeEach(async () => {
- await createComponent();
-
- findIntersectionObserver().vm.$emit('appear');
- });
-
- it('makes GraphQL request with `after` variable set', async () => {
- expect(getProjectsQueryRequestHandler).toHaveBeenLastCalledWith({
- after: pageInfo.endCursor,
- first: 20,
- search: '',
- ids: null,
- });
- });
-
- it('displays loading icon while waiting for GraphQL request to resolve', async () => {
- expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
-
- resolveGetProjectsQuery(getProjectsQueryResponsePage2);
- await waitForPromises();
-
- expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(false);
- });
- });
-
- describe('when there is not a next page of projects', () => {
- it('does not render `GlIntersectionObserver`', async () => {
- createComponent({ resolveQueries: false });
-
- resolveGetProjectsQuery(getProjectsQueryResponsePage2);
- await waitForPromises();
-
- expect(findIntersectionObserver().exists()).toBe(false);
- });
- });
-
- describe('when `GlTokenSelector` emits `input` event', () => {
- it('emits `input` event used by `v-model`', () => {
- findTokenSelector().vm.$emit('input', project1);
-
- expect(wrapper.emitted('input')[0]).toEqual([project1]);
- });
- });
-
- describe('when `GlTokenSelector` emits `focus` event', () => {
- it('emits `focus` event', () => {
- const event = { fakeEvent: 'foo' };
- findTokenSelector().vm.$emit('focus', event);
-
- expect(wrapper.emitted('focus')[0]).toEqual([event]);
- });
- });
-
- describe('when `initialProjectIds` is an empty array', () => {
- it('does not request initial projects', async () => {
- await createComponent();
-
- expect(getProjectsQueryRequestHandler).toHaveBeenCalledTimes(1);
- expect(getProjectsQueryRequestHandler).toHaveBeenCalledWith(
- expect.objectContaining({
- ids: null,
- }),
- );
- });
- });
-
- describe('when `initialProjectIds` is an array of project IDs', () => {
- it('requests those projects and emits `input` event with result', async () => {
- await createComponent({
- propsData: {
- initialProjectIds: [getIdFromGraphQLId(project1.id), getIdFromGraphQLId(project2.id)],
- },
- });
-
- resolveGetInitialProjectsQuery(getProjectsQueryResponse);
- await waitForPromises();
-
- expect(getProjectsQueryRequestHandler).toHaveBeenCalledWith({
- after: '',
- first: null,
- search: '',
- ids: [project1.id, project2.id],
- });
- expect(wrapper.emitted('input')[0][0]).toEqual([
- { ...project1, id: getIdFromGraphQLId(project1.id) },
- { ...project2, id: getIdFromGraphQLId(project2.id) },
- ]);
- });
- });
-});