spark_api 1.2.1 → 1.3.0

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.
Files changed (70) hide show
  1. data/History.txt +12 -0
  2. data/README.md +7 -0
  3. data/Rakefile +1 -0
  4. data/VERSION +1 -1
  5. data/lib/spark_api/authentication.rb +0 -3
  6. data/lib/spark_api/authentication/oauth2.rb +1 -1
  7. data/lib/spark_api/configuration.rb +6 -1
  8. data/lib/spark_api/models.rb +6 -2
  9. data/lib/spark_api/models/activity.rb +10 -0
  10. data/lib/spark_api/models/base.rb +25 -5
  11. data/lib/spark_api/models/comment.rb +9 -0
  12. data/lib/spark_api/models/concerns/destroyable.rb +1 -1
  13. data/lib/spark_api/models/concerns/savable.rb +3 -6
  14. data/lib/spark_api/models/contact.rb +38 -1
  15. data/lib/spark_api/models/dirty.rb +1 -1
  16. data/lib/spark_api/models/fields.rb +12 -0
  17. data/lib/spark_api/models/listing_cart.rb +6 -34
  18. data/lib/spark_api/models/portal.rb +37 -0
  19. data/lib/spark_api/models/saved_search.rb +36 -0
  20. data/lib/spark_api/models/vow_account.rb +44 -0
  21. data/lib/spark_api/request.rb +1 -1
  22. data/spec/fixtures/activities/get.json +22 -0
  23. data/spec/fixtures/base.json +2 -2
  24. data/spec/fixtures/comments/get.json +32 -0
  25. data/spec/fixtures/comments/new.json +7 -0
  26. data/spec/fixtures/comments/post.json +19 -0
  27. data/spec/fixtures/contacts/my.json +1 -0
  28. data/spec/fixtures/contacts/vow_accounts/edit.json +5 -0
  29. data/spec/fixtures/contacts/vow_accounts/get.json +15 -0
  30. data/spec/fixtures/contacts/vow_accounts/new.json +12 -0
  31. data/spec/fixtures/contacts/vow_accounts/post.json +10 -0
  32. data/spec/fixtures/fields/order.json +22 -0
  33. data/spec/fixtures/fields/order_a.json +39 -0
  34. data/spec/fixtures/portal/disable.json +5 -0
  35. data/spec/fixtures/portal/enable.json +5 -0
  36. data/spec/fixtures/portal/my.json +15 -0
  37. data/spec/fixtures/portal/my_non_existant.json +6 -0
  38. data/spec/fixtures/portal/new.json +7 -0
  39. data/spec/fixtures/portal/post.json +10 -0
  40. data/spec/fixtures/saved_searches/get.json +4 -1
  41. data/spec/spec_helper.rb +11 -7
  42. data/spec/unit/spark_api/authentication/oauth2_impl/faraday_middleware_spec.rb +2 -2
  43. data/spec/unit/spark_api/authentication/oauth2_impl/grant_type_base_spec.rb +1 -2
  44. data/spec/unit/spark_api/authentication/oauth2_spec.rb +3 -4
  45. data/spec/unit/spark_api/models/activity_spec.rb +29 -0
  46. data/spec/unit/spark_api/models/base_spec.rb +23 -0
  47. data/spec/unit/spark_api/models/concerns/destroyable_spec.rb +1 -1
  48. data/spec/unit/spark_api/models/concerns/savable_spec.rb +8 -4
  49. data/spec/unit/spark_api/models/contact_spec.rb +144 -21
  50. data/spec/unit/spark_api/models/fields_spec.rb +56 -0
  51. data/spec/unit/spark_api/models/listing_cart_spec.rb +1 -1
  52. data/spec/unit/spark_api/models/portal_spec.rb +50 -0
  53. data/spec/unit/spark_api/models/saved_search_spec.rb +60 -0
  54. data/spec/unit/spark_api/models/shared_listing_spec.rb +1 -1
  55. data/spec/unit/spark_api/models/vow_account_spec.rb +64 -0
  56. data/spec/unit/spark_api/request_spec.rb +1 -1
  57. data/spec/unit/spark_api_spec.rb +1 -1
  58. metadata +362 -360
  59. data/lib/spark_api/models/subscription.rb +0 -52
  60. data/spec/fixtures/subscriptions/get.json +0 -19
  61. data/spec/fixtures/subscriptions/new.json +0 -13
  62. data/spec/fixtures/subscriptions/post.json +0 -10
  63. data/spec/fixtures/subscriptions/put.json +0 -12
  64. data/spec/fixtures/subscriptions/subscribe.json +0 -5
  65. data/spec/fixtures/subscriptions/update.json +0 -6
  66. data/spec/json_hash_test_support.rb +0 -251
  67. data/spec/json_helper.rb +0 -76
  68. data/spec/mock_helper.rb +0 -132
  69. data/spec/oauth2_helper.rb +0 -70
  70. data/spec/unit/spark_api/models/subscription_spec.rb +0 -106
@@ -10,18 +10,41 @@ class MyDefaultModel < Base
10
10
  end
11
11
 
12
12
  describe MyExampleModel, "Example model" do
13
+
13
14
  before(:each) do
14
15
  stub_auth_request
15
16
  stub_api_get("/test/example", 'base.json')
16
17
  @model = MyExampleModel.first
17
18
  end
19
+
18
20
  it "should be persisted" do
19
21
  @model.persisted?.should eq(true)
20
22
  end
23
+
21
24
  it "should not be persisted" do
22
25
  @new_model = MyExampleModel.new()
23
26
  @new_model.persisted?.should eq(false)
24
27
  end
28
+
29
+ it "should parse and return ResourceUri without v1" do
30
+ @model.resource_uri.should eq("/some/place/20101230223226074201000000")
31
+ end
32
+
33
+ it "should parse and return the correct path for a persisted resource" do
34
+ @model.path.should eq("/some/place")
35
+ end
36
+
37
+ it "should parse and return the correct path" do
38
+ @model = MyExampleModel.new
39
+ @model.path.should eq("/test/example")
40
+ end
41
+
42
+ it "should parse and return the correct path for resource with a parent" do
43
+ @model = MyExampleModel.new
44
+ @model.parent = Contact.new(Id: "20101230223226074201000000")
45
+ @model.path.should eq("/contacts/20101230223226074201000000/test/example")
46
+ end
47
+
25
48
  end
26
49
 
27
50
  describe Base, "Base model" do
@@ -19,7 +19,7 @@ describe Concerns::Destroyable, "Destroyable Concern" do
19
19
  end
20
20
 
21
21
  it "should be destroyable" do
22
- stub_api_delete("/test/example/1")
22
+ stub_api_delete("/some/place/20101230223226074201000000")
23
23
  @model = MyExampleModel.first
24
24
  @model.destroy
25
25
  @model.destroyed?.should eq(true)
@@ -30,32 +30,36 @@ describe Concerns::Savable, "Model" do
30
30
 
31
31
  it "should be creatable" do
32
32
  @model = MyExampleModel.new({ :Name => "my name" })
33
- stub_api_post("/test/example", { :MyExampleModels => [ @model.attributes ] }, "base.json")
33
+ s = stub_api_post("/test/example", { :MyExampleModels => [ @model.attributes ] }, "base.json")
34
34
  @model.save.should eq(true)
35
35
  @model.persisted?.should eq(true)
36
+ s.should have_been_requested
36
37
  end
37
38
 
38
39
  it "should be updatable" do
39
40
  stub_api_get("/test/example", 'base.json')
40
41
  @model = MyExampleModel.first
41
42
  @model.Name = "new name"
42
- stub_api_put("/test/example/1", @model.dirty_attributes)
43
+ s = stub_api_put("/some/place/20101230223226074201000000", @model.dirty_attributes)
43
44
  @model.save.should eq(true)
44
45
  @model.persisted?.should eq(true)
46
+ s.should have_been_requested
45
47
  end
46
48
 
47
49
  it "should allow the pluralize method to be overriden" do
48
50
  @model = MyOtherExampleModel.new({ :Name => "my name" })
49
- stub_api_post("/test/example", { :MyOtherExampleModelThatIsPluralized => [ @model.attributes ] }, "base.json")
51
+ s = stub_api_post("/test/example", { :MyOtherExampleModelThatIsPluralized => [ @model.attributes ] }, "base.json")
50
52
  @model.save.should eq(true)
51
53
  @model.persisted?.should eq(true)
54
+ s.should have_been_requested
52
55
  end
53
56
 
54
57
  it "should not pluralize the resource if it already is" do
55
58
  @model = MyPluralizedModels.new({ :Name => "my name" })
56
- stub_api_post("/test/example", { :MyPluralizedModels => [ @model.attributes ] }, "base.json")
59
+ s = stub_api_post("/test/example", { :MyPluralizedModels => [ @model.attributes ] }, "base.json")
57
60
  @model.save.should eq(true)
58
61
  @model.persisted?.should eq(true)
62
+ s.should have_been_requested
59
63
  end
60
64
 
61
65
  end
@@ -11,6 +11,7 @@ describe Contact do
11
11
  end
12
12
 
13
13
  context "/contacts", :support do
14
+
14
15
  on_get_it "should get all my contacts" do
15
16
  stub_api_get("/contacts", 'contacts/contacts.json')
16
17
  contacts = Contact.get
@@ -72,6 +73,149 @@ describe Contact do
72
73
  expect{ c.save }.to raise_error(SparkApi::ClientError){ |e| e.status.should == 500 }
73
74
  end
74
75
  end
