@@ -135,7 +135,7 @@ defmodule AshPostgres.Test.MultitenancyTest do
135
135
assert [ _ ] = CompositeKeyPost |> Ash.Query . set_tenant ( org1 ) |> Ash . read! ( )
136
136
end
137
137
138
- test "aggregate validations work with multitenancy " , % { org1: org1 , org2: org2 } do
138
+ test "aggregate validation prevents update with linked posts " , % { org1: org1 } do
139
139
# Create a post in org1
140
140
post =
141
141
Post
@@ -150,13 +150,6 @@ defmodule AshPostgres.Test.MultitenancyTest do
150
150
|> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
151
151
|> Ash . create! ( )
152
152
153
- # Create a linked post in org2 - should not affect validation in org1
154
- _org2_post =
155
- Post
156
- |> Ash.Changeset . for_create ( :create , % { name: "org2 post" } )
157
- |> Ash.Changeset . set_tenant ( "org_" <> org2 . id )
158
- |> Ash . create! ( )
159
-
160
153
# Link the posts in org1
161
154
post
162
155
|> Ash.Changeset . new ( )
@@ -173,6 +166,29 @@ defmodule AshPostgres.Test.MultitenancyTest do
173
166
|> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
174
167
|> Ash . update! ( )
175
168
end
169
+ end
170
+
171
+ test "non-atomic aggregate validation prevents update with linked posts" , % { org1: org1 } do
172
+ # Create a post in org1
173
+ post =
174
+ Post
175
+ |> Ash.Changeset . for_create ( :create , % { name: "foo" } )
176
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
177
+ |> Ash . create! ( )
178
+
179
+ # Create a linked post for the post in org1
180
+ linked_post =
181
+ Post
182
+ |> Ash.Changeset . for_create ( :create , % { name: "linked post" } )
183
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
184
+ |> Ash . create! ( )
185
+
186
+ # Link the posts in org1
187
+ post
188
+ |> Ash.Changeset . new ( )
189
+ |> Ash.Changeset . manage_relationship ( :linked_posts , linked_post , type: :append_and_remove )
190
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
191
+ |> Ash . update! ( )
176
192
177
193
# Test non-atomic validation
178
194
assert_raise Ash.Error.Invalid , ~r/ Can only update if Post has no linked posts/ , fn ->
@@ -183,6 +199,29 @@ defmodule AshPostgres.Test.MultitenancyTest do
183
199
|> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
184
200
|> Ash . update! ( )
185
201
end
202
+ end
203
+
204
+ test "aggregate validation prevents destroy with linked posts" , % { org1: org1 } do
205
+ # Create a post in org1
206
+ post =
207
+ Post
208
+ |> Ash.Changeset . for_create ( :create , % { name: "foo" } )
209
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
210
+ |> Ash . create! ( )
211
+
212
+ # Create a linked post for the post in org1
213
+ linked_post =
214
+ Post
215
+ |> Ash.Changeset . for_create ( :create , % { name: "linked post" } )
216
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
217
+ |> Ash . create! ( )
218
+
219
+ # Link the posts in org1
220
+ post
221
+ |> Ash.Changeset . new ( )
222
+ |> Ash.Changeset . manage_relationship ( :linked_posts , linked_post , type: :append_and_remove )
223
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
224
+ |> Ash . update! ( )
186
225
187
226
# Test destroy with atomic validation
188
227
assert_raise Ash.Error.Invalid , ~r/ Can only delete if Post has no linked posts/ , fn ->
@@ -193,6 +232,29 @@ defmodule AshPostgres.Test.MultitenancyTest do
193
232
|> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
194
233
|> Ash . destroy! ( )
195
234
end
235
+ end
236
+
237
+ test "non-atomic aggregate validation prevents destroy with linked posts" , % { org1: org1 } do
238
+ # Create a post in org1
239
+ post =
240
+ Post
241
+ |> Ash.Changeset . for_create ( :create , % { name: "foo" } )
242
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
243
+ |> Ash . create! ( )
244
+
245
+ # Create a linked post for the post in org1
246
+ linked_post =
247
+ Post
248
+ |> Ash.Changeset . for_create ( :create , % { name: "linked post" } )
249
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
250
+ |> Ash . create! ( )
251
+
252
+ # Link the posts in org1
253
+ post
254
+ |> Ash.Changeset . new ( )
255
+ |> Ash.Changeset . manage_relationship ( :linked_posts , linked_post , type: :append_and_remove )
256
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
257
+ |> Ash . update! ( )
196
258
197
259
# Test destroy with non-atomic validation
198
260
assert_raise Ash.Error.Invalid , ~r/ Can only delete if Post has no linked posts/ , fn ->
@@ -203,8 +265,29 @@ defmodule AshPostgres.Test.MultitenancyTest do
203
265
|> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
204
266
|> Ash . destroy! ( )
205
267
end
268
+ end
206
269
207
- # Verify that a post with no linked posts in org2 can be updated
270
+ test "post with no linked posts can be updated in another tenant" , % { org1: org1 , org2: org2 } do
271
+ # Create a post in org1 with a linked post
272
+ post_in_org1 =
273
+ Post
274
+ |> Ash.Changeset . for_create ( :create , % { name: "foo" } )
275
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
276
+ |> Ash . create! ( )
277
+
278
+ linked_post =
279
+ Post
280
+ |> Ash.Changeset . for_create ( :create , % { name: "linked post" } )
281
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
282
+ |> Ash . create! ( )
283
+
284
+ post_in_org1
285
+ |> Ash.Changeset . new ( )
286
+ |> Ash.Changeset . manage_relationship ( :linked_posts , linked_post , type: :append_and_remove )
287
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
288
+ |> Ash . update! ( )
289
+
290
+ # Create a post in org2 with no linked posts
208
291
org2_post =
209
292
Post
210
293
|> Ash.Changeset . for_create ( :create , % { name: "updateable" } )
@@ -221,8 +304,29 @@ defmodule AshPostgres.Test.MultitenancyTest do
221
304
|> Ash . update! ( )
222
305
223
306
assert updated_post . name == "updated"
307
+ end
308
+
309
+ test "post with no linked posts can be destroyed in another tenant" , % { org1: org1 , org2: org2 } do
310
+ # Create a post in org1 with a linked post
311
+ post_in_org1 =
312
+ Post
313
+ |> Ash.Changeset . for_create ( :create , % { name: "foo" } )
314
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
315
+ |> Ash . create! ( )
224
316
225
- # Test that a post with no linked posts in org2 can be destroyed
317
+ linked_post =
318
+ Post
319
+ |> Ash.Changeset . for_create ( :create , % { name: "linked post" } )
320
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
321
+ |> Ash . create! ( )
322
+
323
+ post_in_org1
324
+ |> Ash.Changeset . new ( )
325
+ |> Ash.Changeset . manage_relationship ( :linked_posts , linked_post , type: :append_and_remove )
326
+ |> Ash.Changeset . set_tenant ( "org_" <> org1 . id )
327
+ |> Ash . update! ( )
328
+
329
+ # Create a post in org2 with no linked posts
226
330
org2_post_for_destroy =
227
331
Post
228
332
|> Ash.Changeset . for_create ( :create , % { name: "destroyable" } )
@@ -236,6 +340,13 @@ defmodule AshPostgres.Test.MultitenancyTest do
236
340
|> Ash.Changeset . for_destroy ( :destroy_if_no_linked_posts , % { } )
237
341
|> Ash.Changeset . set_tenant ( "org_" <> org2 . id )
238
342
|> Ash . destroy! ( )
343
+
344
+ # Verify the post was destroyed
345
+ assert [ ] =
346
+ Post
347
+ |> Ash.Query . filter ( id == ^ org2_post_for_destroy . id )
348
+ |> Ash.Query . set_tenant ( "org_" <> org2 . id )
349
+ |> Ash . read! ( )
239
350
end
240
351
241
352
test "loading attribute multitenant resources from context multitenant resources works" do
0 commit comments