From e7c711002aaaeaa94c758fe2f26bf50aceb4aef7 Mon Sep 17 00:00:00 2001 From: Simone Scarduzio Date: Thu, 21 Jan 2016 14:37:47 +0000 Subject: [PATCH 1/3] The correct HTTP status code for integrity constraint violation is 509, fixes #469 --- src/PostgREST/Error.hs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/PostgREST/Error.hs b/src/PostgREST/Error.hs index 94a8f0554..d1a33f3d0 100644 --- a/src/PostgREST/Error.hs +++ b/src/PostgREST/Error.hs @@ -54,6 +54,7 @@ httpStatus (H.TxError (P.ErroneousResult codeBS _ _ _)) = '0':'9':_ -> HT.status500 -- triggered action exception '0':'L':_ -> HT.status403 -- invalid grantor '0':'P':_ -> HT.status403 -- invalid role specification + '2':'3':_ -> HT.status409 -- Integrity Constraint Violation '2':'5':_ -> HT.status500 -- invalid tx state '2':'8':_ -> HT.status403 -- invalid auth specification '2':'D':_ -> HT.status500 -- invalid tx termination From b5e6a93b32cefdbf9adc8dd6200ee19ba9b80a66 Mon Sep 17 00:00:00 2001 From: Simone Scarduzio Date: Thu, 21 Jan 2016 15:21:30 +0000 Subject: [PATCH 2/3] Being more specific --- src/PostgREST/Error.hs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PostgREST/Error.hs b/src/PostgREST/Error.hs index d1a33f3d0..cdd12761e 100644 --- a/src/PostgREST/Error.hs +++ b/src/PostgREST/Error.hs @@ -54,7 +54,8 @@ httpStatus (H.TxError (P.ErroneousResult codeBS _ _ _)) = '0':'9':_ -> HT.status500 -- triggered action exception '0':'L':_ -> HT.status403 -- invalid grantor '0':'P':_ -> HT.status403 -- invalid role specification - '2':'3':_ -> HT.status409 -- Integrity Constraint Violation + "23503" -> HT.status409 -- foreign_key_violation + "23505" -> HT.status409 -- unique_violation '2':'5':_ -> HT.status500 -- invalid tx state '2':'8':_ -> HT.status403 -- invalid auth specification '2':'D':_ -> HT.status500 -- invalid tx termination From 74d76c690f514ebbfa167325e88360c63df7e2bb Mon Sep 17 00:00:00 2001 From: Simone Scarduzio Date: Sun, 24 Jan 2016 14:50:25 +0000 Subject: [PATCH 3/3] Adding two test cases for 469 --- test/Feature/InsertSpec.hs | 12 ++++++++++++ test/Feature/StructureSpec.hs | 1 + test/fixtures/data.sql | 2 ++ test/fixtures/privileges.sql | 1 + test/fixtures/schema.sql | 5 +++++ 5 files changed, 21 insertions(+) diff --git a/test/Feature/InsertSpec.hs b/test/Feature/InsertSpec.hs index b1f8f0df5..17ea3aa04 100644 --- a/test/Feature/InsertSpec.hs +++ b/test/Feature/InsertSpec.hs @@ -124,6 +124,18 @@ spec struct pool = beforeAll_ resetDb $ around (withApp cfgDefault struct pool) it "fails with 400 and error" $ post "/simple_pk" "}{ x = 2" `shouldRespondWith` 400 + context "with valid json payload" $ + it "succeeds and returns 201 created" $ + post "/simple_pk" [json| { "k":"k1", "extra":"e1" } |] `shouldRespondWith` 201 + + context "attempting to insert a row with the same primary key" $ + it "fails returning a 409 Conflict" $ + post "/simple_pk" [json| { "k":"k1", "extra":"e1" } |] `shouldRespondWith` 409 + + context "attempting to insert a row with confliting unique constraint" $ + it "fails returning a 409 Conflict" $ + post "/withUnique" [json| { "uni":"nodup", "extra":"e2" } |] `shouldRespondWith` 409 + context "jsonb" $ do it "serializes nested object" $ do let inserted = [json| { "data": { "foo":"bar" } } |] diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index e13f207b0..3fca1ce3f 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -45,6 +45,7 @@ spec struct pool = around (withApp cfgDefault struct pool) $ do , {"schema":"test","name":"users","insertable":true} , {"schema":"test","name":"users_projects","insertable":true} , {"schema":"test","name":"users_tasks","insertable":true} + , {"schema":"test","name":"withUnique","insertable":true} ] |] {matchStatus = 200} diff --git a/test/fixtures/data.sql b/test/fixtures/data.sql index 3cc537eb3..63195049f 100644 --- a/test/fixtures/data.sql +++ b/test/fixtures/data.sql @@ -266,6 +266,8 @@ INSERT INTO "Escap3e;" VALUES (1), (2), (3), (4), (5); TRUNCATE TABLE "ghostBusters" CASCADE; INSERT INTO "ghostBusters" VALUES (1), (3), (5); +TRUNCATE TABLE "withUnique" CASCADE; +INSERT INTO "withUnique" VALUES ('nodup', 'blah') -- -- PostgreSQL database dump complete -- diff --git a/test/fixtures/privileges.sql b/test/fixtures/privileges.sql index cebb5ef0d..61551a0f7 100644 --- a/test/fixtures/privileges.sql +++ b/test/fixtures/privileges.sql @@ -34,6 +34,7 @@ GRANT ALL ON TABLE , users_tasks , "Escap3e;" , "ghostBusters" + , "withUnique" 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 08d264262..f4d2eed04 100755 --- a/test/fixtures/schema.sql +++ b/test/fixtures/schema.sql @@ -599,6 +599,11 @@ CREATE TABLE "ghostBusters" ( "escapeId" integer not null references "Escap3e;"("so6meIdColumn") ); +CREATE TABLE "withUnique" ( + uni text UNIQUE, + extra text +); + -- -- Name: id; Type: DEFAULT; Schema: test; Owner: -