76
+
77
+ context "/tags", :support do
78
+ on_get_it "should get all my Tags" do
79
+ stub_api_get("/contacts/tags", 'contacts/tags.json')
80
+ tags = Contact.tags
81
+ tags.should be_an(Array)
82
+ tags.length.should eq(4)
83
+ tags.first["Tag"].should eq("Current Buyers")
84
+ end
85
+ end
86
+
87
+ context "/tags/<tag_name>", :support do
88
+ on_get_it "should get all contacts with Tag <tag_name>" do
89
+ stub_api_get("/contacts/tags/IDX%20Lead", 'contacts/contacts.json')
90
+ contacts = Contact.by_tag("IDX Lead")
91
+ contacts.should be_an(Array)
92
+ contacts.length.should eq(3)
93
+ contacts.first.Id.should eq("20101230223226074201000000")
94
+ contacts.first.Tags[0].should eq("IDX Lead")
95
+ end
96
+ end
97
+
98
+ context "/export", :support do
99
+ on_get_it "should get all contacts belonging to the current user" do
100
+ stub_api_get("/contacts/export", 'contacts/contacts.json')
101
+ Contact.should respond_to(:export)
102
+ contacts = Contact.export
103
+ contacts.should be_an(Array)
104
+ contacts.length.should eq(3)
105
+ end
106
+ end
107
+
108
+ context "/export/all", :support do
109
+ on_get_it "should get all contacts belonging to the current user" do
110
+ stub_api_get("/contacts/export/all", 'contacts/contacts.json')
111
+ Contact.should respond_to(:export_all)
112
+ contacts = Contact.export_all
113
+ contacts.should be_an(Array)
114
+ contacts.length.should eq(3)
115
+ end
116
+ end
117
+
118
+ end
119
+
120
+ context "/contacts/<contact_id>" do
121
+
122
+ let(:contact_id) { "20090928182824338901000000" }
123
+
124
+ context "/savedsearches", :support do
125
+
126
+ subject(:contact) do
127
+ stub_api_get("/my/contact", 'contacts/my.json')
128
+ contact = Contact.my
129
+ end
130
+
131
+ on_get_it "should get all the saved searches belonging to the customer" do
132
+ stub_api_get("/contacts/#{contact.Id}/savedsearches", 'saved_searches/get.json')
133
+ saved_searches = contact.saved_searches
134
+ saved_searches.should be_an(Array)
135
+ saved_searches.length.should eq(2)
136
+ end
137
+
138
+ it "should pass any arguments as parameters" do
139
+ stub_api_get("/contacts/#{contact.Id}/savedsearches", 'saved_searches/get.json', :_pagination => 1)
140
+ saved_searches = contact.saved_searches(:_pagination => 1)
141
+ end
142
+
143
+ end
144
+
145
+ context "/listingcarts", :support do
146
+
147
+ subject(:contact) do
148
+ stub_api_get("/my/contact", 'contacts/my.json')
149
+ Contact.my
150
+ end
151
+
152
+ on_get_it "should get all the listing carts belonging to the customer" do
153
+ stub_api_get("/contacts/#{contact.Id}/listingcarts", 'listing_carts/listing_cart.json')
154
+ saved_searches = contact.listing_carts
155
+ saved_searches.should be_an(Array)
156
+ saved_searches.length.should eq(2)
157
+ end
158
+
159
+ it "should pass any arguments as parameters" do
160
+ stub_api_get("/contacts/#{contact.Id}/listingcarts", 'listing_carts/listing_cart.json', :test_argument => "yay")
161
+ saved_searches = contact.listing_carts(:test_argument => "yay")
162
+ end
163
+
164
+ end
165
+
166
+ context "/portal", :support do
167
+ on_get_it "should return account information for the current user/contact?" do
168
+ stub_api_get("/my/contact", 'contacts/my.json')
169
+ contact = Contact.my
170
+ stub_api_get("/contacts/#{contact.Id}/portal", 'contacts/vow_accounts/get.json')
171
+ vow_account = contact.vow_account
172
+ vow_account.persisted?.should be_true
173
+ end
174
+ end
175
+
176
+ context "/comments" do
177
+
178
+ it "should get all of a contact's comments" do
179
+ s = stub_api_get("/contacts/#{contact_id}/comments", "comments/get.json")
180
+ comments = Contact.new(:Id => contact_id).comments
181
+ comments.size.should eq(2)
182
+ s.should have_been_requested
183
+ end
184
+
185
+ it "should create a new contact comment" do
186
+ s = stub_api_post("/contacts/#{contact_id}/comments", "comments/new.json", "comments/post.json")
187
+ comment = Comment.new(:Comment => "This is a comment.")
188
+ comment.parent = Contact.new(:Id => contact_id)
189
+ comment.save.should be(true)
190
+ comment.Id.should eq("20121114100201798092000005")
191
+ s.should have_been_requested
192
+ end
193
+
194
+ it "should create a new contact comment using helper method" do
195
+ stub_api_get("/my/contact", 'contacts/my.json')
196
+ s = stub_api_post("/contacts/#{contact_id}/comments", "comments/new.json", "comments/post.json")
197
+ contact = Contact.my
198
+ comment = contact.comment "This is a comment."
199
+ comment.should be_a(Comment)
200
+ s.should have_been_requested
201
+ end
202
+
203
+ end
204
+
205
+ context "/comments/<id>" do
206
+
207
+ let(:id) { "20121128133936712557000097" }
208
+
209
+ on_delete_it "should remove a comment" do
210
+ stub_api_get("/contacts/#{contact_id}/comments", "comments/get.json")
211
+ s = stub_api_delete("/activities/20121128132106172132000004/comments/#{id}", "success.json")
212
+ comment = Contact.new(:Id => contact_id).comments.first
213
+ comment.destroy.should eq(true)
214
+ s.should have_been_requested
215
+ end
216
+
217
+ end
218
+
75
219
  end
76
220
 
77
221
  context "/my/contact", :support do
@@ -84,25 +228,4 @@ describe Contact do
84
228
  end
