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
d90a33f4
Commit
d90a33f4
authored
Mar 26, 2020
by
Alexander Turinske
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor security_dashboard store tests to be Jest
- moving Karma tests to Jest
parent
8d1fe49b
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1688 additions
and
2393 deletions
+1688
-2393
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/actions.js
...curity_dashboard/store/modules/vulnerabilities/actions.js
+4
-4
ee/spec/frontend/security_dashboard/store/modules/filters/actions_spec.js
.../security_dashboard/store/modules/filters/actions_spec.js
+11
-5
ee/spec/frontend/security_dashboard/store/modules/projects/actions_spec.js
...security_dashboard/store/modules/projects/actions_spec.js
+1
-1
ee/spec/frontend/security_dashboard/store/modules/projects/data/mock_data.json
...rity_dashboard/store/modules/projects/data/mock_data.json
+0
-0
ee/spec/frontend/security_dashboard/store/modules/projects/mutations_spec.js
...curity_dashboard/store/modules/projects/mutations_spec.js
+0
-0
ee/spec/frontend/security_dashboard/store/modules/vulnerabilities/actions_spec.js
...y_dashboard/store/modules/vulnerabilities/actions_spec.js
+1656
-46
ee/spec/frontend/security_dashboard/store/modules/vulnerabilities/getters_spec.js
...y_dashboard/store/modules/vulnerabilities/getters_spec.js
+15
-5
ee/spec/frontend/security_dashboard/store/plugins/mediator_spec.js
...rontend/security_dashboard/store/plugins/mediator_spec.js
+1
-1
ee/spec/javascripts/security_dashboard/store/vulnerabilities/actions_spec.js
.../security_dashboard/store/vulnerabilities/actions_spec.js
+0
-1693
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities.js
...d/store/vulnerabilities/data/mock_data_vulnerabilities.js
+0
-3
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities_count.json
...vulnerabilities/data/mock_data_vulnerabilities_count.json
+0
-7
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities_history.json
...lnerabilities/data/mock_data_vulnerabilities_history.json
+0
-628
No files found.
ee/app/assets/javascripts/security_dashboard/store/modules/vulnerabilities/actions.js
View file @
d90a33f4
...
...
@@ -441,11 +441,11 @@ export const receiveUndoDismissError = ({ commit }, { flashError }) => {
};
export
const
downloadPatch
=
({
state
})
=>
{
/*
/*
This action doesn't actually mutate the Vuex state and is a dirty
workaround to modifying the dom. We do this because gl-split-button
relies on a old version of vue-bootstrap and it doesn't allow us to
set a href for a file download.
workaround to modifying the dom. We do this because gl-split-button
relies on a old version of vue-bootstrap and it doesn't allow us to
set a href for a file download.
https://gitlab.com/gitlab-org/gitlab-ui/issues/188#note_165808493
*/
...
...
ee/spec/
javascripts/security_dashboard/store
/filters/actions_spec.js
→
ee/spec/
frontend/security_dashboard/store/modules
/filters/actions_spec.js
View file @
d90a33f4
import
testAction
from
'
spec/
helpers/vuex_action_helper
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
createState
from
'
ee/security_dashboard/store/modules/filters/state
'
;
import
*
as
types
from
'
ee/security_dashboard/store/modules/filters/mutation_types
'
;
import
module
,
*
as
actions
from
'
ee/security_dashboard/store/modules/filters/actions
'
;
import
*
as
actions
from
'
ee/security_dashboard/store/modules/filters/actions
'
;
import
{
ALL
}
from
'
ee/security_dashboard/store/modules/filters/constants
'
;
import
Tracking
from
'
~/tracking
'
;
import
{
getParameterValues
}
from
'
~/lib/utils/url_utility
'
;
jest
.
mock
(
'
~/lib/utils/url_utility
'
,
()
=>
({
getParameterValues
:
jest
.
fn
().
mockReturnValue
([]),
}));
describe
(
'
filters actions
'
,
()
=>
{
beforeEach
(()
=>
{
spyOn
(
Tracking
,
'
event
'
);
jest
.
spyOn
(
Tracking
,
'
event
'
).
mockImplementation
(()
=>
{}
);
});
describe
(
'
setFilter
'
,
()
=>
{
...
...
@@ -85,7 +90,7 @@ describe('filters actions', () => {
},
{
type
:
types
.
SET_FILTER
,
payload
:
jasmine
.
objectContaining
({
payload
:
expect
.
objectContaining
({
filterId
:
'
project_id
'
,
optionId
:
ALL
,
}),
...
...
@@ -164,7 +169,8 @@ describe('filters actions', () => {
},
].
forEach
(
testCase
=>
{
it
(
testCase
.
description
,
done
=>
{
spyOnDependency
(
module
,
'
getParameterValues
'
).
and
.
returnValue
(
testCase
.
returnValue
);
const
mockValue
=
testCase
.
returnValue
;
getParameterValues
.
mockImplementation
(()
=>
mockValue
);
const
state
=
createState
();
testAction
(
actions
.
setHideDismissedToggleInitialState
,
...
...
ee/spec/
javascripts/security_dashboard/store
/projects/actions_spec.js
→
ee/spec/
frontend/security_dashboard/store/modules
/projects/actions_spec.js
View file @
d90a33f4
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
testAction
from
'
spec/
helpers/vuex_action_helper
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
createState
from
'
ee/security_dashboard/store/modules/projects/state
'
;
...
...
ee/spec/
javascripts/security_dashboard/store
/projects/data/mock_data.json
→
ee/spec/
frontend/security_dashboard/store/modules
/projects/data/mock_data.json
View file @
d90a33f4
File moved
ee/spec/
javascripts/security_dashboard/store
/projects/mutations_spec.js
→
ee/spec/
frontend/security_dashboard/store/modules
/projects/mutations_spec.js
View file @
d90a33f4
File moved
ee/spec/frontend/security_dashboard/store/modules/vulnerabilities/actions_spec.js
View file @
d90a33f4
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
testAction
from
'
helpers/vuex_action_helper
'
;
import
createState
from
'
ee/security_dashboard/store/modules/unscanned_projects/state
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
{
DAYS
}
from
'
ee/security_dashboard/store/modules/vulnerabilities/constants
'
;
import
initialState
from
'
ee/security_dashboard/store/modules/vulnerabilities/state
'
;
import
*
as
types
from
'
ee/security_dashboard/store/modules/vulnerabilities/mutation_types
'
;
import
*
as
actions
from
'
ee/security_dashboard/store/modules/vulnerabilities/actions
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
toast
from
'
~/vue_shared/plugins/global_toast
'
;
import
mockDataVulnerabilities
from
'
./data/mock_data_vulnerabilities
'
;
import
mockDataVulnerabilitiesCount
from
'
./data/mock_data_vulnerabilities_count.json
'
;
import
mockDataVulnerabilitiesHistory
from
'
./data/mock_data_vulnerabilities_history.json
'
;
const
sourceBranch
=
'
feature-branch-1
'
;
jest
.
mock
(
'
~/vue_shared/plugins/global_toast
'
);
jest
.
mock
(
'
jquery
'
,
()
=>
()
=>
({
modal
:
jest
.
fn
(),
}));
describe
(
'
vulnerabilities count actions
'
,
()
=>
{
const
data
=
mockDataVulnerabilitiesCount
;
const
params
=
{
filters
:
{
type
:
[
'
sast
'
]
}
};
const
filteredData
=
mockDataVulnerabilitiesCount
.
sast
;
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
setPipelineId
'
,
()
=>
{
const
pipelineId
=
123
;
it
(
'
should commit the correct mutation
'
,
done
=>
{
testAction
(
actions
.
setPipelineId
,
pipelineId
,
state
,
[
{
type
:
types
.
SET_PIPELINE_ID
,
payload
:
pipelineId
,
},
],
[],
done
,
);
});
});
describe
(
'
setSourceBranch
'
,
()
=>
{
it
(
'
should commit the correct mutation
'
,
done
=>
{
testAction
(
actions
.
setSourceBranch
,
sourceBranch
,
state
,
[
{
type
:
types
.
SET_SOURCE_BRANCH
,
payload
:
sourceBranch
,
},
],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesCountEndpoint
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
endpoint
=
'
fakepath.json
'
;
testAction
(
actions
.
setVulnerabilitiesCountEndpoint
,
endpoint
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_COUNT_ENDPOINT
,
payload
:
endpoint
,
},
],
[],
done
,
);
});
});
describe
(
'
fetchVulnerabilitiesCount
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
state
.
vulnerabilitiesCountEndpoint
=
`
${
TEST_HOST
}
/vulnerabilities_count.json`
;
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesCountEndpoint
,
{
params
})
.
replyOnce
(
200
,
filteredData
)
.
onGet
(
state
.
vulnerabilitiesCountEndpoint
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilitiesCount
'
},
{
type
:
'
receiveVulnerabilitiesCountSuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
it
(
'
should send the passed filters to the endpoint
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
params
,
state
,
[],
[
{
type
:
'
requestVulnerabilitiesCount
'
},
{
type
:
'
receiveVulnerabilitiesCountSuccess
'
,
payload
:
{
data
:
filteredData
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesCountEndpoint
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
{},
state
,
[],
[{
type
:
'
requestVulnerabilitiesCount
'
},
{
type
:
'
receiveVulnerabilitiesCountError
'
}],
done
,
);
});
});
describe
(
'
with an empty endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
vulnerabilitiesCountEndpoint
=
''
;
});
it
(
'
should not do anything
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
{},
state
,
[],
[],
done
);
});
});
});
describe
(
'
requestVulnerabilitiesCount
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestVulnerabilitiesCount
,
{},
state
,
[{
type
:
types
.
REQUEST_VULNERABILITIES_COUNT
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesCountSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesCountSuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_COUNT_SUCCESS
,
payload
:
data
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesCountError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesCountError
,
{},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_COUNT_ERROR
}],
[],
done
,
);
});
});
});
describe
(
'
vulnerabilities actions
'
,
()
=>
{
const
data
=
mockDataVulnerabilities
;
const
params
=
{
filters
:
{
severity
:
[
'
critical
'
]
}
};
const
filteredData
=
mockDataVulnerabilities
.
filter
(
vuln
=>
vuln
.
severity
===
'
critical
'
);
const
pageInfo
=
{
page
:
1
,
nextPage
:
2
,
previousPage
:
1
,
perPage
:
20
,
total
:
100
,
totalPages
:
5
,
};
const
headers
=
{
'
X-Next-Page
'
:
pageInfo
.
nextPage
,
'
X-Page
'
:
pageInfo
.
page
,
'
X-Per-Page
'
:
pageInfo
.
perPage
,
'
X-Prev-Page
'
:
pageInfo
.
previousPage
,
'
X-Total
'
:
pageInfo
.
total
,
'
X-Total-Pages
'
:
pageInfo
.
totalPages
,
};
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
fetchVulnerabilities
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
state
.
vulnerabilitiesEndpoint
=
`
${
TEST_HOST
}
/vulnerabilities.json`
;
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesEndpoint
,
{
params
})
.
replyOnce
(
200
,
filteredData
,
headers
)
.
onGet
(
state
.
vulnerabilitiesEndpoint
)
.
replyOnce
(
200
,
data
,
headers
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilities
'
},
{
type
:
'
receiveVulnerabilitiesSuccess
'
,
payload
:
{
data
,
headers
},
},
],
done
,
);
});
it
(
'
should pass through the filters
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
params
,
state
,
[],
[
{
type
:
'
requestVulnerabilities
'
},
{
type
:
'
receiveVulnerabilitiesSuccess
'
,
payload
:
{
data
:
filteredData
,
headers
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
const
errorCode
=
404
;
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesEndpoint
).
replyOnce
(
errorCode
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilities
'
},
{
type
:
'
receiveVulnerabilitiesError
'
,
payload
:
errorCode
},
],
done
,
);
});
});
describe
(
'
with an empty endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
vulnerabilitiesEndpoint
=
''
;
});
it
(
'
should not do anything
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
{},
state
,
[],
[],
done
);
});
});
});
describe
(
'
receiveVulnerabilitiesSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesSuccess
,
{
headers
,
data
},
state
,
[
{
type
:
types
.
RECEIVE_VULNERABILITIES_SUCCESS
,
payload
:
{
pageInfo
,
vulnerabilities
:
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
const
errorCode
=
403
;
testAction
(
actions
.
receiveVulnerabilitiesError
,
errorCode
,
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_ERROR
,
payload
:
errorCode
}],
[],
done
,
);
});
});
describe
(
'
requestVulnerabilities
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestVulnerabilities
,
{},
state
,
[{
type
:
types
.
REQUEST_VULNERABILITIES
}],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesEndpoint
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
endpoint
=
'
fakepath.json
'
;
testAction
(
actions
.
setVulnerabilitiesEndpoint
,
endpoint
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_ENDPOINT
,
payload
:
endpoint
,
},
],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesPage
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
page
=
3
;
testAction
(
actions
.
setVulnerabilitiesPage
,
page
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_PAGE
,
payload
:
page
,
},
],
[],
done
,
);
});
});
});
describe
(
'
openModal
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
it
(
'
should commit the SET_MODAL_DATA mutation
'
,
done
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
openModal
,
{
vulnerability
},
state
,
[
{
type
:
types
.
SET_MODAL_DATA
,
payload
:
{
vulnerability
},
},
],
[],
done
,
);
});
});
describe
(
'
downloadPatch
'
,
()
=>
{
it
(
'
creates a download link and clicks on it to download the file
'
,
()
=>
{
jest
.
spyOn
(
document
,
'
createElement
'
);
jest
.
spyOn
(
document
.
body
,
'
appendChild
'
);
jest
.
spyOn
(
document
.
body
,
'
removeChild
'
);
actions
.
downloadPatch
({
state
:
{
modal
:
{
vulnerability
:
{
remediations
:
[
{
diff
:
'
abcdef
'
,
},
],
},
},
},
});
expect
(
document
.
createElement
).
toHaveBeenCalledTimes
(
1
);
expect
(
document
.
body
.
appendChild
).
toHaveBeenCalledTimes
(
1
);
expect
(
document
.
body
.
removeChild
).
toHaveBeenCalledTimes
(
1
);
});
});
describe
(
'
issue creation
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
createIssue
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
const
data
=
{
issue_url
:
'
fakepath.html
'
};
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_issue_path
)
.
replyOnce
(
200
,
{
data
});
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
createIssue
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestCreateIssue
'
},
{
type
:
'
receiveCreateIssueSuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_issue_path
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
createIssue
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestCreateIssue
'
},
{
type
:
'
receiveCreateIssueError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
});
describe
(
'
receiveCreateIssueSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveCreateIssueSuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_CREATE_ISSUE_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveCreateIssueError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveCreateIssueError
,
{},
state
,
[{
type
:
types
.
RECEIVE_CREATE_ISSUE_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestCreateIssue
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestCreateIssue
,
{},
state
,
[{
type
:
types
.
REQUEST_CREATE_ISSUE
}],
[],
done
,
);
});
});
});
describe
(
'
merge request creation
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
createMergeRequest
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
const
data
=
{
merge_request_path
:
'
fakepath.html
'
};
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
vulnerability_feedback_merge_request_path
)
.
replyOnce
(
200
,
{
data
});
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
createMergeRequest
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestCreateMergeRequest
'
},
{
type
:
'
receiveCreateMergeRequestSuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
vulnerability_feedback_merge_request_path
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
createMergeRequest
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestCreateMergeRequest
'
},
{
type
:
'
receiveCreateMergeRequestError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
});
describe
(
'
receiveCreateMergeRequestSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveCreateMergeRequestSuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_CREATE_MERGE_REQUEST_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveCreateMergeRequestError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveCreateMergeRequestError
,
{},
state
,
[{
type
:
types
.
RECEIVE_CREATE_MERGE_REQUEST_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestCreateMergeRequest
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestCreateMergeRequest
,
{},
state
,
[{
type
:
types
.
REQUEST_CREATE_MERGE_REQUEST
}],
[],
done
,
);
});
});
});
describe
(
'
vulnerability dismissal
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
dismissVulnerability
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
const
data
=
{
vulnerability
};
const
comment
=
'
How many times have I told you we need locking mechanisms on the vehicle doors!
'
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
],
done
,
);
});
it
(
'
should show the dismissal toast message
'
,
done
=>
{
const
checkToastMessage
=
()
=>
{
expect
(
toast
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
],
checkToastMessage
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_dismissal_path
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
receiveDismissVulnerabilityError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
describe
(
'
with dismissed vulnerabilities hidden
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{
...
initialState
(),
filters
:
{
hideDismissed
:
true
,
},
};
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should show the dismissal toast message and refresh vulnerabilities
'
,
done
=>
{
const
checkToastMessage
=
()
=>
{
const
[
message
,
options
]
=
toast
.
mock
.
calls
[
0
];
expect
(
toast
).
toHaveBeenCalledTimes
(
1
);
expect
(
message
).
toContain
(
'
Turn off the hide dismissed toggle to view
'
);
expect
(
Object
.
keys
(
options
.
action
).
length
).
toBe
(
2
);
done
();
};
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
state
,
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
{
type
:
'
fetchVulnerabilities
'
,
payload
:
{
page
:
1
}
},
],
checkToastMessage
,
);
});
it
(
'
should load the previous page if there is no more vulnerabiliy on the current one and page > 1
'
,
()
=>
{
state
.
vulnerabilities
=
[
mockDataVulnerabilities
[
0
]];
state
.
pageInfo
.
page
=
3
;
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
state
,
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
{
type
:
'
fetchVulnerabilities
'
,
payload
:
{
page
:
2
}
},
],
);
});
});
});
describe
(
'
receiveDismissVulnerabilitySuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveDismissVulnerabilitySuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_DISMISS_VULNERABILITY_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveDismissVulnerabilityError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveDismissVulnerabilityError
,
{},
state
,
[{
type
:
types
.
RECEIVE_DISMISS_VULNERABILITY_ERROR
}],
[],
done
,
);
});
});
describe
(
'
EE Vulnerabilities actions
'
,
()
=>
{
const
mockEndpoint
=
'
mock-list-endpoint
'
;
const
mockResponse
=
[{
key_foo
:
'
valueFoo
'
}];
describe
(
'
requestDismissVulnerability
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestDismissVulnerability
,
{},
state
,
[{
type
:
types
.
REQUEST_DISMISS_VULNERABILITY
}],
[],
done
,
);
});
});
});
let
mockAxios
;
describe
(
'
add vulnerability dismissal comment
'
,
()
=>
{
let
state
;
let
vulnerability
;
beforeEach
(()
=>
{
mockAxios
=
new
MockAdapter
(
axios
);
state
=
createState
();
vulnerability
=
{
create_vulnerability_feedback_issue_path
:
mockEndpoint
,
report_type
:
'
issue
'
,
project_fingerprint
:
'
some-fingerprint
'
,
};
state
=
initialState
();
});
afterEach
(()
=>
{
mockAxios
.
restore
();
describe
(
'
addDismissalComment
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
2
];
const
data
=
{
vulnerability
};
const
url
=
`
${
vulnerability
.
create_vulnerability_feedback_dismissal_path
}
/
${
vulnerability
.
dismissal_feedback
.
id
}
`
;
const
comment
=
'
Well, we’re back in the car again.
'
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
,
id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
expect
(
toast
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
addDismissalComment
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveAddDismissalCommentSuccess
'
,
payload
:
{
data
,
vulnerability
}
},
],
checkPassedData
,
);
});
it
(
'
should show the add dismissal toast message
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
,
id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
expect
(
toast
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
addDismissalComment
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveAddDismissalCommentSuccess
'
,
payload
:
{
data
,
vulnerability
}
},
],
checkPassedData
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
404
);
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
addDismissalComment
,
{
vulnerability
,
comment
},
{},
[],
[{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
receiveAddDismissalCommentError
'
}],
done
,
);
});
});
describe
(
'
receiveAddDismissalCommentSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveAddDismissalCommentSuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS
,
payload
:
{
data
}
}],
[],
done
,
);
});
});
describe
(
'
receiveAddDismissalCommentError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveAddDismissalCommentError
,
{},
state
,
[{
type
:
types
.
RECEIVE_ADD_DISMISSAL_COMMENT_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestAddDismissalComment
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestAddDismissalComment
,
{},
state
,
[{
type
:
types
.
REQUEST_ADD_DISMISSAL_COMMENT
}],
[],
done
,
);
});
});
});
describe
(
'
createIssue
'
,
()
=>
{
it
(
'
calls the createIssue endpoint and receives a success response
'
,
done
=>
{
mockAxios
.
onPost
(
mockEndpoint
).
replyOnce
(
200
,
mockResponse
);
const
spy
=
jest
.
spyOn
(
axios
,
'
post
'
);
describe
(
'
deleteDismissalComment
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
2
];
const
data
=
{
vulnerability
};
const
url
=
`
${
vulnerability
.
create_vulnerability_feedback_dismissal_path
}
/
${
vulnerability
.
dismissal_feedback
.
id
}
`
;
const
comment
=
''
;
let
mock
;
return
testAction
(
actions
.
createIssue
,
{
vulnerability
,
},
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
done
();
};
testAction
(
actions
.
deleteDismissalComment
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDeleteDismissalCommentSuccess
'
,
payload
:
{
data
,
id
:
vulnerability
.
id
},
},
],
checkPassedData
,
);
});
it
(
'
should show the delete dismissal comment toast message
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
expect
(
toast
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
deleteDismissalComment
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDeleteDismissalCommentSuccess
'
,
payload
:
{
data
,
id
:
vulnerability
.
id
},
},
],
checkPassedData
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
404
);
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
deleteDismissalComment
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
receiveDeleteDismissalCommentError
'
},
],
done
,
);
});
});
describe
(
'
receiveDeleteDismissalCommentSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveDeleteDismissalCommentSuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_DELETE_DISMISSAL_COMMENT_SUCCESS
,
payload
:
{
data
}
}],
[],
done
,
);
});
});
describe
(
'
receiveDeleteDismissalCommentError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveDeleteDismissalCommentError
,
{},
state
,
[{
type
:
types
.
RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestDeleteDismissalComment
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestDeleteDismissalComment
,
{},
state
,
[{
type
:
types
.
REQUEST_DELETE_DISMISSAL_COMMENT
}],
[],
done
,
);
});
});
});
});
describe
(
'
dismiss multiple vulnerabilities
'
,
()
=>
{
let
state
;
let
selectedVulnerabilities
;
beforeEach
(()
=>
{
state
=
initialState
();
state
.
vulnerabilities
=
mockDataVulnerabilities
;
selectedVulnerabilities
=
{
[
state
.
vulnerabilities
[
0
].
id
]:
true
,
[
state
.
vulnerabilities
[
1
].
id
]:
true
,
};
state
.
selectedVulnerabilities
=
selectedVulnerabilities
;
});
describe
(
'
dismissSelectedVulnerabilities
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
'
should fire the dismissSelected mutations when all is well
'
,
done
=>
{
mock
.
onPost
(
state
.
vulnerabilities
[
0
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
)
.
onPost
(
state
.
vulnerabilities
[
1
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
);
testAction
(
actions
.
dismissSelectedVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestCreateIssue
'
},
{
type
:
'
receiveCreateIssueSuccess
'
,
payload
:
mockResponse
},
{
type
:
'
requestDismissSelectedVulnerabilities
'
},
{
type
:
'
receiveDismissSelectedVulnerabilitiesSuccess
'
,
},
],
()
=>
{
expect
(
spy
).
toHaveBeenCalledWith
(
mockEndpoint
,
{
vulnerability_feedback
:
{
category
:
'
issue
'
,
feedback_type
:
'
issue
'
,
project_fingerprint
:
'
some-fingerprint
'
,
vulnerability_data
:
{
category
:
'
issue
'
,
create_vulnerability_feedback_issue_path
:
mockEndpoint
,
project_fingerprint
:
'
some-fingerprint
'
,
report_type
:
'
issue
'
,
},
},
});
expect
(
mock
.
history
.
post
).
toHaveLength
(
2
);
expect
(
mock
.
history
.
post
[
0
].
url
).
toEqual
(
state
.
vulnerabilities
[
0
].
create_vulnerability_feedback_dismissal_path
,
);
done
();
},
);
});
it
(
'
handles an API error by dispatching "receiveCreateIssueError"
'
,
done
=>
{
mockAxios
.
onPost
(
mockEndpoint
).
replyOnce
(
500
);
it
(
'
should trigger the error state when something goes wrong
'
,
done
=>
{
mock
.
onPost
(
state
.
vulnerabilities
[
0
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
)
.
onPost
(
state
.
vulnerabilities
[
1
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
500
);
testAction
(
actions
.
dismissSelectedVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestDismissSelectedVulnerabilities
'
},
{
type
:
'
receiveDismissSelectedVulnerabilitiesError
'
,
payload
:
{
flashError
:
true
}
},
],
done
,
);
});
describe
(
'
receiveDismissSelectedVulnerabilitiesSuccess
'
,
()
=>
{
it
(
`should commit
${
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_SUCCESS
}
`
,
done
=>
{
testAction
(
actions
.
receiveDismissSelectedVulnerabilitiesSuccess
,
{
selectedVulnerabilities
},
state
,
[{
type
:
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_SUCCESS
}],
[],
done
,
);
});
});
describe
(
'
receiveDismissSelectedVulnerabilitiesError
'
,
()
=>
{
it
(
`should commit
${
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR
}
`
,
done
=>
{
testAction
(
actions
.
receiveDismissSelectedVulnerabilitiesError
,
{},
state
,
[{
type
:
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR
}],
[],
done
,
);
});
});
});
});
describe
(
'
selecting vulnerabilities
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
selectVulnerability
'
,
()
=>
{
it
(
`selectVulnerability should commit
${
types
.
SELECT_VULNERABILITY
}
`
,
done
=>
{
const
id
=
1234
;
testAction
(
actions
.
selectVulnerability
,
{
id
},
state
,
[{
type
:
types
.
SELECT_VULNERABILITY
,
payload
:
id
}],
[],
done
,
);
});
});
describe
(
'
deselectVulnerability
'
,
()
=>
{
it
(
`should commit
${
types
.
DESELECT_VULNERABILITY
}
`
,
done
=>
{
const
id
=
1234
;
testAction
(
actions
.
deselectVulnerability
,
{
id
},
state
,
[{
type
:
types
.
DESELECT_VULNERABILITY
,
payload
:
id
}],
[],
done
,
);
});
});
describe
(
'
selectAllVulnerabilities
'
,
()
=>
{
it
(
`should commit
${
types
.
SELECT_ALL_VULNERABILITIES
}
`
,
done
=>
{
testAction
(
actions
.
selectAllVulnerabilities
,
{},
state
,
[{
type
:
types
.
SELECT_ALL_VULNERABILITIES
}],
[],
done
,
);
});
});
describe
(
'
deselectAllVulnerabilities
'
,
()
=>
{
it
(
`should commit
${
types
.
DESELECT_ALL_VULNERABILITIES
}
`
,
done
=>
{
testAction
(
actions
.
deselectAllVulnerabilities
,
{},
state
,
[{
type
:
types
.
DESELECT_ALL_VULNERABILITIES
}],
[],
done
,
);
});
});
});
describe
(
'
showDismissalDeleteButtons
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
it
(
'
commits show dismissal delete buttons
'
,
done
=>
{
testAction
(
actions
.
showDismissalDeleteButtons
,
null
,
state
,
[
{
type
:
types
.
SHOW_DISMISSAL_DELETE_BUTTONS
,
},
],
[],
done
,
);
});
});
describe
(
'
hideDismissalDeleteButtons
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
return
testAction
(
actions
.
createIssue
,
it
(
'
commits hide dismissal delete buttons
'
,
done
=>
{
testAction
(
actions
.
hideDismissalDeleteButtons
,
null
,
state
,
[
{
vulnerability
,
type
:
types
.
HIDE_DISMISSAL_DELETE_BUTTONS
,
},
],
[],
done
,
);
});
});
describe
(
'
revert vulnerability dismissal
'
,
()
=>
{
describe
(
'
undoDismiss
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
2
];
const
url
=
vulnerability
.
dismissal_feedback
.
destroy_vulnerability_feedback_dismissal_path
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onDelete
(
url
).
replyOnce
(
200
,
{});
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
undoDismiss
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestUndoDismiss
'
},
{
type
:
'
receiveUndoDismissSuccess
'
,
payload
:
{
vulnerability
}
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onDelete
(
url
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
undoDismiss
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestUndoDismiss
'
},
{
type
:
'
receiveUndoDismissError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
});
describe
(
'
receiveUndoDismissSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
state
=
initialState
;
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveUndoDismissSuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_REVERT_DISMISSAL_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveUndoDismissError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
const
state
=
initialState
;
testAction
(
actions
.
receiveUndoDismissError
,
{},
state
,
[{
type
:
types
.
RECEIVE_REVERT_DISMISSAL_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestUndoDismiss
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
const
state
=
initialState
;
testAction
(
actions
.
requestUndoDismiss
,
{},
state
,
[{
type
:
types
.
REQUEST_REVERT_DISMISSAL
}],
[],
done
,
);
});
});
});
describe
(
'
vulnerabilities history actions
'
,
()
=>
{
const
data
=
mockDataVulnerabilitiesHistory
;
const
params
=
{
filters
:
{
severity
:
[
'
critical
'
]
}
};
const
filteredData
=
mockDataVulnerabilitiesHistory
.
critical
;
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
setVulnerabilitiesHistoryEndpoint
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
endpoint
=
'
fakepath.json
'
;
testAction
(
actions
.
setVulnerabilitiesHistoryEndpoint
,
endpoint
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_HISTORY_ENDPOINT
,
payload
:
endpoint
,
},
],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesHistoryDayRange
'
,
()
=>
{
it
(
'
should commit the number of past days to show
'
,
done
=>
{
const
days
=
DAYS
.
THIRTY
;
testAction
(
actions
.
setVulnerabilitiesHistoryDayRange
,
days
,
state
,
[
{
type
:
'
requestCreateIssue
'
},
{
type
:
'
receiveCreateIssueError
'
,
payload
:
{
flashError
:
undefined
}
},
{
type
:
types
.
SET_VULNERABILITIES_HISTORY_DAY_RANGE
,
payload
:
days
,
},
],
[],
done
,
);
});
});
describe
(
'
fetchVulnerabilitiesHistory
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
state
.
vulnerabilitiesHistoryEndpoint
=
`
${
TEST_HOST
}
/vulnerabilitIES_HISTORY.json`
;
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesHistoryEndpoint
,
{
params
})
.
replyOnce
(
200
,
filteredData
)
.
onGet
(
state
.
vulnerabilitiesHistoryEndpoint
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilitiesHistory
'
},
{
type
:
'
receiveVulnerabilitiesHistorySuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
it
(
'
return the filtered results
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
params
,
state
,
[],
[
{
type
:
'
requestVulnerabilitiesHistory
'
},
{
type
:
'
receiveVulnerabilitiesHistorySuccess
'
,
payload
:
{
data
:
filteredData
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesHistoryEndpoint
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilitiesHistory
'
},
{
type
:
'
receiveVulnerabilitiesHistoryError
'
},
],
done
,
);
});
});
describe
(
'
with an empty endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
vulnerabilitiesHistoryEndpoint
=
''
;
});
it
(
'
should not do anything
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
{},
state
,
[],
[],
done
);
});
});
});
describe
(
'
requestVulnerabilitiesHistory
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestVulnerabilitiesHistory
,
{},
state
,
[{
type
:
types
.
REQUEST_VULNERABILITIES_HISTORY
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesHistorySuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesHistorySuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_HISTORY_SUCCESS
,
payload
:
data
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesHistoryError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesHistoryError
,
{},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_HISTORY_ERROR
}],
[],
done
,
);
});
});
describe
(
'
openDismissalCommentBox
'
,
()
=>
{
it
(
'
should commit the open comment mutation with a default payload
'
,
done
=>
{
testAction
(
actions
.
openDismissalCommentBox
,
undefined
,
state
,
[{
type
:
types
.
OPEN_DISMISSAL_COMMENT_BOX
}],
[],
done
,
);
});
});
describe
(
'
closeDismissalCommentBox
'
,
()
=>
{
it
(
'
should commit the close comment mutation
'
,
done
=>
{
testAction
(
actions
.
closeDismissalCommentBox
,
{},
state
,
[{
type
:
types
.
CLOSE_DISMISSAL_COMMENT_BOX
}],
[],
done
,
);
});
...
...
ee/spec/
javascripts/security_dashboard/store
/vulnerabilities/getters_spec.js
→
ee/spec/
frontend/security_dashboard/store/modules
/vulnerabilities/getters_spec.js
View file @
d90a33f4
import
createState
from
'
ee/security_dashboard/store/modules/vulnerabilities/state
'
;
import
{
DAYS
}
from
'
ee/security_dashboard/store/modules/vulnerabilities/constants
'
;
import
*
as
getters
from
'
ee/security_dashboard/store/modules/vulnerabilities/getters
'
;
import
mockHistoryData
from
'
.
./vulnerabilities
/data/mock_data_vulnerabilities_history.json
'
;
import
mockHistoryData
from
'
./data/mock_data_vulnerabilities_history.json
'
;
describe
(
'
vulnerabilities module getters
'
,
()
=>
{
describe
(
'
dashboardError
'
,
()
=>
{
...
...
@@ -65,16 +65,26 @@ describe('vulnerabilities module getters', () => {
getters
.
getVulnerabilityHistoryByName
(
state
)(
name
);
return
{
getVulnerabilityHistoryByName
};
};
const
realDate
=
Date
;
beforeEach
(()
=>
{
state
=
createState
();
state
.
vulnerabilitiesHistory
=
mockHistoryData
;
jasmine
.
clock
().
install
();
jasmine
.
clock
().
mockDate
(
new
Date
(
2019
,
1
,
2
));
jest
.
useFakeTimers
();
const
currentDate
=
new
Date
(
2019
,
1
,
2
);
global
.
Date
=
class
extends
Date
{
constructor
(
date
)
{
if
(
date
)
{
// eslint-disable-next-line constructor-super
return
super
(
date
);
}
return
currentDate
;
}
};
});
afterEach
(
function
()
{
jasmine
.
clock
().
uninstall
()
;
afterEach
(
()
=>
{
global
.
Date
=
realDate
;
});
it
(
'
should filter the data to the last 30 days and days we have data for
'
,
()
=>
{
...
...
ee/spec/
javascripts
/security_dashboard/store/plugins/mediator_spec.js
→
ee/spec/
frontend
/security_dashboard/store/plugins/mediator_spec.js
View file @
d90a33f4
...
...
@@ -19,7 +19,7 @@ describe('mediator', () => {
beforeEach
(()
=>
{
store
=
createStore
();
spyOn
(
store
,
'
dispatch
'
);
jest
.
spyOn
(
store
,
'
dispatch
'
).
mockImplementation
(()
=>
{}
);
});
it
(
'
triggers fetching vulnerabilities after one filter changes
'
,
()
=>
{
...
...
ee/spec/javascripts/security_dashboard/store/vulnerabilities/actions_spec.js
deleted
100644 → 0
View file @
8d1fe49b
import
Vue
from
'
vue
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
testAction
from
'
spec/helpers/vuex_action_helper
'
;
import
{
TEST_HOST
}
from
'
spec/test_constants
'
;
import
{
DAYS
}
from
'
ee/security_dashboard/store/modules/vulnerabilities/constants
'
;
import
initialState
from
'
ee/security_dashboard/store/modules/vulnerabilities/state
'
;
import
*
as
types
from
'
ee/security_dashboard/store/modules/vulnerabilities/mutation_types
'
;
import
*
as
actions
from
'
ee/security_dashboard/store/modules/vulnerabilities/actions
'
;
import
axios
from
'
~/lib/utils/axios_utils
'
;
import
mockDataVulnerabilities
from
'
./data/mock_data_vulnerabilities
'
;
import
mockDataVulnerabilitiesCount
from
'
./data/mock_data_vulnerabilities_count.json
'
;
import
mockDataVulnerabilitiesHistory
from
'
./data/mock_data_vulnerabilities_history.json
'
;
const
sourceBranch
=
'
feature-branch-1
'
;
describe
(
'
vulnerabilities count actions
'
,
()
=>
{
const
data
=
mockDataVulnerabilitiesCount
;
const
params
=
{
filters
:
{
type
:
[
'
sast
'
]
}
};
const
filteredData
=
mockDataVulnerabilitiesCount
.
sast
;
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
setPipelineId
'
,
()
=>
{
const
pipelineId
=
123
;
it
(
'
should commit the correct mutation
'
,
done
=>
{
testAction
(
actions
.
setPipelineId
,
pipelineId
,
state
,
[
{
type
:
types
.
SET_PIPELINE_ID
,
payload
:
pipelineId
,
},
],
[],
done
,
);
});
});
describe
(
'
setSourceBranch
'
,
()
=>
{
it
(
'
should commit the correct mutation
'
,
done
=>
{
testAction
(
actions
.
setSourceBranch
,
sourceBranch
,
state
,
[
{
type
:
types
.
SET_SOURCE_BRANCH
,
payload
:
sourceBranch
,
},
],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesCountEndpoint
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
endpoint
=
'
fakepath.json
'
;
testAction
(
actions
.
setVulnerabilitiesCountEndpoint
,
endpoint
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_COUNT_ENDPOINT
,
payload
:
endpoint
,
},
],
[],
done
,
);
});
});
describe
(
'
fetchVulnerabilitiesCount
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
state
.
vulnerabilitiesCountEndpoint
=
`
${
TEST_HOST
}
/vulnerabilities_count.json`
;
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesCountEndpoint
,
{
params
})
.
replyOnce
(
200
,
filteredData
)
.
onGet
(
state
.
vulnerabilitiesCountEndpoint
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilitiesCount
'
},
{
type
:
'
receiveVulnerabilitiesCountSuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
it
(
'
should send the passed filters to the endpoint
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
params
,
state
,
[],
[
{
type
:
'
requestVulnerabilitiesCount
'
},
{
type
:
'
receiveVulnerabilitiesCountSuccess
'
,
payload
:
{
data
:
filteredData
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesCountEndpoint
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
{},
state
,
[],
[{
type
:
'
requestVulnerabilitiesCount
'
},
{
type
:
'
receiveVulnerabilitiesCountError
'
}],
done
,
);
});
});
describe
(
'
with an empty endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
vulnerabilitiesCountEndpoint
=
''
;
});
it
(
'
should not do anything
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesCount
,
{},
state
,
[],
[],
done
);
});
});
});
describe
(
'
requestVulnerabilitiesCount
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestVulnerabilitiesCount
,
{},
state
,
[{
type
:
types
.
REQUEST_VULNERABILITIES_COUNT
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesCountSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesCountSuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_COUNT_SUCCESS
,
payload
:
data
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesCountError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesCountError
,
{},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_COUNT_ERROR
}],
[],
done
,
);
});
});
});
describe
(
'
vulnerabilities actions
'
,
()
=>
{
const
data
=
mockDataVulnerabilities
;
const
params
=
{
filters
:
{
severity
:
[
'
critical
'
]
}
};
const
filteredData
=
mockDataVulnerabilities
.
filter
(
vuln
=>
vuln
.
severity
===
'
critical
'
);
const
pageInfo
=
{
page
:
1
,
nextPage
:
2
,
previousPage
:
1
,
perPage
:
20
,
total
:
100
,
totalPages
:
5
,
};
const
headers
=
{
'
X-Next-Page
'
:
pageInfo
.
nextPage
,
'
X-Page
'
:
pageInfo
.
page
,
'
X-Per-Page
'
:
pageInfo
.
perPage
,
'
X-Prev-Page
'
:
pageInfo
.
previousPage
,
'
X-Total
'
:
pageInfo
.
total
,
'
X-Total-Pages
'
:
pageInfo
.
totalPages
,
};
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
fetchVulnerabilities
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
state
.
vulnerabilitiesEndpoint
=
`
${
TEST_HOST
}
/vulnerabilities.json`
;
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesEndpoint
,
{
params
})
.
replyOnce
(
200
,
filteredData
,
headers
)
.
onGet
(
state
.
vulnerabilitiesEndpoint
)
.
replyOnce
(
200
,
data
,
headers
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilities
'
},
{
type
:
'
receiveVulnerabilitiesSuccess
'
,
payload
:
{
data
,
headers
},
},
],
done
,
);
});
it
(
'
should pass through the filters
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
params
,
state
,
[],
[
{
type
:
'
requestVulnerabilities
'
},
{
type
:
'
receiveVulnerabilitiesSuccess
'
,
payload
:
{
data
:
filteredData
,
headers
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
const
errorCode
=
404
;
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesEndpoint
).
replyOnce
(
errorCode
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilities
'
},
{
type
:
'
receiveVulnerabilitiesError
'
,
payload
:
errorCode
},
],
done
,
);
});
});
describe
(
'
with an empty endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
vulnerabilitiesEndpoint
=
''
;
});
it
(
'
should not do anything
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilities
,
{},
state
,
[],
[],
done
);
});
});
});
describe
(
'
receiveVulnerabilitiesSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesSuccess
,
{
headers
,
data
},
state
,
[
{
type
:
types
.
RECEIVE_VULNERABILITIES_SUCCESS
,
payload
:
{
pageInfo
,
vulnerabilities
:
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
const
errorCode
=
403
;
testAction
(
actions
.
receiveVulnerabilitiesError
,
errorCode
,
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_ERROR
,
payload
:
errorCode
}],
[],
done
,
);
});
});
describe
(
'
requestVulnerabilities
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestVulnerabilities
,
{},
state
,
[{
type
:
types
.
REQUEST_VULNERABILITIES
}],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesEndpoint
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
endpoint
=
'
fakepath.json
'
;
testAction
(
actions
.
setVulnerabilitiesEndpoint
,
endpoint
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_ENDPOINT
,
payload
:
endpoint
,
},
],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesPage
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
page
=
3
;
testAction
(
actions
.
setVulnerabilitiesPage
,
page
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_PAGE
,
payload
:
page
,
},
],
[],
done
,
);
});
});
});
describe
(
'
openModal
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
it
(
'
should commit the SET_MODAL_DATA mutation
'
,
done
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
openModal
,
{
vulnerability
},
state
,
[
{
type
:
types
.
SET_MODAL_DATA
,
payload
:
{
vulnerability
},
},
],
[],
done
,
);
});
});
describe
(
'
downloadPatch
'
,
()
=>
{
it
(
'
creates a download link and clicks on it to download the file
'
,
()
=>
{
spyOn
(
document
,
'
createElement
'
).
and
.
callThrough
();
spyOn
(
document
.
body
,
'
appendChild
'
).
and
.
callThrough
();
spyOn
(
document
.
body
,
'
removeChild
'
).
and
.
callThrough
();
actions
.
downloadPatch
({
state
:
{
modal
:
{
vulnerability
:
{
remediations
:
[
{
diff
:
'
abcdef
'
,
},
],
},
},
},
});
expect
(
document
.
createElement
).
toHaveBeenCalledTimes
(
1
);
expect
(
document
.
body
.
appendChild
).
toHaveBeenCalledTimes
(
1
);
expect
(
document
.
body
.
removeChild
).
toHaveBeenCalledTimes
(
1
);
});
});
describe
(
'
issue creation
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
createIssue
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
const
data
=
{
issue_url
:
'
fakepath.html
'
};
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_issue_path
)
.
replyOnce
(
200
,
{
data
});
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
createIssue
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestCreateIssue
'
},
{
type
:
'
receiveCreateIssueSuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_issue_path
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
createIssue
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestCreateIssue
'
},
{
type
:
'
receiveCreateIssueError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
});
describe
(
'
receiveCreateIssueSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveCreateIssueSuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_CREATE_ISSUE_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveCreateIssueError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveCreateIssueError
,
{},
state
,
[{
type
:
types
.
RECEIVE_CREATE_ISSUE_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestCreateIssue
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestCreateIssue
,
{},
state
,
[{
type
:
types
.
REQUEST_CREATE_ISSUE
}],
[],
done
,
);
});
});
});
describe
(
'
merge request creation
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
createMergeRequest
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
const
data
=
{
merge_request_path
:
'
fakepath.html
'
};
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
vulnerability_feedback_merge_request_path
)
.
replyOnce
(
200
,
{
data
});
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
createMergeRequest
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestCreateMergeRequest
'
},
{
type
:
'
receiveCreateMergeRequestSuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
vulnerability_feedback_merge_request_path
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
createMergeRequest
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestCreateMergeRequest
'
},
{
type
:
'
receiveCreateMergeRequestError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
});
describe
(
'
receiveCreateMergeRequestSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveCreateMergeRequestSuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_CREATE_MERGE_REQUEST_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveCreateMergeRequestError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveCreateMergeRequestError
,
{},
state
,
[{
type
:
types
.
RECEIVE_CREATE_MERGE_REQUEST_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestCreateMergeRequest
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestCreateMergeRequest
,
{},
state
,
[{
type
:
types
.
REQUEST_CREATE_MERGE_REQUEST
}],
[],
done
,
);
});
});
});
describe
(
'
vulnerability dismissal
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
dismissVulnerability
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
0
];
const
data
=
{
vulnerability
};
const
comment
=
'
How many times have I told you we need locking mechanisms on the vehicle doors!
'
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
],
done
,
);
});
it
(
'
should show the dismissal toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkToastMessage
=
()
=>
{
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
],
checkToastMessage
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_dismissal_path
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
receiveDismissVulnerabilityError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
describe
(
'
with dismissed vulnerabilities hidden
'
,
()
=>
{
beforeEach
(()
=>
{
state
=
{
...
initialState
(),
filters
:
{
hideDismissed
:
true
,
},
};
mock
.
onPost
(
vulnerability
.
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should show the dismissal toast message and refresh vulnerabilities
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkToastMessage
=
()
=>
{
const
[
message
,
options
]
=
Vue
.
toasted
.
show
.
calls
.
argsFor
(
0
);
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
expect
(
message
).
toContain
(
'
Turn off the hide dismissed toggle to view
'
);
expect
(
options
.
action
.
length
).
toBe
(
2
);
done
();
};
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
state
,
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
{
type
:
'
fetchVulnerabilities
'
,
payload
:
{
page
:
1
}
},
],
checkToastMessage
,
);
});
it
(
'
should load the previous page if there is no more vulnerabiliy on the current one and page > 1
'
,
()
=>
{
state
.
vulnerabilities
=
[
mockDataVulnerabilities
[
0
]];
state
.
pageInfo
.
page
=
3
;
testAction
(
actions
.
dismissVulnerability
,
{
vulnerability
,
comment
},
state
,
[],
[
{
type
:
'
requestDismissVulnerability
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDismissVulnerabilitySuccess
'
,
payload
:
{
data
,
vulnerability
},
},
{
type
:
'
fetchVulnerabilities
'
,
payload
:
{
page
:
2
}
},
],
);
});
});
});
describe
(
'
receiveDismissVulnerabilitySuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveDismissVulnerabilitySuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_DISMISS_VULNERABILITY_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveDismissVulnerabilityError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveDismissVulnerabilityError
,
{},
state
,
[{
type
:
types
.
RECEIVE_DISMISS_VULNERABILITY_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestDismissVulnerability
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestDismissVulnerability
,
{},
state
,
[{
type
:
types
.
REQUEST_DISMISS_VULNERABILITY
}],
[],
done
,
);
});
});
});
describe
(
'
add vulnerability dismissal comment
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
addDismissalComment
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
2
];
const
data
=
{
vulnerability
};
const
url
=
`
${
vulnerability
.
create_vulnerability_feedback_dismissal_path
}
/
${
vulnerability
.
dismissal_feedback
.
id
}
`
;
const
comment
=
'
Well, we’re back in the car again.
'
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
,
id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
done
();
};
testAction
(
actions
.
addDismissalComment
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveAddDismissalCommentSuccess
'
,
payload
:
{
data
,
vulnerability
}
},
],
checkPassedData
,
);
});
it
(
'
should show the add dismissal toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkPassedData
=
()
=>
{
const
{
project_id
,
id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
addDismissalComment
,
{
vulnerability
,
comment
},
{},
[],
[
{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveAddDismissalCommentSuccess
'
,
payload
:
{
data
,
vulnerability
}
},
],
checkPassedData
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
404
);
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
addDismissalComment
,
{
vulnerability
,
comment
},
{},
[],
[{
type
:
'
requestAddDismissalComment
'
},
{
type
:
'
receiveAddDismissalCommentError
'
}],
done
,
);
});
});
describe
(
'
receiveAddDismissalCommentSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveAddDismissalCommentSuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_ADD_DISMISSAL_COMMENT_SUCCESS
,
payload
:
{
data
}
}],
[],
done
,
);
});
});
describe
(
'
receiveAddDismissalCommentError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveAddDismissalCommentError
,
{},
state
,
[{
type
:
types
.
RECEIVE_ADD_DISMISSAL_COMMENT_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestAddDismissalComment
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestAddDismissalComment
,
{},
state
,
[{
type
:
types
.
REQUEST_ADD_DISMISSAL_COMMENT
}],
[],
done
,
);
});
});
});
describe
(
'
deleteDismissalComment
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
2
];
const
data
=
{
vulnerability
};
const
url
=
`
${
vulnerability
.
create_vulnerability_feedback_dismissal_path
}
/
${
vulnerability
.
dismissal_feedback
.
id
}
`
;
const
comment
=
''
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
const
checkPassedData
=
()
=>
{
const
{
project_id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
done
();
};
testAction
(
actions
.
deleteDismissalComment
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDeleteDismissalCommentSuccess
'
,
payload
:
{
data
,
id
:
vulnerability
.
id
},
},
],
checkPassedData
,
);
});
it
(
'
should show the delete dismissal comment toast message
'
,
done
=>
{
spyOn
(
Vue
.
toasted
,
'
show
'
).
and
.
callThrough
();
const
checkPassedData
=
()
=>
{
const
{
project_id
}
=
vulnerability
.
dismissal_feedback
;
const
expected
=
JSON
.
stringify
({
project_id
,
comment
});
expect
(
mock
.
history
.
patch
[
0
].
data
).
toBe
(
expected
);
expect
(
Vue
.
toasted
.
show
).
toHaveBeenCalledTimes
(
1
);
done
();
};
testAction
(
actions
.
deleteDismissalComment
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
closeDismissalCommentBox
'
},
{
type
:
'
receiveDeleteDismissalCommentSuccess
'
,
payload
:
{
data
,
id
:
vulnerability
.
id
},
},
],
checkPassedData
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onPatch
(
url
).
replyOnce
(
404
);
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
deleteDismissalComment
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestDeleteDismissalComment
'
},
{
type
:
'
receiveDeleteDismissalCommentError
'
},
],
done
,
);
});
});
describe
(
'
receiveDeleteDismissalCommentSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveDeleteDismissalCommentSuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_DELETE_DISMISSAL_COMMENT_SUCCESS
,
payload
:
{
data
}
}],
[],
done
,
);
});
});
describe
(
'
receiveDeleteDismissalCommentError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveDeleteDismissalCommentError
,
{},
state
,
[{
type
:
types
.
RECEIVE_DELETE_DISMISSAL_COMMENT_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestDeleteDismissalComment
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestDeleteDismissalComment
,
{},
state
,
[{
type
:
types
.
REQUEST_DELETE_DISMISSAL_COMMENT
}],
[],
done
,
);
});
});
});
});
describe
(
'
dismiss multiple vulnerabilities
'
,
()
=>
{
let
state
;
let
selectedVulnerabilities
;
beforeEach
(()
=>
{
state
=
initialState
();
state
.
vulnerabilities
=
mockDataVulnerabilities
;
selectedVulnerabilities
=
{
[
state
.
vulnerabilities
[
0
].
id
]:
true
,
[
state
.
vulnerabilities
[
1
].
id
]:
true
,
};
state
.
selectedVulnerabilities
=
selectedVulnerabilities
;
});
describe
(
'
dismissSelectedVulnerabilities
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
it
(
'
should fire the dismissSelected mutations when all is well
'
,
done
=>
{
mock
.
onPost
(
state
.
vulnerabilities
[
0
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
)
.
onPost
(
state
.
vulnerabilities
[
1
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
);
testAction
(
actions
.
dismissSelectedVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestDismissSelectedVulnerabilities
'
},
{
type
:
'
receiveDismissSelectedVulnerabilitiesSuccess
'
,
},
],
()
=>
{
expect
(
mock
.
history
.
post
).
toHaveLength
(
2
);
expect
(
mock
.
history
.
post
[
0
].
url
).
toEqual
(
state
.
vulnerabilities
[
0
].
create_vulnerability_feedback_dismissal_path
,
);
done
();
},
);
});
it
(
'
should trigger the error state when something goes wrong
'
,
done
=>
{
mock
.
onPost
(
state
.
vulnerabilities
[
0
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
200
)
.
onPost
(
state
.
vulnerabilities
[
1
].
create_vulnerability_feedback_dismissal_path
)
.
replyOnce
(
500
);
testAction
(
actions
.
dismissSelectedVulnerabilities
,
{},
state
,
[],
[
{
type
:
'
requestDismissSelectedVulnerabilities
'
},
{
type
:
'
receiveDismissSelectedVulnerabilitiesError
'
,
payload
:
{
flashError
:
true
}
},
],
done
,
);
});
describe
(
'
receiveDismissSelectedVulnerabilitiesSuccess
'
,
()
=>
{
it
(
`should commit
${
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_SUCCESS
}
`
,
done
=>
{
testAction
(
actions
.
receiveDismissSelectedVulnerabilitiesSuccess
,
{
selectedVulnerabilities
},
state
,
[{
type
:
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_SUCCESS
}],
[],
done
,
);
});
});
describe
(
'
receiveDismissSelectedVulnerabilitiesError
'
,
()
=>
{
it
(
`should commit
${
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR
}
`
,
done
=>
{
testAction
(
actions
.
receiveDismissSelectedVulnerabilitiesError
,
{},
state
,
[{
type
:
types
.
RECEIVE_DISMISS_SELECTED_VULNERABILITIES_ERROR
}],
[],
done
,
);
});
});
});
});
describe
(
'
selecting vulnerabilities
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
selectVulnerability
'
,
()
=>
{
it
(
`selectVulnerability should commit
${
types
.
SELECT_VULNERABILITY
}
`
,
done
=>
{
const
id
=
1234
;
testAction
(
actions
.
selectVulnerability
,
{
id
},
state
,
[{
type
:
types
.
SELECT_VULNERABILITY
,
payload
:
id
}],
[],
done
,
);
});
});
describe
(
'
deselectVulnerability
'
,
()
=>
{
it
(
`should commit
${
types
.
DESELECT_VULNERABILITY
}
`
,
done
=>
{
const
id
=
1234
;
testAction
(
actions
.
deselectVulnerability
,
{
id
},
state
,
[{
type
:
types
.
DESELECT_VULNERABILITY
,
payload
:
id
}],
[],
done
,
);
});
});
describe
(
'
selectAllVulnerabilities
'
,
()
=>
{
it
(
`should commit
${
types
.
SELECT_ALL_VULNERABILITIES
}
`
,
done
=>
{
testAction
(
actions
.
selectAllVulnerabilities
,
{},
state
,
[{
type
:
types
.
SELECT_ALL_VULNERABILITIES
}],
[],
done
,
);
});
});
describe
(
'
deselectAllVulnerabilities
'
,
()
=>
{
it
(
`should commit
${
types
.
DESELECT_ALL_VULNERABILITIES
}
`
,
done
=>
{
testAction
(
actions
.
deselectAllVulnerabilities
,
{},
state
,
[{
type
:
types
.
DESELECT_ALL_VULNERABILITIES
}],
[],
done
,
);
});
});
});
describe
(
'
showDismissalDeleteButtons
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
it
(
'
commits show dismissal delete buttons
'
,
done
=>
{
testAction
(
actions
.
showDismissalDeleteButtons
,
null
,
state
,
[
{
type
:
types
.
SHOW_DISMISSAL_DELETE_BUTTONS
,
},
],
[],
done
,
);
});
});
describe
(
'
hideDismissalDeleteButtons
'
,
()
=>
{
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
it
(
'
commits hide dismissal delete buttons
'
,
done
=>
{
testAction
(
actions
.
hideDismissalDeleteButtons
,
null
,
state
,
[
{
type
:
types
.
HIDE_DISMISSAL_DELETE_BUTTONS
,
},
],
[],
done
,
);
});
});
describe
(
'
revert vulnerability dismissal
'
,
()
=>
{
describe
(
'
undoDismiss
'
,
()
=>
{
const
vulnerability
=
mockDataVulnerabilities
[
2
];
const
url
=
vulnerability
.
dismissal_feedback
.
destroy_vulnerability_feedback_dismissal_path
;
let
mock
;
beforeEach
(()
=>
{
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onDelete
(
url
).
replyOnce
(
200
,
{});
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
undoDismiss
,
{
vulnerability
},
{},
[],
[
{
type
:
'
requestUndoDismiss
'
},
{
type
:
'
receiveUndoDismissSuccess
'
,
payload
:
{
vulnerability
}
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onDelete
(
url
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
const
flashError
=
false
;
testAction
(
actions
.
undoDismiss
,
{
vulnerability
,
flashError
},
{},
[],
[
{
type
:
'
requestUndoDismiss
'
},
{
type
:
'
receiveUndoDismissError
'
,
payload
:
{
flashError
}
},
],
done
,
);
});
});
});
describe
(
'
receiveUndoDismissSuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
const
state
=
initialState
;
const
data
=
mockDataVulnerabilities
[
0
];
testAction
(
actions
.
receiveUndoDismissSuccess
,
{
data
},
state
,
[
{
type
:
types
.
RECEIVE_REVERT_DISMISSAL_SUCCESS
,
payload
:
{
data
},
},
],
[],
done
,
);
});
});
describe
(
'
receiveUndoDismissError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
const
state
=
initialState
;
testAction
(
actions
.
receiveUndoDismissError
,
{},
state
,
[{
type
:
types
.
RECEIVE_REVERT_DISMISSAL_ERROR
}],
[],
done
,
);
});
});
describe
(
'
requestUndoDismiss
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
const
state
=
initialState
;
testAction
(
actions
.
requestUndoDismiss
,
{},
state
,
[{
type
:
types
.
REQUEST_REVERT_DISMISSAL
}],
[],
done
,
);
});
});
});
describe
(
'
vulnerabilities history actions
'
,
()
=>
{
const
data
=
mockDataVulnerabilitiesHistory
;
const
params
=
{
filters
:
{
severity
:
[
'
critical
'
]
}
};
const
filteredData
=
mockDataVulnerabilitiesHistory
.
critical
;
let
state
;
beforeEach
(()
=>
{
state
=
initialState
();
});
describe
(
'
setVulnerabilitiesHistoryEndpoint
'
,
()
=>
{
it
(
'
should commit the correct mutuation
'
,
done
=>
{
const
endpoint
=
'
fakepath.json
'
;
testAction
(
actions
.
setVulnerabilitiesHistoryEndpoint
,
endpoint
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_HISTORY_ENDPOINT
,
payload
:
endpoint
,
},
],
[],
done
,
);
});
});
describe
(
'
setVulnerabilitiesHistoryDayRange
'
,
()
=>
{
it
(
'
should commit the number of past days to show
'
,
done
=>
{
const
days
=
DAYS
.
THIRTY
;
testAction
(
actions
.
setVulnerabilitiesHistoryDayRange
,
days
,
state
,
[
{
type
:
types
.
SET_VULNERABILITIES_HISTORY_DAY_RANGE
,
payload
:
days
,
},
],
[],
done
,
);
});
});
describe
(
'
fetchVulnerabilitiesHistory
'
,
()
=>
{
let
mock
;
beforeEach
(()
=>
{
state
.
vulnerabilitiesHistoryEndpoint
=
`
${
TEST_HOST
}
/vulnerabilitIES_HISTORY.json`
;
mock
=
new
MockAdapter
(
axios
);
});
afterEach
(()
=>
{
mock
.
restore
();
});
describe
(
'
on success
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesHistoryEndpoint
,
{
params
})
.
replyOnce
(
200
,
filteredData
)
.
onGet
(
state
.
vulnerabilitiesHistoryEndpoint
)
.
replyOnce
(
200
,
data
);
});
it
(
'
should dispatch the request and success actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilitiesHistory
'
},
{
type
:
'
receiveVulnerabilitiesHistorySuccess
'
,
payload
:
{
data
},
},
],
done
,
);
});
it
(
'
return the filtered results
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
params
,
state
,
[],
[
{
type
:
'
requestVulnerabilitiesHistory
'
},
{
type
:
'
receiveVulnerabilitiesHistorySuccess
'
,
payload
:
{
data
:
filteredData
},
},
],
done
,
);
});
});
describe
(
'
on error
'
,
()
=>
{
beforeEach
(()
=>
{
mock
.
onGet
(
state
.
vulnerabilitiesHistoryEndpoint
).
replyOnce
(
404
,
{});
});
it
(
'
should dispatch the request and error actions
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
{},
state
,
[],
[
{
type
:
'
requestVulnerabilitiesHistory
'
},
{
type
:
'
receiveVulnerabilitiesHistoryError
'
},
],
done
,
);
});
});
describe
(
'
with an empty endpoint
'
,
()
=>
{
beforeEach
(()
=>
{
state
.
vulnerabilitiesHistoryEndpoint
=
''
;
});
it
(
'
should not do anything
'
,
done
=>
{
testAction
(
actions
.
fetchVulnerabilitiesHistory
,
{},
state
,
[],
[],
done
);
});
});
});
describe
(
'
requestVulnerabilitiesHistory
'
,
()
=>
{
it
(
'
should commit the request mutation
'
,
done
=>
{
testAction
(
actions
.
requestVulnerabilitiesHistory
,
{},
state
,
[{
type
:
types
.
REQUEST_VULNERABILITIES_HISTORY
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesHistorySuccess
'
,
()
=>
{
it
(
'
should commit the success mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesHistorySuccess
,
{
data
},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_HISTORY_SUCCESS
,
payload
:
data
}],
[],
done
,
);
});
});
describe
(
'
receiveVulnerabilitiesHistoryError
'
,
()
=>
{
it
(
'
should commit the error mutation
'
,
done
=>
{
testAction
(
actions
.
receiveVulnerabilitiesHistoryError
,
{},
state
,
[{
type
:
types
.
RECEIVE_VULNERABILITIES_HISTORY_ERROR
}],
[],
done
,
);
});
});
describe
(
'
openDismissalCommentBox
'
,
()
=>
{
it
(
'
should commit the open comment mutation with a default payload
'
,
done
=>
{
testAction
(
actions
.
openDismissalCommentBox
,
undefined
,
state
,
[{
type
:
types
.
OPEN_DISMISSAL_COMMENT_BOX
}],
[],
done
,
);
});
});
describe
(
'
closeDismissalCommentBox
'
,
()
=>
{
it
(
'
should commit the close comment mutation
'
,
done
=>
{
testAction
(
actions
.
closeDismissalCommentBox
,
{},
state
,
[{
type
:
types
.
CLOSE_DISMISSAL_COMMENT_BOX
}],
[],
done
,
);
});
});
});
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities.js
deleted
100644 → 0
View file @
8d1fe49b
export
{
default
,
}
from
'
../../../../../frontend/security_dashboard/store/modules/vulnerabilities/data/mock_data_vulnerabilities
'
;
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities_count.json
deleted
100644 → 0
View file @
8d1fe49b
{
"critical"
:
2
,
"high"
:
4
,
"low"
:
7
,
"medium"
:
8
,
"unknown"
:
0
}
\ No newline at end of file
ee/spec/javascripts/security_dashboard/store/vulnerabilities/data/mock_data_vulnerabilities_history.json
deleted
100644 → 0
View file @
8d1fe49b
{
"low"
:
{
"2018-10-1"
:
87
,
"2018-10-2"
:
88
,
"2018-10-3"
:
90
,
"2018-10-4"
:
89
,
"2018-10-5"
:
89
,
"2018-10-6"
:
80
,
"2018-10-7"
:
85
,
"2018-10-8"
:
67
,
"2018-10-9"
:
84
,
"2018-10-10"
:
72
,
"2018-10-11"
:
67
,
"2018-10-12"
:
86
,
"2018-10-13"
:
70
,
"2018-10-14"
:
68
,
"2018-10-15"
:
61
,
"2018-10-16"
:
74
,
"2018-10-17"
:
67
,
"2018-10-18"
:
78
,
"2018-10-19"
:
65
,
"2018-10-20"
:
72
,
"2018-10-21"
:
78
,
"2018-10-22"
:
81
,
"2018-10-23"
:
62
,
"2018-10-24"
:
86
,
"2018-10-25"
:
79
,
"2018-10-26"
:
86
,
"2018-10-27"
:
78
,
"2018-10-28"
:
75
,
"2018-10-29"
:
67
,
"2018-10-30"
:
87
,
"2018-10-31"
:
86
,
"2018-11-1"
:
75
,
"2018-11-2"
:
81
,
"2018-11-3"
:
88
,
"2018-11-4"
:
82
,
"2018-11-5"
:
76
,
"2018-11-6"
:
76
,
"2018-11-7"
:
68
,
"2018-11-8"
:
86
,
"2018-11-9"
:
70
,
"2018-11-10"
:
74
,
"2018-11-11"
:
60
,
"2018-11-12"
:
61
,
"2018-11-13"
:
73
,
"2018-11-14"
:
90
,
"2018-11-15"
:
69
,
"2018-11-16"
:
78
,
"2018-11-17"
:
81
,
"2018-11-18"
:
60
,
"2018-11-19"
:
86
,
"2018-11-20"
:
72
,
"2018-11-21"
:
73
,
"2018-11-22"
:
60
,
"2018-11-23"
:
88
,
"2018-11-24"
:
70
,
"2018-11-25"
:
60
,
"2018-11-26"
:
72
,
"2018-11-27"
:
71
,
"2018-11-28"
:
77
,
"2018-11-29"
:
77
,
"2018-11-30"
:
70
,
"2018-12-1"
:
69
,
"2018-12-2"
:
80
,
"2018-12-3"
:
73
,
"2018-12-4"
:
71
,
"2018-12-5"
:
84
,
"2018-12-6"
:
82
,
"2018-12-7"
:
68
,
"2018-12-8"
:
66
,
"2018-12-9"
:
76
,
"2018-12-10"
:
81
,
"2018-12-11"
:
61
,
"2018-12-12"
:
78
,
"2018-12-13"
:
85
,
"2018-12-14"
:
74
,
"2018-12-15"
:
65
,
"2018-12-16"
:
90
,
"2018-12-17"
:
87
,
"2018-12-18"
:
83
,
"2018-12-19"
:
72
,
"2018-12-20"
:
79
,
"2018-12-21"
:
83
,
"2018-12-22"
:
70
,
"2018-12-23"
:
75
,
"2018-12-24"
:
77
,
"2018-12-25"
:
68
,
"2018-12-26"
:
86
,
"2018-12-27"
:
76
,
"2018-12-28"
:
86
,
"2018-12-29"
:
89
,
"2018-12-30"
:
73
,
"2018-12-31"
:
70
},
"medium"
:
{
"2018-10-1"
:
73
,
"2018-10-2"
:
76
,
"2018-10-3"
:
101
,
"2018-10-4"
:
84
,
"2018-10-5"
:
90
,
"2018-10-6"
:
97
,
"2018-10-7"
:
77
,
"2018-10-8"
:
81
,
"2018-10-9"
:
98
,
"2018-10-10"
:
83
,
"2018-10-11"
:
82
,
"2018-10-12"
:
70
,
"2018-10-13"
:
99
,
"2018-10-14"
:
83
,
"2018-10-15"
:
81
,
"2018-10-16"
:
80
,
"2018-10-17"
:
82
,
"2018-10-18"
:
89
,
"2018-10-19"
:
89
,
"2018-10-20"
:
71
,
"2018-10-21"
:
73
,
"2018-10-22"
:
74
,
"2018-10-23"
:
83
,
"2018-10-24"
:
91
,
"2018-10-25"
:
85
,
"2018-10-26"
:
90
,
"2018-10-27"
:
77
,
"2018-10-28"
:
102
,
"2018-10-29"
:
75
,
"2018-10-30"
:
78
,
"2018-10-31"
:
70
,
"2018-11-1"
:
90
,
"2018-11-2"
:
96
,
"2018-11-3"
:
98
,
"2018-11-4"
:
88
,
"2018-11-5"
:
79
,
"2018-11-6"
:
91
,
"2018-11-7"
:
101
,
"2018-11-8"
:
75
,
"2018-11-9"
:
75
,
"2018-11-10"
:
84
,
"2018-11-11"
:
70
,
"2018-11-12"
:
89
,
"2018-11-13"
:
104
,
"2018-11-14"
:
90
,
"2018-11-15"
:
81
,
"2018-11-16"
:
102
,
"2018-11-17"
:
86
,
"2018-11-18"
:
80
,
"2018-11-19"
:
71
,
"2018-11-20"
:
72
,
"2018-11-21"
:
103
,
"2018-11-22"
:
89
,
"2018-11-23"
:
83
,
"2018-11-24"
:
79
,
"2018-11-25"
:
87
,
"2018-11-26"
:
79
,
"2018-11-27"
:
104
,
"2018-11-28"
:
70
,
"2018-11-29"
:
103
,
"2018-11-30"
:
86
,
"2018-12-1"
:
86
,
"2018-12-2"
:
77
,
"2018-12-3"
:
96
,
"2018-12-4"
:
95
,
"2018-12-5"
:
74
,
"2018-12-6"
:
99
,
"2018-12-7"
:
101
,
"2018-12-8"
:
78
,
"2018-12-9"
:
83
,
"2018-12-10"
:
76
,
"2018-12-11"
:
77
,
"2018-12-12"
:
105
,
"2018-12-13"
:
81
,
"2018-12-14"
:
82
,
"2018-12-15"
:
90
,
"2018-12-16"
:
88
,
"2018-12-17"
:
78
,
"2018-12-18"
:
82
,
"2018-12-19"
:
83
,
"2018-12-20"
:
105
,
"2018-12-21"
:
70
,
"2018-12-22"
:
85
,
"2018-12-23"
:
91
,
"2018-12-24"
:
89
,
"2018-12-25"
:
83
,
"2018-12-26"
:
73
,
"2018-12-27"
:
91
,
"2018-12-28"
:
77
,
"2018-12-29"
:
101
,
"2018-12-30"
:
83
,
"2018-12-31"
:
94
},
"high"
:
{
"2018-10-1"
:
43
,
"2018-10-2"
:
42
,
"2018-10-3"
:
42
,
"2018-10-4"
:
49
,
"2018-10-5"
:
44
,
"2018-10-6"
:
59
,
"2018-10-7"
:
49
,
"2018-10-8"
:
53
,
"2018-10-9"
:
44
,
"2018-10-10"
:
51
,
"2018-10-11"
:
43
,
"2018-10-12"
:
53
,
"2018-10-13"
:
52
,
"2018-10-14"
:
43
,
"2018-10-15"
:
60
,
"2018-10-16"
:
53
,
"2018-10-17"
:
57
,
"2018-10-18"
:
42
,
"2018-10-19"
:
46
,
"2018-10-20"
:
43
,
"2018-10-21"
:
43
,
"2018-10-22"
:
41
,
"2018-10-23"
:
47
,
"2018-10-24"
:
44
,
"2018-10-25"
:
43
,
"2018-10-26"
:
60
,
"2018-10-27"
:
43
,
"2018-10-28"
:
59
,
"2018-10-29"
:
55
,
"2018-10-30"
:
45
,
"2018-10-31"
:
51
,
"2018-11-1"
:
55
,
"2018-11-2"
:
50
,
"2018-11-3"
:
43
,
"2018-11-4"
:
41
,
"2018-11-5"
:
51
,
"2018-11-6"
:
49
,
"2018-11-7"
:
49
,
"2018-11-8"
:
60
,
"2018-11-9"
:
60
,
"2018-11-10"
:
43
,
"2018-11-11"
:
57
,
"2018-11-12"
:
42
,
"2018-11-13"
:
59
,
"2018-11-14"
:
41
,
"2018-11-15"
:
53
,
"2018-11-16"
:
53
,
"2018-11-17"
:
43
,
"2018-11-18"
:
53
,
"2018-11-19"
:
48
,
"2018-11-20"
:
56
,
"2018-11-21"
:
51
,
"2018-11-22"
:
42
,
"2018-11-23"
:
60
,
"2018-11-24"
:
50
,
"2018-11-25"
:
49
,
"2018-11-26"
:
47
,
"2018-11-27"
:
46
,
"2018-11-28"
:
40
,
"2018-11-29"
:
41
,
"2018-11-30"
:
57
,
"2018-12-1"
:
57
,
"2018-12-2"
:
45
,
"2018-12-3"
:
52
,
"2018-12-4"
:
46
,
"2018-12-5"
:
56
,
"2018-12-6"
:
48
,
"2018-12-7"
:
58
,
"2018-12-8"
:
59
,
"2018-12-9"
:
47
,
"2018-12-10"
:
58
,
"2018-12-11"
:
50
,
"2018-12-12"
:
45
,
"2018-12-13"
:
59
,
"2018-12-14"
:
40
,
"2018-12-15"
:
40
,
"2018-12-16"
:
48
,
"2018-12-17"
:
44
,
"2018-12-18"
:
54
,
"2018-12-19"
:
44
,
"2018-12-20"
:
57
,
"2018-12-21"
:
54
,
"2018-12-22"
:
44
,
"2018-12-23"
:
59
,
"2018-12-24"
:
41
,
"2018-12-25"
:
52
,
"2018-12-26"
:
52
,
"2018-12-27"
:
50
,
"2018-12-28"
:
49
,
"2018-12-29"
:
45
,
"2018-12-30"
:
44
,
"2018-12-31"
:
60
},
"critical"
:
{
"2018-10-1"
:
54
,
"2018-10-2"
:
67
,
"2018-10-3"
:
62
,
"2018-10-4"
:
63
,
"2018-10-5"
:
51
,
"2018-10-6"
:
56
,
"2018-10-7"
:
66
,
"2018-10-8"
:
69
,
"2018-10-9"
:
58
,
"2018-10-10"
:
61
,
"2018-10-11"
:
69
,
"2018-10-12"
:
73
,
"2018-10-13"
:
68
,
"2018-10-14"
:
64
,
"2018-10-15"
:
69
,
"2018-10-16"
:
63
,
"2018-10-17"
:
72
,
"2018-10-18"
:
71
,
"2018-10-19"
:
56
,
"2018-10-20"
:
71
,
"2018-10-21"
:
59
,
"2018-10-22"
:
55
,
"2018-10-23"
:
51
,
"2018-10-24"
:
74
,
"2018-10-25"
:
68
,
"2018-10-26"
:
74
,
"2018-10-27"
:
53
,
"2018-10-28"
:
73
,
"2018-10-29"
:
54
,
"2018-10-30"
:
53
,
"2018-10-31"
:
53
,
"2018-11-1"
:
68
,
"2018-11-2"
:
71
,
"2018-11-3"
:
57
,
"2018-11-4"
:
59
,
"2018-11-5"
:
58
,
"2018-11-6"
:
67
,
"2018-11-7"
:
56
,
"2018-11-8"
:
74
,
"2018-11-9"
:
54
,
"2018-11-10"
:
67
,
"2018-11-11"
:
61
,
"2018-11-12"
:
73
,
"2018-11-13"
:
58
,
"2018-11-14"
:
56
,
"2018-11-15"
:
55
,
"2018-11-16"
:
72
,
"2018-11-17"
:
53
,
"2018-11-18"
:
68
,
"2018-11-19"
:
52
,
"2018-11-20"
:
64
,
"2018-11-21"
:
72
,
"2018-11-22"
:
50
,
"2018-11-23"
:
59
,
"2018-11-24"
:
56
,
"2018-11-25"
:
74
,
"2018-11-26"
:
71
,
"2018-11-27"
:
66
,
"2018-11-28"
:
55
,
"2018-11-29"
:
51
,
"2018-11-30"
:
63
,
"2018-12-1"
:
54
,
"2018-12-2"
:
63
,
"2018-12-3"
:
64
,
"2018-12-4"
:
51
,
"2018-12-5"
:
66
,
"2018-12-6"
:
61
,
"2018-12-7"
:
62
,
"2018-12-8"
:
59
,
"2018-12-9"
:
69
,
"2018-12-10"
:
73
,
"2018-12-11"
:
67
,
"2018-12-12"
:
58
,
"2018-12-13"
:
69
,
"2018-12-14"
:
71
,
"2018-12-15"
:
69
,
"2018-12-16"
:
72
,
"2018-12-17"
:
73
,
"2018-12-18"
:
59
,
"2018-12-19"
:
60
,
"2018-12-20"
:
52
,
"2018-12-21"
:
71
,
"2018-12-22"
:
56
,
"2018-12-23"
:
61
,
"2018-12-24"
:
61
,
"2018-12-25"
:
72
,
"2018-12-26"
:
66
,
"2018-12-27"
:
67
,
"2018-12-28"
:
72
,
"2018-12-29"
:
58
,
"2018-12-30"
:
68
,
"2018-12-31"
:
54
,
"2019-1-1"
:
139
,
"2019-1-2"
:
137
,
"2019-1-3"
:
142
,
"2019-1-4"
:
137
,
"2019-1-5"
:
134
,
"2019-1-6"
:
133
,
"2019-1-7"
:
137
,
"2019-1-8"
:
140
,
"2019-1-9"
:
130
,
"2019-1-10"
:
132
,
"2019-1-11"
:
134
,
"2019-1-12"
:
143
,
"2019-1-13"
:
130
,
"2019-1-14"
:
133
,
"2019-1-15"
:
137
,
"2019-1-16"
:
141
,
"2019-1-17"
:
139
,
"2019-1-18"
:
145
,
"2019-1-19"
:
141
,
"2019-1-20"
:
137
,
"2019-1-21"
:
139
,
"2019-1-22"
:
131
,
"2019-1-23"
:
134
,
"2019-1-24"
:
144
,
"2019-1-25"
:
140
,
"2019-1-26"
:
145
,
"2019-1-27"
:
138
,
"2019-1-28"
:
136
,
"2019-1-29"
:
144
,
"2019-1-30"
:
131
,
"2019-1-31"
:
142
},
"unknown"
:
{
"2018-10-1"
:
39
,
"2018-10-2"
:
44
,
"2018-10-3"
:
35
,
"2018-10-4"
:
34
,
"2018-10-5"
:
38
,
"2018-10-6"
:
34
,
"2018-10-7"
:
34
,
"2018-10-8"
:
43
,
"2018-10-9"
:
41
,
"2018-10-10"
:
45
,
"2018-10-11"
:
41
,
"2018-10-12"
:
37
,
"2018-10-13"
:
34
,
"2018-10-14"
:
41
,
"2018-10-15"
:
45
,
"2018-10-16"
:
33
,
"2018-10-17"
:
40
,
"2018-10-18"
:
31
,
"2018-10-19"
:
42
,
"2018-10-20"
:
33
,
"2018-10-21"
:
44
,
"2018-10-22"
:
33
,
"2018-10-23"
:
35
,
"2018-10-24"
:
37
,
"2018-10-25"
:
43
,
"2018-10-26"
:
33
,
"2018-10-27"
:
43
,
"2018-10-28"
:
39
,
"2018-10-29"
:
37
,
"2018-10-30"
:
36
,
"2018-10-31"
:
37
,
"2018-11-1"
:
42
,
"2018-11-2"
:
41
,
"2018-11-3"
:
36
,
"2018-11-4"
:
31
,
"2018-11-5"
:
41
,
"2018-11-6"
:
37
,
"2018-11-7"
:
42
,
"2018-11-8"
:
42
,
"2018-11-9"
:
45
,
"2018-11-10"
:
34
,
"2018-11-11"
:
30
,
"2018-11-12"
:
40
,
"2018-11-13"
:
39
,
"2018-11-14"
:
44
,
"2018-11-15"
:
36
,
"2018-11-16"
:
35
,
"2018-11-17"
:
30
,
"2018-11-18"
:
31
,
"2018-11-19"
:
34
,
"2018-11-20"
:
31
,
"2018-11-21"
:
36
,
"2018-11-22"
:
37
,
"2018-11-23"
:
41
,
"2018-11-24"
:
38
,
"2018-11-25"
:
42
,
"2018-11-26"
:
41
,
"2018-11-27"
:
36
,
"2018-11-28"
:
32
,
"2018-11-29"
:
43
,
"2018-11-30"
:
36
,
"2018-12-1"
:
44
,
"2018-12-2"
:
34
,
"2018-12-3"
:
42
,
"2018-12-4"
:
32
,
"2018-12-5"
:
44
,
"2018-12-6"
:
31
,
"2018-12-7"
:
39
,
"2018-12-8"
:
37
,
"2018-12-9"
:
33
,
"2018-12-10"
:
37
,
"2018-12-11"
:
38
,
"2018-12-12"
:
35
,
"2018-12-13"
:
34
,
"2018-12-14"
:
40
,
"2018-12-15"
:
35
,
"2018-12-16"
:
42
,
"2018-12-17"
:
44
,
"2018-12-18"
:
40
,
"2018-12-19"
:
40
,
"2018-12-20"
:
30
,
"2018-12-21"
:
44
,
"2018-12-22"
:
32
,
"2018-12-23"
:
39
,
"2018-12-24"
:
37
,
"2018-12-25"
:
35
,
"2018-12-26"
:
39
,
"2018-12-27"
:
38
,
"2018-12-28"
:
44
,
"2018-12-29"
:
42
,
"2018-12-30"
:
37
,
"2018-12-31"
:
35
},
"all"
:
{
"2018-10-1"
:
143
,
"2018-10-2"
:
130
,
"2018-10-3"
:
139
,
"2018-10-4"
:
134
,
"2018-10-5"
:
138
,
"2018-10-6"
:
131
,
"2018-10-7"
:
137
,
"2018-10-8"
:
144
,
"2018-10-9"
:
140
,
"2018-10-10"
:
134
,
"2018-10-11"
:
142
,
"2018-10-12"
:
132
,
"2018-10-13"
:
136
,
"2018-10-14"
:
141
,
"2018-10-15"
:
134
,
"2018-10-16"
:
139
,
"2018-10-17"
:
141
,
"2018-10-18"
:
134
,
"2018-10-19"
:
131
,
"2018-10-20"
:
141
,
"2018-10-21"
:
139
,
"2018-10-22"
:
145
,
"2018-10-23"
:
142
,
"2018-10-24"
:
143
,
"2018-10-25"
:
143
,
"2018-10-26"
:
135
,
"2018-10-27"
:
136
,
"2018-10-28"
:
143
,
"2018-10-29"
:
142
,
"2018-10-30"
:
131
,
"2018-10-31"
:
141
,
"2018-11-1"
:
134
,
"2018-11-2"
:
134
,
"2018-11-3"
:
130
,
"2018-11-4"
:
137
,
"2018-11-5"
:
145
,
"2018-11-6"
:
137
,
"2018-11-7"
:
135
,
"2018-11-8"
:
145
,
"2018-11-9"
:
132
,
"2018-11-10"
:
134
,
"2018-11-11"
:
139
,
"2018-11-12"
:
139
,
"2018-11-13"
:
130
,
"2018-11-14"
:
137
,
"2018-11-15"
:
136
,
"2018-11-16"
:
145
,
"2018-11-17"
:
130
,
"2018-11-18"
:
143
,
"2018-11-19"
:
134
,
"2018-11-20"
:
145
,
"2018-11-21"
:
137
,
"2018-11-22"
:
140
,
"2018-11-23"
:
138
,
"2018-11-24"
:
132
,
"2018-11-25"
:
143
,
"2018-11-26"
:
131
,
"2018-11-27"
:
130
,
"2018-11-28"
:
144
,
"2018-11-29"
:
139
,
"2018-11-30"
:
143
,
"2018-12-1"
:
139
,
"2018-12-2"
:
137
,
"2018-12-3"
:
142
,
"2018-12-4"
:
137
,
"2018-12-5"
:
134
,
"2018-12-6"
:
133
,
"2018-12-7"
:
137
,
"2018-12-8"
:
140
,
"2018-12-9"
:
130
,
"2018-12-10"
:
132
,
"2018-12-11"
:
134
,
"2018-12-12"
:
143
,
"2018-12-13"
:
130
,
"2018-12-14"
:
133
,
"2018-12-15"
:
137
,
"2018-12-16"
:
141
,
"2018-12-17"
:
139
,
"2018-12-18"
:
145
,
"2018-12-19"
:
141
,
"2018-12-20"
:
137
,
"2018-12-21"
:
139
,
"2018-12-22"
:
131
,
"2018-12-23"
:
134
,
"2018-12-24"
:
144
,
"2018-12-25"
:
140
,
"2018-12-26"
:
145
,
"2018-12-27"
:
138
,
"2018-12-28"
:
136
,
"2018-12-29"
:
144
,
"2018-12-30"
:
131
,
"2018-12-31"
:
142
,
"2019-1-1"
:
139
,
"2019-1-2"
:
137
,
"2019-1-3"
:
142
,
"2019-1-4"
:
137
,
"2019-1-5"
:
134
,
"2019-1-6"
:
133
,
"2019-1-7"
:
137
,
"2019-1-8"
:
140
,
"2019-1-9"
:
130
,
"2019-1-10"
:
132
,
"2019-1-11"
:
134
,
"2019-1-12"
:
143
,
"2019-1-13"
:
130
,
"2019-1-14"
:
133
,
"2019-1-15"
:
137
,
"2019-1-16"
:
141
,
"2019-1-17"
:
139
,
"2019-1-18"
:
145
,
"2019-1-19"
:
141
,
"2019-1-20"
:
137
,
"2019-1-21"
:
139
,
"2019-1-22"
:
131
,
"2019-1-23"
:
134
,
"2019-1-24"
:
144
,
"2019-1-25"
:
140
,
"2019-1-26"
:
145
,
"2019-1-27"
:
138
,
"2019-1-28"
:
136
,
"2019-1-29"
:
144
,
"2019-1-30"
:
131
,
"2019-1-31"
:
142
}
}
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