on main help sign in
reshape/tests/add_foreign_key.rs
166 lines 4.3 kB history raw
1mod common;
2use common::Test;
4#[test]
5fn add_foreign_key() {
6 let mut test = Test::new("Add foreign key");
8 test.first_migration(
9 r#"
10 name = "create_user_table"
12 [[actions]]
13 type = "create_table"
14 name = "users"
15 primary_key = ["id"]
17 [[actions.columns]]
18 name = "id"
19 type = "INTEGER"
21 [[actions]]
22 type = "create_table"
23 name = "items"
24 primary_key = ["id"]
26 [[actions.columns]]
27 name = "id"
28 type = "INTEGER"
30 [[actions.columns]]
31 name = "user_id"
32 type = "INTEGER"
33 "#,
34 );
36 test.second_migration(
37 r#"
38 name = "add_foreign_key"
40 [[actions]]
41 type = "add_foreign_key"
42 table = "items"
44 [actions.foreign_key]
45 columns = ["user_id"]
46 referenced_table = "users"
47 referenced_columns = ["id"]
48 "#,
49 );
51 test.after_first(|db| {
52 // Insert some test users
53 db.simple_query("INSERT INTO users (id) VALUES (1), (2)")
54 .unwrap();
55 });
57 test.intermediate(|db, _| {
58 // Ensure items can be inserted if they reference valid users
59 db.simple_query("INSERT INTO items (id, user_id) VALUES (1, 1), (2, 2)")
60 .unwrap();
62 // Ensure items can't be inserted if they don't reference valid users
63 let result = db.simple_query("INSERT INTO items (id, user_id) VALUES (3, 3)");
64 assert!(result.is_err(), "expected insert to fail");
65 });
67 test.after_completion(|db| {
68 // Ensure items can be inserted if they reference valid users
69 db.simple_query("INSERT INTO items (id, user_id) VALUES (3, 1), (4, 2)")
70 .unwrap();
72 // Ensure items can't be inserted if they don't reference valid users
73 let result = db.simple_query("INSERT INTO items (id, user_id) VALUES (5, 3)");
74 assert!(result.is_err(), "expected insert to fail");
76 // Ensure foreign key exists with the right name
77 let foreign_key_name: Option<String> = db
78 .query(
79 "
80 SELECT tc.constraint_name
81 FROM information_schema.table_constraints AS tc
82 WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='items';
83 ",
84 &[],
85 )
86 .unwrap()
87 .first()
88 .map(|row| row.get(0));
89 assert_eq!(Some("items_user_id_fkey".to_string()), foreign_key_name);
90 });
92 test.after_abort(|db| {
93 // Ensure foreign key doesn't exist
94 let fk_does_not_exist = db
95 .query(
96 "
97 SELECT tc.constraint_name
98 FROM information_schema.table_constraints AS tc
99 WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.table_name='items';
100 ",
101 &[],
102 )
103 .unwrap()
104 .is_empty();
105 assert!(fk_does_not_exist);
106 });
108 test.run()
111#[test]
112fn add_invalid_foreign_key() {
113 let mut test = Test::new("Add invalid foreign key");
115 test.first_migration(
116 r#"
117 name = "create_user_table"
119 [[actions]]
120 type = "create_table"
121 name = "users"
122 primary_key = ["id"]
124 [[actions.columns]]
125 name = "id"
126 type = "INTEGER"
128 [[actions]]
129 type = "create_table"
130 name = "items"
131 primary_key = ["id"]
133 [[actions.columns]]
134 name = "id"
135 type = "INTEGER"
137 [[actions.columns]]
138 name = "user_id"
139 type = "INTEGER"
140 "#,
141 );
143 test.second_migration(
144 r#"
145 name = "add_foreign_key"
147 [[actions]]
148 type = "add_foreign_key"
149 table = "items"
151 [actions.foreign_key]
152 columns = ["user_id"]
153 referenced_table = "users"
154 referenced_columns = ["id"]
155 "#,
156 );
158 test.after_first(|db| {
159 // Insert some items which don't reference a valid user
160 db.simple_query("INSERT INTO items (id, user_id) VALUES (1, 1), (2, 2)")
161 .unwrap();
162 });
164 test.expect_failure();
165 test.run()