Commit 66c54a54 authored by Dave Pisek's avatar Dave Pisek

Maintainer feedback: Refactor tests

Leverage recent changes made to the specs to get closer to
replicating actual user interaction, instead of reaching into
implementation details, such as mutating a view model.
parent 4f7c7b15
...@@ -137,18 +137,18 @@ export default { ...@@ -137,18 +137,18 @@ export default {
<!-- TODO: Remove feature flag --> <!-- TODO: Remove feature flag -->
<template v-if="hasLicensePolicyList"> <template v-if="hasLicensePolicyList">
<gl-tabs v-model="tabIndex" content-class="pt-0"> <gl-tabs v-model="tabIndex" content-class="pt-0">
<gl-tab> <gl-tab data-testid="licensesTab">
<template #title> <template #title>
{{ s__('Licenses|Detected in Project') }} <span data-testid="licensesTabTitle">{{ s__('Licenses|Detected in Project') }}</span>
<gl-badge pill>{{ licenseCount }}</gl-badge> <gl-badge pill>{{ licenseCount }}</gl-badge>
</template> </template>
<detected-licenses-table /> <detected-licenses-table />
</gl-tab> </gl-tab>
<gl-tab> <gl-tab data-testid="policiesTab">
<template #title> <template #title>
{{ s__('Licenses|Policies') }} <span data-testid="policiesTabTitle">{{ s__('Licenses|Policies') }}</span>
<gl-badge pill>{{ policyCount }}</gl-badge> <gl-badge pill>{{ policyCount }}</gl-badge>
</template> </template>
......
...@@ -81,13 +81,11 @@ const createComponent = ({ state, props, options }) => { ...@@ -81,13 +81,11 @@ const createComponent = ({ state, props, options }) => {
}, },
...options, ...options,
store: fakeStore, store: fakeStore,
stubs: {
GlTabs,
GlTab,
},
}); });
}; };
const findByTestId = testId => wrapper.find(`[data-testid="${testId}"]`);
describe('Project Licenses', () => { describe('Project Licenses', () => {
afterEach(() => { afterEach(() => {
wrapper.destroy(); wrapper.destroy();
...@@ -188,66 +186,62 @@ describe('Project Licenses', () => { ...@@ -188,66 +186,62 @@ describe('Project Licenses', () => {
expect(wrapper.findAll(GlTab)).toHaveLength(2); expect(wrapper.findAll(GlTab)).toHaveLength(2);
}); });
it('it renders the "Detected in project" table', () => {
expect(wrapper.find(DetectedLicensesTable).exists()).toBe(true);
});
it('it renders the "Policies" table', () => {
expect(wrapper.find(LicenseManagement).exists()).toBe(true);
});
it('renders the pipeline info', () => {
expect(wrapper.find(PipelineInfo).exists()).toBe(true);
});
describe.each` describe.each`
givenLocationHash | expectedTabIndex givenLocationHash | expectedActiveTab
${'licenses'} | ${0} ${'#licenses'} | ${'licenses'}
${'policies'} | ${1} ${'#policies'} | ${'policies'}
${'foo'} | ${0}
${'bar'} | ${0}
`( `(
'when the url contains $givenLocationHash hash', 'when window.location contains the hash "$givenLocationHash"',
({ givenLocationHash, expectedTabIndex }) => { ({ givenLocationHash, expectedActiveTab }) => {
const originalLocation = window.location;
beforeEach(() => { beforeEach(() => {
setWindowLocation({ setWindowLocation(`http://foo.com/index${givenLocationHash}`);
href: `${TEST_HOST}#${givenLocationHash}`,
});
createComponent({ createComponent({
state: { state: {
initialized: true, initialized: true,
isLoading: false,
licenses: [
{
name: 'MIT',
classification: LICENSE_APPROVAL_CLASSIFICATION.DENIED,
components: [],
},
],
pageInfo: 1,
}, },
options: { options: {
provide: { provide: {
glFeatures: { licensePolicyList: true }, glFeatures: { licensePolicyList: true },
}, },
mount: true,
}, },
}); });
}); });
it(`sets the tabIndex to be "${expectedTabIndex}"`, () => { afterEach(() => {
expect(wrapper.find(GlTabs).attributes('value')).toBe(`${expectedTabIndex}`); window.location = originalLocation;
}); });
},
);
it.each`
givenTabIndex | expectedLocationHash
${0} | ${'licenses'}
${1} | ${'policies'}
`(
'sets the location hash to "tabName" when the corresponding tab is activated',
({ givenTabIndex, expectedLocationHash }) => {
wrapper.setData({ tabIndex: givenTabIndex });
wrapper.vm.$forceUpdate();
return wrapper.vm.$nextTick().then(() => { it(`sets the active tab to be "${expectedActiveTab}"`, () => {
expect(window.location.hash).toBe(expectedLocationHash); expect(findByTestId(`${expectedActiveTab}Tab`).classes()).toContain('active');
}); });
}, },
); );
it('it renders the "Detected in project" table', () => {
expect(wrapper.find(DetectedLicensesTable).exists()).toBe(true);
});
it('it renders the "Policies" table', () => {
expect(wrapper.find(LicenseManagement).exists()).toBe(true);
});
it('renders the pipeline info', () => {
expect(wrapper.find(PipelineInfo).exists()).toBe(true);
});
describe('when the tabs are rendered', () => { describe('when the tabs are rendered', () => {
const pageInfo = { const pageInfo = {
total: 1, total: 1,
...@@ -281,6 +275,21 @@ describe('Project Licenses', () => { ...@@ -281,6 +275,21 @@ describe('Project Licenses', () => {
}); });
}); });
it.each`
givenActiveTab | expectedLocationHash
${'policies'} | ${'#policies'}
${'licenses'} | ${'#licenses'}
`(
'sets the location hash to "$expectedLocationHash" when the "$givenTab" tab is activate',
({ givenActiveTab, expectedLocationHash }) => {
findByTestId(`${givenActiveTab}TabTitle`).trigger('click');
return wrapper.vm.$nextTick().then(() => {
expect(window.location.hash).toBe(expectedLocationHash);
});
},
);
it('it renders the correct count in "Detected in project" tab', () => { it('it renders the correct count in "Detected in project" tab', () => {
expect( expect(
wrapper wrapper
......
/** /**
* setWindowLocation allows for setting properties of `window.location` * setWindowLocation allows for setting `window.location`
* (doing so directly is causing an error in jsdom) * (doing so directly is causing an error in jsdom)
* *
* Example usage: * Example usage:
* assert(window.location.hash === undefined); * assert(window.location.hash === undefined);
* setWindowLocation({ * setWindowLocation('http://example.com#foo')
* href: 'http://example.com#foo'
* })
* assert(window.location.hash === '#foo'); * assert(window.location.hash === '#foo');
* *
* More information: * More information:
* https://github.com/facebook/jest/issues/890 * https://github.com/facebook/jest/issues/890
* *
* @param value * @param url
*/ */
export default function setWindowLocation(value) { export default function setWindowLocation(url) {
const parsedUrl = new URL(url);
const newLocationValue = [
'hash',
'host',
'hostname',
'href',
'origin',
'pathname',
'port',
'protocol',
'search',
].reduce(
(location, prop) => ({
...location,
[prop]: parsedUrl[prop],
}),
{},
);
Object.defineProperty(window, 'location', { Object.defineProperty(window, 'location', {
value: newLocationValue,
writable: true, writable: true,
value,
}); });
} }
import setWindowLocationHelper from './set_window_location_helper'; import setWindowLocation from './set_window_location_helper';
describe('setWindowLocationHelper', () => { describe('setWindowLocation', () => {
const originalLocation = window.location; const originalLocation = window.location;
afterEach(() => { afterEach(() => {
...@@ -8,22 +8,33 @@ describe('setWindowLocationHelper', () => { ...@@ -8,22 +8,33 @@ describe('setWindowLocationHelper', () => {
}); });
it.each` it.each`
property | value url | property | value
${'hash'} | ${'foo'} ${'https://gitlab.com#foo'} | ${'hash'} | ${'#foo'}
${'host'} | ${'gitlab.com'} ${'http://gitlab.com'} | ${'host'} | ${'gitlab.com'}
${'hostname'} | ${'gitlab.com'} ${'http://gitlab.org'} | ${'hostname'} | ${'gitlab.org'}
${'href'} | ${'https://gitlab.com/foo'} ${'http://gitlab.org/foo#bar'} | ${'href'} | ${'http://gitlab.org/foo#bar'}
${'origin'} | ${'https://gitlab.com'} ${'http://gitlab.com'} | ${'origin'} | ${'http://gitlab.com'}
${'origin'} | ${'/foo'} ${'http://gitlab.com/foo/bar/baz'} | ${'pathname'} | ${'/foo/bar/baz'}
${'port'} | ${'80'} ${'https://gitlab.com'} | ${'protocol'} | ${'https:'}
${'protocol'} | ${'https:'} ${'http://gitlab.com#foo'} | ${'protocol'} | ${'http:'}
`('sets "window.location.$property" to be $value', ({ property, value }) => { ${'http://gitlab.com:8080'} | ${'port'} | ${'8080'}
${'http://gitlab.com?foo=bar&bar=foo'} | ${'search'} | ${'?foo=bar&bar=foo'}
`(
'sets "window.location.$property" to be "$value" when called with: "$url"',
({ url, property, value }) => {
expect(window.location).toBe(originalLocation); expect(window.location).toBe(originalLocation);
setWindowLocationHelper({ setWindowLocation(url);
[property]: value,
});
expect(window.location[property]).toBe(value); expect(window.location[property]).toBe(value);
}); },
);
it.each([null, 1, undefined, false, '', 'gitlab.com'])(
'throws an error when called with an invalid url: "%s"',
invalidUrl => {
expect(() => setWindowLocation(invalidUrl)).toThrow(new TypeError('Invalid URL'));
expect(window.location).toBe(originalLocation);
},
);
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment