Commit c2d42932 authored by Ezekiel Kigbo's avatar Ezekiel Kigbo

Merge branch '219418-fix-case' into 'master'

Replace snake case with camel case

See merge request gitlab-org/gitlab!47966
parents 07d3c8ab 0052e342
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,10 @@ import { CancelToken } from 'axios'; ...@@ -5,6 +5,10 @@ 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,
convertObjectPropsToCamelCase,
} 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 +82,7 @@ export default { ...@@ -78,7 +82,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 +90,14 @@ export default { ...@@ -86,14 +90,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 +107,7 @@ export default { ...@@ -103,7 +107,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.
...@@ -133,7 +137,7 @@ export default { ...@@ -133,7 +137,7 @@ export default {
Api.changeVulnerabilityState(this.vulnerability.id, newState) Api.changeVulnerabilityState(this.vulnerability.id, newState)
.then(({ data }) => { .then(({ data }) => {
Object.assign(this.vulnerability, data); Object.assign(this.vulnerability, convertObjectPropsToCamelCase(data));
this.$emit('vulnerability-state-change'); this.$emit('vulnerability-state-change');
}) })
.catch(() => { .catch(() => {
...@@ -151,26 +155,26 @@ export default { ...@@ -151,26 +155,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 +229,7 @@ export default { ...@@ -225,7 +229,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