debian-mirror-gitlab/spec/frontend/token_access/outbound_token_access_spec.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

342 lines
11 KiB
JavaScript
Raw Normal View History

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';
2023-05-27 22:25:52 +05:30
import { createAlert } from '~/alert';
2023-04-23 21:23:45 +05:30
import OutboundTokenAccess from '~/token_access/components/outbound_token_access.vue';
2021-09-30 23:02:18 +05:30
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';
2023-03-04 22:38:38 +05:30
import updateCIJobTokenScopeMutation from '~/token_access/graphql/mutations/update_ci_job_token_scope.mutation.graphql';
2021-09-30 23:02:18 +05:30
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,
2023-03-04 22:38:38 +05:30
updateScopeSuccess,
2021-09-30 23:02:18 +05:30
} 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
2023-05-27 22:25:52 +05:30
jest.mock('~/alert');
2021-09-30 23:02:18 +05:30
describe('TokenAccess component', () => {
let wrapper;
const enabledJobTokenScopeHandler = jest.fn().mockResolvedValue(enabledJobTokenScope);
const disabledJobTokenScopeHandler = jest.fn().mockResolvedValue(disabledJobTokenScope);
2023-03-04 22:38:38 +05:30
const getProjectsWithScopeHandler = jest.fn().mockResolvedValue(projectsWithScope);
2021-09-30 23:02:18 +05:30
const addProjectSuccessHandler = jest.fn().mockResolvedValue(addProjectSuccess);
const removeProjectSuccessHandler = jest.fn().mockResolvedValue(removeProjectSuccess);
2023-03-04 22:38:38 +05:30
const updateScopeSuccessHandler = jest.fn().mockResolvedValue(updateScopeSuccess);
const failureHandler = jest.fn().mockRejectedValue(error);
2021-09-30 23:02:18 +05:30
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');
2023-07-09 08:55:56 +05:30
const findDeprecationAlert = () => wrapper.findByTestId('deprecation-alert');
const findProjectPathInput = () => wrapper.findByTestId('project-path-input');
2021-09-30 23:02:18 +05:30
const createMockApolloProvider = (requestHandlers) => {
return createMockApollo(requestHandlers);
};
2023-07-09 08:55:56 +05:30
const createComponent = (
requestHandlers,
mountFn = shallowMountExtended,
frozenOutboundJobTokenScopes = false,
frozenOutboundJobTokenScopesOverride = false,
) => {
2023-04-23 21:23:45 +05:30
wrapper = mountFn(OutboundTokenAccess, {
2021-09-30 23:02:18 +05:30
provide: {
fullPath: projectPath,
2023-07-09 08:55:56 +05:30
glFeatures: {
frozenOutboundJobTokenScopes,
frozenOutboundJobTokenScopesOverride,
},
2021-09-30 23:02:18 +05:30
},
apolloProvider: createMockApolloProvider(requestHandlers),
data() {
return {
targetProjectPath: 'root/test',
};
},
});
};
describe('loading state', () => {
it('shows loading state while waiting on query to resolve', async () => {
createComponent([
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
2023-03-04 22:38:38 +05:30
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
2021-09-30 23:02:18 +05:30
]);
expect(findLoadingIcon().exists()).toBe(true);
await waitForPromises();
expect(findLoadingIcon().exists()).toBe(false);
});
});
2023-03-04 22:38:38 +05:30
describe('fetching projects and scope', () => {
it('fetches projects and scope correctly', () => {
const expectedVariables = {
fullPath: 'root/my-repo',
};
createComponent([
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
]);
expect(enabledJobTokenScopeHandler).toHaveBeenCalledWith(expectedVariables);
expect(getProjectsWithScopeHandler).toHaveBeenCalledWith(expectedVariables);
});
it('handles fetch projects error correctly', async () => {
createComponent([
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
[getProjectsWithCIJobTokenScopeQuery, failureHandler],
]);
await waitForPromises();
expect(createAlert).toHaveBeenCalledWith({
message: 'There was a problem fetching the projects',
});
});
it('handles fetch scope error correctly', async () => {
createComponent([
[getCIJobTokenScopeQuery, failureHandler],
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
]);
await waitForPromises();
expect(createAlert).toHaveBeenCalledWith({
message: 'There was a problem fetching the job token scope value',
});
});
});
2021-09-30 23:02:18 +05:30
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],
2023-03-04 22:38:38 +05:30
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
2021-09-30 23:02:18 +05:30
]);
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],
2023-03-04 22:38:38 +05:30
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
2021-09-30 23:02:18 +05:30
]);
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
});
2023-03-04 22:38:38 +05:30
describe('update ci job token scope', () => {
it('calls updateCIJobTokenScopeMutation mutation', async () => {
createComponent(
[
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
[updateCIJobTokenScopeMutation, updateScopeSuccessHandler],
],
mountExtended,
);
await waitForPromises();
findToggle().vm.$emit('change', false);
expect(updateScopeSuccessHandler).toHaveBeenCalledWith({
input: {
fullPath: 'root/my-repo',
jobTokenScopeEnabled: false,
},
});
});
it('handles update scope error correctly', async () => {
createComponent(
[
[getCIJobTokenScopeQuery, disabledJobTokenScopeHandler],
[updateCIJobTokenScopeMutation, failureHandler],
],
mountExtended,
);
await waitForPromises();
findToggle().vm.$emit('change', true);
await waitForPromises();
expect(createAlert).toHaveBeenCalledWith({ message });
});
});
2021-09-30 23:02:18 +05:30
});
describe('add project', () => {
it('calls add project mutation', async () => {
createComponent(
[
[getCIJobTokenScopeQuery, enabledJobTokenScopeHandler],
2023-03-04 22:38:38 +05:30
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
2021-09-30 23:02:18 +05:30
[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],
2023-03-04 22:38:38 +05:30
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
[addProjectCIJobTokenScopeMutation, failureHandler],
2021-09-30 23:02:18 +05:30
],
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],
2023-03-04 22:38:38 +05:30
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
2021-09-30 23:02:18 +05:30
[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],
2023-03-04 22:38:38 +05:30
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
[removeProjectCIJobTokenScopeMutation, failureHandler],
2021-09-30 23:02:18 +05:30
],
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
});
});
2023-07-09 08:55:56 +05:30
describe('with the frozenOutboundJobTokenScopes feature flag enabled', () => {
describe('toggle', () => {
it('the toggle is off and the deprecation alert is visible', async () => {
createComponent(
[
[getCIJobTokenScopeQuery, disabledJobTokenScopeHandler],
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
],
shallowMountExtended,
true,
);
await waitForPromises();
expect(findToggle().props('value')).toBe(false);
expect(findToggle().props('disabled')).toBe(true);
expect(findDeprecationAlert().exists()).toBe(true);
expect(findTokenDisabledAlert().exists()).toBe(false);
});
it('contains a warning message about disabling the current configuration', async () => {
createComponent(
[
[getCIJobTokenScopeQuery, disabledJobTokenScopeHandler],
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
],
mountExtended,
true,
);
await waitForPromises();
expect(findToggle().text()).toContain('Disabling this feature is a permanent change.');
});
});
describe('adding a new project', () => {
it('disables the input to add new projects', async () => {
createComponent(
[
[getCIJobTokenScopeQuery, disabledJobTokenScopeHandler],
[getProjectsWithCIJobTokenScopeQuery, getProjectsWithScopeHandler],
],
mountExtended,
true,
false,
);
await waitForPromises();
expect(findProjectPathInput().attributes('disabled')).toBe('disabled');
});
});
});
2021-09-30 23:02:18 +05:30
});