e356f4d9fa19806e9fc48f3f41f16bb90e200608
[arvados.git] / services / api / test / unit / owner_test.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'test_helper'
6
7 # Test referential integrity: ensure we cannot leave any object
8 # without owners by deleting a user or group.
9 #
10 # "o" is an owner.
11 # "i" is an item.
12
13 class OwnerTest < ActiveSupport::TestCase
14   fixtures :users, :groups, :specimens
15
16   setup do
17     set_user_from_auth :admin_trustedclient
18   end
19
20   User.all
21   Group.all
22   [User, Group].each do |o_class|
23     test "create object with legit #{o_class} owner" do
24       if o_class == Group
25         o = o_class.create! group_class: "project"
26       else
27         o = o_class.create!
28       end
29       i = Specimen.create(owner_uuid: o.uuid)
30       assert i.valid?, "new item should pass validation"
31       assert i.uuid, "new item should have an ID"
32       assert Specimen.where(uuid: i.uuid).any?, "new item should really be in DB"
33     end
34
35     test "create object with non-existent #{o_class} owner" do
36       assert_raises(ActiveRecord::RecordInvalid,
37                     "create should fail with random owner_uuid") do
38         Specimen.create!(owner_uuid: o_class.generate_uuid)
39       end
40
41       i = Specimen.create(owner_uuid: o_class.generate_uuid)
42       assert !i.valid?, "object with random owner_uuid should not be valid?"
43
44       i = Specimen.new(owner_uuid: o_class.generate_uuid)
45       assert !i.valid?, "new item should not pass validation"
46       assert !i.uuid, "new item should not have an ID"
47     end
48
49     [User, Group].each do |new_o_class|
50       test "change owner from legit #{o_class} to legit #{new_o_class} owner" do
51         o = if o_class == Group
52               o_class.create! group_class: "project"
53             else
54               o_class.create!
55             end
56         i = Specimen.create!(owner_uuid: o.uuid)
57
58         new_o = if new_o_class == Group
59               new_o_class.create! group_class: "project"
60             else
61               new_o_class.create!
62             end
63
64         assert(Specimen.where(uuid: i.uuid).any?,
65                "new item should really be in DB")
66         assert(i.update_attributes(owner_uuid: new_o.uuid),
67                "should change owner_uuid from #{o.uuid} to #{new_o.uuid}")
68       end
69     end
70
71     test "delete #{o_class} that owns nothing" do
72       if o_class == Group
73         o = o_class.create! group_class: "project"
74       else
75         o = o_class.create!
76       end
77       assert(o_class.where(uuid: o.uuid).any?,
78              "new #{o_class} should really be in DB")
79       assert(o.destroy, "should delete #{o_class} that owns nothing")
80       assert_equal(false, o_class.where(uuid: o.uuid).any?,
81                    "#{o.uuid} should not be in DB after deleting")
82     end
83
84     test "change uuid of #{o_class} that owns nothing" do
85       # (we're relying on our admin credentials here)
86       if o_class == Group
87         o = o_class.create! group_class: "project"
88       else
89         o = o_class.create!
90       end
91       assert(o_class.where(uuid: o.uuid).any?,
92              "new #{o_class} should really be in DB")
93       old_uuid = o.uuid
94       new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9])
95       if o.respond_to? :update_uuid
96         o.update_uuid(new_uuid: new_uuid)
97       else
98         assert(o.update_attributes(uuid: new_uuid),
99                "should change #{o_class} uuid from #{old_uuid} to #{new_uuid}")
100       end
101       assert_equal(false, o_class.where(uuid: old_uuid).any?,
102                    "#{old_uuid} should disappear when renamed to #{new_uuid}")
103     end
104   end
105
106   ['users(:active)', 'groups(:aproject)'].each do |ofixt|
107     test "delete #{ofixt} that owns other objects" do
108       o = eval ofixt
109       assert_equal(true, Specimen.where(owner_uuid: o.uuid).any?,
110                    "need something to be owned by #{o.uuid} for this test")
111
112       skip_check_permissions_against_full_refresh do
113         assert_raises(ActiveRecord::DeleteRestrictionError,
114                       "should not delete #{ofixt} that owns objects") do
115           o.destroy
116         end
117       end
118     end
119
120     test "change uuid of #{ofixt} that owns other objects" do
121       o = eval ofixt
122       assert_equal(true, Specimen.where(owner_uuid: o.uuid).any?,
123                    "need something to be owned by #{o.uuid} for this test")
124       new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9])
125       assert(!o.update_attributes(uuid: new_uuid),
126              "should not change uuid of #{ofixt} that owns objects")
127     end
128   end
129
130   test "delete User that owns self" do
131     o = User.create!
132     assert User.where(uuid: o.uuid).any?, "new User should really be in DB"
133     assert_equal(true, o.update_attributes(owner_uuid: o.uuid),
134                  "setting owner to self should work")
135
136     skip_check_permissions_against_full_refresh do
137       assert(o.destroy, "should delete User that owns self")
138     end
139
140     assert_equal(false, User.where(uuid: o.uuid).any?,
141                  "#{o.uuid} should not be in DB after deleting")
142     check_permissions_against_full_refresh
143   end
144
145   test "change uuid of User that owns self" do
146     o = User.create!
147     assert User.where(uuid: o.uuid).any?, "new User should really be in DB"
148     assert_equal(true, o.update_attributes(owner_uuid: o.uuid),
149                  "setting owner to self should work")
150     old_uuid = o.uuid
151     new_uuid = o.uuid.sub(/..........$/, rand(2**256).to_s(36)[0..9])
152     o.update_uuid(new_uuid: new_uuid)
153     o = User.find_by_uuid(new_uuid)
154     assert_equal(false, User.where(uuid: old_uuid).any?,
155                  "#{old_uuid} should not be in DB after deleting")
156     assert_equal(true, User.where(uuid: new_uuid).any?,
157                  "#{new_uuid} should be in DB after renaming")
158     assert_equal(new_uuid, User.where(uuid: new_uuid).first.owner_uuid,
159                  "#{new_uuid} should be its own owner in DB after renaming")
160   end
161
162 end