Commit 4913784f authored by Savas Vedova's avatar Savas Vedova

Replace snake case with camel case

In order to increase consistency across the codebase,
this MR replaces snake case properties with camelCase
parent 9c4f6ecb
import Vue from 'vue'; import Vue from 'vue';
import MainApp from 'ee/vulnerabilities/components/vulnerability.vue'; import MainApp from 'ee/vulnerabilities/components/vulnerability.vue';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
(function createMainApp() { (function createMainApp() {
const el = document.getElementById('js-vulnerability-main'); const el = document.getElementById('js-vulnerability-main');
const vulnerability = JSON.parse(el.dataset.vulnerability); const vulnerability = convertObjectPropsToCamelCase(JSON.parse(el.dataset.vulnerability), {
deep: true,
});
return new Vue({ return new Vue({
el, el,
provide: { provide: {
reportType: vulnerability.report_type, reportType: vulnerability.reportType,
createIssueUrl: vulnerability.create_issue_url, createIssueUrl: vulnerability.createIssueUrl,
projectFingerprint: vulnerability.project_fingerprint, projectFingerprint: vulnerability.projectFingerprint,
vulnerabilityId: vulnerability.id, vulnerabilityId: vulnerability.id,
issueTrackingHelpPath: vulnerability.issueTrackingHelpPath, issueTrackingHelpPath: vulnerability.issueTrackingHelpPath,
permissionsHelpPath: vulnerability.permissionsHelpPath, permissionsHelpPath: vulnerability.permissionsHelpPath,
......
...@@ -23,7 +23,7 @@ export default { ...@@ -23,7 +23,7 @@ export default {
return this.vulnerability.location || {}; return this.vulnerability.location || {};
}, },
stacktraceSnippet() { stacktraceSnippet() {
return this.vulnerability.stacktrace_snippet || ''; return this.vulnerability.stacktraceSnippet || '';
}, },
scanner() { scanner() {
return this.vulnerability.scanner || {}; return this.vulnerability.scanner || {};
...@@ -32,10 +32,10 @@ export default { ...@@ -32,10 +32,10 @@ export default {
return (this.location.file || '') + (this.lineNumber ? `:${this.lineNumber}` : ''); return (this.location.file || '') + (this.lineNumber ? `:${this.lineNumber}` : '');
}, },
fileUrl() { fileUrl() {
return (this.location.blob_path || '') + (this.lineNumber ? `#L${this.lineNumber}` : ''); return (this.location.blobPath || '') + (this.lineNumber ? `#L${this.lineNumber}` : '');
}, },
lineNumber() { lineNumber() {
const { start_line: start, end_line: end } = this.location; const { startLine: start, endLine: end } = this.location;
return end > start ? `${start}-${end}` : start; return end > start ? `${start}-${end}` : start;
}, },
scannerUrl() { scannerUrl() {
...@@ -58,10 +58,10 @@ export default { ...@@ -58,10 +58,10 @@ export default {
}; };
}, },
assertion() { assertion() {
return this.vulnerability.evidence_source?.name; return this.vulnerability.evidenceSource?.name;
}, },
recordedMessage() { recordedMessage() {
return this.vulnerability?.supporting_messages?.find( return this.vulnerability?.supportingMessages?.find(
msg => msg.name === SUPPORTING_MESSAGE_TYPES.RECORDED, msg => msg.name === SUPPORTING_MESSAGE_TYPES.RECORDED,
)?.response; )?.response;
}, },
...@@ -115,12 +115,12 @@ export default { ...@@ -115,12 +115,12 @@ export default {
}, },
shouldShowLocation() { shouldShowLocation() {
return ( return (
this.location.crash_address || this.location.crashAddress ||
this.location.crash_type || this.location.crashType ||
this.location.stacktrace_snippet || this.location.stacktraceSnippet ||
this.location.file || this.location.file ||
this.location.image || this.location.image ||
this.location.operating_system this.location.operatingSystem
); );
}, },
hasRequest() { hasRequest() {
...@@ -181,7 +181,7 @@ export default { ...@@ -181,7 +181,7 @@ export default {
<severity-badge :severity="vulnerability.severity" class="gl-display-inline ml-1" /> <severity-badge :severity="vulnerability.severity" class="gl-display-inline ml-1" />
</detail-item> </detail-item>
<detail-item :sprintf-message="__('%{labelStart}Scan Type:%{labelEnd} %{reportType}')" <detail-item :sprintf-message="__('%{labelStart}Scan Type:%{labelEnd} %{reportType}')"
>{{ vulnerability.report_type }} >{{ vulnerability.reportType }}
</detail-item> </detail-item>
<detail-item <detail-item
v-if="scanner.name" v-if="scanner.name"
...@@ -229,9 +229,9 @@ export default { ...@@ -229,9 +229,9 @@ export default {
>{{ location.image }} >{{ location.image }}
</detail-item> </detail-item>
<detail-item <detail-item
v-if="location.operating_system" v-if="location.operatingSystem"
:sprintf-message="__('%{labelStart}Namespace:%{labelEnd} %{namespace}')" :sprintf-message="__('%{labelStart}Namespace:%{labelEnd} %{namespace}')"
>{{ location.operating_system }} >{{ location.operatingSystem }}
</detail-item> </detail-item>
<detail-item <detail-item
v-if="location.file" v-if="location.file"
...@@ -240,15 +240,15 @@ export default { ...@@ -240,15 +240,15 @@ export default {
<gl-link :href="fileUrl" target="_blank">{{ fileText }}</gl-link> <gl-link :href="fileUrl" target="_blank">{{ fileText }}</gl-link>
</detail-item> </detail-item>
<detail-item <detail-item
v-if="location.crash_address" v-if="location.crashAddress"
:sprintf-message="__('%{labelStart}Crash Address:%{labelEnd} %{crash_address}')" :sprintf-message="__('%{labelStart}Crash Address:%{labelEnd} %{crash_address}')"
>{{ location.crash_address }} >{{ location.crashAddress }}
</detail-item> </detail-item>
<detail-item <detail-item
v-if="location.stacktrace_snippet" v-if="location.stacktraceSnippet"
:sprintf-message="__('%{labelStart}Crash State:%{labelEnd} %{stacktrace_snippet}')" :sprintf-message="__('%{labelStart}Crash State:%{labelEnd} %{stacktrace_snippet}')"
> >
<code-block :code="location.stacktrace_snippet" max-height="225px" /> <code-block :code="location.stacktraceSnippet" max-height="225px" />
</detail-item> </detail-item>
</ul> </ul>
</template> </template>
......
...@@ -6,6 +6,7 @@ import Api from 'ee/api'; ...@@ -6,6 +6,7 @@ import Api from 'ee/api';
import { VULNERABILITY_STATE_OBJECTS } from 'ee/vulnerabilities/constants'; import { VULNERABILITY_STATE_OBJECTS } from 'ee/vulnerabilities/constants';
import { GlIcon } from '@gitlab/ui'; import { GlIcon } from '@gitlab/ui';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
import Poll from '~/lib/utils/poll'; import Poll from '~/lib/utils/poll';
import { deprecatedCreateFlash as createFlash } from '~/flash'; import { deprecatedCreateFlash as createFlash } from '~/flash';
import { s__, __ } from '~/locale'; import { s__, __ } from '~/locale';
...@@ -50,12 +51,12 @@ export default { ...@@ -50,12 +51,12 @@ export default {
}, },
project() { project() {
return { return {
url: this.vulnerability.project.full_path, url: this.vulnerability.project.fullPath,
value: this.vulnerability.project.full_name, value: this.vulnerability.project.fullName,
}; };
}, },
solutionInfo() { solutionInfo() {
const { solution, has_mr: hasMr, remediations, state } = this.vulnerability; const { solution, hasMr, remediations, state } = this.vulnerability;
const remediation = remediations?.[0]; const remediation = remediations?.[0];
const hasDownload = Boolean( const hasDownload = Boolean(
...@@ -103,7 +104,7 @@ export default { ...@@ -103,7 +104,7 @@ export default {
}, },
fetchDiscussions() { fetchDiscussions() {
axios axios
.get(this.vulnerability.discussions_url) .get(this.vulnerability.discussionsUrl)
.then(({ data, headers: { date } }) => { .then(({ data, headers: { date } }) => {
this.discussionsDictionary = data.reduce((acc, discussion) => { this.discussionsDictionary = data.reduce((acc, discussion) => {
acc[discussion.id] = discussion; acc[discussion.id] = discussion;
...@@ -139,13 +140,13 @@ export default { ...@@ -139,13 +140,13 @@ export default {
this.poll = new Poll({ this.poll = new Poll({
resource: { resource: {
fetchNotes: () => fetchNotes: () =>
axios.get(this.vulnerability.notes_url, { axios.get(this.vulnerability.notesUrl, {
headers: { 'X-Last-Fetched-At': this.lastFetchedAt }, headers: { 'X-Last-Fetched-At': this.lastFetchedAt },
}), }),
}, },
method: 'fetchNotes', method: 'fetchNotes',
successCallback: ({ data: { notes, last_fetched_at: lastFetchedAt } }) => { successCallback: ({ data: { notes, last_fetched_at: lastFetchedAt } }) => {
this.updateNotes(notes); this.updateNotes(convertObjectPropsToCamelCase(notes, { deep: true }));
this.lastFetchedAt = lastFetchedAt; this.lastFetchedAt = lastFetchedAt;
}, },
errorCallback: () => errorCallback: () =>
...@@ -158,23 +159,23 @@ export default { ...@@ -158,23 +159,23 @@ export default {
notes.forEach(note => { notes.forEach(note => {
// If the note exists, update it. // If the note exists, update it.
if (this.noteDictionary[note.id]) { if (this.noteDictionary[note.id]) {
const updatedDiscussion = { ...this.discussionsDictionary[note.discussion_id] }; const updatedDiscussion = { ...this.discussionsDictionary[note.discussionId] };
updatedDiscussion.notes = updatedDiscussion.notes.map(curr => updatedDiscussion.notes = updatedDiscussion.notes.map(curr =>
curr.id === note.id ? note : curr, curr.id === note.id ? note : curr,
); );
this.discussionsDictionary[note.discussion_id] = updatedDiscussion; this.discussionsDictionary[note.discussionId] = updatedDiscussion;
} }
// If the note doesn't exist, but the discussion does, add the note to the discussion. // If the note doesn't exist, but the discussion does, add the note to the discussion.
else if (this.discussionsDictionary[note.discussion_id]) { else if (this.discussionsDictionary[note.discussionId]) {
const updatedDiscussion = { ...this.discussionsDictionary[note.discussion_id] }; const updatedDiscussion = { ...this.discussionsDictionary[note.discussionId] };
updatedDiscussion.notes.push(note); updatedDiscussion.notes.push(note);
this.discussionsDictionary[note.discussion_id] = updatedDiscussion; this.discussionsDictionary[note.discussionId] = updatedDiscussion;
} }
// If the discussion doesn't exist, create it. // If the discussion doesn't exist, create it.
else { else {
const newDiscussion = { const newDiscussion = {
id: note.discussion_id, id: note.discussionId,
reply_id: note.discussion_id, replyId: note.discussionId,
notes: [note], notes: [note],
}; };
this.$set(this.discussionsDictionary, newDiscussion.id, newDiscussion); this.$set(this.discussionsDictionary, newDiscussion.id, newDiscussion);
...@@ -198,9 +199,9 @@ export default { ...@@ -198,9 +199,9 @@ export default {
<div data-qa-selector="vulnerability_footer"> <div data-qa-selector="vulnerability_footer">
<solution-card v-if="hasSolution" v-bind="solutionInfo" /> <solution-card v-if="hasSolution" v-bind="solutionInfo" />
<div v-if="vulnerability.merge_request_feedback" class="card gl-mt-5"> <div v-if="vulnerability.mergeRequestFeedback" class="card gl-mt-5">
<merge-request-note <merge-request-note
:feedback="vulnerability.merge_request_feedback" :feedback="vulnerability.mergeRequestFeedback"
:project="project" :project="project"
class="card-body" class="card-body"
/> />
...@@ -208,9 +209,9 @@ export default { ...@@ -208,9 +209,9 @@ export default {
<related-issues <related-issues
:endpoint="issueLinksEndpoint" :endpoint="issueLinksEndpoint"
:can-modify-related-issues="vulnerability.can_modify_related_issues" :can-modify-related-issues="vulnerability.canModifyRelatedIssues"
:project-path="project.url" :project-path="project.url"
:help-path="vulnerability.related_issues_help_path" :help-path="vulnerability.relatedIssuesHelpPath"
/> />
<div class="notes" data-testid="detection-note"> <div class="notes" data-testid="detection-note">
...@@ -233,7 +234,7 @@ export default { ...@@ -233,7 +234,7 @@ export default {
v-for="discussion in discussions" v-for="discussion in discussions"
:key="discussion.id" :key="discussion.id"
:discussion="discussion" :discussion="discussion"
:notes-url="vulnerability.notes_url" :notes-url="vulnerability.notesUrl"
/> />
</ul> </ul>
</div> </div>
......
...@@ -5,6 +5,7 @@ import { CancelToken } from 'axios'; ...@@ -5,6 +5,7 @@ import { CancelToken } from 'axios';
import SplitButton from 'ee/vue_shared/security_reports/components/split_button.vue'; import SplitButton from 'ee/vue_shared/security_reports/components/split_button.vue';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import download from '~/lib/utils/downloader'; import download from '~/lib/utils/downloader';
import { convertObjectPropsToSnakeCase } from '~/lib/utils/common_utils';
import { redirectTo } from '~/lib/utils/url_utility'; import { redirectTo } from '~/lib/utils/url_utility';
import { deprecatedCreateFlash as createFlash } from '~/flash'; import { deprecatedCreateFlash as createFlash } from '~/flash';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
...@@ -78,7 +79,7 @@ export default { ...@@ -78,7 +79,7 @@ export default {
); );
}, },
hasIssue() { hasIssue() {
return Boolean(this.vulnerability.issue_feedback?.issue_iid); return Boolean(this.vulnerability.issueFeedback?.issueIid);
}, },
hasRemediation() { hasRemediation() {
const { remediations } = this.vulnerability; const { remediations } = this.vulnerability;
...@@ -86,14 +87,14 @@ export default { ...@@ -86,14 +87,14 @@ export default {
}, },
canCreateMergeRequest() { canCreateMergeRequest() {
return ( return (
!this.vulnerability.merge_request_feedback?.merge_request_path && !this.vulnerability.mergeRequestFeedback?.mergeRequestPath &&
Boolean(this.vulnerability.create_mr_url) && Boolean(this.vulnerability.createMrUrl) &&
this.hasRemediation this.hasRemediation
); );
}, },
showResolutionAlert() { showResolutionAlert() {
return ( return (
this.vulnerability.resolved_on_default_branch && this.vulnerability.resolvedOnDefaultBranch &&
this.vulnerability.state !== VULNERABILITY_STATE_OBJECTS.resolved.state this.vulnerability.state !== VULNERABILITY_STATE_OBJECTS.resolved.state
); );
}, },
...@@ -103,7 +104,7 @@ export default { ...@@ -103,7 +104,7 @@ export default {
'vulnerability.state': { 'vulnerability.state': {
immediate: true, immediate: true,
handler(state) { handler(state) {
const id = this.vulnerability[`${state}_by_id`]; const id = this.vulnerability[`${state}ById`];
if (id === undefined) return; // Don't do anything if there's no ID. if (id === undefined) return; // Don't do anything if there's no ID.
...@@ -151,26 +152,26 @@ export default { ...@@ -151,26 +152,26 @@ export default {
this.isProcessingAction = true; this.isProcessingAction = true;
const { const {
report_type: category, reportType: category,
pipeline: { sourceBranch }, pipeline: { sourceBranch },
project_fingerprint: projectFingerprint, projectFingerprint,
} = this.vulnerability; } = this.vulnerability;
axios axios
.post(this.vulnerability.create_mr_url, { .post(this.vulnerability.createMrUrl, {
vulnerability_feedback: { vulnerability_feedback: {
feedback_type: FEEDBACK_TYPES.MERGE_REQUEST, feedback_type: FEEDBACK_TYPES.MERGE_REQUEST,
category, category,
project_fingerprint: projectFingerprint, project_fingerprint: projectFingerprint,
vulnerability_data: { vulnerability_data: {
...this.vulnerability, ...convertObjectPropsToSnakeCase(this.vulnerability),
category, category,
target_branch: sourceBranch, target_branch: sourceBranch,
}, },
}, },
}) })
.then(({ data: { merge_request_path } }) => { .then(({ data: { merge_request_path: mergeRequestPath } }) => {
redirectTo(merge_request_path); redirectTo(mergeRequestPath);
}) })
.catch(() => { .catch(() => {
this.isProcessingAction = false; this.isProcessingAction = false;
...@@ -225,7 +226,7 @@ export default { ...@@ -225,7 +226,7 @@ export default {
<resolution-alert <resolution-alert
v-if="showResolutionAlert" v-if="showResolutionAlert"
:vulnerability-id="vulnerability.id" :vulnerability-id="vulnerability.id"
:default-branch-name="vulnerability.project_default_branch" :default-branch-name="vulnerability.projectDefaultBranch"
/> />
<div class="detail-page-header"> <div class="detail-page-header">
<div class="detail-page-header-body align-items-center"> <div class="detail-page-header-body align-items-center">
......
...@@ -59,8 +59,8 @@ export default { ...@@ -59,8 +59,8 @@ export default {
<event-item <event-item
:id="systemNote.id" :id="systemNote.id"
:author="systemNote.author" :author="systemNote.author"
:created-at="systemNote.updated_at" :created-at="systemNote.updatedAt"
:icon-name="systemNote.system_note_icon_name" :icon-name="systemNote.systemNoteIconName"
icon-class="timeline-icon m-0" icon-class="timeline-icon m-0"
class="m-3" class="m-3"
> >
...@@ -74,7 +74,7 @@ export default { ...@@ -74,7 +74,7 @@ export default {
:key="comment.id" :key="comment.id"
ref="existingComment" ref="existingComment"
:comment="comment" :comment="comment"
:discussion-id="discussion.reply_id" :discussion-id="discussion.replyId"
:notes-url="notesUrl" :notes-url="notesUrl"
@onCommentUpdated="updateComment" @onCommentUpdated="updateComment"
@onCommentDeleted="removeComment" @onCommentDeleted="removeComment"
...@@ -84,7 +84,7 @@ export default { ...@@ -84,7 +84,7 @@ export default {
<history-comment <history-comment
v-else v-else
ref="newComment" ref="newComment"
:discussion-id="discussion.reply_id" :discussion-id="discussion.replyId"
:notes-url="notesUrl" :notes-url="notesUrl"
@onCommentAdded="addComment" @onCommentAdded="addComment"
/> />
......
...@@ -50,8 +50,8 @@ export default { ...@@ -50,8 +50,8 @@ export default {
time() { time() {
const { state } = this.vulnerability; const { state } = this.vulnerability;
return state === 'detected' return state === 'detected'
? this.vulnerability.pipeline.created_at ? this.vulnerability.pipeline.createdAt
: this.vulnerability[`${this.vulnerability.state}_at`]; : this.vulnerability[`${this.vulnerability.state}At`];
}, },
statusText() { statusText() {
......
...@@ -12,7 +12,7 @@ describe('Vulnerability Details', () => { ...@@ -12,7 +12,7 @@ describe('Vulnerability Details', () => {
title: 'some title', title: 'some title',
severity: 'bad severity', severity: 'bad severity',
confidence: 'high confidence', confidence: 'high confidence',
report_type: 'nice report_type', reportType: 'nice report_type',
description: 'vulnerability description', description: 'vulnerability description',
}; };
...@@ -37,7 +37,7 @@ describe('Vulnerability Details', () => { ...@@ -37,7 +37,7 @@ describe('Vulnerability Details', () => {
expect(getText('title')).toBe(vulnerability.title); expect(getText('title')).toBe(vulnerability.title);
expect(getText('description')).toBe(vulnerability.description); expect(getText('description')).toBe(vulnerability.description);
expect(wrapper.find(SeverityBadge).props('severity')).toBe(vulnerability.severity); expect(wrapper.find(SeverityBadge).props('severity')).toBe(vulnerability.severity);
expect(getText('reportType')).toBe(`Scan Type: ${vulnerability.report_type}`); expect(getText('reportType')).toBe(`Scan Type: ${vulnerability.reportType}`);
expect(getById('image').exists()).toBe(false); expect(getById('image').exists()).toBe(false);
expect(getById('os').exists()).toBe(false); expect(getById('os').exists()).toBe(false);
...@@ -56,7 +56,7 @@ describe('Vulnerability Details', () => { ...@@ -56,7 +56,7 @@ describe('Vulnerability Details', () => {
}); });
it('shows the operating system if it exists', () => { it('shows the operating system if it exists', () => {
createWrapper({ location: { operating_system: 'linux' } }); createWrapper({ location: { operatingSystem: 'linux' } });
expect(getText('namespace')).toBe(`Namespace: linux`); expect(getText('namespace')).toBe(`Namespace: linux`);
}); });
...@@ -111,14 +111,14 @@ describe('Vulnerability Details', () => { ...@@ -111,14 +111,14 @@ describe('Vulnerability Details', () => {
const file = () => getById('file').find(GlLink); const file = () => getById('file').find(GlLink);
it('shows only the file name if there is no start line', () => { it('shows only the file name if there is no start line', () => {
createWrapper({ location: { file: 'test.txt', blob_path: 'blob_path.txt' } }); createWrapper({ location: { file: 'test.txt', blobPath: 'blob_path.txt' } });
expect(file().attributes('target')).toBe('_blank'); expect(file().attributes('target')).toBe('_blank');
expect(file().attributes('href')).toBe('blob_path.txt'); expect(file().attributes('href')).toBe('blob_path.txt');
expect(file().text()).toBe('test.txt'); expect(file().text()).toBe('test.txt');
}); });
it('shows the correct line number when there is a start line', () => { it('shows the correct line number when there is a start line', () => {
createWrapper({ location: { file: 'test.txt', start_line: 24, blob_path: 'blob.txt' } }); createWrapper({ location: { file: 'test.txt', startLine: 24, blobPath: 'blob.txt' } });
expect(file().attributes('target')).toBe('_blank'); expect(file().attributes('target')).toBe('_blank');
expect(file().attributes('href')).toBe('blob.txt#L24'); expect(file().attributes('href')).toBe('blob.txt#L24');
expect(file().text()).toBe('test.txt:24'); expect(file().text()).toBe('test.txt:24');
...@@ -126,7 +126,7 @@ describe('Vulnerability Details', () => { ...@@ -126,7 +126,7 @@ describe('Vulnerability Details', () => {
it('shows the correct line numbers when there is a start and end line', () => { it('shows the correct line numbers when there is a start and end line', () => {
createWrapper({ createWrapper({
location: { file: 'test.txt', start_line: 24, end_line: 27, blob_path: 'blob.txt' }, location: { file: 'test.txt', startLine: 24, endLine: 27, blobPath: 'blob.txt' },
}); });
expect(file().attributes('target')).toBe('_blank'); expect(file().attributes('target')).toBe('_blank');
expect(file().attributes('href')).toBe('blob.txt#L24-27'); expect(file().attributes('href')).toBe('blob.txt#L24-27');
...@@ -135,7 +135,7 @@ describe('Vulnerability Details', () => { ...@@ -135,7 +135,7 @@ describe('Vulnerability Details', () => {
it('shows only the start line when the end line is the same', () => { it('shows only the start line when the end line is the same', () => {
createWrapper({ createWrapper({
location: { file: 'test.txt', start_line: 24, end_line: 24, blob_path: 'blob.txt' }, location: { file: 'test.txt', startLine: 24, endLine: 24, blobPath: 'blob.txt' },
}); });
expect(file().attributes('target')).toBe('_blank'); expect(file().attributes('target')).toBe('_blank');
expect(file().attributes('href')).toBe('blob.txt#L24'); expect(file().attributes('href')).toBe('blob.txt#L24');
...@@ -237,7 +237,7 @@ describe('Vulnerability Details', () => { ...@@ -237,7 +237,7 @@ describe('Vulnerability Details', () => {
}); });
it.each` it.each`
supporting_messages | expectedData supportingMessages | expectedData
${null} | ${null} ${null} | ${null}
${[]} | ${null} ${[]} | ${null}
${[{}]} | ${null} ${[{}]} | ${null}
...@@ -247,8 +247,8 @@ describe('Vulnerability Details', () => { ...@@ -247,8 +247,8 @@ describe('Vulnerability Details', () => {
${[{}, { response: { headers: TEST_HEADERS, body: '[{"user_id":1,}]', status_code: '200' } }]} | ${null} ${[{}, { response: { headers: TEST_HEADERS, body: '[{"user_id":1,}]', status_code: '200' } }]} | ${null}
${[{}, { response: { headers: TEST_HEADERS, body: '[{"user_id":1,}]', status_code: '200', reason_phrase: 'OK' } }]} | ${null} ${[{}, { response: { headers: TEST_HEADERS, body: '[{"user_id":1,}]', status_code: '200', reason_phrase: 'OK' } }]} | ${null}
${[{}, { name: SUPPORTING_MESSAGE_TYPES.RECORDED, response: { headers: TEST_HEADERS, body: '[{"user_id":1,}]', status_code: '200', reason_phrase: 'OK' } }]} | ${[EXPECT_RECORDED_RESPONSE]} ${[{}, { name: SUPPORTING_MESSAGE_TYPES.RECORDED, response: { headers: TEST_HEADERS, body: '[{"user_id":1,}]', status_code: '200', reason_phrase: 'OK' } }]} | ${[EXPECT_RECORDED_RESPONSE]}
`('shows response data for $supporting_messages', ({ supporting_messages, expectedData }) => { `('shows response data for $supporting_messages', ({ supportingMessages, expectedData }) => {
createWrapper({ supporting_messages }); createWrapper({ supportingMessages });
expect(getSectionData('recorded-response')).toEqual(expectedData); expect(getSectionData('recorded-response')).toEqual(expectedData);
}); });
}); });
......
...@@ -21,15 +21,15 @@ describe('Vulnerability Footer', () => { ...@@ -21,15 +21,15 @@ describe('Vulnerability Footer', () => {
const vulnerability = { const vulnerability = {
id: 1, id: 1,
discussions_url: '/discussions', discussionsUrl: '/discussions',
notes_url: '/notes', notesUrl: '/notes',
project: { project: {
full_path: '/root/security-reports', fullPath: '/root/security-reports',
full_name: 'Administrator / Security Reports', fullName: 'Administrator / Security Reports',
}, },
can_modify_related_issues: true, canModifyRelatedIssues: true,
related_issues_help_path: 'help/path', relatedIssuesHelpPath: 'help/path',
has_mr: false, hasMr: false,
pipeline: {}, pipeline: {},
}; };
...@@ -67,7 +67,7 @@ describe('Vulnerability Footer', () => { ...@@ -67,7 +67,7 @@ describe('Vulnerability Footer', () => {
solution: properties.solution, solution: properties.solution,
remediation: properties.remediations[0], remediation: properties.remediations[0],
hasDownload: true, hasDownload: true,
hasMr: vulnerability.has_mr, hasMr: vulnerability.hasMr,
}); });
}); });
...@@ -89,14 +89,14 @@ describe('Vulnerability Footer', () => { ...@@ -89,14 +89,14 @@ describe('Vulnerability Footer', () => {
// The object itself does not matter, we just want to make sure it's passed to the issue note. // The object itself does not matter, we just want to make sure it's passed to the issue note.
const mergeRequestFeedback = {}; const mergeRequestFeedback = {};
createWrapper({ merge_request_feedback: mergeRequestFeedback }); createWrapper({ mergeRequestFeedback });
expect(mergeRequestNote().exists()).toBe(true); expect(mergeRequestNote().exists()).toBe(true);
expect(mergeRequestNote().props('feedback')).toBe(mergeRequestFeedback); expect(mergeRequestNote().props('feedback')).toBe(mergeRequestFeedback);
}); });
}); });
describe('state history', () => { describe('state history', () => {
const discussionUrl = vulnerability.discussions_url; const discussionUrl = vulnerability.discussionsUrl;
const historyList = () => wrapper.find({ ref: 'historyList' }); const historyList = () => wrapper.find({ ref: 'historyList' });
const historyEntries = () => wrapper.findAll(HistoryEntry); const historyEntries = () => wrapper.findAll(HistoryEntry);
...@@ -152,7 +152,7 @@ describe('Vulnerability Footer', () => { ...@@ -152,7 +152,7 @@ describe('Vulnerability Footer', () => {
const createNotesRequest = (...notes) => const createNotesRequest = (...notes) =>
mockAxios mockAxios
.onGet(vulnerability.notes_url) .onGet(vulnerability.notes_url)
.replyOnce(200, { notes, last_fetched_at: Date.now() }); .replyOnce(200, { notes, lastFetchedAt: Date.now() });
// Following #217184 the vulnerability polling uses an initial timeout // Following #217184 the vulnerability polling uses an initial timeout
// which we need to run and then wait for the subsequent request. // which we need to run and then wait for the subsequent request.
...@@ -268,9 +268,9 @@ describe('Vulnerability Footer', () => { ...@@ -268,9 +268,9 @@ describe('Vulnerability Footer', () => {
expect(relatedIssues().exists()).toBe(true); expect(relatedIssues().exists()).toBe(true);
expect(relatedIssues().props()).toMatchObject({ expect(relatedIssues().props()).toMatchObject({
endpoint, endpoint,
canModifyRelatedIssues: vulnerability.can_modify_related_issues, canModifyRelatedIssues: vulnerability.canModifyRelatedIssues,
projectPath: vulnerability.project.full_path, projectPath: vulnerability.project.fullPath,
helpPath: vulnerability.related_issues_help_path, helpPath: vulnerability.relatedIssuesHelpPath,
}); });
}); });
}); });
......
...@@ -10,6 +10,7 @@ import VulnerabilityStateDropdown from 'ee/vulnerabilities/components/vulnerabil ...@@ -10,6 +10,7 @@ import VulnerabilityStateDropdown from 'ee/vulnerabilities/components/vulnerabil
import { FEEDBACK_TYPES, VULNERABILITY_STATE_OBJECTS } from 'ee/vulnerabilities/constants'; import { FEEDBACK_TYPES, VULNERABILITY_STATE_OBJECTS } from 'ee/vulnerabilities/constants';
import UsersMockHelper from 'helpers/user_mock_data_helper'; import UsersMockHelper from 'helpers/user_mock_data_helper';
import waitForPromises from 'helpers/wait_for_promises'; import waitForPromises from 'helpers/wait_for_promises';
import { convertObjectPropsToSnakeCase } from '~/lib/utils/common_utils';
import { deprecatedCreateFlash as createFlash } from '~/flash'; import { deprecatedCreateFlash as createFlash } from '~/flash';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import download from '~/lib/utils/downloader'; import download from '~/lib/utils/downloader';
...@@ -25,15 +26,15 @@ describe('Vulnerability Header', () => { ...@@ -25,15 +26,15 @@ describe('Vulnerability Header', () => {
const defaultVulnerability = { const defaultVulnerability = {
id: 1, id: 1,
created_at: new Date().toISOString(), createdAt: new Date().toISOString(),
report_type: 'sast', reportType: 'sast',
state: 'detected', state: 'detected',
create_mr_url: '/create_mr_url', createMrUrl: '/create_mr_url',
create_issue_url: '/create_issue_url', createIssueUrl: '/create_issue_url',
project_fingerprint: 'abc123', projectFingerprint: 'abc123',
pipeline: { pipeline: {
id: 2, id: 2,
created_at: new Date().toISOString(), createdAt: new Date().toISOString(),
url: 'pipeline_url', url: 'pipeline_url',
sourceBranch: 'master', sourceBranch: 'master',
}, },
...@@ -53,8 +54,8 @@ describe('Vulnerability Header', () => { ...@@ -53,8 +54,8 @@ describe('Vulnerability Header', () => {
return { return {
remediations: shouldShowMergeRequestButton ? [{ diff }] : null, remediations: shouldShowMergeRequestButton ? [{ diff }] : null,
hasMr: !shouldShowDownloadPatchButton, hasMr: !shouldShowDownloadPatchButton,
merge_request_feedback: { mergeRequestFeedback: {
merge_request_path: shouldShowMergeRequestButton ? null : 'some path', mergeRequestPath: shouldShowMergeRequestButton ? null : 'some path',
}, },
}; };
}; };
...@@ -196,23 +197,25 @@ describe('Vulnerability Header', () => { ...@@ -196,23 +197,25 @@ describe('Vulnerability Header', () => {
it('emits createMergeRequest when create merge request button is clicked', () => { it('emits createMergeRequest when create merge request button is clicked', () => {
const mergeRequestPath = '/group/project/merge_request/123'; const mergeRequestPath = '/group/project/merge_request/123';
const spy = jest.spyOn(urlUtility, 'redirectTo'); const spy = jest.spyOn(urlUtility, 'redirectTo');
mockAxios.onPost(defaultVulnerability.create_mr_url).reply(200, { mockAxios.onPost(defaultVulnerability.createMrUrl).reply(200, {
merge_request_path: mergeRequestPath, merge_request_path: mergeRequestPath,
}); });
findGlButton().vm.$emit('click'); findGlButton().vm.$emit('click');
return waitForPromises().then(() => { return waitForPromises().then(() => {
expect(mockAxios.history.post).toHaveLength(1); expect(mockAxios.history.post).toHaveLength(1);
const [postRequest] = mockAxios.history.post; const [postRequest] = mockAxios.history.post;
expect(postRequest.url).toBe(defaultVulnerability.create_mr_url); expect(postRequest.url).toBe(defaultVulnerability.createMrUrl);
expect(JSON.parse(postRequest.data)).toMatchObject({ expect(JSON.parse(postRequest.data)).toMatchObject({
vulnerability_feedback: { vulnerability_feedback: {
feedback_type: FEEDBACK_TYPES.MERGE_REQUEST, feedback_type: FEEDBACK_TYPES.MERGE_REQUEST,
category: defaultVulnerability.report_type, category: defaultVulnerability.reportType,
project_fingerprint: defaultVulnerability.project_fingerprint, project_fingerprint: defaultVulnerability.projectFingerprint,
vulnerability_data: { vulnerability_data: {
...getVulnerability({ shouldShowMergeRequestButton: true }), ...convertObjectPropsToSnakeCase(
hasMr: true, getVulnerability({ shouldShowMergeRequestButton: true }),
category: defaultVulnerability.report_type, ),
has_mr: true,
category: defaultVulnerability.reportType,
state: 'resolved', state: 'resolved',
}, },
}, },
...@@ -237,7 +240,7 @@ describe('Vulnerability Header', () => { ...@@ -237,7 +240,7 @@ describe('Vulnerability Header', () => {
beforeEach(() => { beforeEach(() => {
createWrapper({ createWrapper({
...getVulnerability({ shouldShowMergeRequestButton: true }), ...getVulnerability({ shouldShowMergeRequestButton: true }),
create_mr_url: '', createMrUrl: '',
}); });
}); });
...@@ -280,7 +283,7 @@ describe('Vulnerability Header', () => { ...@@ -280,7 +283,7 @@ describe('Vulnerability Header', () => {
const vulnerability = { const vulnerability = {
...defaultVulnerability, ...defaultVulnerability,
state: 'confirmed', state: 'confirmed',
confirmed_by_id: user.id, confirmedById: user.id,
}; };
createWrapper(vulnerability); createWrapper(vulnerability);
...@@ -303,8 +306,8 @@ describe('Vulnerability Header', () => { ...@@ -303,8 +306,8 @@ describe('Vulnerability Header', () => {
beforeEach(() => { beforeEach(() => {
createWrapper({ createWrapper({
resolved_on_default_branch: true, resolvedOnDefaultBranch: true,
project_default_branch: branchName, projectDefaultBranch: branchName,
}); });
}); });
...@@ -334,7 +337,7 @@ describe('Vulnerability Header', () => { ...@@ -334,7 +337,7 @@ describe('Vulnerability Header', () => {
`loads the correct user for the vulnerability state "%s"`, `loads the correct user for the vulnerability state "%s"`,
state => { state => {
const user = createRandomUser(); const user = createRandomUser();
createWrapper({ state, [`${state}_by_id`]: user.id }); createWrapper({ state, [`${state}ById`]: user.id });
return waitForPromises().then(() => { return waitForPromises().then(() => {
expect(mockAxios.history.get).toHaveLength(1); expect(mockAxios.history.get).toHaveLength(1);
...@@ -353,7 +356,7 @@ describe('Vulnerability Header', () => { ...@@ -353,7 +356,7 @@ describe('Vulnerability Header', () => {
}); });
it('will show an error when the user cannot be loaded', () => { it('will show an error when the user cannot be loaded', () => {
createWrapper({ state: 'confirmed', confirmed_by_id: 1 }); createWrapper({ state: 'confirmed', confirmedById: 1 });
mockAxios.onGet().replyOnce(500); mockAxios.onGet().replyOnce(500);
...@@ -365,7 +368,7 @@ describe('Vulnerability Header', () => { ...@@ -365,7 +368,7 @@ describe('Vulnerability Header', () => {
it('will set the isLoadingUser property correctly when the user is loading and finished loading', () => { it('will set the isLoadingUser property correctly when the user is loading and finished loading', () => {
const user = createRandomUser(); const user = createRandomUser();
createWrapper({ state: 'confirmed', confirmed_by_id: user.id }); createWrapper({ state: 'confirmed', confirmedById: user.id });
expect(findStatusDescription().props('isLoadingUser')).toBe(true); expect(findStatusDescription().props('isLoadingUser')).toBe(true);
......
...@@ -9,8 +9,8 @@ describe('History Entry', () => { ...@@ -9,8 +9,8 @@ describe('History Entry', () => {
system: true, system: true,
id: 1, id: 1,
note: 'changed vulnerability status to dismissed', note: 'changed vulnerability status to dismissed',
system_note_icon_name: 'cancel', systemNoteIconName: 'cancel',
updated_at: new Date().toISOString(), updatedAt: new Date().toISOString(),
author: { author: {
name: 'author name', name: 'author name',
username: 'author username', username: 'author username',
...@@ -22,8 +22,8 @@ describe('History Entry', () => { ...@@ -22,8 +22,8 @@ describe('History Entry', () => {
id: 2, id: 2,
note: 'some note', note: 'some note',
author: {}, author: {},
current_user: { currentUser: {
can_edit: true, canEdit: true,
}, },
}; };
...@@ -53,8 +53,8 @@ describe('History Entry', () => { ...@@ -53,8 +53,8 @@ describe('History Entry', () => {
expect(eventItem().props()).toMatchObject({ expect(eventItem().props()).toMatchObject({
id: systemNote.id, id: systemNote.id,
author: systemNote.author, author: systemNote.author,
createdAt: systemNote.updated_at, createdAt: systemNote.updatedAt,
iconName: systemNote.system_note_icon_name, iconName: systemNote.systemNoteIconName,
}); });
}); });
......
...@@ -37,9 +37,9 @@ describe('Vulnerability status description component', () => { ...@@ -37,9 +37,9 @@ describe('Vulnerability status description component', () => {
// Automatically create the ${v.state}_at property if it doesn't exist. Otherwise, every test would need to create // Automatically create the ${v.state}_at property if it doesn't exist. Otherwise, every test would need to create
// it manually for the component to mount properly. // it manually for the component to mount properly.
if (vulnerability.state === 'detected') { if (vulnerability.state === 'detected') {
vulnerability.pipeline.created_at = vulnerability.pipeline.created_at || createDate(); vulnerability.pipeline.createdAt = vulnerability.pipeline.createdAt || createDate();
} else { } else {
const propertyName = `${vulnerability.state}_at`; const propertyName = `${vulnerability.state}At`;
vulnerability[propertyName] = vulnerability[propertyName] || createDate(); vulnerability[propertyName] = vulnerability[propertyName] || createDate();
} }
...@@ -59,7 +59,7 @@ describe('Vulnerability status description component', () => { ...@@ -59,7 +59,7 @@ describe('Vulnerability status description component', () => {
${'shows bolded state text'} | ${true} ${'shows bolded state text'} | ${true}
`('$description if isStatusBolded is isStatusBolded', ({ isStatusBolded }) => { `('$description if isStatusBolded is isStatusBolded', ({ isStatusBolded }) => {
createWrapper({ createWrapper({
vulnerability: { state: 'detected', pipeline: { created_at: createDate('2001') } }, vulnerability: { state: 'detected', pipeline: { createdAt: createDate('2001') } },
isStatusBolded, isStatusBolded,
}); });
...@@ -71,7 +71,7 @@ describe('Vulnerability status description component', () => { ...@@ -71,7 +71,7 @@ describe('Vulnerability status description component', () => {
it('uses the pipeline created date when the vulnerability state is "detected"', () => { it('uses the pipeline created date when the vulnerability state is "detected"', () => {
const pipelineDateString = createDate('2001'); const pipelineDateString = createDate('2001');
createWrapper({ createWrapper({
vulnerability: { state: 'detected', pipeline: { created_at: pipelineDateString } }, vulnerability: { state: 'detected', pipeline: { createdAt: pipelineDateString } },
}); });
expect(timeAgo().props('time')).toBe(pipelineDateString); expect(timeAgo().props('time')).toBe(pipelineDateString);
...@@ -85,8 +85,8 @@ describe('Vulnerability status description component', () => { ...@@ -85,8 +85,8 @@ describe('Vulnerability status description component', () => {
createWrapper({ createWrapper({
vulnerability: { vulnerability: {
state, state,
pipeline: { created_at: 'pipeline_created_at' }, pipeline: { createdAt: 'pipeline_created_at' },
[`${state}_at`]: expectedDate, [`${state}At`]: expectedDate,
}, },
}); });
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment