diff options
author | Igor <idrozdov@gitlab.com> | 2019-03-07 23:55:45 +0000 |
---|---|---|
committer | Mike Greiling <mike@pixelcog.com> | 2019-03-07 23:55:45 +0000 |
commit | 9745d0de2ff605a03e7fbb95d0f71279bbd4afa5 (patch) | |
tree | 0d7f0f89b51199bf676988888539338086f419a3 /spec | |
parent | 90f4b6563d42ff7412de277682c0ecb7c25e41bb (diff) | |
download | gitlab-ce-9745d0de2ff605a03e7fbb95d0f71279bbd4afa5.tar.gz |
Provide EE backports for filtering by approver feature
Adds custom validator for ArrayNoneAny param
Extracts some logic in js into separate files
Diffstat (limited to 'spec')
3 files changed, 385 insertions, 334 deletions
diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js index 6230da77f49..f3dc35552d5 100644 --- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js +++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js @@ -1,9 +1,4 @@ -import _ from 'underscore'; -import AjaxCache from '~/lib/utils/ajax_cache'; -import UsersCache from '~/lib/utils/users_cache'; - import FilteredSearchVisualTokens from '~/filtered_search/filtered_search_visual_tokens'; -import DropdownUtils from '~/filtered_search//dropdown_utils'; import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; describe('Filtered Search Visual Tokens', () => { @@ -685,349 +680,21 @@ describe('Filtered Search Visual Tokens', () => { }); describe('renderVisualTokenValue', () => { - const keywordToken = FilteredSearchSpecHelper.createFilterVisualToken('search'); - const milestoneToken = FilteredSearchSpecHelper.createFilterVisualToken( - 'milestone', - 'upcoming', - ); - - let updateLabelTokenColorSpy; - let updateUserTokenAppearanceSpy; - beforeEach(() => { tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(` ${authorToken.outerHTML} ${bugLabelToken.outerHTML} - ${keywordToken.outerHTML} - ${milestoneToken.outerHTML} `); - - spyOn(subject, 'updateLabelTokenColor'); - updateLabelTokenColorSpy = subject.updateLabelTokenColor; - - spyOn(subject, 'updateUserTokenAppearance'); - updateUserTokenAppearanceSpy = subject.updateUserTokenAppearance; }); it('renders a author token value element', () => { - const { tokenNameElement, tokenValueContainer, tokenValueElement } = findElements( - authorToken, - ); + const { tokenNameElement, tokenValueElement } = findElements(authorToken); const tokenName = tokenNameElement.innerText; const tokenValue = 'new value'; subject.renderVisualTokenValue(authorToken, tokenName, tokenValue); expect(tokenValueElement.innerText).toBe(tokenValue); - expect(updateUserTokenAppearanceSpy.calls.count()).toBe(1); - const expectedArgs = [tokenValueContainer, tokenValueElement, tokenValue]; - - expect(updateUserTokenAppearanceSpy.calls.argsFor(0)).toEqual(expectedArgs); - expect(updateLabelTokenColorSpy.calls.count()).toBe(0); - }); - - it('renders a label token value element', () => { - const { tokenNameElement, tokenValueContainer, tokenValueElement } = findElements( - bugLabelToken, - ); - const tokenName = tokenNameElement.innerText; - const tokenValue = 'new value'; - - subject.renderVisualTokenValue(bugLabelToken, tokenName, tokenValue); - - expect(tokenValueElement.innerText).toBe(tokenValue); - expect(updateLabelTokenColorSpy.calls.count()).toBe(1); - const expectedArgs = [tokenValueContainer, tokenValue]; - - expect(updateLabelTokenColorSpy.calls.argsFor(0)).toEqual(expectedArgs); - expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); - }); - - it('renders a milestone token value element', () => { - const { tokenNameElement, tokenValueElement } = findElements(milestoneToken); - const tokenName = tokenNameElement.innerText; - const tokenValue = 'new value'; - - subject.renderVisualTokenValue(milestoneToken, tokenName, tokenValue); - - expect(tokenValueElement.innerText).toBe(tokenValue); - expect(updateLabelTokenColorSpy.calls.count()).toBe(0); - expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); - }); - - it('does not update user token appearance for `None` filter', () => { - const { tokenNameElement } = findElements(authorToken); - - const tokenName = tokenNameElement.innerText; - const tokenValue = 'None'; - - subject.renderVisualTokenValue(authorToken, tokenName, tokenValue); - - expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); - }); - - it('does not update user token appearance for `none` filter', () => { - const { tokenNameElement } = findElements(authorToken); - - const tokenName = tokenNameElement.innerText; - const tokenValue = 'none'; - - subject.renderVisualTokenValue(authorToken, tokenName, tokenValue); - - expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); - }); - - it('does not update user token appearance for `any` filter', () => { - const { tokenNameElement } = findElements(authorToken); - - const tokenName = tokenNameElement.innerText; - const tokenValue = 'any'; - - subject.renderVisualTokenValue(authorToken, tokenName, tokenValue); - - expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); - }); - - it('does not update label token color for `none` filter', () => { - const { tokenNameElement } = findElements(bugLabelToken); - - const tokenName = tokenNameElement.innerText; - const tokenValue = 'none'; - - subject.renderVisualTokenValue(bugLabelToken, tokenName, tokenValue); - - expect(updateLabelTokenColorSpy.calls.count()).toBe(0); - }); - - it('does not update label token color for `any` filter', () => { - const { tokenNameElement } = findElements(bugLabelToken); - - const tokenName = tokenNameElement.innerText; - const tokenValue = 'any'; - - subject.renderVisualTokenValue(bugLabelToken, tokenName, tokenValue); - - expect(updateLabelTokenColorSpy.calls.count()).toBe(0); - }); - }); - - describe('updateUserTokenAppearance', () => { - let usersCacheSpy; - - beforeEach(() => { - spyOn(UsersCache, 'retrieve').and.callFake(username => usersCacheSpy(username)); - }); - - it('ignores error if UsersCache throws', done => { - spyOn(window, 'Flash'); - const dummyError = new Error('Earth rotated backwards'); - const { tokenValueContainer, tokenValueElement } = findElements(authorToken); - const tokenValue = tokenValueElement.innerText; - usersCacheSpy = username => { - expect(`@${username}`).toBe(tokenValue); - return Promise.reject(dummyError); - }; - - subject - .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) - .then(() => { - expect(window.Flash.calls.count()).toBe(0); - }) - .then(done) - .catch(done.fail); - }); - - it('does nothing if user cannot be found', done => { - const { tokenValueContainer, tokenValueElement } = findElements(authorToken); - const tokenValue = tokenValueElement.innerText; - usersCacheSpy = username => { - expect(`@${username}`).toBe(tokenValue); - return Promise.resolve(undefined); - }; - - subject - .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) - .then(() => { - expect(tokenValueElement.innerText).toBe(tokenValue); - }) - .then(done) - .catch(done.fail); - }); - - it('replaces author token with avatar and display name', done => { - const dummyUser = { - name: 'Important Person', - avatar_url: 'https://host.invalid/mypics/avatar.png', - }; - const { tokenValueContainer, tokenValueElement } = findElements(authorToken); - const tokenValue = tokenValueElement.innerText; - usersCacheSpy = username => { - expect(`@${username}`).toBe(tokenValue); - return Promise.resolve(dummyUser); - }; - - subject - .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) - .then(() => { - expect(tokenValueContainer.dataset.originalValue).toBe(tokenValue); - expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); - const avatar = tokenValueElement.querySelector('img.avatar'); - - expect(avatar.src).toBe(dummyUser.avatar_url); - expect(avatar.alt).toBe(''); - }) - .then(done) - .catch(done.fail); - }); - - it('escapes user name when creating token', done => { - const dummyUser = { - name: '<script>', - avatar_url: `${gl.TEST_HOST}/mypics/avatar.png`, - }; - const { tokenValueContainer, tokenValueElement } = findElements(authorToken); - const tokenValue = tokenValueElement.innerText; - usersCacheSpy = username => { - expect(`@${username}`).toBe(tokenValue); - return Promise.resolve(dummyUser); - }; - - subject - .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) - .then(() => { - expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); - tokenValueElement.querySelector('.avatar').remove(); - - expect(tokenValueElement.innerHTML.trim()).toBe(_.escape(dummyUser.name)); - }) - .then(done) - .catch(done.fail); - }); - }); - - describe('setTokenStyle', () => { - let originalTextColor; - - beforeEach(() => { - originalTextColor = bugLabelToken.style.color; - }); - - it('should set backgroundColor', () => { - const originalBackgroundColor = bugLabelToken.style.backgroundColor; - const token = subject.setTokenStyle(bugLabelToken, 'blue', 'white'); - - expect(token.style.backgroundColor).toEqual('blue'); - expect(token.style.backgroundColor).not.toEqual(originalBackgroundColor); - }); - - it('should set textColor', () => { - const token = subject.setTokenStyle(bugLabelToken, 'white', 'black'); - - expect(token.style.color).toEqual('black'); - expect(token.style.color).not.toEqual(originalTextColor); - }); - - it('should add inverted class when textColor is #FFFFFF', () => { - const token = subject.setTokenStyle(bugLabelToken, 'black', '#FFFFFF'); - - expect(token.style.color).toEqual('rgb(255, 255, 255)'); - expect(token.style.color).not.toEqual(originalTextColor); - expect(token.querySelector('.remove-token').classList.contains('inverted')).toEqual(true); - }); - }); - - describe('updateLabelTokenColor', () => { - const jsonFixtureName = 'labels/project_labels.json'; - const dummyEndpoint = '/dummy/endpoint'; - - preloadFixtures(jsonFixtureName); - - let labelData; - - beforeAll(() => { - labelData = getJSONFixture(jsonFixtureName); - }); - - const missingLabelToken = FilteredSearchSpecHelper.createFilterVisualToken( - 'label', - '~doesnotexist', - ); - const spaceLabelToken = FilteredSearchSpecHelper.createFilterVisualToken( - 'label', - '~"some space"', - ); - - beforeEach(() => { - tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(` - ${bugLabelToken.outerHTML} - ${missingLabelToken.outerHTML} - ${spaceLabelToken.outerHTML} - `); - - const filteredSearchInput = document.querySelector('.filtered-search'); - filteredSearchInput.dataset.baseEndpoint = dummyEndpoint; - - AjaxCache.internalStorage = {}; - AjaxCache.internalStorage[`${dummyEndpoint}/labels.json`] = labelData; - }); - - const parseColor = color => { - const dummyElement = document.createElement('div'); - dummyElement.style.color = color; - return dummyElement.style.color; - }; - - const expectValueContainerStyle = (tokenValueContainer, label) => { - expect(tokenValueContainer.getAttribute('style')).not.toBe(null); - expect(tokenValueContainer.style.backgroundColor).toBe(parseColor(label.color)); - expect(tokenValueContainer.style.color).toBe(parseColor(label.text_color)); - }; - - const findLabel = tokenValue => - labelData.find(label => tokenValue === `~${DropdownUtils.getEscapedText(label.title)}`); - - it('updates the color of a label token', done => { - const { tokenValueContainer, tokenValueElement } = findElements(bugLabelToken); - const tokenValue = tokenValueElement.innerText; - const matchingLabel = findLabel(tokenValue); - - subject - .updateLabelTokenColor(tokenValueContainer, tokenValue) - .then(() => { - expectValueContainerStyle(tokenValueContainer, matchingLabel); - }) - .then(done) - .catch(done.fail); - }); - - it('updates the color of a label token with spaces', done => { - const { tokenValueContainer, tokenValueElement } = findElements(spaceLabelToken); - const tokenValue = tokenValueElement.innerText; - const matchingLabel = findLabel(tokenValue); - - subject - .updateLabelTokenColor(tokenValueContainer, tokenValue) - .then(() => { - expectValueContainerStyle(tokenValueContainer, matchingLabel); - }) - .then(done) - .catch(done.fail); - }); - - it('does not change color of a missing label', done => { - const { tokenValueContainer, tokenValueElement } = findElements(missingLabelToken); - const tokenValue = tokenValueElement.innerText; - const matchingLabel = findLabel(tokenValue); - - expect(matchingLabel).toBe(undefined); - - subject - .updateLabelTokenColor(tokenValueContainer, tokenValue) - .then(() => { - expect(tokenValueContainer.getAttribute('style')).toBe(null); - }) - .then(done) - .catch(done.fail); }); }); }); diff --git a/spec/javascripts/filtered_search/visual_token_value_spec.js b/spec/javascripts/filtered_search/visual_token_value_spec.js new file mode 100644 index 00000000000..f52dc26a7bb --- /dev/null +++ b/spec/javascripts/filtered_search/visual_token_value_spec.js @@ -0,0 +1,361 @@ +import VisualTokenValue from '~/filtered_search/visual_token_value'; +import _ from 'underscore'; +import AjaxCache from '~/lib/utils/ajax_cache'; +import UsersCache from '~/lib/utils/users_cache'; +import DropdownUtils from '~/filtered_search//dropdown_utils'; +import FilteredSearchSpecHelper from '../helpers/filtered_search_spec_helper'; + +describe('Filtered Search Visual Tokens', () => { + const findElements = tokenElement => { + const tokenNameElement = tokenElement.querySelector('.name'); + const tokenValueContainer = tokenElement.querySelector('.value-container'); + const tokenValueElement = tokenValueContainer.querySelector('.value'); + const tokenType = tokenNameElement.innerText.toLowerCase(); + const tokenValue = tokenValueElement.innerText; + const subject = new VisualTokenValue(tokenValue, tokenType); + return { subject, tokenValueContainer, tokenValueElement }; + }; + + let tokensContainer; + let authorToken; + let bugLabelToken; + + beforeEach(() => { + setFixtures(` + <ul class="tokens-container"> + ${FilteredSearchSpecHelper.createInputHTML()} + </ul> + `); + tokensContainer = document.querySelector('.tokens-container'); + + authorToken = FilteredSearchSpecHelper.createFilterVisualToken('author', '@user'); + bugLabelToken = FilteredSearchSpecHelper.createFilterVisualToken('label', '~bug'); + }); + + describe('updateUserTokenAppearance', () => { + let usersCacheSpy; + + beforeEach(() => { + spyOn(UsersCache, 'retrieve').and.callFake(username => usersCacheSpy(username)); + }); + + it('ignores error if UsersCache throws', done => { + spyOn(window, 'Flash'); + const dummyError = new Error('Earth rotated backwards'); + const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken); + const tokenValue = tokenValueElement.innerText; + usersCacheSpy = username => { + expect(`@${username}`).toBe(tokenValue); + return Promise.reject(dummyError); + }; + + subject + .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) + .then(() => { + expect(window.Flash.calls.count()).toBe(0); + }) + .then(done) + .catch(done.fail); + }); + + it('does nothing if user cannot be found', done => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken); + const tokenValue = tokenValueElement.innerText; + usersCacheSpy = username => { + expect(`@${username}`).toBe(tokenValue); + return Promise.resolve(undefined); + }; + + subject + .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) + .then(() => { + expect(tokenValueElement.innerText).toBe(tokenValue); + }) + .then(done) + .catch(done.fail); + }); + + it('replaces author token with avatar and display name', done => { + const dummyUser = { + name: 'Important Person', + avatar_url: 'https://host.invalid/mypics/avatar.png', + }; + const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken); + const tokenValue = tokenValueElement.innerText; + usersCacheSpy = username => { + expect(`@${username}`).toBe(tokenValue); + return Promise.resolve(dummyUser); + }; + + subject + .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) + .then(() => { + expect(tokenValueContainer.dataset.originalValue).toBe(tokenValue); + expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); + const avatar = tokenValueElement.querySelector('img.avatar'); + + expect(avatar.src).toBe(dummyUser.avatar_url); + expect(avatar.alt).toBe(''); + }) + .then(done) + .catch(done.fail); + }); + + it('escapes user name when creating token', done => { + const dummyUser = { + name: '<script>', + avatar_url: `${gl.TEST_HOST}/mypics/avatar.png`, + }; + const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken); + const tokenValue = tokenValueElement.innerText; + usersCacheSpy = username => { + expect(`@${username}`).toBe(tokenValue); + return Promise.resolve(dummyUser); + }; + + subject + .updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue) + .then(() => { + expect(tokenValueElement.innerText.trim()).toBe(dummyUser.name); + tokenValueElement.querySelector('.avatar').remove(); + + expect(tokenValueElement.innerHTML.trim()).toBe(_.escape(dummyUser.name)); + }) + .then(done) + .catch(done.fail); + }); + }); + + describe('updateLabelTokenColor', () => { + const jsonFixtureName = 'labels/project_labels.json'; + const dummyEndpoint = '/dummy/endpoint'; + + preloadFixtures(jsonFixtureName); + + let labelData; + + beforeAll(() => { + labelData = getJSONFixture(jsonFixtureName); + }); + + const missingLabelToken = FilteredSearchSpecHelper.createFilterVisualToken( + 'label', + '~doesnotexist', + ); + const spaceLabelToken = FilteredSearchSpecHelper.createFilterVisualToken( + 'label', + '~"some space"', + ); + + beforeEach(() => { + tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(` + ${bugLabelToken.outerHTML} + ${missingLabelToken.outerHTML} + ${spaceLabelToken.outerHTML} + `); + + const filteredSearchInput = document.querySelector('.filtered-search'); + filteredSearchInput.dataset.baseEndpoint = dummyEndpoint; + + AjaxCache.internalStorage = {}; + AjaxCache.internalStorage[`${dummyEndpoint}/labels.json`] = labelData; + }); + + const parseColor = color => { + const dummyElement = document.createElement('div'); + dummyElement.style.color = color; + return dummyElement.style.color; + }; + + const expectValueContainerStyle = (tokenValueContainer, label) => { + expect(tokenValueContainer.getAttribute('style')).not.toBe(null); + expect(tokenValueContainer.style.backgroundColor).toBe(parseColor(label.color)); + expect(tokenValueContainer.style.color).toBe(parseColor(label.text_color)); + }; + + const findLabel = tokenValue => + labelData.find(label => tokenValue === `~${DropdownUtils.getEscapedText(label.title)}`); + + it('updates the color of a label token', done => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(bugLabelToken); + const tokenValue = tokenValueElement.innerText; + const matchingLabel = findLabel(tokenValue); + + subject + .updateLabelTokenColor(tokenValueContainer, tokenValue) + .then(() => { + expectValueContainerStyle(tokenValueContainer, matchingLabel); + }) + .then(done) + .catch(done.fail); + }); + + it('updates the color of a label token with spaces', done => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(spaceLabelToken); + const tokenValue = tokenValueElement.innerText; + const matchingLabel = findLabel(tokenValue); + + subject + .updateLabelTokenColor(tokenValueContainer, tokenValue) + .then(() => { + expectValueContainerStyle(tokenValueContainer, matchingLabel); + }) + .then(done) + .catch(done.fail); + }); + + it('does not change color of a missing label', done => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(missingLabelToken); + const tokenValue = tokenValueElement.innerText; + const matchingLabel = findLabel(tokenValue); + + expect(matchingLabel).toBe(undefined); + + subject + .updateLabelTokenColor(tokenValueContainer, tokenValue) + .then(() => { + expect(tokenValueContainer.getAttribute('style')).toBe(null); + }) + .then(done) + .catch(done.fail); + }); + }); + + describe('setTokenStyle', () => { + let originalTextColor; + + beforeEach(() => { + originalTextColor = bugLabelToken.style.color; + }); + + it('should set backgroundColor', () => { + const originalBackgroundColor = bugLabelToken.style.backgroundColor; + const token = VisualTokenValue.setTokenStyle(bugLabelToken, 'blue', 'white'); + + expect(token.style.backgroundColor).toEqual('blue'); + expect(token.style.backgroundColor).not.toEqual(originalBackgroundColor); + }); + + it('should set textColor', () => { + const token = VisualTokenValue.setTokenStyle(bugLabelToken, 'white', 'black'); + + expect(token.style.color).toEqual('black'); + expect(token.style.color).not.toEqual(originalTextColor); + }); + + it('should add inverted class when textColor is #FFFFFF', () => { + const token = VisualTokenValue.setTokenStyle(bugLabelToken, 'black', '#FFFFFF'); + + expect(token.style.color).toEqual('rgb(255, 255, 255)'); + expect(token.style.color).not.toEqual(originalTextColor); + expect(token.querySelector('.remove-token').classList.contains('inverted')).toEqual(true); + }); + }); + + describe('render', () => { + const setupSpies = subject => { + spyOn(subject, 'updateLabelTokenColor'); // eslint-disable-line jasmine/no-unsafe-spy + const updateLabelTokenColorSpy = subject.updateLabelTokenColor; + + spyOn(subject, 'updateUserTokenAppearance'); // eslint-disable-line jasmine/no-unsafe-spy + const updateUserTokenAppearanceSpy = subject.updateUserTokenAppearance; + + return { updateLabelTokenColorSpy, updateUserTokenAppearanceSpy }; + }; + + const keywordToken = FilteredSearchSpecHelper.createFilterVisualToken('search'); + const milestoneToken = FilteredSearchSpecHelper.createFilterVisualToken( + 'milestone', + 'upcoming', + ); + + beforeEach(() => { + tokensContainer.innerHTML = FilteredSearchSpecHelper.createTokensContainerHTML(` + ${authorToken.outerHTML} + ${bugLabelToken.outerHTML} + ${keywordToken.outerHTML} + ${milestoneToken.outerHTML} + `); + }); + + it('renders a author token value element', () => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken); + + const { updateLabelTokenColorSpy, updateUserTokenAppearanceSpy } = setupSpies(subject); + subject.render(tokenValueContainer, tokenValueElement); + + expect(updateUserTokenAppearanceSpy.calls.count()).toBe(1); + const expectedArgs = [tokenValueContainer, tokenValueElement]; + + expect(updateUserTokenAppearanceSpy.calls.argsFor(0)).toEqual(expectedArgs); + expect(updateLabelTokenColorSpy.calls.count()).toBe(0); + }); + + it('renders a label token value element', () => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(bugLabelToken); + + const { updateLabelTokenColorSpy, updateUserTokenAppearanceSpy } = setupSpies(subject); + subject.render(tokenValueContainer, tokenValueElement); + + expect(updateLabelTokenColorSpy.calls.count()).toBe(1); + const expectedArgs = [tokenValueContainer]; + + expect(updateLabelTokenColorSpy.calls.argsFor(0)).toEqual(expectedArgs); + expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); + }); + + it('renders a milestone token value element', () => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(milestoneToken); + + const { updateLabelTokenColorSpy, updateUserTokenAppearanceSpy } = setupSpies(subject); + subject.render(tokenValueContainer, tokenValueElement); + + expect(updateLabelTokenColorSpy.calls.count()).toBe(0); + expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); + }); + + it('does not update user token appearance for `none` filter', () => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken); + + subject.tokenType = 'none'; + + const { updateUserTokenAppearanceSpy } = setupSpies(subject); + subject.render(tokenValueContainer, tokenValueElement); + + expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); + }); + + it('does not update user token appearance for `any` filter', () => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken); + + subject.tokenType = 'any'; + + const { updateUserTokenAppearanceSpy } = setupSpies(subject); + subject.render(tokenValueContainer, tokenValueElement); + + expect(updateUserTokenAppearanceSpy.calls.count()).toBe(0); + }); + + it('does not update label token color for `none` filter', () => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(bugLabelToken); + + subject.tokenType = 'none'; + + const { updateLabelTokenColorSpy } = setupSpies(subject); + subject.render(tokenValueContainer, tokenValueElement); + + expect(updateLabelTokenColorSpy.calls.count()).toBe(0); + }); + + it('does not update label token color for `any` filter', () => { + const { subject, tokenValueContainer, tokenValueElement } = findElements(bugLabelToken); + + subject.tokenType = 'any'; + + const { updateLabelTokenColorSpy } = setupSpies(subject); + subject.render(tokenValueContainer, tokenValueElement); + + expect(updateLabelTokenColorSpy.calls.count()).toBe(0); + }); + }); +}); diff --git a/spec/lib/api/helpers/custom_validators_spec.rb b/spec/lib/api/helpers/custom_validators_spec.rb index 41e6fb47b11..9945d598a14 100644 --- a/spec/lib/api/helpers/custom_validators_spec.rb +++ b/spec/lib/api/helpers/custom_validators_spec.rb @@ -50,6 +50,29 @@ describe API::Helpers::CustomValidators do end end + describe API::Helpers::CustomValidators::ArrayNoneAny do + subject do + described_class.new(['test'], {}, false, scope.new) + end + + context 'valid parameters' do + it 'does not raise a validation error' do + expect_no_validation_error({ 'test' => [] }) + expect_no_validation_error({ 'test' => [1, 2, 3] }) + expect_no_validation_error({ 'test' => 'None' }) + expect_no_validation_error({ 'test' => 'Any' }) + expect_no_validation_error({ 'test' => 'none' }) + expect_no_validation_error({ 'test' => 'any' }) + end + end + + context 'invalid parameters' do + it 'should raise a validation error' do + expect_validation_error({ 'test' => 'some_other_string' }) + end + end + end + def expect_no_validation_error(params) expect { validate_test_param!(params) }.not_to raise_error end |