@gitlab/ui
Version:
GitLab UI Components
136 lines (114 loc) • 4.01 kB
JavaScript
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
import GlLink from '../../components/base/link/link.vue';
import { absoluteUrls, javascriptUrls, encodedJavaScriptUrls, relativeUrls } from './mock_data';
import { SafeLinkDirective } from './safe_link';
const httpLink = 'https://gitlab.com';
describe('safe link directive', () => {
let wrapper;
const createComponent = ({
href,
safeLinkConfig = {},
components,
template = `<a v-safe-link :href="href" target="_blank">Click</a>`,
mountFn = shallowMount,
} = {}) => {
const component = {
props: {
href: { type: String },
safeLinkConfig: { type: Object },
},
directives: {
SafeLink: SafeLinkDirective,
},
components,
template,
};
wrapper = mountFn(component, { propsData: { href, safeLinkConfig } });
};
describe('default', () => {
it('should render the anchor tag with given href', () => {
createComponent({
href: httpLink,
});
expect(wrapper.element.tagName).toBe('A');
expect(wrapper.attributes('href')).toBe(httpLink);
});
it('should render the element with secure rel attr', () => {
createComponent({
href: httpLink,
});
expect(wrapper.attributes('rel')).toBe(`noopener noreferrer`);
});
});
describe('invalid urls', () => {
it.each(javascriptUrls)('%s should be sanitized', (url) => {
createComponent({
href: url,
});
expect(wrapper.attributes('href')).toBe('about:blank');
});
});
describe('valid urls', () => {
const validUrls = [...absoluteUrls, ...relativeUrls, ...encodedJavaScriptUrls];
/* Note:
/* Encoded JavaScript URLs are safe urls in Vue context, since
/* Vue attribute bindings are also automatically escaped
/* https://vuejs.org/v2/guide/security.html#Injecting-URLs
*/
it.each(validUrls)('%s should be rendered', (url) => {
createComponent({
href: url,
});
expect(wrapper.attributes('href')).toBe(url);
});
});
describe('`skipSanitization` arg', () => {
it.each(javascriptUrls)('%s should be rendered', (url) => {
createComponent({
href: url,
safeLinkConfig: { skipSanitization: true },
template: '<a v-safe-link:[safeLinkConfig] :href="href" target="_blank">Click</a>',
});
expect(wrapper.attributes('href')).toBe(url);
});
});
describe('reactivity', () => {
it('should sanitize the updated url', async () => {
createComponent({
mountFn: mount,
components: { GlLink },
template: '<gl-link :href="href" target="_blank">Click</gl-link>',
href: javascriptUrls[0],
});
expect(wrapper.attributes('href')).toBe('about:blank');
// set href to a valid url
await wrapper.setProps({ href: 'https://gitlab.com' });
expect(wrapper.attributes('href')).toBe('https://gitlab.com');
// set href to back to an invalid url
await wrapper.setProps({ href: javascriptUrls[1] });
await Vue.nextTick();
expect(wrapper.attributes('href')).toBe('about:blank');
});
describe('`skipSanitization` arg', () => {
it('should not sanitize the updated url', async () => {
const url = javascriptUrls[0];
createComponent({
mountFn: mount,
components: { GlLink },
template: '<gl-link is-unsafe-link :href="href" target="_blank">Click</gl-link>',
href: url,
});
expect(wrapper.attributes('href')).toBe(url);
// set href to a valid url
await wrapper.setProps({ href: 'https://gitlab.com' });
await Vue.nextTick();
expect(wrapper.attributes('href')).toBe('https://gitlab.com');
// set href to back to an invalid url
await wrapper.setProps({ href: url });
await Vue.nextTick();
expect(wrapper.attributes('href')).toBe(url);
});
});
});
});