1{-# LANGUAGE OverloadedLists #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE QuasiQuotes #-}
5module Data.SwaggerSpec where
13import Data.Aeson.QQ.Simple
14import Data.HashMap.Strict (HashMap)
15import qualified Data.HashSet.InsOrd as InsOrdHS
16import Data.Text (Text)
20import Test.Hspec hiding (example)
24 describe "License Object" $ licenseExample <=> licenseExampleJSON
25 describe "Contact Object" $ contactExample <=> contactExampleJSON
26 describe "Info Object" $ infoExample <=> infoExampleJSON
27 describe "Operation Object" $ operationExample <=> operationExampleJSON
28 describe "Schema Object" $ do
29 context "Primitive Sample" $ schemaPrimitiveExample <=> schemaPrimitiveExampleJSON
30 context "Simple Model" $ schemaSimpleModelExample <=> schemaSimpleModelExampleJSON
31 context "Model with Map/Dictionary Properties" $ schemaModelDictExample <=> schemaModelDictExampleJSON
32 context "Model with Arbitrary Properties" $ schemaAdditionalExample <=> schemaAdditionalExampleJSON
33 context "Model with Example" $ schemaWithExampleExample <=> schemaWithExampleExampleJSON
34 describe "Definitions Object" $ definitionsExample <=> definitionsExampleJSON
35 describe "Parameters Definition Object" $ paramsDefinitionExample <=> paramsDefinitionExampleJSON
36 describe "Responses Definition Object" $ responsesDefinitionExample <=> responsesDefinitionExampleJSON
37 describe "Security Definitions Object" $ securityDefinitionsExample <=> securityDefinitionsExampleJSON
38 describe "OAuth2 Security Definitions with merged Scope" $ oAuth2SecurityDefinitionsExample <=> oAuth2SecurityDefinitionsExampleJSON
39 describe "Composition Schema Example" $ compositionSchemaExample <=> compositionSchemaExampleJSON
40 describe "Swagger Object" $ do
41 context "Example with no paths" $ emptyPathsFieldExample <=> emptyPathsFieldExampleJSON
42 context "Todo Example" $ swaggerExample <=> swaggerExampleJSON
43 context "PetStore Example" $ do
44 it "decodes successfully" $ do
45 fromJSON petstoreExampleJSON `shouldSatisfy` (\x -> case x of Success (_ :: Swagger) -> True; _ -> False)
46 it "roundtrips: fmap toJSON . fromJSON" $ do
47 (toJSON :: Swagger -> Value) <$> fromJSON petstoreExampleJSON `shouldBe` Success petstoreExampleJSON
52-- =======================================================================
54-- =======================================================================
58 & title .~ "Swagger Sample App"
59 & description ?~ "This is a sample server Petstore server."
60 & termsOfService ?~ "http://swagger.io/terms/"
61 & contact ?~ contactExample
62 & license ?~ licenseExample
65infoExampleJSON :: Value
66infoExampleJSON = [aesonQQ|
68 "title": "Swagger Sample App",
69 "description": "This is a sample server Petstore server.",
70 "termsOfService": "http://swagger.io/terms/",
72 "name": "API Support",
73 "url": "http://www.swagger.io/support",
74 "email": "support@swagger.io"
78 "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
84-- =======================================================================
86-- =======================================================================
88contactExample :: Contact
89contactExample = mempty
90 & name ?~ "API Support"
91 & url ?~ URL "http://www.swagger.io/support"
92 & email ?~ "support@swagger.io"
94contactExampleJSON :: Value
95contactExampleJSON = [aesonQQ|
97 "name": "API Support",
98 "url": "http://www.swagger.io/support",
99 "email": "support@swagger.io"
103-- =======================================================================
105-- =======================================================================
107licenseExample :: License
108licenseExample = "Apache 2.0"
109 & url ?~ URL "http://www.apache.org/licenses/LICENSE-2.0.html"
111licenseExampleJSON :: Value
112licenseExampleJSON = [aesonQQ|
114 "name": "Apache 2.0",
115 "url": "http://www.apache.org/licenses/LICENSE-2.0.html"
120-- =======================================================================
122-- =======================================================================
124operationExample :: Operation
125operationExample = mempty
126 & tags .~ InsOrdHS.fromList ["pet"]
127 & summary ?~ "Updates a pet in the store with form data"
129 & operationId ?~ "updatePetWithForm"
130 & parameters .~ [Inline (mempty
132 & description ?~ "ID of pet that needs to be updated"
135 & schema ?~ Inline (mempty & type_ ?~ SwaggerString))]
136 & requestBody ?~ Inline (
137 mempty & content . at "application/x-www-form-urlencoded" ?~ (mempty & schema ?~ (Inline (mempty
138 & properties . at "petId" ?~ Inline (mempty
139 & description ?~ "Updated name of the pet"
140 & type_ ?~ SwaggerString)
141 & properties . at "status" ?~ Inline (mempty
142 & description ?~ "Updated status of the pet"
143 & type_ ?~ SwaggerString)))))
144 & at 200 ?~ "Pet updated."
145 & at 405 ?~ "Invalid input"
146 & security .~ [SecurityRequirement [("petstore_auth", ["write:pets", "read:pets"])]]
148operationExampleJSON :: Value
149operationExampleJSON = [aesonQQ|
154 "summary": "Updates a pet in the store with form data",
156 "operationId": "updatePetWithForm",
165 "description": "ID of pet that needs to be updated"
170 "application/x-www-form-urlencoded": {
175 "description": "Updated name of the pet"
179 "description": "Updated status of the pet"
188 "description": "Pet updated."
191 "description": "Invalid input"
205-- =======================================================================
207-- =======================================================================
209schemaPrimitiveExample :: Schema
210schemaPrimitiveExample = mempty
211 & type_ ?~ SwaggerString
214schemaPrimitiveExampleJSON :: Value
215schemaPrimitiveExampleJSON = [aesonQQ|
222schemaSimpleModelExample :: Schema
223schemaSimpleModelExample = mempty
224 & type_ ?~ SwaggerObject
225 & required .~ [ "name" ]
227 [ ("name", Inline (mempty & type_ ?~ SwaggerString))
228 , ("address", Ref (Reference "Address"))
229 , ("age", Inline $ mempty
231 & type_ ?~ SwaggerInteger
232 & format ?~ "int32" ) ]
234schemaSimpleModelExampleJSON :: Value
235schemaSimpleModelExampleJSON = [aesonQQ|
236{ "required": [ "name" ],
242 "$ref": "#/components/schemas/Address"
254schemaModelDictExample :: Schema
255schemaModelDictExample = mempty
256 & type_ ?~ SwaggerObject
257 & additionalProperties ?~ AdditionalPropertiesSchema (Inline (mempty & type_ ?~ SwaggerString))
259schemaModelDictExampleJSON :: Value
260schemaModelDictExampleJSON = [aesonQQ|
263 "additionalProperties": {
269schemaAdditionalExample :: Schema
270schemaAdditionalExample = mempty
271 & type_ ?~ SwaggerObject
272 & additionalProperties ?~ AdditionalPropertiesAllowed True
274schemaAdditionalExampleJSON :: Value
275schemaAdditionalExampleJSON = [aesonQQ|
278 "additionalProperties": true
282schemaWithExampleExample :: Schema
283schemaWithExampleExample = mempty
284 & type_ ?~ SwaggerObject
286 [ ("id", Inline $ mempty
287 & type_ ?~ SwaggerInteger
288 & format ?~ "int64" )
289 , ("name", Inline $ mempty
290 & type_ ?~ SwaggerString) ]
291 & required .~ [ "name" ]
292 & example ?~ [aesonQQ|
299schemaWithExampleExampleJSON :: Value
300schemaWithExampleExampleJSON = [aesonQQ|
322-- =======================================================================
324-- =======================================================================
326definitionsExample :: HashMap Text Schema
328 [ ("Category", mempty
329 & type_ ?~ SwaggerObject
331 [ ("id", Inline $ mempty
332 & type_ ?~ SwaggerInteger
334 , ("name", Inline (mempty & type_ ?~ SwaggerString)) ] )
336 & type_ ?~ SwaggerObject
338 [ ("id", Inline $ mempty
339 & type_ ?~ SwaggerInteger
341 , ("name", Inline (mempty & type_ ?~ SwaggerString)) ] ) ]
343definitionsExampleJSON :: Value
344definitionsExampleJSON = [aesonQQ|
373-- =======================================================================
374-- Parameters Definition object
375-- =======================================================================
377paramsDefinitionExample :: HashMap Text Param
378paramsDefinitionExample =
379 [ ("skipParam", mempty
381 & description ?~ "number of items to skip"
384 & schema ?~ Inline (mempty
385 & type_ ?~ SwaggerInteger
386 & format ?~ "int32" ))
387 , ("limitParam", mempty
389 & description ?~ "max records to return"
392 & schema ?~ Inline (mempty
393 & type_ ?~ SwaggerInteger
394 & format ?~ "int32" )) ]
396paramsDefinitionExampleJSON :: Value
397paramsDefinitionExampleJSON = [aesonQQ|
402 "description": "number of items to skip",
412 "description": "max records to return",
422-- =======================================================================
423-- Responses Definition object
424-- =======================================================================
426responsesDefinitionExample :: HashMap Text Response
427responsesDefinitionExample =
428 [ ("NotFound", mempty & description .~ "Entity not found.")
429 , ("IllegalInput", mempty & description .~ "Illegal input for operation.") ]
431responsesDefinitionExampleJSON :: Value
432responsesDefinitionExampleJSON = [aesonQQ|
435 "description": "Entity not found."
438 "description": "Illegal input for operation."
443-- =======================================================================
444-- Responses Definition object
445-- =======================================================================
447securityDefinitionsExample :: SecurityDefinitions
448securityDefinitionsExample = SecurityDefinitions
449 [ ("api_key", SecurityScheme
450 { _securitySchemeType = SecuritySchemeApiKey (ApiKeyParams "api_key" ApiKeyHeader)
451 , _securitySchemeDescription = Nothing })
452 , ("petstore_auth", SecurityScheme
453 { _securitySchemeType = SecuritySchemeOAuth2 (mempty & implicit ?~ OAuth2Flow
454 { _oAuth2Params = OAuth2ImplicitFlow "http://swagger.io/api/oauth/dialog"
455 , _oAath2RefreshUrl = Nothing
457 [ ("write:pets", "modify pets in your account")
458 , ("read:pets", "read your pets") ] } )
459 , _securitySchemeDescription = Nothing }) ]
461securityDefinitionsExampleJSON :: Value
462securityDefinitionsExampleJSON = [aesonQQ|
474 "write:pets": "modify pets in your account",
475 "read:pets": "read your pets"
477 "authorizationUrl": "http://swagger.io/api/oauth/dialog"
485oAuth2SecurityDefinitionsReadExample :: SecurityDefinitions
486oAuth2SecurityDefinitionsReadExample = SecurityDefinitions
487 [ ("petstore_auth", SecurityScheme
488 { _securitySchemeType = SecuritySchemeOAuth2 (mempty & implicit ?~ OAuth2Flow
489 { _oAuth2Params = OAuth2ImplicitFlow "http://swagger.io/api/oauth/dialog"
490 , _oAath2RefreshUrl = Nothing
492 [ ("read:pets", "read your pets") ] } )
493 , _securitySchemeDescription = Nothing })
496oAuth2SecurityDefinitionsWriteExample :: SecurityDefinitions
497oAuth2SecurityDefinitionsWriteExample = SecurityDefinitions
498 [ ("petstore_auth", SecurityScheme
499 { _securitySchemeType = SecuritySchemeOAuth2 (mempty & implicit ?~ OAuth2Flow
500 { _oAuth2Params = OAuth2ImplicitFlow "http://swagger.io/api/oauth/dialog"
501 , _oAath2RefreshUrl = Nothing
503 [ ("write:pets", "modify pets in your account") ] } )
504 , _securitySchemeDescription = Nothing })
507oAuth2SecurityDefinitionsExample :: SecurityDefinitions
508oAuth2SecurityDefinitionsExample =
509 oAuth2SecurityDefinitionsWriteExample <>
510 oAuth2SecurityDefinitionsReadExample
512oAuth2SecurityDefinitionsExampleJSON :: Value
513oAuth2SecurityDefinitionsExampleJSON = [aesonQQ|
520 "write:pets": "modify pets in your account",
521 "read:pets": "read your pets"
523 "authorizationUrl": "http://swagger.io/api/oauth/dialog"
530-- =======================================================================
532-- =======================================================================
534emptyPathsFieldExample :: Swagger
535emptyPathsFieldExample = mempty
537emptyPathsFieldExampleJSON :: Value
538emptyPathsFieldExampleJSON = [aesonQQ|
541 "info": {"version": "", "title": ""},
547swaggerExample :: Swagger
548swaggerExample = mempty
550 -- & schemes ?~ [Http]
553 & title .~ "Todo API"
555 & license._Just.url ?~ URL "http://mit.com"
556 & description ?~ "This is an API that tests servant-swagger support for a Todo API")
557 & paths.at "/todo/{id}" ?~ (mempty & get ?~ ((mempty :: Operation)
558 & responses . at 200 ?~ Inline (mempty
559 & description .~ "OK"
560 & content . at "application/json" ?~ (mempty
561 & schema ?~ Inline (mempty
562 & type_ ?~ SwaggerObject
563 & example ?~ [aesonQQ|
566 "description": "get milk"
568 & description ?~ "This is some real Todo right here"
570 [ ("created", Inline $ mempty
571 & type_ ?~ SwaggerInteger
573 , ("description", Inline (mempty & type_ ?~ SwaggerString))])))
578 & description ?~ "TodoId param"
580 & schema ?~ Inline (mempty
581 & type_ ?~ SwaggerString ) ]
582 & tags .~ InsOrdHS.fromList [ "todo" ] ))
584swaggerExampleJSON :: Value
585swaggerExampleJSON = [aesonQQ|
592 "url": "http://mit.com",
595 "description": "This is an API that tests servant-swagger support for a Todo API"
611 "description": "TodoId param"
617 "application/json": {
621 "description": "get milk"
624 "description": "This is some real Todo right here",
647petstoreExampleJSON :: Value
648petstoreExampleJSON = [aesonQQ|
653 "title": "Swagger Petstore",
660 "url": "http://petstore.swagger.io/v1"
666 "summary": "List all pets",
667 "operationId": "listPets",
675 "description": "How many items to return at one time (max 100)",
685 "description": "A paged array of pets",
688 "description": "A link to the next page of responses",
695 "application/json": {
722 "description": "unexpected error",
724 "application/json": {
747 "summary": "Create a pet",
748 "operationId": "createPets",
754 "description": "Null response"
757 "description": "unexpected error",
759 "application/json": {
784 "summary": "Info for a specific pet",
785 "operationId": "showPetById",
794 "description": "The id of the pet to retrieve",
802 "description": "Expected response to a valid request",
804 "application/json": {
828 "description": "unexpected error",
830 "application/json": {
918compositionSchemaExample :: Schema
919compositionSchemaExample = mempty
920 & type_ ?~ SwaggerObject
921 & Data.Swagger.allOf ?~ [
922 Ref (Reference "Other")
924 & type_ ?~ SwaggerObject
926 [ ("greet", Inline $ mempty
927 & type_ ?~ SwaggerString) ])
930compositionSchemaExampleJSON :: Value
931compositionSchemaExampleJSON = [aesonQQ|
936 "$ref": "#/components/schemas/Other"
941 "greet": { "type": "string" }
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list