Merge pull request #410 from diogob/refactor_tests

Refactor tests
This commit is contained in:
Joe Nelson
2015-12-08 13:43:02 -08:00
15 changed files with 960 additions and 629 deletions
+1 -3
View File
@@ -10,9 +10,7 @@ import SpecHelper
-- }}}
spec :: Spec
spec = beforeAll
(clearTable "postgrest.auth") . afterAll_ (clearTable "postgrest.auth")
$ around (withApp cfgDefault)
spec = around (withApp cfgDefault)
$ describe "authorization" $ do
it "hides tables that anonymous does not own" $
+1 -1
View File
@@ -7,7 +7,7 @@ import SpecHelper
import Network.HTTP.Types
spec :: Spec
spec = beforeAll (clearTable "items" >> createItems 15) . afterAll_ (clearTable "items")
spec = beforeAll resetDb
. around (withApp cfgDefault) $
describe "Deleting" $ do
context "existing record" $ do
+4 -5
View File
@@ -17,7 +17,7 @@ import Control.Monad (replicateM_)
import TestTypes(IncPK(..), CompoundPK(..))
spec :: Spec
spec = afterAll_ resetDb $ around (withApp cfgDefault) $ do
spec = beforeAll_ resetDb $ around (withApp cfgDefault) $ do
describe "Posting new record" $ do
after_ (clearTable "menagerie") . context "disparate csv types" $ do
it "accepts disparate json types" $ do
@@ -301,17 +301,16 @@ spec = afterAll_ resetDb $ around (withApp cfgDefault) $ do
context "on an empty table" $
it "indicates no records found to update" $
request methodPatch "/simple_pk" []
request methodPatch "/empty_table" []
[json| { "extra":20 } |]
`shouldRespondWith` 404
context "in a nonempty table" . before_ (clearTable "items" >> createItems 15) .
after_ (clearTable "items") $ do
context "in a nonempty table" $ do
it "can update a single item" $ do
g <- get "/items?id=eq.42"
liftIO $ simpleHeaders g
`shouldSatisfy` matchHeader "Content-Range" "\\*/0"
request methodPatch "/items?id=eq.1" []
request methodPatch "/items?id=eq.2" []
[json| { "id":42 } |]
`shouldRespondWith` ResponseMatcher {
matchBody = Nothing,
+1 -2
View File
@@ -10,8 +10,7 @@ import SpecHelper
spec :: Spec
spec =
beforeAll (clearTable "items" >> createItems 15)
. afterAll_ (clearTable "items")
beforeAll resetDb
. around (withApp $ cfgLimitRows 3) $
describe "Requesting many items with server limits enabled" $ do
it "restricts results" $
+2 -14
View File
@@ -11,18 +11,7 @@ import Text.Heredoc
spec :: Spec
spec =
beforeAll (clearTable "items" >> createItems 15)
. beforeAll clearProjectsTable
. beforeAll (clearTable "complex_items" >> createComplexItems)
. beforeAll (clearTable "nullable_integer" >> createNullInteger)
. beforeAll (
clearTable "no_pk" >>
createNulls 2 >>
createLikableStrings >>
createJsonData)
. afterAll_ (clearTable "items" >> clearTable "complex_items" >> clearTable "no_pk" >> clearTable "simple_pk")
. around (withApp cfgDefault) $ do
spec = around (withApp cfgDefault) $ do
describe "Querying a table with a column called count" $
it "should not confuse count column with pg_catalog.count aggregate" $
@@ -355,8 +344,7 @@ spec =
[json| [{"data": {"id": 1, "foo": {"bar": "baz"}}}] |]
describe "remote procedure call" $ do
context "a proc that returns a set" . before_ (clearTable "items" >> createItems 10) .
after_ (clearTable "items") $
context "a proc that returns a set" $
it "returns proper json" $
post "/rpc/getitemrange" [json| { "min": 2, "max": 4 } |] `shouldRespondWith`
[json| [ {"id": 3}, {"id":4} ] |]
+1 -1
View File
@@ -9,7 +9,7 @@ import Network.Wai.Test (SResponse(simpleHeaders,simpleStatus))
import SpecHelper
spec :: Spec
spec = beforeAll (clearTable "items" >> createItems 15) . afterAll_ (clearTable "items")
spec = beforeAll resetDb
. around (withApp cfgDefault) $
describe "GET /items" $ do
+2 -1
View File
@@ -257,7 +257,8 @@ spec = around (withApp cfgDefault) $ do
}
|]
it "includes all information on views for renamed columns, and raises relations to correct schema" $
it "includes all information on views for renamed columns, and raises relations to correct schema" $ do
pendingWith "have to resolve issue #107"
request methodOptions "/articleStars" [] ""
`shouldRespondWith` [json|
{
+1 -1
View File
@@ -5,4 +5,4 @@ import SpecHelper
import Spec
main :: IO ()
main = resetDb >> hspec spec
main = setupDb >> hspec spec
+13 -89
View File
@@ -14,7 +14,6 @@ import Data.Text hiding (map)
import qualified Data.Vector as V
import Data.Time.Clock.POSIX (getPOSIXTime)
import Control.Monad (void)
import Control.Applicative
import Network.HTTP.Types.Header (Header, ByteRange, renderByteRange,
hRange, hAuthorization, hAccept)
@@ -26,8 +25,6 @@ import qualified Data.ByteString.Char8 as BS
import System.Process (readProcess)
import Web.JWT (secret)
import qualified Data.Aeson.Types as J
import PostgREST.App (app)
import PostgREST.Config (AppConfig(..))
import PostgREST.Middleware
@@ -35,19 +32,16 @@ import PostgREST.Error(pgErrResponse)
import PostgREST.DbStructure
dbString :: String
dbString = "postgres://postgrest_test@localhost:5432/postgrest_test"
dbString = "postgres://postgrest_test_authenticator@localhost:5432/postgrest_test"
isLeft :: Either a b -> Bool
isLeft (Left _ ) = True
isLeft _ = False
cfg :: String -> Maybe Int -> AppConfig
cfg conStr = AppConfig conStr 3000 "postgrest_test_anonymous" "test" (secret "safe") 10
cfgDefault :: AppConfig
cfgDefault = AppConfig dbString 3000 "postgrest_anonymous" "test" (secret "safe") 10 Nothing
cfgDefault = cfg dbString Nothing
cfgLimitRows :: Int -> AppConfig
cfgLimitRows limit =
AppConfig dbString 3000 "postgrest_anonymous" "test"
(secret "safe") 10 (Just limit)
cfgLimitRows = cfg dbString . Just
testPoolOpts :: PoolSettings
testPoolOpts = fromMaybe (error "bad settings") $ H.poolSettings 1 30
@@ -73,26 +67,21 @@ withApp config perform = do
where middle = defaultMiddle
resetDb :: IO ()
resetDb = do
pool :: H.Pool P.Postgres
<- H.acquirePool pgSettings testPoolOpts
void . liftIO $ H.session pool $
H.tx Nothing $ do
H.unitEx [H.stmt| drop schema if exists test cascade |]
H.unitEx [H.stmt| drop schema if exists private cascade |]
H.unitEx [H.stmt| drop schema if exists postgrest cascade |]
setupDb :: IO ()
setupDb = do
void $ readProcess "psql" ["-d", "postgres", "-a", "-f", "test/fixtures/database.sql"] []
loadFixture "roles"
loadFixture "schema"
loadFixture "privileges"
resetDb
resetDb :: IO ()
resetDb = loadFixture "data"
loadFixture :: FilePath -> IO()
loadFixture name =
void $ readProcess "psql" ["-U", "postgrest_test", "-d", "postgrest_test", "-a", "-f", "test/fixtures/" ++ name ++ ".sql"] []
rangeHdrs :: ByteRange -> [Header]
rangeHdrs r = [rangeUnit, (hRange, renderByteRange r)]
@@ -121,69 +110,4 @@ clearTable :: Text -> IO ()
clearTable table = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing $
H.unitEx $ B.Stmt ("delete from test."<>table) V.empty True
clearProjectsTable :: IO ()
clearProjectsTable = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing $
H.unitEx $ B.Stmt "delete from test.projects where id > 4" V.empty True
createItems :: Int -> IO ()
createItems n = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing txn
where
txn = mapM_ H.unitEx stmts
stmts = map [H.stmt|insert into test.items (id) values (?)|] [1..n]
createComplexItems :: IO ()
createComplexItems = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing txn
where
txn = mapM_ H.unitEx stmts
stmts = getZipList $ [H.stmt|insert into test.complex_items (id, name, settings, arr_data) values (?,?,?,?)|]
<$> ZipList ([1..3]::[Int])
<*> ZipList (["One", "Two", "Three"]::[Text])
<*> ZipList [jobj,jobj,jobj]
<*> ZipList ([[1], [1,2], [1,2,3]]::[[Int]])
jobj = J.object [("foo", J.object [("int", J.Number 1),("bar", J.String "baz")])]
createNulls :: Int -> IO ()
createNulls n = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing txn
where
txn = mapM_ H.unitEx (stmt':stmts)
stmt' = [H.stmt|insert into test.no_pk (a,b) values (null,null)|]
stmts = map [H.stmt|insert into test.no_pk (a,b) values (?,0)|] [1..n]
createNullInteger :: IO ()
createNullInteger = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing $
H.unitEx $ [H.stmt| insert into "test".nullable_integer (a) values (null) |]
createLikableStrings :: IO ()
createLikableStrings = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing $ do
H.unitEx $ insertSimplePk "xyyx" "u"
H.unitEx $ insertSimplePk "xYYx" "v"
where
insertSimplePk :: Text -> Text -> H.Stmt P.Postgres
insertSimplePk = [H.stmt|insert into test.simple_pk (k, extra) values (?,?)|]
createJsonData :: IO ()
createJsonData = do
pool <- testPool
void . liftIO $ H.session pool $ H.tx Nothing $
H.unitEx $
[H.stmt|
insert into test.json (data) values (?)
|]
(J.object [("id", J.Number 1)
,("foo", J.object [("bar", J.String "baz")])
])
H.unitEx $ B.Stmt ("truncate table test." <> table <> " cascade") V.empty True
+1 -1
View File
@@ -60,7 +60,7 @@ spec = around dbWithSchema $ do
quickALQuery c "select * from \"1\".items where id = ?" [snd row]
`shouldReturn` [[row]]
let {user = "jdoe"; pass = "secret"; role = "test_default_role"}
let {user = "jdoe"; pass = "secret"; role = "postgrest_test_default_role"}
describe "addUser" $ do
it "adds a correct user to the right table" $ \conn -> do
addUser user pass role conn
+266
View File
@@ -0,0 +1,266 @@
--
-- PostgreSQL database dump
--
-- Dumped from database version 9.5beta1
-- Dumped by pg_dump version 9.5beta1
SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
SET search_path = postgrest, pg_catalog;
--
-- Data for Name: auth; Type: TABLE DATA; Schema: postgrest; Owner: -
--
TRUNCATE TABLE auth CASCADE;
INSERT INTO auth VALUES ('jdoe', 'postgrest_test_author', '1234 ');
SET search_path = private, pg_catalog;
--
-- Data for Name: articles; Type: TABLE DATA; Schema: private; Owner: -
--
TRUNCATE TABLE articles CASCADE;
INSERT INTO articles VALUES (1, 'No… It''s a thing; it''s like a plan, but with more greatness.', 'diogo');
INSERT INTO articles VALUES (2, 'Stop talking, brain thinking. Hush.', 'diogo');
INSERT INTO articles VALUES (3, 'It''s a fez. I wear a fez now. Fezes are cool.', 'diogo');
SET search_path = test, pg_catalog;
--
-- Data for Name: users; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE users CASCADE;
INSERT INTO users VALUES (1, 'Angela Martin');
INSERT INTO users VALUES (2, 'Michael Scott');
INSERT INTO users VALUES (3, 'Dwight Schrute');
SET search_path = private, pg_catalog;
--
-- Data for Name: article_stars; Type: TABLE DATA; Schema: private; Owner: -
--
TRUNCATE TABLE article_stars CASCADE;
INSERT INTO article_stars VALUES (1, 1, '2015-12-08 04:22:57.472738');
INSERT INTO article_stars VALUES (1, 2, '2015-12-08 04:22:57.472738');
INSERT INTO article_stars VALUES (2, 3, '2015-12-08 04:22:57.472738');
INSERT INTO article_stars VALUES (3, 2, '2015-12-08 04:22:57.472738');
INSERT INTO article_stars VALUES (1, 3, '2015-12-08 04:22:57.472738');
SET search_path = test, pg_catalog;
--
-- Data for Name: authors_only; Type: TABLE DATA; Schema: test; Owner: -
--
--
-- Data for Name: auto_incrementing_pk; Type: TABLE DATA; Schema: test; Owner: -
--
--
-- Name: auto_incrementing_pk_id_seq; Type: SEQUENCE SET; Schema: test; Owner: -
--
SELECT pg_catalog.setval('auto_incrementing_pk_id_seq', 1, true);
--
-- Data for Name: clients; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE clients CASCADE;
INSERT INTO clients VALUES (1, 'Microsoft');
INSERT INTO clients VALUES (2, 'Apple');
--
-- Data for Name: projects; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE projects CASCADE;
INSERT INTO projects VALUES (1, 'Windows 7', 1);
INSERT INTO projects VALUES (2, 'Windows 10', 1);
INSERT INTO projects VALUES (3, 'IOS', 2);
INSERT INTO projects VALUES (4, 'OSX', 2);
--
-- Data for Name: tasks; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE tasks CASCADE;
INSERT INTO tasks VALUES (1, 'Design w7', 1);
INSERT INTO tasks VALUES (2, 'Code w7', 1);
INSERT INTO tasks VALUES (3, 'Design w10', 2);
INSERT INTO tasks VALUES (4, 'Code w10', 2);
INSERT INTO tasks VALUES (5, 'Design IOS', 3);
INSERT INTO tasks VALUES (6, 'Code IOS', 3);
INSERT INTO tasks VALUES (7, 'Design OSX', 4);
INSERT INTO tasks VALUES (8, 'Code OSX', 4);
--
-- Data for Name: users_tasks; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE users_tasks CASCADE;
INSERT INTO users_tasks VALUES (1, 1);
INSERT INTO users_tasks VALUES (1, 2);
INSERT INTO users_tasks VALUES (1, 3);
INSERT INTO users_tasks VALUES (1, 4);
INSERT INTO users_tasks VALUES (2, 5);
INSERT INTO users_tasks VALUES (2, 6);
INSERT INTO users_tasks VALUES (2, 7);
INSERT INTO users_tasks VALUES (3, 1);
INSERT INTO users_tasks VALUES (3, 5);
--
-- Data for Name: comments; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE comments CASCADE;
INSERT INTO comments VALUES (1, 1, 2, 6, 'Needs to be delivered ASAP');
--
-- Data for Name: complex_items; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE complex_items CASCADE;
INSERT INTO complex_items VALUES (1, 'One', '{"foo":{"int":1,"bar":"baz"}}', '{1}');
INSERT INTO complex_items VALUES (2, 'Two', '{"foo":{"int":1,"bar":"baz"}}', '{1,2}');
INSERT INTO complex_items VALUES (3, 'Three', '{"foo":{"int":1,"bar":"baz"}}', '{1,2,3}');
--
-- Data for Name: compound_pk; Type: TABLE DATA; Schema: test; Owner: -
--
--
-- Data for Name: simple_pk; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE simple_pk CASCADE;
INSERT INTO simple_pk VALUES ('xyyx', 'u');
INSERT INTO simple_pk VALUES ('xYYx', 'v');
--
-- Data for Name: has_fk; Type: TABLE DATA; Schema: test; Owner: -
--
--
-- Name: has_fk_id_seq; Type: SEQUENCE SET; Schema: test; Owner: -
--
SELECT pg_catalog.setval('has_fk_id_seq', 1, false);
--
-- Data for Name: items; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE items CASCADE;
INSERT INTO items VALUES (1);
INSERT INTO items VALUES (2);
INSERT INTO items VALUES (3);
INSERT INTO items VALUES (4);
INSERT INTO items VALUES (5);
INSERT INTO items VALUES (6);
INSERT INTO items VALUES (7);
INSERT INTO items VALUES (8);
INSERT INTO items VALUES (9);
INSERT INTO items VALUES (10);
INSERT INTO items VALUES (11);
INSERT INTO items VALUES (12);
INSERT INTO items VALUES (13);
INSERT INTO items VALUES (14);
INSERT INTO items VALUES (15);
--
-- Name: items_id_seq; Type: SEQUENCE SET; Schema: test; Owner: -
--
SELECT pg_catalog.setval('items_id_seq', 1, true);
--
-- Data for Name: json; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE json CASCADE;
INSERT INTO json VALUES ('{"foo":{"bar":"baz"},"id":1}');
--
-- Data for Name: menagerie; Type: TABLE DATA; Schema: test; Owner: -
--
--
-- Data for Name: no_pk; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE no_pk CASCADE;
INSERT INTO no_pk VALUES (NULL, NULL);
INSERT INTO no_pk VALUES ('1', '0');
INSERT INTO no_pk VALUES ('2', '0');
--
-- Data for Name: nullable_integer; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE nullable_integer CASCADE;
INSERT INTO nullable_integer VALUES (NULL);
--
-- Data for Name: tsearch; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE tsearch CASCADE;
INSERT INTO tsearch VALUES ('''bar'':2 ''foo'':1');
INSERT INTO tsearch VALUES ('''baz'':1 ''qux'':2');
--
-- Data for Name: users_projects; Type: TABLE DATA; Schema: test; Owner: -
--
TRUNCATE TABLE users_projects CASCADE;
INSERT INTO users_projects VALUES (1, 1);
INSERT INTO users_projects VALUES (1, 2);
INSERT INTO users_projects VALUES (2, 3);
INSERT INTO users_projects VALUES (2, 4);
INSERT INTO users_projects VALUES (3, 1);
INSERT INTO users_projects VALUES (3, 3);
--
-- PostgreSQL database dump complete
--
+4
View File
@@ -0,0 +1,4 @@
DROP DATABASE IF EXISTS postgrest_test;
DROP ROLE IF EXISTS postgrest_test;
CREATE USER postgrest_test createdb createrole;
CREATE DATABASE postgrest_test OWNER postgrest_test;
+44
View File
@@ -0,0 +1,44 @@
-- Privileges for anonymous
GRANT USAGE ON SCHEMA
postgrest
, test
TO postgrest_test_anonymous;
-- Schema test objects
SET search_path = test, pg_catalog;
GRANT ALL ON TABLE
items
, "articleStars"
, articles
, auto_incrementing_pk
, clients
, comments
, complex_items
, compound_pk
, has_count_column
, has_fk
, insertable_view_with_join
, json
, materialized_view
, menagerie
, no_pk
, nullable_integer
, projects
, projects_view
, simple_pk
, tasks
, tsearch
, users
, users_projects
, users_tasks
TO postgrest_test_anonymous;
GRANT USAGE ON SEQUENCE
auto_incrementing_pk_id_seq
, items_id_seq
TO postgrest_test_anonymous;
-- Privileges for non anonymous users
GRANT USAGE ON SCHEMA test TO postgrest_test_author;
GRANT ALL ON TABLE authors_only TO postgrest_test_author;
+6 -15
View File
@@ -1,16 +1,7 @@
create function pg_temp.create_role_if_not_exists(rolename name, opts character varying) RETURNS text
LANGUAGE plpgsql
AS $$
BEGIN
IF NOT EXISTS (SELECT * FROM pg_roles WHERE rolname = rolename) THEN
EXECUTE format('CREATE ROLE %I %s', rolename, opts);
RETURN 'CREATE ROLE';
ELSE
RETURN format('ROLE ''%I'' ALREADY EXISTS', rolename);
END IF;
END;
$$;
DROP ROLE IF EXISTS postgrest_test_authenticator, postgrest_test_anonymous, postgrest_test_default_role, postgrest_test_author;
CREATE ROLE postgrest_test_authenticator WITH login;
CREATE ROLE postgrest_test_anonymous;
CREATE ROLE postgrest_test_default_role;
CREATE ROLE postgrest_test_author;
select pg_temp.create_role_if_not_exists('postgrest_anonymous', 'with nologin') as a
, pg_temp.create_role_if_not_exists('test_default_role', 'with nologin') as b
, pg_temp.create_role_if_not_exists('postgrest_test_author', 'with nologin') into temp shh;
GRANT postgrest_test_anonymous, postgrest_test_default_role, postgrest_test_author TO postgrest_test_authenticator;
+613 -496
View File
File diff suppressed because it is too large Load Diff