gitea源码

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. // Copyright 2022 The Gitea Authors. All rights reserved.
  2. // SPDX-License-Identifier: MIT
  3. package template
  4. import (
  5. "net/url"
  6. "testing"
  7. "code.gitea.io/gitea/modules/json"
  8. api "code.gitea.io/gitea/modules/structs"
  9. "github.com/stretchr/testify/assert"
  10. "github.com/stretchr/testify/require"
  11. )
  12. func TestValidate(t *testing.T) {
  13. tests := []struct {
  14. name string
  15. filename string
  16. content string
  17. want *api.IssueTemplate
  18. wantErr string
  19. }{
  20. {
  21. name: "miss name",
  22. content: ``,
  23. wantErr: "'name' is required",
  24. },
  25. {
  26. name: "miss about",
  27. content: `
  28. name: "test"
  29. `,
  30. wantErr: "'about' is required",
  31. },
  32. {
  33. name: "miss body",
  34. content: `
  35. name: "test"
  36. about: "this is about"
  37. `,
  38. wantErr: "'body' is required",
  39. },
  40. {
  41. name: "markdown miss value",
  42. content: `
  43. name: "test"
  44. about: "this is about"
  45. body:
  46. - type: "markdown"
  47. `,
  48. wantErr: "body[0](markdown): 'value' is required",
  49. },
  50. {
  51. name: "markdown invalid value",
  52. content: `
  53. name: "test"
  54. about: "this is about"
  55. body:
  56. - type: "markdown"
  57. attributes:
  58. value: true
  59. `,
  60. wantErr: "body[0](markdown): 'value' should be a string",
  61. },
  62. {
  63. name: "markdown empty value",
  64. content: `
  65. name: "test"
  66. about: "this is about"
  67. body:
  68. - type: "markdown"
  69. attributes:
  70. value: ""
  71. `,
  72. wantErr: "body[0](markdown): 'value' is required",
  73. },
  74. {
  75. name: "textarea invalid id",
  76. content: `
  77. name: "test"
  78. about: "this is about"
  79. body:
  80. - type: "textarea"
  81. id: "?"
  82. `,
  83. wantErr: "body[0](textarea): 'id' should contain only alphanumeric, '-' and '_'",
  84. },
  85. {
  86. name: "textarea miss label",
  87. content: `
  88. name: "test"
  89. about: "this is about"
  90. body:
  91. - type: "textarea"
  92. id: "1"
  93. `,
  94. wantErr: "body[0](textarea): 'label' is required",
  95. },
  96. {
  97. name: "textarea conflict id",
  98. content: `
  99. name: "test"
  100. about: "this is about"
  101. body:
  102. - type: "textarea"
  103. id: "1"
  104. attributes:
  105. label: "a"
  106. - type: "textarea"
  107. id: "1"
  108. attributes:
  109. label: "b"
  110. `,
  111. wantErr: "body[1](textarea): 'id' should be unique",
  112. },
  113. {
  114. name: "textarea invalid description",
  115. content: `
  116. name: "test"
  117. about: "this is about"
  118. body:
  119. - type: "textarea"
  120. id: "1"
  121. attributes:
  122. label: "a"
  123. description: true
  124. `,
  125. wantErr: "body[0](textarea): 'description' should be a string",
  126. },
  127. {
  128. name: "textarea invalid required",
  129. content: `
  130. name: "test"
  131. about: "this is about"
  132. body:
  133. - type: "textarea"
  134. id: "1"
  135. attributes:
  136. label: "a"
  137. validations:
  138. required: "on"
  139. `,
  140. wantErr: "body[0](textarea): 'required' should be a bool",
  141. },
  142. {
  143. name: "input invalid description",
  144. content: `
  145. name: "test"
  146. about: "this is about"
  147. body:
  148. - type: "input"
  149. id: "1"
  150. attributes:
  151. label: "a"
  152. description: true
  153. `,
  154. wantErr: "body[0](input): 'description' should be a string",
  155. },
  156. {
  157. name: "input invalid is_number",
  158. content: `
  159. name: "test"
  160. about: "this is about"
  161. body:
  162. - type: "input"
  163. id: "1"
  164. attributes:
  165. label: "a"
  166. validations:
  167. is_number: "yes"
  168. `,
  169. wantErr: "body[0](input): 'is_number' should be a bool",
  170. },
  171. {
  172. name: "input invalid regex",
  173. content: `
  174. name: "test"
  175. about: "this is about"
  176. body:
  177. - type: "input"
  178. id: "1"
  179. attributes:
  180. label: "a"
  181. validations:
  182. regex: true
  183. `,
  184. wantErr: "body[0](input): 'regex' should be a string",
  185. },
  186. {
  187. name: "dropdown invalid description",
  188. content: `
  189. name: "test"
  190. about: "this is about"
  191. body:
  192. - type: "dropdown"
  193. id: "1"
  194. attributes:
  195. label: "a"
  196. description: true
  197. `,
  198. wantErr: "body[0](dropdown): 'description' should be a string",
  199. },
  200. {
  201. name: "dropdown invalid multiple",
  202. content: `
  203. name: "test"
  204. about: "this is about"
  205. body:
  206. - type: "dropdown"
  207. id: "1"
  208. attributes:
  209. label: "a"
  210. multiple: "on"
  211. `,
  212. wantErr: "body[0](dropdown): 'multiple' should be a bool",
  213. },
  214. {
  215. name: "dropdown invalid list",
  216. content: `
  217. name: "test"
  218. about: "this is about"
  219. body:
  220. - type: "dropdown"
  221. id: "1"
  222. attributes:
  223. label: "a"
  224. list: "on"
  225. `,
  226. wantErr: "body[0](dropdown): 'list' should be a bool",
  227. },
  228. {
  229. name: "checkboxes invalid description",
  230. content: `
  231. name: "test"
  232. about: "this is about"
  233. body:
  234. - type: "checkboxes"
  235. id: "1"
  236. attributes:
  237. label: "a"
  238. description: true
  239. `,
  240. wantErr: "body[0](checkboxes): 'description' should be a string",
  241. },
  242. {
  243. name: "invalid type",
  244. content: `
  245. name: "test"
  246. about: "this is about"
  247. body:
  248. - type: "video"
  249. id: "1"
  250. attributes:
  251. label: "a"
  252. `,
  253. wantErr: "body[0](video): unknown type",
  254. },
  255. {
  256. name: "dropdown miss options",
  257. content: `
  258. name: "test"
  259. about: "this is about"
  260. body:
  261. - type: "dropdown"
  262. id: "1"
  263. attributes:
  264. label: "a"
  265. `,
  266. wantErr: "body[0](dropdown): 'options' is required and should be a array",
  267. },
  268. {
  269. name: "dropdown invalid options",
  270. content: `
  271. name: "test"
  272. about: "this is about"
  273. body:
  274. - type: "dropdown"
  275. id: "1"
  276. attributes:
  277. label: "a"
  278. options:
  279. - "a"
  280. - true
  281. `,
  282. wantErr: "body[0](dropdown), option[1]: should be a string",
  283. },
  284. {
  285. name: "checkboxes invalid options",
  286. content: `
  287. name: "test"
  288. about: "this is about"
  289. body:
  290. - type: "checkboxes"
  291. id: "1"
  292. attributes:
  293. label: "a"
  294. options:
  295. - "a"
  296. - true
  297. `,
  298. wantErr: "body[0](checkboxes), option[0]: should be a dictionary",
  299. },
  300. {
  301. name: "checkboxes option miss label",
  302. content: `
  303. name: "test"
  304. about: "this is about"
  305. body:
  306. - type: "checkboxes"
  307. id: "1"
  308. attributes:
  309. label: "a"
  310. options:
  311. - required: true
  312. `,
  313. wantErr: "body[0](checkboxes), option[0]: 'label' is required and should be a string",
  314. },
  315. {
  316. name: "checkboxes option invalid required",
  317. content: `
  318. name: "test"
  319. about: "this is about"
  320. body:
  321. - type: "checkboxes"
  322. id: "1"
  323. attributes:
  324. label: "a"
  325. options:
  326. - label: "a"
  327. required: "on"
  328. `,
  329. wantErr: "body[0](checkboxes), option[0]: 'required' should be a bool",
  330. },
  331. {
  332. name: "field is required but hidden",
  333. content: `
  334. name: "test"
  335. about: "this is about"
  336. body:
  337. - type: "input"
  338. id: "1"
  339. attributes:
  340. label: "a"
  341. validations:
  342. required: true
  343. visible: [content]
  344. `,
  345. wantErr: "body[0](input): can not require a hidden field",
  346. },
  347. {
  348. name: "checkboxes is required but hidden",
  349. content: `
  350. name: "test"
  351. about: "this is about"
  352. body:
  353. - type: checkboxes
  354. id: "1"
  355. attributes:
  356. label: Label of checkboxes
  357. description: Description of checkboxes
  358. options:
  359. - label: Option 1
  360. required: false
  361. - label: Required and hidden
  362. required: true
  363. visible: [content]
  364. `,
  365. wantErr: "body[0](checkboxes), option[1]: can not require a hidden checkbox",
  366. },
  367. {
  368. name: "dropdown default is not an integer",
  369. content: `
  370. name: "test"
  371. about: "this is about"
  372. body:
  373. - type: dropdown
  374. id: "1"
  375. attributes:
  376. label: Label of dropdown
  377. description: Description of dropdown
  378. multiple: true
  379. options:
  380. - Option 1 of dropdown
  381. - Option 2 of dropdown
  382. - Option 3 of dropdown
  383. default: "def"
  384. validations:
  385. required: true
  386. `,
  387. wantErr: "body[0](dropdown): 'default' should be an int",
  388. },
  389. {
  390. name: "dropdown default is out of range",
  391. content: `
  392. name: "test"
  393. about: "this is about"
  394. body:
  395. - type: dropdown
  396. id: "1"
  397. attributes:
  398. label: Label of dropdown
  399. description: Description of dropdown
  400. multiple: true
  401. options:
  402. - Option 1 of dropdown
  403. - Option 2 of dropdown
  404. - Option 3 of dropdown
  405. default: 3
  406. validations:
  407. required: true
  408. `,
  409. wantErr: "body[0](dropdown): the value of 'default' is out of range",
  410. },
  411. {
  412. name: "dropdown without default is valid",
  413. content: `
  414. name: "test"
  415. about: "this is about"
  416. body:
  417. - type: dropdown
  418. id: "1"
  419. attributes:
  420. label: Label of dropdown
  421. description: Description of dropdown
  422. multiple: true
  423. options:
  424. - Option 1 of dropdown
  425. - Option 2 of dropdown
  426. - Option 3 of dropdown
  427. validations:
  428. required: true
  429. `,
  430. want: &api.IssueTemplate{
  431. Name: "test",
  432. About: "this is about",
  433. Fields: []*api.IssueFormField{
  434. {
  435. Type: "dropdown",
  436. ID: "1",
  437. Attributes: map[string]any{
  438. "label": "Label of dropdown",
  439. "description": "Description of dropdown",
  440. "multiple": true,
  441. "options": []any{
  442. "Option 1 of dropdown",
  443. "Option 2 of dropdown",
  444. "Option 3 of dropdown",
  445. },
  446. },
  447. Validations: map[string]any{
  448. "required": true,
  449. },
  450. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
  451. },
  452. },
  453. FileName: "test.yaml",
  454. },
  455. wantErr: "",
  456. },
  457. {
  458. name: "valid",
  459. content: `
  460. name: Name
  461. title: Title
  462. about: About
  463. labels: ["label1", "label2"]
  464. assignees: ["user1", "user2"]
  465. ref: Ref
  466. body:
  467. - type: markdown
  468. id: id1
  469. attributes:
  470. value: Value of the markdown
  471. - type: textarea
  472. id: id2
  473. attributes:
  474. label: Label of textarea
  475. description: Description of textarea
  476. placeholder: Placeholder of textarea
  477. value: Value of textarea
  478. render: bash
  479. validations:
  480. required: true
  481. - type: input
  482. id: id3
  483. attributes:
  484. label: Label of input
  485. description: Description of input
  486. placeholder: Placeholder of input
  487. value: Value of input
  488. validations:
  489. required: true
  490. is_number: true
  491. regex: "[a-zA-Z0-9]+"
  492. - type: dropdown
  493. id: id4
  494. attributes:
  495. label: Label of dropdown
  496. description: Description of dropdown
  497. multiple: true
  498. options:
  499. - Option 1 of dropdown
  500. - Option 2 of dropdown
  501. - Option 3 of dropdown
  502. default: 1
  503. validations:
  504. required: true
  505. - type: checkboxes
  506. id: id5
  507. attributes:
  508. label: Label of checkboxes
  509. description: Description of checkboxes
  510. options:
  511. - label: Option 1 of checkboxes
  512. required: true
  513. - label: Option 2 of checkboxes
  514. required: false
  515. - label: Hidden Option 3 of checkboxes
  516. visible: [content]
  517. - label: Required but not submitted
  518. required: true
  519. visible: [form]
  520. `,
  521. want: &api.IssueTemplate{
  522. Name: "Name",
  523. Title: "Title",
  524. About: "About",
  525. Labels: []string{"label1", "label2"},
  526. Assignees: []string{"user1", "user2"},
  527. Ref: "Ref",
  528. Fields: []*api.IssueFormField{
  529. {
  530. Type: "markdown",
  531. ID: "id1",
  532. Attributes: map[string]any{
  533. "value": "Value of the markdown",
  534. },
  535. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
  536. },
  537. {
  538. Type: "textarea",
  539. ID: "id2",
  540. Attributes: map[string]any{
  541. "label": "Label of textarea",
  542. "description": "Description of textarea",
  543. "placeholder": "Placeholder of textarea",
  544. "value": "Value of textarea",
  545. "render": "bash",
  546. },
  547. Validations: map[string]any{
  548. "required": true,
  549. },
  550. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
  551. },
  552. {
  553. Type: "input",
  554. ID: "id3",
  555. Attributes: map[string]any{
  556. "label": "Label of input",
  557. "description": "Description of input",
  558. "placeholder": "Placeholder of input",
  559. "value": "Value of input",
  560. },
  561. Validations: map[string]any{
  562. "required": true,
  563. "is_number": true,
  564. "regex": "[a-zA-Z0-9]+",
  565. },
  566. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
  567. },
  568. {
  569. Type: "dropdown",
  570. ID: "id4",
  571. Attributes: map[string]any{
  572. "label": "Label of dropdown",
  573. "description": "Description of dropdown",
  574. "multiple": true,
  575. "options": []any{
  576. "Option 1 of dropdown",
  577. "Option 2 of dropdown",
  578. "Option 3 of dropdown",
  579. },
  580. "default": 1,
  581. },
  582. Validations: map[string]any{
  583. "required": true,
  584. },
  585. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
  586. },
  587. {
  588. Type: "checkboxes",
  589. ID: "id5",
  590. Attributes: map[string]any{
  591. "label": "Label of checkboxes",
  592. "description": "Description of checkboxes",
  593. "options": []any{
  594. map[string]any{"label": "Option 1 of checkboxes", "required": true},
  595. map[string]any{"label": "Option 2 of checkboxes", "required": false},
  596. map[string]any{"label": "Hidden Option 3 of checkboxes", "visible": []string{"content"}},
  597. map[string]any{"label": "Required but not submitted", "required": true, "visible": []string{"form"}},
  598. },
  599. },
  600. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm, api.IssueFormFieldVisibleContent},
  601. },
  602. },
  603. FileName: "test.yaml",
  604. },
  605. wantErr: "",
  606. },
  607. {
  608. name: "single label",
  609. content: `
  610. name: Name
  611. title: Title
  612. about: About
  613. labels: label1
  614. ref: Ref
  615. body:
  616. - type: markdown
  617. id: id1
  618. attributes:
  619. value: Value of the markdown shown in form
  620. - type: markdown
  621. id: id2
  622. attributes:
  623. value: Value of the markdown shown in created issue
  624. visible: [content]
  625. `,
  626. want: &api.IssueTemplate{
  627. Name: "Name",
  628. Title: "Title",
  629. About: "About",
  630. Labels: []string{"label1"},
  631. Ref: "Ref",
  632. Fields: []*api.IssueFormField{
  633. {
  634. Type: "markdown",
  635. ID: "id1",
  636. Attributes: map[string]any{
  637. "value": "Value of the markdown shown in form",
  638. },
  639. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
  640. },
  641. {
  642. Type: "markdown",
  643. ID: "id2",
  644. Attributes: map[string]any{
  645. "value": "Value of the markdown shown in created issue",
  646. },
  647. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleContent},
  648. },
  649. },
  650. FileName: "test.yaml",
  651. },
  652. wantErr: "",
  653. },
  654. {
  655. name: "comma-delimited labels",
  656. content: `
  657. name: Name
  658. title: Title
  659. about: About
  660. labels: label1,label2,,label3 ,,
  661. ref: Ref
  662. body:
  663. - type: markdown
  664. id: id1
  665. attributes:
  666. value: Value of the markdown
  667. `,
  668. want: &api.IssueTemplate{
  669. Name: "Name",
  670. Title: "Title",
  671. About: "About",
  672. Labels: []string{"label1", "label2", "label3"},
  673. Ref: "Ref",
  674. Fields: []*api.IssueFormField{
  675. {
  676. Type: "markdown",
  677. ID: "id1",
  678. Attributes: map[string]any{
  679. "value": "Value of the markdown",
  680. },
  681. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
  682. },
  683. },
  684. FileName: "test.yaml",
  685. },
  686. wantErr: "",
  687. },
  688. {
  689. name: "empty string as labels",
  690. content: `
  691. name: Name
  692. title: Title
  693. about: About
  694. labels: ''
  695. ref: Ref
  696. body:
  697. - type: markdown
  698. id: id1
  699. attributes:
  700. value: Value of the markdown
  701. `,
  702. want: &api.IssueTemplate{
  703. Name: "Name",
  704. Title: "Title",
  705. About: "About",
  706. Labels: nil,
  707. Ref: "Ref",
  708. Fields: []*api.IssueFormField{
  709. {
  710. Type: "markdown",
  711. ID: "id1",
  712. Attributes: map[string]any{
  713. "value": "Value of the markdown",
  714. },
  715. Visible: []api.IssueFormFieldVisible{api.IssueFormFieldVisibleForm},
  716. },
  717. },
  718. FileName: "test.yaml",
  719. },
  720. wantErr: "",
  721. },
  722. {
  723. name: "comma delimited labels in markdown",
  724. filename: "test.md",
  725. content: `---
  726. name: Name
  727. title: Title
  728. about: About
  729. labels: label1,label2,,label3 ,,
  730. ref: Ref
  731. ---
  732. Content
  733. `,
  734. want: &api.IssueTemplate{
  735. Name: "Name",
  736. Title: "Title",
  737. About: "About",
  738. Labels: []string{"label1", "label2", "label3"},
  739. Ref: "Ref",
  740. Fields: nil,
  741. Content: "Content\n",
  742. FileName: "test.md",
  743. },
  744. wantErr: "",
  745. },
  746. }
  747. for _, tt := range tests {
  748. t.Run(tt.name, func(t *testing.T) {
  749. filename := "test.yaml"
  750. if tt.filename != "" {
  751. filename = tt.filename
  752. }
  753. tmpl, err := unmarshal(filename, []byte(tt.content))
  754. require.NoError(t, err)
  755. if tt.wantErr != "" {
  756. require.EqualError(t, Validate(tmpl), tt.wantErr)
  757. } else {
  758. require.NoError(t, Validate(tmpl))
  759. want, _ := json.Marshal(tt.want)
  760. got, _ := json.Marshal(tmpl)
  761. require.JSONEq(t, string(want), string(got))
  762. }
  763. })
  764. }
  765. }
  766. func TestRenderToMarkdown(t *testing.T) {
  767. type args struct {
  768. template string
  769. values url.Values
  770. }
  771. tests := []struct {
  772. name string
  773. args args
  774. want string
  775. }{
  776. {
  777. name: "normal",
  778. args: args{
  779. template: `
  780. name: Name
  781. title: Title
  782. about: About
  783. labels: ["label1", "label2"]
  784. ref: Ref
  785. body:
  786. - type: markdown
  787. id: id1
  788. attributes:
  789. value: Value of the markdown shown in form
  790. - type: markdown
  791. id: id2
  792. attributes:
  793. value: Value of the markdown shown in created issue
  794. visible: [content]
  795. - type: textarea
  796. id: id3
  797. attributes:
  798. label: Label of textarea
  799. description: Description of textarea
  800. placeholder: Placeholder of textarea
  801. value: Value of textarea
  802. render: bash
  803. validations:
  804. required: true
  805. - type: input
  806. id: id4
  807. attributes:
  808. label: Label of input
  809. description: Description of input
  810. placeholder: Placeholder of input
  811. value: Value of input
  812. hide_label: true
  813. validations:
  814. required: true
  815. is_number: true
  816. regex: "[a-zA-Z0-9]+"
  817. - type: dropdown
  818. id: id5
  819. attributes:
  820. label: Label of dropdown (one line)
  821. description: Description of dropdown
  822. multiple: true
  823. options:
  824. - Option 1 of dropdown
  825. - Option 2 of dropdown
  826. - Option 3 of dropdown
  827. validations:
  828. required: true
  829. - type: dropdown
  830. id: id6
  831. attributes:
  832. label: Label of dropdown (list)
  833. description: Description of dropdown
  834. multiple: true
  835. list: true
  836. options:
  837. - Option 1 of dropdown
  838. - Option 2 of dropdown
  839. - Option 3 of dropdown
  840. validations:
  841. required: true
  842. - type: checkboxes
  843. id: id7
  844. attributes:
  845. label: Label of checkboxes
  846. description: Description of checkboxes
  847. options:
  848. - label: Option 1 of checkboxes
  849. required: true
  850. - label: Option 2 of checkboxes
  851. required: false
  852. - label: Option 3 of checkboxes
  853. required: true
  854. visible: [form]
  855. - label: Hidden Option of checkboxes
  856. visible: [content]
  857. `,
  858. values: map[string][]string{
  859. "form-field-id3": {"Value of id3"},
  860. "form-field-id4": {"Value of id4"},
  861. "form-field-id5": {"0,1"},
  862. "form-field-id6": {"1,2"},
  863. "form-field-id7-0": {"on"},
  864. "form-field-id7-2": {"on"},
  865. },
  866. },
  867. want: `Value of the markdown shown in created issue
  868. ### Label of textarea
  869. ` + "```bash\nValue of id3\n```" + `
  870. Value of id4
  871. ### Label of dropdown (one line)
  872. Option 1 of dropdown, Option 2 of dropdown
  873. ### Label of dropdown (list)
  874. - Option 2 of dropdown
  875. - Option 3 of dropdown
  876. ### Label of checkboxes
  877. - [x] Option 1 of checkboxes
  878. - [ ] Option 2 of checkboxes
  879. - [ ] Hidden Option of checkboxes
  880. `,
  881. },
  882. }
  883. for _, tt := range tests {
  884. t.Run(tt.name, func(t *testing.T) {
  885. template, err := Unmarshal("test.yaml", []byte(tt.args.template))
  886. if err != nil {
  887. t.Fatal(err)
  888. }
  889. if got := RenderToMarkdown(template, tt.args.values); got != tt.want {
  890. assert.Equal(t, tt.want, got)
  891. }
  892. })
  893. }
  894. }
  895. func Test_minQuotes(t *testing.T) {
  896. type args struct {
  897. value string
  898. }
  899. tests := []struct {
  900. name string
  901. args args
  902. want string
  903. }{
  904. {
  905. name: "without quote",
  906. args: args{
  907. value: "Hello\nWorld",
  908. },
  909. want: "```",
  910. },
  911. {
  912. name: "with 1 quote",
  913. args: args{
  914. value: "Hello\nWorld\n`text`\n",
  915. },
  916. want: "```",
  917. },
  918. {
  919. name: "with 3 quotes",
  920. args: args{
  921. value: "Hello\nWorld\n`text`\n```go\ntext\n```\n",
  922. },
  923. want: "````",
  924. },
  925. {
  926. name: "with more quotes",
  927. args: args{
  928. value: "Hello\nWorld\n`text`\n```go\ntext\n```\n``````````bash\ntext\n``````````\n",
  929. },
  930. want: "```````````",
  931. },
  932. {
  933. name: "not leading quotes",
  934. args: args{
  935. value: "Hello\nWorld`text````go\ntext`````````````bash\ntext``````````\n",
  936. },
  937. want: "```",
  938. },
  939. }
  940. for _, tt := range tests {
  941. t.Run(tt.name, func(t *testing.T) {
  942. got := minQuotes(tt.args.value)
  943. assert.Equal(t, tt.want, got)
  944. })
  945. }
  946. }