85
229
  end
86
230
 
87
- context "/contact/tags", :support do
88
- on_get_it "should get all my Tags" do
89
- stub_api_get("/contacts/tags", 'contacts/tags.json')
90
- tags = Contact.tags
91
- tags.should be_an(Array)
92
- tags.length.should eq(4)
93
- tags.first["Tag"].should eq("Current Buyers")
94
- end
95
- end
96
-
97
- context "/contact/tags/<tag_name>", :support do
98
- on_get_it "should get all contacts with Tag <tag_name>" do
99
- stub_api_get("/contacts/tags/IDX%20Lead", 'contacts/contacts.json')
100
- contacts = Contact.by_tag("IDX Lead")
101
- contacts.should be_an(Array)
102
- contacts.length.should eq(3)
103
- contacts.first.Id.should eq("20101230223226074201000000")
104
- contacts.first.Tags[0].should eq("IDX Lead")
105
- end
106
- end
107
-
108
231
  end
@@ -0,0 +1,56 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe Fields do
4
+ before(:each) do
5
+ stub_auth_request
6
+ end
7
+
8
+ context "/fields/order", :support do
9
+ on_get_it "should find field orders for all property types" do
10
+ Fields.should respond_to(:order)
11
+
12
+ # stub request
13
+ stub_api_get('/fields/order','fields/order.json')
14
+
15
+ # request
16
+ resources = subject.class.order
17
+
18
+ # a standard array of results
19
+ resources.should be_an(Array)
20
+ resources.length.should eq(1)
21
+
22
+ # make sure multiple property types are present
23
+ resources.first.should have_key("A")
24
+ resources.first.should have_key("B")
25
+
26
+ resources.first["A"].should be_an(Array)
27
+ end
28
+ end
29
+
30
+ context "/fields/order/<property_type>", :support do
31
+ on_get_it "should find field order for a single property type" do
32
+ Fields.should respond_to(:order)
33
+
34
+ # stub request
35
+ stub_api_get('/fields/order/A','fields/order_a.json')
36
+
37
+ # request
38
+ resources = subject.class.order("A")
39
+
40
+ # a standard array of results
41
+ resources.should be_an(Array)
42
+ resources.length.should eq(2)
43
+
44
+ # validate a single entity
45
+ group = resources.first[resources.first.keys.first]
46
+ group.should be_an(Array)
47
+ group.length.should eq(2)
48
+ group.each do |field|
49
+ field.should have_key("Field")
50
+ end
51
+
52
+ end
53
+ end
54
+
55
+
56
+ end
@@ -73,7 +73,7 @@ describe ListingCart do
73
73
  resource.Name.should eq("My Listing Cart")
74
74
  resource.ListingCount.should eq(10)
75
75
  stub_api_delete("/#{subject.class.element_name}/#{resource.Id}", 'success.json')
76
- resource.delete.empty?.should be(true)
76
+ resource.delete.should be(true)
77
77
  end
78
78
  end
79
79
 
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Portal do
4
+
5
+ before :each do
6
+ stub_auth_request
7
+ end
8
+
9
+ context "/portal" do
10
+
11
+ it "should return a new portal if the current user doesn't have one yet" do
12
+ stub_api_get("/portal", "portal/my_non_existant.json")
13
+ portal = Portal.my
14
+ portal.persisted?.should eq(false)
15
+ end
16
+
17
+ it "should get the current user's portal" do
18
+ stub_api_get("/portal", "portal/my.json")
19
+ portal = Portal.my
20
+ portal.persisted?.should eq(true)
21
+ end
22
+
23
+ it "should create a portal for the current user" do
24
+ stub_api_post("/portal", "portal/new.json", "portal/post.json")
25
+ portal = Portal.new({
26
+ :DisplayName => "GreatPortal",
27
+ :Enabled => true,
28
+ :RequiredFields => [ "Address", "Phone" ]
29
+ })
30
+ portal.save
31
+ end
32
+
33
+ it "should enable the current user's portal" do
34
+ stub_api_get("/portal", "portal/my.json")
35
+ s = stub_api_put("/portal/20100912153422758914000000", "portal/enable.json", "portal/post.json")
36
+ portal = Portal.my
37
+ portal.enable
38
+ s.should have_been_requested
39
+ end
40
+
41
+ it "should disable the current user's portal" do
42
+ stub_api_get("/portal", "portal/my.json")
43
+ s = stub_api_put("/portal/20100912153422758914000000", "portal/disable.json", "portal/post.json")
44
+ portal = Portal.my
45
+ portal.disable
46
+ s.should have_been_requested
47
+ end
48
+
49
+ end
50
+ end
@@ -56,6 +56,49 @@ describe SavedSearch do
56
56
  resource.delete
