231 lines
7.3 KiB
JavaScript
231 lines
7.3 KiB
JavaScript
import $ from 'jquery';
|
|
import MockAdapter from 'axios-mock-adapter';
|
|
import axios from '~/lib/utils/axios_utils';
|
|
import AjaxFormVariableList from '~/ci_variable_list/ajax_variable_list';
|
|
|
|
const VARIABLE_PATCH_ENDPOINT = 'http://test.host/frontend-fixtures/builds-project/variables';
|
|
const HIDE_CLASS = 'hide';
|
|
|
|
describe('AjaxFormVariableList', () => {
|
|
preloadFixtures('projects/ci_cd_settings.html');
|
|
preloadFixtures('projects/ci_cd_settings_with_variables.html');
|
|
|
|
let container;
|
|
let saveButton;
|
|
let errorBox;
|
|
|
|
let mock;
|
|
let ajaxVariableList;
|
|
|
|
beforeEach(() => {
|
|
loadFixtures('projects/ci_cd_settings.html');
|
|
container = document.querySelector('.js-ci-variable-list-section');
|
|
|
|
mock = new MockAdapter(axios);
|
|
|
|
const ajaxVariableListEl = document.querySelector('.js-ci-variable-list-section');
|
|
saveButton = ajaxVariableListEl.querySelector('.js-ci-variables-save-button');
|
|
errorBox = container.querySelector('.js-ci-variable-error-box');
|
|
ajaxVariableList = new AjaxFormVariableList({
|
|
container,
|
|
formField: 'variables',
|
|
saveButton,
|
|
errorBox,
|
|
saveEndpoint: container.dataset.saveEndpoint,
|
|
maskableRegex: container.dataset.maskableRegex,
|
|
});
|
|
|
|
spyOn(ajaxVariableList, 'updateRowsWithPersistedVariables').and.callThrough();
|
|
spyOn(ajaxVariableList.variableList, 'toggleEnableRow').and.callThrough();
|
|
});
|
|
|
|
afterEach(() => {
|
|
mock.restore();
|
|
});
|
|
|
|
describe('onSaveClicked', () => {
|
|
it('shows loading spinner while waiting for the request', done => {
|
|
const loadingIcon = saveButton.querySelector('.js-ci-variables-save-loading-icon');
|
|
|
|
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(() => {
|
|
expect(loadingIcon.classList.contains(HIDE_CLASS)).toEqual(false);
|
|
|
|
return [200, {}];
|
|
});
|
|
|
|
expect(loadingIcon.classList.contains(HIDE_CLASS)).toEqual(true);
|
|
|
|
ajaxVariableList
|
|
.onSaveClicked()
|
|
.then(() => {
|
|
expect(loadingIcon.classList.contains(HIDE_CLASS)).toEqual(true);
|
|
})
|
|
.then(done)
|
|
.catch(done.fail);
|
|
});
|
|
|
|
it('calls `updateRowsWithPersistedVariables` with the persisted variables', done => {
|
|
const variablesResponse = [{ id: 1, key: 'foo', value: 'bar' }];
|
|
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(200, {
|
|
variables: variablesResponse,
|
|
});
|
|
|
|
ajaxVariableList
|
|
.onSaveClicked()
|
|
.then(() => {
|
|
expect(ajaxVariableList.updateRowsWithPersistedVariables).toHaveBeenCalledWith(
|
|
variablesResponse,
|
|
);
|
|
})
|
|
.then(done)
|
|
.catch(done.fail);
|
|
});
|
|
|
|
it('hides any previous error box', done => {
|
|
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(200);
|
|
|
|
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
|
|
|
|
ajaxVariableList
|
|
.onSaveClicked()
|
|
.then(() => {
|
|
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
|
|
})
|
|
.then(done)
|
|
.catch(done.fail);
|
|
});
|
|
|
|
it('disables remove buttons while waiting for the request', done => {
|
|
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(() => {
|
|
expect(ajaxVariableList.variableList.toggleEnableRow).toHaveBeenCalledWith(false);
|
|
|
|
return [200, {}];
|
|
});
|
|
|
|
ajaxVariableList
|
|
.onSaveClicked()
|
|
.then(() => {
|
|
expect(ajaxVariableList.variableList.toggleEnableRow).toHaveBeenCalledWith(true);
|
|
})
|
|
.then(done)
|
|
.catch(done.fail);
|
|
});
|
|
|
|
it('hides secret values', done => {
|
|
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(200, {});
|
|
|
|
const row = container.querySelector('.js-row');
|
|
const valueInput = row.querySelector('.js-ci-variable-input-value');
|
|
const valuePlaceholder = row.querySelector('.js-secret-value-placeholder');
|
|
|
|
valueInput.value = 'bar';
|
|
$(valueInput).trigger('input');
|
|
|
|
expect(valuePlaceholder.classList.contains(HIDE_CLASS)).toBe(true);
|
|
expect(valueInput.classList.contains(HIDE_CLASS)).toBe(false);
|
|
|
|
ajaxVariableList
|
|
.onSaveClicked()
|
|
.then(() => {
|
|
expect(valuePlaceholder.classList.contains(HIDE_CLASS)).toBe(false);
|
|
expect(valueInput.classList.contains(HIDE_CLASS)).toBe(true);
|
|
})
|
|
.then(done)
|
|
.catch(done.fail);
|
|
});
|
|
|
|
it('shows error box with validation errors', done => {
|
|
const validationError = 'some validation error';
|
|
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(400, [validationError]);
|
|
|
|
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
|
|
|
|
ajaxVariableList
|
|
.onSaveClicked()
|
|
.then(() => {
|
|
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(false);
|
|
expect(errorBox.textContent.trim().replace(/\n+\s+/m, ' ')).toEqual(
|
|
`Validation failed ${validationError}`,
|
|
);
|
|
})
|
|
.then(done)
|
|
.catch(done.fail);
|
|
});
|
|
|
|
it('shows flash message when request fails', done => {
|
|
mock.onPatch(VARIABLE_PATCH_ENDPOINT).reply(500);
|
|
|
|
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
|
|
|
|
ajaxVariableList
|
|
.onSaveClicked()
|
|
.then(() => {
|
|
expect(errorBox.classList.contains(HIDE_CLASS)).toEqual(true);
|
|
})
|
|
.then(done)
|
|
.catch(done.fail);
|
|
});
|
|
});
|
|
|
|
describe('updateRowsWithPersistedVariables', () => {
|
|
beforeEach(() => {
|
|
loadFixtures('projects/ci_cd_settings_with_variables.html');
|
|
container = document.querySelector('.js-ci-variable-list-section');
|
|
|
|
const ajaxVariableListEl = document.querySelector('.js-ci-variable-list-section');
|
|
saveButton = ajaxVariableListEl.querySelector('.js-ci-variables-save-button');
|
|
errorBox = container.querySelector('.js-ci-variable-error-box');
|
|
ajaxVariableList = new AjaxFormVariableList({
|
|
container,
|
|
formField: 'variables',
|
|
saveButton,
|
|
errorBox,
|
|
saveEndpoint: container.dataset.saveEndpoint,
|
|
});
|
|
});
|
|
|
|
it('removes variable that was removed', () => {
|
|
expect(container.querySelectorAll('.js-row').length).toBe(3);
|
|
|
|
container.querySelector('.js-row-remove-button').click();
|
|
|
|
expect(container.querySelectorAll('.js-row').length).toBe(3);
|
|
|
|
ajaxVariableList.updateRowsWithPersistedVariables([]);
|
|
|
|
expect(container.querySelectorAll('.js-row').length).toBe(2);
|
|
});
|
|
|
|
it('updates new variable row with persisted ID', () => {
|
|
const row = container.querySelector('.js-row:last-child');
|
|
const idInput = row.querySelector('.js-ci-variable-input-id');
|
|
const keyInput = row.querySelector('.js-ci-variable-input-key');
|
|
const valueInput = row.querySelector('.js-ci-variable-input-value');
|
|
|
|
keyInput.value = 'foo';
|
|
$(keyInput).trigger('input');
|
|
valueInput.value = 'bar';
|
|
$(valueInput).trigger('input');
|
|
|
|
expect(idInput.value).toEqual('');
|
|
|
|
ajaxVariableList.updateRowsWithPersistedVariables([
|
|
{
|
|
id: 3,
|
|
key: 'foo',
|
|
value: 'bar',
|
|
},
|
|
]);
|
|
|
|
expect(idInput.value).toEqual('3');
|
|
expect(row.dataset.isPersisted).toEqual('true');
|
|
});
|
|
});
|
|
|
|
describe('maskableRegex', () => {
|
|
it('takes in the regex provided by the data attribute', () => {
|
|
expect(container.dataset.maskableRegex).toBe('^[a-zA-Z0-9_+=/@:-]{8,}$');
|
|
expect(ajaxVariableList.maskableRegex).toBe(container.dataset.maskableRegex);
|
|
});
|
|
});
|
|
});
|