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
25dc9f11
Commit
25dc9f11
authored
May 14, 2020
by
Vitaly Slobodin
Committed by
Paul Slaughter
Jun 22, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Migrate ee/approvals to Jest
Closes
https://gitlab.com/gitlab-org/gitlab/-/issues/194266
parent
9552bbee
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
69 additions
and
68 deletions
+69
-68
ee/spec/frontend/approvals/components/approvers_select_spec.js
...ec/frontend/approvals/components/approvers_select_spec.js
+12
-11
ee/spec/frontend/approvals/components/mr_edit/app_spec.js
ee/spec/frontend/approvals/components/mr_edit/app_spec.js
+12
-5
ee/spec/frontend/approvals/stores/modules/project_settings/actions_spec.js
...approvals/stores/modules/project_settings/actions_spec.js
+45
-52
No files found.
ee/spec/
javascripts
/approvals/components/approvers_select_spec.js
→
ee/spec/
frontend
/approvals/components/approvers_select_spec.js
View file @
25dc9f11
import
{
createLocalVue
,
m
ount
}
from
'
@vue/test-utils
'
;
import
{
createLocalVue
,
shallowM
ount
}
from
'
@vue/test-utils
'
;
import
$
from
'
jquery
'
;
import
Api
from
'
ee/api
'
;
import
ApproversSelect
from
'
ee/approvals/components/approvers_select.vue
'
;
import
{
TYPE_USER
,
TYPE_GROUP
}
from
'
ee/approvals/constants
'
;
import
{
TEST_HOST
}
from
'
spec
/test_constants
'
;
import
{
TEST_HOST
}
from
'
helpers
/test_constants
'
;
const
DEBOUNCE_TIME
=
250
;
const
TEST_PROJECT_ID
=
'
17
'
;
const
TEST_GROUP_AVATAR
=
`
${
TEST_HOST
}
/group-avatar.png`
;
const
TEST_USER_AVATAR
=
`
${
TEST_HOST
}
/user-avatar.png`
;
...
...
@@ -26,7 +25,8 @@ const TEST_USERS = [
const
localVue
=
createLocalVue
();
const
waitForEvent
=
(
$input
,
event
)
=>
new
Promise
(
resolve
=>
$input
.
one
(
event
,
resolve
));
const
parseAvatar
=
element
=>
(
element
.
classList
.
contains
(
'
identicon
'
)
?
null
:
element
.
src
);
const
parseAvatar
=
element
=>
element
.
classList
.
contains
(
'
identicon
'
)
?
null
:
element
.
getAttribute
(
'
src
'
);
const
select2Container
=
()
=>
document
.
querySelector
(
'
.select2-container
'
);
const
select2DropdownOptions
=
()
=>
document
.
querySelectorAll
(
'
#select2-drop .user-result
'
);
const
select2DropdownItems
=
()
=>
...
...
@@ -57,7 +57,7 @@ describe('Approvals ApproversSelect', () => {
...
options
.
propsData
,
};
wrapper
=
mount
(
localVue
.
extend
(
ApproversSelect
)
,
{
wrapper
=
shallowMount
(
ApproversSelect
,
{
...
options
,
propsData
,
localVue
,
...
...
@@ -68,18 +68,15 @@ describe('Approvals ApproversSelect', () => {
};
const
search
=
(
term
=
''
)
=>
{
$input
.
select2
(
'
search
'
,
term
);
jasmine
.
clock
().
mockDate
();
jasmine
.
clock
().
tick
(
DEBOUNCE_TIME
);
jest
.
runOnlyPendingTimers
();
};
beforeEach
(()
=>
{
jasmine
.
clock
().
install
();
spyOn
(
Api
,
'
groups
'
).
and
.
returnValue
(
Promise
.
resolve
(
TEST_GROUPS
));
spyOn
(
Api
,
'
projectUsers
'
).
and
.
returnValue
(
Promise
.
resolve
(
TEST_USERS
));
jest
.
spyOn
(
Api
,
'
groups
'
).
mockResolvedValue
(
TEST_GROUPS
);
jest
.
spyOn
(
Api
,
'
projectUsers
'
).
mockReturnValue
(
Promise
.
resolve
(
TEST_USERS
));
});
afterEach
(()
=>
{
jasmine
.
clock
().
uninstall
();
wrapper
.
destroy
();
});
...
...
@@ -117,6 +114,7 @@ describe('Approvals ApproversSelect', () => {
factory
();
waitForEvent
(
$input
,
'
select2-loaded
'
)
.
then
(
jest
.
runOnlyPendingTimers
)
.
then
(
done
)
.
catch
(
done
.
fail
);
...
...
@@ -147,6 +145,7 @@ describe('Approvals ApproversSelect', () => {
});
waitForEvent
(
$input
,
'
select2-loaded
'
)
.
then
(
jest
.
runOnlyPendingTimers
)
.
then
(
done
)
.
catch
(
done
.
fail
);
...
...
@@ -185,10 +184,12 @@ describe('Approvals ApproversSelect', () => {
$
(
options
[
TEST_GROUPS
.
length
]).
trigger
(
'
mouseup
'
);
$
(
options
[
0
]).
trigger
(
'
mouseup
'
);
})
.
then
(
jest
.
runOnlyPendingTimers
)
.
then
(
done
)
.
catch
(
done
.
fail
);
waitForEvent
(
$input
,
'
change
'
)
.
then
(
jest
.
runOnlyPendingTimers
)
.
then
(()
=>
{
expect
(
wrapper
.
emittedByOrder
()).
toEqual
(
expected
);
})
...
...
ee/spec/
javascripts
/approvals/components/mr_edit/app_spec.js
→
ee/spec/
frontend
/approvals/components/mr_edit/app_spec.js
View file @
25dc9f11
import
{
mount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
Vuex
from
'
vuex
'
;
import
axios
from
'
axios
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
createStoreOptions
}
from
'
ee/approvals/stores
'
;
import
MREditModule
from
'
ee/approvals/stores/modules/mr_edit
'
;
import
MREditApp
from
'
ee/approvals/components/mr_edit/app.vue
'
;
...
...
@@ -12,21 +14,26 @@ localVue.use(Vuex);
describe
(
'
EE Approvals MREditApp
'
,
()
=>
{
let
wrapper
;
let
store
;
let
axiosMock
;
const
factory
=
()
=>
{
wrapper
=
mount
(
localVue
.
extend
(
MREditApp
)
,
{
wrapper
=
mount
(
MREditApp
,
{
localVue
,
store
:
new
Vuex
.
Store
(
store
),
});
};
beforeEach
(()
=>
{
axiosMock
=
new
MockAdapter
(
axios
);
axiosMock
.
onGet
(
'
*
'
);
store
=
createStoreOptions
(
MREditModule
());
store
.
modules
.
approvals
.
state
.
hasLoaded
=
true
;
});
afterEach
(()
=>
{
wrapper
.
destroy
();
axiosMock
.
restore
();
});
describe
(
'
with empty rules
'
,
()
=>
{
...
...
@@ -36,11 +43,11 @@ describe('EE Approvals MREditApp', () => {
});
it
(
'
does not render MR rules
'
,
()
=>
{
expect
(
wrapper
.
find
(
MRRules
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
find
(
MRRules
).
findAll
(
'
.js-name
'
)).
toHaveLength
(
0
);
});
it
(
'
renders hidden inputs
'
,
()
=>
{
expect
(
wrapper
.
find
(
MRRulesHiddenInputs
).
exists
(
)).
toBe
(
true
);
expect
(
wrapper
.
find
(
'
.js-approval-rules
'
).
contains
(
MRRulesHiddenInputs
)).
toBe
(
true
);
});
});
...
...
@@ -51,11 +58,11 @@ describe('EE Approvals MREditApp', () => {
});
it
(
'
renders MR rules
'
,
()
=>
{
expect
(
wrapper
.
find
(
MRRules
).
exists
()).
toBe
(
true
);
expect
(
wrapper
.
find
(
MRRules
).
findAll
(
'
.js-name
'
)).
toHaveLength
(
1
);
});
it
(
'
renders hidden inputs
'
,
()
=>
{
expect
(
wrapper
.
find
(
MRRulesHiddenInputs
).
exists
(
)).
toBe
(
true
);
expect
(
wrapper
.
find
(
'
.js-approval-rules
'
).
contains
(
MRRulesHiddenInputs
)).
toBe
(
true
);
});
});
});
ee/spec/
javascripts
/approvals/stores/modules/project_settings/actions_spec.js
→
ee/spec/
frontend
/approvals/stores/modules/project_settings/actions_spec.js
View file @
25dc9f11
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
testAction
from
'
spec/helpers/vuex_action_helper
'
;
import
createFlash
from
'
~/flash
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
*
as
types
from
'
ee/approvals/stores/modules/base/mutation_types
'
;
import
actionsModule
,
*
as
actions
from
'
ee/approvals/stores/modules/project_settings/actions
'
;
import
*
as
actions
from
'
ee/approvals/stores/modules/project_settings/actions
'
;
import
{
mapApprovalRuleRequest
,
mapApprovalSettingsResponse
}
from
'
ee/approvals/mappers
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
jest
.
mock
(
'
~/flash
'
);
const
TEST_PROJECT_ID
=
9
;
const
TEST_RULE_ID
=
7
;
const
TEST_RULE_REQUEST
=
{
...
...
@@ -26,7 +29,6 @@ const TEST_RULES_PATH = 'projects/9/approval_settings/rules';
describe
(
'
EE approvals project settings module actions
'
,
()
=>
{
let
state
;
let
flashSpy
;
let
mock
;
beforeEach
(()
=>
{
...
...
@@ -37,7 +39,6 @@ describe('EE approvals project settings module actions', () => {
rulesPath
:
TEST_RULES_PATH
,
},
};
flashSpy
=
spyOnDependency
(
actionsModule
,
'
createFlash
'
);
mock
=
new
MockAdapter
(
axios
);
});
...
...
@@ -46,23 +47,22 @@ describe('EE approvals project settings module actions', () => {
});
describe
(
'
requestRules
'
,
()
=>
{
it
(
'
sets loading
'
,
done
=>
{
testAction
(
it
(
'
sets loading
'
,
()
=>
{
return
testAction
(
actions
.
requestRules
,
null
,
{},
[{
type
:
types
.
SET_LOADING
,
payload
:
true
}],
[],
done
,
);
});
});
describe
(
'
receiveRulesSuccess
'
,
()
=>
{
it
(
'
sets rules
'
,
done
=>
{
it
(
'
sets rules
'
,
()
=>
{
const
settings
=
{
rules
:
[{
id
:
1
}]
};
testAction
(
return
testAction
(
actions
.
receiveRulesSuccess
,
settings
,
{},
...
...
@@ -71,28 +71,27 @@ describe('EE approvals project settings module actions', () => {
{
type
:
types
.
SET_LOADING
,
payload
:
false
},
],
[],
done
,
);
});
});
describe
(
'
receiveRulesError
'
,
()
=>
{
it
(
'
creates a flash
'
,
()
=>
{
expect
(
flashSpy
).
not
.
toHaveBeenCalled
();
expect
(
createFlash
).
not
.
toHaveBeenCalled
();
actions
.
receiveRulesError
();
expect
(
flashSpy
).
toHaveBeenCalledTimes
(
1
);
expect
(
flashSpy
).
toHaveBeenCalledWith
(
jasmine
.
stringMatching
(
'
error occurred
'
));
expect
(
createFlash
).
toHaveBeenCalledTimes
(
1
);
expect
(
createFlash
).
toHaveBeenCalledWith
(
expect
.
stringMatching
(
'
error occurred
'
));
});
});
describe
(
'
fetchRules
'
,
()
=>
{
it
(
'
dispatches request/receive
'
,
done
=>
{
it
(
'
dispatches request/receive
'
,
()
=>
{
const
data
=
{
rules
:
[
TEST_RULE_RESPONSE
]
};
mock
.
onGet
(
TEST_SETTINGS_PATH
).
replyOnce
(
200
,
data
);
testAction
(
return
testAction
(
actions
.
fetchRules
,
null
,
state
,
...
...
@@ -103,54 +102,50 @@ describe('EE approvals project settings module actions', () => {
],
()
=>
{
expect
(
mock
.
history
.
get
.
map
(
x
=>
x
.
url
)).
toEqual
([
TEST_SETTINGS_PATH
]);
done
();
},
);
});
it
(
'
dispatches request/receive on error
'
,
done
=>
{
it
(
'
dispatches request/receive on error
'
,
()
=>
{
mock
.
onGet
(
TEST_SETTINGS_PATH
).
replyOnce
(
500
);
testAction
(
return
testAction
(
actions
.
fetchRules
,
null
,
state
,
[],
[{
type
:
'
requestRules
'
},
{
type
:
'
receiveRulesError
'
}],
done
,
);
});
});
describe
(
'
postRuleSuccess
'
,
()
=>
{
it
(
'
closes modal and fetches
'
,
done
=>
{
testAction
(
it
(
'
closes modal and fetches
'
,
()
=>
{
return
testAction
(
actions
.
postRuleSuccess
,
null
,
{},
[],
[{
type
:
'
createModal/close
'
},
{
type
:
'
fetchRules
'
}],
done
,
);
});
});
describe
(
'
postRuleError
'
,
()
=>
{
it
(
'
creates a flash
'
,
()
=>
{
expect
(
flashSpy
).
not
.
toHaveBeenCalled
();
expect
(
createFlash
).
not
.
toHaveBeenCalled
();
actions
.
postRuleError
();
expect
(
flashSpy
.
calls
.
allArgs
()).
toEqual
([[
jasmine
.
stringMatching
(
'
error occurred
'
)]
]);
expect
(
createFlash
.
mock
.
calls
[
0
]).
toEqual
([
expect
.
stringMatching
(
'
error occurred
'
)
]);
});
});
describe
(
'
postRule
'
,
()
=>
{
it
(
'
dispatches success on success
'
,
done
=>
{
it
(
'
dispatches success on success
'
,
()
=>
{
mock
.
onPost
(
TEST_RULES_PATH
).
replyOnce
(
200
);
testAction
(
return
testAction
(
actions
.
postRule
,
TEST_RULE_REQUEST
,
state
,
...
...
@@ -158,29 +153,33 @@ describe('EE approvals project settings module actions', () => {
[{
type
:
'
postRuleSuccess
'
}],
()
=>
{
expect
(
mock
.
history
.
post
).
toEqual
([
jasmine
.
objectContaining
({
expect
.
objectContaining
({
url
:
TEST_RULES_PATH
,
data
:
JSON
.
stringify
(
mapApprovalRuleRequest
(
TEST_RULE_REQUEST
)),
}),
]);
done
();
},
);
});
it
(
'
dispatches error on error
'
,
done
=>
{
it
(
'
dispatches error on error
'
,
()
=>
{
mock
.
onPost
(
TEST_RULES_PATH
).
replyOnce
(
500
);
testAction
(
actions
.
postRule
,
TEST_RULE_REQUEST
,
state
,
[],
[{
type
:
'
postRuleError
'
}],
done
);
return
testAction
(
actions
.
postRule
,
TEST_RULE_REQUEST
,
state
,
[],
[{
type
:
'
postRuleError
'
}],
);
});
});
describe
(
'
putRule
'
,
()
=>
{
it
(
'
dispatches success on success
'
,
done
=>
{
it
(
'
dispatches success on success
'
,
()
=>
{
mock
.
onPut
(
`
${
TEST_RULES_PATH
}
/
${
TEST_RULE_ID
}
`
).
replyOnce
(
200
);
testAction
(
return
testAction
(
actions
.
putRule
,
{
id
:
TEST_RULE_ID
,
...
TEST_RULE_REQUEST
},
state
,
...
...
@@ -188,59 +187,55 @@ describe('EE approvals project settings module actions', () => {
[{
type
:
'
postRuleSuccess
'
}],
()
=>
{
expect
(
mock
.
history
.
put
).
toEqual
([
jasmine
.
objectContaining
({
expect
.
objectContaining
({
url
:
`
${
TEST_RULES_PATH
}
/
${
TEST_RULE_ID
}
`
,
data
:
JSON
.
stringify
(
mapApprovalRuleRequest
(
TEST_RULE_REQUEST
)),
}),
]);
done
();
},
);
});
it
(
'
dispatches error on error
'
,
done
=>
{
it
(
'
dispatches error on error
'
,
()
=>
{
mock
.
onPut
(
`
${
TEST_RULES_PATH
}
/
${
TEST_RULE_ID
}
`
).
replyOnce
(
500
);
testAction
(
return
testAction
(
actions
.
putRule
,
{
id
:
TEST_RULE_ID
,
...
TEST_RULE_REQUEST
},
state
,
[],
[{
type
:
'
postRuleError
'
}],
done
,
);
});
});
describe
(
'
deleteRuleSuccess
'
,
()
=>
{
it
(
'
closes modal and fetches
'
,
done
=>
{
testAction
(
it
(
'
closes modal and fetches
'
,
()
=>
{
return
testAction
(
actions
.
deleteRuleSuccess
,
null
,
{},
[],
[{
type
:
'
deleteModal/close
'
},
{
type
:
'
fetchRules
'
}],
done
,
);
});
});
describe
(
'
deleteRuleError
'
,
()
=>
{
it
(
'
creates a flash
'
,
()
=>
{
expect
(
flashSpy
).
not
.
toHaveBeenCalled
();
expect
(
createFlash
).
not
.
toHaveBeenCalled
();
actions
.
deleteRuleError
();
expect
(
flashSpy
.
calls
.
allArgs
()).
toEqual
([[
jasmine
.
stringMatching
(
'
error occurred
'
)]
]);
expect
(
createFlash
.
mock
.
calls
[
0
]).
toEqual
([
expect
.
stringMatching
(
'
error occurred
'
)
]);
});
});
describe
(
'
deleteRule
'
,
()
=>
{
it
(
'
dispatches success on success
'
,
done
=>
{
it
(
'
dispatches success on success
'
,
()
=>
{
mock
.
onDelete
(
`
${
TEST_RULES_PATH
}
/
${
TEST_RULE_ID
}
`
).
replyOnce
(
200
);
testAction
(
return
testAction
(
actions
.
deleteRule
,
TEST_RULE_ID
,
state
,
...
...
@@ -248,20 +243,18 @@ describe('EE approvals project settings module actions', () => {
[{
type
:
'
deleteRuleSuccess
'
}],
()
=>
{
expect
(
mock
.
history
.
delete
).
toEqual
([
jasmine
.
objectContaining
({
expect
.
objectContaining
({
url
:
`
${
TEST_RULES_PATH
}
/
${
TEST_RULE_ID
}
`
,
}),
]);
done
();
},
);
});
it
(
'
dispatches error on error
'
,
done
=>
{
it
(
'
dispatches error on error
'
,
()
=>
{
mock
.
onDelete
(
`
${
TEST_RULES_PATH
}
/
${
TEST_RULE_ID
}
`
).
replyOnce
(
500
);
testAction
(
actions
.
deleteRule
,
TEST_RULE_ID
,
state
,
[],
[{
type
:
'
deleteRuleError
'
}],
done
);
return
testAction
(
actions
.
deleteRule
,
TEST_RULE_ID
,
state
,
[],
[{
type
:
'
deleteRuleError
'
}]
);
});
});
});
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