test_track_rails_client 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +62 -7
  3. data/Rakefile +8 -4
  4. data/app/models/test_track/analytics/mixpanel_client.rb +2 -5
  5. data/app/models/test_track/analytics/safe_wrapper.rb +4 -4
  6. data/app/models/test_track/config_updater.rb +2 -2
  7. data/app/models/test_track/fake/split_registry.rb +2 -2
  8. data/app/models/test_track/notify_assignment_job.rb +3 -4
  9. data/app/models/test_track/offline_session.rb +6 -4
  10. data/app/models/test_track/remote/split_registry.rb +2 -2
  11. data/app/models/test_track/remote/visitor.rb +2 -2
  12. data/app/models/test_track/session.rb +12 -73
  13. data/app/models/test_track/unsynced_assignments_notifier.rb +2 -4
  14. data/app/models/test_track/vary_dsl.rb +5 -1
  15. data/app/models/test_track/visitor.rb +0 -11
  16. data/lib/test_track_rails_client/version.rb +1 -1
  17. data/vendor/gems/fakeable_her/fakeable_her.gemspec +2 -3
  18. data/vendor/gems/her/her.gemspec +4 -5
  19. data/vendor/gems/her/lib/her/api.rb +1 -1
  20. data/vendor/gems/her/lib/her/model/associations/association_proxy.rb +1 -2
  21. data/vendor/gems/her/lib/her/model/orm.rb +41 -29
  22. data/vendor/gems/her/lib/her/model/parse.rb +1 -0
  23. data/vendor/gems/her/lib/her/model/relation.rb +21 -6
  24. data/vendor/gems/her/lib/her/version.rb +1 -1
  25. metadata +52 -139
  26. data/app/models/test_track/create_alias_job.rb +0 -18
  27. data/vendor/gems/her/CONTRIBUTING.md +0 -26
  28. data/vendor/gems/her/Gemfile +0 -10
  29. data/vendor/gems/her/README.md +0 -1023
  30. data/vendor/gems/her/Rakefile +0 -11
  31. data/vendor/gems/her/UPGRADE.md +0 -101
  32. data/vendor/gems/her/gemfiles/Gemfile.activemodel-3.2.x +0 -7
  33. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.0 +0 -7
  34. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.1 +0 -7
  35. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.2 +0 -7
  36. data/vendor/gems/her/spec/api_spec.rb +0 -114
  37. data/vendor/gems/her/spec/collection_spec.rb +0 -26
  38. data/vendor/gems/her/spec/error_collection_spec.rb +0 -33
  39. data/vendor/gems/her/spec/json_api/model_spec.rb +0 -168
  40. data/vendor/gems/her/spec/middleware/accept_json_spec.rb +0 -10
  41. data/vendor/gems/her/spec/middleware/first_level_parse_json_spec.rb +0 -62
  42. data/vendor/gems/her/spec/middleware/json_api_parser_spec.rb +0 -32
  43. data/vendor/gems/her/spec/middleware/second_level_parse_json_spec.rb +0 -35
  44. data/vendor/gems/her/spec/model/associations/association_proxy_spec.rb +0 -31
  45. data/vendor/gems/her/spec/model/associations_spec.rb +0 -504
  46. data/vendor/gems/her/spec/model/attributes_spec.rb +0 -404
  47. data/vendor/gems/her/spec/model/callbacks_spec.rb +0 -145
  48. data/vendor/gems/her/spec/model/dirty_spec.rb +0 -110
  49. data/vendor/gems/her/spec/model/http_spec.rb +0 -165
  50. data/vendor/gems/her/spec/model/introspection_spec.rb +0 -76
  51. data/vendor/gems/her/spec/model/nested_attributes_spec.rb +0 -134
  52. data/vendor/gems/her/spec/model/orm_spec.rb +0 -791
  53. data/vendor/gems/her/spec/model/parse_spec.rb +0 -372
  54. data/vendor/gems/her/spec/model/paths_spec.rb +0 -347
  55. data/vendor/gems/her/spec/model/relation_spec.rb +0 -226
  56. data/vendor/gems/her/spec/model/validations_spec.rb +0 -42
  57. data/vendor/gems/her/spec/model_spec.rb +0 -31
  58. data/vendor/gems/her/spec/spec_helper.rb +0 -27
  59. data/vendor/gems/her/spec/support/extensions/array.rb +0 -5
  60. data/vendor/gems/her/spec/support/extensions/hash.rb +0 -5
  61. data/vendor/gems/her/spec/support/macros/her_macros.rb +0 -17
  62. data/vendor/gems/her/spec/support/macros/model_macros.rb +0 -36
  63. data/vendor/gems/her/spec/support/macros/request_macros.rb +0 -27
  64. data/vendor/gems/publicsuffix-ruby/CHANGELOG.md +0 -236
  65. data/vendor/gems/publicsuffix-ruby/Gemfile +0 -3
  66. data/vendor/gems/publicsuffix-ruby/LICENSE.txt +0 -22
  67. data/vendor/gems/publicsuffix-ruby/README.md +0 -151
  68. data/vendor/gems/publicsuffix-ruby/Rakefile +0 -109
  69. data/vendor/gems/publicsuffix-ruby/lib/definitions.txt +0 -11467
  70. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/domain.rb +0 -387
  71. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/errors.rb +0 -53
  72. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/list.rb +0 -302
  73. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/rule.rb +0 -373
  74. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/version.rb +0 -23
  75. data/vendor/gems/publicsuffix-ruby/lib/public_suffix.rb +0 -131
  76. data/vendor/gems/publicsuffix-ruby/public_suffix.gemspec +0 -39
  77. data/vendor/gems/publicsuffix-ruby/test/acceptance_test.rb +0 -42
  78. data/vendor/gems/publicsuffix-ruby/test/test_helper.rb +0 -6
  79. data/vendor/gems/publicsuffix-ruby/test/unit/domain_test.rb +0 -170
  80. data/vendor/gems/publicsuffix-ruby/test/unit/errors_test.rb +0 -23
  81. data/vendor/gems/publicsuffix-ruby/test/unit/list_test.rb +0 -179
  82. data/vendor/gems/publicsuffix-ruby/test/unit/public_suffix_test.rb +0 -115
  83. data/vendor/gems/publicsuffix-ruby/test/unit/rule_test.rb +0 -307
  84. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/capybara_configuration.rb +0 -98
  85. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/matchers.rb +0 -151
  86. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rspec_configuration.rb +0 -34
  87. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/html_safe.rb +0 -15
  88. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/raw.rb +0 -15
  89. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/safe_concat.rb +0 -15
  90. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop.rb +0 -3
  91. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/shared_examples/betterment_application_examples.rb +0 -43
  92. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/shared_examples.rb +0 -1
  93. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/site_prism_configuration.rb +0 -42
  94. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/site_prism_dropdown.rb +0 -17
  95. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/version.rb +0 -3
  96. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/webmock_configuration.rb +0 -8
  97. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers.rb +0 -2
  98. data/vendor/gems/ruby_spec_helpers/ruby_spec_helpers.gemspec +0 -25
