Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 

1217 linhas
32 KiB

  1. /* eslint-env mocha */
  2. import expect from "expect"
  3. import { Map, fromJS, OrderedMap } from "immutable"
  4. import {
  5. mapToList,
  6. parseSearch,
  7. serializeSearch,
  8. validatePattern,
  9. validateMinLength,
  10. validateMaxLength,
  11. validateDateTime,
  12. validateGuid,
  13. validateNumber,
  14. validateInteger,
  15. validateParam,
  16. validateFile,
  17. validateMaximum,
  18. validateMinimum,
  19. fromJSOrdered,
  20. getAcceptControllingResponse,
  21. createDeepLinkPath,
  22. escapeDeepLinkPath,
  23. getExtensions,
  24. getCommonExtensions,
  25. sanitizeUrl,
  26. extractFileNameFromContentDispositionHeader,
  27. deeplyStripKey,
  28. getSampleSchema
  29. } from "core/utils"
  30. import win from "core/window"
  31. describe("utils", function() {
  32. describe("mapToList", function(){
  33. it("should convert a map to a list, setting `key`", function(){
  34. // With
  35. const aMap = fromJS({
  36. a: {
  37. one: 1,
  38. },
  39. b: {
  40. two: 2,
  41. }
  42. })
  43. // When
  44. const aList = mapToList(aMap, "someKey")
  45. // Then
  46. expect(aList.toJS()).toEqual([
  47. { someKey: "a", one: 1 },
  48. { someKey: "b", two: 2 },
  49. ])
  50. })
  51. it("should flatten an arbitrarily deep map", function(){
  52. // With
  53. const aMap = fromJS({
  54. a: {
  55. one: {
  56. alpha: true
  57. }
  58. },
  59. b: {
  60. two: {
  61. bravo: true
  62. },
  63. three: {
  64. charlie: true
  65. }
  66. }
  67. })
  68. // When
  69. const aList = mapToList(aMap, ["levelA", "levelB"])
  70. // Then
  71. expect(aList.toJS()).toEqual([
  72. { levelA: "a", levelB: "one", alpha: true },
  73. { levelA: "b", levelB: "two", bravo: true },
  74. { levelA: "b", levelB: "three", charlie: true },
  75. ])
  76. })
  77. it("should handle an empty map", function(){
  78. // With
  79. const aMap = fromJS({})
  80. // When
  81. const aList = mapToList(aMap, ["levelA", "levelB"])
  82. // Then
  83. expect(aList.toJS()).toEqual([])
  84. })
  85. })
  86. describe("extractFileNameFromContentDispositionHeader", function(){
  87. it("should extract quoted filename", function(){
  88. let cdHeader = "attachment; filename=\"file name.jpg\""
  89. let expectedResult = "file name.jpg"
  90. expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
  91. })
  92. it("should extract filename", function(){
  93. let cdHeader = "attachment; filename=filename.jpg"
  94. let expectedResult = "filename.jpg"
  95. expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
  96. })
  97. it("should not extract filename and return null", function(){
  98. let cdHeader = "attachment; no file name provided"
  99. let expectedResult = null
  100. expect(extractFileNameFromContentDispositionHeader(cdHeader)).toEqual(expectedResult)
  101. })
  102. })
  103. describe("validateMaximum", function() {
  104. let errorMessage = "Value must be less than Maximum"
  105. it("doesn't return for valid input", function() {
  106. expect(validateMaximum(9, 10)).toBeFalsy()
  107. expect(validateMaximum(19, 20)).toBeFalsy()
  108. })
  109. it("returns a message for invalid input", function() {
  110. expect(validateMaximum(1, 0)).toEqual(errorMessage)
  111. expect(validateMaximum(10, 9)).toEqual(errorMessage)
  112. expect(validateMaximum(20, 19)).toEqual(errorMessage)
  113. })
  114. })
  115. describe("validateMinimum", function() {
  116. let errorMessage = "Value must be greater than Minimum"
  117. it("doesn't return for valid input", function() {
  118. expect(validateMinimum(2, 1)).toBeFalsy()
  119. expect(validateMinimum(20, 10)).toBeFalsy()
  120. })
  121. it("returns a message for invalid input", function() {
  122. expect(validateMinimum(-1, 0)).toEqual(errorMessage)
  123. expect(validateMinimum(1, 2)).toEqual(errorMessage)
  124. expect(validateMinimum(10, 20)).toEqual(errorMessage)
  125. })
  126. })
  127. describe("validateNumber", function() {
  128. let errorMessage = "Value must be a number"
  129. it("doesn't return for whole numbers", function() {
  130. expect(validateNumber(0)).toBeFalsy()
  131. expect(validateNumber(1)).toBeFalsy()
  132. expect(validateNumber(20)).toBeFalsy()
  133. expect(validateNumber(5000000)).toBeFalsy()
  134. expect(validateNumber("1")).toBeFalsy()
  135. expect(validateNumber("2")).toBeFalsy()
  136. expect(validateNumber(-1)).toBeFalsy()
  137. expect(validateNumber(-20)).toBeFalsy()
  138. expect(validateNumber(-5000000)).toBeFalsy()
  139. })
  140. it("doesn't return for negative numbers", function() {
  141. expect(validateNumber(-1)).toBeFalsy()
  142. expect(validateNumber(-20)).toBeFalsy()
  143. expect(validateNumber(-5000000)).toBeFalsy()
  144. })
  145. it("doesn't return for decimal numbers", function() {
  146. expect(validateNumber(1.1)).toBeFalsy()
  147. expect(validateNumber(2.5)).toBeFalsy()
  148. expect(validateNumber(-30.99)).toBeFalsy()
  149. })
  150. it("returns a message for strings", function() {
  151. expect(validateNumber("")).toEqual(errorMessage)
  152. expect(validateNumber(" ")).toEqual(errorMessage)
  153. expect(validateNumber("test")).toEqual(errorMessage)
  154. })
  155. it("returns a message for invalid input", function() {
  156. expect(validateNumber(undefined)).toEqual(errorMessage)
  157. expect(validateNumber(null)).toEqual(errorMessage)
  158. expect(validateNumber({})).toEqual(errorMessage)
  159. expect(validateNumber([])).toEqual(errorMessage)
  160. expect(validateNumber(true)).toEqual(errorMessage)
  161. expect(validateNumber(false)).toEqual(errorMessage)
  162. })
  163. })
  164. describe("validateInteger", function() {
  165. let errorMessage = "Value must be an integer"
  166. it("doesn't return for positive integers", function() {
  167. expect(validateInteger(0)).toBeFalsy()
  168. expect(validateInteger(1)).toBeFalsy()
  169. expect(validateInteger(20)).toBeFalsy()
  170. expect(validateInteger(5000000)).toBeFalsy()
  171. expect(validateInteger("1")).toBeFalsy()
  172. expect(validateInteger("2")).toBeFalsy()
  173. expect(validateInteger(-1)).toBeFalsy()
  174. expect(validateInteger(-20)).toBeFalsy()
  175. expect(validateInteger(-5000000)).toBeFalsy()
  176. })
  177. it("doesn't return for negative integers", function() {
  178. expect(validateInteger(-1)).toBeFalsy()
  179. expect(validateInteger(-20)).toBeFalsy()
  180. expect(validateInteger(-5000000)).toBeFalsy()
  181. })
  182. it("returns a message for decimal values", function() {
  183. expect(validateInteger(1.1)).toEqual(errorMessage)
  184. expect(validateInteger(2.5)).toEqual(errorMessage)
  185. expect(validateInteger(-30.99)).toEqual(errorMessage)
  186. })
  187. it("returns a message for strings", function() {
  188. expect(validateInteger("")).toEqual(errorMessage)
  189. expect(validateInteger(" ")).toEqual(errorMessage)
  190. expect(validateInteger("test")).toEqual(errorMessage)
  191. })
  192. it("returns a message for invalid input", function() {
  193. expect(validateInteger(undefined)).toEqual(errorMessage)
  194. expect(validateInteger(null)).toEqual(errorMessage)
  195. expect(validateInteger({})).toEqual(errorMessage)
  196. expect(validateInteger([])).toEqual(errorMessage)
  197. expect(validateInteger(true)).toEqual(errorMessage)
  198. expect(validateInteger(false)).toEqual(errorMessage)
  199. })
  200. })
  201. describe("validateFile", function() {
  202. let errorMessage = "Value must be a file"
  203. it("validates against objects which are instances of 'File'", function() {
  204. let fileObj = new win.File([], "Test File")
  205. expect(validateFile(fileObj)).toBeFalsy()
  206. expect(validateFile(null)).toBeFalsy()
  207. expect(validateFile(undefined)).toBeFalsy()
  208. expect(validateFile(1)).toEqual(errorMessage)
  209. expect(validateFile("string")).toEqual(errorMessage)
  210. })
  211. })
  212. describe("validateDateTime", function() {
  213. let errorMessage = "Value must be a DateTime"
  214. it("doesn't return for valid dates", function() {
  215. expect(validateDateTime("Mon, 25 Dec 1995 13:30:00 +0430")).toBeFalsy()
  216. })
  217. it("returns a message for invalid input'", function() {
  218. expect(validateDateTime(null)).toEqual(errorMessage)
  219. expect(validateDateTime("string")).toEqual(errorMessage)
  220. })
  221. })
  222. describe("validateGuid", function() {
  223. let errorMessage = "Value must be a Guid"
  224. it("doesn't return for valid guid", function() {
  225. expect(validateGuid("8ce4811e-cec5-4a29-891a-15d1917153c1")).toBeFalsy()
  226. expect(validateGuid("{8ce4811e-cec5-4a29-891a-15d1917153c1}")).toBeFalsy()
  227. expect(validateGuid("8CE4811E-CEC5-4A29-891A-15D1917153C1")).toBeFalsy()
  228. expect(validateGuid("6ffefd8e-a018-e811-bbf9-60f67727d806")).toBeFalsy()
  229. expect(validateGuid("6FFEFD8E-A018-E811-BBF9-60F67727D806")).toBeFalsy()
  230. expect(validateGuid("00000000-0000-0000-0000-000000000000")).toBeFalsy()
  231. })
  232. it("returns a message for invalid input'", function() {
  233. expect(validateGuid(1)).toEqual(errorMessage)
  234. expect(validateGuid("string")).toEqual(errorMessage)
  235. })
  236. })
  237. describe("validateMaxLength", function() {
  238. let errorMessage = "Value must be less than MaxLength"
  239. it("doesn't return for valid guid", function() {
  240. expect(validateMaxLength("a", 1)).toBeFalsy()
  241. expect(validateMaxLength("abc", 5)).toBeFalsy()
  242. })
  243. it("returns a message for invalid input'", function() {
  244. expect(validateMaxLength("abc", 0)).toEqual(errorMessage)
  245. expect(validateMaxLength("abc", 1)).toEqual(errorMessage)
  246. expect(validateMaxLength("abc", 2)).toEqual(errorMessage)
  247. })
  248. })
  249. describe("validateMinLength", function() {
  250. let errorMessage = "Value must be greater than MinLength"
  251. it("doesn't return for valid guid", function() {
  252. expect(validateMinLength("a", 1)).toBeFalsy()
  253. expect(validateMinLength("abc", 2)).toBeFalsy()
  254. })
  255. it("returns a message for invalid input'", function() {
  256. expect(validateMinLength("abc", 5)).toEqual(errorMessage)
  257. expect(validateMinLength("abc", 8)).toEqual(errorMessage)
  258. })
  259. })
  260. describe("validatePattern", function() {
  261. let rxPattern = "^(red|blue)"
  262. let errorMessage = "Value must follow pattern " + rxPattern
  263. it("doesn't return for a match", function() {
  264. expect(validatePattern("red", rxPattern)).toBeFalsy()
  265. expect(validatePattern("blue", rxPattern)).toBeFalsy()
  266. })
  267. it("returns a message for invalid pattern", function() {
  268. expect(validatePattern("pink", rxPattern)).toEqual(errorMessage)
  269. expect(validatePattern("123", rxPattern)).toEqual(errorMessage)
  270. })
  271. it("fails gracefully when an invalid regex value is passed", function() {
  272. expect(() => validatePattern("aValue", "---")).toNotThrow()
  273. expect(() => validatePattern("aValue", 1234)).toNotThrow()
  274. expect(() => validatePattern("aValue", null)).toNotThrow()
  275. expect(() => validatePattern("aValue", [])).toNotThrow()
  276. })
  277. })
  278. describe("validateParam", function() {
  279. let param = null
  280. let result = null
  281. const assertValidateParam = (param, expectedError) => {
  282. // Swagger 2.0 version
  283. result = validateParam( fromJS(param), false )
  284. expect( result ).toEqual( expectedError )
  285. // OAS3 version, using `schema` sub-object
  286. let oas3Param = {
  287. value: param.value,
  288. required: param.required,
  289. schema: {
  290. ...param,
  291. value: undefined,
  292. required: undefined
  293. }
  294. }
  295. result = validateParam( fromJS(oas3Param), false, true )
  296. expect( result ).toEqual( expectedError )
  297. }
  298. const assertValidateOas3Param = (param, expectedError) => {
  299. // for cases where you _only_ want to try OAS3
  300. result = validateParam( fromJS(param), false, true )
  301. expect( result ).toEqual( expectedError )
  302. }
  303. it("should check the isOAS3 flag when validating parameters", function() {
  304. // This should "skip" validation because there is no `schema` property
  305. // and we are telling `validateParam` this is an OAS3 spec
  306. param = fromJS({
  307. value: "",
  308. required: true
  309. })
  310. result = validateParam( param, false, true )
  311. expect( result ).toEqual( [] )
  312. })
  313. it("validates required OAS3 objects", function() {
  314. // valid object
  315. param = {
  316. required: true,
  317. schema: {
  318. type: "object"
  319. },
  320. value: {
  321. abc: 123
  322. }
  323. }
  324. assertValidateOas3Param(param, [])
  325. // valid object-as-string
  326. param = {
  327. required: true,
  328. schema: {
  329. type: "object"
  330. },
  331. value: JSON.stringify({
  332. abc: 123
  333. })
  334. }
  335. assertValidateOas3Param(param, [])
  336. // invalid object-as-string
  337. param = {
  338. required: true,
  339. schema: {
  340. type: "object"
  341. },
  342. value: "{{}"
  343. }
  344. assertValidateOas3Param(param, ["Parameter string value must be valid JSON"])
  345. // missing when required
  346. param = {
  347. required: true,
  348. schema: {
  349. type: "object"
  350. },
  351. }
  352. assertValidateOas3Param(param, ["Required field is not provided"])
  353. })
  354. it("validates optional OAS3 objects", function() {
  355. // valid object
  356. param = {
  357. schema: {
  358. type: "object"
  359. },
  360. value: {
  361. abc: 123
  362. }
  363. }
  364. assertValidateOas3Param(param, [])
  365. // valid object-as-string
  366. param = {
  367. schema: {
  368. type: "object"
  369. },
  370. value: JSON.stringify({
  371. abc: 123
  372. })
  373. }
  374. assertValidateOas3Param(param, [])
  375. // invalid object-as-string
  376. param = {
  377. schema: {
  378. type: "object"
  379. },
  380. value: "{{}"
  381. }
  382. assertValidateOas3Param(param, ["Parameter string value must be valid JSON"])
  383. // missing when not required
  384. param = {
  385. schema: {
  386. type: "object"
  387. },
  388. }
  389. assertValidateOas3Param(param, [])
  390. })
  391. it("validates required strings", function() {
  392. // invalid string
  393. param = {
  394. required: true,
  395. type: "string",
  396. value: ""
  397. }
  398. assertValidateParam(param, ["Required field is not provided"])
  399. // valid string
  400. param = {
  401. required: true,
  402. type: "string",
  403. value: "test string"
  404. }
  405. assertValidateParam(param, [])
  406. // valid string with min and max length
  407. param = {
  408. required: true,
  409. type: "string",
  410. value: "test string",
  411. maxLength: 50,
  412. minLength: 1
  413. }
  414. assertValidateParam(param, [])
  415. })
  416. it("validates required strings with min and max length", function() {
  417. // invalid string with max length
  418. param = {
  419. required: true,
  420. type: "string",
  421. value: "test string",
  422. maxLength: 5
  423. }
  424. assertValidateParam(param, ["Value must be less than MaxLength"])
  425. // invalid string with max length 0
  426. param = {
  427. required: true,
  428. type: "string",
  429. value: "test string",
  430. maxLength: 0
  431. }
  432. assertValidateParam(param, ["Value must be less than MaxLength"])
  433. // invalid string with min length
  434. param = {
  435. required: true,
  436. type: "string",
  437. value: "test string",
  438. minLength: 50
  439. }
  440. assertValidateParam(param, ["Value must be greater than MinLength"])
  441. })
  442. it("validates optional strings", function() {
  443. // valid (empty) string
  444. param = {
  445. required: false,
  446. type: "string",
  447. value: ""
  448. }
  449. assertValidateParam(param, [])
  450. // valid string
  451. param = {
  452. required: false,
  453. type: "string",
  454. value: "test"
  455. }
  456. assertValidateParam(param, [])
  457. })
  458. it("validates required files", function() {
  459. // invalid file
  460. param = {
  461. required: true,
  462. type: "file",
  463. value: undefined
  464. }
  465. assertValidateParam(param, ["Required field is not provided"])
  466. // valid file
  467. param = {
  468. required: true,
  469. type: "file",
  470. value: new win.File()
  471. }
  472. assertValidateParam(param, [])
  473. })
  474. it("validates optional files", function() {
  475. // invalid file
  476. param = {
  477. required: false,
  478. type: "file",
  479. value: "not a file"
  480. }
  481. assertValidateParam(param, ["Value must be a file"])
  482. // valid (empty) file
  483. param = {
  484. required: false,
  485. type: "file",
  486. value: undefined
  487. }
  488. assertValidateParam(param, [])
  489. // valid file
  490. param = {
  491. required: false,
  492. type: "file",
  493. value: new win.File()
  494. }
  495. assertValidateParam(param, [])
  496. })
  497. it("validates required arrays", function() {
  498. // invalid (empty) array
  499. param = {
  500. required: true,
  501. type: "array",
  502. value: []
  503. }
  504. assertValidateParam(param, ["Required field is not provided"])
  505. // invalid (not an array)
  506. param = {
  507. required: true,
  508. type: "array",
  509. value: undefined
  510. }
  511. assertValidateParam(param, ["Required field is not provided"])
  512. // invalid array, items do not match correct type
  513. param = {
  514. required: true,
  515. type: "array",
  516. value: [1],
  517. items: {
  518. type: "string"
  519. }
  520. }
  521. assertValidateParam(param, [{index: 0, error: "Value must be a string"}])
  522. // valid array, with no 'type' for items
  523. param = {
  524. required: true,
  525. type: "array",
  526. value: ["1"]
  527. }
  528. assertValidateParam(param, [])
  529. // valid array, items match type
  530. param = {
  531. required: true,
  532. type: "array",
  533. value: ["1"],
  534. items: {
  535. type: "string"
  536. }
  537. }
  538. assertValidateParam(param, [])
  539. })
  540. it("validates optional arrays", function() {
  541. // valid, empty array
  542. param = {
  543. required: false,
  544. type: "array",
  545. value: []
  546. }
  547. assertValidateParam(param, [])
  548. // invalid, items do not match correct type
  549. param = {
  550. required: false,
  551. type: "array",
  552. value: ["number"],
  553. items: {
  554. type: "number"
  555. }
  556. }
  557. assertValidateParam(param, [{index: 0, error: "Value must be a number"}])
  558. // valid
  559. param = {
  560. required: false,
  561. type: "array",
  562. value: ["test"],
  563. items: {
  564. type: "string"
  565. }
  566. }
  567. assertValidateParam(param, [])
  568. })
  569. it("validates required booleans", function() {
  570. // invalid boolean value
  571. param = {
  572. required: true,
  573. type: "boolean",
  574. value: undefined
  575. }
  576. assertValidateParam(param, ["Required field is not provided"])
  577. // invalid boolean value (not a boolean)
  578. param = {
  579. required: true,
  580. type: "boolean",
  581. value: "test string"
  582. }
  583. assertValidateParam(param, ["Value must be a boolean"])
  584. // valid boolean value
  585. param = {
  586. required: true,
  587. type: "boolean",
  588. value: "true"
  589. }
  590. assertValidateParam(param, [])
  591. // valid boolean value
  592. param = {
  593. required: true,
  594. type: "boolean",
  595. value: false
  596. }
  597. assertValidateParam(param, [])
  598. })
  599. it("validates optional booleans", function() {
  600. // valid (empty) boolean value
  601. param = {
  602. required: false,
  603. type: "boolean",
  604. value: undefined
  605. }
  606. assertValidateParam(param, [])
  607. // invalid boolean value (not a boolean)
  608. param = {
  609. required: false,
  610. type: "boolean",
  611. value: "test string"
  612. }
  613. assertValidateParam(param, ["Value must be a boolean"])
  614. // valid boolean value
  615. param = {
  616. required: false,
  617. type: "boolean",
  618. value: "true"
  619. }
  620. assertValidateParam(param, [])
  621. // valid boolean value
  622. param = {
  623. required: false,
  624. type: "boolean",
  625. value: false
  626. }
  627. assertValidateParam(param, [])
  628. })
  629. it("validates required numbers", function() {
  630. // invalid number, string instead of a number
  631. param = {
  632. required: true,
  633. type: "number",
  634. value: "test"
  635. }
  636. assertValidateParam(param, ["Value must be a number"])
  637. // invalid number, undefined value
  638. param = {
  639. required: true,
  640. type: "number",
  641. value: undefined
  642. }
  643. assertValidateParam(param, ["Required field is not provided"])
  644. // valid number with min and max
  645. param = {
  646. required: true,
  647. type: "number",
  648. value: 10,
  649. minimum: 5,
  650. maximum: 99
  651. }
  652. assertValidateParam(param, [])
  653. // valid negative number with min and max
  654. param = {
  655. required: true,
  656. type: "number",
  657. value: -10,
  658. minimum: -50,
  659. maximum: -5
  660. }
  661. assertValidateParam(param, [])
  662. // invalid number with maximum:0
  663. param = {
  664. required: true,
  665. type: "number",
  666. value: 1,
  667. maximum: 0
  668. }
  669. assertValidateParam(param, ["Value must be less than Maximum"])
  670. // invalid number with minimum:0
  671. param = {
  672. required: true,
  673. type: "number",
  674. value: -10,
  675. minimum: 0
  676. }
  677. assertValidateParam(param, ["Value must be greater than Minimum"])
  678. })
  679. it("validates optional numbers", function() {
  680. // invalid number, string instead of a number
  681. param = {
  682. required: false,
  683. type: "number",
  684. value: "test"
  685. }
  686. assertValidateParam(param, ["Value must be a number"])
  687. // valid (empty) number
  688. param = {
  689. required: false,
  690. type: "number",
  691. value: undefined
  692. }
  693. assertValidateParam(param, [])
  694. // valid number
  695. param = {
  696. required: false,
  697. type: "number",
  698. value: 10
  699. }
  700. assertValidateParam(param, [])
  701. })
  702. it("validates required integers", function() {
  703. // invalid integer, string instead of an integer
  704. param = {
  705. required: true,
  706. type: "integer",
  707. value: "test"
  708. }
  709. assertValidateParam(param, ["Value must be an integer"])
  710. // invalid integer, undefined value
  711. param = {
  712. required: true,
  713. type: "integer",
  714. value: undefined
  715. }
  716. assertValidateParam(param, ["Required field is not provided"])
  717. // valid integer, but 0 is falsy in JS
  718. param = {
  719. required: true,
  720. type: "integer",
  721. value: 0
  722. }
  723. assertValidateParam(param, [])
  724. // valid integer
  725. param = {
  726. required: true,
  727. type: "integer",
  728. value: 10
  729. }
  730. assertValidateParam(param, [])
  731. })
  732. it("validates optional integers", function() {
  733. // invalid integer, string instead of an integer
  734. param = {
  735. required: false,
  736. type: "integer",
  737. value: "test"
  738. }
  739. assertValidateParam(param, ["Value must be an integer"])
  740. // valid (empty) integer
  741. param = {
  742. required: false,
  743. type: "integer",
  744. value: undefined
  745. }
  746. assertValidateParam(param, [])
  747. // integers
  748. param = {
  749. required: false,
  750. type: "integer",
  751. value: 10
  752. }
  753. assertValidateParam(param, [])
  754. })
  755. })
  756. describe("fromJSOrdered", () => {
  757. it("should create an OrderedMap from an object", () => {
  758. const param = {
  759. value: "test"
  760. }
  761. const result = fromJSOrdered(param).toJS()
  762. expect( result ).toEqual( { value: "test" } )
  763. })
  764. it("should not use an object's length property for Map size", () => {
  765. const param = {
  766. length: 5
  767. }
  768. const result = fromJSOrdered(param).toJS()
  769. expect( result ).toEqual( { length: 5 } )
  770. })
  771. it("should create an OrderedMap from an array", () => {
  772. const param = [1, 1, 2, 3, 5, 8]
  773. const result = fromJSOrdered(param).toJS()
  774. expect( result ).toEqual( [1, 1, 2, 3, 5, 8] )
  775. })
  776. })
  777. describe("getAcceptControllingResponse", () => {
  778. it("should return the first 2xx response with a media type", () => {
  779. const responses = fromJSOrdered({
  780. "200": {
  781. content: {
  782. "application/json": {
  783. schema: {
  784. type: "object"
  785. }
  786. }
  787. }
  788. },
  789. "201": {
  790. content: {
  791. "application/json": {
  792. schema: {
  793. type: "object"
  794. }
  795. }
  796. }
  797. }
  798. })
  799. expect(getAcceptControllingResponse(responses)).toEqual(responses.get("200"))
  800. })
  801. it("should skip 2xx responses without defined media types", () => {
  802. const responses = fromJSOrdered({
  803. "200": {
  804. content: {
  805. "application/json": {
  806. schema: {
  807. type: "object"
  808. }
  809. }
  810. }
  811. },
  812. "201": {
  813. content: {
  814. "application/json": {
  815. schema: {
  816. type: "object"
  817. }
  818. }
  819. }
  820. }
  821. })
  822. expect(getAcceptControllingResponse(responses)).toEqual(responses.get("201"))
  823. })
  824. it("should default to the `default` response if it has defined media types", () => {
  825. const responses = fromJSOrdered({
  826. "200": {
  827. description: "quite empty"
  828. },
  829. "201": {
  830. description: "quite empty"
  831. },
  832. default: {
  833. content: {
  834. "application/json": {
  835. schema: {
  836. type: "object"
  837. }
  838. }
  839. }
  840. }
  841. })
  842. expect(getAcceptControllingResponse(responses)).toEqual(responses.get("default"))
  843. })
  844. it("should return null if there are no suitable controlling responses", () => {
  845. const responses = fromJSOrdered({
  846. "200": {
  847. description: "quite empty"
  848. },
  849. "201": {
  850. description: "quite empty"
  851. },
  852. "default": {
  853. description: "also empty.."
  854. }
  855. })
  856. expect(getAcceptControllingResponse(responses)).toBe(null)
  857. })
  858. it("should return null if an empty OrderedMap is passed", () => {
  859. const responses = fromJSOrdered()
  860. expect(getAcceptControllingResponse(responses)).toBe(null)
  861. })
  862. it("should return null if anything except an OrderedMap is passed", () => {
  863. const responses = {}
  864. expect(getAcceptControllingResponse(responses)).toBe(null)
  865. })
  866. })
  867. describe("createDeepLinkPath", function() {
  868. it("creates a deep link path replacing spaces with underscores", function() {
  869. const result = createDeepLinkPath("tag id with spaces")
  870. expect(result).toEqual("tag_id_with_spaces")
  871. })
  872. it("trims input when creating a deep link path", function() {
  873. let result = createDeepLinkPath(" spaces before and after ")
  874. expect(result).toEqual("spaces_before_and_after")
  875. result = createDeepLinkPath(" ")
  876. expect(result).toEqual("")
  877. })
  878. it("creates a deep link path with special characters", function() {
  879. const result = createDeepLinkPath("!@#$%^&*(){}[]")
  880. expect(result).toEqual("!@#$%^&*(){}[]")
  881. })
  882. it("returns an empty string for invalid input", function() {
  883. expect( createDeepLinkPath(null) ).toEqual("")
  884. expect( createDeepLinkPath(undefined) ).toEqual("")
  885. expect( createDeepLinkPath(1) ).toEqual("")
  886. expect( createDeepLinkPath([]) ).toEqual("")
  887. expect( createDeepLinkPath({}) ).toEqual("")
  888. })
  889. })
  890. describe("escapeDeepLinkPath", function() {
  891. it("creates and escapes a deep link path", function() {
  892. const result = escapeDeepLinkPath("tag id with spaces?")
  893. expect(result).toEqual("tag_id_with_spaces\\?")
  894. })
  895. it("escapes a deep link path that starts with a number", function() {
  896. const result = escapeDeepLinkPath("123")
  897. expect(result).toEqual("\\31 23")
  898. })
  899. it("escapes a deep link path with a class selector", function() {
  900. const result = escapeDeepLinkPath("hello.world")
  901. expect(result).toEqual("hello\\.world")
  902. })
  903. it("escapes a deep link path with an id selector", function() {
  904. const result = escapeDeepLinkPath("hello#world")
  905. expect(result).toEqual("hello\\#world")
  906. })
  907. })
  908. describe("getExtensions", function() {
  909. const objTest = Map([[ "x-test", "a"], ["minimum", "b"]])
  910. it("does not error on empty array", function() {
  911. const result1 = getExtensions([])
  912. expect(result1).toEqual([])
  913. const result2 = getCommonExtensions([])
  914. expect(result2).toEqual([])
  915. })
  916. it("gets only the x- keys", function() {
  917. const result = getExtensions(objTest)
  918. expect(result).toEqual(Map([[ "x-test", "a"]]))
  919. })
  920. it("gets the common keys", function() {
  921. const result = getCommonExtensions(objTest, true)
  922. expect(result).toEqual(Map([[ "minimum", "b"]]))
  923. })
  924. })
  925. describe("deeplyStripKey", function() {
  926. it("should filter out a specified key", function() {
  927. const input = {
  928. $$ref: "#/this/is/my/ref",
  929. a: {
  930. $$ref: "#/this/is/my/other/ref",
  931. value: 12345
  932. }
  933. }
  934. const result = deeplyStripKey(input, "$$ref")
  935. expect(result).toEqual({
  936. a: {
  937. value: 12345
  938. }
  939. })
  940. })
  941. it("should filter out a specified key by predicate", function() {
  942. const input = {
  943. $$ref: "#/this/is/my/ref",
  944. a: {
  945. $$ref: "#/keep/this/one",
  946. value: 12345
  947. }
  948. }
  949. const result = deeplyStripKey(input, "$$ref", (v) => v !== "#/keep/this/one")
  950. expect(result).toEqual({
  951. a: {
  952. value: 12345,
  953. $$ref: "#/keep/this/one"
  954. }
  955. })
  956. })
  957. it("should only call the predicate when the key matches", function() {
  958. const input = {
  959. $$ref: "#/this/is/my/ref",
  960. a: {
  961. $$ref: "#/this/is/my/other/ref",
  962. value: 12345
  963. }
  964. }
  965. let count = 0
  966. const result = deeplyStripKey(input, "$$ref", () => {
  967. count++
  968. return true
  969. })
  970. expect(count).toEqual(2)
  971. })
  972. })
  973. describe("parse and serialize search", function() {
  974. afterEach(function() {
  975. win.location.search = ""
  976. })
  977. describe("parsing", function() {
  978. it("works with empty search", function() {
  979. win.location.search = ""
  980. expect(parseSearch()).toEqual({})
  981. })
  982. it("works with only one key", function() {
  983. win.location.search = "?foo"
  984. expect(parseSearch()).toEqual({foo: ""})
  985. })
  986. it("works with keys and values", function() {
  987. win.location.search = "?foo=fooval&bar&baz=bazval"
  988. expect(parseSearch()).toEqual({foo: "fooval", bar: "", baz: "bazval"})
  989. })
  990. it("decode url encoded components", function() {
  991. win.location.search = "?foo=foo%20bar"
  992. expect(parseSearch()).toEqual({foo: "foo bar"})
  993. })
  994. })
  995. describe("serializing", function() {
  996. it("works with empty map", function() {
  997. expect(serializeSearch({})).toEqual("")
  998. })
  999. it("works with multiple keys with and without values", function() {
  1000. expect(serializeSearch({foo: "", bar: "barval"})).toEqual("foo=&bar=barval")
  1001. })
  1002. it("encode url components", function() {
  1003. expect(serializeSearch({foo: "foo bar"})).toEqual("foo=foo%20bar")
  1004. })
  1005. })
  1006. })
  1007. describe("sanitizeUrl", function() {
  1008. it("should sanitize a `javascript:` url", function() {
  1009. const res = sanitizeUrl("javascript:alert('bam!')")
  1010. expect(res).toEqual("about:blank")
  1011. })
  1012. it("should sanitize a `data:` url", function() {
  1013. const res = sanitizeUrl(`data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=`)
  1014. expect(res).toEqual("about:blank")
  1015. })
  1016. it("should not modify a `http:` url", function() {
  1017. const res = sanitizeUrl(`http://swagger.io/`)
  1018. expect(res).toEqual("http://swagger.io/")
  1019. })
  1020. it("should not modify a `https:` url", function() {
  1021. const res = sanitizeUrl(`https://swagger.io/`)
  1022. expect(res).toEqual("https://swagger.io/")
  1023. })
  1024. it("should gracefully handle empty strings", function() {
  1025. expect(sanitizeUrl("")).toEqual("")
  1026. })
  1027. it("should gracefully handle non-string values", function() {
  1028. expect(sanitizeUrl(123)).toEqual("")
  1029. expect(sanitizeUrl(null)).toEqual("")
  1030. expect(sanitizeUrl(undefined)).toEqual("")
  1031. expect(sanitizeUrl([])).toEqual("")
  1032. expect(sanitizeUrl({})).toEqual("")
  1033. })
  1034. })
  1035. describe("getSampleSchema", function() {
  1036. const oriDate = Date
  1037. before(function() {
  1038. Date = function () {
  1039. this.toISOString = function () {
  1040. return "2018-07-07T07:07:05.189Z"
  1041. }
  1042. }
  1043. })
  1044. after(function() {
  1045. Date = oriDate
  1046. })
  1047. it("should not unnecessarily stringify non-object values", function() {
  1048. // Given
  1049. const res = getSampleSchema({
  1050. type: "string",
  1051. format: "date-time"
  1052. })
  1053. // Then
  1054. expect(res).toEqual(new Date().toISOString())
  1055. })
  1056. })
  1057. })