Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
6a3b4071
Commit
6a3b4071
authored
Jan 23, 2020
by
Natalia Tepluhina
Committed by
Martin Wortschack
Jan 23, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert Jest tests to use VTU in 'spec/frontend/vue_shared'
parent
0768943e
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
509 additions
and
397 deletions
+509
-397
app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
...ed_search/components/recent_searches_dropdown_content.vue
+12
-5
app/assets/javascripts/vue_shared/components/identicon.vue
app/assets/javascripts/vue_shared/components/identicon.vue
+1
-1
app/assets/javascripts/vue_shared/components/issue/issue_warning.vue
...javascripts/vue_shared/components/issue/issue_warning.vue
+3
-3
app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
...ascripts/vue_shared/components/notes/placeholder_note.vue
+1
-1
spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js
...earch/components/recent_searches_dropdown_content_spec.js
+80
-156
spec/frontend/vue_shared/components/__snapshots__/code_block_spec.js.snap
...e_shared/components/__snapshots__/code_block_spec.js.snap
+16
-0
spec/frontend/vue_shared/components/__snapshots__/identicon_spec.js.snap
...ue_shared/components/__snapshots__/identicon_spec.js.snap
+11
-0
spec/frontend/vue_shared/components/code_block_spec.js
spec/frontend/vue_shared/components/code_block_spec.js
+15
-23
spec/frontend/vue_shared/components/identicon_spec.js
spec/frontend/vue_shared/components/identicon_spec.js
+24
-56
spec/frontend/vue_shared/components/issue/__snapshots__/issue_warning_spec.js.snap
...components/issue/__snapshots__/issue_warning_spec.js.snap
+62
-0
spec/frontend/vue_shared/components/issue/issue_warning_spec.js
...rontend/vue_shared/components/issue/issue_warning_spec.js
+87
-47
spec/frontend/vue_shared/components/markdown/__snapshots__/suggestion_diff_spec.js.snap
...nents/markdown/__snapshots__/suggestion_diff_spec.js.snap
+28
-0
spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
...nd/vue_shared/components/markdown/suggestion_diff_spec.js
+34
-49
spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_note_spec.js.snap
...ponents/notes/__snapshots__/placeholder_note_spec.js.snap
+62
-0
spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_system_note_spec.js.snap
.../notes/__snapshots__/placeholder_system_note_spec.js.snap
+15
-0
spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
...tend/vue_shared/components/notes/placeholder_note_spec.js
+42
-38
spec/frontend/vue_shared/components/notes/placeholder_system_note_spec.js
...e_shared/components/notes/placeholder_system_note_spec.js
+16
-18
No files found.
app/assets/javascripts/filtered_search/components/recent_searches_dropdown_content.vue
View file @
6a3b4071
...
...
@@ -59,21 +59,25 @@ export default {
</
script
>
<
template
>
<div>
<div
v-if=
"!isLocalStorageAvailable"
class=
"dropdown-info-note"
>
<div
v-if=
"!isLocalStorageAvailable"
ref=
"localStorageNote"
class=
"dropdown-info-note"
>
{{
__
(
'
This feature requires local storage to be enabled
'
)
}}
</div>
<ul
v-else-if=
"hasItems"
>
<li
v-for=
"(item, index) in processedItems"
:key=
"`processed-items-$
{index}`">
<li
v-for=
"(item, index) in processedItems"
ref=
"dropdownItem"
:key=
"`processed-items-$
{index}`"
>
<button
type=
"button"
class=
"filtered-search-history-dropdown-item"
class=
"filtered-search-history-dropdown-item
js-dropdown-button
"
@
click=
"onItemActivated(item.text)"
>
<span>
<span
v-for=
"(token, tokenIndex) in item.tokens"
:key=
"`dropdown-token-$
{tokenIndex}`"
class="filtered-search-history-dropdown-token"
class="filtered-search-history-dropdown-token
js-dropdown-token
"
>
<span
class=
"name"
>
{{
token
.
prefix
}}
</span>
<span
class=
"name"
>
{{
token
.
operator
}}
</span>
...
...
@@ -88,6 +92,7 @@ export default {
<li
class=
"divider"
></li>
<li>
<button
ref=
"clearButton"
type=
"button"
class=
"filtered-search-history-clear-button"
@
click=
"onRequestClearRecentSearches($event)"
...
...
@@ -96,6 +101,8 @@ export default {
</button>
</li>
</ul>
<div
v-else
class=
"dropdown-info-note"
>
{{
__
(
"
You don't have any recent searches
"
)
}}
</div>
<div
v-else
ref=
"dropdownNote"
class=
"dropdown-info-note"
>
{{
__
(
"
You don't have any recent searches
"
)
}}
</div>
</div>
</
template
>
app/assets/javascripts/vue_shared/components/identicon.vue
View file @
6a3b4071
...
...
@@ -29,7 +29,7 @@ export default {
</
script
>
<
template
>
<div
:class=
"[sizeClass, identiconBackgroundClass]"
class=
"avatar identicon"
>
<div
ref=
"identicon"
:class=
"[sizeClass, identiconBackgroundClass]"
class=
"avatar identicon"
>
{{
identiconTitle
}}
</div>
</
template
>
app/assets/javascripts/vue_shared/components/issue/issue_warning.vue
View file @
6a3b4071
...
...
@@ -65,14 +65,14 @@ export default {
<div
class=
"issuable-note-warning"
>
<icon
v-if=
"!isLockedAndConfidential"
:name=
"warningIcon"
:size=
"16"
class=
"icon inline"
/>
<span
v-if=
"isLockedAndConfidential"
>
<span
v-if=
"isLockedAndConfidential"
ref=
"lockedAndConfidential"
>
<span
v-html=
"confidentialAndLockedDiscussionText"
></span>
{{
__
(
"
People without permission will never get a notification and won't be able to comment.
"
)
}}
</span>
<span
v-else-if=
"isConfidential"
>
<span
v-else-if=
"isConfidential"
ref=
"confidential"
>
{{
__
(
'
This is a confidential issue.
'
)
}}
{{
__
(
'
People without permission will never get a notification.
'
)
}}
<gl-link
:href=
"confidentialIssueDocsPath"
target=
"_blank"
>
...
...
@@ -80,7 +80,7 @@ export default {
</gl-link>
</span>
<span
v-else-if=
"isLocked"
>
<span
v-else-if=
"isLocked"
ref=
"locked"
>
{{
__
(
'
This issue is locked.
'
)
}}
{{
__
(
'
Only project members can comment.
'
)
}}
<gl-link
:href=
"lockedIssueDocsPath"
target=
"_blank"
>
...
...
app/assets/javascripts/vue_shared/components/notes/placeholder_note.vue
View file @
6a3b4071
...
...
@@ -47,7 +47,7 @@ export default {
:img-size=
"40"
/>
</div>
<div
:class=
"
{ discussion: !note.individual_note }" class="timeline-content">
<div
ref=
"note"
:class=
"
{ discussion: !note.individual_note }" class="timeline-content">
<div
class=
"note-header"
>
<div
class=
"note-header-info"
>
<a
:href=
"getUserData.path"
>
...
...
spec/frontend/filtered_search/components/recent_searches_dropdown_content_spec.js
View file @
6a3b4071
import
Vue
from
'
vue
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
eventHub
from
'
~/filtered_search/event_hub
'
;
import
RecentSearchesDropdownContent
from
'
~/filtered_search/components/recent_searches_dropdown_content.vue
'
;
import
IssuableFilteredSearchTokenKeys
from
'
~/filtered_search/issuable_filtered_search_token_keys
'
;
const
createComponent
=
propsData
=>
{
const
Component
=
Vue
.
extend
(
RecentSearchesDropdownContent
);
return
new
Component
({
el
:
document
.
createElement
(
'
div
'
),
propsData
,
});
};
// Remove all the newlines and whitespace from the formatted markup
const
trimMarkupWhitespace
=
text
=>
text
.
replace
(
/
(\n
|
\s)
+/gm
,
'
'
).
trim
();
describe
(
'
RecentSearchesDropdownContent
'
,
()
=>
{
const
propsDataWithoutItems
=
{
items
:
[],
allowedKeys
:
IssuableFilteredSearchTokenKeys
.
getKeys
(),
};
const
propsDataWithItems
=
{
items
:
[
'
foo
'
,
'
author:@root label:~foo bar
'
],
allowedKeys
:
IssuableFilteredSearchTokenKeys
.
getKeys
(),
describe
(
'
Recent Searches Dropdown Content
'
,
()
=>
{
let
wrapper
;
const
findLocalStorageNote
=
()
=>
wrapper
.
find
({
ref
:
'
localStorageNote
'
});
const
findDropdownItems
=
()
=>
wrapper
.
findAll
({
ref
:
'
dropdownItem
'
});
const
findDropdownNote
=
()
=>
wrapper
.
find
({
ref
:
'
dropdownNote
'
});
const
createComponent
=
props
=>
{
wrapper
=
shallowMount
(
RecentSearchesDropdownContent
,
{
propsData
:
{
allowedKeys
:
IssuableFilteredSearchTokenKeys
.
getKeys
(),
items
:
[],
isLocalStorageAvailable
:
false
,
...
props
,
},
});
};
let
vm
;
afterEach
(()
=>
{
if
(
vm
)
{
vm
.
$destroy
();
}
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
with no items
'
,
()
=>
{
let
el
;
describe
(
'
when local storage is not available
'
,
()
=>
{
beforeEach
(()
=>
{
vm
=
createComponent
(
propsDataWithoutItems
);
el
=
vm
.
$el
;
createComponent
();
});
it
(
'
should render empty state
'
,
()
=>
{
expect
(
el
.
querySelector
(
'
.dropdown-info-note
'
)).
toBeDefined
();
const
items
=
el
.
querySelectorAll
(
'
.filtered-search-history-dropdown-item
'
);
expect
(
items
.
length
).
toEqual
(
propsDataWithoutItems
.
items
.
length
);
it
(
'
renders a note about enabling local storage
'
,
()
=>
{
expect
(
findLocalStorageNote
().
exists
()).
toBe
(
true
);
});
});
describe
(
'
with items
'
,
()
=>
{
let
el
;
beforeEach
(()
=>
{
vm
=
createComponent
(
propsDataWithItems
);
el
=
vm
.
$el
;
it
(
'
does not render dropdown items
'
,
()
=>
{
expect
(
findDropdownItems
().
exists
()).
toBe
(
false
);
});
it
(
'
should render clear recent searches button
'
,
()
=>
{
expect
(
el
.
querySelector
(
'
.filtered-search-history-clear-button
'
)).
toBeDefined
(
);
it
(
'
does not render dropdownNote
'
,
()
=>
{
expect
(
findDropdownNote
().
exists
()).
toBe
(
false
);
});
});
it
(
'
should render recent search items
'
,
()
=>
{
const
items
=
el
.
querySelectorAll
(
'
.filtered-search-history-dropdown-item
'
);
expect
(
items
.
length
).
toEqual
(
propsDataWithItems
.
items
.
length
);
describe
(
'
when localStorage is available and items array is not empty
'
,
()
=>
{
let
onRecentSearchesItemSelectedSpy
;
let
onRequestClearRecentSearchesSpy
;
expect
(
trimMarkupWhitespace
(
items
[
0
].
querySelector
(
'
.filtered-search-history-dropdown-search-token
'
).
textContent
,
),
).
toEqual
(
'
foo
'
);
const
item1Tokens
=
items
[
1
].
querySelectorAll
(
'
.filtered-search-history-dropdown-token
'
);
expect
(
item1Tokens
.
length
).
toEqual
(
2
);
expect
(
item1Tokens
[
0
].
querySelector
(
'
.name
'
).
textContent
).
toEqual
(
'
author:
'
);
expect
(
item1Tokens
[
0
].
querySelector
(
'
.value
'
).
textContent
).
toEqual
(
'
@root
'
);
expect
(
item1Tokens
[
1
].
querySelector
(
'
.name
'
).
textContent
).
toEqual
(
'
label:
'
);
expect
(
item1Tokens
[
1
].
querySelector
(
'
.value
'
).
textContent
).
toEqual
(
'
~foo
'
);
expect
(
trimMarkupWhitespace
(
items
[
1
].
querySelector
(
'
.filtered-search-history-dropdown-search-token
'
).
textContent
,
),
).
toEqual
(
'
bar
'
);
beforeAll
(()
=>
{
onRecentSearchesItemSelectedSpy
=
jest
.
fn
();
onRequestClearRecentSearchesSpy
=
jest
.
fn
();
eventHub
.
$on
(
'
recentSearchesItemSelected
'
,
onRecentSearchesItemSelectedSpy
);
eventHub
.
$on
(
'
requestClearRecentSearches
'
,
onRequestClearRecentSearchesSpy
);
});
});
describe
(
'
if isLocalStorageAvailable is `false`
'
,
()
=>
{
let
el
;
beforeEach
(()
=>
{
c
onst
props
=
Object
.
assign
({
isLocalStorageAvailable
:
false
},
propsDataWithItems
);
vm
=
createComponent
(
props
);
el
=
vm
.
$el
;
c
reateComponent
({
items
:
[
'
foo
'
,
'
author:@root label:~foo bar
'
],
isLocalStorageAvailable
:
true
,
})
;
});
it
(
'
should render an info note
'
,
()
=>
{
const
note
=
el
.
querySelector
(
'
.dropdown-info-note
'
);
const
items
=
el
.
querySelectorAll
(
'
.filtered-search-history-dropdown-item
'
);
afterAll
(()
=>
{
eventHub
.
$off
(
'
recentSearchesItemSelected
'
,
onRecentSearchesItemSelectedSpy
);
eventHub
.
$off
(
'
requestClearRecentSearchesSpy
'
,
onRequestClearRecentSearchesSpy
);
});
expect
(
note
).
toBeDefined
();
expect
(
note
.
innerText
.
trim
()).
toBe
(
'
This feature requires local storage to be enabled
'
);
expect
(
items
.
length
).
toEqual
(
propsDataWithoutItems
.
items
.
length
);
it
(
'
does not render a note about enabling local storage
'
,
()
=>
{
expect
(
findLocalStorageNote
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
computed
'
,
()
=>
{
describe
(
'
processedItems
'
,
()
=>
{
it
(
'
with items
'
,
()
=>
{
vm
=
createComponent
(
propsDataWithItems
);
const
{
processedItems
}
=
vm
;
expect
(
processedItems
.
length
).
toEqual
(
2
);
expect
(
processedItems
[
0
].
text
).
toEqual
(
propsDataWithItems
.
items
[
0
]);
expect
(
processedItems
[
0
].
tokens
).
toEqual
([]);
expect
(
processedItems
[
0
].
searchToken
).
toEqual
(
'
foo
'
);
expect
(
processedItems
[
1
].
text
).
toEqual
(
propsDataWithItems
.
items
[
1
]);
expect
(
processedItems
[
1
].
tokens
.
length
).
toEqual
(
2
);
expect
(
processedItems
[
1
].
tokens
[
0
].
prefix
).
toEqual
(
'
author:
'
);
expect
(
processedItems
[
1
].
tokens
[
0
].
suffix
).
toEqual
(
'
@root
'
);
expect
(
processedItems
[
1
].
tokens
[
1
].
prefix
).
toEqual
(
'
label:
'
);
expect
(
processedItems
[
1
].
tokens
[
1
].
suffix
).
toEqual
(
'
~foo
'
);
expect
(
processedItems
[
1
].
searchToken
).
toEqual
(
'
bar
'
);
});
it
(
'
does not render dropdownNote
'
,
()
=>
{
expect
(
findDropdownNote
().
exists
()).
toBe
(
false
);
});
it
(
'
with no
items
'
,
()
=>
{
vm
=
createComponent
(
propsDataWithoutItems
);
const
{
processedItems
}
=
vm
;
it
(
'
renders a correct amount of dropdown
items
'
,
()
=>
{
expect
(
findDropdownItems
()).
toHaveLength
(
2
);
})
;
expect
(
processedItems
.
length
).
toEqual
(
0
);
});
it
(
'
expect second dropdown to have 2 tokens
'
,
()
=>
{
expect
(
findDropdownItems
()
.
at
(
1
)
.
findAll
(
'
.js-dropdown-token
'
),
).
toHaveLength
(
2
);
});
describe
(
'
hasItems
'
,
()
=>
{
it
(
'
with items
'
,
()
=>
{
vm
=
createComponent
(
propsDataWithItems
);
const
{
hasItems
}
=
vm
;
it
(
'
emits recentSearchesItemSelected on dropdown item click
'
,
()
=>
{
findDropdownItems
()
.
at
(
0
)
.
find
(
'
.js-dropdown-button
'
)
.
trigger
(
'
click
'
);
expect
(
hasItems
).
toEqual
(
true
);
});
expect
(
onRecentSearchesItemSelectedSpy
).
toHaveBeenCalledWith
(
'
foo
'
);
});
it
(
'
with no items
'
,
()
=>
{
vm
=
createComponent
(
propsDataWithoutItems
);
const
{
hasItems
}
=
vm
;
it
(
'
emits requestClearRecentSearches on Clear resent searches button
'
,
()
=>
{
wrapper
.
find
({
ref
:
'
clearButton
'
}).
trigger
(
'
click
'
);
expect
(
hasItems
).
toEqual
(
false
);
});
expect
(
onRequestClearRecentSearchesSpy
).
toHaveBeenCalled
();
});
});
describe
(
'
methods
'
,
()
=>
{
describe
(
'
onItemActivated
'
,
()
=>
{
let
onRecentSearchesItemSelectedSpy
;
beforeEach
(()
=>
{
onRecentSearchesItemSelectedSpy
=
jest
.
fn
();
eventHub
.
$on
(
'
recentSearchesItemSelected
'
,
onRecentSearchesItemSelectedSpy
);
vm
=
createComponent
(
propsDataWithItems
);
});
afterEach
(()
=>
{
eventHub
.
$off
(
'
recentSearchesItemSelected
'
,
onRecentSearchesItemSelectedSpy
);
});
it
(
'
emits event
'
,
()
=>
{
expect
(
onRecentSearchesItemSelectedSpy
).
not
.
toHaveBeenCalled
();
vm
.
onItemActivated
(
'
something
'
);
expect
(
onRecentSearchesItemSelectedSpy
).
toHaveBeenCalledWith
(
'
something
'
);
describe
(
'
when locale storage is available and items array is empty
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
isLocalStorageAvailable
:
true
,
});
});
describe
(
'
onRequestClearRecentSearches
'
,
()
=>
{
let
onRequestClearRecentSearchesSpy
;
beforeEach
(()
=>
{
onRequestClearRecentSearchesSpy
=
jest
.
fn
();
eventHub
.
$on
(
'
requestClearRecentSearches
'
,
onRequestClearRecentSearchesSpy
);
vm
=
createComponent
(
propsDataWithItems
);
});
afterEach
(()
=>
{
eventHub
.
$off
(
'
requestClearRecentSearches
'
,
onRequestClearRecentSearchesSpy
);
});
it
(
'
does not render a note about enabling local storage
'
,
()
=>
{
expect
(
findLocalStorageNote
().
exists
()).
toBe
(
false
);
});
it
(
'
emits event
'
,
()
=>
{
expect
(
onRequestClearRecentSearchesSpy
).
not
.
toHaveBeenCalled
(
);
vm
.
onRequestClearRecentSearches
({
stopPropagation
:
()
=>
{}
});
it
(
'
does not render dropdown items
'
,
()
=>
{
expect
(
findDropdownItems
().
exists
()).
toBe
(
false
);
});
expect
(
onRequestClearRecentSearchesSpy
).
toHaveBeenCalled
();
}
);
it
(
'
renders dropdown note
'
,
()
=>
{
expect
(
findDropdownNote
().
exists
()).
toBe
(
true
);
});
});
});
spec/frontend/vue_shared/components/__snapshots__/code_block_spec.js.snap
0 → 100644
View file @
6a3b4071
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Code Block matches snapshot 1`] = `
<pre
class="code-block rounded"
>
<code
class="d-block"
>
test-code
</code>
</pre>
`;
spec/frontend/vue_shared/components/__snapshots__/identicon_spec.js.snap
0 → 100644
View file @
6a3b4071
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Identicon matches snapshot 1`] = `
<div
class="avatar identicon s40 bg2"
>
E
</div>
`;
spec/frontend/vue_shared/components/code_block_spec.js
View file @
6a3b4071
import
Vue
from
'
vue
'
;
import
component
from
'
~/vue_shared/components/code_block.vue
'
;
import
mountComponent
from
'
../../helpers/vue_mount_component_helper
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
CodeBlock
from
'
~/vue_shared/components/code_block.vue
'
;
describe
(
'
Code Block
'
,
()
=>
{
const
Component
=
Vue
.
extend
(
component
);
let
vm
;
let
wrapper
;
afterEach
(()
=>
{
vm
.
$destroy
();
});
it
(
'
renders a code block with the provided code
'
,
()
=>
{
const
code
=
"
Failure/Error: is_expected.to eq(3)
\n\n
expected: 3
\n
got: -1
\n\n
(compared using ==)
\n
./spec/test_spec.rb:12:in `block (4 levels) in
\
u003ctop (required)
\
u003e'
"
;
vm
=
mountComponent
(
Component
,
{
code
,
const
createComponent
=
()
=>
{
wrapper
=
shallowMount
(
CodeBlock
,
{
propsData
:
{
code
:
'
test-code
'
,
},
});
};
expect
(
vm
.
$el
.
querySelector
(
'
code
'
).
textContent
).
toEqual
(
code
);
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
it
(
'
escapes XSS injections
'
,
()
=>
{
const
code
=
'
CCC<img src=x onerror=alert(document.domain)>
'
;
vm
=
mountComponent
(
Component
,
{
code
,
});
it
(
'
matches snapshot
'
,
()
=>
{
createComponent
();
expect
(
vm
.
$el
.
querySelector
(
'
code
'
).
textContent
).
toEqual
(
code
);
expect
(
wrapper
.
element
).
toMatchSnapshot
(
);
});
});
spec/frontend/vue_shared/components/identicon_spec.js
View file @
6a3b4071
import
Vue
from
'
vue
'
;
import
identiconComponent
from
'
~/vue_shared/components/identicon.vue
'
;
const
createComponent
=
sizeClass
=>
{
const
Component
=
Vue
.
extend
(
identiconComponent
);
return
new
Component
({
propsData
:
{
entityId
:
1
,
entityName
:
'
entity-name
'
,
sizeClass
,
},
}).
$mount
();
};
describe
(
'
IdenticonComponent
'
,
()
=>
{
describe
(
'
computed
'
,
()
=>
{
let
vm
;
beforeEach
(()
=>
{
vm
=
createComponent
();
});
afterEach
(()
=>
{
vm
.
$destroy
();
});
describe
(
'
identiconBackgroundClass
'
,
()
=>
{
it
(
'
should return bg class based on entityId
'
,
()
=>
{
vm
.
entityId
=
4
;
expect
(
vm
.
identiconBackgroundClass
).
toBeDefined
();
expect
(
vm
.
identiconBackgroundClass
).
toBe
(
'
bg5
'
);
});
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
IdenticonComponent
from
'
~/vue_shared/components/identicon.vue
'
;
describe
(
'
Identicon
'
,
()
=>
{
let
wrapper
;
const
createComponent
=
()
=>
{
wrapper
=
shallowMount
(
IdenticonComponent
,
{
propsData
:
{
entityId
:
1
,
entityName
:
'
entity-name
'
,
sizeClass
:
'
s40
'
,
},
});
};
describe
(
'
identiconTitle
'
,
()
=>
{
it
(
'
should return first letter of entity title in uppercase
'
,
()
=>
{
vm
.
entityName
=
'
dummy-group
'
;
expect
(
vm
.
identiconTitle
).
toBeDefined
();
expect
(
vm
.
identiconTitle
).
toBe
(
'
D
'
);
});
});
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
template
'
,
()
=>
{
it
(
'
should render identicon
'
,
()
=>
{
const
vm
=
createComponent
();
it
(
'
matches snapshot
'
,
()
=>
{
createComponent
();
expect
(
vm
.
$el
.
nodeName
).
toBe
(
'
DIV
'
);
expect
(
vm
.
$el
.
classList
.
contains
(
'
identicon
'
)).
toBeTruthy
();
expect
(
vm
.
$el
.
classList
.
contains
(
'
s40
'
)).
toBeTruthy
();
expect
(
vm
.
$el
.
classList
.
contains
(
'
bg2
'
)).
toBeTruthy
();
vm
.
$destroy
();
});
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
it
(
'
should render identicon with provided sizing class
'
,
()
=>
{
const
vm
=
createComponent
(
'
s32
'
);
it
(
'
adds a correct class to identicon
'
,
()
=>
{
createComponent
(
);
expect
(
vm
.
$el
.
classList
.
contains
(
'
s32
'
)).
toBeTruthy
();
vm
.
$destroy
();
});
expect
(
wrapper
.
find
({
ref
:
'
identicon
'
}).
classes
()).
toContain
(
'
bg2
'
);
});
});
spec/frontend/vue_shared/components/issue/__snapshots__/issue_warning_spec.js.snap
0 → 100644
View file @
6a3b4071
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Issue Warning Component when issue is confidential but not locked renders information about confidential issue 1`] = `
<span>
This is a confidential issue.
People without permission will never get a notification.
<gl-link-stub
href="confidential-path"
target="_blank"
>
Learn more
</gl-link-stub>
</span>
`;
exports[`Issue Warning Component when issue is locked and confidential renders information about locked and confidential issue 1`] = `
<span>
<span>
This issue is
<a
href=""
rel="noopener noreferrer"
target="_blank"
>
confidential
</a>
and
<a
href=""
rel="noopener noreferrer"
target="_blank"
>
locked
</a>
.
</span>
People without permission will never get a notification and won't be able to comment.
</span>
`;
exports[`Issue Warning Component when issue is locked but not confidential renders information about locked issue 1`] = `
<span>
This issue is locked.
Only project members can comment.
<gl-link-stub
href="locked-path"
target="_blank"
>
Learn more
</gl-link-stub>
</span>
`;
spec/frontend/vue_shared/components/issue/issue_warning_spec.js
View file @
6a3b4071
import
Vue
from
'
vue
'
;
import
mountComponent
from
'
helpers/vue_mount_component_helper
'
;
import
issueWarning
from
'
~/vue_shared/components/issue/issue_warning
.vue
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
IssueWarning
from
'
~/vue_shared/components/issue/issue_warning.vue
'
;
import
Icon
from
'
~/vue_shared/components/icon
.vue
'
;
const
IssueWarning
=
Vue
.
extend
(
issueWarning
);
describe
(
'
Issue Warning Component
'
,
()
=>
{
let
wrapper
;
function
formatWarning
(
string
)
{
// Replace newlines with a space then replace multiple spaces with one space
return
string
.
trim
()
.
replace
(
/
\n
/g
,
'
'
)
.
replace
(
/
\s\s
+/g
,
'
'
);
}
const
findIcon
=
()
=>
wrapper
.
find
(
Icon
);
const
findLockedBlock
=
()
=>
wrapper
.
find
({
ref
:
'
locked
'
});
const
findConfidentialBlock
=
()
=>
wrapper
.
find
({
ref
:
'
confidential
'
});
const
findLockedAndConfidentialBlock
=
()
=>
wrapper
.
find
({
ref
:
'
lockedAndConfidential
'
});
describe
(
'
Issue Warning Component
'
,
()
=>
{
describe
(
'
isLocked
'
,
()
=>
{
it
(
'
should render locked issue warning information
'
,
()
=>
{
const
props
=
{
const
createComponent
=
props
=>
{
wrapper
=
shallowMount
(
IssueWarning
,
{
propsData
:
{
...
props
,
},
});
};
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
when issue is locked but not confidential
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
isLocked
:
true
,
lockedIssueDocsPath
:
'
docs/issues/locked
'
,
};
const
vm
=
mountComponent
(
IssueWarning
,
props
);
expect
(
vm
.
$el
.
querySelector
(
'
.icon use
'
).
getAttributeNS
(
'
http://www.w3.org/1999/xlink
'
,
'
href
'
),
).
toMatch
(
/lock$/
);
expect
(
formatWarning
(
vm
.
$el
.
querySelector
(
'
span
'
).
textContent
)).
toEqual
(
'
This issue is locked. Only project members can comment. Learn more
'
,
);
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
href
).
toContain
(
props
.
lockedIssueDocsPath
);
lockedIssueDocsPath
:
'
locked-path
'
,
isConfidential
:
false
,
});
});
it
(
'
renders information about locked issue
'
,
()
=>
{
expect
(
findLockedBlock
().
exists
()).
toBe
(
true
);
expect
(
findLockedBlock
().
element
).
toMatchSnapshot
();
});
it
(
'
renders warning icon
'
,
()
=>
{
expect
(
findIcon
().
exists
()).
toBe
(
true
);
});
it
(
'
does not render information about locked and confidential issue
'
,
()
=>
{
expect
(
findLockedAndConfidentialBlock
().
exists
()).
toBe
(
false
);
});
it
(
'
does not render information about confidential issue
'
,
()
=>
{
expect
(
findConfidentialBlock
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
isConfidential
'
,
()
=>
{
it
(
'
should render confidential issue warning information
'
,
()
=>
{
const
props
=
{
describe
(
'
when issue is confidential but not locked
'
,
()
=>
{
beforeEach
(()
=>
{
createComponent
({
isLocked
:
false
,
isConfidential
:
true
,
confidentialIssueDocsPath
:
'
/docs/issues/confidential
'
,
};
const
vm
=
mountComponent
(
IssueWarning
,
props
);
expect
(
vm
.
$el
.
querySelector
(
'
.icon use
'
).
getAttributeNS
(
'
http://www.w3.org/1999/xlink
'
,
'
href
'
),
).
toMatch
(
/eye-slash$/
);
expect
(
formatWarning
(
vm
.
$el
.
querySelector
(
'
span
'
).
textContent
)).
toEqual
(
'
This is a confidential issue. People without permission will never get a notification. Learn more
'
,
);
expect
(
vm
.
$el
.
querySelector
(
'
a
'
).
href
).
toContain
(
props
.
confidentialIssueDocsPath
);
confidentialIssueDocsPath
:
'
confidential-path
'
,
});
});
it
(
'
renders information about confidential issue
'
,
()
=>
{
expect
(
findConfidentialBlock
().
exists
()).
toBe
(
true
);
expect
(
findConfidentialBlock
().
element
).
toMatchSnapshot
();
});
it
(
'
renders warning icon
'
,
()
=>
{
expect
(
wrapper
.
find
(
Icon
).
exists
()).
toBe
(
true
);
});
it
(
'
does not render information about locked issue
'
,
()
=>
{
expect
(
findLockedBlock
().
exists
()).
toBe
(
false
);
});
it
(
'
does not render information about locked and confidential issue
'
,
()
=>
{
expect
(
findLockedAndConfidentialBlock
().
exists
()).
toBe
(
false
);
});
});
describe
(
'
isLocked and isC
onfidential
'
,
()
=>
{
it
(
'
should render locked and confidential issue warning information
'
,
()
=>
{
c
onst
vm
=
mountComponent
(
IssueWarning
,
{
describe
(
'
when issue is locked and c
onfidential
'
,
()
=>
{
beforeEach
(
()
=>
{
c
reateComponent
(
{
isLocked
:
true
,
isConfidential
:
true
,
});
});
it
(
'
renders information about locked and confidential issue
'
,
()
=>
{
expect
(
findLockedAndConfidentialBlock
().
exists
()).
toBe
(
true
);
expect
(
findLockedAndConfidentialBlock
().
element
).
toMatchSnapshot
();
});
it
(
'
does not render warning icon
'
,
()
=>
{
expect
(
wrapper
.
find
(
Icon
).
exists
()).
toBe
(
false
);
});
it
(
'
does not render information about locked issue
'
,
()
=>
{
expect
(
findLockedBlock
().
exists
()).
toBe
(
false
);
});
expect
(
vm
.
$el
.
querySelector
(
'
.icon
'
)).
toBeFalsy
();
expect
(
formatWarning
(
vm
.
$el
.
querySelector
(
'
span
'
).
textContent
)).
toEqual
(
"
This issue is confidential and locked. People without permission will never get a notification and won't be able to comment.
"
,
);
it
(
'
does not render information about confidential issue
'
,
()
=>
{
expect
(
findConfidentialBlock
().
exists
()).
toBe
(
false
);
});
});
});
spec/frontend/vue_shared/components/markdown/__snapshots__/suggestion_diff_spec.js.snap
0 → 100644
View file @
6a3b4071
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Suggestion Diff component matches snapshot 1`] = `
<div
class="md-suggestion"
>
<suggestion-diff-header-stub
class="qa-suggestion-diff-header js-suggestion-diff-header"
helppagepath="path_to_docs"
/>
<table
class="mb-3 md-suggestion-diff js-syntax-highlight code"
>
<tbody>
<suggestion-diff-row-stub
line="[object Object]"
/>
<suggestion-diff-row-stub
line="[object Object]"
/>
<suggestion-diff-row-stub
line="[object Object]"
/>
</tbody>
</table>
</div>
`;
spec/frontend/vue_shared/components/markdown/suggestion_diff_spec.js
View file @
6a3b4071
import
Vue
from
'
vue
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
SuggestionDiffComponent
from
'
~/vue_shared/components/markdown/suggestion_diff.vue
'
;
import
{
selectDiffLines
}
from
'
~/vue_shared/components/lib/utils/diff_utils
'
;
import
SuggestionDiffHeader
from
'
~/vue_shared/components/markdown/suggestion_diff_header.vue
'
;
import
SuggestionDiffRow
from
'
~/vue_shared/components/markdown/suggestion_diff_row.vue
'
;
const
MOCK_DATA
=
{
canApply
:
true
,
suggestion
:
{
id
:
1
,
diff_lines
:
[
...
...
@@ -42,60 +42,45 @@ const MOCK_DATA = {
helpPagePath
:
'
path_to_docs
'
,
};
const
lines
=
selectDiffLines
(
MOCK_DATA
.
suggestion
.
diff_lines
);
const
newLines
=
lines
.
filter
(
line
=>
line
.
type
===
'
new
'
);
describe
(
'
Suggestion Diff component
'
,
()
=>
{
let
vm
;
beforeEach
(
done
=>
{
const
Component
=
Vue
.
extend
(
SuggestionDiffComponent
);
vm
=
new
Component
({
propsData
:
MOCK_DATA
,
}).
$mount
();
Vue
.
nextTick
(
done
);
});
describe
(
'
init
'
,
()
=>
{
it
(
'
renders a suggestion header
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.js-suggestion-diff-header
'
)).
not
.
toBeNull
();
});
it
(
'
renders a diff table with syntax highlighting
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.md-suggestion-diff.js-syntax-highlight.code
'
)).
not
.
toBeNull
();
});
let
wrapper
;
it
(
'
renders the oldLineNumber
'
,
()
=>
{
const
fromLine
=
vm
.
$el
.
querySelector
(
'
.old_line
'
).
innerHTML
;
expect
(
parseInt
(
fromLine
,
10
)).
toBe
(
lines
[
0
].
old_line
);
const
createComponent
=
()
=>
{
wrapper
=
shallowMount
(
SuggestionDiffComponent
,
{
propsData
:
{
...
MOCK_DATA
,
},
});
};
it
(
'
renders the oldLineContent
'
,
()
=>
{
const
fromContent
=
vm
.
$el
.
querySelector
(
'
.line_content.old
'
).
innerHTML
;
expect
(
fromContent
.
includes
(
lines
[
0
].
text
)).
toBe
(
true
);
});
beforeEach
(()
=>
{
createComponent
();
});
it
(
'
renders new lines
'
,
()
=>
{
const
newLinesElements
=
vm
.
$el
.
querySelectorAll
(
'
.line_holder.new
'
);
afterEach
(()
=>
{
wrapper
.
destroy
();
wrapper
=
null
;
});
newLinesElements
.
forEach
((
line
,
i
)
=>
{
expect
(
newLinesElements
[
i
].
innerHTML
.
includes
(
newLines
[
i
].
new_line
)).
toBe
(
true
);
expect
(
newLinesElements
[
i
].
innerHTML
.
includes
(
newLines
[
i
].
text
)).
toBe
(
true
);
});
});
it
(
'
matches snapshot
'
,
()
=>
{
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
describe
(
'
applySuggestion
'
,
()
=>
{
it
(
'
emits apply event when applySuggestion is called
'
,
()
=>
{
const
callback
=
()
=>
{};
jest
.
spyOn
(
vm
,
'
$emit
'
).
mockImplementation
(()
=>
{});
vm
.
applySuggestion
(
callback
);
it
(
'
renders a correct amount of suggestion diff rows
'
,
()
=>
{
expect
(
wrapper
.
findAll
(
SuggestionDiffRow
)).
toHaveLength
(
3
);
});
expect
(
vm
.
$emit
).
toHaveBeenCalledWith
(
'
apply
'
,
{
suggestionId
:
vm
.
suggestion
.
id
,
callback
});
});
it
(
'
emits apply event on sugestion diff header apply
'
,
()
=>
{
wrapper
.
find
(
SuggestionDiffHeader
).
vm
.
$emit
(
'
apply
'
,
'
test-event
'
);
expect
(
wrapper
.
emitted
(
'
apply
'
)).
toBeDefined
();
expect
(
wrapper
.
emitted
(
'
apply
'
)).
toEqual
([
[
{
callback
:
'
test-event
'
,
suggestionId
:
1
,
},
],
]);
});
});
spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_note_spec.js.snap
0 → 100644
View file @
6a3b4071
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Issue placeholder note component matches snapshot 1`] = `
<timeline-entry-item-stub
class="note note-wrapper being-posted fade-in-half"
>
<div
class="timeline-icon"
>
<user-avatar-link-stub
imgalt=""
imgcssclasses=""
imgsize="40"
imgsrc="mock_path"
linkhref="/root"
tooltipplacement="top"
tooltiptext=""
username=""
/>
</div>
<div
class="timeline-content discussion"
>
<div
class="note-header"
>
<div
class="note-header-info"
>
<a
href="/root"
>
<span
class="d-none d-sm-inline-block bold"
>
Root
</span>
<span
class="note-headline-light"
>
@root
</span>
</a>
</div>
</div>
<div
class="note-body"
>
<div
class="note-text md"
>
<p>
Foo
</p>
</div>
</div>
</div>
</timeline-entry-item-stub>
`;
spec/frontend/vue_shared/components/notes/__snapshots__/placeholder_system_note_spec.js.snap
0 → 100644
View file @
6a3b4071
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Placeholder system note component matches snapshot 1`] = `
<timeline-entry-item-stub
class="note system-note being-posted fade-in-half"
>
<div
class="timeline-content"
>
<em>
This is a placeholder
</em>
</div>
</timeline-entry-item-stub>
`;
spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
View file @
6a3b4071
import
Vue
from
'
vue
'
;
import
issuePlaceholderNote
from
'
~/vue_shared/components/notes/placeholder_note.vue
'
;
import
createStore
from
'
~/notes/stores
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
Vuex
from
'
vuex
'
;
import
IssuePlaceholderNote
from
'
~/vue_shared/components/notes/placeholder_note.vue
'
;
import
{
userDataMock
}
from
'
../../../notes/mock_data
'
;
describe
(
'
issue placeholder system note component
'
,
()
=>
{
let
store
;
let
vm
;
beforeEach
(()
=>
{
const
Component
=
Vue
.
extend
(
issuePlaceholderNote
);
store
=
createStore
();
store
.
dispatch
(
'
setUserData
'
,
userDataMock
);
vm
=
new
Component
({
store
,
propsData
:
{
note
:
{
body
:
'
Foo
'
}
},
}).
$mount
();
});
const
localVue
=
createLocalVue
();
localVue
.
use
(
Vuex
);
const
getters
=
{
getUserData
:
()
=>
userDataMock
,
};
describe
(
'
Issue placeholder note component
'
,
()
=>
{
let
wrapper
;
const
findNote
=
()
=>
wrapper
.
find
({
ref
:
'
note
'
});
const
createComponent
=
(
isIndividual
=
false
)
=>
{
wrapper
=
shallowMount
(
IssuePlaceholderNote
,
{
localVue
,
store
:
new
Vuex
.
Store
({
getters
,
}),
propsData
:
{
note
:
{
body
:
'
Foo
'
,
individual_note
:
isIndividual
,
},
},
});
};
afterEach
(()
=>
{
vm
.
$destroy
();
wrapper
.
destroy
();
wrapper
=
null
;
});
describe
(
'
user information
'
,
()
=>
{
it
(
'
should render user avatar with link
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.user-avatar-link
'
).
getAttribute
(
'
href
'
)).
toEqual
(
userDataMock
.
path
,
);
it
(
'
matches snapshot
'
,
()
=>
{
createComponent
();
expect
(
vm
.
$el
.
querySelector
(
'
.user-avatar-link img
'
).
getAttribute
(
'
src
'
)).
toEqual
(
`
${
userDataMock
.
avatar_url
}
?width=40`
,
);
});
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
describe
(
'
note content
'
,
()
=>
{
it
(
'
should render note header information
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.note-header-info a
'
).
getAttribute
(
'
href
'
)).
toEqual
(
userDataMock
.
path
,
);
it
(
'
does not add "discussion" class to individual notes
'
,
()
=>
{
createComponent
(
true
);
expect
(
vm
.
$el
.
querySelector
(
'
.note-header-info .note-headline-light
'
).
textContent
.
trim
(),
).
toEqual
(
`@
${
userDataMock
.
username
}
`
);
});
expect
(
findNote
().
classes
()).
not
.
toContain
(
'
discussion
'
);
});
it
(
'
should render note body
'
,
()
=>
{
expect
(
vm
.
$el
.
querySelector
(
'
.note-text p
'
).
textContent
.
trim
()).
toEqual
(
'
Foo
'
);
});
it
(
'
adds "discussion" class to non-individual notes
'
,
()
=>
{
createComponent
();
expect
(
findNote
().
classes
()).
toContain
(
'
discussion
'
);
});
});
spec/frontend/vue_shared/components/notes/placeholder_system_note_spec.js
View file @
6a3b4071
import
Vue
from
'
vue
'
;
import
mountComponent
from
'
helpers/vue_mount_component_helper
'
;
import
placeholderSystemNote
from
'
~/vue_shared/components/notes/placeholder_system_note.vue
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
PlaceholderSystemNote
from
'
~/vue_shared/components/notes/placeholder_system_note.vue
'
;
describe
(
'
placeholder system note component
'
,
()
=>
{
let
PlaceholderSystemNote
;
let
vm
;
describe
(
'
Placeholder system note component
'
,
()
=>
{
let
wrapper
;
beforeEach
(()
=>
{
PlaceholderSystemNote
=
Vue
.
extend
(
placeholderSystemNote
);
});
const
createComponent
=
()
=>
{
wrapper
=
shallowMount
(
PlaceholderSystemNote
,
{
propsData
:
{
note
:
{
body
:
'
This is a placeholder
'
},
},
});
};
afterEach
(()
=>
{
vm
.
$destroy
();
wrapper
.
destroy
();
wrapper
=
null
;
});
it
(
'
should render system note placeholder with plain text
'
,
()
=>
{
vm
=
mountComponent
(
PlaceholderSystemNote
,
{
note
:
{
body
:
'
This is a placeholder
'
},
});
it
(
'
matches snapshot
'
,
()
=>
{
createComponent
();
expect
(
vm
.
$el
.
tagName
).
toEqual
(
'
LI
'
);
expect
(
vm
.
$el
.
querySelector
(
'
.timeline-content em
'
).
textContent
.
trim
()).
toEqual
(
'
This is a placeholder
'
,
);
expect
(
wrapper
.
element
).
toMatchSnapshot
();
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment