2021-09-30 23:02:18 +05:30
|
|
|
import { GlToggle, GlLoadingIcon } from '@gitlab/ui';
|
2022-04-04 11:22:00 +05:30
|
|
|
import Vue from 'vue';
|
2021-09-30 23:02:18 +05:30
|
|
|
import VueApollo from 'vue-apollo';
|
|
|
|
import createMockApollo from 'helpers/mock_apollo_helper';
|
2021-10-27 15:23:28 +05:30
|
|
|
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
2021-09-30 23:02:18 +05:30
|
|
|
import waitForPromises from 'helpers/wait_for_promises';
|
2022-11-25 23:54:43 +05:30
|
|
|
import { createAlert } from '~/flash';
|
2021-09-30 23:02:18 +05:30
|
|
|
import TokenAccess from '~/token_access/components/token_access.vue';
|
|
|
|
import addProjectCIJobTokenScopeMutation from '~/token_access/graphql/mutations/add_project_ci_job_token_scope.mutation.graphql';
|
|
|
|
import removeProjectCIJobTokenScopeMutation from '~/token_access/graphql/mutations/remove_project_ci_job_token_scope.mutation.graphql';
|
|
|
|
import getCIJobTokenScopeQuery from '~/token_access/graphql/queries/get_ci_job_token_scope.query.graphql';
|
|
|
|
import getProjectsWithCIJobTokenScopeQuery from '~/token_access/graphql/queries/get_projects_with_ci_job_token_scope.query.graphql';
|
|
|
|
import {
|
|
|
|
enabledJobTokenScope,
|
|
|
|
disabledJobTokenScope,
|
|
|
|
projectsWithScope,
|
|
|
|
addProjectSuccess,
|
|
|
|
removeProjectSuccess,
|
|
|
|
} from './mock_data';
|
|
|
|
|
|
|
|
const projectPath = 'root/my-repo';
|
2023-01-13 00:05:48 +05:30
|
|
|
const message = 'An error occurred';
|
|
|
|
const error = new Error(message);
|
2021-09-30 23:02:18 +05:30
|
|
|
|
2022-04-04 11:22:00 +05:30
|
|
|
Vue.use(VueApollo);
|
2021-09-30 23:02:18 +05:30
|
|
|
|
|
|
|
jest.mock('~/flash');
|
|
|
|
|
|
|
|
describe('TokenAccess component', () => {
|
|
|
|
let wrapper;
|
|
|
|
|
|
|
|
const enabledJobTokenScopeHandler = jest.fn().mockResolvedValue(enabledJobTokenScope);
|
|
|
|
const disabledJobTokenScopeHandler = jest.fn().mockResolvedValue(disabledJobTokenScope);
|
|
|
|
const getProjectsWithScope = jest.fn().mockResolvedValue(projectsWithScope);
|
|
|
|
const addProjectSuccessHandler = jest.fn().mockResolvedValue(addProjectSuccess);
|
|
|
|
const addProjectFailureHandler = jest.fn().mockRejectedValue(error);
|
|
|
|
const removeProjectSuccessHandler = jest.fn().mockResolvedValue(removeProjectSuccess);
|
|
|
|
const removeProjectFailureHandler = jest.fn().mockRejectedValue(error);
|
|
|
|
|
|
|
|
const findToggle = () => wrapper.findComponent(GlToggle);
|
|
|
|
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
|
2021-10-27 15:23:28 +05:30
|
|
|
const findAddProjectBtn = () => wrapper.findByRole('button', { name: 'Add project' });
|
|
|
|
const findRemoveProjectBtn = () => wrapper.findByRole('button', { name: 'Remove access' });
|
2022-11-25 23:54:43 +05:30
|
|
|
const findTokenDisabledAlert = () => wrapper.findByTestId('token-disabled-alert');
|
2021-09-30 23:02:18 +05:30
|
|
|
|
|
|
|
const createMockApolloProvider = (requestHandlers) => {
|
|
|
|
return createMockApollo(requestHandlers);
|
|
|
|
};
|
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
const createComponent = (requestHandlers, mountFn = shallowMountExtended) => {
|
2021-09-30 23:02:18 +05:30
|
|
|
wrapper = mountFn(TokenAccess, {
|
|
|
|
provide: {
|
|
|
|
fullPath: projectPath,
|
|
|
|
},
|
|
|
|
apolloProvider: createMockApolloProvider(requestHandlers),
|
|
|
|
data() {
|
|
|
|
return {
|
|
|
|
targetProjectPath: 'root/test',
|
|
|
|
};
|
|
|
|
},
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
afterEach(() => {
|
|
|
|
wrapper.destroy();
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('loading state', () => {
|
|
|
|
it('shows loading state while waiting on query to resolve', async () => {
|
|
|
|
createComponent([
|
|
|
|
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
|
|
|
|
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScope],
|
|
|
|
]);
|
|
|
|
|
|
|
|
expect(findLoadingIcon().exists()).toBe(true);
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
expect(findLoadingIcon().exists()).toBe(false);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('toggle', () => {
|
2022-11-25 23:54:43 +05:30
|
|
|
it('the toggle is on and the alert is hidden', async () => {
|
2021-09-30 23:02:18 +05:30
|
|
|
createComponent([
|
|
|
|
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
|
|
|
|
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScope],
|
|
|
|
]);
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
expect(findToggle().props('value')).toBe(true);
|
2022-11-25 23:54:43 +05:30
|
|
|
expect(findTokenDisabledAlert().exists()).toBe(false);
|
2021-09-30 23:02:18 +05:30
|
|
|
});
|
|
|
|
|
2022-11-25 23:54:43 +05:30
|
|
|
it('the toggle is off and the alert is visible', async () => {
|
2021-09-30 23:02:18 +05:30
|
|
|
createComponent([
|
|
|
|
[getCIJobTokenScopeQuery, disabledJobTokenScopeHandler],
|
|
|
|
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScope],
|
|
|
|
]);
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
expect(findToggle().props('value')).toBe(false);
|
2022-11-25 23:54:43 +05:30
|
|
|
expect(findTokenDisabledAlert().exists()).toBe(true);
|
2021-09-30 23:02:18 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('add project', () => {
|
|
|
|
it('calls add project mutation', async () => {
|
|
|
|
createComponent(
|
|
|
|
[
|
|
|
|
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
|
|
|
|
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScope],
|
|
|
|
[addProjectCIJobTokenScopeMutation, addProjectSuccessHandler],
|
|
|
|
],
|
2021-10-27 15:23:28 +05:30
|
|
|
mountExtended,
|
2021-09-30 23:02:18 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
findAddProjectBtn().trigger('click');
|
|
|
|
|
|
|
|
expect(addProjectSuccessHandler).toHaveBeenCalledWith({
|
|
|
|
input: {
|
|
|
|
projectPath,
|
|
|
|
targetProjectPath: 'root/test',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('add project handles error correctly', async () => {
|
|
|
|
createComponent(
|
|
|
|
[
|
|
|
|
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
|
|
|
|
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScope],
|
|
|
|
[addProjectCIJobTokenScopeMutation, addProjectFailureHandler],
|
|
|
|
],
|
2021-10-27 15:23:28 +05:30
|
|
|
mountExtended,
|
2021-09-30 23:02:18 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
findAddProjectBtn().trigger('click');
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
expect(createAlert).toHaveBeenCalledWith({ message });
|
2021-09-30 23:02:18 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
describe('remove project', () => {
|
|
|
|
it('calls remove project mutation', async () => {
|
|
|
|
createComponent(
|
|
|
|
[
|
|
|
|
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
|
|
|
|
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScope],
|
|
|
|
[removeProjectCIJobTokenScopeMutation, removeProjectSuccessHandler],
|
|
|
|
],
|
2021-10-27 15:23:28 +05:30
|
|
|
mountExtended,
|
2021-09-30 23:02:18 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
findRemoveProjectBtn().trigger('click');
|
|
|
|
|
|
|
|
expect(removeProjectSuccessHandler).toHaveBeenCalledWith({
|
|
|
|
input: {
|
|
|
|
projectPath,
|
|
|
|
targetProjectPath: 'root/332268-test',
|
|
|
|
},
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
it('remove project handles error correctly', async () => {
|
|
|
|
createComponent(
|
|
|
|
[
|
|
|
|
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
|
|
|
|
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScope],
|
|
|
|
[removeProjectCIJobTokenScopeMutation, removeProjectFailureHandler],
|
|
|
|
],
|
2021-10-27 15:23:28 +05:30
|
|
|
mountExtended,
|
2021-09-30 23:02:18 +05:30
|
|
|
);
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
|
|
|
findRemoveProjectBtn().trigger('click');
|
|
|
|
|
|
|
|
await waitForPromises();
|
|
|
|
|
2023-01-13 00:05:48 +05:30
|
|
|
expect(createAlert).toHaveBeenCalledWith({ message });
|
2021-09-30 23:02:18 +05:30
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|