You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

utils.js 26 KiB

7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
7 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960
  1. /* eslint-env mocha */
  2. import expect from "expect"
  3. import { fromJS, OrderedMap } from "immutable"
  4. import {
  5. mapToList,
  6. validatePattern,
  7. validateMinLength,
  8. validateMaxLength,
  9. validateDateTime,
  10. validateGuid,
  11. validateNumber,
  12. validateInteger,
  13. validateParam,
  14. validateFile,
  15. validateMaximum,
  16. validateMinimum,
  17. fromJSOrdered,
  18. getAcceptControllingResponse,
  19. createDeepLinkPath,
  20. escapeDeepLinkPath,
  21. sanitizeUrl
  22. } from "core/utils"
  23. import win from "core/window"
  24. describe("utils", function() {
  25. describe("mapToList", function(){
  26. it("should convert a map to a list, setting `key`", function(){
  27. // With
  28. const aMap = fromJS({
  29. a: {
  30. one: 1,
  31. },
  32. b: {
  33. two: 2,
  34. }
  35. })
  36. // When
  37. const aList = mapToList(aMap, "someKey")
  38. // Then
  39. expect(aList.toJS()).toEqual([
  40. { someKey: "a", one: 1 },
  41. { someKey: "b", two: 2 },
  42. ])
  43. })
  44. it("should flatten an arbitrarily deep map", function(){
  45. // With
  46. const aMap = fromJS({
  47. a: {
  48. one: {
  49. alpha: true
  50. }
  51. },
  52. b: {
  53. two: {
  54. bravo: true
  55. },
  56. three: {
  57. charlie: true
  58. }
  59. }
  60. })
  61. // When
  62. const aList = mapToList(aMap, ["levelA", "levelB"])
  63. // Then
  64. expect(aList.toJS()).toEqual([
  65. { levelA: "a", levelB: "one", alpha: true },
  66. { levelA: "b", levelB: "two", bravo: true },
  67. { levelA: "b", levelB: "three", charlie: true },
  68. ])
  69. })
  70. it("should handle an empty map", function(){
  71. // With
  72. const aMap = fromJS({})
  73. // When
  74. const aList = mapToList(aMap, ["levelA", "levelB"])
  75. // Then
  76. expect(aList.toJS()).toEqual([])
  77. })
  78. })
  79. describe("validateMaximum", function() {
  80. let errorMessage = "Value must be less than Maximum"
  81. it("doesn't return for valid input", function() {
  82. expect(validateMaximum(9, 10)).toBeFalsy()
  83. expect(validateMaximum(19, 20)).toBeFalsy()
  84. })
  85. it("returns a message for invalid input", function() {
  86. expect(validateMaximum(1, 0)).toEqual(errorMessage)
  87. expect(validateMaximum(10, 9)).toEqual(errorMessage)
  88. expect(validateMaximum(20, 19)).toEqual(errorMessage)
  89. })
  90. })
  91. describe("validateMinimum", function() {
  92. let errorMessage = "Value must be greater than Minimum"
  93. it("doesn't return for valid input", function() {
  94. expect(validateMinimum(2, 1)).toBeFalsy()
  95. expect(validateMinimum(20, 10)).toBeFalsy()
  96. })
  97. it("returns a message for invalid input", function() {
  98. expect(validateMinimum(-1, 0)).toEqual(errorMessage)
  99. expect(validateMinimum(1, 2)).toEqual(errorMessage)
  100. expect(validateMinimum(10, 20)).toEqual(errorMessage)
  101. })
  102. })
  103. describe("validateNumber", function() {
  104. let errorMessage = "Value must be a number"
  105. it("doesn't return for whole numbers", function() {
  106. expect(validateNumber(0)).toBeFalsy()
  107. expect(validateNumber(1)).toBeFalsy()
  108. expect(validateNumber(20)).toBeFalsy()
  109. expect(validateNumber(5000000)).toBeFalsy()
  110. expect(validateNumber("1")).toBeFalsy()
  111. expect(validateNumber("2")).toBeFalsy()
  112. expect(validateNumber(-1)).toBeFalsy()
  113. expect(validateNumber(-20)).toBeFalsy()
  114. expect(validateNumber(-5000000)).toBeFalsy()
  115. })
  116. it("doesn't return for negative numbers", function() {
  117. expect(validateNumber(-1)).toBeFalsy()
  118. expect(validateNumber(-20)).toBeFalsy()
  119. expect(validateNumber(-5000000)).toBeFalsy()
  120. })
  121. it("doesn't return for decimal numbers", function() {
  122. expect(validateNumber(1.1)).toBeFalsy()
  123. expect(validateNumber(2.5)).toBeFalsy()
  124. expect(validateNumber(-30.99)).toBeFalsy()
  125. })
  126. it("returns a message for strings", function() {
  127. expect(validateNumber("")).toEqual(errorMessage)
  128. expect(validateNumber(" ")).toEqual(errorMessage)
  129. expect(validateNumber("test")).toEqual(errorMessage)
  130. })
  131. it("returns a message for invalid input", function() {
  132. expect(validateNumber(undefined)).toEqual(errorMessage)
  133. expect(validateNumber(null)).toEqual(errorMessage)
  134. expect(validateNumber({})).toEqual(errorMessage)
  135. expect(validateNumber([])).toEqual(errorMessage)
  136. expect(validateNumber(true)).toEqual(errorMessage)
  137. expect(validateNumber(false)).toEqual(errorMessage)
  138. })
  139. })
  140. describe("validateInteger", function() {
  141. let errorMessage = "Value must be an integer"
  142. it("doesn't return for positive integers", function() {
  143. expect(validateInteger(0)).toBeFalsy()
  144. expect(validateInteger(1)).toBeFalsy()
  145. expect(validateInteger(20)).toBeFalsy()
  146. expect(validateInteger(5000000)).toBeFalsy()
  147. expect(validateInteger("1")).toBeFalsy()
  148. expect(validateInteger("2")).toBeFalsy()
  149. expect(validateInteger(-1)).toBeFalsy()
  150. expect(validateInteger(-20)).toBeFalsy()
  151. expect(validateInteger(-5000000)).toBeFalsy()
  152. })
  153. it("doesn't return for negative integers", function() {
  154. expect(validateInteger(-1)).toBeFalsy()
  155. expect(validateInteger(-20)).toBeFalsy()
  156. expect(validateInteger(-5000000)).toBeFalsy()
  157. })
  158. it("returns a message for decimal values", function() {
  159. expect(validateInteger(1.1)).toEqual(errorMessage)
  160. expect(validateInteger(2.5)).toEqual(errorMessage)
  161. expect(validateInteger(-30.99)).toEqual(errorMessage)
  162. })
  163. it("returns a message for strings", function() {
  164. expect(validateInteger("")).toEqual(errorMessage)
  165. expect(validateInteger(" ")).toEqual(errorMessage)
  166. expect(validateInteger("test")).toEqual(errorMessage)
  167. })
  168. it("returns a message for invalid input", function() {
  169. expect(validateInteger(undefined)).toEqual(errorMessage)
  170. expect(validateInteger(null)).toEqual(errorMessage)
  171. expect(validateInteger({})).toEqual(errorMessage)
  172. expect(validateInteger([])).toEqual(errorMessage)
  173. expect(validateInteger(true)).toEqual(errorMessage)
  174. expect(validateInteger(false)).toEqual(errorMessage)
  175. })
  176. })
  177. describe("validateFile", function() {
  178. let errorMessage = "Value must be a file"
  179. it("validates against objects which are instances of 'File'", function() {
  180. let fileObj = new win.File([], "Test File")
  181. expect(validateFile(fileObj)).toBeFalsy()
  182. expect(validateFile(null)).toBeFalsy()
  183. expect(validateFile(undefined)).toBeFalsy()
  184. expect(validateFile(1)).toEqual(errorMessage)
  185. expect(validateFile("string")).toEqual(errorMessage)
  186. })
  187. })
  188. describe("validateDateTime", function() {
  189. let errorMessage = "Value must be a DateTime"
  190. it("doesn't return for valid dates", function() {
  191. expect(validateDateTime("Mon, 25 Dec 1995 13:30:00 +0430")).toBeFalsy()
  192. })
  193. it("returns a message for invalid input'", function() {
  194. expect(validateDateTime(null)).toEqual(errorMessage)
  195. expect(validateDateTime("string")).toEqual(errorMessage)
  196. })
  197. })
  198. describe("validateGuid", function() {
  199. let errorMessage = "Value must be a Guid"
  200. it("doesn't return for valid guid", function() {
  201. expect(validateGuid("8ce4811e-cec5-4a29-891a-15d1917153c1")).toBeFalsy()
  202. expect(validateGuid("{8ce4811e-cec5-4a29-891a-15d1917153c1}")).toBeFalsy()
  203. })
  204. it("returns a message for invalid input'", function() {
  205. expect(validateGuid(1)).toEqual(errorMessage)
  206. expect(validateGuid("string")).toEqual(errorMessage)
  207. })
  208. })
  209. describe("validateMaxLength", function() {
  210. let errorMessage = "Value must be less than MaxLength"
  211. it("doesn't return for valid guid", function() {
  212. expect(validateMaxLength("a", 1)).toBeFalsy()
  213. expect(validateMaxLength("abc", 5)).toBeFalsy()
  214. })
  215. it("returns a message for invalid input'", function() {
  216. expect(validateMaxLength("abc", 0)).toEqual(errorMessage)
  217. expect(validateMaxLength("abc", 1)).toEqual(errorMessage)
  218. expect(validateMaxLength("abc", 2)).toEqual(errorMessage)
  219. })
  220. })
  221. describe("validateMinLength", function() {
  222. let errorMessage = "Value must be greater than MinLength"
  223. it("doesn't return for valid guid", function() {
  224. expect(validateMinLength("a", 1)).toBeFalsy()
  225. expect(validateMinLength("abc", 2)).toBeFalsy()
  226. })
  227. it("returns a message for invalid input'", function() {
  228. expect(validateMinLength("abc", 5)).toEqual(errorMessage)
  229. expect(validateMinLength("abc", 8)).toEqual(errorMessage)
  230. })
  231. })
  232. describe("validatePattern", function() {
  233. let rxPattern = "^(red|blue)"
  234. let errorMessage = "Value must follow pattern " + rxPattern
  235. it("doesn't return for a match", function() {
  236. expect(validatePattern("red", rxPattern)).toBeFalsy()
  237. expect(validatePattern("blue", rxPattern)).toBeFalsy()
  238. })
  239. it("returns a message for invalid pattern", function() {
  240. expect(validatePattern("pink", rxPattern)).toEqual(errorMessage)
  241. expect(validatePattern("123", rxPattern)).toEqual(errorMessage)
  242. })
  243. it("fails gracefully when an invalid regex value is passed", function() {
  244. expect(() => validatePattern("aValue", "---")).toNotThrow()
  245. expect(() => validatePattern("aValue", 1234)).toNotThrow()
  246. expect(() => validatePattern("aValue", null)).toNotThrow()
  247. expect(() => validatePattern("aValue", [])).toNotThrow()
  248. })
  249. })
  250. describe("validateParam", function() {
  251. let param = null
  252. let result = null
  253. const assertValidateParam = (param, expectedError) => {
  254. // Swagger 2.0 version
  255. result = validateParam( fromJS(param), false )
  256. expect( result ).toEqual( expectedError )
  257. // OAS3 version, using `schema` sub-object
  258. let oas3Param = {
  259. value: param.value,
  260. required: param.required,
  261. schema: {
  262. ...param,
  263. value: undefined,
  264. required: undefined
  265. }
  266. }
  267. result = validateParam( fromJS(oas3Param), false, true )
  268. expect( result ).toEqual( expectedError )
  269. }
  270. it("should check the isOAS3 flag when validating parameters", function() {
  271. // This should "skip" validation because there is no `schema.type` property
  272. // and we are telling `validateParam` this is an OAS3 spec
  273. param = fromJS({
  274. value: "",
  275. required: true,
  276. schema: {
  277. notTheTypeProperty: "string"
  278. }
  279. })
  280. result = validateParam( param, false, true )
  281. expect( result ).toEqual( [] )
  282. })
  283. it("validates required strings", function() {
  284. // invalid string
  285. param = {
  286. required: true,
  287. type: "string",
  288. value: ""
  289. }
  290. assertValidateParam(param, ["Required field is not provided"])
  291. // valid string
  292. param = {
  293. required: true,
  294. type: "string",
  295. value: "test string"
  296. }
  297. assertValidateParam(param, [])
  298. // valid string with min and max length
  299. param = {
  300. required: true,
  301. type: "string",
  302. value: "test string",
  303. maxLength: 50,
  304. minLength: 1
  305. }
  306. assertValidateParam(param, [])
  307. })
  308. it("validates required strings with min and max length", function() {
  309. // invalid string with max length
  310. param = {
  311. required: true,
  312. type: "string",
  313. value: "test string",
  314. maxLength: 5
  315. }
  316. assertValidateParam(param, ["Value must be less than MaxLength"])
  317. // invalid string with max length 0
  318. param = {
  319. required: true,
  320. type: "string",
  321. value: "test string",
  322. maxLength: 0
  323. }
  324. assertValidateParam(param, ["Value must be less than MaxLength"])
  325. // invalid string with min length
  326. param = {
  327. required: true,
  328. type: "string",
  329. value: "test string",
  330. minLength: 50
  331. }
  332. assertValidateParam(param, ["Value must be greater than MinLength"])
  333. })
  334. it("validates optional strings", function() {
  335. // valid (empty) string
  336. param = {
  337. required: false,
  338. type: "string",
  339. value: ""
  340. }
  341. assertValidateParam(param, [])
  342. // valid string
  343. param = {
  344. required: false,
  345. type: "string",
  346. value: "test"
  347. }
  348. assertValidateParam(param, [])
  349. })
  350. it("validates required files", function() {
  351. // invalid file
  352. param = {
  353. required: true,
  354. type: "file",
  355. value: undefined
  356. }
  357. assertValidateParam(param, ["Required field is not provided"])
  358. // valid file
  359. param = {
  360. required: true,
  361. type: "file",
  362. value: new win.File()
  363. }
  364. assertValidateParam(param, [])
  365. })
  366. it("validates optional files", function() {
  367. // invalid file
  368. param = {
  369. required: false,
  370. type: "file",
  371. value: "not a file"
  372. }
  373. assertValidateParam(param, ["Value must be a file"])
  374. // valid (empty) file
  375. param = {
  376. required: false,
  377. type: "file",
  378. value: undefined
  379. }
  380. assertValidateParam(param, [])
  381. // valid file
  382. param = {
  383. required: false,
  384. type: "file",
  385. value: new win.File()
  386. }
  387. assertValidateParam(param, [])
  388. })
  389. it("validates required arrays", function() {
  390. // invalid (empty) array
  391. param = {
  392. required: true,
  393. type: "array",
  394. value: []
  395. }
  396. assertValidateParam(param, ["Required field is not provided"])
  397. // invalid (not an array)
  398. param = {
  399. required: true,
  400. type: "array",
  401. value: undefined
  402. }
  403. assertValidateParam(param, ["Required field is not provided"])
  404. // invalid array, items do not match correct type
  405. param = {
  406. required: true,
  407. type: "array",
  408. value: [1],
  409. items: {
  410. type: "string"
  411. }
  412. }
  413. assertValidateParam(param, [{index: 0, error: "Value must be a string"}])
  414. // valid array, with no 'type' for items
  415. param = {
  416. required: true,
  417. type: "array",
  418. value: ["1"]
  419. }
  420. assertValidateParam(param, [])
  421. // valid array, items match type
  422. param = {
  423. required: true,
  424. type: "array",
  425. value: ["1"],
  426. items: {
  427. type: "string"
  428. }
  429. }
  430. assertValidateParam(param, [])
  431. })
  432. it("validates optional arrays", function() {
  433. // valid, empty array
  434. param = {
  435. required: false,
  436. type: "array",
  437. value: []
  438. }
  439. assertValidateParam(param, [])
  440. // invalid, items do not match correct type
  441. param = {
  442. required: false,
  443. type: "array",
  444. value: ["number"],
  445. items: {
  446. type: "number"
  447. }
  448. }
  449. assertValidateParam(param, [{index: 0, error: "Value must be a number"}])
  450. // valid
  451. param = {
  452. required: false,
  453. type: "array",
  454. value: ["test"],
  455. items: {
  456. type: "string"
  457. }
  458. }
  459. assertValidateParam(param, [])
  460. })
  461. it("validates required booleans", function() {
  462. // invalid boolean value
  463. param = {
  464. required: true,
  465. type: "boolean",
  466. value: undefined
  467. }
  468. assertValidateParam(param, ["Required field is not provided"])
  469. // invalid boolean value (not a boolean)
  470. param = {
  471. required: true,
  472. type: "boolean",
  473. value: "test string"
  474. }
  475. assertValidateParam(param, ["Value must be a boolean"])
  476. // valid boolean value
  477. param = {
  478. required: true,
  479. type: "boolean",
  480. value: "true"
  481. }
  482. assertValidateParam(param, [])
  483. // valid boolean value
  484. param = {
  485. required: true,
  486. type: "boolean",
  487. value: false
  488. }
  489. assertValidateParam(param, [])
  490. })
  491. it("validates optional booleans", function() {
  492. // valid (empty) boolean value
  493. param = {
  494. required: false,
  495. type: "boolean",
  496. value: undefined
  497. }
  498. assertValidateParam(param, [])
  499. // invalid boolean value (not a boolean)
  500. param = {
  501. required: false,
  502. type: "boolean",
  503. value: "test string"
  504. }
  505. assertValidateParam(param, ["Value must be a boolean"])
  506. // valid boolean value
  507. param = {
  508. required: false,
  509. type: "boolean",
  510. value: "true"
  511. }
  512. assertValidateParam(param, [])
  513. // valid boolean value
  514. param = {
  515. required: false,
  516. type: "boolean",
  517. value: false
  518. }
  519. assertValidateParam(param, [])
  520. })
  521. it("validates required numbers", function() {
  522. // invalid number, string instead of a number
  523. param = {
  524. required: true,
  525. type: "number",
  526. value: "test"
  527. }
  528. assertValidateParam(param, ["Value must be a number"])
  529. // invalid number, undefined value
  530. param = {
  531. required: true,
  532. type: "number",
  533. value: undefined
  534. }
  535. assertValidateParam(param, ["Required field is not provided"])
  536. // valid number with min and max
  537. param = {
  538. required: true,
  539. type: "number",
  540. value: 10,
  541. minimum: 5,
  542. maximum: 99
  543. }
  544. assertValidateParam(param, [])
  545. // valid negative number with min and max
  546. param = {
  547. required: true,
  548. type: "number",
  549. value: -10,
  550. minimum: -50,
  551. maximum: -5
  552. }
  553. assertValidateParam(param, [])
  554. // invalid number with maximum:0
  555. param = {
  556. required: true,
  557. type: "number",
  558. value: 1,
  559. maximum: 0
  560. }
  561. assertValidateParam(param, ["Value must be less than Maximum"])
  562. // invalid number with minimum:0
  563. param = {
  564. required: true,
  565. type: "number",
  566. value: -10,
  567. minimum: 0
  568. }
  569. assertValidateParam(param, ["Value must be greater than Minimum"])
  570. })
  571. it("validates optional numbers", function() {
  572. // invalid number, string instead of a number
  573. param = {
  574. required: false,
  575. type: "number",
  576. value: "test"
  577. }
  578. assertValidateParam(param, ["Value must be a number"])
  579. // valid (empty) number
  580. param = {
  581. required: false,
  582. type: "number",
  583. value: undefined
  584. }
  585. assertValidateParam(param, [])
  586. // valid number
  587. param = {
  588. required: false,
  589. type: "number",
  590. value: 10
  591. }
  592. assertValidateParam(param, [])
  593. })
  594. it("validates required integers", function() {
  595. // invalid integer, string instead of an integer
  596. param = {
  597. required: true,
  598. type: "integer",
  599. value: "test"
  600. }
  601. assertValidateParam(param, ["Value must be an integer"])
  602. // invalid integer, undefined value
  603. param = {
  604. required: true,
  605. type: "integer",
  606. value: undefined
  607. }
  608. assertValidateParam(param, ["Required field is not provided"])
  609. // valid integer, but 0 is falsy in JS
  610. param = {
  611. required: true,
  612. type: "integer",
  613. value: 0
  614. }
  615. assertValidateParam(param, [])
  616. // valid integer
  617. param = {
  618. required: true,
  619. type: "integer",
  620. value: 10
  621. }
  622. assertValidateParam(param, [])
  623. })
  624. it("validates optional integers", function() {
  625. // invalid integer, string instead of an integer
  626. param = {
  627. required: false,
  628. type: "integer",
  629. value: "test"
  630. }
  631. assertValidateParam(param, ["Value must be an integer"])
  632. // valid (empty) integer
  633. param = {
  634. required: false,
  635. type: "integer",
  636. value: undefined
  637. }
  638. assertValidateParam(param, [])
  639. // integers
  640. param = {
  641. required: false,
  642. type: "integer",
  643. value: 10
  644. }
  645. assertValidateParam(param, [])
  646. })
  647. })
  648. describe("fromJSOrdered", () => {
  649. it("should create an OrderedMap from an object", () => {
  650. const param = {
  651. value: "test"
  652. }
  653. const result = fromJSOrdered(param).toJS()
  654. expect( result ).toEqual( { value: "test" } )
  655. })
  656. it("should not use an object's length property for Map size", () => {
  657. const param = {
  658. length: 5
  659. }
  660. const result = fromJSOrdered(param).toJS()
  661. expect( result ).toEqual( { length: 5 } )
  662. })
  663. it("should create an OrderedMap from an array", () => {
  664. const param = [1, 1, 2, 3, 5, 8]
  665. const result = fromJSOrdered(param).toJS()
  666. expect( result ).toEqual( [1, 1, 2, 3, 5, 8] )
  667. })
  668. })
  669. describe("getAcceptControllingResponse", () => {
  670. it("should return the first 2xx response with a media type", () => {
  671. const responses = fromJSOrdered({
  672. "200": {
  673. content: {
  674. "application/json": {
  675. schema: {
  676. type: "object"
  677. }
  678. }
  679. }
  680. },
  681. "201": {
  682. content: {
  683. "application/json": {
  684. schema: {
  685. type: "object"
  686. }
  687. }
  688. }
  689. }
  690. })
  691. expect(getAcceptControllingResponse(responses)).toEqual(responses.get("200"))
  692. })
  693. it("should skip 2xx responses without defined media types", () => {
  694. const responses = fromJSOrdered({
  695. "200": {
  696. content: {
  697. "application/json": {
  698. schema: {
  699. type: "object"
  700. }
  701. }
  702. }
  703. },
  704. "201": {
  705. content: {
  706. "application/json": {
  707. schema: {
  708. type: "object"
  709. }
  710. }
  711. }
  712. }
  713. })
  714. expect(getAcceptControllingResponse(responses)).toEqual(responses.get("201"))
  715. })
  716. it("should default to the `default` response if it has defined media types", () => {
  717. const responses = fromJSOrdered({
  718. "200": {
  719. description: "quite empty"
  720. },
  721. "201": {
  722. description: "quite empty"
  723. },
  724. default: {
  725. content: {
  726. "application/json": {
  727. schema: {
  728. type: "object"
  729. }
  730. }
  731. }
  732. }
  733. })
  734. expect(getAcceptControllingResponse(responses)).toEqual(responses.get("default"))
  735. })
  736. it("should return null if there are no suitable controlling responses", () => {
  737. const responses = fromJSOrdered({
  738. "200": {
  739. description: "quite empty"
  740. },
  741. "201": {
  742. description: "quite empty"
  743. },
  744. "default": {
  745. description: "also empty.."
  746. }
  747. })
  748. expect(getAcceptControllingResponse(responses)).toBe(null)
  749. })
  750. it("should return null if an empty OrderedMap is passed", () => {
  751. const responses = fromJSOrdered()
  752. expect(getAcceptControllingResponse(responses)).toBe(null)
  753. })
  754. it("should return null if anything except an OrderedMap is passed", () => {
  755. const responses = {}
  756. expect(getAcceptControllingResponse(responses)).toBe(null)
  757. })
  758. })
  759. describe("createDeepLinkPath", function() {
  760. it("creates a deep link path replacing spaces with underscores", function() {
  761. const result = createDeepLinkPath("tag id with spaces")
  762. expect(result).toEqual("tag_id_with_spaces")
  763. })
  764. it("trims input when creating a deep link path", function() {
  765. let result = createDeepLinkPath(" spaces before and after ")
  766. expect(result).toEqual("spaces_before_and_after")
  767. result = createDeepLinkPath(" ")
  768. expect(result).toEqual("")
  769. })
  770. it("creates a deep link path with special characters", function() {
  771. const result = createDeepLinkPath("!@#$%^&*(){}[]")
  772. expect(result).toEqual("!@#$%^&*(){}[]")
  773. })
  774. it("returns an empty string for invalid input", function() {
  775. expect( createDeepLinkPath(null) ).toEqual("")
  776. expect( createDeepLinkPath(undefined) ).toEqual("")
  777. expect( createDeepLinkPath(1) ).toEqual("")
  778. expect( createDeepLinkPath([]) ).toEqual("")
  779. expect( createDeepLinkPath({}) ).toEqual("")
  780. })
  781. })
  782. describe("escapeDeepLinkPath", function() {
  783. it("creates and escapes a deep link path", function() {
  784. const result = escapeDeepLinkPath("tag id with spaces?")
  785. expect(result).toEqual("tag_id_with_spaces\\?")
  786. })
  787. it("escapes a deep link path that starts with a number", function() {
  788. const result = escapeDeepLinkPath("123")
  789. expect(result).toEqual("\\31 23")
  790. })
  791. it("escapes a deep link path with a class selector", function() {
  792. const result = escapeDeepLinkPath("hello.world")
  793. expect(result).toEqual("hello\\.world")
  794. })
  795. it("escapes a deep link path with an id selector", function() {
  796. const result = escapeDeepLinkPath("hello#world")
  797. expect(result).toEqual("hello\\#world")
  798. })
  799. })
  800. describe("sanitizeUrl", function() {
  801. it("should sanitize a `javascript:` url", function() {
  802. const res = sanitizeUrl("javascript:alert('bam!')")
  803. expect(res).toEqual("about:blank")
  804. })
  805. it("should sanitize a `data:` url", function() {
  806. const res = sanitizeUrl(`data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGV
  807. sbG8iKTs8L3NjcmlwdD4=`)
  808. expect(res).toEqual("about:blank")
  809. })
  810. it("should not modify a `http:` url", function() {
  811. const res = sanitizeUrl(`http://swagger.io/`)
  812. expect(res).toEqual("http://swagger.io/")
  813. })
  814. it("should not modify a `https:` url", function() {
  815. const res = sanitizeUrl(`https://swagger.io/`)
  816. expect(res).toEqual("https://swagger.io/")
  817. })
  818. it("should gracefully handle empty strings", function() {
  819. expect(sanitizeUrl("")).toEqual("")
  820. })
  821. it("should gracefully handle non-string values", function() {
  822. expect(sanitizeUrl(123)).toEqual("")
  823. expect(sanitizeUrl(null)).toEqual("")
  824. expect(sanitizeUrl(undefined)).toEqual("")
  825. expect(sanitizeUrl([])).toEqual("")
  826. expect(sanitizeUrl({})).toEqual("")
  827. })
  828. })
  829. })