spark_api 1.1.2 → 1.2.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 (73) hide show
  1. data/History.txt +14 -0
  2. data/README.md +42 -233
  3. data/VERSION +1 -1
  4. data/lib/spark_api.rb +1 -0
  5. data/lib/spark_api/authentication/oauth2.rb +39 -9
  6. data/lib/spark_api/authentication/oauth2_impl/cli_provider.rb +96 -0
  7. data/lib/spark_api/authentication/oauth2_impl/faraday_middleware.rb +28 -0
  8. data/lib/spark_api/authentication/oauth2_impl/grant_type_base.rb +7 -2
  9. data/lib/spark_api/authentication/oauth2_impl/single_session_provider.rb +27 -0
  10. data/lib/spark_api/cli.rb +29 -10
  11. data/lib/spark_api/cli/api_auth.rb +1 -0
  12. data/lib/spark_api/cli/oauth2.rb +23 -8
  13. data/lib/spark_api/cli/setup.rb +31 -0
  14. data/lib/spark_api/configuration.rb +10 -2
  15. data/lib/spark_api/configuration/yaml.rb +6 -1
  16. data/lib/spark_api/connection.rb +1 -1
  17. data/lib/spark_api/errors.rb +48 -0
  18. data/lib/spark_api/models.rb +3 -0
  19. data/lib/spark_api/models/account.rb +9 -1
  20. data/lib/spark_api/models/base.rb +24 -19
  21. data/lib/spark_api/models/concerns.rb +7 -0
  22. data/lib/spark_api/models/concerns/destroyable.rb +32 -0
  23. data/lib/spark_api/models/concerns/savable.rb +66 -0
  24. data/lib/spark_api/models/contact.rb +6 -25
  25. data/lib/spark_api/models/dirty.rb +57 -0
  26. data/lib/spark_api/models/finders.rb +0 -4
  27. data/lib/spark_api/models/saved_search.rb +10 -0
  28. data/lib/spark_api/models/subresource.rb +5 -1
  29. data/lib/spark_api/models/subscription.rb +52 -0
  30. data/lib/spark_api/request.rb +17 -4
  31. data/lib/spark_api/response.rb +0 -37
  32. data/script/combined_flow_example.rb +3 -3
  33. data/script/oauth2_example.rb +3 -3
  34. data/spec/fixtures/base.json +3 -1
  35. data/spec/fixtures/contacts/new.json +2 -3
  36. data/spec/fixtures/contacts/new_empty.json +2 -3
  37. data/spec/fixtures/contacts/new_notify.json +1 -1
  38. data/spec/fixtures/{listings/saved_search.json → saved_searches/get.json} +1 -1
  39. data/spec/fixtures/saved_searches/new.json +8 -0
  40. data/spec/fixtures/saved_searches/post.json +12 -0
  41. data/spec/fixtures/saved_searches/update.json +6 -0
  42. data/spec/fixtures/subscriptions/get.json +19 -0
  43. data/spec/fixtures/subscriptions/new.json +13 -0
  44. data/spec/fixtures/subscriptions/post.json +10 -0
  45. data/spec/fixtures/subscriptions/put.json +12 -0
  46. data/spec/fixtures/subscriptions/subscribe.json +5 -0
  47. data/spec/fixtures/subscriptions/update.json +6 -0
  48. data/spec/mock_helper.rb +14 -6
  49. data/spec/oauth2_helper.rb +2 -0
  50. data/spec/spec_helper.rb +4 -7
  51. data/spec/unit/spark_api/authentication/api_auth_spec.rb +0 -1
  52. data/spec/unit/spark_api/authentication/oauth2_impl/faraday_middleware_spec.rb +32 -0
  53. data/spec/unit/spark_api/authentication/oauth2_impl/single_session_provider_spec.rb +9 -0
  54. data/spec/unit/spark_api/authentication/oauth2_spec.rb +29 -3
  55. data/spec/unit/spark_api/authentication_spec.rb +4 -10
  56. data/spec/unit/spark_api/configuration/yaml_spec.rb +4 -3
  57. data/spec/unit/spark_api/configuration_spec.rb +22 -8
  58. data/spec/unit/spark_api/models/account_spec.rb +5 -0
  59. data/spec/unit/spark_api/models/base_spec.rb +27 -0
  60. data/spec/unit/spark_api/models/concerns/destroyable_spec.rb +28 -0
  61. data/spec/unit/spark_api/models/concerns/savable_spec.rb +61 -0
  62. data/spec/unit/spark_api/models/contact_spec.rb +5 -5
  63. data/spec/unit/spark_api/models/dirty_spec.rb +46 -0
  64. data/spec/unit/spark_api/models/finders_spec.rb +0 -7
  65. data/spec/unit/spark_api/models/saved_search_spec.rb +34 -3
  66. data/spec/unit/spark_api/models/shared_listing_spec.rb +1 -1
  67. data/spec/unit/spark_api/models/subscription_spec.rb +106 -0
  68. data/spec/unit/spark_api/multi_client_spec.rb +14 -4
  69. data/spec/unit/spark_api/paginate_spec.rb +0 -1
  70. data/spec/unit/spark_api/request_spec.rb +10 -0
  71. data/spec/unit/spark_api_spec.rb +0 -3
  72. metadata +127 -45
  73. data/lib/spark_api/authentication/oauth2_impl/password_provider.rb +0 -24
