usergrid_ironhorse 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +18 -0
- data/.rspec +1 -0
- data/.rvmrc +2 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +121 -0
- data/Rakefile +7 -0
- data/lib/extensions/hash.rb +7 -0
- data/lib/usergrid_ironhorse.rb +24 -0
- data/lib/usergrid_ironhorse/base.rb +360 -0
- data/lib/usergrid_ironhorse/query.rb +890 -0
- data/lib/usergrid_ironhorse/user_context.rb +79 -0
- data/lib/usergrid_ironhorse/version.rb +5 -0
- data/spec/spec_helper.rb +78 -0
- data/spec/spec_settings.yaml +5 -0
- data/spec/support/active_model_lint.rb +17 -0
- data/spec/usergrid_ironhorse/base_spec.rb +283 -0
- data/usergrid_ironhorse.gemspec +29 -0
- metadata +186 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
module Usergrid
|
2
|
+
module Ironhorse
|
3
|
+
module UserContext
|
4
|
+
|
5
|
+
# returns user if logged in, nil otherwise
|
6
|
+
# if session is passed, stores user_id and auth_token in the session
|
7
|
+
# and sets User as current_user
|
8
|
+
def authenticate(username, password, session=nil)
|
9
|
+
application = Usergrid::Application.new Usergrid::Ironhorse::Base.settings[:application_url]
|
10
|
+
begin
|
11
|
+
application.login username, password
|
12
|
+
user = new application.current_user.data
|
13
|
+
if session
|
14
|
+
session[:usergrid_user_id] = user.id
|
15
|
+
session[:usergrid_auth_token] = user.current_auth_token
|
16
|
+
set_thread_context(session)
|
17
|
+
Thread.current[:usergrid_current_user] = user
|
18
|
+
end
|
19
|
+
user
|
20
|
+
rescue
|
21
|
+
Rails.logger.info $!
|
22
|
+
raise $!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# clears auth from session and thread
|
27
|
+
def clear_authentication(session)
|
28
|
+
session[:usergrid_user_id] = nil
|
29
|
+
session[:usergrid_auth_token] = nil
|
30
|
+
clear_thread_context(session)
|
31
|
+
end
|
32
|
+
|
33
|
+
# allows admin actions to be done in a block
|
34
|
+
def as_admin(&block)
|
35
|
+
save_user_id = Thread.current[:usergrid_user_id]
|
36
|
+
save_auth_token = Thread.current[:usergrid_auth_token]
|
37
|
+
save_user = Thread.current[:usergrid_current_user]
|
38
|
+
begin
|
39
|
+
Thread.current[:usergrid_user_id] = nil
|
40
|
+
Thread.current[:usergrid_auth_token] = Base.settings[:auth_token]
|
41
|
+
Thread.current[:usergrid_current_user] = nil
|
42
|
+
yield block
|
43
|
+
ensure
|
44
|
+
Thread.current[:usergrid_user_id] = save_user_id
|
45
|
+
Thread.current[:usergrid_auth_token] = save_auth_token
|
46
|
+
Thread.current[:usergrid_current_user] = save_user
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# sets auth for current thread
|
51
|
+
def set_thread_context(session)
|
52
|
+
Thread.current[:usergrid_user_id] = session[:usergrid_user_id]
|
53
|
+
Thread.current[:usergrid_auth_token] = session[:usergrid_auth_token]
|
54
|
+
Thread.current[:usergrid_current_user] = nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# clears auth from current thread
|
58
|
+
def clear_thread_context(session)
|
59
|
+
Thread.current[:usergrid_user_id] = nil
|
60
|
+
Thread.current[:usergrid_auth_token] = nil
|
61
|
+
Thread.current[:usergrid_current_user] = nil
|
62
|
+
end
|
63
|
+
|
64
|
+
# returns the auth token for the current thread
|
65
|
+
def current_auth_token
|
66
|
+
Thread.current[:usergrid_auth_token]
|
67
|
+
end
|
68
|
+
|
69
|
+
# does a find and return
|
70
|
+
def current_user
|
71
|
+
unless Thread.current[:usergrid_current_user]
|
72
|
+
Thread.current[:usergrid_current_user] = find(Thread.current[:usergrid_user_id]) if Thread.current[:usergrid_user_id]
|
73
|
+
end
|
74
|
+
Thread.current[:usergrid_current_user]
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'rspec'
|
4
|
+
require 'yaml'
|
5
|
+
require 'securerandom'
|
6
|
+
require_relative '../lib/usergrid_ironhorse'
|
7
|
+
|
8
|
+
ENV["RAILS_ENV"] ||= 'test'
|
9
|
+
Dir[Pathname.new(File.dirname(__FILE__)).join("support/**/*.rb")].each { |f| require f }
|
10
|
+
|
11
|
+
RSpec.configure do |config|
|
12
|
+
config.mock_with :rspec
|
13
|
+
config.expect_with :stdlib
|
14
|
+
config.expect_with :rspec
|
15
|
+
end
|
16
|
+
|
17
|
+
LOG = Logger.new(STDOUT)
|
18
|
+
RestClient.log=LOG
|
19
|
+
|
20
|
+
SimpleCov.at_exit do
|
21
|
+
SimpleCov.result.format!
|
22
|
+
#index = File.join(SimpleCov.coverage_path, 'index.html')
|
23
|
+
#`open #{index}` if File.exists?(index)
|
24
|
+
end
|
25
|
+
SimpleCov.start
|
26
|
+
|
27
|
+
|
28
|
+
SPEC_SETTINGS = YAML::load_file(File.join File.dirname(__FILE__), 'spec_settings.yaml')
|
29
|
+
|
30
|
+
def login_management
|
31
|
+
management = Usergrid::Resource.new(SPEC_SETTINGS[:api_url]).management
|
32
|
+
management.login SPEC_SETTINGS[:organization][:username], SPEC_SETTINGS[:organization][:password]
|
33
|
+
management
|
34
|
+
end
|
35
|
+
|
36
|
+
# ensure we are correctly setup (management login & organization)
|
37
|
+
management = login_management
|
38
|
+
|
39
|
+
begin
|
40
|
+
management.create_organization(SPEC_SETTINGS[:organization][:name],
|
41
|
+
SPEC_SETTINGS[:organization][:username],
|
42
|
+
SPEC_SETTINGS[:organization][:username],
|
43
|
+
"#{SPEC_SETTINGS[:organization][:username]}@email.com",
|
44
|
+
SPEC_SETTINGS[:organization][:password])
|
45
|
+
LOG.info "created organization with user #{SPEC_SETTINGS[:organization][:username]}@email.com"
|
46
|
+
rescue
|
47
|
+
if MultiJson.load($!.response)['error'] == "duplicate_unique_property_exists"
|
48
|
+
LOG.debug "test organization exists"
|
49
|
+
else
|
50
|
+
raise $!
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def create_random_application
|
55
|
+
management = login_management
|
56
|
+
organization = management.organization SPEC_SETTINGS[:organization][:name]
|
57
|
+
|
58
|
+
app_name = "_test_app_#{SecureRandom.hex}"
|
59
|
+
organization.create_application app_name
|
60
|
+
management.application SPEC_SETTINGS[:organization][:name], app_name
|
61
|
+
end
|
62
|
+
|
63
|
+
def delete_application(application)
|
64
|
+
management = login_management
|
65
|
+
application.auth_token = management.auth_token
|
66
|
+
application.delete rescue nil # not implemented on server yet
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_random_user(application, login=false)
|
70
|
+
random = SecureRandom.hex
|
71
|
+
user_hash = {username: "username_#{random}",
|
72
|
+
password: random,
|
73
|
+
email: "#{random}@email.com",
|
74
|
+
name: "#{random} name" }
|
75
|
+
entity = application['users'].post(user_hash).entity
|
76
|
+
application.login user_hash[:username], user_hash[:password] if login
|
77
|
+
entity
|
78
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# spec/support/active_model_lint.rb
|
2
|
+
# adapted from rspec-rails: http://github.com/rspec/rspec-rails/blob/master/spec/rspec/rails/mocks/mock_model_spec.rb
|
3
|
+
|
4
|
+
shared_examples_for "ActiveModel" do
|
5
|
+
include ActiveModel::Lint::Tests
|
6
|
+
|
7
|
+
# to_s is to support ruby-1.9
|
8
|
+
ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
|
9
|
+
example m.sub('_',' ') do
|
10
|
+
send m
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def model
|
15
|
+
subject
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,283 @@
|
|
1
|
+
describe Usergrid::Ironhorse::Base do
|
2
|
+
|
3
|
+
it_should_behave_like 'ActiveModel'
|
4
|
+
|
5
|
+
before :all do
|
6
|
+
@application = create_random_application
|
7
|
+
Foo.configure!(@application.url, @application.auth_token)
|
8
|
+
@user = create_random_user @application, true
|
9
|
+
@foo = (@application.create_entity 'foos', name: 'foo42', answer: 42).entity
|
10
|
+
end
|
11
|
+
|
12
|
+
after :all do
|
13
|
+
@foo.delete
|
14
|
+
@user.delete
|
15
|
+
#delete_application @application
|
16
|
+
end
|
17
|
+
|
18
|
+
class Foo < Usergrid::Ironhorse::Base; end
|
19
|
+
Foo.validates :name, :presence => true
|
20
|
+
|
21
|
+
class Bar < Usergrid::Ironhorse::Base; end
|
22
|
+
|
23
|
+
describe 'subclasses should be able to' do
|
24
|
+
|
25
|
+
it 'be created and destroyed' do
|
26
|
+
foo = Foo.create name: 'foo2'
|
27
|
+
foo.persisted?.should be_true
|
28
|
+
foo.name.should eq 'foo2'
|
29
|
+
foo.destroy.should be_true
|
30
|
+
foo.persisted?.should be_false
|
31
|
+
foo = Foo.find_by_name 'foo2'
|
32
|
+
foo.should be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'be changed and saved' do
|
36
|
+
foo = Foo.find_by_name @foo.name
|
37
|
+
foo.answer.should eq @foo.answer
|
38
|
+
foo.number = 43
|
39
|
+
foo.changed?.should be_true
|
40
|
+
foo.number.should == 43
|
41
|
+
foo.save!
|
42
|
+
foo = Foo.find_by_name @foo.name
|
43
|
+
foo.number.should == 43
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'be reloaded' do
|
47
|
+
foo = Foo.find @foo.uuid
|
48
|
+
foo.answer = 44
|
49
|
+
foo.changed?.should be_true
|
50
|
+
foo.answer.should == 44
|
51
|
+
foo.reload
|
52
|
+
foo.answer.should == 42
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'be found using find_by_name' do
|
56
|
+
foo = Foo.find_by_name @foo.name
|
57
|
+
foo.uuid.should_not be_nil
|
58
|
+
foo.name.should eq @foo.name
|
59
|
+
foo.should be_a Foo
|
60
|
+
foo.persisted?.should be_true
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'be found using find_by_name!' do
|
64
|
+
foo = Foo.find_by_name! @foo.name
|
65
|
+
foo.uuid.should_not be_nil
|
66
|
+
foo.name.should eq @foo.name
|
67
|
+
foo.should be_a Foo
|
68
|
+
foo.persisted?.should be_true
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'throw a RecordNotFound when find_by_name! misses' do
|
72
|
+
expect { Foo.find_by_name! 'name3' }.to raise_error(ActiveRecord::RecordNotFound)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'add a validation' do
|
76
|
+
foo = Foo.new
|
77
|
+
foo.valid?.should be_false
|
78
|
+
foo.name = 'joe'
|
79
|
+
foo.valid?.should be_true
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'fail to save an invalid record and save the errors' do
|
83
|
+
foo = Foo.new
|
84
|
+
foo.save.should be_false
|
85
|
+
foo.persisted?.should be_false
|
86
|
+
foo.errors.count.should == 1
|
87
|
+
foo.errors.get(:name).first.should eq "can't be blank"
|
88
|
+
end
|
89
|
+
|
90
|
+
it 'fail to create an invalid record and save the errors' do
|
91
|
+
foo = Foo.create
|
92
|
+
foo.persisted?.should be_false
|
93
|
+
foo.errors.count.should == 1
|
94
|
+
foo.errors.get(:name).first.should eq "can't be blank"
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'fail to save! an invalid record' do
|
98
|
+
expect { Foo.new.save! }.to raise_error(ActiveRecord::RecordNotSaved)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'fail to create! an invalid record' do
|
102
|
+
expect { Foo.create! }.to raise_error(ActiveRecord::RecordNotSaved)
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'retrieve first' do
|
106
|
+
foo2 = Foo.create! name: 'foo2'
|
107
|
+
foo = Foo.first
|
108
|
+
foo.uuid.should eq @foo.uuid
|
109
|
+
foo2.destroy
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'retrieve last' do
|
113
|
+
foo2 = Foo.create! name: 'foo2'
|
114
|
+
foo = Foo.last
|
115
|
+
foo.uuid.should eq foo2.uuid
|
116
|
+
foo2.destroy
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'take multiple' do
|
120
|
+
foo2 = Foo.create! name: 'foo2'
|
121
|
+
foos = Foo.take(2)
|
122
|
+
foos.size.should == 2
|
123
|
+
foos.first.uuid.should_not be_nil
|
124
|
+
foo2.destroy
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'find multiple by id' do
|
128
|
+
foo2 = Foo.create name: 'foo2'
|
129
|
+
foos = Foo.find @foo.uuid, foo2.uuid
|
130
|
+
foos.size.should == 2
|
131
|
+
foos.first.uuid.should eq @foo.uuid
|
132
|
+
foos.last.uuid.should eq foo2.uuid
|
133
|
+
foo2.destroy
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'find multiple by name' do
|
137
|
+
foo2 = Foo.create! name: 'foo2'
|
138
|
+
foos = Foo.find @foo.name, foo2.name
|
139
|
+
foos.size.should == 2
|
140
|
+
foos.first.uuid.should eq @foo.uuid
|
141
|
+
foos.last.uuid.should eq foo2.uuid
|
142
|
+
foo2.destroy
|
143
|
+
end
|
144
|
+
|
145
|
+
it 'check exists?(string)' do
|
146
|
+
Foo.exists?(@foo.name).should be_true
|
147
|
+
end
|
148
|
+
|
149
|
+
it 'check not exists?(string)' do
|
150
|
+
Foo.exists?('asdfasdf').should be_false
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'check exists?(Array)' do
|
154
|
+
Foo.exists?(['name = ?', @foo.name]).should be_true
|
155
|
+
end
|
156
|
+
|
157
|
+
it 'check not exists?(Array)' do
|
158
|
+
Foo.exists?(['name = ?', 'asdfasdf']).should be_false
|
159
|
+
end
|
160
|
+
|
161
|
+
it 'check exists?(Hash)' do
|
162
|
+
Foo.exists?(name: @foo.name).should be_true
|
163
|
+
end
|
164
|
+
|
165
|
+
it 'check not exists?(Hash)' do
|
166
|
+
Foo.exists?(name: 'asfasdf').should be_false
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'check exists?(nil)' do
|
170
|
+
Foo.exists?.should be_true
|
171
|
+
end
|
172
|
+
|
173
|
+
it 'check not exists?(nil)' do
|
174
|
+
Bar.exists?.should be_false
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'perform first_or_create where found' do
|
178
|
+
foo = Foo.where(name: @foo.name).first_or_create
|
179
|
+
foo.uuid.should eq @foo.uuid
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'perform first_or_create where not found' do
|
183
|
+
foo = Foo.where(name: 'foo2').first_or_create(number: 42)
|
184
|
+
foo.name.should eq 'foo2'
|
185
|
+
foo.number.should == 42
|
186
|
+
foo.destroy
|
187
|
+
end
|
188
|
+
|
189
|
+
it 'perform first_or_create! where found' do
|
190
|
+
foo = Foo.where(name: @foo.name).first_or_create!
|
191
|
+
foo.uuid.should eq @foo.uuid
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'perform first_or_create! where not found' do
|
195
|
+
expect { Foo.where(nuumber: 'foo2').first_or_create! }.to raise_error(ActiveRecord::RecordNotSaved)
|
196
|
+
end
|
197
|
+
|
198
|
+
it 'perform first_or_initialize where found' do
|
199
|
+
foo = Foo.where(name: @foo.name).first_or_initialize(xxx: 42)
|
200
|
+
foo.uuid.should eq @foo.uuid
|
201
|
+
foo.xxx.should be_nil
|
202
|
+
end
|
203
|
+
|
204
|
+
it 'perform first_or_initialize where not found' do
|
205
|
+
foo = Foo.where(name: 'foo2').first_or_initialize(number: 42)
|
206
|
+
foo.name.should eq 'foo2'
|
207
|
+
foo.number.should == 42
|
208
|
+
foo.persisted?.should be_false
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should destroy by id" do
|
212
|
+
foo = Foo.create! name: 'foo'
|
213
|
+
Foo.destroy(foo.id)
|
214
|
+
foo = Foo.find_by_name 'foo'
|
215
|
+
foo.should be_nil
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should destroy by ids" do
|
219
|
+
foo = Foo.create! name: 'foo'
|
220
|
+
foo2 = Foo.create! name: 'foo2'
|
221
|
+
Foo.destroy([foo.id, foo2.id])
|
222
|
+
Foo.find_by_name('foo').should be_nil
|
223
|
+
Foo.find_by_name('foo2').should be_nil
|
224
|
+
end
|
225
|
+
|
226
|
+
it "should destroy_all" do
|
227
|
+
foo = Foo.create! name: 'foo', number: 42
|
228
|
+
foo2 = Foo.create! name: 'foo2', number: 42
|
229
|
+
Foo.destroy_all(number: 42)
|
230
|
+
Foo.find_by_name('foo').should be_nil
|
231
|
+
Foo.find_by_name('foo2').should be_nil
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should delete by id" do
|
235
|
+
foo = Foo.create! name: 'foo'
|
236
|
+
Foo.delete(foo.id)
|
237
|
+
foo = Foo.find_by_name 'foo'
|
238
|
+
foo.should be_nil
|
239
|
+
end
|
240
|
+
|
241
|
+
it "should delete by ids" do
|
242
|
+
foo = Foo.create! name: 'foo'
|
243
|
+
foo2 = Foo.create! name: 'foo2'
|
244
|
+
Foo.delete([foo.id, foo2.id])
|
245
|
+
Foo.find_by_name('foo').should be_nil
|
246
|
+
Foo.find_by_name('foo2').should be_nil
|
247
|
+
end
|
248
|
+
|
249
|
+
it "should delete_all" do
|
250
|
+
foo = Foo.create! name: 'foo', number: 42
|
251
|
+
foo2 = Foo.create! name: 'foo2', number: 42
|
252
|
+
Foo.delete_all(number: 42)
|
253
|
+
Foo.find_by_name('foo').should be_nil
|
254
|
+
Foo.find_by_name('foo2').should be_nil
|
255
|
+
end
|
256
|
+
|
257
|
+
it "should update one" do
|
258
|
+
foo = Foo.create! name: 'foo', number: 42
|
259
|
+
Foo.update foo.uuid, { number: 43 }
|
260
|
+
foo.reload.number.should == 43
|
261
|
+
foo.destroy
|
262
|
+
end
|
263
|
+
|
264
|
+
it "should update multiple" do
|
265
|
+
foo = Foo.create! name: 'foo', number: 42
|
266
|
+
foo2 = Foo.create! name: 'foo2', number: 42
|
267
|
+
updates = { foo.uuid => {number: 43}, foo2.uuid => {number: 44}}
|
268
|
+
Foo.update(updates.keys, updates.values)
|
269
|
+
foo.reload.number.should == 43
|
270
|
+
foo2.reload.number.should == 44
|
271
|
+
foo.destroy
|
272
|
+
foo2.destroy
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should update_all" do
|
276
|
+
foo = Foo.create! name: 'foo', number: 43
|
277
|
+
Foo.where(number: 43).update_all({number: 44})
|
278
|
+
Foo.find_by_number(44).should_not be_nil
|
279
|
+
foo.destroy
|
280
|
+
end
|
281
|
+
|
282
|
+
end
|
283
|
+
end
|