selectors.js 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. import { fromJS } from "immutable"
  2. import { fromJSOrdered } from "core/utils"
  3. import {
  4. definitions,
  5. parameterValues,
  6. contentTypeValues,
  7. operationScheme,
  8. specJsonWithResolvedSubtrees,
  9. producesOptionsFor,
  10. operationWithMeta,
  11. parameterWithMeta,
  12. parameterWithMetaByIdentity,
  13. parameterInclusionSettingFor,
  14. consumesOptionsFor,
  15. taggedOperations
  16. } from "corePlugins/spec/selectors"
  17. import Petstore from "./assets/petstore.json"
  18. describe("definitions", function(){
  19. it("should return definitions by default", function(){
  20. // Given
  21. const spec = fromJS({
  22. json: {
  23. swagger: "2.0",
  24. definitions: {
  25. a: {
  26. type: "string"
  27. },
  28. b: {
  29. type: "string"
  30. }
  31. }
  32. }
  33. })
  34. // When
  35. let res = definitions(spec)
  36. // Then
  37. expect(res.toJS()).toEqual({
  38. a: {
  39. type: "string"
  40. },
  41. b: {
  42. type: "string"
  43. }
  44. })
  45. })
  46. it("should return an empty Map when missing definitions", function(){
  47. // Given
  48. const spec = fromJS({
  49. json: {
  50. swagger: "2.0"
  51. }
  52. })
  53. // When
  54. let res = definitions(spec)
  55. // Then
  56. expect(res.toJS()).toEqual({})
  57. })
  58. it("should return an empty Map when given non-object definitions", function(){
  59. // Given
  60. const spec = fromJS({
  61. json: {
  62. swagger: "2.0",
  63. definitions: "..."
  64. }
  65. })
  66. // When
  67. let res = definitions(spec)
  68. // Then
  69. expect(res.toJS()).toEqual({})
  70. })
  71. })
  72. describe("parameterValue", function(){
  73. it("should return Map({}) if no path found", function(){
  74. // Given
  75. const spec = fromJS({ })
  76. // When
  77. let paramValues = parameterValues(spec, ["/one", "get"])
  78. // Then
  79. expect(paramValues.toJS()).toEqual({})
  80. })
  81. it("should return a hash of [parameterName]: value", function(){
  82. // Given
  83. const spec = fromJS({
  84. json: {
  85. paths: {
  86. "/one": {
  87. get: {
  88. parameters: [
  89. { name: "one", in: "query", value: 1},
  90. { name: "two", in: "query", value: "duos"}
  91. ]
  92. }
  93. }
  94. }
  95. }
  96. })
  97. // When
  98. let paramValues = parameterValues(spec, ["/one", "get"])
  99. // Then
  100. expect(paramValues.toJS()).toEqual({
  101. "query.one": 1,
  102. "query.two": "duos"
  103. })
  104. })
  105. })
  106. describe("contentTypeValues", function(){
  107. it("should return { requestContentType, responseContentType } from an operation", function(){
  108. // Given
  109. let state = fromJS({
  110. json: {
  111. paths: {
  112. "/one": {
  113. get: {}
  114. }
  115. }
  116. },
  117. meta: {
  118. paths: {
  119. "/one": {
  120. get: {
  121. "consumes_value": "one",
  122. "produces_value": "two"
  123. }
  124. }
  125. }
  126. }
  127. })
  128. // When
  129. let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  130. // Then
  131. expect(contentTypes.toJS()).toEqual({
  132. requestContentType: "one",
  133. responseContentType: "two"
  134. })
  135. })
  136. it("should default to the first `produces` array value if current is not set", function(){
  137. // Given
  138. let state = fromJS({
  139. json: {
  140. paths: {
  141. "/one": {
  142. get: {
  143. produces: [
  144. "application/xml",
  145. "application/whatever"
  146. ]
  147. }
  148. }
  149. }
  150. },
  151. meta: {
  152. paths: {
  153. "/one": {
  154. get: {
  155. "consumes_value": "one"
  156. }
  157. }
  158. }
  159. }
  160. })
  161. // When
  162. let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  163. // Then
  164. expect(contentTypes.toJS()).toEqual({
  165. requestContentType: "one",
  166. responseContentType: "application/xml"
  167. })
  168. })
  169. it("should default to `application/json` if a default produces value is not available", function(){
  170. // Given
  171. let state = fromJS({
  172. json: {
  173. paths: {
  174. "/one": {
  175. get: {}
  176. }
  177. }
  178. },
  179. meta: {
  180. paths: {
  181. "/one": {
  182. get: {
  183. "consumes_value": "one"
  184. }
  185. }
  186. }
  187. }
  188. })
  189. // When
  190. let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  191. // Then
  192. expect(contentTypes.toJS()).toEqual({
  193. requestContentType: "one",
  194. responseContentType: "application/json"
  195. })
  196. })
  197. it("should prioritize consumes value first from an operation", function(){
  198. // Given
  199. let state = fromJS({
  200. json: {
  201. paths: {
  202. "/one": {
  203. get: {
  204. "parameters": [{
  205. "type": "file"
  206. }],
  207. }
  208. }
  209. }
  210. },
  211. meta: {
  212. paths: {
  213. "/one": {
  214. get: {
  215. "consumes_value": "one",
  216. }
  217. }
  218. }
  219. }
  220. })
  221. // When
  222. let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  223. // Then
  224. expect(contentTypes.toJS().requestContentType).toEqual("one")
  225. })
  226. it("should fallback to multipart/form-data if there is no consumes value but there is a file parameter", function(){
  227. // Given
  228. let state = fromJS({
  229. json: {
  230. paths: {
  231. "/one": {
  232. get: {
  233. "parameters": [{
  234. "type": "file"
  235. }],
  236. }
  237. }
  238. }
  239. }
  240. })
  241. // When
  242. let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  243. // Then
  244. expect(contentTypes.toJS().requestContentType).toEqual("multipart/form-data")
  245. })
  246. it("should fallback to application/x-www-form-urlencoded if there is no consumes value, no file parameter, but there is a formData parameter", function(){
  247. // Given
  248. let state = fromJS({
  249. json: {
  250. paths: {
  251. "/one": {
  252. get: {
  253. "parameters": [{
  254. "type": "formData"
  255. }],
  256. }
  257. }
  258. }
  259. }
  260. })
  261. // When
  262. let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  263. // Then
  264. expect(contentTypes.toJS().requestContentType).toEqual("application/x-www-form-urlencoded")
  265. })
  266. it("should return nothing, if the operation does not exist", function(){
  267. // Given
  268. let state = fromJS({ })
  269. // When
  270. let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  271. // Then
  272. expect(contentTypes.toJS()).toEqual({
  273. requestContentType: undefined,
  274. responseContentType: undefined
  275. })
  276. })
  277. })
  278. describe("operationScheme", function(){
  279. it("should return the correct scheme for a remote spec that doesn't specify a scheme", function(){
  280. // Given
  281. let state = fromJS({
  282. url: "https://generator.swagger.io/api/swagger.json",
  283. json: {
  284. paths: {
  285. "/one": {
  286. get: {
  287. "consumes_value": "one",
  288. "produces_value": "two"
  289. }
  290. }
  291. }
  292. }
  293. })
  294. // When
  295. let scheme = operationScheme(state, ["/one"], "get")
  296. // Then
  297. expect(scheme).toEqual("https")
  298. })
  299. // it("should be ok, if no operation found", function(){
  300. // // Given
  301. // let state = fromJS({ })
  302. //
  303. // // When
  304. // let contentTypes = contentTypeValues(state, [ "/one", "get" ])
  305. // // Then
  306. // expect(contentTypes.toJS()).toEqual({
  307. // requestContentType: undefined,
  308. // responseContentType: undefined
  309. // })
  310. // })
  311. })
  312. describe("specJsonWithResolvedSubtrees", function(){
  313. it("should return a correctly merged tree", function(){
  314. // Given
  315. let state = fromJS({
  316. json: {
  317. definitions: {
  318. Asdf: {
  319. $ref: "#/some/path",
  320. randomKey: "this should be removed b/c siblings of $refs must be removed, per the specification",
  321. description: "same for this key"
  322. },
  323. Fgsfds: {
  324. $ref: "#/another/path"
  325. },
  326. OtherDef: {
  327. description: "has no refs"
  328. }
  329. }
  330. },
  331. resolvedSubtrees: {
  332. definitions: {
  333. Asdf: {
  334. type: "object",
  335. $$ref: "#/some/path"
  336. }
  337. }
  338. }
  339. })
  340. // When
  341. let result = specJsonWithResolvedSubtrees(state)
  342. // Then
  343. expect(result.toJS()).toEqual({
  344. definitions: {
  345. Asdf: {
  346. type: "object",
  347. $$ref: "#/some/path"
  348. },
  349. Fgsfds: {
  350. $ref: "#/another/path"
  351. },
  352. OtherDef: {
  353. description: "has no refs"
  354. }
  355. }
  356. })
  357. })
  358. it("should preserve initial map key ordering", function(){
  359. // Given
  360. let state = fromJSOrdered({
  361. json: Petstore,
  362. resolvedSubtrees: {
  363. paths: {
  364. "/pet/{petId}": {
  365. post: {
  366. tags: [
  367. "pet"
  368. ],
  369. summary: "Updates a pet in the store with form data",
  370. description: "",
  371. operationId: "updatePetWithForm",
  372. consumes: [
  373. "application/x-www-form-urlencoded"
  374. ],
  375. produces: [
  376. "application/xml",
  377. "application/json"
  378. ],
  379. parameters: [
  380. {
  381. name: "petId",
  382. "in": "path",
  383. description: "ID of pet that needs to be updated",
  384. required: true,
  385. type: "integer",
  386. format: "int64"
  387. },
  388. {
  389. name: "name",
  390. "in": "formData",
  391. description: "Updated name of the pet",
  392. required: false,
  393. type: "string"
  394. },
  395. {
  396. name: "status",
  397. "in": "formData",
  398. description: "Updated status of the pet",
  399. required: false,
  400. type: "string"
  401. }
  402. ],
  403. responses: {
  404. "405": {
  405. description: "Invalid input"
  406. }
  407. },
  408. security: [
  409. {
  410. petstore_auth: [
  411. "write:pets",
  412. "read:pets"
  413. ]
  414. }
  415. ],
  416. __originalOperationId: "updatePetWithForm"
  417. }
  418. }
  419. }
  420. }
  421. })
  422. // When
  423. let result = specJsonWithResolvedSubtrees(state)
  424. // Then
  425. const correctOrder = [
  426. "/pet",
  427. "/pet/findByStatus",
  428. "/pet/findByTags",
  429. "/pet/{petId}",
  430. "/pet/{petId}/uploadImage",
  431. "/store/inventory",
  432. "/store/order",
  433. "/store/order/{orderId}",
  434. "/user",
  435. "/user/createWithArray",
  436. "/user/createWithList",
  437. "/user/login",
  438. "/user/logout",
  439. "/user/{username}"
  440. ]
  441. expect(state.getIn(["json", "paths"]).keySeq().toJS()).toEqual(correctOrder)
  442. expect(result.getIn(["paths"]).keySeq().toJS()).toEqual(correctOrder)
  443. })
  444. })
  445. describe("operationWithMeta", function() {
  446. it("should support merging in {in}.{name} keyed param metadata", function () {
  447. const state = fromJS({
  448. json: {
  449. paths: {
  450. "/": {
  451. "get": {
  452. parameters: [
  453. {
  454. name: "myBody",
  455. in: "body"
  456. }
  457. ]
  458. }
  459. }
  460. }
  461. },
  462. meta: {
  463. paths: {
  464. "/": {
  465. "get": {
  466. parameters: {
  467. "body.myBody": {
  468. value: "abc123"
  469. }
  470. }
  471. }
  472. }
  473. }
  474. }
  475. })
  476. const result = operationWithMeta(state, "/", "get")
  477. expect(result.toJS()).toEqual({
  478. parameters: [
  479. {
  480. name: "myBody",
  481. in: "body",
  482. value: "abc123"
  483. }
  484. ]
  485. })
  486. })
  487. it("should support merging in hash-keyed param metadata", function () {
  488. const bodyParam = fromJS({
  489. name: "myBody",
  490. in: "body"
  491. })
  492. const state = fromJS({
  493. json: {
  494. paths: {
  495. "/": {
  496. "get": {
  497. parameters: [
  498. bodyParam
  499. ]
  500. }
  501. }
  502. }
  503. },
  504. meta: {
  505. paths: {
  506. "/": {
  507. "get": {
  508. parameters: {
  509. [`body.myBody.hash-${bodyParam.hashCode()}`]: {
  510. value: "abc123"
  511. }
  512. }
  513. }
  514. }
  515. }
  516. }
  517. })
  518. const result = operationWithMeta(state, "/", "get")
  519. expect(result.toJS()).toEqual({
  520. parameters: [
  521. {
  522. name: "myBody",
  523. in: "body",
  524. value: "abc123"
  525. }
  526. ]
  527. })
  528. })
  529. })
  530. describe("parameterWithMeta", function() {
  531. it("should support merging in {in}.{name} keyed param metadata", function () {
  532. const state = fromJS({
  533. json: {
  534. paths: {
  535. "/": {
  536. "get": {
  537. parameters: [
  538. {
  539. name: "myBody",
  540. in: "body"
  541. }
  542. ]
  543. }
  544. }
  545. }
  546. },
  547. meta: {
  548. paths: {
  549. "/": {
  550. "get": {
  551. parameters: {
  552. "body.myBody": {
  553. value: "abc123"
  554. }
  555. }
  556. }
  557. }
  558. }
  559. }
  560. })
  561. const result = parameterWithMeta(state, ["/", "get"], "myBody", "body")
  562. expect(result.toJS()).toEqual({
  563. name: "myBody",
  564. in: "body",
  565. value: "abc123"
  566. })
  567. })
  568. it("should give best-effort when encountering hash-keyed param metadata", function () {
  569. const bodyParam = fromJS({
  570. name: "myBody",
  571. in: "body"
  572. })
  573. const state = fromJS({
  574. json: {
  575. paths: {
  576. "/": {
  577. "get": {
  578. parameters: [
  579. bodyParam
  580. ]
  581. }
  582. }
  583. }
  584. },
  585. meta: {
  586. paths: {
  587. "/": {
  588. "get": {
  589. parameters: {
  590. [`body.myBody.hash-${bodyParam.hashCode()}`]: {
  591. value: "abc123"
  592. }
  593. }
  594. }
  595. }
  596. }
  597. }
  598. })
  599. const result = parameterWithMeta(state, ["/", "get"], "myBody", "body")
  600. expect(result.toJS()).toEqual({
  601. name: "myBody",
  602. in: "body",
  603. value: "abc123"
  604. })
  605. })
  606. })
  607. describe("parameterWithMetaByIdentity", function() {
  608. it("should support merging in {in}.{name} keyed param metadata", function () {
  609. const bodyParam = fromJS({
  610. name: "myBody",
  611. in: "body"
  612. })
  613. const state = fromJS({
  614. json: {
  615. paths: {
  616. "/": {
  617. "get": {
  618. parameters: [bodyParam]
  619. }
  620. }
  621. }
  622. },
  623. meta: {
  624. paths: {
  625. "/": {
  626. "get": {
  627. parameters: {
  628. "body.myBody": {
  629. value: "abc123"
  630. }
  631. }
  632. }
  633. }
  634. }
  635. }
  636. })
  637. const result = parameterWithMetaByIdentity(state, ["/", "get"], bodyParam)
  638. expect(result.toJS()).toEqual({
  639. name: "myBody",
  640. in: "body",
  641. value: "abc123"
  642. })
  643. })
  644. it("should support merging in hash-keyed param metadata", function () {
  645. const bodyParam = fromJS({
  646. name: "myBody",
  647. in: "body"
  648. })
  649. const state = fromJS({
  650. json: {
  651. paths: {
  652. "/": {
  653. "get": {
  654. parameters: [
  655. bodyParam
  656. ]
  657. }
  658. }
  659. }
  660. },
  661. meta: {
  662. paths: {
  663. "/": {
  664. "get": {
  665. parameters: {
  666. [`body.myBody.hash-${bodyParam.hashCode()}`]: {
  667. value: "abc123"
  668. }
  669. }
  670. }
  671. }
  672. }
  673. }
  674. })
  675. const result = parameterWithMetaByIdentity(state, ["/", "get"], bodyParam)
  676. expect(result.toJS()).toEqual({
  677. name: "myBody",
  678. in: "body",
  679. value: "abc123"
  680. })
  681. })
  682. })
  683. describe("parameterInclusionSettingFor", function() {
  684. it("should support getting {in}.{name} param inclusion settings", function () {
  685. const param = fromJS({
  686. name: "param",
  687. in: "query",
  688. allowEmptyValue: true
  689. })
  690. const state = fromJS({
  691. json: {
  692. paths: {
  693. "/": {
  694. "get": {
  695. parameters: [
  696. param
  697. ]
  698. }
  699. }
  700. }
  701. },
  702. meta: {
  703. paths: {
  704. "/": {
  705. "get": {
  706. "parameter_inclusions": {
  707. [`query.param`]: true
  708. }
  709. }
  710. }
  711. }
  712. }
  713. })
  714. const result = parameterInclusionSettingFor(state, ["/", "get"], "param", "query")
  715. expect(result).toEqual(true)
  716. })
  717. })
  718. describe("producesOptionsFor", function() {
  719. it("should return an operation produces value", function () {
  720. const state = fromJS({
  721. json: {
  722. paths: {
  723. "/": {
  724. "get": {
  725. description: "my operation",
  726. produces: [
  727. "operation/one",
  728. "operation/two",
  729. ]
  730. }
  731. }
  732. }
  733. }
  734. })
  735. const result = producesOptionsFor(state, ["/", "get"])
  736. expect(result.toJS()).toEqual([
  737. "operation/one",
  738. "operation/two",
  739. ])
  740. })
  741. it("should return a path item produces value", function () {
  742. const state = fromJS({
  743. json: {
  744. paths: {
  745. "/": {
  746. "get": {
  747. description: "my operation",
  748. produces: [
  749. "path-item/one",
  750. "path-item/two",
  751. ]
  752. }
  753. }
  754. }
  755. }
  756. })
  757. const result = producesOptionsFor(state, ["/", "get"])
  758. expect(result.toJS()).toEqual([
  759. "path-item/one",
  760. "path-item/two",
  761. ])
  762. })
  763. it("should return a global produces value", function () {
  764. const state = fromJS({
  765. json: {
  766. produces: [
  767. "global/one",
  768. "global/two",
  769. ],
  770. paths: {
  771. "/": {
  772. "get": {
  773. description: "my operation"
  774. }
  775. }
  776. }
  777. }
  778. })
  779. const result = producesOptionsFor(state, ["/", "get"])
  780. expect(result.toJS()).toEqual([
  781. "global/one",
  782. "global/two",
  783. ])
  784. })
  785. it("should favor an operation produces value over a path-item value", function () {
  786. const state = fromJS({
  787. json: {
  788. paths: {
  789. "/": {
  790. produces: [
  791. "path-item/one",
  792. "path-item/two",
  793. ],
  794. "get": {
  795. description: "my operation",
  796. produces: [
  797. "operation/one",
  798. "operation/two",
  799. ]
  800. }
  801. }
  802. }
  803. }
  804. })
  805. const result = producesOptionsFor(state, ["/", "get"])
  806. expect(result.toJS()).toEqual([
  807. "operation/one",
  808. "operation/two",
  809. ])
  810. })
  811. it("should favor a path-item produces value over a global value", function () {
  812. const state = fromJS({
  813. json: {
  814. produces: [
  815. "global/one",
  816. "global/two",
  817. ],
  818. paths: {
  819. "/": {
  820. produces: [
  821. "path-item/one",
  822. "path-item/two",
  823. ],
  824. "get": {
  825. description: "my operation"
  826. }
  827. }
  828. }
  829. }
  830. })
  831. const result = producesOptionsFor(state, ["/", "get"])
  832. expect(result.toJS()).toEqual([
  833. "path-item/one",
  834. "path-item/two",
  835. ])
  836. })
  837. })
  838. describe("consumesOptionsFor", function() {
  839. it("should return an operation consumes value", function () {
  840. const state = fromJS({
  841. json: {
  842. paths: {
  843. "/": {
  844. "get": {
  845. description: "my operation",
  846. consumes: [
  847. "operation/one",
  848. "operation/two",
  849. ]
  850. }
  851. }
  852. }
  853. }
  854. })
  855. const result = consumesOptionsFor(state, ["/", "get"])
  856. expect(result.toJS()).toEqual([
  857. "operation/one",
  858. "operation/two",
  859. ])
  860. })
  861. it("should return a path item consumes value", function () {
  862. const state = fromJS({
  863. json: {
  864. paths: {
  865. "/": {
  866. "get": {
  867. description: "my operation",
  868. consumes: [
  869. "path-item/one",
  870. "path-item/two",
  871. ]
  872. }
  873. }
  874. }
  875. }
  876. })
  877. const result = consumesOptionsFor(state, ["/", "get"])
  878. expect(result.toJS()).toEqual([
  879. "path-item/one",
  880. "path-item/two",
  881. ])
  882. })
  883. it("should return a global consumes value", function () {
  884. const state = fromJS({
  885. json: {
  886. consumes: [
  887. "global/one",
  888. "global/two",
  889. ],
  890. paths: {
  891. "/": {
  892. "get": {
  893. description: "my operation"
  894. }
  895. }
  896. }
  897. }
  898. })
  899. const result = consumesOptionsFor(state, ["/", "get"])
  900. expect(result.toJS()).toEqual([
  901. "global/one",
  902. "global/two",
  903. ])
  904. })
  905. it("should favor an operation consumes value over a path-item value", function () {
  906. const state = fromJS({
  907. json: {
  908. paths: {
  909. "/": {
  910. consumes: [
  911. "path-item/one",
  912. "path-item/two",
  913. ],
  914. "get": {
  915. description: "my operation",
  916. consumes: [
  917. "operation/one",
  918. "operation/two",
  919. ]
  920. }
  921. }
  922. }
  923. }
  924. })
  925. const result = consumesOptionsFor(state, ["/", "get"])
  926. expect(result.toJS()).toEqual([
  927. "operation/one",
  928. "operation/two",
  929. ])
  930. })
  931. it("should favor a path-item consumes value over a global value", function () {
  932. const state = fromJS({
  933. json: {
  934. consumes: [
  935. "global/one",
  936. "global/two",
  937. ],
  938. paths: {
  939. "/": {
  940. consumes: [
  941. "path-item/one",
  942. "path-item/two",
  943. ],
  944. "get": {
  945. description: "my operation"
  946. }
  947. }
  948. }
  949. }
  950. })
  951. const result = consumesOptionsFor(state, ["/", "get"])
  952. expect(result.toJS()).toEqual([
  953. "path-item/one",
  954. "path-item/two",
  955. ])
  956. })
  957. })
  958. describe("taggedOperations", function () {
  959. it("should return a List of ad-hoc tagged operations", function () {
  960. const system = {
  961. getConfigs: () => ({})
  962. }
  963. const state = fromJS({
  964. json: {
  965. // tags: [
  966. // "myTag"
  967. // ],
  968. paths: {
  969. "/": {
  970. "get": {
  971. produces: [],
  972. tags: ["myTag"],
  973. description: "my operation",
  974. consumes: [
  975. "operation/one",
  976. "operation/two",
  977. ]
  978. }
  979. }
  980. }
  981. }
  982. })
  983. const result = taggedOperations(state)(system)
  984. const op = state.getIn(["json", "paths", "/", "get"]).toJS()
  985. expect(result.toJS()).toEqual({
  986. myTag: {
  987. tagDetails: undefined,
  988. operations: [{
  989. id: "get-/",
  990. method: "get",
  991. path: "/",
  992. operation: op
  993. }]
  994. }
  995. })
  996. })
  997. it("should return a List of defined tagged operations", function () {
  998. const system = {
  999. getConfigs: () => ({})
  1000. }
  1001. const state = fromJS({
  1002. json: {
  1003. tags: [
  1004. {
  1005. name: "myTag"
  1006. }
  1007. ],
  1008. paths: {
  1009. "/": {
  1010. "get": {
  1011. produces: [],
  1012. tags: ["myTag"],
  1013. description: "my operation",
  1014. consumes: [
  1015. "operation/one",
  1016. "operation/two",
  1017. ]
  1018. }
  1019. }
  1020. }
  1021. }
  1022. })
  1023. const result = taggedOperations(state)(system)
  1024. const op = state.getIn(["json", "paths", "/", "get"]).toJS()
  1025. expect(result.toJS()).toEqual({
  1026. myTag: {
  1027. tagDetails: {
  1028. name: "myTag"
  1029. },
  1030. operations: [{
  1031. id: "get-/",
  1032. method: "get",
  1033. path: "/",
  1034. operation: op
  1035. }]
  1036. }
  1037. })
  1038. })
  1039. it("should gracefully handle a malformed global tags array", function () {
  1040. const system = {
  1041. getConfigs: () => ({})
  1042. }
  1043. const state = fromJS({
  1044. json: {
  1045. tags: [null],
  1046. paths: {
  1047. "/": {
  1048. "get": {
  1049. produces: [],
  1050. tags: ["myTag"],
  1051. description: "my operation",
  1052. consumes: [
  1053. "operation/one",
  1054. "operation/two",
  1055. ]
  1056. }
  1057. }
  1058. }
  1059. }
  1060. })
  1061. const result = taggedOperations(state)(system)
  1062. const op = state.getIn(["json", "paths", "/", "get"]).toJS()
  1063. expect(result.toJS()).toEqual({
  1064. myTag: {
  1065. tagDetails: undefined,
  1066. operations: [{
  1067. id: "get-/",
  1068. method: "get",
  1069. path: "/",
  1070. operation: op
  1071. }]
  1072. }
  1073. })
  1074. })
  1075. it("should gracefully handle a non-array global tags entry", function () {
  1076. const system = {
  1077. getConfigs: () => ({})
  1078. }
  1079. const state = fromJS({
  1080. json: {
  1081. tags: "asdf",
  1082. paths: {
  1083. "/": {
  1084. "get": {
  1085. produces: [],
  1086. tags: ["myTag"],
  1087. description: "my operation",
  1088. consumes: [
  1089. "operation/one",
  1090. "operation/two",
  1091. ]
  1092. }
  1093. }
  1094. }
  1095. }
  1096. })
  1097. const result = taggedOperations(state)(system)
  1098. const op = state.getIn(["json", "paths", "/", "get"]).toJS()
  1099. expect(result.toJS()).toEqual({
  1100. myTag: {
  1101. tagDetails: undefined,
  1102. operations: [{
  1103. id: "get-/",
  1104. method: "get",
  1105. path: "/",
  1106. operation: op
  1107. }]
  1108. }
  1109. })
  1110. })
  1111. })