@@ -1,791 +0,0 @@
1
- # encoding: utf-8
2
- require File.join(File.dirname(__FILE__), "../spec_helper.rb")
3
-
4
- describe Her::Model::ORM do
5
- context "mapping data to Ruby objects" do
6
- before do
7
- api = Her::API.new
8
- api.setup :url => "https://api.example.com" do |builder|
9
- builder.use Her::Middleware::FirstLevelParseJSON
10
- builder.use Faraday::Request::UrlEncoded
11
- builder.adapter :test do |stub|
12
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :name => "Tobias Fünke" }.to_json] }
13
- stub.get("/users") { |env| [200, {}, [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }].to_json] }
14
- stub.get("/admin_users") { |env| [200, {}, [{ :admin_id => 1, :name => "Tobias Fünke" }, { :admin_id => 2, :name => "Lindsay Fünke" }].to_json] }
15
- stub.get("/admin_users/1") { |env| [200, {}, { :admin_id => 1, :name => "Tobias Fünke" }.to_json] }
16
- end
17
- end
18
-
19
- spawn_model "Foo::User" do
20
- uses_api api
21
- end
22
-
23
- spawn_model "Foo::AdminUser" do
24
- uses_api api
25
- primary_key :admin_id
26
- end
27
- end
28
-
29
- it "maps a single resource to a Ruby object" do
30
- @user = Foo::User.find(1)
31
- @user.id.should == 1
32
- @user.name.should == "Tobias Fünke"
33
-
34
- @admin = Foo::AdminUser.find(1)
35
- @admin.id.should == 1
36
- @admin.name.should == "Tobias Fünke"
37
- end
38
-
39
- it "maps a collection of resources to an array of Ruby objects" do
40
- @users = Foo::User.all
41
- @users.length.should == 2
42
- @users.first.name.should == "Tobias Fünke"
43
-
44
- @users = Foo::AdminUser.all
45
- @users.length.should == 2
46
- @users.first.name.should == "Tobias Fünke"
47
- end
48
-
49
- it "handles new resource" do
50
- @new_user = Foo::User.new(:fullname => "Tobias Fünke")
51
- @new_user.new?.should be_truthy
52
- @new_user.new_record?.should be_truthy
53
- @new_user.fullname.should == "Tobias Fünke"
54
-
55
- @existing_user = Foo::User.find(1)
56
- @existing_user.new?.should be_falsey
57
- @existing_user.new_record?.should be_falsey
58
- end
59
-
60
- it 'handles new resource with custom primary key' do
61
- @new_user = Foo::AdminUser.new(:fullname => 'Lindsay Fünke', :id => -1)
62
- @new_user.should be_new
63
-
64
- @existing_user = Foo::AdminUser.find(1)
65
- @existing_user.should_not be_new
66
- end
67
- end
68
-
69
- context "mapping data, metadata and error data to Ruby objects" do
70
- before do
71
- api = Her::API.new
72
- api.setup :url => "https://api.example.com" do |builder|
73
- builder.use Her::Middleware::SecondLevelParseJSON
74
- builder.use Faraday::Request::UrlEncoded
75
- builder.adapter :test do |stub|
76
- stub.get("/users") { |env| [200, {}, { :data => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }], :metadata => { :total_pages => 10, :next_page => 2 }, :errors => ["Oh", "My", "God"] }.to_json] }
77
- stub.post("/users") { |env| [200, {}, { :data => { :name => "George Michael Bluth" }, :metadata => { :foo => "bar" }, :errors => ["Yes", "Sir"] }.to_json] }
78
- end
79
- end
80
-
81
- spawn_model :User do
82
- uses_api api
83
- end
84
- end
85
-
86
- it "handles metadata on a collection" do
87
- @users = User.all
88
- @users.metadata[:total_pages].should == 10
89
- end
90
-
91
- it "handles error data on a collection" do
92
- @users = User.all
93
- @users.errors.length.should == 3
94
- end
95
-
96
- it "handles metadata on a resource" do
97
- @user = User.create(:name => "George Michael Bluth")
98
- @user.metadata[:foo].should == "bar"
99
- end
100
-
101
- it "handles error data on a resource" do
102
- @user = User.create(:name => "George Michael Bluth")
103
- @user.response_errors.should == ["Yes", "Sir"]
104
- end
105
- end
106
-
107
- context "mapping data, metadata and error data in string keys to Ruby objects" do
108
- before do
109
- api = Her::API.new
110
- api.setup :url => "https://api.example.com" do |builder|
111
- builder.use Her::Middleware::SecondLevelParseJSON
112
- builder.use Faraday::Request::UrlEncoded
113
- builder.adapter :test do |stub|
114
- stub.get("/users") { |env| [200, {}, { 'data' => [{ :id => 1, :name => "Tobias Fünke" }, { :id => 2, :name => "Lindsay Fünke" }], 'metadata' => { :total_pages => 10, :next_page => 2 }, 'errors' => ["Oh", "My", "God"] }.to_json] }
115
- stub.post("/users") { |env| [200, {}, { 'data' => { :name => "George Michael Bluth" }, 'metadata' => { :foo => "bar" }, 'errors' => ["Yes", "Sir"] }.to_json] }
116
- end
117
- end
118
-
119
- spawn_model :User do
120
- uses_api api
121
- end
122
- end
123
-
124
- it "handles metadata on a collection" do
125
- @users = User.all
126
- @users.metadata[:total_pages].should == 10
127
- end
128
-
129
- it "handles error data on a collection" do
130
- @users = User.all
131
- @users.errors.length.should == 3
132
- end
133
-
134
- it "handles metadata on a resource" do
135
- @user = User.create(:name => "George Michael Bluth")
136
- @user.metadata[:foo].should == "bar"
137
- end
138
-
139
- it "handles error data on a resource" do
140
- @user = User.create(:name => "George Michael Bluth")
141
- @user.response_errors.should == ["Yes", "Sir"]
142
- end
143
- end
144
-
145
- context "defining custom getters and setters" do
146
- before do
147
- api = Her::API.new
148
- api.setup :url => "https://api.example.com" do |builder|
149
- builder.use Her::Middleware::FirstLevelParseJSON
150
- builder.use Faraday::Request::UrlEncoded
151
- builder.adapter :test do |stub|
152
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :friends => ["Maeby", "GOB", "Anne"] }.to_json] }
153
- stub.get("/users/2") { |env| [200, {}, { :id => 1 }.to_json] }
154
- end
155
- end
156
-
157
- spawn_model :User do
158
- uses_api api
159
- belongs_to :organization
160
-
161
- def friends=(val)
162
- val = val.gsub("\r", "").split("\n").map { |friend| friend.gsub(/^\s*\*\s*/, "") } if val and val.is_a?(String)
163
- @attributes[:friends] = val
164
- end
165
-
166
- def friends
167
- @attributes[:friends].map { |friend| "* #{friend}" }.join("\n")
168
- end
169
- end
170
- end
171
-
172
- it "handles custom setters" do
173
- @user = User.find(1)
174
- @user.friends.should == "* Maeby\n* GOB\n* Anne"
175
- @user.instance_eval do
176
- @attributes[:friends] = ["Maeby", "GOB", "Anne"]
177
- end
178
- end
179
-
180
- it "handles custom getters" do
181
- @user = User.new
182
- @user.friends = "* George\n* Oscar\n* Lucille"
183
- @user.friends.should == "* George\n* Oscar\n* Lucille"
184
- @user.instance_eval do
185
- @attributes[:friends] = ["George", "Oscar", "Lucille"]
186
- end
187
- end
188
- end
189
-
190
- context "finding resources" do
191
- before do
192
- api = Her::API.new
193
- api.setup :url => "https://api.example.com" do |builder|
194
- builder.use Her::Middleware::FirstLevelParseJSON
195
- builder.use Faraday::Request::UrlEncoded
196
- builder.adapter :test do |stub|
197
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :age => 42 }.to_json] }
198
- stub.get("/users/2") { |env| [200, {}, { :id => 2, :age => 34 }.to_json] }
199
- stub.get("/users/3") { |env| [404, {}, nil] }
200
- stub.get("/users?id[]=1&id[]=2") { |env| [200, {}, [{ :id => 1, :age => 42 }, { :id => 2, :age => 34 }].to_json] }
201
- stub.get("/users?age=42&foo=bar") { |env| [200, {}, [{ :id => 3, :age => 42 }].to_json] }
202
- stub.get("/users?bad_request=true") { |env| [400, {}, { errors: ["bad request params"] }.to_json] }
203
- stub.get("/users?age=42") { |env| [200, {}, [{ :id => 1, :age => 42 }].to_json] }
204
- stub.get("/users?age=40") { |env| [200, {}, [{ :id => 1, :age => 40 }].to_json] }
205
- end
206
- end
207
-
208
- spawn_model :User do
209
- uses_api api
210
- end
211
- end
212
-
213
- it "handles finding by a single id" do
214
- @user = User.find(1)
215
- @user.id.should == 1
216
- end
217
-
218
- it "handles finding by multiple ids" do
219
- @users = User.find(1, 2)
220
- @users.should be_kind_of(Array)
221
- @users.length.should == 2
222
- @users[0].id.should == 1
223
- @users[1].id.should == 2
224
- end
225
-
226
- it "handles finding by an array of ids" do
227
- @users = User.find([1, 2])
228
- @users.should be_kind_of(Array)
229
- @users.length.should == 2
230
- @users[0].id.should == 1
231
- @users[1].id.should == 2
232
- end
233
-
234
- it "handles finding by an array of ids of length 1" do
235
- @users = User.find([1])
236
- @users.should be_kind_of(Array)
237
- @users.length.should == 1
238
- @users[0].id.should == 1
239
- end
240
-
241
- it "handles finding by an array id param of length 2" do
242
- @users = User.find(id: [1, 2])
243
- @users.should be_kind_of(Array)
244
- @users.length.should == 2
245
- @users[0].id.should == 1
246
- @users[1].id.should == 2
247
- end
248
-
249
- it 'handles finding with id parameter as an array' do
250
- @users = User.where(id: [1, 2])
251
- @users.should be_kind_of(Array)
252
- @users.length.should == 2
253
- @users[0].id.should == 1
254
- @users[1].id.should == 2
255
- end
256
-
257
- it "handles finding with other parameters" do
258
- @users = User.where(:age => 42, :foo => "bar").all
259
- @users.should be_kind_of(Array)
260
- @users.first.id.should == 3
261
- end
262
-
263
- it "handles finding with other parameters and scoped" do
264
- @users = User.scoped
265
- @users.where(:age => 42).should be_all { |u| u.age == 42 }
266
- @users.where(:age => 40).should be_all { |u| u.age == 40 }
267
- end
268
-
269
- it "throws when a given resource does not exist" do
270
- expect { User.find(3) }.to raise_error(Her::Errors::RecordNotFound, /User returned a 404/)
271
- end
272
-
273
- it "throws when accessing collection of a resource that does not exist" do
274
- @users = User.where(bad_request: true).all
275
- expect { @users.first }.to raise_error(Her::Errors::ResponseError, "Cannot access collection, Request returned an error")
276
- end
277
- end
278
-
279
- describe :find_by do
280
- before do
281
- api = Her::API.new
282
- api.setup :url => "https://api.example.com" do |builder|
283
- builder.use Her::Middleware::FirstLevelParseJSON
284
- builder.use Faraday::Request::UrlEncoded
285
- builder.adapter :test do |stub|
286
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :age => 42 }.to_json] }
287
- end
288
- end
289
-
290
- spawn_model :User do
291
- uses_api api
292
- end
293
- end
294
-
295
- it "supports the same basic behavior of find with an id" do
296
- expect(User.find_by(id: 1).id).to eq 1
297
- end
298
- end
299
-
300
- describe :first do
301
- before do
302
- api = Her::API.new
303
- api.setup :url => "https://api.example.com" do |builder|
304
- builder.use Her::Middleware::FirstLevelParseJSON
305
- builder.use Faraday::Request::UrlEncoded
306
- builder.adapter :test do |stub|
307
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :age => 42 }.to_json] }
308
- stub.get("/users/2") { |env| [404, {}, nil] }
309
- stub.get("/users/3") { |env| [410, {}, nil] }
310
- stub.get("/users/8") { |env| [401, {}, nil] }
311
- stub.get("/users/4?age=42&foo=bar") { |env| [200, {}, { :id => 4, :age => 42 }.to_json] }
312
- stub.get("/users?age=50&color=blue") { |env| [200, {}, [{ :id => 5, :age => 50, :color => 'blue' }].to_json] }
313
- stub.get("/users?id[]=6&id[]=7") { |env| [200, {}, [{ :id => 6 }].to_json] }
314
- end
315
- end
316
-
317
- spawn_model :User do
318
- uses_api api
319
- end
320
- end
321
-
322
- it "supports the same basic behavior of find with an id" do
323
- expect(User.where(id: 1).first.id).to eq 1
324
- end
325
-
326
- it "returns nil when a given resource returns 404" do
327
- expect(User.where(id: 2).first).to be_nil
328
- end
329
-
330
- it "returns nil when a given resource returns 410" do
331
- expect(User.where(id: 3).first).to be_nil
332
- end
333
-
334
- it "raises on any other 4xx" do
335
- expect { User.where(id: 8).first }.to raise_error(Her::Errors::ResponseError, /returned a 401/)
336
- end
337
-
338
- it "handles finding with an id AND other parameters" do
339
- expect(User.where(:id => 4, :age => 42, :foo => "bar").first.id).to eq 4
340
- end
341
-
342
- it "handles finding with other parameters" do
343
- expect(User.where(:age => 50, :color => "blue").first.id).to eq 5
344
- end
345
-
346
- it "accepts multiple id values" do
347
- expect(User.where(id: [6, 7]).first.id).to eq 6
348
- end
349
- end
350
-
351
- context "building resources" do
352
- context "when request_new_object_on_build is not set (default)" do
353
- before do
354
- spawn_model("Foo::User")
355
- end
356
-
357
- it "builds a new resource without requesting it" do
358
- Foo::User.should_not_receive(:request)
359
- @new_user = Foo::User.build(:fullname => "Tobias Fünke")
360
- @new_user.new?.should be_truthy
361
- @new_user.fullname.should == "Tobias Fünke"
362
- end
363
- end
364
-
365
- context "when request_new_object_on_build is set" do
366
- before do
367
- Her::API.setup :url => "https://api.example.com" do |builder|
368
- builder.use Her::Middleware::FirstLevelParseJSON
369
- builder.use Faraday::Request::UrlEncoded
370
- builder.adapter :test do |stub|
371
- stub.get("/users/new") { |env| ok! :id => nil, :fullname => params(env)[:fullname], :email => "tobias@bluthcompany.com" }
372
- end
373
- end
374
-
375
- spawn_model("Foo::User") { request_new_object_on_build true }
376
- end
377
-
378
- it "requests a new resource" do
379
- Foo::User.should_receive(:request).once.and_call_original
380
- @new_user = Foo::User.build(:fullname => "Tobias Fünke")
381
- @new_user.new?.should be_truthy
382
- @new_user.fullname.should == "Tobias Fünke"
383
- @new_user.email.should == "tobias@bluthcompany.com"
384
- end
385
- end
386
- end
387
-
388
- context "creating resources" do
389
- before do
390
- Her::API.setup :url => "https://api.example.com" do |builder|
391
- builder.use Her::Middleware::FirstLevelParseJSON
392
- builder.use Faraday::Request::UrlEncoded
393
- builder.adapter :test do |stub|
394
- stub.post("/users") { |env| [200, {}, { :id => 1, :fullname => Faraday::Utils.parse_query(env[:body])['fullname'], :email => Faraday::Utils.parse_query(env[:body])['email'] }.to_json] }
395
- stub.post("/companies") { |env| [422, {}, { :errors => { :name => ["is required", "must be alphabetical"], :birthday => ['is required'] } }.to_json] }
396
- end
397
- end
398
-
399
- spawn_model "Foo::User"
400
- spawn_model "Foo::Company"
401
- end
402
-
403
- it "handle one-line resource creation" do
404
- @user = Foo::User.create(:fullname => "Tobias Fünke", :email => "tobias@bluth.com")
405
- @user.id.should == 1
406
- @user.fullname.should == "Tobias Fünke"
407
- @user.email.should == "tobias@bluth.com"
408
- end
409
-
410
- it "handle resource creation through Model.new + #save" do
411
- @user = Foo::User.new(:fullname => "Tobias Fünke")
412
- @user.save.should be true
413
- @user.fullname.should == "Tobias Fünke"
414
- end
415
-
416
- it "handle resource creation through Model.new + #save!" do
417
- @user = Foo::User.new(:fullname => "Tobias Fünke")
418
- @user.save!.should be true
419
- @user.fullname.should == "Tobias Fünke"
420
- end
421
-
422
- it "returns false when #save gets errors" do
423
- @company = Foo::Company.new
424
- @company.save.should be false
425
- end
426
-
427
- it "raises RecordInvalid when #save! gets errors" do
428
- @company = Foo::Company.new
429
- expect { @company.save! }.to raise_error Her::Errors::RecordInvalid, "Remote validation of Foo::Company failed with a 422: name is required, must be alphabetical. birthday is required"
430
- end
431
-
432
- it "contains 1 copy of any error message when the server responds with validation errors" do
433
- @company = Foo::Company.new
434
- @company.save
435
- @company.save
436
- expect(@company.errors.messages).to include :name => ['is required', 'must be alphabetical']
437
- end
438
-
439
- it "don't overwrite data if response is empty" do
440
- @company = Foo::Company.new(:name => 'Company Inc.')
441
- @company.save.should be false
442
- @company.name.should == "Company Inc."
443
- end
444
- end
445
-
446
- context "updating resources" do
447
- before do
448
- Her::API.setup :url => "https://api.example.com" do |builder|
449
- builder.use Her::Middleware::FirstLevelParseJSON
450
- builder.use Faraday::Request::UrlEncoded
451
- builder.adapter :test do |stub|
452
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke" }.to_json] }
453
- stub.put("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke" }.to_json] }
454
- end
455
- end
456
-
457
- spawn_model "Foo::User"
458
- end
459
-
460
- it "handle resource data update without saving it" do
461
- @user = Foo::User.find(1)
462
- @user.fullname.should == "Tobias Fünke"
463
- @user.fullname = "Kittie Sanchez"
464
- @user.fullname.should == "Kittie Sanchez"
465
- end
466
-
467
- it "handle resource update through the .update class method" do
468
- @user = Foo::User.save_existing(1, { :fullname => "Lindsay Fünke" })
469
- @user.fullname.should == "Lindsay Fünke"
470
- end
471
-
472
- it "handle resource update through #save on an existing resource" do
473
- @user = Foo::User.find(1)
474
- @user.fullname = "Lindsay Fünke"
475
- @user.save
476
- @user.fullname.should == "Lindsay Fünke"
477
- end
478
- end
479
-
480
- context "deleting resources" do
481
- describe "successful deletion requests" do
482
- before do
483
- Her::API.setup :url => "https://api.example.com" do |builder|
484
- builder.use Her::Middleware::FirstLevelParseJSON
485
- builder.use Faraday::Request::UrlEncoded
486
- builder.adapter :test do |stub|
487
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json] }
488
- stub.delete("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Lindsay Fünke", :active => false }.to_json] }
489
- end
490
- end
491
-
492
- spawn_model "Foo::User"
493
- end
494
-
495
- it "handle resource deletion through the .destroy class method" do
496
- @user = Foo::User.destroy_existing(1)
497
- @user.active.should be_falsey
498
- @user.should be_destroyed
499
- end
500
-
501
- it "handle resource deletion through #destroy on an existing resource" do
502
- @user = Foo::User.find(1)
503
- @user.destroy
504
- @user.active.should be_falsey
505
- @user.should be_destroyed
506
- end
507
- end
508
-
509
- describe "failed deletion requests (400-space responses)" do
510
- before do
511
- Her::API.setup :url => "https://api.example.com" do |builder|
512
- builder.use Her::Middleware::FirstLevelParseJSON
513
- builder.use Faraday::Request::UrlEncoded
514
- builder.adapter :test do |stub|
515
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json] }
516
- stub.get("/users/2") { |env| [200, {}, { :id => 2, :fullname => "Tobias Fünke", :active => true }.to_json] }
517
- stub.get("/users/3") { |env| [200, {}, { :id => 3, :fullname => "Tobias Fünke", :active => true }.to_json] }
518
- stub.delete("/users/1") { |env| [404, {}, { :id => 1, :fullname => "Lindsay Fünke", :active => false }.to_json] }
519
- stub.delete("/users/2") { |env| [411, {}, { :id => 2, :fullname => "Lindsay Fünke", :active => false }.to_json] }
520
- stub.delete("/users/3") { |env| [422, {}, { :id => 3, :fullname => "Lindsay Fünke", :active => false }.to_json] }
521
- end
522
- end
523
-
524
- spawn_model "Foo::User"
525
- end
526
-
527
- it "throws RecordNotFound exceptions for .destroy class method when a 404 is returned" do
528
- expect { Foo::User.destroy_existing(1) }.to raise_error(Her::Errors::RecordNotFound, /Foo::User returned a 404/)
529
- end
530
-
531
- it "throws RecordInvalid exceptions for .destroy class method when a 409 is returned" do
532
- expect { Foo::User.destroy_existing(2) }.to raise_error(Her::Errors::ResponseError, /Foo::User returned a 411/)
533
- end
534
-
535
- it "throws RecordInvalid exceptions for .destroy class method when a 422 is returned" do
536
- expect { Foo::User.destroy_existing(3) }.to raise_error(Her::Errors::RecordInvalid, /Foo::User returned a 422/)
537
- end
538
-
539
- it "throws RecordNotFound exceptions for #destroy on an existing resource when a 404 is returned" do
540
- @user = Foo::User.find(1)
541
- expect { @user.destroy }.to raise_error(Her::Errors::RecordNotFound, /Foo::User returned a 404/)
542
- end
543
-
544
- it "throws RecordInvalid exceptions for #destroy on an existing resource when a 409 is returned" do
545
- @user = Foo::User.find(2)
546
- expect { @user.destroy }.to raise_error(Her::Errors::ResponseError, /Foo::User returned a 411/)
547
- end
548
-
549
- it "throws RecordInvalid exceptions for #destroy on an existing resource when a 422 is returned" do
550
- @user = Foo::User.find(3)
551
- expect { @user.destroy }.to raise_error(Her::Errors::RecordInvalid, /Foo::User returned a 422/)
552
- end
553
- end
554
-
555
- describe "failed deletion requests (500-space responses)" do
556
- before do
557
- Her::API.setup :url => "https://api.example.com" do |builder|
558
- builder.use Her::Middleware::FirstLevelParseJSON
559
- builder.use Faraday::Request::UrlEncoded
560
- builder.adapter :test do |stub|
561
- stub.get("/users/1") { |env| [200, {}, { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json] }
562
- stub.delete("/users/1") { |env| [500, {}, { :id => 1, :fullname => "Lindsay Fünke", :active => false }.to_json] }
563
- end
564
- end
565
-
566
- spawn_model "Foo::User"
567
- end
568
-
569
- it "handles resource deletion through the .destroy class method" do
570
- expect { Foo::User.destroy_existing(1) }.to raise_error(Her::Errors::RemoteServerError, /Foo::User returned a 500/)
571
- end
572
-
573
- it "handles resource deletion through #destroy on an existing resource" do
574
- @user = Foo::User.find(1)
575
- expect { @user.destroy }.to raise_error(Her::Errors::RemoteServerError, /Foo::User returned a 500/)
576
- end
577
- end
578
- end
579
-
580
- describe '.with_request_headers, #request_headers and #request_options' do
581
- before do
582
- @headers = {}
583
- Her::API.setup :url => "https://api.example.com" do |builder|
584
- builder.use Her::Middleware::FirstLevelParseJSON
585
- builder.use Faraday::Request::UrlEncoded
586
- builder.options[:timeout] = 100
587
- builder.adapter :test do |stub|
588
- stub.get("/users/1") { |env|
589
- @headers = env[:request_headers]
590
- @timeout = env[:request][:timeout]
591
- [200, {}, { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json]
592
- }
593
- stub.get("/users?active=true") { |env|
594
- @headers = env[:request_headers]
595
- @timeout = env[:request][:timeout]
596
- [200, {}, [{ :id => 1, :fullname => "Tobias Fünke", :active => true }].to_json]
597
- }
598
- stub.get("/users") { |env|
599
- @headers = env[:request_headers]
600
- @timeout = env[:request][:timeout]
601
- [200, {}, [{ :id => 1, :fullname => "Tobias Fünke", :active => true }].to_json]
602
- }
603
- stub.put("/users/1") { |env|
604
- @headers = env[:request_headers]
605
- @timeout = env[:request][:timeout]
606
- [200, {}, { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json]
607
- }
608
- stub.post("/users") { |env|
609
- @headers = env[:request_headers]
610
- @timeout = env[:request][:timeout]
611
- [200, {}, { :id => 1, :fullname => "Tobias Fünke", :active => true }.to_json]
612
- }
613
- stub.delete("/users/1") { |env|
614
- @headers = env[:request_headers]
615
- @timeout = env[:request][:timeout]
616
- [200, {}, nil]
617
- }
618
- end
619
- end
620
-
621
- spawn_model "Foo::User"
622
- end
623
-
624
- it "includes headers added via a relation chain" do
625
- user = Foo::User.where(active: true).with_request_headers("Authorization" => "Basic FooBar").all.first
626
- expect(@headers).to include "Authorization" => "Basic FooBar"
627
- end
628
-
629
- it "sets timeout added via a relation chain" do
630
- user = Foo::User.where(active: true).with_request_options(timeout: 1).all.first
631
- expect(@timeout).to eq 1
632
- end
633
-
634
- it "includes headers added via start of a relation chain" do
635
- user = Foo::User.with_request_headers("Authorization" => "Basic FooBar").find(1)
636
- expect(@headers).to include "Authorization" => "Basic FooBar"
637
- end
638
-
639
- it "sets timeout added via start of a relation chain" do
640
- user = Foo::User.with_request_options(timeout: 2).find(1)
641
- expect(@timeout).to eq 2
642
- end
643
-
644
- it "includes headers added via start of a relation chain when creating" do
645
- user = Foo::User.with_request_headers("Authorization" => "Basic FooBar").create
646
- expect(@headers).to include "Authorization" => "Basic FooBar"
647
- end
648
-
649
- it "includes timeout added via start of a relation chain when creating" do
650
- user = Foo::User.with_request_options(timeout: 3).create
651
- expect(@timeout).to eq 3
652
- end
653
-
654
- it "includes headers added to an instance when saving" do
655
- user = Foo::User.find(1)
656
- user.request_headers = { "Authorization" => "Basic FooBar" }
657
- user.save
658
- expect(@headers).to include "Authorization" => "Basic FooBar"
659
- end
660
-
661
- it "includes headers added to an instance when destroying" do
662
- user = Foo::User.find(1)
663
- user.request_headers = { "Authorization" => "Basic FooBar" }
664
- user.destroy
665
- expect(@headers).to include "Authorization" => "Basic FooBar"
666
- end
667
-
668
- it "includes headers added when destroying existing" do
669
- Foo::User.destroy_existing(1, {}, { "Authorization" => "Basic FooBar" })
670
- expect(@headers).to include "Authorization" => "Basic FooBar"
671
- end
672
-
673
- it "includes timeout added when destroying existing" do
674
- Foo::User.destroy_existing(1, {}, {}, timeout: 4)
675
- expect(@timeout).to eq 4
676
- end
677
-
678
- it "includes headers added via start of a relation chain when saving existing" do
679
- user = Foo::User.save_existing(1, {}, { "Authorization" => "Basic FooBar" })
680
- expect(@headers).to include "Authorization" => "Basic FooBar"
681
- end
682
-
683
- it "includes timeout added via start of a relation chain when saving existing" do
684
- user = Foo::User.save_existing(1, {}, {}, timeout: 5)
685
- expect(@timeout).to eq 5
686
- end
687
-
688
-
689
- it "overrides the timeout when added to an existing model's request_options" do
690
- user = Foo::User.find(1)
691
- user.request_options = { timeout: 6 }
692
- user.save
693
-
694
- expect(@timeout).to eq 6
695
- end
696
-
697
- it "overrides the timeout when added to a new model's request_options" do
698
- user = Foo::User.new
699
- user.request_options = { timeout: 7 }
700
- user.save
701
-
702
- expect(@timeout).to eq 7
703
- end
704
-
705
- it "overrides the timeout when added to destroying a model with request_options" do
706
- user = Foo::User.find(1)
707
- user.request_options = { timeout: 8 }
708
- user.destroy
709
-
710
- expect(@timeout).to eq 8
711
- end
712
-
713
- it "does not remove timeout set up by the api" do
714
- user = Foo::User.find(1)
715
- user.destroy
716
-
717
- expect(@timeout).to eq 100
718
- end
719
-
720
- it "raises an exception when setting unimplemented options" do
721
- user = Foo::User.find(1)
722
- user.request_options = { not_implemented: 123, 500 => 'crazy' }
723
-
724
- expect { user.save }.to raise_error "options not implemented: not_implemented, 500"
725
- end
726
- end
727
-
728
- context 'customizing HTTP methods' do
729
- before do
730
- Her::API.setup :url => "https://api.example.com" do |builder|
731
- builder.use Her::Middleware::FirstLevelParseJSON
732
- builder.use Faraday::Request::UrlEncoded
733
- end
734
- end
735
-
736
- context 'create' do
737
- before do
738
- Her::API.default_api.connection.adapter :test do |stub|
739
- stub.put('/users') { |env| [200, {}, { :id => 1, :fullname => 'Tobias Fünke' }.to_json] }
740
- end
741
- spawn_model 'Foo::User' do
742
- attributes :fullname, :email
743
- method_for :create, 'PUT'
744
- end
745
- end
746
-
747
- context 'for top-level class' do
748
- it 'uses the custom method (PUT) instead of default method (POST)' do
749
- user = Foo::User.new(:fullname => 'Tobias Fünke')
750
- user.should be_new
751
- user.save.should be true
752
- end
753
- end
754
-
755
- context 'for children class' do
756
- before do
757
- class User < Foo::User; end
758
- @spawned_models << :User
759
- end
760
-
761
- it 'uses the custom method (PUT) instead of default method (POST)' do
762
- user = User.new(:fullname => 'Tobias Fünke')
763
- user.should be_new
764
- user.save.should be true
765
- end
766
- end
767
- end
768
-
769
- context 'update' do
770
- before do
771
- Her::API.default_api.connection.adapter :test do |stub|
772
- stub.get('/users/1') { |env| [200, {}, { :id => 1, :fullname => 'Lindsay Fünke' }.to_json] }
773
- stub.post('/users/1') { |env| [200, {}, { :id => 1, :fullname => 'Tobias Fünke' }.to_json] }
774
- end
775
-
776
- spawn_model 'Foo::User' do
777
- attributes :fullname, :email
778
- method_for :update, :post
779
- end
780
- end
781
-
782
- it 'uses the custom method (POST) instead of default method (PUT)' do
783
- user = Foo::User.find(1)
784
- user.fullname.should eq 'Lindsay Fünke'
785
- user.fullname = 'Toby Fünke'
786
- user.save
787
- user.fullname.should eq 'Tobias Fünke'
788
- end
789
- end
790
- end
791
- end