57
57
  end
58
58
 
59
+ it "should attach a contact by id" do
60
+ stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
61
+ stub_api_put("/#{subject.class.element_name}/#{id}/contacts/20101230223226074306000000", nil, "success.json")
62
+ resource = subject.class.find(id)
63
+ resource.attach("20101230223226074306000000")
64
+ resource.ContactIds.size.should eq(2)
65
+ resource.ContactIds.any? { |c| c == "20101230223226074306000000" }.should eq(true)
66
+ end
67
+
68
+ it "should detach a contact by id" do
69
+ stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
70
+ stub_api_delete("/#{subject.class.element_name}/#{id}/contacts/20100815220615294367000000", "generic_delete.json")
71
+ resource = subject.class.find(id)
72
+ resource.detach("20100815220615294367000000")
73
+ resource.ContactIds.size.should eq(0)
74
+ end
75
+
76
+ it "should attach a contact by Contact object" do
77
+ stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
78
+ stub_api_put("/#{subject.class.element_name}/#{id}/contacts/20101230223226074306000000", nil, "success.json")
79
+ resource = subject.class.find(id)
80
+ resource.attach(Contact.new({ :Id => "20101230223226074306000000" }))
81
+ resource.ContactIds.size.should eq(2)
82
+ resource.ContactIds.any? { |c| c == "20101230223226074306000000" }.should eq(true)
83
+ end
84
+
85
+ it "should detach a contact by Contact object" do
86
+ stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
87
+ stub_api_delete("/#{subject.class.element_name}/#{id}/contacts/20100815220615294367000000", "generic_delete.json")
88
+ resource = subject.class.find(id)
89
+ resource.detach(Contact.new({:Id => "20100815220615294367000000" }))
90
+ resource.ContactIds.size.should eq(0)
91
+ end
92
+
93
+ it "should initialize ContactIds as an array if nil" do
94
+ stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
95
+ stub_api_delete("/#{subject.class.element_name}/#{id}/contacts/20100815220615294367000000", "generic_delete.json")
96
+ resource = subject.class.find(id)
97
+ resource.ContactIds = nil
98
+ resource.detach(Contact.new({:Id => "20100815220615294367000000" }))
99
+ resource.ContactIds.size.should eq(0)
100
+ end
101
+
59
102
  end
60
103
 
61
104
  context "/provided/savedsearches", :support do
@@ -68,4 +111,21 @@ describe SavedSearch do
68
111
  end
69
112
  end
70
113
 
114
+ context "/savedsearches/<id>/contacts" do
115
+
116
+ on_get_it "should return a list of contacts" do
117
+ stub_api_get("/savedsearches/#{id}", "saved_searches/get.json")
118
+ stub_api_get("/savedsearches/20101230223226074204000000", "saved_searches/get.json")
119
+
120
+ resource = subject.class.find(id)
121
+ contacts = resource.contacts
122
+ contacts.should be_an(Array)
123
+ end
124
+
125
+ it "should return an empty array if model isn't persisted" do
126
+ resource = SavedSearch.new
127
+ resource.contacts.should be_an(Array)
128
+ end
129
+ end
130
+
71
131
  end