openapi-hs-4.0.0: test/Data/OpenApi/MigrationSpec.hs
{-# LANGUAGE OverloadedStrings #-}
-- this spec intentionally exercises the deprecated migration helpers
{-# OPTIONS_GHC -Wno-deprecations #-}
-- | Tests for the 3.0 -> 3.1 'Data.Aeson.Value'-layer migration helpers (EP-7).
module Data.OpenApi.MigrationSpec where
import Data.Aeson (Value, decode, encode, object, (.=))
import Data.HashMap.Strict.InsOrd.Compat qualified as InsOrdHashMap
import Data.OpenApi
import Data.OpenApi.Internal
import Data.OpenApi.Migration
( migrate30ExclusiveBoundsValue,
migrate30ItemsArrayValue,
migrate30NullableValue,
migrate30To31,
)
import Data.Text (Text)
import Test.Hspec
spec :: Spec
spec = describe "3.0 to 3.1 migration" $ do
it "converts nullable:true to a type array" $ do
let v30 = object ["type" .= ("string" :: Text), "nullable" .= True]
(decode (encode (migrate30NullableValue v30)) :: Maybe Schema)
`shouldBe` Just (mempty {_schemaType = Just (OpenApiTypeArray [OpenApiString, OpenApiNull])})
it "drops nullable:false without touching type" $ do
let v30 = object ["type" .= ("string" :: Text), "nullable" .= False]
(decode (encode (migrate30NullableValue v30)) :: Maybe Schema)
`shouldBe` Just (mempty {_schemaType = Just (OpenApiTypeSingle OpenApiString)})
it "rewrites boolean exclusiveMaximum to a numeric bound (dropping maximum)" $ do
let v30 = object ["maximum" .= (100 :: Int), "exclusiveMaximum" .= True]
(decode (encode (migrate30ExclusiveBoundsValue v30)) :: Maybe Schema)
`shouldBe` Just (mempty {_schemaExclusiveMaximum = Just 100})
it "keeps maximum when exclusiveMaximum:false" $ do
let v30 = object ["maximum" .= (100 :: Int), "exclusiveMaximum" .= False]
(decode (encode (migrate30ExclusiveBoundsValue v30)) :: Maybe Schema)
`shouldBe` Just (mempty {_schemaMaximum = Just 100})
it "rewrites a tuple items array into prefixItems + items:false" $ do
let v30 =
object
[ "items"
.= ( [ object ["type" .= ("string" :: Text)],
object ["type" .= ("number" :: Text)]
] ::
[Value]
)
]
expected =
mempty
{ _schemaPrefixItems =
Just
[ Inline (mempty {_schemaType = Just (OpenApiTypeSingle OpenApiString)}),
Inline (mempty {_schemaType = Just (OpenApiTypeSingle OpenApiNumber)})
],
_schemaItems = Just (OpenApiItemsBoolean False)
}
(decode (encode (migrate30ItemsArrayValue v30)) :: Maybe Schema) `shouldBe` Just expected
it "migrate30To31 recurses into nested properties" $ do
let v30 =
object
[ "type" .= ("object" :: Text),
"properties"
.= object
["n" .= object ["type" .= ("string" :: Text), "nullable" .= True]]
]
nestedType = do
s <- decode (encode (migrate30To31 v30)) :: Maybe Schema
pn <- InsOrdHashMap.lookup ("n" :: Text) (_schemaProperties s)
case pn of
Inline ns -> _schemaType ns
_ -> Nothing
-- the nested property schema's nullable became a 3.1 type array
nestedType `shouldBe` Just (OpenApiTypeArray [OpenApiString, OpenApiNull])