stormpath-sdk 1.0.0.beta.4 → 1.0.0.beta.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGES.md +15 -0
- data/README.md +35 -3
- data/lib/stormpath-sdk.rb +5 -6
- data/lib/stormpath-sdk/auth/basic_authenticator.rb +2 -0
- data/lib/stormpath-sdk/auth/basic_login_attempt.rb +11 -0
- data/lib/stormpath-sdk/auth/username_password_request.rb +6 -12
- data/lib/stormpath-sdk/data_store.rb +118 -127
- data/lib/stormpath-sdk/http/http_client_request_executor.rb +10 -42
- data/lib/stormpath-sdk/resource/account.rb +13 -3
- data/lib/stormpath-sdk/resource/account_membership.rb +16 -0
- data/lib/stormpath-sdk/resource/account_status.rb +26 -0
- data/lib/stormpath-sdk/resource/account_store_mapping.rb +4 -2
- data/lib/stormpath-sdk/resource/application.rb +4 -2
- data/lib/stormpath-sdk/resource/associations.rb +7 -3
- data/lib/stormpath-sdk/resource/base.rb +21 -15
- data/lib/stormpath-sdk/resource/custom_data.rb +86 -0
- data/lib/stormpath-sdk/resource/custom_data_hash_methods.rb +33 -0
- data/lib/stormpath-sdk/resource/custom_data_storage.rb +39 -0
- data/lib/stormpath-sdk/resource/directory.rb +4 -4
- data/lib/stormpath-sdk/resource/expansion.rb +15 -0
- data/lib/stormpath-sdk/resource/group.rb +10 -0
- data/lib/stormpath-sdk/resource/status.rb +16 -5
- data/lib/stormpath-sdk/version.rb +2 -2
- data/spec/client_spec.rb +6 -1
- data/spec/data_store_spec.rb +7 -2
- data/spec/resource/account_spec.rb +73 -30
- data/spec/resource/account_store_mapping_spec.rb +20 -5
- data/spec/resource/application_spec.rb +135 -0
- data/spec/resource/custom_data_spec.rb +198 -0
- data/spec/resource/directory_spec.rb +192 -9
- data/spec/resource/group_membership_spec.rb +35 -0
- data/spec/resource/group_spec.rb +44 -26
- data/spec/resource/status_spec.rb +81 -0
- data/spec/resource/tenant_spec.rb +19 -0
- data/stormpath-sdk.gemspec +2 -2
- metadata +13 -3
@@ -0,0 +1,198 @@
|
|
1
|
+
# test_api_client.accounts.get "https://api.stormpath.com/v1/accounts/1SmmWv659tY9Eeb4qKZqr0"
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe Stormpath::Resource::CustomData, :vcr do
|
5
|
+
|
6
|
+
RESERVED_FIELDS = %w( created_at modified_at meta sp_meta spmeta ion_meta ionmeta )
|
7
|
+
|
8
|
+
describe "#for accounts" do
|
9
|
+
let(:directory) { test_api_client.directories.create name: 'test_directory' }
|
10
|
+
|
11
|
+
let(:account) do
|
12
|
+
directory.accounts.create username: "jlpicard",
|
13
|
+
email: "capt@enterprise.com",
|
14
|
+
givenName: "Jean-Luc",
|
15
|
+
surname: "Picard",
|
16
|
+
password: "uGhd%a8Kl!"
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:reloaded_account) { test_api_client.accounts.get account.href }
|
20
|
+
|
21
|
+
after do
|
22
|
+
account.delete if account
|
23
|
+
directory.delete if directory
|
24
|
+
end
|
25
|
+
|
26
|
+
it 'read reserved data' do
|
27
|
+
expect(account.custom_data["href"]).not_to eq(nil)
|
28
|
+
expect(account.custom_data["created_at"]).not_to eq(nil)
|
29
|
+
expect(account.custom_data["modified_at"]).not_to eq(nil)
|
30
|
+
end
|
31
|
+
|
32
|
+
RESERVED_FIELDS.each do |reserved_field|
|
33
|
+
it "set reserved data #{reserved_field} should raise error" do
|
34
|
+
account.custom_data[reserved_field] = 12
|
35
|
+
expect{ account.custom_data.save }.to raise_error
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'set custom data' do
|
40
|
+
account.custom_data[:rank] = "Captain"
|
41
|
+
expect(account.custom_data[:rank]).to eq("Captain")
|
42
|
+
account.custom_data.save
|
43
|
+
expect(reloaded_account.custom_data[:rank]).to eq("Captain")
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'set nested custom data' do
|
47
|
+
account.custom_data[:special_rank] = "Captain"
|
48
|
+
account.custom_data[:permissions] = {"crew_quarters" => "93-601"}
|
49
|
+
expect(account.custom_data[:permissions]).to eq({"crew_quarters" => "93-601"})
|
50
|
+
account.custom_data.save
|
51
|
+
expect(reloaded_account.custom_data[:special_rank]).to eq("Captain")
|
52
|
+
expect(reloaded_account.custom_data[:permissions]).to eq({"crew_quarters" => "93-601"})
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'not raise errors when saving a empty properties array' do
|
56
|
+
account.custom_data.save
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'trigger custom data saving on account.save' do
|
60
|
+
account.custom_data[:rank] = "Captain"
|
61
|
+
account.surname = "Picard!"
|
62
|
+
account.save
|
63
|
+
expect(reloaded_account.surname).to eq("Picard!")
|
64
|
+
expect(reloaded_account.custom_data[:rank]).to eq("Captain")
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'delete all custom data' do
|
68
|
+
account.custom_data[:rank] = "Captain"
|
69
|
+
account.custom_data.save
|
70
|
+
expect(account.custom_data[:rank]).to eq("Captain")
|
71
|
+
account.custom_data.delete
|
72
|
+
expect(reloaded_account.custom_data[:rank]).to eq(nil)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'delete a specific custom data field' do
|
76
|
+
account.custom_data[:rank] = "Captain"
|
77
|
+
account.custom_data["favorite_drink"] = "Earl Grey Tea"
|
78
|
+
account.custom_data.save
|
79
|
+
|
80
|
+
account.custom_data.delete(:rank)
|
81
|
+
account.custom_data.save
|
82
|
+
|
83
|
+
expect(reloaded_account.custom_data[:rank]).to eq(nil)
|
84
|
+
expect(reloaded_account.custom_data["favorite_drink"]).to eq("Earl Grey Tea")
|
85
|
+
end
|
86
|
+
|
87
|
+
context 'should respond to' do
|
88
|
+
it '#has_key?' do
|
89
|
+
expect(account.custom_data.has_key? "created_at").to be_true
|
90
|
+
end
|
91
|
+
|
92
|
+
it '#include?' do
|
93
|
+
expect(account.custom_data.include? "created_at").to be_true
|
94
|
+
end
|
95
|
+
|
96
|
+
it '#has_value?' do
|
97
|
+
account.custom_data[:rank] = "Captain"
|
98
|
+
account.custom_data.save
|
99
|
+
expect(reloaded_account.custom_data.has_value? "Captain").to be_true
|
100
|
+
end
|
101
|
+
|
102
|
+
it '#store' do
|
103
|
+
account.custom_data.store(:rank, "Captain")
|
104
|
+
account.custom_data.save
|
105
|
+
expect(reloaded_account.custom_data[:rank]).to eq("Captain")
|
106
|
+
end
|
107
|
+
|
108
|
+
it '#keys' do
|
109
|
+
expect(account.custom_data.keys).to be_kind_of(Array)
|
110
|
+
expect(account.custom_data.keys).to have_at_least(3).items
|
111
|
+
expect(account.custom_data.keys.map {|key| key.to_s.camelize :lower}).to eq(account.custom_data.properties.keys)
|
112
|
+
end
|
113
|
+
|
114
|
+
it '#values' do
|
115
|
+
account.custom_data[:permissions] = {"crew_quarters" => "93-601"}
|
116
|
+
account.custom_data.save
|
117
|
+
expect(reloaded_account.custom_data.values).to include({"crew_quarters" => "93-601"})
|
118
|
+
expect(reloaded_account.custom_data.values).to eq(reloaded_account.custom_data.properties.values)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#for groups" do
|
125
|
+
let(:directory) { test_api_client.directories.create name: 'test_directory' }
|
126
|
+
|
127
|
+
let(:group) { directory.groups.create name: 'test_group' }
|
128
|
+
|
129
|
+
let(:reloaded_group) { test_api_client.groups.get group.href }
|
130
|
+
|
131
|
+
after do
|
132
|
+
group.delete if group
|
133
|
+
directory.delete if directory
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'read reserved data' do
|
137
|
+
expect(group.custom_data["href"]).not_to eq(nil)
|
138
|
+
expect(group.custom_data["created_at"]).not_to eq(nil)
|
139
|
+
expect(group.custom_data["modified_at"]).not_to eq(nil)
|
140
|
+
end
|
141
|
+
|
142
|
+
RESERVED_FIELDS.each do |reserved_field|
|
143
|
+
it "set reserved data #{reserved_field} should raise error" do
|
144
|
+
group.custom_data[reserved_field] = 12
|
145
|
+
expect{ group.custom_data.save }.to raise_error
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'set custom data' do
|
150
|
+
group.custom_data[:series] = "Enterprise"
|
151
|
+
expect(group.custom_data[:series]).to eq("Enterprise")
|
152
|
+
group.custom_data.save
|
153
|
+
expect(reloaded_group.custom_data[:series]).to eq("Enterprise")
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'set nested custom data' do
|
157
|
+
group.custom_data[:special_rank] = "Captain"
|
158
|
+
group.custom_data[:permissions] = {"crew_quarters" => "93-601"}
|
159
|
+
expect(group.custom_data[:permissions]).to eq({"crew_quarters" => "93-601"})
|
160
|
+
group.custom_data.save
|
161
|
+
expect(reloaded_group.custom_data[:special_rank]).to eq("Captain")
|
162
|
+
expect(reloaded_group.custom_data[:permissions]).to eq({"crew_quarters" => "93-601"})
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'not raise errors when saving a empty properties array' do
|
166
|
+
group.custom_data.save
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'trigger custom data saving on group.save' do
|
170
|
+
group.custom_data[:series] = "Enterprise"
|
171
|
+
group.description = "founded on the twin principles of joy and service"
|
172
|
+
group.save
|
173
|
+
expect(reloaded_group.description).to eq("founded on the twin principles of joy and service")
|
174
|
+
expect(reloaded_group.custom_data[:series]).to eq("Enterprise")
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'delete all custom data' do
|
178
|
+
group.custom_data["series"] = "Enterprise"
|
179
|
+
group.custom_data.save
|
180
|
+
expect(group.custom_data["series"]).to eq("Enterprise")
|
181
|
+
group.custom_data.delete
|
182
|
+
expect(reloaded_group.custom_data["series"]).to eq(nil)
|
183
|
+
end
|
184
|
+
|
185
|
+
it 'delete a specific custom data field' do
|
186
|
+
group.custom_data["series"] = "Enterprise"
|
187
|
+
group.custom_data["favorite_drink"] = "Earl Grey Tea"
|
188
|
+
group.custom_data.save
|
189
|
+
|
190
|
+
group.custom_data.delete("series")
|
191
|
+
group.custom_data.save
|
192
|
+
|
193
|
+
expect(reloaded_group.custom_data["series"]).to eq(nil)
|
194
|
+
expect(reloaded_group.custom_data["favorite_drink"]).to eq("Earl Grey Tea")
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
end
|
@@ -1,30 +1,213 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Stormpath::Resource::Directory, :vcr do
|
4
|
+
|
5
|
+
describe "instances should respond to attribute property methods" do
|
6
|
+
subject(:directory) { test_api_client.directories.create name: 'some_test_directory', description: 'description_for_some_test_directory' }
|
7
|
+
|
8
|
+
it { should be_instance_of Stormpath::Resource::Directory }
|
9
|
+
|
10
|
+
[:name, :description, :status].each do |property_accessor|
|
11
|
+
it { should respond_to property_accessor }
|
12
|
+
it { should respond_to "#{property_accessor}="}
|
13
|
+
its(property_accessor) { should be_instance_of String }
|
14
|
+
end
|
15
|
+
|
16
|
+
its(:tenant) { should be_instance_of Stormpath::Resource::Tenant }
|
17
|
+
its(:groups) { should be_instance_of Stormpath::Resource::Collection }
|
18
|
+
its(:accounts) { should be_instance_of Stormpath::Resource::Collection }
|
19
|
+
|
20
|
+
after do
|
21
|
+
directory.delete if directory
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'directory_associations' do
|
26
|
+
let(:directory) { test_directory }
|
27
|
+
|
28
|
+
context '#accounts' do
|
29
|
+
let(:account) { directory.accounts.create build_account}
|
30
|
+
|
31
|
+
after do
|
32
|
+
account.delete if account
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should be able to create an account' do
|
36
|
+
expect(directory.accounts).to include(account)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should be able to create and fetch the account' do
|
40
|
+
expect(directory.accounts.get account.href).to be
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context '#groups' do
|
45
|
+
let(:group) { directory.groups.create name: "test_group"}
|
46
|
+
|
47
|
+
after do
|
48
|
+
group.delete if group
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should be able to create a group' do
|
52
|
+
expect(directory.groups).to include(group)
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should be able to create and get a group' do
|
56
|
+
expect(directory.groups.get group.href).to be
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
4
62
|
describe '#create_account' do
|
5
63
|
let(:directory) { test_directory }
|
6
64
|
|
7
|
-
|
8
|
-
|
9
|
-
|
65
|
+
let(:account) do
|
66
|
+
Stormpath::Resource::Account.new({
|
67
|
+
email: "test@example.com",
|
68
|
+
given_name: 'Ruby SDK',
|
69
|
+
password: 'P@$$w0rd',
|
70
|
+
surname: 'SDK',
|
71
|
+
username: "username"
|
72
|
+
})
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'without registration workflow' do
|
76
|
+
|
77
|
+
let(:created_account) { directory.create_account account }
|
78
|
+
|
79
|
+
after do
|
80
|
+
created_account.delete if created_account
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'creates an account with status ENABLED' do
|
84
|
+
expect(created_account).to be
|
85
|
+
expect(created_account.username).to eq(account.username)
|
86
|
+
expect(created_account).to eq(account)
|
87
|
+
expect(created_account.status).to eq("ENABLED")
|
88
|
+
expect(created_account.email_verification_token.href).not_to be
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context 'with registration workflow' do
|
93
|
+
|
94
|
+
let(:created_account_with_reg_workflow) { test_directory_with_verification.create_account account }
|
95
|
+
|
96
|
+
after do
|
97
|
+
created_account_with_reg_workflow.delete if created_account_with_reg_workflow
|
98
|
+
end
|
99
|
+
|
100
|
+
it 'creates an account with status UNVERIFIED' do
|
101
|
+
expect(created_account_with_reg_workflow).to be
|
102
|
+
expect(created_account_with_reg_workflow.username).to eq(account.username)
|
103
|
+
expect(created_account_with_reg_workflow).to eq(account)
|
104
|
+
expect(created_account_with_reg_workflow.status).to eq("UNVERIFIED")
|
105
|
+
expect(created_account_with_reg_workflow.email_verification_token.href).to be
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
|
110
|
+
context 'with registration workflow but set it to false on account creation' do
|
111
|
+
|
112
|
+
let(:created_account_with_reg_workflow) { test_directory_with_verification.create_account account, false }
|
113
|
+
|
114
|
+
after do
|
115
|
+
created_account_with_reg_workflow.delete if created_account_with_reg_workflow
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'creates an account with status ENABLED' do
|
119
|
+
expect(created_account_with_reg_workflow).to be
|
120
|
+
expect(created_account_with_reg_workflow.username).to eq(account.username)
|
121
|
+
expect(created_account_with_reg_workflow).to eq(account)
|
122
|
+
expect(created_account_with_reg_workflow.status).to eq("ENABLED")
|
123
|
+
expect(created_account_with_reg_workflow.email_verification_token.href).not_to be
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
describe '#create_account_with_custom_data' do
|
131
|
+
let(:directory) { test_directory }
|
132
|
+
|
133
|
+
it 'creates an account with custom data' do
|
134
|
+
account = Stormpath::Resource::Account.new({
|
10
135
|
email: "test@example.com",
|
11
136
|
given_name: 'Ruby SDK',
|
12
137
|
password: 'P@$$w0rd',
|
13
138
|
surname: 'SDK',
|
14
139
|
username: "username"
|
15
140
|
})
|
16
|
-
end
|
17
141
|
|
18
|
-
|
142
|
+
account.custom_data["birth_date"] = "2305-07-13"
|
19
143
|
|
20
|
-
|
21
|
-
created_account.delete if created_account
|
22
|
-
end
|
144
|
+
created_account = directory.create_account account
|
23
145
|
|
24
|
-
it 'creates an account' do
|
25
146
|
expect(created_account).to be
|
26
147
|
expect(created_account.username).to eq(account.username)
|
148
|
+
expect(created_account).to eq(account)
|
149
|
+
expect(created_account.custom_data["birth_date"]).to eq("2305-07-13")
|
150
|
+
created_account.delete
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
describe '#create_group' do
|
155
|
+
let(:directory) { test_directory }
|
156
|
+
|
157
|
+
context 'given a valid group' do
|
158
|
+
let(:group_name) { "valid_test_group" }
|
159
|
+
|
160
|
+
let(:created_group) { directory.groups.create name: group_name }
|
161
|
+
|
162
|
+
after do
|
163
|
+
created_group.delete if created_group
|
164
|
+
end
|
165
|
+
|
166
|
+
it 'creates a group' do
|
167
|
+
expect(created_group).to be
|
168
|
+
expect(created_group.name).to eq(group_name)
|
27
169
|
end
|
28
170
|
end
|
29
171
|
end
|
172
|
+
|
173
|
+
describe '#delete_directory' do
|
174
|
+
|
175
|
+
let(:directory) { test_api_client.directories.create name: 'test_directory' }
|
176
|
+
|
177
|
+
let(:application) { test_api_client.applications.create name: 'test_application' }
|
178
|
+
|
179
|
+
let!(:group) { directory.groups.create name: 'someGroup' }
|
180
|
+
|
181
|
+
let!(:account) { directory.accounts.create({ email: 'rubysdk@example.com', given_name: 'Ruby SDK', password: 'P@$$w0rd',surname: 'SDK' }) }
|
182
|
+
|
183
|
+
let!(:account_store_mapping) do
|
184
|
+
test_api_client.account_store_mappings.create({ application: application, account_store: directory })
|
185
|
+
end
|
186
|
+
|
187
|
+
after do
|
188
|
+
application.delete if application
|
189
|
+
end
|
190
|
+
|
191
|
+
it 'and all of its associations' do
|
192
|
+
expect(directory.groups).to have(1).item
|
193
|
+
expect(directory.accounts).to have(1).item
|
194
|
+
|
195
|
+
expect(application.account_store_mappings.first.account_store).to eq(directory)
|
196
|
+
|
197
|
+
expect(application.accounts).to include(account)
|
198
|
+
expect(application.groups).to include(group)
|
199
|
+
|
200
|
+
expect(application.account_store_mappings).to have(1).item
|
201
|
+
|
202
|
+
directory.delete
|
203
|
+
|
204
|
+
expect(application.account_store_mappings).to have(0).item
|
205
|
+
|
206
|
+
expect(application.accounts).not_to include(account)
|
207
|
+
expect(application.groups).not_to include(group)
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
|
212
|
+
|
30
213
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Stormpath::Resource::GroupMembership, :vcr do
|
4
|
+
it "should be the same as AccountMembership" do
|
5
|
+
expect(Stormpath::Resource::GroupMembership).to eq(Stormpath::Resource::AccountMembership)
|
6
|
+
end
|
7
|
+
|
8
|
+
describe '#add_account' do
|
9
|
+
context "given an account and a group" do
|
10
|
+
|
11
|
+
let(:directory) { test_api_client.directories.create name: 'testDirectory' }
|
12
|
+
|
13
|
+
let(:group) { directory.groups.create name: 'someGroup' }
|
14
|
+
|
15
|
+
let(:account) { directory.accounts.create({ email: 'rubysdk@example.com', given_name: 'Ruby SDK', password: 'P@$$w0rd', surname: 'SDK' }) }
|
16
|
+
|
17
|
+
before { group.add_account account }
|
18
|
+
|
19
|
+
after do
|
20
|
+
group.delete if group
|
21
|
+
directory.delete if directory
|
22
|
+
account.delete if account
|
23
|
+
end
|
24
|
+
|
25
|
+
it ", group membership and account membership should correspond to each other" do
|
26
|
+
expect(group.account_memberships).to have(1).item
|
27
|
+
expect(account.group_memberships).to have(1).item
|
28
|
+
expect(group.accounts).to include(account)
|
29
|
+
expect(account.groups).to include(group)
|
30
|
+
expect(group.account_memberships.first).to be_a(Stormpath::Resource::GroupMembership)
|
31
|
+
expect(account.group_memberships.first).to be_a(Stormpath::Resource::GroupMembership)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|