invitational 1.3.2 → 1.4.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +30 -20
- data/Rakefile +6 -1
- data/app/modules/invitational/invitation_core.rb +1 -1
- data/db/migrate/20130528220144_create_invitations.rb +1 -1
- data/lib/generators/invitational/install/templates/invitation.rb +1 -1
- data/lib/invitational/cancan.rb +2 -0
- data/lib/invitational/version.rb +1 -1
- data/spec/internal/app/assets/config/manifest.js +0 -0
- data/spec/internal/app/models/ability.rb +29 -0
- data/spec/internal/app/models/child.rb +5 -0
- data/spec/internal/app/models/entity.rb +9 -0
- data/spec/internal/app/models/grandparent.rb +9 -0
- data/spec/internal/app/models/invitation.rb +10 -0
- data/spec/internal/app/models/other_entity.rb +7 -0
- data/spec/internal/app/models/system_thing.rb +5 -0
- data/spec/internal/app/models/user.rb +6 -0
- data/spec/internal/config/database.yml +3 -0
- data/spec/internal/config/routes.rb +3 -0
- data/spec/internal/db/combustion_test.sqlite +0 -0
- data/spec/internal/db/schema.rb +35 -0
- data/spec/internal/log/test.log +37683 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/invitational/models/ability_spec.rb +105 -0
- data/spec/invitational/models/entity_spec.rb +51 -0
- data/spec/invitational/models/invitation_spec.rb +145 -0
- data/spec/invitational/models/user_spec.rb +107 -0
- data/spec/invitational/services/checks_for_invitation_spec.rb +91 -0
- data/spec/invitational/services/claims_all_invitations_spec.rb +29 -0
- data/spec/invitational/services/claims_invitation_spec.rb +49 -0
- data/spec/invitational/services/creates_invitation_spec.rb +55 -0
- data/spec/invitational/services/creates_system_user_invitation_spec.rb +52 -0
- data/spec/invitational/services/creates_uber_admin_invitation_spec.rb +52 -0
- data/spec/invitational/services/service_helper.rb +78 -0
- data/spec/spec_helper.rb +19 -0
- metadata +82 -29
File without changes
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'cancan/matchers'
|
3
|
+
require 'invitational/services/service_helper'
|
4
|
+
|
5
|
+
describe Ability do
|
6
|
+
|
7
|
+
Given(:user1) { setup_user "test1@d-i.co" }
|
8
|
+
Given(:user2) { setup_user "test2@d-i.co" }
|
9
|
+
Given(:user3) { setup_user "test3@d-i.co" }
|
10
|
+
Given(:user4) { setup_user "test4@d-i.co" }
|
11
|
+
Given(:user5) { setup_user "test5@d-i.co" }
|
12
|
+
|
13
|
+
Given(:entity1) { setup_entity "Test entity 1"}
|
14
|
+
Given(:entity2) { setup_entity "Test entity 2"}
|
15
|
+
Given(:child1) {setup_child "Child 1", entity2}
|
16
|
+
Given(:grandparent) {setup_grandparent "A Grandparent", entity2}
|
17
|
+
|
18
|
+
Given(:other_entity) { setup_other_entity "Test other entity"}
|
19
|
+
Given(:system_thing) { setup_system_thing "A System Object" }
|
20
|
+
|
21
|
+
Given {invite_user user1, entity1, :user}
|
22
|
+
Given {invite_user user2, entity2, :admin}
|
23
|
+
Given {invite_user user5, grandparent, :admin}
|
24
|
+
|
25
|
+
Given {invite_uber_admin user3}
|
26
|
+
Given {invite_system_role user4, :employer}
|
27
|
+
|
28
|
+
context "User" do
|
29
|
+
Given (:i) { Ability.new(user1) }
|
30
|
+
When (:role) {:user}
|
31
|
+
|
32
|
+
Then { i.should be_able_to(:read, entity1) }
|
33
|
+
And { i.should_not be_able_to(:manage, entity1) }
|
34
|
+
And { i.should_not be_able_to(:read, entity2) }
|
35
|
+
end
|
36
|
+
|
37
|
+
context "Admin" do
|
38
|
+
Given (:i) { Ability.new(user2) }
|
39
|
+
When (:role) {:admin}
|
40
|
+
|
41
|
+
Then { i.should be_able_to(:read, entity2) }
|
42
|
+
And { i.should be_able_to(:manage, entity2) }
|
43
|
+
And { i.should_not be_able_to(:read, entity1) }
|
44
|
+
end
|
45
|
+
|
46
|
+
context "Any Role (wildcard)" do
|
47
|
+
Given (:user) { Ability.new(user1) }
|
48
|
+
Given (:admin) { Ability.new(user2) }
|
49
|
+
When (:role) {:*}
|
50
|
+
|
51
|
+
Then { user.should be_able_to(:validate, entity1) }
|
52
|
+
And { user.should_not be_able_to(:validate, entity2) }
|
53
|
+
And { admin.should be_able_to(:validate, entity2) }
|
54
|
+
And { admin.should_not be_able_to(:validate, entity1) }
|
55
|
+
end
|
56
|
+
|
57
|
+
context "System - Employer" do
|
58
|
+
Given (:i) { Ability.new(user4) }
|
59
|
+
When (:role) {:employer}
|
60
|
+
|
61
|
+
Then { i.should be_able_to(:manage, system_thing) }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "Uber Admin" do
|
65
|
+
Given (:i) { Ability.new(user3) }
|
66
|
+
When (:role) {:uberadmin}
|
67
|
+
|
68
|
+
Then { i.should be_able_to(:manage, entity1) }
|
69
|
+
And { i.should be_able_to(:manage, entity2) }
|
70
|
+
And {i.should be_able_to(:manage, child1)}
|
71
|
+
And { i.should be_able_to(:manage, other_entity) }
|
72
|
+
And { i.should be_able_to(:manage, system_thing) }
|
73
|
+
end
|
74
|
+
|
75
|
+
context "Uber Admin only permissions" do
|
76
|
+
Given (:i) { Ability.new(user3) }
|
77
|
+
When (:role) {:uberadmin}
|
78
|
+
|
79
|
+
Then { i.should be_able_to(:manage, other_entity) }
|
80
|
+
end
|
81
|
+
|
82
|
+
context "Cascading Permissions" do
|
83
|
+
context "One level" do
|
84
|
+
Given (:i) { Ability.new(user2) }
|
85
|
+
When (:role) {:admin}
|
86
|
+
|
87
|
+
Then {i.should be_able_to(:manage, child1)}
|
88
|
+
end
|
89
|
+
|
90
|
+
context "Two levels" do
|
91
|
+
Given (:i) { Ability.new(user5) }
|
92
|
+
When (:role) {:admin}
|
93
|
+
|
94
|
+
Then {i.should be_able_to(:manage, child1)}
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "Access to everybody" do
|
99
|
+
Given (:i) { Ability.new(user1) }
|
100
|
+
When (:role) {:admin}
|
101
|
+
|
102
|
+
Then {i.should be_able_to(:read, child1) }
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'invitational/services/service_helper'
|
3
|
+
|
4
|
+
describe Entity do
|
5
|
+
Given {no_invitations_exist}
|
6
|
+
|
7
|
+
Given(:user) { setup_user "test1@d-i.co" }
|
8
|
+
Given(:entity) { setup_entity "Test entity 1"}
|
9
|
+
|
10
|
+
context "relationships" do
|
11
|
+
When {invite_user user, entity, :admin}
|
12
|
+
|
13
|
+
Then {entity.admins.should include(user)}
|
14
|
+
end
|
15
|
+
|
16
|
+
context "inviting" do
|
17
|
+
context "Users can be invited with a defined role" do
|
18
|
+
When(:result) {entity.invite user, :admin}
|
19
|
+
|
20
|
+
Then {result.should_not be_nil}
|
21
|
+
And {result.invitable.should == entity}
|
22
|
+
And {result.user.should == user }
|
23
|
+
And {result.role.should == :admin}
|
24
|
+
And {result.claimed?.should be_truthy}
|
25
|
+
end
|
26
|
+
|
27
|
+
context "Users cannot be invited again if they are already invited" do
|
28
|
+
Given {invite_user user, entity, :admin}
|
29
|
+
|
30
|
+
When(:result) {entity.invite user, :user}
|
31
|
+
|
32
|
+
Then { expect(result).to have_failed(Invitational::AlreadyInvitedError) }
|
33
|
+
end
|
34
|
+
|
35
|
+
context "Users cannot be invited with a role that isn't defined on the entity" do
|
36
|
+
When(:result) {entity.invite user, :client}
|
37
|
+
|
38
|
+
Then { expect(result).to have_failed(Invitational::InvalidRoleError) }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "cleans up invitations when an entity is deleted" do
|
43
|
+
Given! (:invite) {invite_user user, entity, :admin}
|
44
|
+
Given {entity.destroy}
|
45
|
+
|
46
|
+
When (:result) {Invitation.find(invite.id)}
|
47
|
+
|
48
|
+
Then {expect(result).to have_failed(ActiveRecord::RecordNotFound)}
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'invitational/services/service_helper'
|
3
|
+
|
4
|
+
describe Invitational::Invitation do
|
5
|
+
Given {no_invitations_exist}
|
6
|
+
|
7
|
+
Given(:user1) { setup_user "test1@d-i.co" }
|
8
|
+
Given(:user2) { setup_user "test2@d-i.co" }
|
9
|
+
Given(:user3) { setup_user "test3@d-i.co" }
|
10
|
+
Given(:user4) { setup_user "test4@d-i.co" }
|
11
|
+
Given(:user5) { setup_user "test5@d-i.co" }
|
12
|
+
|
13
|
+
Given(:entity1) { setup_entity "Test entity 1"}
|
14
|
+
Given(:entity2) { setup_entity "Test entity 2"}
|
15
|
+
Given(:entity3) { setup_entity "Test entity 3"}
|
16
|
+
|
17
|
+
Given (:unclaimed) {invite_by_email user1.email, entity1, :user}
|
18
|
+
Given (:claimed) {invite_user user2, entity2, :admin}
|
19
|
+
Given (:uber_admin) {invite_uber_admin user3}
|
20
|
+
|
21
|
+
context "Initialization" do
|
22
|
+
context "Creates Claim hash and date sent on creation" do
|
23
|
+
Given(:new_invite) {Invitation.new(email: "test999@d-i.co", invitable: entity1, role: :user)}
|
24
|
+
|
25
|
+
When {new_invite.save}
|
26
|
+
|
27
|
+
Then {new_invite.claim_hash.should_not be_nil}
|
28
|
+
And {new_invite.date_sent.should_not be_nil}
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "Role Title" do
|
33
|
+
context "Standard Role" do
|
34
|
+
Then {unclaimed.role_title.should == "User"}
|
35
|
+
end
|
36
|
+
|
37
|
+
context "Uber Admin" do
|
38
|
+
Then {uber_admin.role_title.should == "Uber Admin"}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "Type" do
|
43
|
+
context "Standard Role" do
|
44
|
+
Then {unclaimed.uberadmin?.should_not be_truthy}
|
45
|
+
And {claimed.uberadmin?.should_not be_truthy}
|
46
|
+
end
|
47
|
+
|
48
|
+
context "Uber Admin" do
|
49
|
+
Then {uber_admin.uberadmin?.should be_truthy}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "Claim Status" do
|
54
|
+
context "Unclaimed" do
|
55
|
+
Then {unclaimed.claimed?.should_not be_truthy}
|
56
|
+
And {unclaimed.unclaimed?.should be_truthy}
|
57
|
+
end
|
58
|
+
|
59
|
+
context "Claimed" do
|
60
|
+
Then {claimed.claimed?.should be_truthy}
|
61
|
+
And {claimed.unclaimed?.should_not be_truthy}
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "Claiming" do
|
66
|
+
context "By Hash" do
|
67
|
+
When (:result) {Invitation.claim unclaimed.claim_hash, user1}
|
68
|
+
|
69
|
+
Then { result.id.should == unclaimed.id}
|
70
|
+
And { user1.invitations.should include(result) }
|
71
|
+
end
|
72
|
+
|
73
|
+
context "All for a given user" do
|
74
|
+
Given {invite_by_email user4.email, entity3, :user}
|
75
|
+
|
76
|
+
When (:result) {Invitation.claim_all_for user4}
|
77
|
+
|
78
|
+
Then {user4.entities.should include(entity3)}
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context "Invites Uberadmin" do
|
83
|
+
context "By email" do
|
84
|
+
When (:result) {Invitation.invite_uberadmin user4.email}
|
85
|
+
|
86
|
+
Then {result.should_not be_nil}
|
87
|
+
And {result.invitable.should be_nil}
|
88
|
+
And {result.email.should == user4.email}
|
89
|
+
And {result.role.should == :uberadmin }
|
90
|
+
And {result.unclaimed?.should be_truthy}
|
91
|
+
end
|
92
|
+
|
93
|
+
context "Existing user" do
|
94
|
+
When (:result) {Invitation.invite_uberadmin user4}
|
95
|
+
|
96
|
+
Then {result.should_not be_nil}
|
97
|
+
And {result.invitable.should be_nil}
|
98
|
+
And {result.email.should == user4.email}
|
99
|
+
And {result.role.should == :uberadmin}
|
100
|
+
And {result.claimed?.should be_truthy}
|
101
|
+
And {result.user.should == user4 }
|
102
|
+
end
|
103
|
+
|
104
|
+
context "When already invited" do
|
105
|
+
Given {invite_uber_admin user4}
|
106
|
+
|
107
|
+
When (:result) {Invitation.invite_uberadmin user4}
|
108
|
+
|
109
|
+
Then { expect(result).to have_failed(Invitational::AlreadyInvitedError) }
|
110
|
+
end
|
111
|
+
|
112
|
+
context "Invites to System Role" do
|
113
|
+
context "By email" do
|
114
|
+
When (:result) {Invitation.invite_system_user user4.email, :employer}
|
115
|
+
|
116
|
+
Then {result.should_not be_nil}
|
117
|
+
And {result.invitable.should be_nil}
|
118
|
+
And {result.email.should == user4.email}
|
119
|
+
And {result.role.should == :employer }
|
120
|
+
And {result.unclaimed?.should be_truthy}
|
121
|
+
end
|
122
|
+
|
123
|
+
context "Existing user" do
|
124
|
+
When (:result) {Invitation.invite_system_user user4, :employer}
|
125
|
+
|
126
|
+
Then {result.should_not be_nil}
|
127
|
+
And {result.invitable.should be_nil}
|
128
|
+
And {result.email.should == user4.email}
|
129
|
+
And {result.role.should == :employer}
|
130
|
+
And {result.claimed?.should be_truthy}
|
131
|
+
And {result.user.should == user4 }
|
132
|
+
end
|
133
|
+
|
134
|
+
context "When already invited" do
|
135
|
+
Given {invite_system_role user4, :employer}
|
136
|
+
|
137
|
+
When (:result) {Invitation.invite_system_user user4, :employer}
|
138
|
+
|
139
|
+
Then { expect(result).to have_failed(Invitational::AlreadyInvitedError) }
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
|
145
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'invitational/services/service_helper'
|
3
|
+
|
4
|
+
describe User do
|
5
|
+
Given {no_invitations_exist}
|
6
|
+
|
7
|
+
Given(:user1) { setup_user "test1@d-i.co" }
|
8
|
+
Given(:user2) { setup_user "test2@d-i.co" }
|
9
|
+
Given(:user3) { setup_user "test2@d-i.co" }
|
10
|
+
|
11
|
+
Given(:entity1) { setup_entity "Test entity 1"}
|
12
|
+
|
13
|
+
context 'invited_to creates a has_many_through relationship' do
|
14
|
+
When {invite_user user1, entity1, :admin}
|
15
|
+
|
16
|
+
Then {user1.entities.should include(entity1)}
|
17
|
+
And {user1.children.count.should == 0}
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'indicates if a user is an uberadmin' do
|
21
|
+
context 'when an uberadmin' do
|
22
|
+
When {invite_uber_admin user2}
|
23
|
+
|
24
|
+
Then {user2.uberadmin?.should be_truthy}
|
25
|
+
end
|
26
|
+
|
27
|
+
context 'when not an uberadmin' do
|
28
|
+
When {invite_user user1, entity1, :admin}
|
29
|
+
|
30
|
+
Then {user1.uberadmin?.should_not be_truthy}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'checks to see if a user is invited to a given system role' do
|
35
|
+
context 'when an invited' do
|
36
|
+
When {invite_system_role user2, :employer}
|
37
|
+
|
38
|
+
Then {user2.invited_to_system?(:employer).should be_truthy}
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'when not invited' do
|
42
|
+
When {invite_user user1, entity1, :admin}
|
43
|
+
|
44
|
+
Then {user1.invited_to_system?(:employer).should_not be_truthy}
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'checks to see if a user is invited to a given entity' do
|
49
|
+
|
50
|
+
context 'for any role' do
|
51
|
+
context 'when invited' do
|
52
|
+
When {invite_user user1, entity1, :admin}
|
53
|
+
|
54
|
+
Then {user1.invited_to?(entity1).should be_truthy}
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when not invited' do
|
58
|
+
When {invite_user user2, entity1, :admin}
|
59
|
+
|
60
|
+
Then {user1.invited_to?(entity1).should_not be_truthy}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
context 'for a specific role' do
|
66
|
+
When {invite_user user1, entity1, :admin}
|
67
|
+
|
68
|
+
context 'when invited' do
|
69
|
+
Then {user1.invited_to?(entity1, :admin).should be_truthy}
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when not invited' do
|
73
|
+
Then {user2.invited_to?(entity1, :admin).should_not be_truthy}
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'when invited to a different role' do
|
77
|
+
Then {user1.invited_to?(entity1, :user).should_not be_truthy}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
context "cleans up invitations when a user is deleted" do
|
84
|
+
Given! (:invite) {invite_user user1, entity1, :admin}
|
85
|
+
Given {user1.destroy}
|
86
|
+
|
87
|
+
When (:result) {Invitation.find(invite.id)}
|
88
|
+
|
89
|
+
Then {expect(result).to have_failed(ActiveRecord::RecordNotFound)}
|
90
|
+
end
|
91
|
+
|
92
|
+
context "creates named scopes for system roles" do
|
93
|
+
context 'when an uberadmin' do
|
94
|
+
When {invite_uber_admin user2}
|
95
|
+
Then {User.uberadmins.should include(user2)}
|
96
|
+
And {User.uberadmins.should_not include(user1)}
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'when an employer' do
|
100
|
+
When {invite_system_role user2, :employer}
|
101
|
+
Then {User.employers.should include(user2)}
|
102
|
+
And {User.employers.should_not include(user1)}
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'invitational/services/service_helper'
|
3
|
+
|
4
|
+
describe Invitational::ChecksForInvitation do
|
5
|
+
Given {no_invitations_exist}
|
6
|
+
|
7
|
+
Given(:user1) { setup_user "test1@d-i.co" }
|
8
|
+
Given(:user2) { setup_user "test2@d-i.co" }
|
9
|
+
Given(:user3) { setup_user "test3@d-i.co" }
|
10
|
+
|
11
|
+
Given(:entity) { setup_entity "Test entity"}
|
12
|
+
|
13
|
+
Given {invite_user user1, entity, :user}
|
14
|
+
Given {invite_uber_admin user3}
|
15
|
+
|
16
|
+
context "checking for any role" do
|
17
|
+
|
18
|
+
context "when invited" do
|
19
|
+
When(:result) { Invitational::ChecksForInvitation.for user1, entity }
|
20
|
+
|
21
|
+
Then {result.should be_truthy}
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when not invited" do
|
25
|
+
When(:result) { Invitational::ChecksForInvitation.for user2, entity }
|
26
|
+
|
27
|
+
Then {result.should_not be_truthy}
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when uber admin" do
|
31
|
+
When(:result) { Invitational::ChecksForInvitation.for user3, entity }
|
32
|
+
|
33
|
+
Then {result.should be_truthy}
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
context "checking for specific role" do
|
39
|
+
context "when invited in that role" do
|
40
|
+
When(:result) { Invitational::ChecksForInvitation.for user1, entity, :user }
|
41
|
+
|
42
|
+
Then {result.should be_truthy}
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when invited in another role" do
|
46
|
+
When(:result) { Invitational::ChecksForInvitation.for user1, entity, :admin }
|
47
|
+
|
48
|
+
Then {result.should_not be_truthy}
|
49
|
+
end
|
50
|
+
|
51
|
+
context "when not invited" do
|
52
|
+
When(:result) { Invitational::ChecksForInvitation.for user2, entity, :user }
|
53
|
+
|
54
|
+
Then {result.should_not be_truthy}
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when uber admin" do
|
58
|
+
When(:result) { Invitational::ChecksForInvitation.for user3, entity, :user }
|
59
|
+
|
60
|
+
Then {result.should be_truthy}
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "checking for any of an array of roles" do
|
65
|
+
context "when invited to one of the roles" do
|
66
|
+
When(:result) { Invitational::ChecksForInvitation.for user1, entity, [:user, :admin] }
|
67
|
+
|
68
|
+
Then {result.should be_truthy}
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when invited in another role" do
|
72
|
+
When(:result) { Invitational::ChecksForInvitation.for user1, entity, [:none, :admin] }
|
73
|
+
|
74
|
+
Then {result.should_not be_truthy}
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when not invited" do
|
78
|
+
When(:result) { Invitational::ChecksForInvitation.for user2, entity, [:user, :admin] }
|
79
|
+
|
80
|
+
Then {result.should_not be_truthy}
|
81
|
+
end
|
82
|
+
|
83
|
+
context "when uber admin" do
|
84
|
+
When(:result) { Invitational::ChecksForInvitation.for user3, entity, [:user, :admin] }
|
85
|
+
|
86
|
+
Then {result.should be_truthy}
|
87
|
+
end
|
88
|
+
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|