Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
5e5c529ef6
commit
f2ba923aa7
18 changed files with 312 additions and 7 deletions
|
@ -3,10 +3,10 @@ import { GlButton, GlEmptyState, GlLoadingIcon, GlTab } from '@gitlab/ui';
|
|||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
import { TYPE_ISSUE } from '~/graphql_shared/constants';
|
||||
import { fetchPolicies } from '~/lib/graphql';
|
||||
import notesEventHub from '~/notes/event_hub';
|
||||
import getTimelineEvents from './graphql/queries/get_timeline_events.query.graphql';
|
||||
import { displayAndLogError } from './utils';
|
||||
import { timelineTabI18n } from './constants';
|
||||
|
||||
import CreateTimelineEvent from './create_timeline_event.vue';
|
||||
import IncidentTimelineEventsList from './timeline_events_list.vue';
|
||||
|
||||
|
@ -56,7 +56,16 @@ export default {
|
|||
return !this.timelineEventLoading && !this.hasTimelineEvents;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
notesEventHub.$on('comment-promoted-to-timeline-event', this.refreshTimelineEvents);
|
||||
},
|
||||
destroyed() {
|
||||
notesEventHub.$off('comment-promoted-to-timeline-event', this.refreshTimelineEvents);
|
||||
},
|
||||
methods: {
|
||||
refreshTimelineEvents() {
|
||||
this.$apollo.queries.timelineEvents.refetch();
|
||||
},
|
||||
hideEventForm() {
|
||||
this.isEventFormVisible = false;
|
||||
},
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
import { GlTooltipDirective, GlIcon, GlButton, GlDropdownItem } from '@gitlab/ui';
|
||||
import { mapActions, mapGetters } from 'vuex';
|
||||
import { mapActions, mapGetters, mapState } from 'vuex';
|
||||
import Api from '~/api';
|
||||
import resolvedStatusMixin from '~/batch_comments/mixins/resolved_status';
|
||||
import createFlash from '~/flash';
|
||||
|
@ -11,6 +11,7 @@ import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge.
|
|||
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import { splitCamelCase } from '~/lib/utils/text_utility';
|
||||
import ReplyButton from './note_actions/reply_button.vue';
|
||||
import TimelineEventButton from './note_actions/timeline_event_button.vue';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
|
@ -23,6 +24,7 @@ export default {
|
|||
components: {
|
||||
GlIcon,
|
||||
ReplyButton,
|
||||
TimelineEventButton,
|
||||
GlButton,
|
||||
GlDropdownItem,
|
||||
UserAccessRoleBadge,
|
||||
|
@ -133,7 +135,8 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(['getUserDataByProp', 'getNoteableData']),
|
||||
...mapState(['isPromoteCommentToTimelineEventInProgress']),
|
||||
...mapGetters(['getUserDataByProp', 'getNoteableData', 'canUserAddIncidentTimelineEvents']),
|
||||
shouldShowActionsDropdown() {
|
||||
return this.currentUserId && (this.canEdit || this.canReportAsAbuse);
|
||||
},
|
||||
|
@ -199,7 +202,7 @@ export default {
|
|||
},
|
||||
},
|
||||
methods: {
|
||||
...mapActions(['toggleAwardRequest']),
|
||||
...mapActions(['toggleAwardRequest', 'promoteCommentToTimelineEvent']),
|
||||
onEdit() {
|
||||
this.$emit('handleEdit');
|
||||
},
|
||||
|
@ -292,6 +295,12 @@ export default {
|
|||
class="line-resolve-btn note-action-button"
|
||||
@click="onResolve"
|
||||
/>
|
||||
<timeline-event-button
|
||||
v-if="canUserAddIncidentTimelineEvents"
|
||||
:note-id="noteId"
|
||||
:is-promotion-in-progress="isPromoteCommentToTimelineEventInProgress"
|
||||
@click-promote-comment-to-event="promoteCommentToTimelineEvent"
|
||||
/>
|
||||
<emoji-picker
|
||||
v-if="canAwardEmoji"
|
||||
toggle-class="note-action-button note-emoji-button btn-icon btn-default-tertiary"
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<script>
|
||||
import { GlTooltipDirective, GlButton } from '@gitlab/ui';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export default {
|
||||
i18n: {
|
||||
buttonText: __('Add comment to incident timeline'),
|
||||
addError: __('Error promoting the note to timeline event: %{error}'),
|
||||
addGenericError: __('Something went wrong while promoting the note to timeline event.'),
|
||||
},
|
||||
components: {
|
||||
GlButton,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: GlTooltipDirective,
|
||||
},
|
||||
props: {
|
||||
noteId: {
|
||||
type: [String, Number],
|
||||
required: true,
|
||||
},
|
||||
isPromotionInProgress: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
handleButtonClick() {
|
||||
this.$emit('click-promote-comment-to-event', {
|
||||
noteId: this.noteId,
|
||||
addError: this.$options.i18n.addError,
|
||||
addGenericError: this.$options.i18n.addGenericError,
|
||||
});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<span v-gl-tooltip :title="$options.i18n.buttonText">
|
||||
<gl-button
|
||||
category="tertiary"
|
||||
icon="clock"
|
||||
:aria-label="$options.i18n.buttonText"
|
||||
:disabled="isPromotionInProgress"
|
||||
@click="handleButtonClick"
|
||||
/>
|
||||
</span>
|
||||
</template>
|
|
@ -13,6 +13,7 @@ export const MERGED = 'merged';
|
|||
export const ISSUE_NOTEABLE_TYPE = 'Issue';
|
||||
export const EPIC_NOTEABLE_TYPE = 'Epic';
|
||||
export const MERGE_REQUEST_NOTEABLE_TYPE = 'MergeRequest';
|
||||
export const INCIDENT_NOTEABLE_TYPE = 'INCIDENT'; // TODO: check if value can be converted to `Incident`
|
||||
export const UNRESOLVE_NOTE_METHOD_NAME = 'delete';
|
||||
export const RESOLVE_NOTE_METHOD_NAME = 'post';
|
||||
export const DESCRIPTION_TYPE = 'changed the description';
|
||||
|
@ -31,6 +32,7 @@ export const NOTEABLE_TYPE_MAPPING = {
|
|||
Issue: ISSUE_NOTEABLE_TYPE,
|
||||
MergeRequest: MERGE_REQUEST_NOTEABLE_TYPE,
|
||||
Epic: EPIC_NOTEABLE_TYPE,
|
||||
Incident: INCIDENT_NOTEABLE_TYPE,
|
||||
};
|
||||
|
||||
export const DISCUSSION_FILTER_TYPES = {
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
mutation PromoteTimelineEvent($input: TimelineEventPromoteFromNoteInput!) {
|
||||
timelineEventPromoteFromNote(input: $input) {
|
||||
timelineEvent {
|
||||
id
|
||||
}
|
||||
errors
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import Vue from 'vue';
|
||||
import { parseBoolean } from '~/lib/utils/common_utils';
|
||||
import NotesApp from './components/notes_app.vue';
|
||||
import initDiscussionFilters from './discussion_filters';
|
||||
import { store } from './stores';
|
||||
|
@ -39,6 +40,7 @@ export default () => {
|
|||
username: parsedUserData.username,
|
||||
avatar_url: parsedUserData.avatar_path || parsedUserData.avatar_url,
|
||||
path: parsedUserData.path,
|
||||
can_add_timeline_events: parseBoolean(notesDataset.canAddTimelineEvents),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ import createFlash from '~/flash';
|
|||
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { __, sprintf } from '~/locale';
|
||||
import toast from '~/vue_shared/plugins/global_toast';
|
||||
import { confidentialWidget } from '~/sidebar/components/confidential/sidebar_confidentiality_widget.vue';
|
||||
import updateIssueLockMutation from '~/sidebar/components/lock/mutations/update_issue_lock.mutation.graphql';
|
||||
import updateMergeRequestLockMutation from '~/sidebar/components/lock/mutations/update_merge_request_lock.mutation.graphql';
|
||||
|
@ -18,6 +19,12 @@ import sidebarTimeTrackingEventHub from '~/sidebar/event_hub';
|
|||
import TaskList from '~/task_list';
|
||||
import mrWidgetEventHub from '~/vue_merge_request_widget/event_hub';
|
||||
import SidebarStore from '~/sidebar/stores/sidebar_store';
|
||||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||
import { TYPE_NOTE } from '~/graphql_shared/constants';
|
||||
import notesEventHub from '../event_hub';
|
||||
|
||||
import promoteTimelineEvent from '../graphql/promote_timeline_event.mutation.graphql';
|
||||
|
||||
import * as constants from '../constants';
|
||||
import * as types from './mutation_types';
|
||||
import * as utils from './utils';
|
||||
|
@ -226,6 +233,54 @@ export const updateOrCreateNotes = ({ commit, state, getters, dispatch }, notes)
|
|||
});
|
||||
};
|
||||
|
||||
export const promoteCommentToTimelineEvent = (
|
||||
{ commit },
|
||||
{ noteId, addError, addGenericError },
|
||||
) => {
|
||||
commit(types.SET_PROMOTE_COMMENT_TO_TIMELINE_PROGRESS, true); // Set loading state
|
||||
return utils.gqClient
|
||||
.mutate({
|
||||
mutation: promoteTimelineEvent,
|
||||
variables: {
|
||||
input: {
|
||||
noteId: convertToGraphQLId(TYPE_NOTE, noteId),
|
||||
},
|
||||
},
|
||||
})
|
||||
.then(({ data = {} }) => {
|
||||
const errors = data.timelineEventPromoteFromNote?.errors;
|
||||
if (errors.length) {
|
||||
const errorMessage = sprintf(addError, {
|
||||
error: errors.join('. '),
|
||||
});
|
||||
throw new Error(errorMessage);
|
||||
} else {
|
||||
notesEventHub.$emit('comment-promoted-to-timeline-event');
|
||||
toast(__('Comment added to the timeline.'));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
const message = error.message || addGenericError;
|
||||
|
||||
let captureError = false;
|
||||
let errorObj = null;
|
||||
|
||||
if (message === addGenericError) {
|
||||
captureError = true;
|
||||
errorObj = error;
|
||||
}
|
||||
|
||||
createFlash({
|
||||
message,
|
||||
captureError,
|
||||
error: errorObj,
|
||||
});
|
||||
})
|
||||
.finally(() => {
|
||||
commit(types.SET_PROMOTE_COMMENT_TO_TIMELINE_PROGRESS, false); // Revert loading state
|
||||
});
|
||||
};
|
||||
|
||||
export const replyToDiscussion = (
|
||||
{ commit, state, getters, dispatch },
|
||||
{ endpoint, data: reply },
|
||||
|
|
|
@ -93,6 +93,13 @@ export const getUserDataByProp = (state) => (prop) => state.userData && state.us
|
|||
|
||||
export const descriptionVersions = (state) => state.descriptionVersions;
|
||||
|
||||
export const canUserAddIncidentTimelineEvents = (state) => {
|
||||
return (
|
||||
state.userData.can_add_timeline_events &&
|
||||
state.noteableData.type === constants.NOTEABLE_TYPE_MAPPING.Incident
|
||||
);
|
||||
};
|
||||
|
||||
export const notesById = (state) =>
|
||||
state.discussions.reduce((acc, note) => {
|
||||
note.notes.every((n) => Object.assign(acc, { [n.id]: n }));
|
||||
|
|
|
@ -30,6 +30,7 @@ export default () => ({
|
|||
isNotesFetched: false,
|
||||
isLoading: true,
|
||||
isLoadingDescriptionVersion: false,
|
||||
isPromoteCommentToTimelineEventInProgress: false,
|
||||
|
||||
// holds endpoints and permissions provided through haml
|
||||
notesData: {
|
||||
|
|
|
@ -57,3 +57,6 @@ export const RECEIVE_DESCRIPTION_VERSION_ERROR = 'RECEIVE_DESCRIPTION_VERSION_ER
|
|||
export const REQUEST_DELETE_DESCRIPTION_VERSION = 'REQUEST_DELETE_DESCRIPTION_VERSION';
|
||||
export const RECEIVE_DELETE_DESCRIPTION_VERSION = 'RECEIVE_DELETE_DESCRIPTION_VERSION';
|
||||
export const RECEIVE_DELETE_DESCRIPTION_VERSION_ERROR = 'RECEIVE_DELETE_DESCRIPTION_VERSION_ERROR';
|
||||
|
||||
// Incidents
|
||||
export const SET_PROMOTE_COMMENT_TO_TIMELINE_PROGRESS = 'SET_PROMOTE_COMMENT_TO_TIMELINE_PROGRESS';
|
||||
|
|
|
@ -425,4 +425,7 @@ export default {
|
|||
[types.SET_DONE_FETCHING_BATCH_DISCUSSIONS](state, value) {
|
||||
state.doneFetchingBatchDiscussions = value;
|
||||
},
|
||||
[types.SET_PROMOTE_COMMENT_TO_TIMELINE_PROGRESS](state, value) {
|
||||
state.isPromoteCommentToTimelineEventInProgress = value;
|
||||
},
|
||||
};
|
||||
|
|
|
@ -81,6 +81,7 @@ export const ROUGE_TO_HLJS_LANGUAGE_MAP = {
|
|||
protobuf: 'protobuf',
|
||||
puppet: 'puppet',
|
||||
python: 'python',
|
||||
python3: 'python',
|
||||
q: 'q',
|
||||
qml: 'qml',
|
||||
r: 'r',
|
||||
|
|
|
@ -42,7 +42,7 @@ export default {
|
|||
return {
|
||||
languageDefinition: null,
|
||||
content: this.blob.rawTextBlob,
|
||||
language: ROUGE_TO_HLJS_LANGUAGE_MAP[this.blob.language],
|
||||
language: ROUGE_TO_HLJS_LANGUAGE_MAP[this.blob.language?.toLowerCase()],
|
||||
hljs: null,
|
||||
firstChunk: null,
|
||||
chunks: {},
|
||||
|
@ -62,7 +62,7 @@ export default {
|
|||
const supportedLanguages = Object.keys(languageLoader);
|
||||
return (
|
||||
!supportedLanguages.includes(this.language) &&
|
||||
!supportedLanguages.includes(this.blob.language)
|
||||
!supportedLanguages.includes(this.blob.language?.toLowerCase())
|
||||
);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -7,4 +7,5 @@
|
|||
noteable_data: serialize_issuable(@issue, with_blocking_issues: true),
|
||||
noteable_type: 'Issue',
|
||||
target_type: 'issue',
|
||||
current_user_data: UserSerializer.new.represent(current_user, {only_path: true}, CurrentUserEntity).to_json } }
|
||||
current_user_data: UserSerializer.new.represent(current_user, {only_path: true}, CurrentUserEntity).to_json,
|
||||
can_add_timeline_events: "#{can?(current_user, :admin_incident_management_timeline_event, @issue)}" } }
|
||||
|
|
|
@ -2227,6 +2227,9 @@ msgstr ""
|
|||
msgid "Add comment to design"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add comment to incident timeline"
|
||||
msgstr ""
|
||||
|
||||
msgid "Add comment..."
|
||||
msgstr ""
|
||||
|
||||
|
@ -9451,6 +9454,9 @@ msgstr ""
|
|||
msgid "Comment '%{label}' position"
|
||||
msgstr ""
|
||||
|
||||
msgid "Comment added to the timeline."
|
||||
msgstr ""
|
||||
|
||||
msgid "Comment form position"
|
||||
msgstr ""
|
||||
|
||||
|
@ -15253,6 +15259,9 @@ msgstr ""
|
|||
msgid "Error parsing CSV file. Please make sure it has"
|
||||
msgstr ""
|
||||
|
||||
msgid "Error promoting the note to timeline event: %{error}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Error rendering Markdown preview"
|
||||
msgstr ""
|
||||
|
||||
|
@ -37002,6 +37011,9 @@ msgstr ""
|
|||
msgid "Something went wrong while promoting the issue to an epic. Please try again."
|
||||
msgstr ""
|
||||
|
||||
msgid "Something went wrong while promoting the note to timeline event."
|
||||
msgstr ""
|
||||
|
||||
msgid "Something went wrong while reopening a requirement."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
import { GlButton } from '@gitlab/ui';
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import TimelineEventButton from '~/notes/components/note_actions/timeline_event_button.vue';
|
||||
|
||||
const emitData = {
|
||||
noteId: '1',
|
||||
addError: 'Error promoting the note to timeline event: %{error}',
|
||||
addGenericError: 'Something went wrong while promoting the note to timeline event.',
|
||||
};
|
||||
|
||||
describe('NoteTimelineEventButton', () => {
|
||||
let wrapper;
|
||||
|
||||
beforeEach(() => {
|
||||
wrapper = shallowMount(TimelineEventButton, {
|
||||
propsData: {
|
||||
noteId: '1',
|
||||
isPromotionInProgress: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
const findTimelineButton = () => wrapper.findComponent(GlButton);
|
||||
|
||||
it('emits click-promote-comment-to-event', async () => {
|
||||
findTimelineButton().vm.$emit('click');
|
||||
|
||||
expect(wrapper.emitted('click-promote-comment-to-event')).toEqual([[emitData]]);
|
||||
expect(findTimelineButton().props('disabled')).toEqual(true);
|
||||
});
|
||||
});
|
|
@ -4,6 +4,7 @@ import testAction from 'helpers/vuex_action_helper';
|
|||
import { TEST_HOST } from 'spec/test_constants';
|
||||
import Api from '~/api';
|
||||
import createFlash from '~/flash';
|
||||
import toast from '~/vue_shared/plugins/global_toast';
|
||||
import { EVENT_ISSUABLE_VUE_APP_CHANGE } from '~/issuable/constants';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import * as notesConstants from '~/notes/constants';
|
||||
|
@ -14,7 +15,9 @@ import mutations from '~/notes/stores/mutations';
|
|||
import * as utils from '~/notes/stores/utils';
|
||||
import updateIssueLockMutation from '~/sidebar/components/lock/mutations/update_issue_lock.mutation.graphql';
|
||||
import updateMergeRequestLockMutation from '~/sidebar/components/lock/mutations/update_merge_request_lock.mutation.graphql';
|
||||
import promoteTimelineEvent from '~/notes/graphql/promote_timeline_event.mutation.graphql';
|
||||
import mrWidgetEventHub from '~/vue_merge_request_widget/event_hub';
|
||||
import notesEventHub from '~/notes/event_hub';
|
||||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import { resetStore } from '../helpers';
|
||||
import {
|
||||
|
@ -38,6 +41,8 @@ jest.mock('~/flash', () => {
|
|||
return flash;
|
||||
});
|
||||
|
||||
jest.mock('~/vue_shared/plugins/global_toast');
|
||||
|
||||
describe('Actions Notes Store', () => {
|
||||
let commit;
|
||||
let dispatch;
|
||||
|
@ -1324,6 +1329,102 @@ describe('Actions Notes Store', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('promoteCommentToTimelineEvent', () => {
|
||||
const actionArgs = {
|
||||
noteId: '1',
|
||||
addError: 'addError: Create error',
|
||||
addGenericError: 'addGenericError',
|
||||
};
|
||||
const commitSpy = jest.fn();
|
||||
|
||||
describe('for successful request', () => {
|
||||
const timelineEventSuccessResponse = {
|
||||
data: {
|
||||
timelineEventPromoteFromNote: {
|
||||
timelineEvent: {
|
||||
id: 'gid://gitlab/IncidentManagement::TimelineEvent/19',
|
||||
},
|
||||
errors: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.spyOn(utils.gqClient, 'mutate').mockResolvedValue(timelineEventSuccessResponse);
|
||||
});
|
||||
|
||||
it('calls gqClient mutation with the correct values', () => {
|
||||
actions.promoteCommentToTimelineEvent({ commit: () => {} }, actionArgs);
|
||||
|
||||
expect(utils.gqClient.mutate).toHaveBeenCalledTimes(1);
|
||||
expect(utils.gqClient.mutate).toHaveBeenCalledWith({
|
||||
mutation: promoteTimelineEvent,
|
||||
variables: {
|
||||
input: {
|
||||
noteId: 'gid://gitlab/Note/1',
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('returns success response', () => {
|
||||
jest.spyOn(notesEventHub, '$emit').mockImplementation(() => {});
|
||||
|
||||
return actions.promoteCommentToTimelineEvent({ commit: commitSpy }, actionArgs).then(() => {
|
||||
expect(notesEventHub.$emit).toHaveBeenLastCalledWith(
|
||||
'comment-promoted-to-timeline-event',
|
||||
);
|
||||
expect(toast).toHaveBeenCalledWith('Comment added to the timeline.');
|
||||
expect(commitSpy).toHaveBeenCalledWith(
|
||||
mutationTypes.SET_PROMOTE_COMMENT_TO_TIMELINE_PROGRESS,
|
||||
false,
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('for failing request', () => {
|
||||
const errorResponse = {
|
||||
data: {
|
||||
timelineEventPromoteFromNote: {
|
||||
timelineEvent: null,
|
||||
errors: ['Create error'],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
it.each`
|
||||
mockReject | message | captureError | error
|
||||
${true} | ${'addGenericError'} | ${true} | ${new Error()}
|
||||
${false} | ${'addError: Create error'} | ${false} | ${null}
|
||||
`(
|
||||
'should show an error when submission fails',
|
||||
({ mockReject, message, captureError, error }) => {
|
||||
const expectedAlertArgs = {
|
||||
captureError,
|
||||
error,
|
||||
message,
|
||||
};
|
||||
if (mockReject) {
|
||||
jest.spyOn(utils.gqClient, 'mutate').mockRejectedValueOnce(new Error());
|
||||
} else {
|
||||
jest.spyOn(utils.gqClient, 'mutate').mockResolvedValue(errorResponse);
|
||||
}
|
||||
|
||||
return actions
|
||||
.promoteCommentToTimelineEvent({ commit: commitSpy }, actionArgs)
|
||||
.then(() => {
|
||||
expect(createFlash).toHaveBeenCalledWith(expectedAlertArgs);
|
||||
expect(commitSpy).toHaveBeenCalledWith(
|
||||
mutationTypes.SET_PROMOTE_COMMENT_TO_TIMELINE_PROGRESS,
|
||||
false,
|
||||
);
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('setFetchingState', () => {
|
||||
it('commits SET_NOTES_FETCHING_STATE', () => {
|
||||
return testAction(
|
||||
|
|
|
@ -110,6 +110,13 @@ describe('Source Viewer component', () => {
|
|||
expect(hljs.registerLanguage).toHaveBeenCalledWith('json', languageDefinition.default);
|
||||
});
|
||||
|
||||
it('correctly maps languages starting with uppercase', async () => {
|
||||
await createComponent({ language: 'Python3' });
|
||||
const languageDefinition = await import(`highlight.js/lib/languages/python`);
|
||||
|
||||
expect(hljs.registerLanguage).toHaveBeenCalledWith('python', languageDefinition.default);
|
||||
});
|
||||
|
||||
it('highlights the first chunk', () => {
|
||||
expect(hljs.highlight).toHaveBeenCalledWith(chunk1.trim(), { language: mappedLanguage });
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue