flexmls_api 0.6.5 → 0.7.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 (89) hide show
  1. data/History.txt +12 -1
  2. data/VERSION +1 -1
  3. data/lib/flexmls_api.rb +13 -11
  4. data/lib/flexmls_api/authentication/api_auth.rb +5 -3
  5. data/lib/flexmls_api/authentication/oauth2.rb +23 -17
  6. data/lib/flexmls_api/authentication/oauth2_impl/password_provider.rb +25 -0
  7. data/lib/flexmls_api/cli.rb +51 -25
  8. data/lib/flexmls_api/cli/oauth2.rb +1 -30
  9. data/lib/flexmls_api/cli/setup.rb +4 -1
  10. data/lib/flexmls_api/client.rb +1 -1
  11. data/lib/flexmls_api/configuration.rb +10 -0
  12. data/lib/flexmls_api/configuration/yaml.rb +81 -0
  13. data/lib/flexmls_api/faraday.rb +12 -2
  14. data/lib/flexmls_api/models.rb +25 -23
  15. data/lib/flexmls_api/models/constraint.rb +16 -0
  16. data/lib/flexmls_api/models/listing.rb +45 -2
  17. data/lib/flexmls_api/models/photo.rb +57 -2
  18. data/lib/flexmls_api/models/subresource.rb +5 -2
  19. data/lib/flexmls_api/multi_client.rb +21 -6
  20. data/lib/flexmls_api/paginate.rb +18 -1
  21. data/lib/flexmls_api/request.rb +1 -71
  22. data/lib/flexmls_api/response.rb +69 -0
  23. data/spec/fixtures/{contacts.json → contacts/contacts.json} +0 -0
  24. data/spec/fixtures/{contact_my.json → contacts/my.json} +0 -0
  25. data/spec/fixtures/{contact_new.json → contacts/new.json} +0 -0
  26. data/spec/fixtures/{contact_new_empty.json → contacts/new_empty.json} +0 -0
  27. data/spec/fixtures/{contact_new_notify.json → contacts/new_notify.json} +0 -0
  28. data/spec/fixtures/{contacts_post.json → contacts/post.json} +0 -0
  29. data/spec/fixtures/{contact_tags.json → contacts/tags.json} +0 -0
  30. data/spec/fixtures/{listing_cart_add_listing.json → listing_carts/add_listing.json} +0 -0
  31. data/spec/fixtures/{listing_cart_add_listing_post.json → listing_carts/add_listing_post.json} +0 -0
  32. data/spec/fixtures/{listing_cart_empty.json → listing_carts/empty.json} +0 -0
  33. data/spec/fixtures/{listing_cart.json → listing_carts/listing_cart.json} +0 -0
  34. data/spec/fixtures/{listing_cart_new.json → listing_carts/new.json} +0 -0
  35. data/spec/fixtures/{listing_cart_post.json → listing_carts/post.json} +0 -0
  36. data/spec/fixtures/{listing_cart_remove_listing.json → listing_carts/remove_listing.json} +0 -0
  37. data/spec/fixtures/listings/constraints.json +18 -0
  38. data/spec/fixtures/listings/constraints_with_pagination.json +24 -0
  39. data/spec/fixtures/{listing_document_index.json → listings/document_index.json} +0 -0
  40. data/spec/fixtures/{listing_no_subresources.json → listings/no_subresources.json} +0 -0
  41. data/spec/fixtures/{open_houses.json → listings/open_houses.json} +0 -0
  42. data/spec/fixtures/{listing_photos_index.json → listings/photos/index.json} +0 -0
  43. data/spec/fixtures/listings/photos/new.json +12 -0
  44. data/spec/fixtures/listings/photos/post.json +20 -0
  45. data/spec/fixtures/listings/put.json +5 -0
  46. data/spec/fixtures/{saved_search.json → listings/saved_search.json} +0 -0
  47. data/spec/fixtures/{shared_listing_new.json → listings/shared_listing_new.json} +0 -0
  48. data/spec/fixtures/{shared_listing_post.json → listings/shared_listing_post.json} +0 -0
  49. data/spec/fixtures/{tour_of_homes.json → listings/tour_of_homes.json} +0 -0
  50. data/spec/fixtures/{listing_videos_index.json → listings/videos_index.json} +0 -0
  51. data/spec/fixtures/{listing_virtual_tours_index.json → listings/virtual_tours_index.json} +0 -0
  52. data/spec/fixtures/{listing_with_documents.json → listings/with_documents.json} +0 -0
  53. data/spec/fixtures/listings/with_permissions.json +44 -0
  54. data/spec/fixtures/{listing_with_photos.json → listings/with_photos.json} +0 -0
  55. data/spec/fixtures/{listing_with_supplement.json → listings/with_supplement.json} +0 -0
  56. data/spec/fixtures/{listing_with_videos.json → listings/with_videos.json} +0 -0
  57. data/spec/fixtures/{listing_with_vtour.json → listings/with_vtour.json} +0 -0
  58. data/spec/fixtures/logo_fbs.png +0 -0
  59. data/spec/fixtures/{add_note.json → notes/add.json} +0 -0
  60. data/spec/fixtures/{agent_shared_note.json → notes/agent_shared.json} +0 -0
  61. data/spec/fixtures/{agent_shared_note_empty.json → notes/agent_shared_empty.json} +0 -0
  62. data/spec/fixtures/{note_new.json → notes/new.json} +0 -0
  63. data/spec/fixtures/{standardfields_city.json → standardfields/city.json} +0 -0
  64. data/spec/fixtures/{standardfields_nearby.json → standardfields/nearby.json} +0 -0
  65. data/spec/fixtures/{standardfields.json → standardfields/standardfields.json} +0 -0
  66. data/spec/fixtures/{standardfields_stateorprovince.json → standardfields/stateorprovince.json} +0 -0
  67. data/spec/mock_helper.rb +5 -3
  68. data/spec/unit/flexmls_api/authentication/api_auth_spec.rb +11 -2
  69. data/spec/unit/flexmls_api/authentication/base_auth_spec.rb +10 -0
  70. data/spec/unit/flexmls_api/authentication/oauth2_spec.rb +3 -3
  71. data/spec/unit/flexmls_api/configuration/yaml_spec.rb +70 -0
  72. data/spec/unit/flexmls_api/models/constraint_spec.rb +19 -0
  73. data/spec/unit/flexmls_api/models/contact_spec.rb +8 -8
  74. data/spec/unit/flexmls_api/models/document_spec.rb +1 -1
  75. data/spec/unit/flexmls_api/models/listing_cart_spec.rb +15 -15
  76. data/spec/unit/flexmls_api/models/listing_spec.rb +78 -13
  77. data/spec/unit/flexmls_api/models/note_spec.rb +4 -4
  78. data/spec/unit/flexmls_api/models/open_house_spec.rb +1 -1
  79. data/spec/unit/flexmls_api/models/photo_spec.rb +73 -40
  80. data/spec/unit/flexmls_api/models/saved_search_spec.rb +3 -3
  81. data/spec/unit/flexmls_api/models/shared_listing_spec.rb +1 -1
  82. data/spec/unit/flexmls_api/models/standard_fields_spec.rb +4 -7
  83. data/spec/unit/flexmls_api/models/tour_of_home_spec.rb +1 -1
  84. data/spec/unit/flexmls_api/models/video_spec.rb +1 -1
  85. data/spec/unit/flexmls_api/models/virtual_tour_spec.rb +1 -1
  86. data/spec/unit/flexmls_api/multi_client_spec.rb +9 -1
  87. data/spec/unit/flexmls_api/paginate_spec.rb +1 -1
  88. data/spec/unit/flexmls_api/request_spec.rb +2 -2
  89. metadata +182 -152
