1 | import { shallowMount } from '@vue/test-utils';
|
2 | import FriendlyWrap from './friendly_wrap.vue';
|
3 |
|
4 | describe('Friendly wrap component', () => {
|
5 | let wrapper;
|
6 |
|
7 | const createComponent = (props) => {
|
8 | wrapper = shallowMount(FriendlyWrap, {
|
9 | propsData: props,
|
10 | });
|
11 | };
|
12 |
|
13 | it('wraps text on slashes by default', () => {
|
14 | const text = '/some/file/path';
|
15 | const textWrapped = '/<wbr>some/<wbr>file/<wbr>path';
|
16 | createComponent({
|
17 | text,
|
18 | });
|
19 |
|
20 | expect(wrapper.text()).toBe(text);
|
21 | expect(wrapper.html()).toMatch(textWrapped);
|
22 | });
|
23 |
|
24 | it('supports backslashes', () => {
|
25 | const text = '\\some\\long\\file\\path';
|
26 | const textWrapped = '\\<wbr>some\\<wbr>long\\<wbr>file\\<wbr>path';
|
27 | createComponent({
|
28 | text,
|
29 | symbols: ['\\'],
|
30 | });
|
31 | expect(wrapper.text()).toBe(text);
|
32 | expect(wrapper.html()).toMatch(textWrapped);
|
33 | });
|
34 |
|
35 | it('accepts multiple symbols', () => {
|
36 | const text = 'some;text-that.needs;to-be.wrapped';
|
37 | const textWrapped = 'some;<wbr>text-<wbr>that.<wbr>needs;<wbr>to-<wbr>be.<wbr>wrapped';
|
38 | createComponent({
|
39 | text,
|
40 | symbols: [';', '-', '.'],
|
41 | });
|
42 | expect(wrapper.text()).toBe(text);
|
43 | expect(wrapper.html()).toMatch(textWrapped);
|
44 | });
|
45 |
|
46 | it('works with words', () => {
|
47 | const text = 'it goes on and on and on and on';
|
48 | const textWrapped = 'it goes on and<wbr> on and<wbr> on and<wbr> on';
|
49 | createComponent({
|
50 | text,
|
51 | symbols: ['and'],
|
52 | });
|
53 | expect(wrapper.text()).toBe(text);
|
54 | expect(wrapper.html()).toMatch(textWrapped);
|
55 | });
|
56 |
|
57 | it(`does not break with sensitive symbols like '<' or 'w' or 'b' or 'r' or '>'`, () => {
|
58 | const text = '< or w or b or r or >';
|
59 | const textWrapped = '<<wbr> or<wbr> w<wbr> or<wbr> b<wbr> or<wbr> r<wbr> or<wbr> >';
|
60 | createComponent({
|
61 | text,
|
62 | symbols: ['<', ...'wbr'.split(''), '>'],
|
63 | });
|
64 |
|
65 | expect(wrapper.text()).toBe(text);
|
66 | expect(wrapper.html()).toMatch(textWrapped);
|
67 | });
|
68 |
|
69 | it('allows HTML entities as words', () => {
|
70 | const text = 'foo<foo>foo>foo<foo';
|
71 | const textWrapped = 'foo&lt;<wbr>foo&gt;<wbr>foo>foo<foo';
|
72 | createComponent({
|
73 | text,
|
74 | symbols: ['<', '>'],
|
75 | });
|
76 |
|
77 | expect(wrapper.text()).toBe(text);
|
78 | expect(wrapper.html()).toMatch(textWrapped);
|
79 | });
|
80 |
|
81 | it('escapes text to prevent XSS', () => {
|
82 | const text = '<script>alert(1)</script>';
|
83 | const textWrapped = '<script>alert(1)</<wbr>script>';
|
84 | createComponent({
|
85 | text,
|
86 | });
|
87 |
|
88 | expect(wrapper.text()).toBe(text);
|
89 | expect(wrapper.html()).toMatch(textWrapped);
|
90 | });
|
91 |
|
92 | it('does not unnecessarily insert a wbr at the end', () => {
|
93 | const text = '/';
|
94 | createComponent({
|
95 | text,
|
96 | });
|
97 |
|
98 | expect(wrapper.text()).toBe(text);
|
99 | expect(wrapper.find('wbr').exists()).toBe(false);
|
100 | });
|
101 |
|
102 | it('does not insert unnecessary whitespace', () => {
|
103 | const text = '';
|
104 | createComponent({
|
105 | text,
|
106 | });
|
107 |
|
108 |
|
109 | expect(wrapper.element.textContent).toBe(text);
|
110 | });
|
111 |
|
112 | it.each([null, undefined])('gracefully handles %p', (text) => {
|
113 | createComponent({
|
114 | text,
|
115 | });
|
116 |
|
117 |
|
118 | expect(wrapper).toHaveLoggedVueErrors();
|
119 |
|
120 |
|
121 | expect(wrapper.text()).toBe('');
|
122 | });
|
123 | });
|