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
ac493c39
Commit
ac493c39
authored
May 20, 2020
by
Himanshu Kapoor
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate javascripts/* specs to Jest
Migrate some specs in spec/javascripts/* from Karma to Jest.
parent
42fce179
Changes
13
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
235 additions
and
202 deletions
+235
-202
app/assets/javascripts/gl_dropdown.js
app/assets/javascripts/gl_dropdown.js
+1
-1
app/assets/javascripts/pager.js
app/assets/javascripts/pager.js
+2
-2
spec/frontend/gl_dropdown_spec.js
spec/frontend/gl_dropdown_spec.js
+55
-51
spec/frontend/helpers/local_storage_helper.js
spec/frontend/helpers/local_storage_helper.js
+14
-6
spec/frontend/helpers/local_storage_helper_spec.js
spec/frontend/helpers/local_storage_helper_spec.js
+21
-0
spec/frontend/importer_status_spec.js
spec/frontend/importer_status_spec.js
+12
-9
spec/frontend/merge_request_spec.js
spec/frontend/merge_request_spec.js
+37
-33
spec/frontend/mini_pipeline_graph_dropdown_spec.js
spec/frontend/mini_pipeline_graph_dropdown_spec.js
+9
-9
spec/frontend/pager_spec.js
spec/frontend/pager_spec.js
+19
-14
spec/frontend/pages/dashboard/todos/index/todos_spec.js
spec/frontend/pages/dashboard/todos/index/todos_spec.js
+11
-8
spec/frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
.../frontend/pages/sessions/new/signin_tabs_memoizer_spec.js
+19
-17
spec/frontend/persistent_user_callout_spec.js
spec/frontend/persistent_user_callout_spec.js
+35
-52
spec/frontend/read_more_spec.js
spec/frontend/read_more_spec.js
+0
-0
No files found.
app/assets/javascripts/gl_dropdown.js
View file @
ac493c39
...
...
@@ -4,7 +4,7 @@ import $ from 'jquery';
import
{
escape
}
from
'
lodash
'
;
import
fuzzaldrinPlus
from
'
fuzzaldrin-plus
'
;
import
axios
from
'
./lib/utils/axios_utils
'
;
import
{
visitUrl
}
from
'
.
/lib/utils/url_utility
'
;
import
{
visitUrl
}
from
'
~
/lib/utils/url_utility
'
;
import
{
isObject
}
from
'
./lib/utils/type_utility
'
;
import
renderItem
from
'
./gl_dropdown/render
'
;
...
...
app/assets/javascripts/pager.js
View file @
ac493c39
import
$
from
'
jquery
'
;
import
{
getParameterByName
}
from
'
~/lib/utils/common_utils
'
;
import
axios
from
'
.
/lib/utils/axios_utils
'
;
import
{
removeParams
}
from
'
.
/lib/utils/url_utility
'
;
import
axios
from
'
~
/lib/utils/axios_utils
'
;
import
{
removeParams
}
from
'
~
/lib/utils/url_utility
'
;
const
ENDLESS_SCROLL_BOTTOM_PX
=
400
;
const
ENDLESS_SCROLL_FIRE_DELAY_MS
=
1000
;
...
...
spec/
javascripts
/gl_dropdown_spec.js
→
spec/
frontend
/gl_dropdown_spec.js
View file @
ac493c39
/* eslint-disable no-param-reassign */
import
$
from
'
jquery
'
;
import
GLDropdown
from
'
~/gl_dropdown
'
;
import
'
~/gl_dropdown
'
;
import
'
~/lib/utils/common_utils
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
describe
(
'
glDropdown
'
,
function
describeDropdown
()
{
jest
.
mock
(
'
~/lib/utils/url_utility
'
,
()
=>
({
visitUrl
:
jest
.
fn
().
mockName
(
'
visitUrl
'
),
}));
describe
(
'
glDropdown
'
,
()
=>
{
preloadFixtures
(
'
static/gl_dropdown.html
'
);
loadJSONFixtures
(
'
static/projects.json
'
);
const
NON_SELECTABLE_CLASSES
=
'
.divider, .separator, .dropdown-header, .dropdown-menu-empty-item
'
;
const
SEARCH_INPUT_SELECTOR
=
'
.dropdown-input-field
'
;
const
ITEM_SELECTOR
=
`.dropdown-content li:not(
${
NON_SELECTABLE_CLASSES
}
)`
;
const
FOCUSED_ITEM_SELECTOR
=
`
${
ITEM_SELECTOR
}
a.is-focused`
;
const
ARROW_KEYS
=
{
DOWN
:
40
,
UP
:
38
,
...
...
@@ -23,7 +26,9 @@ describe('glDropdown', function describeDropdown() {
let
remoteCallback
;
const
navigateWithKeys
=
function
navigateWithKeys
(
direction
,
steps
,
cb
,
i
)
{
const
test
=
{};
const
navigateWithKeys
=
(
direction
,
steps
,
cb
,
i
)
=>
{
i
=
i
||
0
;
if
(
!
i
)
direction
=
direction
.
toUpperCase
();
$
(
'
body
'
).
trigger
({
...
...
@@ -39,7 +44,7 @@ describe('glDropdown', function describeDropdown() {
}
};
const
remoteMock
=
function
remoteMock
(
data
,
term
,
callback
)
{
const
remoteMock
=
(
data
,
term
,
callback
)
=>
{
remoteCallback
=
callback
.
bind
({},
data
);
};
...
...
@@ -47,7 +52,7 @@ describe('glDropdown', function describeDropdown() {
const
options
=
{
selectable
:
true
,
filterable
:
isFilterable
,
data
:
hasRemote
?
remoteMock
.
bind
({},
t
his
.
projectsData
)
:
this
.
projectsData
,
data
:
hasRemote
?
remoteMock
.
bind
({},
t
est
.
projectsData
)
:
test
.
projectsData
,
search
:
{
fields
:
[
'
name
'
],
},
...
...
@@ -55,52 +60,52 @@ describe('glDropdown', function describeDropdown() {
id
:
project
=>
project
.
id
,
...
extraOpts
,
};
t
his
.
dropdownButtonElement
=
$
(
t
est
.
dropdownButtonElement
=
$
(
'
#js-project-dropdown
'
,
t
his
.
dropdownContainerElement
,
t
est
.
dropdownContainerElement
,
).
glDropdown
(
options
);
}
beforeEach
(()
=>
{
loadFixtures
(
'
static/gl_dropdown.html
'
);
t
his
.
dropdownContainerElement
=
$
(
'
.dropdown.inline
'
);
t
his
.
$dropdownMenuElement
=
$
(
'
.dropdown-menu
'
,
this
.
dropdownContainerElement
);
t
his
.
projectsData
=
getJSONFixture
(
'
static/projects.json
'
);
t
est
.
dropdownContainerElement
=
$
(
'
.dropdown.inline
'
);
t
est
.
$dropdownMenuElement
=
$
(
'
.dropdown-menu
'
,
test
.
dropdownContainerElement
);
t
est
.
projectsData
=
getJSONFixture
(
'
static/projects.json
'
);
});
afterEach
(()
=>
{
$
(
'
body
'
).
off
(
'
keydown
'
);
t
his
.
dropdownContainerElement
.
off
(
'
keyup
'
);
t
est
.
dropdownContainerElement
.
off
(
'
keyup
'
);
});
it
(
'
should open on click
'
,
()
=>
{
initDropDown
.
call
(
this
,
false
);
expect
(
t
his
.
dropdownContainerElement
).
not
.
toHaveClass
(
'
show
'
);
t
his
.
dropdownButtonElement
.
click
();
expect
(
t
est
.
dropdownContainerElement
).
not
.
toHaveClass
(
'
show
'
);
t
est
.
dropdownButtonElement
.
click
();
expect
(
t
his
.
dropdownContainerElement
).
toHaveClass
(
'
show
'
);
expect
(
t
est
.
dropdownContainerElement
).
toHaveClass
(
'
show
'
);
});
it
(
'
escapes HTML as text
'
,
()
=>
{
t
his
.
projectsData
[
0
].
name_with_namespace
=
'
<script>alert("testing");</script>
'
;
t
est
.
projectsData
[
0
].
name_with_namespace
=
'
<script>alert("testing");</script>
'
;
initDropDown
.
call
(
this
,
false
);
t
his
.
dropdownButtonElement
.
click
();
t
est
.
dropdownButtonElement
.
click
();
expect
(
$
(
'
.dropdown-content li:first-child
'
).
text
()).
toBe
(
'
<script>alert("testing");</script>
'
);
});
it
(
'
should output HTML when highlighting
'
,
()
=>
{
t
his
.
projectsData
[
0
].
name_with_namespace
=
'
testing
'
;
t
est
.
projectsData
[
0
].
name_with_namespace
=
'
testing
'
;
$
(
'
.dropdown-input .dropdown-input-field
'
).
val
(
'
test
'
);
initDropDown
.
call
(
this
,
false
,
true
,
{
highlight
:
true
,
});
t
his
.
dropdownButtonElement
.
click
();
t
est
.
dropdownButtonElement
.
click
();
expect
(
$
(
'
.dropdown-content li:first-child
'
).
text
()).
toBe
(
'
testing
'
);
...
...
@@ -112,31 +117,31 @@ describe('glDropdown', function describeDropdown() {
describe
(
'
that is open
'
,
()
=>
{
beforeEach
(()
=>
{
initDropDown
.
call
(
this
,
false
,
false
);
t
his
.
dropdownButtonElement
.
click
();
t
est
.
dropdownButtonElement
.
click
();
});
it
(
'
should select a following item on DOWN keypress
'
,
()
=>
{
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
his
.
$dropdownMenuElement
).
length
).
toBe
(
0
);
const
randomIndex
=
Math
.
floor
(
Math
.
random
()
*
(
t
his
.
projectsData
.
length
-
1
))
+
0
;
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
est
.
$dropdownMenuElement
).
length
).
toBe
(
0
);
const
randomIndex
=
Math
.
floor
(
Math
.
random
()
*
(
t
est
.
projectsData
.
length
-
1
))
+
0
;
navigateWithKeys
(
'
down
'
,
randomIndex
,
()
=>
{
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
his
.
$dropdownMenuElement
).
length
).
toBe
(
1
);
expect
(
$
(
`
${
ITEM_SELECTOR
}
:eq(
${
randomIndex
}
) a`
,
t
his
.
$dropdownMenuElement
)).
toHaveClass
(
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
est
.
$dropdownMenuElement
).
length
).
toBe
(
1
);
expect
(
$
(
`
${
ITEM_SELECTOR
}
:eq(
${
randomIndex
}
) a`
,
t
est
.
$dropdownMenuElement
)).
toHaveClass
(
'
is-focused
'
,
);
});
});
it
(
'
should select a previous item on UP keypress
'
,
()
=>
{
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
his
.
$dropdownMenuElement
).
length
).
toBe
(
0
);
navigateWithKeys
(
'
down
'
,
t
his
.
projectsData
.
length
-
1
,
()
=>
{
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
his
.
$dropdownMenuElement
).
length
).
toBe
(
1
);
const
randomIndex
=
Math
.
floor
(
Math
.
random
()
*
(
t
his
.
projectsData
.
length
-
2
))
+
0
;
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
est
.
$dropdownMenuElement
).
length
).
toBe
(
0
);
navigateWithKeys
(
'
down
'
,
t
est
.
projectsData
.
length
-
1
,
()
=>
{
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
est
.
$dropdownMenuElement
).
length
).
toBe
(
1
);
const
randomIndex
=
Math
.
floor
(
Math
.
random
()
*
(
t
est
.
projectsData
.
length
-
2
))
+
0
;
navigateWithKeys
(
'
up
'
,
randomIndex
,
()
=>
{
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
his
.
$dropdownMenuElement
).
length
).
toBe
(
1
);
expect
(
$
(
FOCUSED_ITEM_SELECTOR
,
t
est
.
$dropdownMenuElement
).
length
).
toBe
(
1
);
expect
(
$
(
`
${
ITEM_SELECTOR
}
:eq(
${
t
his
.
projectsData
.
length
-
2
-
randomIndex
}
) a`
,
t
his
.
$dropdownMenuElement
,
`
${
ITEM_SELECTOR
}
:eq(
${
t
est
.
projectsData
.
length
-
2
-
randomIndex
}
) a`
,
t
est
.
$dropdownMenuElement
,
),
).
toHaveClass
(
'
is-focused
'
);
});
...
...
@@ -144,13 +149,12 @@ describe('glDropdown', function describeDropdown() {
});
it
(
'
should click the selected item on ENTER keypress
'
,
()
=>
{
expect
(
t
his
.
dropdownContainerElement
).
toHaveClass
(
'
show
'
);
const
randomIndex
=
Math
.
floor
(
Math
.
random
()
*
(
t
his
.
projectsData
.
length
-
1
))
+
0
;
expect
(
t
est
.
dropdownContainerElement
).
toHaveClass
(
'
show
'
);
const
randomIndex
=
Math
.
floor
(
Math
.
random
()
*
(
t
est
.
projectsData
.
length
-
1
))
+
0
;
navigateWithKeys
(
'
down
'
,
randomIndex
,
()
=>
{
const
visitUrl
=
spyOnDependency
(
GLDropdown
,
'
visitUrl
'
).
and
.
stub
();
navigateWithKeys
(
'
enter
'
,
null
,
()
=>
{
expect
(
t
his
.
dropdownContainerElement
).
not
.
toHaveClass
(
'
show
'
);
const
link
=
$
(
`
${
ITEM_SELECTOR
}
:eq(
${
randomIndex
}
) a`
,
t
his
.
$dropdownMenuElement
);
expect
(
t
est
.
dropdownContainerElement
).
not
.
toHaveClass
(
'
show
'
);
const
link
=
$
(
`
${
ITEM_SELECTOR
}
:eq(
${
randomIndex
}
) a`
,
t
est
.
$dropdownMenuElement
);
expect
(
link
).
toHaveClass
(
'
is-active
'
);
const
linkedLocation
=
link
.
attr
(
'
href
'
);
...
...
@@ -162,21 +166,21 @@ describe('glDropdown', function describeDropdown() {
});
it
(
'
should close on ESC keypress
'
,
()
=>
{
expect
(
t
his
.
dropdownContainerElement
).
toHaveClass
(
'
show
'
);
t
his
.
dropdownContainerElement
.
trigger
({
expect
(
t
est
.
dropdownContainerElement
).
toHaveClass
(
'
show
'
);
t
est
.
dropdownContainerElement
.
trigger
({
type
:
'
keyup
'
,
which
:
ARROW_KEYS
.
ESC
,
keyCode
:
ARROW_KEYS
.
ESC
,
});
expect
(
t
his
.
dropdownContainerElement
).
not
.
toHaveClass
(
'
show
'
);
expect
(
t
est
.
dropdownContainerElement
).
not
.
toHaveClass
(
'
show
'
);
});
});
describe
(
'
opened and waiting for a remote callback
'
,
()
=>
{
beforeEach
(()
=>
{
initDropDown
.
call
(
this
,
true
,
true
);
t
his
.
dropdownButtonElement
.
click
();
t
est
.
dropdownButtonElement
.
click
();
});
it
(
'
should show loading indicator while search results are being fetched by backend
'
,
()
=>
{
...
...
@@ -203,13 +207,13 @@ describe('glDropdown', function describeDropdown() {
it
(
'
should focus on input when opening for the second time after transition
'
,
()
=>
{
remoteCallback
();
t
his
.
dropdownContainerElement
.
trigger
({
t
est
.
dropdownContainerElement
.
trigger
({
type
:
'
keyup
'
,
which
:
ARROW_KEYS
.
ESC
,
keyCode
:
ARROW_KEYS
.
ESC
,
});
t
his
.
dropdownButtonElement
.
click
();
t
his
.
dropdownContainerElement
.
trigger
(
'
transitionend
'
);
t
est
.
dropdownButtonElement
.
click
();
t
est
.
dropdownContainerElement
.
trigger
(
'
transitionend
'
);
expect
(
$
(
document
.
activeElement
)).
toEqual
(
$
(
SEARCH_INPUT_SELECTOR
));
});
...
...
@@ -218,8 +222,8 @@ describe('glDropdown', function describeDropdown() {
describe
(
'
input focus with array data
'
,
()
=>
{
it
(
'
should focus input when passing array data to drop down
'
,
()
=>
{
initDropDown
.
call
(
this
,
false
,
true
);
t
his
.
dropdownButtonElement
.
click
();
t
his
.
dropdownContainerElement
.
trigger
(
'
transitionend
'
);
t
est
.
dropdownButtonElement
.
click
();
t
est
.
dropdownContainerElement
.
trigger
(
'
transitionend
'
);
expect
(
$
(
document
.
activeElement
)).
toEqual
(
$
(
SEARCH_INPUT_SELECTOR
));
});
...
...
@@ -234,7 +238,7 @@ describe('glDropdown', function describeDropdown() {
.
trigger
(
'
input
'
);
expect
(
$searchInput
.
val
()).
toEqual
(
'
g
'
);
t
his
.
dropdownButtonElement
.
trigger
(
'
hidden.bs.dropdown
'
);
t
est
.
dropdownButtonElement
.
trigger
(
'
hidden.bs.dropdown
'
);
$searchInput
.
trigger
(
'
blur
'
).
trigger
(
'
focus
'
);
expect
(
$searchInput
.
val
()).
toEqual
(
'
g
'
);
...
...
@@ -323,19 +327,19 @@ describe('glDropdown', function describeDropdown() {
},
};
initDropDown
.
call
(
this
,
false
,
false
,
options
);
const
$item
=
$
(
`
${
ITEM_SELECTOR
}
:first() a`
,
t
his
.
$dropdownMenuElement
);
const
$item
=
$
(
`
${
ITEM_SELECTOR
}
:first() a`
,
t
est
.
$dropdownMenuElement
);
// select item the first time
t
his
.
dropdownButtonElement
.
click
();
t
est
.
dropdownButtonElement
.
click
();
$item
.
click
();
expect
(
$item
).
toHaveClass
(
'
is-active
'
);
// select item the second time
t
his
.
dropdownButtonElement
.
click
();
t
est
.
dropdownButtonElement
.
click
();
$item
.
click
();
expect
(
$item
).
toHaveClass
(
'
is-active
'
);
expect
(
$
(
'
.dropdown-toggle-text
'
)).
toHaveText
(
t
his
.
projectsData
[
0
].
id
.
toString
());
expect
(
$
(
'
.dropdown-toggle-text
'
)).
toHaveText
(
t
est
.
projectsData
[
0
].
id
.
toString
());
});
});
spec/frontend/helpers/local_storage_helper.js
View file @
ac493c39
...
...
@@ -28,12 +28,20 @@ const useLocalStorage = fn => {
/**
* Create an object with the localStorage interface but `jest.fn()` implementations.
*/
export
const
createLocalStorageSpy
=
()
=>
({
clear
:
jest
.
fn
(),
getItem
:
jest
.
fn
(),
setItem
:
jest
.
fn
(),
removeItem
:
jest
.
fn
(),
});
export
const
createLocalStorageSpy
=
()
=>
{
let
storage
=
{};
return
{
clear
:
jest
.
fn
(()
=>
{
storage
=
{};
}),
getItem
:
jest
.
fn
(
key
=>
storage
[
key
]),
setItem
:
jest
.
fn
((
key
,
value
)
=>
{
storage
[
key
]
=
value
;
}),
removeItem
:
jest
.
fn
(
key
=>
delete
storage
[
key
]),
};
};
/**
* Before each test, overwrite `window.localStorage` with a spy implementation.
...
...
spec/frontend/helpers/local_storage_helper_spec.js
0 → 100644
View file @
ac493c39
import
{
useLocalStorageSpy
}
from
'
./local_storage_helper
'
;
useLocalStorageSpy
();
describe
(
'
localStorage helper
'
,
()
=>
{
it
(
'
mocks localStorage but works exactly like original localStorage
'
,
()
=>
{
localStorage
.
setItem
(
'
test
'
,
'
testing
'
);
localStorage
.
setItem
(
'
test2
'
,
'
testing
'
);
expect
(
localStorage
.
getItem
(
'
test
'
)).
toBe
(
'
testing
'
);
localStorage
.
removeItem
(
'
test
'
,
'
testing
'
);
expect
(
localStorage
.
getItem
(
'
test
'
)).
toBeUndefined
();
expect
(
localStorage
.
getItem
(
'
test2
'
)).
toBe
(
'
testing
'
);
localStorage
.
clear
();
expect
(
localStorage
.
getItem
(
'
test2
'
)).
toBeUndefined
();
});
});
spec/
javascripts
/importer_status_spec.js
→
spec/
frontend
/importer_status_spec.js
View file @
ac493c39
...
...
@@ -16,9 +16,8 @@ describe('Importer Status', () => {
describe
(
'
addToImport
'
,
()
=>
{
const
importUrl
=
'
/import_url
'
;
beforeEach
(()
=>
{
setFixtures
(
`
const
fixtures
=
`
<table>
<tr id="repo_123">
<td class="import-target"></td>
<td class="import-actions job-status">
...
...
@@ -26,9 +25,13 @@ describe('Importer Status', () => {
</button>
</td>
</tr>
`
);
spyOn
(
ImporterStatus
.
prototype
,
'
initStatusPage
'
).
and
.
callFake
(()
=>
{});
spyOn
(
ImporterStatus
.
prototype
,
'
setAutoUpdate
'
).
and
.
callFake
(()
=>
{});
</table>
`
;
beforeEach
(()
=>
{
setFixtures
(
fixtures
);
jest
.
spyOn
(
ImporterStatus
.
prototype
,
'
initStatusPage
'
).
mockImplementation
(()
=>
{});
jest
.
spyOn
(
ImporterStatus
.
prototype
,
'
setAutoUpdate
'
).
mockImplementation
(()
=>
{});
instance
=
new
ImporterStatus
({
jobsUrl
:
''
,
importUrl
,
...
...
@@ -53,7 +56,7 @@ describe('Importer Status', () => {
});
it
(
'
shows error message after failed POST request
'
,
done
=>
{
appendSetFixtures
(
'
<div class="flash-container"></div>
'
);
setFixtures
(
`
${
fixtures
}
<div class="flash-container"></div>`
);
mock
.
onPost
(
importUrl
).
reply
(
422
,
{
errors
:
'
You forgot your lunch
'
,
...
...
@@ -89,8 +92,8 @@ describe('Importer Status', () => {
document
.
body
.
appendChild
(
div
);
spyOn
(
ImporterStatus
.
prototype
,
'
initStatusPage
'
).
and
.
callFake
(()
=>
{});
spyOn
(
ImporterStatus
.
prototype
,
'
setAutoUpdate
'
).
and
.
callFake
(()
=>
{});
jest
.
spyOn
(
ImporterStatus
.
prototype
,
'
initStatusPage
'
).
mockImplementation
(()
=>
{});
jest
.
spyOn
(
ImporterStatus
.
prototype
,
'
setAutoUpdate
'
).
mockImplementation
(()
=>
{});
instance
=
new
ImporterStatus
({
jobsUrl
,
});
...
...
spec/
javascripts
/merge_request_spec.js
→
spec/
frontend
/merge_request_spec.js
View file @
ac493c39
...
...
@@ -4,24 +4,26 @@ import axios from '~/lib/utils/axios_utils';
import
MergeRequest
from
'
~/merge_request
'
;
import
CloseReopenReportToggle
from
'
~/close_reopen_report_toggle
'
;
import
IssuablesHelper
from
'
~/helpers/issuables_helper
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
describe
(
'
MergeRequest
'
,
function
()
{
describe
(
'
task lists
'
,
function
()
{
describe
(
'
MergeRequest
'
,
()
=>
{
const
test
=
{};
describe
(
'
task lists
'
,
()
=>
{
let
mock
;
preloadFixtures
(
'
merge_requests/merge_request_with_task_list.html
'
);
beforeEach
(
function
()
{
beforeEach
(
()
=>
{
loadFixtures
(
'
merge_requests/merge_request_with_task_list.html
'
);
spyOn
(
axios
,
'
patch
'
).
and
.
callThrough
(
);
jest
.
spyOn
(
axios
,
'
patch
'
);
mock
=
new
MockAdapter
(
axios
);
mock
.
onPatch
(
`
${
gl
.
TEST_HOST
}
/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`
)
.
onPatch
(
`
${
TEST_HOST
}
/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`
)
.
reply
(
200
,
{});
t
his
.
merge
=
new
MergeRequest
();
return
t
his
.
merge
;
t
est
.
merge
=
new
MergeRequest
();
return
t
est
.
merge
;
});
afterEach
(()
=>
{
...
...
@@ -29,14 +31,14 @@ describe('MergeRequest', function() {
});
it
(
'
modifies the Markdown field
'
,
done
=>
{
spyOn
(
$
,
'
ajax
'
).
and
.
stub
();
jest
.
spyOn
(
$
,
'
ajax
'
).
mockImplementation
();
const
changeEvent
=
document
.
createEvent
(
'
HTMLEvents
'
);
changeEvent
.
initEvent
(
'
change
'
,
true
,
true
);
$
(
'
input[type=checkbox]
'
)
.
first
()
.
attr
(
'
checked
'
,
true
)[
0
]
.
dispatchEvent
(
changeEvent
);
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
$
(
'
.js-task-list-field
'
).
val
()).
toBe
(
'
- [x] Task List Item
\n
- [ ]
\n
- [ ] Task List Item 2
\n
'
,
);
...
...
@@ -46,14 +48,14 @@ describe('MergeRequest', function() {
it
(
'
ensure that task with only spaces does not get checked incorrectly
'
,
done
=>
{
// fixed in 'deckar01-task_list', '2.2.1' gem
spyOn
(
$
,
'
ajax
'
).
and
.
stub
();
jest
.
spyOn
(
$
,
'
ajax
'
).
mockImplementation
();
const
changeEvent
=
document
.
createEvent
(
'
HTMLEvents
'
);
changeEvent
.
initEvent
(
'
change
'
,
true
,
true
);
$
(
'
input[type=checkbox]
'
)
.
last
()
.
attr
(
'
checked
'
,
true
)[
0
]
.
dispatchEvent
(
changeEvent
);
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
$
(
'
.js-task-list-field
'
).
val
()).
toBe
(
'
- [ ] Task List Item
\n
- [ ]
\n
- [x] Task List Item 2
\n
'
,
);
...
...
@@ -73,9 +75,9 @@ describe('MergeRequest', function() {
detail
:
{
lineNumber
,
lineSource
,
index
,
checked
},
});
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
axios
.
patch
).
toHaveBeenCalledWith
(
`
${
gl
.
TEST_HOST
}
/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`
,
`
${
TEST_HOST
}
/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`
,
{
merge_request
:
{
description
:
'
- [ ] Task List Item
\n
- [ ]
\n
- [ ] Task List Item 2
\n
'
,
...
...
@@ -89,13 +91,9 @@ describe('MergeRequest', function() {
});
});
// https://gitlab.com/gitlab-org/gitlab/issues/34861
// eslint-disable-next-line jasmine/no-disabled-tests
xit
(
'
shows an error notification when tasklist update failed
'
,
done
=>
{
it
(
'
shows an error notification when tasklist update failed
'
,
done
=>
{
mock
.
onPatch
(
`
${
gl
.
TEST_HOST
}
/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`
,
)
.
onPatch
(
`
${
TEST_HOST
}
/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`
)
.
reply
(
409
,
{});
$
(
'
.js-task-list-field
'
).
trigger
({
...
...
@@ -103,7 +101,7 @@ describe('MergeRequest', function() {
detail
:
{
lineNumber
,
lineSource
,
index
,
checked
},
});
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
document
.
querySelector
(
'
.flash-container .flash-text
'
).
innerText
.
trim
()).
toBe
(
'
Someone edited this merge request at the same time you did. Please refresh the page to see changes.
'
,
);
...
...
@@ -116,11 +114,11 @@ describe('MergeRequest', function() {
describe
(
'
class constructor
'
,
()
=>
{
beforeEach
(()
=>
{
spyOn
(
$
,
'
ajax
'
).
and
.
stub
();
jest
.
spyOn
(
$
,
'
ajax
'
).
mockImplementation
();
});
it
(
'
calls .initCloseReopenReport
'
,
()
=>
{
spyOn
(
IssuablesHelper
,
'
initCloseReopenReport
'
);
jest
.
spyOn
(
IssuablesHelper
,
'
initCloseReopenReport
'
).
mockImplementation
(()
=>
{}
);
new
MergeRequest
();
// eslint-disable-line no-new
...
...
@@ -128,14 +126,20 @@ describe('MergeRequest', function() {
});
it
(
'
calls .initDroplab
'
,
()
=>
{
const
container
=
jasmine
.
createSpyObj
(
'
container
'
,
[
'
querySelector
'
]);
const
container
=
{
querySelector
:
jest
.
fn
().
mockName
(
'
container.querySelector
'
),
};
const
dropdownTrigger
=
{};
const
dropdownList
=
{};
const
button
=
{};
spyOn
(
CloseReopenReportToggle
.
prototype
,
'
initDroplab
'
);
spyOn
(
document
,
'
querySelector
'
).
and
.
returnValue
(
container
);
container
.
querySelector
.
and
.
returnValues
(
dropdownTrigger
,
dropdownList
,
button
);
jest
.
spyOn
(
CloseReopenReportToggle
.
prototype
,
'
initDroplab
'
).
mockImplementation
(()
=>
{});
jest
.
spyOn
(
document
,
'
querySelector
'
).
mockReturnValue
(
container
);
container
.
querySelector
.
mockReturnValueOnce
(
dropdownTrigger
)
.
mockReturnValueOnce
(
dropdownList
)
.
mockReturnValueOnce
(
button
);
new
MergeRequest
();
// eslint-disable-line no-new
...
...
@@ -151,15 +155,15 @@ describe('MergeRequest', function() {
describe
(
'
merge request of another user
'
,
()
=>
{
beforeEach
(()
=>
{
loadFixtures
(
'
merge_requests/merge_request_with_task_list.html
'
);
t
his
.
el
=
document
.
querySelector
(
'
.js-issuable-actions
'
);
t
est
.
el
=
document
.
querySelector
(
'
.js-issuable-actions
'
);
new
MergeRequest
();
// eslint-disable-line no-new
MergeRequest
.
hideCloseButton
();
});
it
(
'
hides the dropdown close item and selects the next item
'
,
()
=>
{
const
closeItem
=
t
his
.
el
.
querySelector
(
'
li.close-item
'
);
const
smallCloseItem
=
t
his
.
el
.
querySelector
(
'
.js-close-item
'
);
const
reportItem
=
t
his
.
el
.
querySelector
(
'
li.report-item
'
);
const
closeItem
=
t
est
.
el
.
querySelector
(
'
li.close-item
'
);
const
smallCloseItem
=
t
est
.
el
.
querySelector
(
'
.js-close-item
'
);
const
reportItem
=
t
est
.
el
.
querySelector
(
'
li.report-item
'
);
expect
(
closeItem
).
toHaveClass
(
'
hidden
'
);
expect
(
smallCloseItem
).
toHaveClass
(
'
hidden
'
);
...
...
@@ -171,13 +175,13 @@ describe('MergeRequest', function() {
describe
(
'
merge request of current_user
'
,
()
=>
{
beforeEach
(()
=>
{
loadFixtures
(
'
merge_requests/merge_request_of_current_user.html
'
);
t
his
.
el
=
document
.
querySelector
(
'
.js-issuable-actions
'
);
t
est
.
el
=
document
.
querySelector
(
'
.js-issuable-actions
'
);
MergeRequest
.
hideCloseButton
();
});
it
(
'
hides the close button
'
,
()
=>
{
const
closeButton
=
t
his
.
el
.
querySelector
(
'
.btn-close
'
);
const
smallCloseItem
=
t
his
.
el
.
querySelector
(
'
.js-close-item
'
);
const
closeButton
=
t
est
.
el
.
querySelector
(
'
.btn-close
'
);
const
smallCloseItem
=
t
est
.
el
.
querySelector
(
'
.js-close-item
'
);
expect
(
closeButton
).
toHaveClass
(
'
hidden
'
);
expect
(
smallCloseItem
).
toHaveClass
(
'
hidden
'
);
...
...
spec/
javascripts
/mini_pipeline_graph_dropdown_spec.js
→
spec/
frontend
/mini_pipeline_graph_dropdown_spec.js
View file @
ac493c39
...
...
@@ -2,7 +2,7 @@ import $ from 'jquery';
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
MiniPipelineGraph
from
'
~/mini_pipeline_graph_dropdown
'
;
import
timeoutPromise
from
'
./helpers/set_timeout_promise_helper
'
;
import
waitForPromises
from
'
./helpers/wait_for_promises
'
;
describe
(
'
Mini Pipeline Graph Dropdown
'
,
()
=>
{
preloadFixtures
(
'
static/mini_dropdown_graph.html
'
);
...
...
@@ -39,9 +39,9 @@ describe('Mini Pipeline Graph Dropdown', () => {
});
it
(
'
should call getBuildsList
'
,
()
=>
{
const
getBuildsListSpy
=
spyOn
(
MiniPipelineGraph
.
prototype
,
'
getBuildsList
'
).
and
.
callFake
(
function
()
{},
);
const
getBuildsListSpy
=
jest
.
spyOn
(
MiniPipelineGraph
.
prototype
,
'
getBuildsList
'
)
.
mockImplementation
(()
=>
{}
);
new
MiniPipelineGraph
({
container
:
'
.js-builds-dropdown-tests
'
}).
bindEvents
();
...
...
@@ -51,7 +51,7 @@ describe('Mini Pipeline Graph Dropdown', () => {
});
it
(
'
should make a request to the endpoint provided in the html
'
,
()
=>
{
const
ajaxSpy
=
spyOn
(
axios
,
'
get
'
).
and
.
callThrough
(
);
const
ajaxSpy
=
jest
.
spyOn
(
axios
,
'
get
'
);
mock
.
onGet
(
'
foobar
'
).
reply
(
200
,
{
html
:
''
,
...
...
@@ -61,7 +61,7 @@ describe('Mini Pipeline Graph Dropdown', () => {
document
.
querySelector
(
'
.js-builds-dropdown-button
'
).
click
();
expect
(
ajaxSpy
.
calls
.
allArgs
()
[
0
][
0
]).
toEqual
(
'
foobar
'
);
expect
(
ajaxSpy
.
mock
.
calls
[
0
][
0
]).
toEqual
(
'
foobar
'
);
});
it
(
'
should not close when user uses cmd/ctrl + click
'
,
done
=>
{
...
...
@@ -78,11 +78,11 @@ describe('Mini Pipeline Graph Dropdown', () => {
document
.
querySelector
(
'
.js-builds-dropdown-button
'
).
click
();
timeoutPromise
()
waitForPromises
()
.
then
(()
=>
{
document
.
querySelector
(
'
a.mini-pipeline-graph-dropdown-item
'
).
click
();
})
.
then
(
timeoutPromise
)
.
then
(
waitForPromises
)
.
then
(()
=>
{
expect
(
$
(
'
.js-builds-dropdown-list
'
).
is
(
'
:visible
'
)).
toEqual
(
true
);
})
...
...
@@ -97,7 +97,7 @@ describe('Mini Pipeline Graph Dropdown', () => {
document
.
querySelector
(
'
.js-builds-dropdown-button
'
).
click
();
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
$
(
'
.js-builds-dropdown-tests .dropdown
'
).
hasClass
(
'
open
'
)).
toEqual
(
false
);
done
();
});
...
...
spec/
javascripts
/pager_spec.js
→
spec/
frontend
/pager_spec.js
View file @
ac493c39
...
...
@@ -2,6 +2,11 @@ import $ from 'jquery';
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
Pager
from
'
~/pager
'
;
import
{
removeParams
}
from
'
~/lib/utils/url_utility
'
;
jest
.
mock
(
'
~/lib/utils/url_utility
'
,
()
=>
({
removeParams
:
jest
.
fn
().
mockName
(
'
removeParams
'
),
}));
describe
(
'
pager
'
,
()
=>
{
let
axiosMock
;
...
...
@@ -19,7 +24,7 @@ describe('pager', () => {
beforeEach
(()
=>
{
setFixtures
(
'
<div class="content_list"></div><div class="loading"></div>
'
);
spyOn
(
$
.
fn
,
'
endlessScroll
'
).
and
.
stub
();
jest
.
spyOn
(
$
.
fn
,
'
endlessScroll
'
).
mockImplementation
();
});
afterEach
(()
=>
{
...
...
@@ -36,7 +41,7 @@ describe('pager', () => {
it
(
'
should use current url if data-href attribute not provided
'
,
()
=>
{
const
href
=
`
${
gl
.
TEST_HOST
}
/some_list`
;
spyOnDependency
(
Pager
,
'
removeParams
'
).
and
.
r
eturnValue
(
href
);
removeParams
.
mockR
eturnValue
(
href
);
Pager
.
init
();
expect
(
Pager
.
url
).
toBe
(
href
);
...
...
@@ -52,7 +57,7 @@ describe('pager', () => {
it
(
'
keeps extra query parameters from url
'
,
()
=>
{
window
.
history
.
replaceState
({},
null
,
'
?filter=test&offset=100
'
);
const
href
=
`
${
gl
.
TEST_HOST
}
/some_list?filter=test`
;
const
removeParams
=
spyOnDependency
(
Pager
,
'
removeParams
'
).
and
.
r
eturnValue
(
href
);
removeParams
.
mockR
eturnValue
(
href
);
Pager
.
init
();
expect
(
removeParams
).
toHaveBeenCalledWith
([
'
limit
'
,
'
offset
'
]);
...
...
@@ -78,7 +83,7 @@ describe('pager', () => {
setFixtures
(
'
<div class="content_list" data-href="/some_list"></div><div class="loading"></div>
'
,
);
spyOn
(
axios
,
'
get
'
).
and
.
callThrough
(
);
jest
.
spyOn
(
axios
,
'
get
'
);
Pager
.
init
();
});
...
...
@@ -86,10 +91,10 @@ describe('pager', () => {
it
(
'
shows loader while loading next page
'
,
done
=>
{
mockSuccess
();
spyOn
(
Pager
.
loading
,
'
show
'
);
jest
.
spyOn
(
Pager
.
loading
,
'
show
'
).
mockImplementation
(()
=>
{}
);
Pager
.
getOld
();
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
Pager
.
loading
.
show
).
toHaveBeenCalled
();
done
();
...
...
@@ -99,10 +104,10 @@ describe('pager', () => {
it
(
'
hides loader on success
'
,
done
=>
{
mockSuccess
();
spyOn
(
Pager
.
loading
,
'
hide
'
);
jest
.
spyOn
(
Pager
.
loading
,
'
hide
'
).
mockImplementation
(()
=>
{}
);
Pager
.
getOld
();
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
Pager
.
loading
.
hide
).
toHaveBeenCalled
();
done
();
...
...
@@ -112,10 +117,10 @@ describe('pager', () => {
it
(
'
hides loader on error
'
,
done
=>
{
mockError
();
spyOn
(
Pager
.
loading
,
'
hide
'
);
jest
.
spyOn
(
Pager
.
loading
,
'
hide
'
).
mockImplementation
(()
=>
{}
);
Pager
.
getOld
();
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
Pager
.
loading
.
hide
).
toHaveBeenCalled
();
done
();
...
...
@@ -127,8 +132,8 @@ describe('pager', () => {
Pager
.
limit
=
20
;
Pager
.
getOld
();
set
Timeout
(()
=>
{
const
[
url
,
params
]
=
axios
.
get
.
calls
.
argsFor
(
0
)
;
set
Immediate
(()
=>
{
const
[
url
,
params
]
=
axios
.
get
.
mock
.
calls
[
0
]
;
expect
(
params
).
toEqual
({
params
:
{
...
...
@@ -148,10 +153,10 @@ describe('pager', () => {
Pager
.
limit
=
20
;
mockSuccess
(
1
);
spyOn
(
Pager
.
loading
,
'
hide
'
);
jest
.
spyOn
(
Pager
.
loading
,
'
hide
'
).
mockImplementation
(()
=>
{}
);
Pager
.
getOld
();
set
Timeout
(()
=>
{
set
Immediate
(()
=>
{
expect
(
Pager
.
loading
.
hide
).
toHaveBeenCalled
();
expect
(
Pager
.
disable
).
toBe
(
true
);
...
...
spec/
javascripts
/todos_spec.js
→
spec/
frontend/pages/dashboard/todos/index
/todos_spec.js
View file @
ac493c39
...
...
@@ -5,6 +5,11 @@ import '~/lib/utils/common_utils';
import
'
~/gl_dropdown
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
{
addDelimiter
}
from
'
~/lib/utils/text_utility
'
;
import
{
visitUrl
}
from
'
~/lib/utils/url_utility
'
;
jest
.
mock
(
'
~/lib/utils/url_utility
'
,
()
=>
({
visitUrl
:
jest
.
fn
().
mockName
(
'
visitUrl
'
),
}));
const
TEST_COUNT_BIG
=
2000
;
const
TEST_DONE_COUNT_BIG
=
7300
;
...
...
@@ -30,7 +35,7 @@ describe('Todos', () => {
it
(
'
opens the todo url
'
,
done
=>
{
const
todoLink
=
todoItem
.
dataset
.
url
;
spyOnDependency
(
Todos
,
'
visitUrl
'
).
and
.
callFake
(
url
=>
{
visitUrl
.
mockImplementation
(
url
=>
{
expect
(
url
).
toEqual
(
todoLink
);
done
();
});
...
...
@@ -39,14 +44,12 @@ describe('Todos', () => {
});
describe
(
'
meta click
'
,
()
=>
{
let
visitUrlSpy
;
let
windowOpenSpy
;
let
metakeyEvent
;
beforeEach
(()
=>
{
metakeyEvent
=
$
.
Event
(
'
click
'
,
{
keyCode
:
91
,
ctrlKey
:
true
});
visitUrlSpy
=
spyOnDependency
(
Todos
,
'
visitUrl
'
).
and
.
callFake
(()
=>
{});
windowOpenSpy
=
spyOn
(
window
,
'
open
'
).
and
.
callFake
(()
=>
{});
windowOpenSpy
=
jest
.
spyOn
(
window
,
'
open
'
).
mockImplementation
(()
=>
{});
});
it
(
'
opens the todo url in another tab
'
,
()
=>
{
...
...
@@ -54,7 +57,7 @@ describe('Todos', () => {
$
(
'
.todos-list .todo
'
).
trigger
(
metakeyEvent
);
expect
(
visitUrl
Spy
).
not
.
toHaveBeenCalled
();
expect
(
visitUrl
).
not
.
toHaveBeenCalled
();
expect
(
windowOpenSpy
).
toHaveBeenCalledWith
(
todoLink
,
'
_blank
'
);
});
...
...
@@ -62,7 +65,7 @@ describe('Todos', () => {
$
(
'
.todos-list a
'
).
on
(
'
click
'
,
e
=>
e
.
preventDefault
());
$
(
'
.todos-list img
'
).
trigger
(
metakeyEvent
);
expect
(
visitUrl
Spy
).
not
.
toHaveBeenCalled
();
expect
(
visitUrl
).
not
.
toHaveBeenCalled
();
expect
(
windowOpenSpy
).
not
.
toHaveBeenCalled
();
});
});
...
...
@@ -78,7 +81,7 @@ describe('Todos', () => {
mock
.
onDelete
(
path
)
.
replyOnce
(
200
,
{
count
:
TEST_COUNT_BIG
,
done_count
:
TEST_DONE_COUNT_BIG
});
onToggleSpy
=
j
asmine
.
createSpy
(
'
onToggle
'
);
onToggleSpy
=
j
est
.
fn
(
);
$
(
document
).
on
(
'
todo:toggle
'
,
onToggleSpy
);
// Act
...
...
@@ -89,7 +92,7 @@ describe('Todos', () => {
});
it
(
'
dispatches todo:toggle
'
,
()
=>
{
expect
(
onToggleSpy
).
toHaveBeenCalledWith
(
jasmine
.
anything
(),
TEST_COUNT_BIG
);
expect
(
onToggleSpy
).
toHaveBeenCalledWith
(
expect
.
anything
(),
TEST_COUNT_BIG
);
});
it
(
'
updates pending text
'
,
()
=>
{
...
...
spec/
javascripts
/signin_tabs_memoizer_spec.js
→
spec/
frontend/pages/sessions/new
/signin_tabs_memoizer_spec.js
View file @
ac493c39
...
...
@@ -2,6 +2,9 @@ import AccessorUtilities from '~/lib/utils/accessor';
import
SigninTabsMemoizer
from
'
~/pages/sessions/new/signin_tabs_memoizer
'
;
import
trackData
from
'
~/pages/sessions/new/index
'
;
import
Tracking
from
'
~/tracking
'
;
import
{
useLocalStorageSpy
}
from
'
helpers/local_storage_helper
'
;
useLocalStorageSpy
();
describe
(
'
SigninTabsMemoizer
'
,
()
=>
{
const
fixtureTemplate
=
'
static/signin_tabs.html
'
;
...
...
@@ -22,7 +25,7 @@ describe('SigninTabsMemoizer', () => {
beforeEach
(()
=>
{
loadFixtures
(
fixtureTemplate
);
spyOn
(
AccessorUtilities
,
'
isLocalStorageAccessSafe
'
).
and
.
r
eturnValue
(
true
);
jest
.
spyOn
(
AccessorUtilities
,
'
isLocalStorageAccessSafe
'
).
mockR
eturnValue
(
true
);
});
it
(
'
does nothing if no tab was previously selected
'
,
()
=>
{
...
...
@@ -38,8 +41,8 @@ describe('SigninTabsMemoizer', () => {
const
fakeTab
=
{
click
:
()
=>
{},
};
spyOn
(
document
,
'
querySelector
'
).
and
.
r
eturnValue
(
fakeTab
);
spyOn
(
fakeTab
,
'
click
'
);
jest
.
spyOn
(
document
,
'
querySelector
'
).
mockR
eturnValue
(
fakeTab
);
jest
.
spyOn
(
fakeTab
,
'
click
'
).
mockImplementation
(()
=>
{}
);
memo
.
bootstrap
();
...
...
@@ -51,17 +54,18 @@ describe('SigninTabsMemoizer', () => {
it
(
'
clicks the first tab if value in local storage is bad
'
,
()
=>
{
createMemoizer
().
saveData
(
'
#bogus
'
);
const
fakeTab
=
{
click
:
()
=>
{}
,
click
:
jest
.
fn
().
mockName
(
'
fakeTab_click
'
)
,
};
spyOn
(
document
,
'
querySelector
'
).
and
.
callFake
(
selector
=>
jest
.
spyOn
(
document
,
'
querySelector
'
)
.
mockImplementation
(
selector
=>
selector
===
`
${
tabSelector
}
a[href="#bogus"]`
?
null
:
fakeTab
,
);
spyOn
(
fakeTab
,
'
click
'
);
memo
.
bootstrap
();
// verify that triggers click on stored selector and fallback
expect
(
document
.
querySelector
.
calls
.
allArgs
()
).
toEqual
([
expect
(
document
.
querySelector
.
mock
.
calls
).
toEqual
([
[
'
ul.new-session-tabs a[href="#bogus"]
'
],
[
'
ul.new-session-tabs a
'
],
]);
...
...
@@ -97,7 +101,7 @@ describe('SigninTabsMemoizer', () => {
describe
(
'
trackData
'
,
()
=>
{
beforeEach
(()
=>
{
spyOn
(
Tracking
,
'
event
'
);
jest
.
spyOn
(
Tracking
,
'
event
'
).
mockImplementation
(()
=>
{}
);
});
describe
(
'
with tracking data
'
,
()
=>
{
...
...
@@ -144,12 +148,10 @@ describe('SigninTabsMemoizer', () => {
memo
=
{
currentTabKey
,
};
spyOn
(
localStorage
,
'
setItem
'
);
});
describe
(
'
if .isLocalStorageAvailable is `false`
'
,
()
=>
{
beforeEach
(
function
()
{
beforeEach
(
()
=>
{
memo
.
isLocalStorageAvailable
=
false
;
SigninTabsMemoizer
.
prototype
.
saveData
.
call
(
memo
);
...
...
@@ -163,7 +165,7 @@ describe('SigninTabsMemoizer', () => {
describe
(
'
if .isLocalStorageAvailable is `true`
'
,
()
=>
{
const
value
=
'
value
'
;
beforeEach
(
function
()
{
beforeEach
(
()
=>
{
memo
.
isLocalStorageAvailable
=
true
;
SigninTabsMemoizer
.
prototype
.
saveData
.
call
(
memo
,
value
);
...
...
@@ -184,11 +186,11 @@ describe('SigninTabsMemoizer', () => {
currentTabKey
,
};
spyOn
(
localStorage
,
'
getItem
'
).
and
.
r
eturnValue
(
itemValue
);
localStorage
.
getItem
.
mockR
eturnValue
(
itemValue
);
});
describe
(
'
if .isLocalStorageAvailable is `false`
'
,
()
=>
{
beforeEach
(
function
()
{
beforeEach
(
()
=>
{
memo
.
isLocalStorageAvailable
=
false
;
readData
=
SigninTabsMemoizer
.
prototype
.
readData
.
call
(
memo
);
...
...
@@ -201,7 +203,7 @@ describe('SigninTabsMemoizer', () => {
});
describe
(
'
if .isLocalStorageAvailable is `true`
'
,
()
=>
{
beforeEach
(
function
()
{
beforeEach
(
()
=>
{
memo
.
isLocalStorageAvailable
=
true
;
readData
=
SigninTabsMemoizer
.
prototype
.
readData
.
call
(
memo
);
...
...
spec/
javascripts
/persistent_user_callout_spec.js
→
spec/
frontend
/persistent_user_callout_spec.js
View file @
ac493c39
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
setTimeoutPromise
from
'
spec/helpers/set_timeout_promise_helper
'
;
import
waitForPromises
from
'
helpers/wait_for_promises
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
PersistentUserCallout
from
'
~/persistent_user_callout
'
;
import
Flash
from
'
~/flash
'
;
jest
.
mock
(
'
~/flash
'
);
describe
(
'
PersistentUserCallout
'
,
()
=>
{
const
dismissEndpoint
=
'
/dismiss
'
;
...
...
@@ -51,44 +54,35 @@ describe('PersistentUserCallout', () => {
button
=
fixture
.
querySelector
(
'
.js-close
'
);
mockAxios
=
new
MockAdapter
(
axios
);
persistentUserCallout
=
new
PersistentUserCallout
(
container
);
spyOn
(
persistentUserCallout
.
container
,
'
remove
'
);
jest
.
spyOn
(
persistentUserCallout
.
container
,
'
remove
'
).
mockImplementation
(()
=>
{}
);
});
afterEach
(()
=>
{
mockAxios
.
restore
();
});
it
(
'
POSTs endpoint and removes container when clicking close
'
,
done
=>
{
it
(
'
POSTs endpoint and removes container when clicking close
'
,
()
=>
{
mockAxios
.
onPost
(
dismissEndpoint
).
replyOnce
(
200
);
button
.
click
();
setTimeoutPromise
()
.
then
(()
=>
{
return
waitForPromises
().
then
(()
=>
{
expect
(
persistentUserCallout
.
container
.
remove
).
toHaveBeenCalled
();
expect
(
mockAxios
.
history
.
post
[
0
].
data
).
toBe
(
JSON
.
stringify
({
feature_name
:
featureName
}),
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
expect
(
mockAxios
.
history
.
post
[
0
].
data
).
toBe
(
JSON
.
stringify
({
feature_name
:
featureName
}));
});
});
it
(
'
invokes Flash when the dismiss request fails
'
,
done
=>
{
const
Flash
=
spyOnDependency
(
PersistentUserCallout
,
'
Flash
'
);
it
(
'
invokes Flash when the dismiss request fails
'
,
()
=>
{
mockAxios
.
onPost
(
dismissEndpoint
).
replyOnce
(
500
);
button
.
click
();
setTimeoutPromise
()
.
then
(()
=>
{
return
waitForPromises
().
then
(()
=>
{
expect
(
persistentUserCallout
.
container
.
remove
).
not
.
toHaveBeenCalled
();
expect
(
Flash
).
toHaveBeenCalledWith
(
'
An error occurred while dismissing the alert. Refresh the page and try again.
'
,
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
});
...
...
@@ -108,56 +102,45 @@ describe('PersistentUserCallout', () => {
normalLink
=
fixture
.
querySelector
(
'
.normal-link
'
);
mockAxios
=
new
MockAdapter
(
axios
);
persistentUserCallout
=
new
PersistentUserCallout
(
container
);
spyOn
(
persistentUserCallout
.
container
,
'
remove
'
);
windowSpy
=
spyOn
(
window
,
'
open
'
).
and
.
callFake
(()
=>
{});
jest
.
spyOn
(
persistentUserCallout
.
container
,
'
remove
'
).
mockImplementation
(()
=>
{}
);
windowSpy
=
jest
.
spyOn
(
window
,
'
open
'
).
mockImplementation
(()
=>
{});
});
afterEach
(()
=>
{
mockAxios
.
restore
();
});
it
(
'
defers loading of a link until callout is dismissed
'
,
done
=>
{
it
(
'
defers loading of a link until callout is dismissed
'
,
()
=>
{
const
{
href
,
target
}
=
deferredLink
;
mockAxios
.
onPost
(
dismissEndpoint
).
replyOnce
(
200
);
deferredLink
.
click
();
setTimeoutPromise
()
.
then
(()
=>
{
return
waitForPromises
().
then
(()
=>
{
expect
(
windowSpy
).
toHaveBeenCalledWith
(
href
,
target
);
expect
(
persistentUserCallout
.
container
.
remove
).
toHaveBeenCalled
();
expect
(
mockAxios
.
history
.
post
[
0
].
data
).
toBe
(
JSON
.
stringify
({
feature_name
:
featureName
}),
);
})
.
then
(
done
)
.
catch
(
done
.
fail
);
expect
(
mockAxios
.
history
.
post
[
0
].
data
).
toBe
(
JSON
.
stringify
({
feature_name
:
featureName
}));
});
});
it
(
'
does not dismiss callout on non-deferred links
'
,
done
=>
{
it
(
'
does not dismiss callout on non-deferred links
'
,
()
=>
{
normalLink
.
click
();
setTimeoutPromise
()
.
then
(()
=>
{
return
waitForPromises
().
then
(()
=>
{
expect
(
windowSpy
).
not
.
toHaveBeenCalled
();
expect
(
persistentUserCallout
.
container
.
remove
).
not
.
toHaveBeenCalled
();
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
it
(
'
does not follow link when notification is closed
'
,
done
=>
{
it
(
'
does not follow link when notification is closed
'
,
()
=>
{
mockAxios
.
onPost
(
dismissEndpoint
).
replyOnce
(
200
);
button
.
click
();
setTimeoutPromise
()
.
then
(()
=>
{
return
waitForPromises
().
then
(()
=>
{
expect
(
windowSpy
).
not
.
toHaveBeenCalled
();
expect
(
persistentUserCallout
.
container
.
remove
).
toHaveBeenCalled
();
})
.
then
(
done
)
.
catch
(
done
.
fail
);
});
});
});
...
...
spec/
javascripts
/read_more_spec.js
→
spec/
frontend
/read_more_spec.js
View file @
ac493c39
File moved
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