@@ -0,0 +1,18 @@
1
+ {
2
+ "D": {
3
+ "Details": [
4
+ {
5
+ "ListPrice": [
6
+ {
7
+ "RuleValue": 1000000.0,
8
+ "RuleField": null,
9
+ "RuleFieldValue": null,
10
+ "Value": 1000001.0,
11
+ "RuleName": "MaxValue"
12
+ }
13
+ ]
14
+ }
15
+ ],
16
+ "Success": true
17
+ }
18
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "D": {
3
+ "Details": [
4
+ {
5
+ "ListPrice": [
6
+ {
7
+ "RuleValue": 1000000.0,
8
+ "RuleField": null,
9
+ "RuleFieldValue": null,
10
+ "Value": 1000001.0,
11
+ "RuleName": "MaxValue"
12
+ }
13
+ ]
14
+ }
15
+ ],
16
+ "Pagination": {
17
+ "TotalRows": 0,
18
+ "PageSize": 1,
19
+ "TotalPages": 1,
20
+ "CurrentPage": 1
21
+ },
22
+ "Success": true
23
+ }
24
+ }
@@ -0,0 +1,12 @@
1
+ {
2
+ "D": {
3
+ "Photos": [
4
+ {
5
+ "Caption": "Creators of flexMLS!",
6
+ "Name": "FBS Logo",
7
+ "FileName": "logo_fbs.png",
8
+ "Picture": "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"
9
+ }
10
+ ]
11
+ }
12
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "D": {
3
+ "Results": [
4
+ {
5
+ "Uri300": "http://photos.flexmls.com/fgo/20110826220032167405000000.jpg",
6
+ "ResourceUri": "/v1/listings/20050505200220759069000000/photos/20110826220032167405000000",
7
+ "Name": "Front",
8
+ "Uri800": "http://cdn.resize.flexmls.com/fgo/800x600/true/20110826220032167405000000-o.jpg",
9
+ "Id": "20110826220032167405000000",
10
+ "UriLarge": "http://photos.flexmls.com/fgo/20110826220032167405000000-o.jpg",
11
+ "Uri1024": "http://cdn.resize.flexmls.com/fgo/1024x768/true/20110826220032167405000000-o.jpg",
12
+ "Caption": "Creaters of flexMLS!",
13
+ "Uri1280": "http://cdn.resize.flexmls.com/fgo/1280x1024/true/20110826220032167405000000-o.jpg",
14
+ "Uri640": "http://cdn.resize.flexmls.com/fgo/640x480/true/20110826220032167405000000-o.jpg",
15
+ "UriThumb": "http://photos.flexmls.com/fgo/20110826220032167405000000-t.jpg"
16
+ }
17
+ ],
18
+ "Success": true
19
+ }
20
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "D": {
3
+ "ListPrice": 10000.0
4
+ }
5
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "D": {
3
+ "Results": [
4
+ {
5
+ "ResourceUri": "/v1/listings/20060725224713296297000000",
6
+ "StandardFields": {
7
+ "StreetNumber": "7298",
8
+ "Longitude": "-116.3237",
9
+ "City": "Bonners Ferry",
10
+ "ListingId": "06-9395",
11
+ "PublicRemarks": "Afforadable home in town close to hospital,yet quiet country like setting. Good views. Must see",
12
+ "BuildingAreaTotal": "924.0",
13
+ "YearBuilt": 1977,
14
+ "StreetName": "BIRCH",
15
+ "ListPrice": "50000.0",
16
+ "PostalCode": "83805",
17
+ "VirtualTourURLBranded": "http://www.youtube.com/watch?v=T9uuPza41Uw#t=2s",
18
+ "Latitude": "48.7001",
19
+ "BathsThreeQuarter": null,
20
+ "BathsFull": null,
21
+ "BathsTotal": "1.0",
22
+ "StateOrProvince": "ID",
23
+ "PropertyType": "A",
24
+ "StreetAdditionalInfo": null,
25
+ "StreetDirPrefix": null,
26
+ "BedsTotal": 3,
27
+ "StreetDirSuffix": null,
28
+ "ListingKey": "20060725224713296297000000",
29
+ "ListOfficeName": "Century 21 On The Lake",
30
+ "BathsHalf": null,
31
+ "ModificationTimestamp": "2011-01-05T14:54:42Z",
32
+ "CountyOrParish": "Boundary"
33
+ },
34
+ "Permissions": {
35
+ "AvailableStatusChanges": ["A","C","D","E","P"],
36
+ "Editable": true,
37
+ "EditableSettings": {"StatusChange":true,"PriceChange":true, "Photos":false }
38
+ },
39
+ "Id": "20060725224713296297000000"
40
+ }
41
+ ],
42
+ "Success": true
43
+ }
44
+ }
@@ -33,7 +33,8 @@ def stub_api_delete(service_path, stub_fixture="success.json", opts={})
33
33
  log_stub(s)
34
34
  end
35
35
  def stub_api_post(service_path, body, stub_fixture="success.json", opts={})
36
- body_str = JSON.parse(fixture(body).read).to_json
36
+ body_hash = JSON.parse(fixture(body).read)
37
+ body_str = body_hash.to_json
37
38
  params = {:ApiUser => "foobar", :AuthToken => "c401736bf3d3f754f07c04e460e09573"}.merge(opts)
38
39
  sig = $test_client.authenticator.sign_token("/#{FlexmlsApi.version}#{service_path}", params, body_str)
39
40
  s=stub_request(:post, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}#{service_path}").
@@ -50,7 +51,8 @@ def stub_api_post(service_path, body, stub_fixture="success.json", opts={})
50
51
  log_stub(s)
51
52
  end
52
53
  def stub_api_put(service_path, body, stub_fixture="success.json", opts={})
53
- body_str = JSON.parse(fixture(body).read).to_json
54
+ body_hash = JSON.parse(fixture(body).read)
55
+ body_str = body_hash.to_json
54
56
  params = {:ApiUser => "foobar", :AuthToken => "c401736bf3d3f754f07c04e460e09573"}.merge(opts)
55
57
  sig = $test_client.authenticator.sign_token("/#{FlexmlsApi.version}#{service_path}", params, body_str)
56
58
  s=stub_request(:put, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}#{service_path}").
@@ -68,7 +70,7 @@ def stub_api_put(service_path, body, stub_fixture="success.json", opts={})
68
70
  end
69
71
 
70
72
  def log_stub(s)
71
- FlexmlsApi.logger.debug("Stubbed Request: #{s.inspect}")
73
+ FlexmlsApi.logger.debug("Stubbed Request: #{s.inspect} \n\n")
72
74
  end
73
75
 
74
76
  def mock_session()
@@ -96,7 +96,7 @@ describe FlexmlsApi::Authentication::ApiAuth do
96
96
  with(:query => {
97
97
  :ApiSig => "1cb789831f8f4c6925dc708c93762a2c",
98
98
  :AuthToken => "1234"}.merge(args)).
99
- to_return(:body => fixture("listing_no_subresources.json"))
99
+ to_return(:body => fixture("listings/no_subresources.json"))
100
100
  subject.session = session
101
101
  subject.request(:get, "/#{FlexmlsApi.version}/listings", nil, args).status.should eq(200)
102
102
  end
@@ -129,6 +129,15 @@ describe FlexmlsApi::Authentication::ApiAuth do
129
129
  end
130
130
  end
131
131
 
132
+ describe "sign_token" do
133
+ let(:client) { FlexmlsApi::Client.new({:api_key => "my_key", :api_secret => "my_secret"}) }
134
+ subject {FlexmlsApi::Authentication::ApiAuth.new(client) }
135
+ it "should fully sign the token" do
136
+ parms = {:AuthToken => "1234", :ApiUser => "CoolAsIce"}
137
+ subject.sign_token("/test", parms).should eq("7bbe3384a8b64368357f8551cab271e3")
138
+ end
139
+ end
140
+
132
141
  context "when the server says the session is expired (even if we disagree)" do
133
142
  it "should reset the session and reauthenticate" do
134
143
  reset_config
@@ -149,7 +158,7 @@ describe FlexmlsApi::Authentication::ApiAuth do
149
158
  :_expand => "Documents"
150
159
  }).
151
160
  to_return(:body => fixture('errors/expired.json'), :status => 401).times(1).then.
152
- to_return(:body => fixture('listing_with_documents.json'))
161
+ to_return(:body => fixture('listings/with_documents.json'))
153
162
  l = Listing.find('1234', :_expand => "Documents")
154
163
 
155
164
  count.should eq(2)
@@ -0,0 +1,10 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe FlexmlsApi::Authentication::BaseAuth do
4
+ subject {FlexmlsApi::Authentication::BaseAuth.new(nil) }
5
+ it "should raise an error" do
6
+ expect {subject.authenticate()}.to raise_error(){ |e| e.message.should == "Implement me!"}
7
+ expect {subject.logout()}.to raise_error(){ |e| e.message.should == "Implement me!"}
8
+ expect {subject.request(nil, nil, nil, nil)}.to raise_error(){ |e| e.message.should == "Implement me!"}
9
+ end
10
+ end
@@ -75,7 +75,7 @@ describe FlexmlsApi::Authentication::OAuth2 do
75
75
  }
76
76
  c = stub_request(:get, "https://api.flexmls.com/#{FlexmlsApi.version}/listings").
77
77
  with(:query => args).
78
- to_return(:body => fixture("listing_no_subresources.json"))
78
+ to_return(:body => fixture("listings/no_subresources.json"))
79
79
  subject.session = session
80
80
  subject.request(:get, "/#{FlexmlsApi.version}/listings", nil, args).status.should eq(200)
81
81
  end
@@ -118,7 +118,7 @@ describe FlexmlsApi::Authentication::OAuth2 do
118
118
  # Fail the first time, but then return the correct value after reauthentication
119
119
  stub_request(:get, "https://api.flexmls.com/#{FlexmlsApi.version}/listings/1234").
120
120
  to_return(:body => fixture('errors/expired.json'), :status => 401).times(1).then.
