Skip to content

Commit e38e468

Browse files
committed
feat: add orm-test package — M:N integration tests against real PostgreSQL
New graphql/orm-test package that exercises ORM M:N patterns against a live PostGraphile schema via graphile-test: - SQL fixtures: posts, tags, post_tags junction with @behavior +manyToMany - ManyToManyOptInPreset enabled for M:N connection fields - Tests: addTag (createPostTag), removeTag (deletePostTagByPostIdAndTagId, deletePostTagByRowId), CRUD, reverse M:N direction, unique constraint - 10/10 tests pass locally
1 parent b8d4ae2 commit e38e468

8 files changed

Lines changed: 3275 additions & 7422 deletions

File tree

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
-- Schema for orm-test: M:N integration tests
2+
-- posts <-> tags via post_tags junction table
3+
4+
CREATE SCHEMA IF NOT EXISTS "orm_test";
5+
6+
GRANT USAGE ON SCHEMA "orm_test" TO administrator, authenticated, anonymous;
7+
8+
ALTER DEFAULT PRIVILEGES IN SCHEMA "orm_test"
9+
GRANT ALL ON TABLES TO administrator;
10+
ALTER DEFAULT PRIVILEGES IN SCHEMA "orm_test"
11+
GRANT USAGE ON SEQUENCES TO administrator, authenticated;
12+
ALTER DEFAULT PRIVILEGES IN SCHEMA "orm_test"
13+
GRANT ALL ON FUNCTIONS TO administrator, authenticated, anonymous;
14+
15+
-- =============================================================================
16+
-- Table: posts
17+
-- =============================================================================
18+
CREATE TABLE "orm_test".posts (
19+
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
20+
title text NOT NULL,
21+
body text,
22+
is_published boolean DEFAULT false,
23+
created_at timestamptz DEFAULT now(),
24+
updated_at timestamptz DEFAULT now()
25+
);
26+
27+
-- =============================================================================
28+
-- Table: tags
29+
-- =============================================================================
30+
CREATE TABLE "orm_test".tags (
31+
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
32+
name text NOT NULL UNIQUE,
33+
color text DEFAULT '#888888',
34+
created_at timestamptz DEFAULT now()
35+
);
36+
37+
-- =============================================================================
38+
-- Table: post_tags (junction)
39+
-- M:N relationship between posts and tags
40+
-- =============================================================================
41+
CREATE TABLE "orm_test".post_tags (
42+
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
43+
post_id uuid NOT NULL REFERENCES "orm_test".posts(id) ON DELETE CASCADE,
44+
tag_id uuid NOT NULL REFERENCES "orm_test".tags(id) ON DELETE CASCADE,
45+
created_at timestamptz DEFAULT now(),
46+
UNIQUE(post_id, tag_id)
47+
);
48+
49+
CREATE INDEX post_tags_post_id_idx ON "orm_test".post_tags (post_id);
50+
CREATE INDEX post_tags_tag_id_idx ON "orm_test".post_tags (tag_id);
51+
52+
-- Enable many-to-many for this junction table
53+
COMMENT ON TABLE "orm_test".post_tags IS E'@behavior +manyToMany';
54+
55+
-- =============================================================================
56+
-- Timestamp triggers
57+
-- =============================================================================
58+
CREATE TRIGGER posts_timestamps_tg
59+
BEFORE INSERT OR UPDATE ON "orm_test".posts
60+
FOR EACH ROW EXECUTE PROCEDURE stamps.timestamps();
61+
62+
-- =============================================================================
63+
-- Grant table permissions
64+
-- =============================================================================
65+
GRANT SELECT, INSERT, UPDATE, DELETE ON "orm_test".posts TO administrator, authenticated, anonymous;
66+
GRANT SELECT, INSERT, UPDATE, DELETE ON "orm_test".tags TO administrator, authenticated, anonymous;
67+
GRANT SELECT, INSERT, UPDATE, DELETE ON "orm_test".post_tags TO administrator, authenticated, anonymous;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
-- Setup for orm-test
2+
-- Creates required extensions and roles
3+
4+
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
5+
6+
DO $$
7+
BEGIN
8+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'administrator') THEN
9+
CREATE ROLE administrator;
10+
END IF;
11+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'authenticated') THEN
12+
CREATE ROLE authenticated;
13+
END IF;
14+
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'anonymous') THEN
15+
CREATE ROLE anonymous;
16+
END IF;
17+
END
18+
$$;
19+
20+
CREATE SCHEMA IF NOT EXISTS stamps;
21+
22+
CREATE OR REPLACE FUNCTION stamps.timestamps()
23+
RETURNS TRIGGER AS $$
24+
BEGIN
25+
IF TG_OP = 'INSERT' THEN
26+
NEW.created_at = COALESCE(NEW.created_at, now());
27+
END IF;
28+
NEW.updated_at = now();
29+
RETURN NEW;
30+
END;
31+
$$ LANGUAGE plpgsql;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-- Seed data for orm-test
2+
3+
INSERT INTO "orm_test".posts (id, title, body, is_published)
4+
VALUES
5+
('11111111-1111-1111-1111-111111111111', 'Hello World', 'First post content', true),
6+
('22222222-2222-2222-2222-222222222222', 'Second Post', 'Another post', false);
7+
8+
INSERT INTO "orm_test".tags (id, name, color)
9+
VALUES
10+
('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', 'Technology', '#3B82F6'),
11+
('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', 'Design', '#EC4899'),
12+
('cccccccc-cccc-cccc-cccc-cccccccccccc', 'Science', '#10B981');
13+
14+
-- Seed one existing junction row: post1 <-> Technology
15+
INSERT INTO "orm_test".post_tags (post_id, tag_id)
16+
VALUES
17+
('11111111-1111-1111-1111-111111111111', 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa');

0 commit comments

Comments
 (0)