From cefbe8f07f27545873c3bfe01ad88bdc3533fd1f Mon Sep 17 00:00:00 2001 From: fpusch Date: Fri, 29 Mar 2019 17:09:42 +0100 Subject: [PATCH] Add numeric and character types to OpenAPI spec (#1259) * Add numeric and character types * Remove decimal type mapping It is treated as numeric by PostgreSQL so the mapping was redundant. --- CHANGELOG.md | 1 + src/PostgREST/OpenAPI.hs | 16 ++-- test/Feature/StructureSpec.hs | 154 +++++++++++++++++++++++++++++++++- test/fixtures/privileges.sql | 1 + test/fixtures/schema.sql | 13 +++ 5 files changed, 179 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cfe33de0..65375073c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - #1223, Fix incorrect OpenAPI externalDocs url - @steve-chavez - #1221, Fix embedding other resources when having a self join - @steve-chavez - #1242, Fix embedding a view having a select in a where - @steve-chavez +- #1238, Fix PostgreSQL to OpenAPI type mappings for numeric and character types - @fpusch ## [5.2.0] - 2018-12-12 diff --git a/src/PostgREST/OpenAPI.hs b/src/PostgREST/OpenAPI.hs index 08dd0f38d..559435620 100644 --- a/src/PostgREST/OpenAPI.hs +++ b/src/PostgREST/OpenAPI.hs @@ -34,11 +34,17 @@ makeMimeList :: [ContentType] -> MimeList makeMimeList cs = MimeList $ map (fromString . toS . toMime) cs toSwaggerType :: Text -> SwaggerType t -toSwaggerType "text" = SwaggerString -toSwaggerType "integer" = SwaggerInteger -toSwaggerType "boolean" = SwaggerBoolean -toSwaggerType "numeric" = SwaggerNumber -toSwaggerType _ = SwaggerString +toSwaggerType "character varying" = SwaggerString +toSwaggerType "character" = SwaggerString +toSwaggerType "text" = SwaggerString +toSwaggerType "boolean" = SwaggerBoolean +toSwaggerType "smallint" = SwaggerInteger +toSwaggerType "integer" = SwaggerInteger +toSwaggerType "bigint" = SwaggerInteger +toSwaggerType "numeric" = SwaggerNumber +toSwaggerType "real" = SwaggerNumber +toSwaggerType "double precision" = SwaggerNumber +toSwaggerType _ = SwaggerString makeTableDef :: [PrimaryKey] -> (Table, [Column], [Text]) -> (Text, Schema) makeTableDef pks (t, cs, _) = diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index e15017798..d75c7ff87 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -219,6 +219,158 @@ spec = do ] |] + describe "PostgreSQL to Swagger Type Mapping" $ do + + it "character varying to string" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_character_varying" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "character varying", + "type": "string" + } + |] + it "character(1) to string" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_character" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "maxLength": 1, + "format": "character", + "type": "string" + } + |] + + it "text to string" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_text" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "text", + "type": "string" + } + |] + + it "boolean to boolean" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_boolean" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "boolean", + "type": "boolean" + } + |] + + it "smallint to integer" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_smallint" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "smallint", + "type": "integer" + } + |] + + it "integer to integer" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_integer" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "integer", + "type": "integer" + } + |] + + it "bigint to integer" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_bigint" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "bigint", + "type": "integer" + } + |] + + it "numeric to number" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_numeric" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "numeric", + "type": "number" + } + |] + + it "real to number" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_real" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "real", + "type": "number" + } + |] + + it "double_precision to number" $ do + r <- simpleBody <$> get "/" + + let types = r ^? key "definitions" . key "openapi_types" . key "properties" . key "a_double_precision" + + liftIO $ + + types `shouldBe` Just + [aesonQQ| + { + "format": "double precision", + "type": "number" + } + |] + describe "RPC" $ do it "includes function summary/description and body schema for arguments" $ do @@ -249,7 +401,7 @@ spec = do "properties": { "double": { "format": "double precision", - "type": "string" + "type": "number" }, "varchar": { "format": "character varying", diff --git a/test/fixtures/privileges.sql b/test/fixtures/privileges.sql index e31123f74..4e879f2f2 100644 --- a/test/fixtures/privileges.sql +++ b/test/fixtures/privileges.sql @@ -100,6 +100,7 @@ GRANT ALL ON TABLE , "Server Today" , pgrst_reserved_chars , authors_w_entities + , openapi_types TO postgrest_test_anonymous; GRANT INSERT ON TABLE insertonly TO postgrest_test_anonymous; diff --git a/test/fixtures/schema.sql b/test/fixtures/schema.sql index 8ac8942d4..4c6cd0ce3 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -1647,3 +1647,16 @@ create table test.pgrst_reserved_chars ( "a.dotted.column" text, " col w space " text ); + +CREATE TABLE test.openapi_types( + "a_character_varying" character varying, + "a_character" character(1), + "a_text" text, + "a_boolean" boolean, + "a_smallint" smallint, + "a_integer" integer, + "a_bigint" bigint, + "a_numeric" numeric, + "a_real" real, + "a_double_precision" double precision +); \ No newline at end of file