@@ -1,15 +1,12 @@
1
1
  require './spec/spec_helper'
2
2
 
3
3
  describe SparkApi::Client, "Client config" do
4
- after(:all) do
5
- reset_config
6
- end
7
-
8
4
  describe "default settings" do
9
5
  it "should return the proper defaults when called with no arguments" do
10
6
  SparkApi.api_key.should be_nil
11
7
  SparkApi.api_secret.should be_nil
12
8
  SparkApi.version.should match("v1")
9
+ SparkApi.ssl_verify.should be_true
13
10
  SparkApi.auth_endpoint.should match("sparkplatform.com/openid")
14
11
  SparkApi.endpoint.should match("api.sparkapi.com")
15
12
  SparkApi.user_agent.should match(/Spark API Ruby Gem .*/)
@@ -33,6 +30,22 @@ describe SparkApi::Client, "Client config" do
33
30
  client.endpoint.should match("http://api.wade.dev.fbsdata.com")
34
31
  client.version.should match("v1")
35
32
  end
33
+
34
+ it "should allow unverified ssl certificates when verification is off" do
35
+ client = SparkApi::Client.new(:auth_endpoint => "https://login.wade.dev.fbsdata.com",
36
+ :endpoint => "https://api.wade.dev.fbsdata.com",
37
+ :ssl_verify => false)
38
+ client.ssl_verify.should be_false
39
+ client.connection.ssl.should eq({:verify=>false})
40
+ end
41
+
42
+ it "should allow restrict ssl certificates when verification is on" do
43
+ client = SparkApi::Client.new(:auth_endpoint => "https://login.wade.dev.fbsdata.com",
44
+ :endpoint => "https://api.wade.dev.fbsdata.com",
45
+ :ssl_verify => true)
46
+ client.ssl_verify.should be_true
47
+ client.connection.ssl.should eq({})
48
+ end
36
49
  end
37
50
 
38
51
  describe "oauth2 instance configuration" do
@@ -44,7 +57,7 @@ describe SparkApi::Client, "Client config" do
44
57
  :endpoint => "http://api.wade.dev.fbsdata.com",
45
58
  :authentication_mode => SparkApi::Authentication::OAuth2)
46
59
  end
47
-
60
+
48
61
  it "should convert the configuration to oauth2 when specified" do
49
62
  oauth2_client.oauthify!
50
63
  oauth2_client.oauth2_provider.should be_a(SparkApi::Authentication::SimpleProvider)