121
- to_return(:body => fixture('listing_with_documents.json'))
121
+ to_return(:body => fixture('listings/with_documents.json'))
122
122
  client.get("/listings/1234")
123
123
  count.should eq(1)
124
124
  refresh_count.should eq(1)
@@ -138,7 +138,7 @@ describe FlexmlsApi::Authentication::OAuth2 do
138
138
  # Fail the first time, but then return the correct value after reauthentication
139
139
  stub_request(:get, "https://api.flexmls.com/#{FlexmlsApi.version}/listings/1234").
140
140
  to_return(:body => fixture('errors/expired.json'), :status => 401).times(1).then.
141
- to_return(:body => fixture('listing_with_documents.json'))
141
+ to_return(:body => fixture('listings/with_documents.json'))
142
142
 
143
143
  client.get("/listings/1234")
144
144
  count.should eq(2)
@@ -0,0 +1,70 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe FlexmlsApi::Configuration::YamlConfig, "Yaml Config" do
4
+ describe "api auth" do
5
+ let(:api_file){ "spec/config/flexmls_api/test_key.yml" }
6
+ it "should load a configured api key for development" do
7
+ subject.stub(:env){ {} }
8
+ subject.api_env.should eq("development")
9
+ subject.load_file(api_file)
10
+ subject.oauth2?.should eq(false)
11
+ subject.api_key.should eq("demo_key")
12
+ subject.api_secret.should eq("t3sts3cr3t")
13
+ subject.endpoint.should eq("http://api.dev.flexmls.com")
14
+ subject.name.should eq("test_key")
15
+ subject.client_keys.keys.should =~ [:api_key, :api_secret, :endpoint]
16
+ subject.oauth2_keys.keys.should eq([])
17
+ end
18
+ it "should load a configured api key for production" do
19
+ subject.stub(:env){ {"FLEXMLS_API_ENV" => "production"} }
20
+ subject.api_env.should eq("production")
21
+ subject.load_file(api_file)
22
+ subject.oauth2?.should eq(false)
23
+ subject.api_key.should eq("prod_demo_key")
24
+ subject.api_secret.should eq("prod_t3sts3cr3t")
25
+ subject.endpoint.should eq("http://api.test.flexmls.com")
26
+ end
27
+ it "should raise an error for a bad configuration" do
28
+ subject.stub(:env){ {} }
29
+ expect { subject.load_file("spec/config/flexmls_api/some_random_key.yml")}.to raise_error
30
+ subject.stub(:env){ {"RAILS_ENV" => "fake_env"} }
31
+ expect { subject.load_file(api_file)}.to raise_error
32
+ end
33
+ end
34
+ describe "oauth2" do
35
+ let(:oauth2_file){ "spec/config/flexmls_api/test_oauth.yml" }
36
+ it "should load a configured api key for development" do
37
+ subject.stub(:env){ {} }
38
+ subject.api_env.should eq("development")
39
+ subject.load_file(oauth2_file)
40
+ subject.oauth2?.should eq(true)
41
+ subject.authorization_uri.should eq("https://dev.flexmls.com/r/login/")
42
+ subject.access_uri.should eq("https://api.dev.flexmls.com/v1/oauth2/grant")
43
+ subject.redirect_uri.should eq("http://localhost/oauth2/callback")
44
+ subject.client_id.should eq("developmentid124nj4qu3pua")
45
+ subject.client_secret.should eq("developmentsecret4orkp29f")
46
+ subject.endpoint.should eq("http://api.dev.flexmls.com")
47
+ subject.name.should eq("test_oauth")
48
+ subject.client_keys.keys.should eq([:endpoint])
49
+ subject.oauth2_keys.keys.should =~ [:authorization_uri, :client_id, :access_uri, :client_secret, :redirect_uri]
50
+ end
51
+ it "should load a configured api key for production" do
52
+ subject.stub(:env){ {"FLEXMLS_API_ENV" => "production"} }
53
+ subject.api_env.should eq("production")
54
+ subject.load_file(oauth2_file)
55
+ subject.oauth2?.should eq(true)
56
+ subject.authorization_uri.should eq("https://www.flexmls.com/r/login/")
57
+ subject.access_uri.should eq("https://api.flexmls.com/v1/oauth2/grant")
58
+ subject.redirect_uri.should eq("http://localhost/oauth2/callback")
59
+ subject.client_id.should eq("production1id124nj4qu3pua")
60
+ subject.client_secret.should eq("productionsecret4orkp29fv")
61
+ subject.endpoint.should eq("http://api.flexmls.com")
62
+ subject.name.should eq("test_oauth")
63
+ end
64
+
65
+ it "should list available keys" do
66
+ FlexmlsApi::Configuration::YamlConfig.stub(:config_path) { "spec/config/flexmls_api" }
67
+ subject.class.config_keys.should =~ ["test_key", "test_oauth"]
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,19 @@
1
+ require './spec/spec_helper'
2
+
3
+
4
+ describe Constraint do
5
+
6
+ subject do
7
+ Constraint.new(
8
+ "RuleValue" => 1000000.0,
9
+ "Value" => 1000001.0,
10
+ "RuleFieldValue" => 1.0,
11
+ "RuleField" => "ListPrice",
12
+ "RuleName" => "MaxValue")
13
+ end
14
+
15
+ it "should print to string" do
16
+ subject.to_s.should eq("MaxValue: Field(ListPrice,1.0) Value(1000000.0,1000001.0)")
17
+ end
18
+
19
+ end
@@ -12,7 +12,7 @@ describe Contact do
12
12
  end
