Merge branch 'update-secret-values-to-support-dynamic-elements' into 'master'
Update secret_values to support dynamic elements within parent See merge request gitlab-org/gitlab-ce!16665
This commit is contained in:
commit
7d8c624bbb
4 changed files with 116 additions and 25 deletions
|
@ -2,18 +2,19 @@ import { n__ } from '../locale';
|
|||
import { convertPermissionToBoolean } from '../lib/utils/common_utils';
|
||||
|
||||
export default class SecretValues {
|
||||
constructor(container) {
|
||||
constructor({
|
||||
container,
|
||||
valueSelector = '.js-secret-value',
|
||||
placeholderSelector = '.js-secret-value-placeholder',
|
||||
}) {
|
||||
this.container = container;
|
||||
this.valueSelector = valueSelector;
|
||||
this.placeholderSelector = placeholderSelector;
|
||||
}
|
||||
|
||||
init() {
|
||||
this.values = this.container.querySelectorAll('.js-secret-value');
|
||||
this.placeholders = this.container.querySelectorAll('.js-secret-value-placeholder');
|
||||
this.revealButton = this.container.querySelector('.js-secret-value-reveal-button');
|
||||
|
||||
this.revealText = n__('Reveal value', 'Reveal values', this.values.length);
|
||||
this.hideText = n__('Hide value', 'Hide values', this.values.length);
|
||||
|
||||
const isRevealed = convertPermissionToBoolean(this.revealButton.dataset.secretRevealStatus);
|
||||
this.updateDom(isRevealed);
|
||||
|
||||
|
@ -28,15 +29,17 @@ export default class SecretValues {
|
|||
}
|
||||
|
||||
updateDom(isRevealed) {
|
||||
this.values.forEach((value) => {
|
||||
const values = this.container.querySelectorAll(this.valueSelector);
|
||||
values.forEach((value) => {
|
||||
value.classList.toggle('hide', !isRevealed);
|
||||
});
|
||||
|
||||
this.placeholders.forEach((placeholder) => {
|
||||
const placeholders = this.container.querySelectorAll(this.placeholderSelector);
|
||||
placeholders.forEach((placeholder) => {
|
||||
placeholder.classList.toggle('hide', isRevealed);
|
||||
});
|
||||
|
||||
this.revealButton.textContent = isRevealed ? this.hideText : this.revealText;
|
||||
this.revealButton.textContent = isRevealed ? n__('Hide value', 'Hide values', values.length) : n__('Reveal value', 'Reveal values', values.length);
|
||||
this.revealButton.dataset.secretRevealStatus = isRevealed;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ import SecretValues from '~/behaviors/secret_values';
|
|||
export default () => {
|
||||
const secretVariableTable = document.querySelector('.js-secret-variable-table');
|
||||
if (secretVariableTable) {
|
||||
const secretVariableTableValues = new SecretValues(secretVariableTable);
|
||||
const secretVariableTableValues = new SecretValues({
|
||||
container: secretVariableTable,
|
||||
});
|
||||
secretVariableTableValues.init();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -6,13 +6,17 @@ export default function () {
|
|||
initSettingsPanels();
|
||||
const runnerToken = document.querySelector('.js-secret-runner-token');
|
||||
if (runnerToken) {
|
||||
const runnerTokenSecretValue = new SecretValues(runnerToken);
|
||||
const runnerTokenSecretValue = new SecretValues({
|
||||
container: runnerToken,
|
||||
});
|
||||
runnerTokenSecretValue.init();
|
||||
}
|
||||
|
||||
const secretVariableTable = document.querySelector('.js-secret-variable-table');
|
||||
if (secretVariableTable) {
|
||||
const secretVariableTableValues = new SecretValues(secretVariableTable);
|
||||
const secretVariableTableValues = new SecretValues({
|
||||
container: secretVariableTable,
|
||||
});
|
||||
secretVariableTableValues.init();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,24 @@
|
|||
import SecretValues from '~/behaviors/secret_values';
|
||||
|
||||
function generateFixtureMarkup(secrets, isRevealed) {
|
||||
function generateValueMarkup(
|
||||
secret,
|
||||
valueClass = 'js-secret-value',
|
||||
placeholderClass = 'js-secret-value-placeholder',
|
||||
) {
|
||||
return `
|
||||
<div class="${placeholderClass}">
|
||||
***
|
||||
</div>
|
||||
<div class="hide ${valueClass}">
|
||||
${secret}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
function generateFixtureMarkup(secrets, isRevealed, valueClass, placeholderClass) {
|
||||
return `
|
||||
<div class="js-secret-container">
|
||||
${secrets.map(secret => `
|
||||
<div class="js-secret-value-placeholder">
|
||||
***
|
||||
</div>
|
||||
<div class="hide js-secret-value">
|
||||
${secret}
|
||||
</div>
|
||||
`).join('')}
|
||||
${secrets.map(secret => generateValueMarkup(secret, valueClass, placeholderClass)).join('')}
|
||||
<button
|
||||
class="js-secret-value-reveal-button"
|
||||
data-secret-reveal-status="${isRevealed}"
|
||||
|
@ -21,11 +29,25 @@ function generateFixtureMarkup(secrets, isRevealed) {
|
|||
`;
|
||||
}
|
||||
|
||||
function setupSecretFixture(secrets, isRevealed) {
|
||||
function setupSecretFixture(
|
||||
secrets,
|
||||
isRevealed,
|
||||
valueClass = 'js-secret-value',
|
||||
placeholderClass = 'js-secret-value-placeholder',
|
||||
) {
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.innerHTML = generateFixtureMarkup(secrets, isRevealed);
|
||||
wrapper.innerHTML = generateFixtureMarkup(
|
||||
secrets,
|
||||
isRevealed,
|
||||
valueClass,
|
||||
placeholderClass,
|
||||
);
|
||||
|
||||
const secretValues = new SecretValues(wrapper.querySelector('.js-secret-container'));
|
||||
const secretValues = new SecretValues({
|
||||
container: wrapper.querySelector('.js-secret-container'),
|
||||
valueSelector: `.${valueClass}`,
|
||||
placeholderSelector: `.${placeholderClass}`,
|
||||
});
|
||||
secretValues.init();
|
||||
|
||||
return wrapper;
|
||||
|
@ -49,7 +71,7 @@ describe('setupSecretValues', () => {
|
|||
expect(revealButton.textContent).toEqual('Hide value');
|
||||
});
|
||||
|
||||
it('should value hidden initially', () => {
|
||||
it('should have value hidden initially', () => {
|
||||
const wrapper = setupSecretFixture(secrets, false);
|
||||
const values = wrapper.querySelectorAll('.js-secret-value');
|
||||
const placeholders = wrapper.querySelectorAll('.js-secret-value-placeholder');
|
||||
|
@ -143,4 +165,64 @@ describe('setupSecretValues', () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('with dynamic secrets', () => {
|
||||
const secrets = ['mysecret123', 'happygoat456', 'tanuki789'];
|
||||
|
||||
it('should toggle values and placeholders', () => {
|
||||
const wrapper = setupSecretFixture(secrets, false);
|
||||
// Insert the new dynamic row
|
||||
wrapper.querySelector('.js-secret-container').insertAdjacentHTML('afterbegin', generateValueMarkup('foobarbazdynamic'));
|
||||
|
||||
const revealButton = wrapper.querySelector('.js-secret-value-reveal-button');
|
||||
const values = wrapper.querySelectorAll('.js-secret-value');
|
||||
const placeholders = wrapper.querySelectorAll('.js-secret-value-placeholder');
|
||||
|
||||
revealButton.click();
|
||||
|
||||
expect(values.length).toEqual(4);
|
||||
values.forEach((value) => {
|
||||
expect(value.classList.contains('hide')).toEqual(false);
|
||||
});
|
||||
expect(placeholders.length).toEqual(4);
|
||||
placeholders.forEach((placeholder) => {
|
||||
expect(placeholder.classList.contains('hide')).toEqual(true);
|
||||
});
|
||||
|
||||
revealButton.click();
|
||||
|
||||
expect(values.length).toEqual(4);
|
||||
values.forEach((value) => {
|
||||
expect(value.classList.contains('hide')).toEqual(true);
|
||||
});
|
||||
expect(placeholders.length).toEqual(4);
|
||||
placeholders.forEach((placeholder) => {
|
||||
expect(placeholder.classList.contains('hide')).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('selector options', () => {
|
||||
const secrets = ['mysecret123'];
|
||||
|
||||
it('should respect `valueSelector` and `placeholderSelector` options', () => {
|
||||
const valueClass = 'js-some-custom-placeholder-selector';
|
||||
const placeholderClass = 'js-some-custom-value-selector';
|
||||
|
||||
const wrapper = setupSecretFixture(secrets, false, valueClass, placeholderClass);
|
||||
const values = wrapper.querySelectorAll(`.${valueClass}`);
|
||||
const placeholders = wrapper.querySelectorAll(`.${placeholderClass}`);
|
||||
const revealButton = wrapper.querySelector('.js-secret-value-reveal-button');
|
||||
|
||||
expect(values.length).toEqual(1);
|
||||
expect(placeholders.length).toEqual(1);
|
||||
|
||||
revealButton.click();
|
||||
|
||||
expect(values.length).toEqual(1);
|
||||
expect(values[0].classList.contains('hide')).toEqual(false);
|
||||
expect(placeholders.length).toEqual(1);
|
||||
expect(placeholders[0].classList.contains('hide')).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue