2022-01-26 12:08:38 +05:30
import { nextTick } from 'vue' ;
2022-11-25 23:54:43 +05:30
import { GlAlert , GlButton , GlFormInput , GlFormGroup } from '@gitlab/ui' ;
2022-01-26 12:08:38 +05:30
import { mount , shallowMount } from '@vue/test-utils' ;
2021-06-08 01:23:25 +05:30
import axios from 'axios' ;
import MockAdapter from 'axios-mock-adapter' ;
2021-09-04 01:27:46 +05:30
import { mockTracking } from 'helpers/tracking_helper' ;
2021-04-29 21:17:54 +05:30
import { extendedWrapper } from 'helpers/vue_test_utils_helper' ;
import WikiForm from '~/pages/shared/wikis/components/wiki_form.vue' ;
2022-11-25 23:54:43 +05:30
import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue' ;
2021-09-04 01:27:46 +05:30
import {
CONTENT _EDITOR _LOADED _ACTION ,
SAVED _USING _CONTENT _EDITOR _ACTION ,
2021-12-11 22:18:48 +05:30
WIKI _CONTENT _EDITOR _TRACKING _LABEL ,
WIKI _FORMAT _LABEL ,
WIKI _FORMAT _UPDATED _ACTION ,
2021-09-04 01:27:46 +05:30
} from '~/pages/shared/wikis/constants' ;
2021-10-27 15:23:28 +05:30
jest . mock ( '~/emoji' ) ;
2021-04-29 21:17:54 +05:30
describe ( 'WikiForm' , ( ) => {
let wrapper ;
2021-06-08 01:23:25 +05:30
let mock ;
2021-09-04 01:27:46 +05:30
let trackingSpy ;
2021-04-29 21:17:54 +05:30
const findForm = ( ) => wrapper . find ( 'form' ) ;
const findTitle = ( ) => wrapper . find ( '#wiki_title' ) ;
const findFormat = ( ) => wrapper . find ( '#wiki_format' ) ;
const findMessage = ( ) => wrapper . find ( '#wiki_message' ) ;
2022-11-25 23:54:43 +05:30
const findMarkdownEditor = ( ) => wrapper . findComponent ( MarkdownEditor ) ;
2021-04-29 21:17:54 +05:30
const findSubmitButton = ( ) => wrapper . findByTestId ( 'wiki-submit-button' ) ;
2022-03-02 08:16:31 +05:30
const findCancelButton = ( ) => wrapper . findByTestId ( 'wiki-cancel-button' ) ;
const findTitleHelpLink = ( ) => wrapper . findByText ( 'Learn more.' ) ;
2021-04-29 21:17:54 +05:30
const findMarkdownHelpLink = ( ) => wrapper . findByTestId ( 'wiki-markdown-help-link' ) ;
2021-06-08 01:23:25 +05:30
const setFormat = ( value ) => {
const format = findFormat ( ) ;
2022-03-02 08:16:31 +05:30
return format . find ( ` option[value= ${ value } ] ` ) . setSelected ( ) ;
2021-06-08 01:23:25 +05:30
} ;
2022-04-04 11:22:00 +05:30
const triggerFormSubmit = async ( ) => {
2022-03-02 08:16:31 +05:30
findForm ( ) . element . dispatchEvent ( new Event ( 'submit' ) ) ;
2022-04-04 11:22:00 +05:30
await nextTick ( ) ;
2022-03-02 08:16:31 +05:30
} ;
2021-06-08 01:23:25 +05:30
2021-04-29 21:17:54 +05:30
const pageInfoNew = {
persisted : false ,
uploadsPath : '/project/path/-/wikis/attachments' ,
wikiPath : '/project/path/-/wikis' ,
helpPath : '/help/user/project/wiki/index' ,
markdownHelpPath : '/help/user/markdown' ,
markdownPreviewPath : '/project/path/-/wikis/.md/preview-markdown' ,
createPath : '/project/path/-/wikis/new' ,
} ;
const pageInfoPersisted = {
... pageInfoNew ,
persisted : true ,
title : 'My page' ,
2021-09-04 01:27:46 +05:30
content : ' My page content ' ,
2021-04-29 21:17:54 +05:30
format : 'markdown' ,
path : '/project/path/-/wikis/home' ,
} ;
2022-01-26 12:08:38 +05:30
const formatOptions = {
Markdown : 'markdown' ,
RDoc : 'rdoc' ,
AsciiDoc : 'asciidoc' ,
Org : 'org' ,
} ;
2022-03-02 08:16:31 +05:30
function createWrapper ( {
mountFn = shallowMount ,
2022-01-26 12:08:38 +05:30
persisted = false ,
2022-03-02 08:16:31 +05:30
pageInfo ,
glFeatures = { wikiSwitchBetweenContentEditorRawMarkdown : false } ,
} = { } ) {
2022-01-26 12:08:38 +05:30
wrapper = extendedWrapper (
2022-03-02 08:16:31 +05:30
mountFn ( WikiForm , {
2022-01-26 12:08:38 +05:30
provide : {
formatOptions ,
glFeatures ,
pageInfo : {
... ( persisted ? pageInfoPersisted : pageInfoNew ) ,
... pageInfo ,
} ,
} ,
stubs : {
2022-03-02 08:16:31 +05:30
GlAlert ,
GlButton ,
2022-08-13 15:12:31 +05:30
GlFormInput ,
GlFormGroup ,
2022-01-26 12:08:38 +05:30
} ,
} ) ,
) ;
2022-03-02 08:16:31 +05:30
}
2022-01-26 12:08:38 +05:30
2021-06-08 01:23:25 +05:30
beforeEach ( ( ) => {
2021-09-04 01:27:46 +05:30
trackingSpy = mockTracking ( undefined , null , jest . spyOn ) ;
2021-06-08 01:23:25 +05:30
mock = new MockAdapter ( axios ) ;
} ) ;
2021-04-29 21:17:54 +05:30
afterEach ( ( ) => {
2021-06-08 01:23:25 +05:30
mock . restore ( ) ;
2021-04-29 21:17:54 +05:30
wrapper . destroy ( ) ;
wrapper = null ;
} ) ;
2022-11-25 23:54:43 +05:30
it ( 'displays markdown editor' , ( ) => {
createWrapper ( { persisted : true } ) ;
expect ( findMarkdownEditor ( ) . props ( ) ) . toEqual (
expect . objectContaining ( {
value : pageInfoPersisted . content ,
renderMarkdownPath : pageInfoPersisted . markdownPreviewPath ,
markdownDocsPath : pageInfoPersisted . markdownHelpPath ,
uploadsPath : pageInfoPersisted . uploadsPath ,
2023-01-13 00:05:48 +05:30
autofocus : pageInfoPersisted . persisted ,
2022-11-25 23:54:43 +05:30
formFieldId : 'wiki_content' ,
formFieldName : 'wiki[content]' ,
} ) ,
) ;
} ) ;
2021-04-29 21:17:54 +05:30
it . each `
title | persisted | message
$ { 'my page' } | $ { false } | $ { 'Create my page' }
$ { 'my-page' } | $ { false } | $ { 'Create my page' }
$ { 'somedir/my-page' } | $ { false } | $ { 'Create somedir/my page' }
$ { 'my-page' } | $ { true } | $ { 'Update my page' }
` (
'updates the commit message to $message when title is $title and persisted=$persisted' ,
async ( { title , message , persisted } ) => {
2022-08-13 15:12:31 +05:30
createWrapper ( { persisted , mountFn : mount } ) ;
2021-04-29 21:17:54 +05:30
2022-03-02 08:16:31 +05:30
await findTitle ( ) . setValue ( title ) ;
2021-04-29 21:17:54 +05:30
expect ( findMessage ( ) . element . value ) . toBe ( message ) ;
} ,
) ;
it ( 'sets the commit message to "Update My page" when the page first loads when persisted' , async ( ) => {
2022-08-13 15:12:31 +05:30
createWrapper ( { persisted : true , mountFn : mount } ) ;
2021-04-29 21:17:54 +05:30
2022-03-02 08:16:31 +05:30
await nextTick ( ) ;
2021-04-29 21:17:54 +05:30
expect ( findMessage ( ) . element . value ) . toBe ( 'Update My page' ) ;
} ) ;
2021-09-04 01:27:46 +05:30
it ( 'does not trim page content by default' , ( ) => {
2022-03-02 08:16:31 +05:30
createWrapper ( { persisted : true } ) ;
2021-09-04 01:27:46 +05:30
2022-11-25 23:54:43 +05:30
expect ( findMarkdownEditor ( ) . props ( ) . value ) . toBe ( ' My page content ' ) ;
2021-09-04 01:27:46 +05:30
} ) ;
2022-05-07 20:08:51 +05:30
it . each `
format | enabled | action
$ { 'markdown' } | $ { true } | $ { 'displays' }
$ { 'rdoc' } | $ { false } | $ { 'hides' }
$ { 'asciidoc' } | $ { false } | $ { 'hides' }
$ { 'org' } | $ { false } | $ { 'hides' }
` (' $ action preview in the markdown field when format is $ format', async ({ format, enabled }) => {
2022-08-13 15:12:31 +05:30
createWrapper ( { mountFn : mount } ) ;
2022-05-07 20:08:51 +05:30
await setFormat ( format ) ;
2022-11-25 23:54:43 +05:30
nextTick ( ) ;
expect ( findMarkdownEditor ( ) . props ( 'enablePreview' ) ) . toBe ( enabled ) ;
2022-05-07 20:08:51 +05:30
} ) ;
2021-04-29 21:17:54 +05:30
it . each `
value | text
$ { 'markdown' } | $ { '[Link Title](page-slug)' }
$ { 'rdoc' } | $ { '{Link title}[link:page-slug]' }
$ { 'asciidoc' } | $ { 'link:page-slug[Link title]' }
$ { 'org' } | $ { '[[page-slug]]' }
` ('updates the link help message when format= $ value is selected', async ({ value, text }) => {
2022-03-02 08:16:31 +05:30
createWrapper ( { mountFn : mount } ) ;
2021-04-29 21:17:54 +05:30
2022-03-02 08:16:31 +05:30
await setFormat ( value ) ;
2021-04-29 21:17:54 +05:30
expect ( wrapper . text ( ) ) . toContain ( text ) ;
} ) ;
it . each `
persisted | titleHelpText | titleHelpLink
$ { true } | $ { 'You can move this page by adding the path to the beginning of the title.' } | $ { '/help/user/project/wiki/index#move-a-wiki-page' }
$ { false } | $ { 'You can specify the full path for the new file. We will automatically create any missing directories.' } | $ { '/help/user/project/wiki/index#create-a-new-wiki-page' }
` (
'shows appropriate title help text and help link for when persisted=$persisted' ,
2022-03-02 08:16:31 +05:30
( { persisted , titleHelpLink , titleHelpText } ) => {
createWrapper ( { persisted } ) ;
2021-04-29 21:17:54 +05:30
expect ( wrapper . text ( ) ) . toContain ( titleHelpText ) ;
2021-12-11 22:18:48 +05:30
expect ( findTitleHelpLink ( ) . attributes ( ) . href ) . toBe ( titleHelpLink ) ;
2021-04-29 21:17:54 +05:30
} ,
) ;
2022-03-02 08:16:31 +05:30
it ( 'shows correct link for wiki specific markdown docs' , ( ) => {
createWrapper ( { mountFn : mount } ) ;
2021-04-29 21:17:54 +05:30
2021-12-11 22:18:48 +05:30
expect ( findMarkdownHelpLink ( ) . attributes ( ) . href ) . toBe (
2021-04-29 21:17:54 +05:30
'/help/user/markdown#wiki-specific-markdown' ,
) ;
} ) ;
describe ( 'when wiki content is updated' , ( ) => {
2022-01-26 12:08:38 +05:30
beforeEach ( async ( ) => {
2022-03-02 08:16:31 +05:30
createWrapper ( { mountFn : mount , persisted : true } ) ;
2021-04-29 21:17:54 +05:30
2022-11-25 23:54:43 +05:30
await findMarkdownEditor ( ) . vm . $emit ( 'input' , ' Lorem ipsum dolar sit! ' ) ;
2021-04-29 21:17:54 +05:30
} ) ;
2021-09-04 01:27:46 +05:30
describe ( 'form submit' , ( ) => {
beforeEach ( async ( ) => {
2022-03-02 08:16:31 +05:30
await triggerFormSubmit ( ) ;
2021-09-04 01:27:46 +05:30
} ) ;
2021-04-29 21:17:54 +05:30
2022-03-02 08:16:31 +05:30
it ( 'triggers wiki format tracking event' , ( ) => {
2021-12-11 22:18:48 +05:30
expect ( trackingSpy ) . toHaveBeenCalledTimes ( 1 ) ;
2021-09-04 01:27:46 +05:30
} ) ;
it ( 'does not trim page content' , ( ) => {
2022-11-25 23:54:43 +05:30
expect ( findMarkdownEditor ( ) . props ( ) . value ) . toBe ( ' Lorem ipsum dolar sit! ' ) ;
2021-09-04 01:27:46 +05:30
} ) ;
2021-04-29 21:17:54 +05:30
} ) ;
} ) ;
describe ( 'submit button state' , ( ) => {
it . each `
title | content | buttonState | disabledAttr
2022-03-02 08:16:31 +05:30
$ { 'something' } | $ { 'something' } | $ { 'enabled' } | $ { false }
$ { '' } | $ { 'something' } | $ { 'disabled' } | $ { true }
$ { 'something' } | $ { '' } | $ { 'disabled' } | $ { true }
$ { '' } | $ { '' } | $ { 'disabled' } | $ { true }
$ { ' ' } | $ { ' ' } | $ { 'disabled' } | $ { true }
2021-04-29 21:17:54 +05:30
` (
"when title='$title', content='$content', then the button is $buttonState'" ,
async ( { title , content , disabledAttr } ) => {
2022-08-13 15:12:31 +05:30
createWrapper ( { mountFn : mount } ) ;
2021-04-29 21:17:54 +05:30
2022-03-02 08:16:31 +05:30
await findTitle ( ) . setValue ( title ) ;
2022-11-25 23:54:43 +05:30
await findMarkdownEditor ( ) . vm . $emit ( 'input' , content ) ;
2021-04-29 21:17:54 +05:30
2022-03-02 08:16:31 +05:30
expect ( findSubmitButton ( ) . props ( ) . disabled ) . toBe ( disabledAttr ) ;
2021-04-29 21:17:54 +05:30
} ,
) ;
it . each `
persisted | buttonLabel
$ { true } | $ { 'Save changes' }
$ { false } | $ { 'Create page' }
` ('when persisted= $ persisted, label is set to $ buttonLabel', ({ persisted, buttonLabel }) => {
2022-03-02 08:16:31 +05:30
createWrapper ( { persisted } ) ;
2021-04-29 21:17:54 +05:30
expect ( findSubmitButton ( ) . text ( ) ) . toBe ( buttonLabel ) ;
} ) ;
} ) ;
describe ( 'cancel button state' , ( ) => {
it . each `
persisted | redirectLink
$ { false } | $ { '/project/path/-/wikis' }
$ { true } | $ { '/project/path/-/wikis/home' }
` (
'when persisted=$persisted, redirects the user to appropriate path' ,
( { persisted , redirectLink } ) => {
2022-03-02 08:16:31 +05:30
createWrapper ( { persisted } ) ;
2021-04-29 21:17:54 +05:30
2021-12-11 22:18:48 +05:30
expect ( findCancelButton ( ) . attributes ( ) . href ) . toBe ( redirectLink ) ;
2021-04-29 21:17:54 +05:30
} ,
) ;
} ) ;
2021-06-08 01:23:25 +05:30
2022-11-25 23:54:43 +05:30
it . each `
format | enabled | action
$ { 'markdown' } | $ { true } | $ { 'enables' }
$ { 'rdoc' } | $ { false } | $ { 'disables' }
$ { 'asciidoc' } | $ { false } | $ { 'disables' }
$ { 'org' } | $ { false } | $ { 'disables' }
` (' $ action content editor when format is $ format', async ({ format, enabled }) => {
createWrapper ( { mountFn : mount } ) ;
2022-01-26 12:08:38 +05:30
2022-11-25 23:54:43 +05:30
setFormat ( format ) ;
2022-01-26 12:08:38 +05:30
2022-11-25 23:54:43 +05:30
await nextTick ( ) ;
2022-01-26 12:08:38 +05:30
2022-11-25 23:54:43 +05:30
expect ( findMarkdownEditor ( ) . props ( ) . enableContentEditor ) . toBe ( enabled ) ;
} ) ;
2022-01-26 12:08:38 +05:30
2022-11-25 23:54:43 +05:30
describe ( 'when markdown editor activates the content editor' , ( ) => {
beforeEach ( async ( ) => {
createWrapper ( { mountFn : mount , persisted : true } ) ;
2022-01-26 12:08:38 +05:30
2022-11-25 23:54:43 +05:30
await findMarkdownEditor ( ) . vm . $emit ( 'contentEditor' ) ;
2022-01-26 12:08:38 +05:30
} ) ;
2022-11-25 23:54:43 +05:30
it ( 'disables the format dropdown' , ( ) => {
expect ( findFormat ( ) . element . getAttribute ( 'disabled' ) ) . toBeDefined ( ) ;
2022-08-13 15:12:31 +05:30
} ) ;
2022-11-25 23:54:43 +05:30
it ( 'sends tracking event when editor loads' , async ( ) => {
expect ( trackingSpy ) . toHaveBeenCalledWith ( undefined , CONTENT _EDITOR _LOADED _ACTION , {
label : WIKI _CONTENT _EDITOR _TRACKING _LABEL ,
2022-08-27 11:52:29 +05:30
} ) ;
2022-01-26 12:08:38 +05:30
} ) ;
2021-06-08 01:23:25 +05:30
2022-11-25 23:54:43 +05:30
describe ( 'when triggering form submit' , ( ) => {
const updatedMarkdown = 'hello **world**' ;
2021-06-08 01:23:25 +05:30
2022-03-02 08:16:31 +05:30
beforeEach ( async ( ) => {
2022-11-25 23:54:43 +05:30
findMarkdownEditor ( ) . vm . $emit ( 'input' , updatedMarkdown ) ;
await triggerFormSubmit ( ) ;
2021-06-08 01:23:25 +05:30
} ) ;
2022-11-25 23:54:43 +05:30
it ( 'triggers tracking events on form submit' , async ( ) => {
expect ( trackingSpy ) . toHaveBeenCalledWith ( undefined , SAVED _USING _CONTENT _EDITOR _ACTION , {
2021-09-04 01:27:46 +05:30
label : WIKI _CONTENT _EDITOR _TRACKING _LABEL ,
} ) ;
2021-06-08 01:23:25 +05:30
2022-11-25 23:54:43 +05:30
expect ( trackingSpy ) . toHaveBeenCalledWith ( undefined , WIKI _FORMAT _UPDATED _ACTION , {
label : WIKI _FORMAT _LABEL ,
extra : {
value : findFormat ( ) . element . value ,
old _format : pageInfoPersisted . format ,
project _path : pageInfoPersisted . path ,
} ,
2022-03-02 08:16:31 +05:30
} ) ;
2021-06-08 01:23:25 +05:30
} ) ;
} ) ;
} ) ;
2021-04-29 21:17:54 +05:30
} ) ;