@@ -144,19 +157,20 @@ describe SparkApi::Client, "Client config" do
144
157
  end
145
158
 
146
159
  it "should have correct headers based on configuration" do
160
+ reset_config
147
161
  stub_auth_request
148
162
  stub_request(:get, "#{SparkApi.endpoint}/#{SparkApi.version}/headers").
149
163
  with(:query => {
150
- :ApiSig => "6f0cfef263e0bfe7a9ae1f60063a8ad9",
164
+ :ApiUser => "foobar",
165
+ :ApiSig => "717a066c4f4302c5ca9507e484db4812",
151
166
  :AuthToken => "c401736bf3d3f754f07c04e460e09573"
152
167
  }).
153
168
  to_return(:body => '{"D":{"Success": true,"Results": []}}')
154
- SparkApi.reset
155
169
  SparkApi.configure do |config|
156
170
  config.user_agent = "my useragent"
157
171
  end
158
172
  SparkApi.client.get '/headers'
159
- WebMock.should have_requested(:get, "#{SparkApi.endpoint}/#{SparkApi.version}/headers?ApiSig=6f0cfef263e0bfe7a9ae1f60063a8ad9&AuthToken=c401736bf3d3f754f07c04e460e09573").
173
+ WebMock.should have_requested(:get, "#{SparkApi.endpoint}/#{SparkApi.version}/headers?ApiUser=foobar&ApiSig=717a066c4f4302c5ca9507e484db4812&AuthToken=c401736bf3d3f754f07c04e460e09573").
160
174
  with(:headers => {
161
175
  'User-Agent' => SparkApi::Configuration::DEFAULT_USER_AGENT,
162
176
  SparkApi::Configuration::X_SPARK_API_USER_AGENT => "my useragent",
@@ -72,6 +72,11 @@ describe Account do
72
72
  "Name"=>"My Photo two",
73
73
  "Uri"=>"http://photos.flexmls.com/az/...."
74
74
  },
75
+ {
76
+ "Type"=>"Photo",
77
+ "Name"=>nil,
78
+ "Uri"=>"http://photos.flexmls.com/az/...."
79
+ },
75
80
  {
76
81
  "Type"=>"Logo",
77
82
  "Name"=>"1 My Logo",
@@ -9,8 +9,23 @@ end
9
9
  class MyDefaultModel < Base
10
10
  end
11
11
 
12
+ describe MyExampleModel, "Example model" do
13
+ before(:each) do
14
+ stub_auth_request
15
+ stub_api_get("/test/example", 'base.json')
16
+ @model = MyExampleModel.first
17
+ end
18
+ it "should be persisted" do
19
+ @model.persisted?.should eq(true)
20
+ end
21
+ it "should not be persisted" do
22
+ @new_model = MyExampleModel.new()
23
+ @new_model.persisted?.should eq(false)
24
+ end
25
+ end
12
26
 
13
27
  describe Base, "Base model" do
28
+
14
29
  describe "class methods" do
15
30
  it "should set the element name" do
16
31
  MyExampleModel.element_name.should eq("example")
@@ -69,6 +84,10 @@ describe Base, "Base model" do
69
84
  @model.Name?.should satisfy { |p| [true, false].include?(p) }
70
85
  end
71
86
 
87
+ it "should return a boolean for whether or not a model is persisted through the api" do
88
+ @model.persisted?.should satisfy { |p| [true, false].include?(p) }
89
+ end
90
+
72
91
  it "should raise an Error for a predicate for a non-existant attribute" do
73
92
  lambda { @model.Nonsense? }.should raise_error(NoMethodError)
74
93
  end
@@ -101,6 +120,14 @@ describe Base, "Base model" do
101
120
  @model.should respond_to(:freeze)
102
121
  end
103
122
 
123
+ it "should respond_to a will_change! method for an existing attribute" do
124
+ @model.should respond_to(:Name_will_change!)
125
+ end
126
+
127
+ it "should not respond_to a will_change! method for a non-existant attribute" do
128
+ @model.should_not respond_to(:Nonsense_will_change!)
129
+ end
130
+
104
131
  end
105
132
 
106
133
  end
@@ -0,0 +1,28 @@
1
+ require 'spec_helper'
2
+
3
+ class MyExampleModel < Base
4
+ include Concerns::Destroyable
5
+ self.prefix = "/test/"
6
+ self.element_name = "example"
7
+ end
8
+
9
+ describe Concerns::Destroyable, "Destroyable Concern" do
10
+
11
+ before :each do
12
+ stub_auth_request
13
+ stub_api_get("/test/example", 'base.json')
14
+ @model = MyExampleModel.first
15
+ end
16
+
17
+ it "should not be destroyed" do
18
+ @model.destroyed?.should eq(false)
19
+ end
20
+
21
+ it "should be destroyable" do
22
+ stub_api_delete("/test/example/1")
23
+ @model = MyExampleModel.first
24
+ @model.destroy
25
+ @model.destroyed?.should eq(true)
26
+ end
27
+
28
+ end
@@ -0,0 +1,61 @@
1
+ require 'spec_helper'
2
+
3
+ class MyExampleModel < Base
4
+ include Concerns::Savable
5
+ self.prefix = "/test/"
6
+ self.element_name = "example"
7
+ end
8
+
9
+ class MyOtherExampleModel < Base
10
+ include Concerns::Savable
11
+ self.prefix = "/test/"
12
+ self.element_name = "example"
13
+ private
14
+ def resource_pluralized
15
+ "MyOtherExampleModelThatIsPluralized"
16
+ end
17
+ end
18
+
19
+ class MyPluralizedModels < Base
20
+ include Concerns::Savable
21
+ self.prefix = "/test/"
22
+ self.element_name = "example"
23
+ end
24
+
25
+ describe Concerns::Savable, "Model" do
26
+
27
+ before :each do
28
+ stub_auth_request
29
+ end
30
+
31
+ it "should be creatable" do
32
+ @model = MyExampleModel.new({ :Name => "my name" })
33
+ stub_api_post("/test/example", { :MyExampleModels => [ @model.attributes ] }, "base.json")
34
+ @model.save.should eq(true)
35
+ @model.persisted?.should eq(true)
36
+ end
37
+
38
+ it "should be updatable" do
39
+ stub_api_get("/test/example", 'base.json')
40
+ @model = MyExampleModel.first
41
+ @model.Name = "new name"
42
+ stub_api_put("/test/example/1", @model.dirty_attributes)
43
+ @model.save.should eq(true)
44
+ @model.persisted?.should eq(true)
45
+ end
46
+
47
+ it "should allow the pluralize method to be overriden" do
48
+ @model = MyOtherExampleModel.new({ :Name => "my name" })
49
+ stub_api_post("/test/example", { :MyOtherExampleModelThatIsPluralized => [ @model.attributes ] }, "base.json")
50
+ @model.save.should eq(true)
51
+ @model.persisted?.should eq(true)
52
+ end
53
+
54
+ it "should not pluralize the resource if it already is" do
55
+ @model = MyPluralizedModels.new({ :Name => "my name" })
56
+ stub_api_post("/test/example", { :MyPluralizedModels => [ @model.attributes ] }, "base.json")
57
+ @model.save.should eq(true)
58
+ @model.persisted?.should eq(true)
59
+ end
60
+
61
+ end
@@ -1,6 +1,5 @@
1
1
  require './spec/spec_helper'
2
2
 
3
-
4
3
  describe Contact do
5
4
  before(:each) do
6
5
  stub_auth_request
@@ -23,20 +22,21 @@ describe Contact do
23
22
  on_post_it "should save a new contact" do
24
23
  stub_api_post("/contacts", 'contacts/new.json', 'contacts/post.json')
25
24
  c=Contact.new
26
- c.attributes["DisplayName"] = "Contact Four"
27
- c.attributes["PrimaryEmail"] = "contact4@fbsdata.com"
25
+ c.DisplayName = "Contact Four"
26
+ c.PrimaryEmail = "contact4@fbsdata.com"
28
27
  c.save.should be(true)
29
28
  c.Id.should eq('20101230223226074204000000')
30
29
  end
31
30
 
32
31
  on_post_it "should save a new contact and notify" do
33
32
  stub_api_post("/contacts", 'contacts/new_notify.json', 'contacts/post.json')
34
- c=Contact.new
35
- c.notify=true
33
+ c = Contact.new
34
+ c.notify = true
36
35
  c.attributes["DisplayName"] = "Contact Four"
37
36
  c.attributes["PrimaryEmail"] = "contact4@fbsdata.com"
38
37
  c.save.should be(true)
39
38
  c.Id.should eq('20101230223226074204000000')
39
+ c.ResourceUri.should eq('/v1/contacts/20101230223226074204000000')
40
40
  end
41
41
 
42
42
  on_post_it "should fail saving" do
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ class MyExampleModel < Base
4
+ include Concerns::Savable
5
+ self.prefix = "/test/"
6
+ self.element_name = "example"
7
+ end
8
+
9
+ describe Dirty do
10
+
11
+ before :each do
12
+ stub_auth_request
13
+ @model = MyExampleModel.new(:Name => "some old name")
14
+ @model.Name = "a new name"
15
+ end
16
+
17
+ it "should return an array of the attributes that have been changed" do
18
+ @model.changed.should eq(["Name"])
19
+ end
20
+
21
+ it "should return a hash diff of current changes on a model" do
22
+ @model.changes.should eq({
23
+ "Name" => ["some old name", "a new name"]
24
+ })
25
+ end
26
+
27
+ it "should return previously changed attributes after save" do
28
+ stub_api_post('/test/example', { :MyExampleModels => [ @model.attributes ] }, 'base.json')
29
+ @model.save
30
+ @model.previous_changes.should eq({
31
+ })
32
+ end
33
+
34
+ it "should return changed attributes with old values" do
35
+ @model.changed_attributes.should eq({
36
+ "Name" => "some old name"
37
+ })
38
+ end
39
+
40
+ it "should return changed attributes with new values" do
41
+ @model.dirty_attributes.should eq({
42
+ "Name" => "a new name"
43
+ })
44
+ end
45
+
46
+ end
@@ -9,22 +9,15 @@ describe Finders, "Finders model" do
9
9
 
10
10
  before(:each) do
11
11
  stub_auth_request
12
- end
13
-
14
- it "should get all results" do
15
12
  stub_api_get("/my_resource", 'finders.json')
16
- resources = MyResource.all
17
- resources.size.should eq(2)
18
13
  end
19
14
 
20
15
  it "should get first result" do
21
- stub_api_get("/my_resource", 'finders.json')
22
16
  resource = MyResource.first
23
17
  resource.Id.should eq(1)
24
18
  end
25
19
 
26
20
  it "should get last result" do
27
- stub_api_get("/my_resource", 'finders.json')
28
21
  resource = MyResource.last
29
22
  resource.Id.should eq(2)
30
23
  end
@@ -9,27 +9,58 @@ describe SavedSearch do
9
9
  let(:id){ "20100815220615294367000000" }
10
10
 
11
11
  context "/savedsearches", :support do
12
+
12
13
  on_get_it "should get all SavedSearches" do
13
- stub_api_get("/#{subject.class.element_name}", 'listings/saved_search.json')
14
+ stub_api_get("/#{subject.class.element_name}", 'saved_searches/get.json')
14
15
  resources = subject.class.get
15
16
  resources.should be_an(Array)
16
17
  resources.length.should eq(2)
17
18
  resources.first.Id.should eq(id)
18
19
  end
20
+
21
+ on_post_it "should create a saved search" do
22
+ stub_api_post("/#{subject.class.element_name}", "saved_searches/new.json", "saved_searches/post.json")
23
+ resource = SavedSearch.new({ :Name => "A new search name here" })
24
+ resource.should respond_to(:save)
25
+ resource.save
26
+ resource.persisted?.should eq(true)
27
+ resource.attributes['Id'].should eq("20100815220615294367000000")
28
+ resource.attributes['ResourceUri'].should eq("/v1/savedsearches/20100815220615294367000000")
29
+ end
30
+
19
31
  end
20
32
 
21
33
  context "/savedsearches/<search_id>", :support do
34
+
22
35
  on_get_it "should get a SavedSearch" do
23
- stub_api_get("/#{subject.class.element_name}/#{id}", 'listings/saved_search.json')
36
+ stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_searches/get.json')
24
37
  resource = subject.class.find(id)
25
38
  resource.Id.should eq(id)
26
39
  resource.Name.should eq("Search name here")
27
40
  end
41
+
42
+ on_put_it "should update a SavedSearch" do
43
+ stub_api_get("/#{subject.class.element_name}/#{id}", "saved_searches/get.json")
44
+ stub_api_put("/#{subject.class.element_name}/#{id}", "saved_searches/update.json", "saved_searches/post.json")
45
+ resource = subject.class.find(id)
46
+ resource.should respond_to(:save)
47
+ resource.Name = "A new search name here"
48
+ resource.save
49
+ end
50
+
51
+ on_delete_it "should delete a saved search" do
52
+ stub_api_get("/#{subject.class.element_name}/#{id}", "saved_searches/get.json")
53
+ stub_api_delete("/#{subject.class.element_name}/#{id}", "generic_delete.json")
54
+ resource = subject.class.find(id)
55
+ resource.should respond_to(:delete)
56
+ resource.delete
57
+ end
58
+
28
59
  end
29
60
 
30
61
  context "/provided/savedsearches", :support do
31
62
  on_get_it "should get provided SavedSearches" do
32
- stub_api_get("/provided/#{subject.class.element_name}", 'listings/saved_search.json')
63
+ stub_api_get("/provided/#{subject.class.element_name}", 'saved_searches/get.json')
33
64
  resources = subject.class.provided.get
34
65
  resources.should be_an(Array)
35
66
  resources.length.should eq(2)
@@ -20,7 +20,7 @@ describe SharedListing do
20
20
  end
21
21
 
22
22
  on_post_it "should fail creating" do
23
- stub_api_post("/#{subject.class.element_name}",'empty.json') do |request|
23
+ stub_api_post("/#{subject.class.element_name}",{}) do |request|
24
24
  request.to_return(:status => 400, :body => fixture('errors/failure.json'))
25
25
  end
26
26
  subject
@@ -0,0 +1,106 @@
1
+ require 'spec_helper'
2
+
3
+ describe Subscription do
4
+
5
+ it "responds to crud methods" do
6
+ Subscription.should respond_to(:get)
7
+ Subscription.new.should respond_to(:save)
8
+ Subscription.new.should respond_to(:delete)
9
+ end
10
+
11
+ before :each do
12
+ stub_auth_request
13
+ end
14
+
15
+ let(:id){ "20101230223226074204000000" }
16
+
17
+ context "/subscriptions", :support do
18
+
19
+ on_get_it "should get sum subscriptions" do
20
+ stub_api_get("/subscriptions", "subscriptions/get.json")
21
+ subject.class.get
22
+ end
23
+
24
+ on_post_it "should create a new subscription" do
25
+ @subscription = Subscription.new({
26
+ :Name => "A new subscription name",
27
+ :SearchId => "20101230223226074204000000",
28
+ :RecipientIds => [ "20101230223226074204000000" ],
29
+ :Subject => "my subject",
30
+ :Message => "my message"
31
+ })
32
+ stub_api_post("/subscriptions", 'subscriptions/new.json', 'subscriptions/post.json')
33
+ @subscription.save.should be(true)
34
+ @subscription.persisted?.should eq(true)
35
+ end
36
+
37
+ it "should subscribe a contact by id" do
38
+ stub_api_get("/subscriptions/#{id}", "subscriptions/get.json")
39
+ stub_api_put("/subscriptions/#{id}/subscribers/20101230223226074306000000", nil, 'subscriptions/subscribe.json')
40
+ resource = subject.class.find(id)
41
+ resource.subscribe("20101230223226074306000000")
42
+ resource.RecipientIds.size.should eq(2)
43
+ resource.RecipientIds.any? { |c| c == "20101230223226074306000000" }.should eq(true)
44
+ end
45
+
46
+ it "should unsubscribe a contact by id" do
47
+ stub_api_get("/subscriptions/#{id}", "subscriptions/get.json")
48
+ stub_api_delete("/subscriptions/#{id}/subscribers/20101230223226074307000000", 'generic_delete.json')
49
+ resource = subject.class.find(id)
50
+ resource.unsubscribe("20101230223226074307000000")
51
+ resource.RecipientIds.size.should eq(0)
52
+ end
53
+
54
+ it "should subscribe a contact by Contact object" do
55
+ stub_api_get("/subscriptions/#{id}", "subscriptions/get.json")
56
+ stub_api_put("/subscriptions/#{id}/subscribers/20101230223226074306000000", nil, 'subscriptions/subscribe.json')
57
+ resource = subject.class.find(id)
58
+ resource.subscribe(Contact.new({ :Id => "20101230223226074306000000" }))
59
+ resource.RecipientIds.size.should eq(2)
60
+ resource.RecipientIds.any? { |c| c == "20101230223226074306000000" }.should eq(true)
61
+ end
62
+
63
+ it "should unsubscribe a contact by Contact object" do
64
+ stub_api_get("/subscriptions/#{id}", "subscriptions/get.json")
65
+ stub_api_delete("/subscriptions/#{id}/subscribers/20101230223226074307000000", 'generic_delete.json')
66
+ resource = subject.class.find(id)
67
+ resource.unsubscribe(Contact.new({ :Id => "20101230223226074307000000" }))
68
+ resource.RecipientIds.size.should eq(0)
69
+ end
70
+
71
+ it "should initialize RecipientIds as an array if nil" do
72
+ stub_api_get("/subscriptions/#{id}", "subscriptions/get.json")
73
+ stub_api_put("/subscriptions/#{id}/subscribers/20101230223226074306000000", nil, 'subscriptions/subscribe.json')
74
+ resource = subject.class.find(id)
75
+ resource.RecipientIds = nil
76
+ resource.subscribe(Contact.new({ :Id => "20101230223226074306000000" }))
77
+ resource.RecipientIds.size.should eq(1)
78
+ end
79
+
80
+ end
81
+
82
+ context "/subscriptions/:id", :support do
83
+
84
+ on_get_it "should get a subscription" do
85
+ stub_api_get("/subscriptions/#{id}", "subscriptions/get.json")
86
+ subject.class.find(id)
87
+ end
88
+
89
+ on_put_it "should update a subscription" do
90
+ stub_api_get("/subscriptions/#{id}", 'subscriptions/get.json')
91
+ stub_api_put("/subscriptions/#{id}", 'subscriptions/update.json', 'subscriptions/post.json')
92
+ resource = subject.class.find(id)
93
+ resource.Name = "A new subscription name"
94
+ resource.save.should be(true)
95
+ end
96
+
97
+ on_delete_it "should delete a subscription" do
98
+ stub_api_get("/subscriptions/#{id}", 'subscriptions/get.json')
99
+ stub_api_delete("/subscriptions/#{id}", 'generic_delete.json')
100
+ resource = subject.class.find(id)
101
+ resource.delete
102
+ end
103
+
104
+ end
105
+
106
+ end