13
13
 
14
14
  it "should get all my contacts" do
15
- stub_api_get("/contacts", 'contacts.json')
15
+ stub_api_get("/contacts", 'contacts/contacts.json')
16
16
  contacts = Contact.get
17
17
  contacts.should be_an(Array)
18
18
  contacts.length.should eq(3)
@@ -20,7 +20,7 @@ describe Contact do
20
20
  end
21
21
 
22
22
  it "should get a single contact when using #my" do
23
- stub_api_get("/my/contact", 'contact_my.json')
23
+ stub_api_get("/my/contact", 'contacts/my.json')
24
24
  contact = Contact.my
25
25
  contact.should be_a(Contact)
26
26
  contact.Id.should == '20090928182824338901000000'
@@ -28,7 +28,7 @@ describe Contact do
28
28
  end
29
29
 
30
30
  it "should get all my Tags" do
31
- stub_api_get("/contacts/tags", 'contact_tags.json')
31
+ stub_api_get("/contacts/tags", 'contacts/tags.json')
32
32
  tags = Contact.tags
33
33
  tags.should be_an(Array)
34
34
  tags.length.should eq(4)
@@ -36,7 +36,7 @@ describe Contact do
36
36
  end
37
37
 
38
38
  it "should get all my Tags" do
39
- stub_api_get("/contacts/tags/IDX%20Lead", 'contacts.json')
39
+ stub_api_get("/contacts/tags/IDX%20Lead", 'contacts/contacts.json')
40
40
  contacts = Contact.by_tag("IDX Lead")
41
41
  contacts.should be_an(Array)
42
42
  contacts.length.should eq(3)
@@ -45,7 +45,7 @@ describe Contact do
45
45
  end
46
46
 
47
47
  it "should save a new contact" do
48
- stub_api_post("/contacts", 'contact_new.json', 'contacts_post.json')
48
+ stub_api_post("/contacts", 'contacts/new.json', 'contacts/post.json')
49
49
  c=Contact.new
50
50
  c.attributes["DisplayName"] = "Contact Four"
51
51
  c.attributes["PrimaryEmail"] = "contact4@fbsdata.com"
@@ -54,7 +54,7 @@ describe Contact do
54
54
  end
55
55
 
56
56
  it "should save a new contact and notify" do
57
- stub_api_post("/contacts", 'contact_new_notify.json', 'contacts_post.json')
57
+ stub_api_post("/contacts", 'contacts/new_notify.json', 'contacts/post.json')
58
58
  c=Contact.new
59
59
  c.notify=true
60
60
  c.attributes["DisplayName"] = "Contact Four"
@@ -64,7 +64,7 @@ describe Contact do
64
64
  end
65
65
 
66
66
  it "should fail saving" do
67
- stub_api_post("/contacts", 'contact_new_empty.json') do |request|
67
+ stub_api_post("/contacts", 'contacts/new_empty.json') do |request|
68
68
  request.to_return(:status => 400, :body => fixture('errors/failure.json'))
69
69
  end
70
70
 
@@ -75,7 +75,7 @@ describe Contact do
75
75
 
76
76
  context "on an epic fail" do
77
77
  it "should fail saving and asplode" do
78
- stub_api_post("/contacts", 'contact_new_empty.json') do |request|
78
+ stub_api_post("/contacts", 'contacts/new_empty.json') do |request|
79
79
  request.to_return(:status => 500, :body => fixture('errors/failure.json'))
80
80
  end
81
81