flexmls_api 0.4.5 → 0.6.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/Gemfile +2 -17
  2. data/Gemfile.lock +35 -27
  3. data/README.md +23 -1
  4. data/Rakefile +18 -5
  5. data/VERSION +1 -1
  6. data/bin/flexmls_api +8 -0
  7. data/lib/flexmls_api.rb +2 -0
  8. data/lib/flexmls_api/authentication.rb +5 -6
  9. data/lib/flexmls_api/authentication/api_auth.rb +4 -2
  10. data/lib/flexmls_api/authentication/oauth2.rb +51 -99
  11. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_base.rb +85 -0
  12. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_code.rb +48 -0
  13. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_password.rb +45 -0
  14. data/lib/flexmls_api/authentication/oauth2_impl/grant_type_refresh.rb +36 -0
  15. data/lib/flexmls_api/authentication/oauth2_impl/middleware.rb +39 -0
  16. data/lib/flexmls_api/cli.rb +132 -0
  17. data/lib/flexmls_api/cli/api_auth.rb +8 -0
  18. data/lib/flexmls_api/cli/oauth2.rb +43 -0
  19. data/lib/flexmls_api/cli/setup.rb +44 -0
  20. data/lib/flexmls_api/configuration.rb +6 -6
  21. data/lib/flexmls_api/faraday.rb +11 -21
  22. data/lib/flexmls_api/models.rb +3 -0
  23. data/lib/flexmls_api/models/account.rb +48 -5
  24. data/lib/flexmls_api/models/base.rb +27 -2
  25. data/lib/flexmls_api/models/contact.rb +28 -9
  26. data/lib/flexmls_api/models/listing_cart.rb +72 -0
  27. data/lib/flexmls_api/models/note.rb +0 -2
  28. data/lib/flexmls_api/models/saved_search.rb +16 -0
  29. data/lib/flexmls_api/models/shared_listing.rb +35 -0
  30. data/lib/flexmls_api/multi_client.rb +37 -0
  31. data/lib/flexmls_api/paginate.rb +5 -0
  32. data/lib/flexmls_api/request.rb +7 -3
  33. data/script/console +6 -0
  34. data/script/example.rb +27 -0
  35. data/spec/fixtures/accounts/all.json +160 -0
  36. data/spec/fixtures/accounts/my.json +74 -0
  37. data/spec/fixtures/accounts/my_portal.json +20 -0
  38. data/spec/fixtures/accounts/my_put.json +5 -0
  39. data/spec/fixtures/accounts/my_save.json +5 -0
  40. data/spec/fixtures/accounts/office.json +142 -0
  41. data/spec/fixtures/base.json +13 -0
  42. data/spec/fixtures/contact_my.json +19 -0
  43. data/spec/fixtures/contact_new.json +11 -0
  44. data/spec/fixtures/contact_new_empty.json +8 -0
  45. data/spec/fixtures/contact_new_notify.json +11 -0
  46. data/spec/fixtures/contact_tags.json +11 -0
  47. data/spec/fixtures/contacts.json +6 -3
  48. data/spec/fixtures/contacts_post.json +10 -0
  49. data/spec/fixtures/empty.json +3 -0
  50. data/spec/fixtures/errors/failure.json +5 -0
  51. data/spec/fixtures/listing_cart.json +19 -0
  52. data/spec/fixtures/listing_cart_add_listing.json +13 -0
  53. data/spec/fixtures/listing_cart_add_listing_post.json +5 -0
  54. data/spec/fixtures/listing_cart_empty.json +5 -0
  55. data/spec/fixtures/listing_cart_new.json +12 -0
  56. data/spec/fixtures/listing_cart_post.json +10 -0
  57. data/spec/fixtures/listing_cart_remove_listing.json +13 -0
  58. data/spec/fixtures/note_new.json +5 -0
  59. data/spec/fixtures/{oauth2_access.json → oauth2/access.json} +0 -0
  60. data/spec/fixtures/oauth2/access_with_old_refresh.json +5 -0
  61. data/spec/fixtures/oauth2/access_with_refresh.json +5 -0
  62. data/spec/fixtures/oauth2/authorization_code_body.json +7 -0
  63. data/spec/fixtures/oauth2/error.json +3 -0
  64. data/spec/fixtures/oauth2/password_body.json +7 -0
  65. data/spec/fixtures/oauth2/refresh_body.json +7 -0
  66. data/spec/fixtures/saved_search.json +17 -0
  67. data/spec/fixtures/shared_listing_new.json +9 -0
  68. data/spec/fixtures/shared_listing_post.json +10 -0
  69. data/spec/mock_helper.rb +123 -0
  70. data/spec/oauth2_helper.rb +69 -0
  71. data/spec/spec_helper.rb +1 -57
  72. data/spec/unit/flexmls_api/authentication/api_auth_spec.rb +1 -0
  73. data/spec/unit/flexmls_api/authentication/oauth2_impl/grant_type_base_spec.rb +10 -0
  74. data/spec/unit/flexmls_api/authentication/oauth2_spec.rb +74 -79
  75. data/spec/unit/flexmls_api/configuration_spec.rb +25 -4
  76. data/spec/unit/flexmls_api/models/account_spec.rb +152 -85
  77. data/spec/unit/flexmls_api/models/base_spec.rb +69 -25
  78. data/spec/unit/flexmls_api/models/contact_spec.rb +48 -34
  79. data/spec/unit/flexmls_api/models/document_spec.rb +1 -7
  80. data/spec/unit/flexmls_api/models/listing_cart_spec.rb +114 -0
  81. data/spec/unit/flexmls_api/models/listing_spec.rb +8 -56
  82. data/spec/unit/flexmls_api/models/note_spec.rb +8 -38
  83. data/spec/unit/flexmls_api/models/photo_spec.rb +1 -11
  84. data/spec/unit/flexmls_api/models/saved_search_spec.rb +34 -0
  85. data/spec/unit/flexmls_api/models/shared_listing_spec.rb +30 -0
  86. data/spec/unit/flexmls_api/models/standard_fields_spec.rb +50 -30
  87. data/spec/unit/flexmls_api/models/tour_of_home_spec.rb +1 -7
  88. data/spec/unit/flexmls_api/models/video_spec.rb +1 -10
  89. data/spec/unit/flexmls_api/models/virtual_tour_spec.rb +1 -7
  90. data/spec/unit/flexmls_api/multi_client_spec.rb +48 -0
  91. data/spec/unit/flexmls_api/request_spec.rb +42 -5
  92. metadata +239 -93
  93. data/spec/unit/flexmls_api/standard_fields_spec.rb +0 -86
@@ -2,7 +2,6 @@ require './spec/spec_helper'
2
2
 
3
3
  describe Note do
4
4
 
5
-
6
5
  it "responds to instance and class methods" do
7
6
  Note.should respond_to(:get)
8
7
  Note.new.should respond_to(:save)
@@ -21,48 +20,27 @@ describe Note do
21
20
  end
22
21
 
23
22
  it "should get my notes" do
24
- stub_request(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}#{@note.path}").
25
- with(:query => {
26
- :ApiSig => '8b00f10700a479b86acd03776cfea34f',
27
- :AuthToken => 'c401736bf3d3f754f07c04e460e09573',
28
- :ApiUser => 'foobar'
29
- }).
30
- to_return(:body => fixture('agent_shared_note.json'))
23
+ stub_api_get("#{@note.path}", 'agent_shared_note.json')
31
24
  ret = @note.get
32
25
  ret.Note.should == "lorem ipsum dolor sit amet"
33
26
  end
34
27
 
35
28
  it "should return a nil when no shared notes exist" do
36
- stub_request(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}#{@note.path}").
37
- with(:query => {
38
- :ApiSig => '8b00f10700a479b86acd03776cfea34f',
39
- :AuthToken => 'c401736bf3d3f754f07c04e460e09573',
40
- :ApiUser => 'foobar'
41
- }).
42
- to_return(:body => fixture('agent_shared_note_empty.json'))
29
+ stub_api_get("#{@note.path}", 'agent_shared_note_empty.json')
43
30
  @note.get.should be_nil
44
31
  end
45
32
 
46
33
  it "should allow you to delete an existing note" do
47
- stub_request(:delete, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}#{@note.path}").
48
- with(:query => {
49
- :ApiSig => '8b00f10700a479b86acd03776cfea34f',
50
- :ApiUser => 'foobar',
51
- :AuthToken => 'c401736bf3d3f754f07c04e460e09573'
52
- }).
53
- to_return(:body => fixture('generic_delete.json'))
34
+ stub_api_delete("#{@note.path}", 'generic_delete.json')
54
35
  @note.new.delete # test that no exceptions are raised
55
36
  end
56
37
 
57
38
  it "should raise an exception when adding a note fails" do
58
39
  n = @note.new(:Note => "lorem ipsum dolor")
59
- stub_request(:put, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}#{@note.path}").
60
- with(:query => {
61
- :ApiSig => '1e8bcca11ab7307ca99463f199a58c7d',
62
- :ApiUser => 'foobar',
63
- :AuthToken => 'c401736bf3d3f754f07c04e460e09573'
64
- }).
65
- to_return(:status => 500, :body => fixture('generic_failure.json'))
40
+
41
+ stub_api_put("#{@note.path}", 'note_new.json') do |request|
42
+ request.to_return(:status => 500, :body => fixture('generic_failure.json'))
43
+ end
66
44
 
67
45
  expect { n.save! }.to raise_error(FlexmlsApi::ClientError) { |e| e.status.should == 500 }
68
46
  expect { n.save }.to raise_error(FlexmlsApi::ClientError) { |e| e.status.should == 500 }
@@ -70,15 +48,7 @@ describe Note do
70
48
 
71
49
  it "should allow adding of a note" do
72
50
  n = @note.new(:Note => "lorem ipsum dolor")
73
-
74
- stub_request(:put, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}#{@note.path}").
75
- with(:query => {
76
- :ApiSig => '1e8bcca11ab7307ca99463f199a58c7d',
77
- :ApiUser => 'foobar',
78
- :AuthToken => 'c401736bf3d3f754f07c04e460e09573'
79
- }).
80
- to_return(:body => fixture('add_note.json'))
81
-
51
+ stub_api_put("#{@note.path}", 'note_new.json', 'add_note.json')
82
52
  n.save
83
53
  n.ResourceUri.should == '/v1/listings/20100909200152674436000000/shared/notes/contacts/20110407212043616271000000/'
84
54
  end
@@ -19,7 +19,6 @@ describe Photo do
19
19
 
20
20
  end
21
21
 
22
-
23
22
  it "responds to" do
24
23
  @photo.should respond_to(:primary?)
25
24
  Photo.should respond_to(:find_by_listing_key)
@@ -34,26 +33,17 @@ describe Photo do
34
33
  describe "find photos by listing id" do
35
34
  before do
36
35
  stub_auth_request
37
- stub_request(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}/listings/1234/photos").
38
- with(:query => {
39
- :ApiSig => "d060aa12d3ef573aff7298302e0237fa",
40
- :AuthToken => "c401736bf3d3f754f07c04e460e09573",
41
- :ApiUser => "foobar"
42
- }).
43
- to_return(:body => fixture('listing_photos_index.json'))
36
+ stub_api_get('/listings/1234/photos', 'listing_photos_index.json')
44
37
  end
45
38
 
46
39
  it "should get an array of photos" do
47
40
  p = Photo.find_by_listing_key('1234')
48
41
  p.should be_an(Array)
49
42
  end
50
-
51
43
  end
52
44
 
53
-
54
45
  after(:each) do
55
46
  @photo = nil
56
47
  end
57
48
 
58
-
59
49
  end
@@ -0,0 +1,34 @@
1
+ require './spec/spec_helper'
2
+
3
+ describe SavedSearch do
4
+
5
+ before(:each) do
6
+ stub_auth_request
7
+ end
8
+
9
+ let(:id){ "20100815220615294367000000" }
10
+
11
+ it "should get all SavedSearches" do
12
+ stub_api_get("/#{subject.class.element_name}", 'saved_search.json')
13
+ resources = subject.class.get
14
+ resources.should be_an(Array)
15
+ resources.length.should eq(2)
16
+ resources.first.Id.should eq(id)
17
+ end
18
+
19
+ it "should get a SavedSearch" do
20
+ stub_api_get("/#{subject.class.element_name}/#{id}", 'saved_search.json')
21
+ resource = subject.class.find(id)
22
+ resource.Id.should eq(id)
23
+ resource.Name.should eq("Search name here")
24
+ end
25
+
26
+ it "should get provided SavedSearches" do
27
+ stub_api_get("/provided/#{subject.class.element_name}", 'saved_search.json')
28
+ resources = subject.class.provided.get
29
+ resources.should be_an(Array)
30
+ resources.length.should eq(2)
31
+ resources.first.Id.should eq(id)
32
+ end
33
+
34
+ end
@@ -0,0 +1,30 @@
1
+ require './spec/spec_helper'
2
+
3
+
4
+ describe SharedListing do
5
+ before(:each) do
6
+ stub_auth_request
7
+ end
8
+
9
+ it "should respond to the finders" do
10
+ SharedListing.should respond_to(:find)
11
+ end
12
+
13
+ it "should save shared listings" do
14
+ stub_api_post("/#{subject.class.element_name}", 'shared_listing_new.json', 'shared_listing_post.json')
15
+ subject.ListingIds = ["20110224152431857619000000","20110125122333785431000000"]
16
+ subject.ViewId = "20080125122333787615000000"
17
+ subject.save.should be(true)
18
+ subject.ResourceUri.should eq("http://www.flexmls.com/share/15Ar/3544-N-Olsen-Avenue-Tucson-AZ-85719")
19
+ end
20
+
21
+ it "should fail saving" do
22
+ stub_api_post("/#{subject.class.element_name}",'empty.json') do |request|
23
+ request.to_return(:status => 400, :body => fixture('errors/failure.json'))
24
+ end
25
+ subject
26
+ subject.save.should be(false)
27
+ expect{ subject.save! }.to raise_error(FlexmlsApi::ClientError){ |e| e.status.should == 400 }
28
+ end
29
+
30
+ end
@@ -1,42 +1,62 @@
1
1
  require './spec/spec_helper'
2
2
 
3
3
  describe StandardFields do
4
+
4
5
  before(:each) do
5
- @stdfields = StandardFields.new({
6
- "StreetNumber"=>{"Searchable"=>false},
7
- "ListingId"=>{"Searchable"=>true},
8
- "City"=>{"Searchable"=>true},
9
- "Longitude"=>{"Searchable"=>false},
10
- "StreetName"=>{"Searchable"=>false},
11
- "YearBuilt"=>{"Searchable"=>true},
12
- "BuildingAreaTotal"=>{"Searchable"=>true},
13
- "PublicRemarks"=>{"Searchable"=>false},
14
- "PostalCode"=>{"Searchable"=>true},
15
- "ListPrice"=>{"Searchable"=>true},
16
- "BathsThreeQuarter"=>{"Searchable"=>true},
17
- "Latitude"=>{"Searchable"=>false},
18
- "StreetDirPrefix"=>{"Searchable"=>false},
19
- "StreetAdditionalInfo"=>{"Searchable"=>false},
20
- "PropertyType"=>{"Searchable"=>true},
21
- "StateOrProvince"=>{"Searchable"=>true},
22
- "BathsTotal"=>{"Searchable"=>true},
23
- "BathsFull"=>{"Searchable"=>true},
24
- "ListingKey"=>{"Searchable"=>false},
25
- "StreetDirSuffix"=>{"Searchable"=>false},
26
- "BedsTotal"=>{"Searchable"=>true},
27
- "ModificationTimestamp"=>{"Searchable"=>false},
28
- "BathsHalf"=>{"Searchable"=>true},
29
- "CountyOrParish"=>{"Searchable"=>true}
30
- })
6
+ stub_auth_request
31
7
  end
32
8
 
9
+
33
10
  it "should respond to get" do
34
11
  StandardFields.should respond_to(:get)
35
12
  end
36
-
37
13
 
38
- after(:each) do
39
- @stdfields = nil
14
+
15
+ it "should find and expand all" do
16
+ StandardFields.should respond_to(:find_and_expand_all)
17
+
18
+ # stub request to standardFields
19
+ stub_api_get('/standardfields','standardfields.json')
20
+
21
+ # stub request for City
22
+ stub_api_get('/standardfields/City','standardfields_city.json')
23
+
24
+ # stub request for StateOrProvince
25
+ stub_api_get('/standardfields/StateOrProvince','standardfields_stateorprovince.json')
26
+
27
+ # request
28
+ fields = StandardFields.find_and_expand_all(["City","StateOrProvince"])
29
+
30
+ # keys are present
31
+ fields.should have_key("City")
32
+ fields.should have_key("StateOrProvince")
33
+ fields.should_not have_key("SubdivisionName")
34
+
35
+ # FieldList
36
+ fields["City"]["FieldList"].length.should eq(235)
37
+ fields["StateOrProvince"]["FieldList"].length.should eq(5)
38
+
40
39
  end
40
+
41
+
42
+ it "should find nearby fields" do
43
+ StandardFields.should respond_to(:find_nearby)
44
+
45
+ # stub request
46
+ stub_api_get('/standardfields/nearby/A','standardfields_nearby.json',
47
+ :Lat => "50",
48
+ :Lon => "-92",
49
+ :_expand => "1")
50
+
51
+ # request
52
+ fields = StandardFields.find_nearby(["A"], {:Lat => 50, :Lon => -92})
53
+
54
+ # validate response
55
+ fields["D"]["Success"].should eq(true)
56
+ fields["D"]["Results"].first.should have_key("City")
57
+ fields["D"]["Results"].first.should have_key("PostalCode")
58
+ fields["D"]["Results"].first.should have_key("StateOrProvince")
41
59
 
42
- end
60
+ end
61
+
62
+ end
@@ -28,13 +28,7 @@ describe TourOfHome do
28
28
 
29
29
  it "should get home tours for a listing" do
30
30
  stub_auth_request
31
- stub_request(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}/listings/20060725224713296297000000/tourofhomes").
32
- with( :query => {
33
- :ApiSig => "153446de6d1db765d541587d34ed0fcf",
34
- :AuthToken => "c401736bf3d3f754f07c04e460e09573",
35
- :ApiUser => "foobar"
36
- }).
37
- to_return(:body => fixture('tour_of_homes.json'))
31
+ stub_api_get('/listings/20060725224713296297000000/tourofhomes','tour_of_homes.json')
38
32
  v = subject.class.find_by_listing_key('20060725224713296297000000')
39
33
  v.should be_an(Array)
40
34
  v.length.should == 2
@@ -18,13 +18,7 @@ describe Video do
18
18
  describe "find videos by listing id" do
19
19
  before do
20
20
  stub_auth_request
21
- stub_request(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}/listings/1234/videos").
22
- with(:query => {
23
- :ApiSig => "c95bfef766128b91a2643fcc2fa40dfc",
24
- :AuthToken => "c401736bf3d3f754f07c04e460e09573",
25
- :ApiUser => "foobar"
26
- }).
27
- to_return(:body => fixture('listing_videos_index.json'))
21
+ stub_api_get('/listings/1234/videos','listing_videos_index.json')
28
22
  end
29
23
 
30
24
  it "should get an array of videos" do
@@ -35,7 +29,4 @@ describe Video do
35
29
 
36
30
  end
37
31
 
38
-
39
-
40
-
41
32
  end
@@ -24,13 +24,7 @@ describe VirtualTour do
24
24
 
25
25
  it "should get virtual tours for a listing" do
26
26
  stub_auth_request
27
- stub_request(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}/listings/1234/virtualtours").
28
- with( :query => {
29
- :ApiSig => "1cb60934d68b64e5eaaab4aff4b7cd3a",
30
- :AuthToken => "c401736bf3d3f754f07c04e460e09573",
31
- :ApiUser => "foobar"
32
- }).
33
- to_return(:body => fixture('listing_virtual_tours_index.json'))
27
+ stub_api_get('/listings/1234/virtualtours','listing_virtual_tours_index.json')
34
28
 
35
29
  v = VirtualTour.find_by_listing_key('1234')
36
30
  v.should be_an(Array)
@@ -0,0 +1,48 @@
1
+ require './spec/spec_helper'
2
+
3
+ # Test client implemenations for multi client switching
4
+ module FlexmlsApi
5
+ def self.test_client_a
6
+ Client.new(:api_key => "a")
7
+ end
8
+ def self.test_client_b
9
+ Client.new(:api_key => "b")
10
+ end
11
+ def self.test_client_c
12
+ Client.new(:api_key => "c")
13
+ end
14
+ end
15
+
16
+ describe FlexmlsApi::MultiClient do
17
+ it "should activate a client implemenation when activate()" do
18
+ FlexmlsApi.activate(:test_client_a)
19
+ FlexmlsApi.client.api_key.should eq('a')
20
+ FlexmlsApi.activate(:test_client_b)
21
+ FlexmlsApi.client.api_key.should eq('b')
22
+ FlexmlsApi.activate(:test_client_c)
23
+ FlexmlsApi.client.api_key.should eq('c')
24
+ FlexmlsApi.activate(:test_client_a)
25
+ FlexmlsApi.client.api_key.should eq('a')
26
+ end
27
+ it "should fail to activate symbols that do not have implementations" do
28
+ expect { FlexmlsApi.activate(:test_client_d) }.to raise_error(ArgumentError)
29
+ end
30
+
31
+ it "should temporarily activate a client implemenation when activate() block" do
32
+ FlexmlsApi.activate(:test_client_a)
33
+ FlexmlsApi.client.api_key.should eq('a')
34
+ FlexmlsApi.activate(:test_client_b) do
35
+ FlexmlsApi.client.api_key.should eq('b')
36
+ end
37
+ FlexmlsApi.client.api_key.should eq('a')
38
+ expect do
39
+ FlexmlsApi.activate(:test_client_c) do
40
+ FlexmlsApi.client.api_key.should eq('c')
41
+ raise "OH MY GOODNESS I BLEW UP!!!"
42
+ end
43
+ end.to raise_error
44
+ FlexmlsApi.client.api_key.should eq('a')
45
+ end
46
+
47
+ end
48
+
@@ -2,15 +2,38 @@ require './spec/spec_helper'
2
2
 
3
3
  describe FlexmlsApi do
4
4
  describe FlexmlsApi::ClientError do
5
- subject { FlexmlsApi::ClientError.new("1234", 200) }
5
+ subject { FlexmlsApi::ClientError.new({:message=>"OMG FAIL", :code=>1234, :status=>500}) }
6
+ it "should print a helpful to_s" do
7
+ subject.to_s.should == "OMG FAIL"
8
+ subject.message.should == "OMG FAIL"
9
+ end
6
10
  it "should have an api code" do
7
- subject.code.should == "1234"
11
+ subject.code.should == 1234
8
12
  end
9
13
  it "should have an http status" do
10
- subject.status.should == 200
14
+ subject.status.should == 500
11
15
  end
12
16
  it "should raise and exception with attached message" do
13
- expect { raise subject, "My Message" }.to raise_error(FlexmlsApi::ClientError){ |e| e.message.should == "My Message" }
17
+ expect { raise subject.class, {:message=>"My Message", :code=>1000, :status=>404}}.to raise_error(FlexmlsApi::ClientError) do |e|
18
+ e.message.should == "My Message"
19
+ e.code.should == 1000
20
+ e.status.should == 404
21
+ end
22
+ expect { raise subject.class.new({:message=>"My Message", :code=>1000, :status=>404}) }.to raise_error(FlexmlsApi::ClientError) do |e|
23
+ e.message.should == "My Message"
24
+ e.code.should == 1000
25
+ e.status.should == 404
26
+ end
27
+ expect { raise subject.class.new({:code=>1000, :status=>404}), "My Message"}.to raise_error(FlexmlsApi::ClientError) do |e|
28
+ e.message.should == "My Message"
29
+ e.code.should == 1000
30
+ e.status.should == 404
31
+ end
32
+ expect { raise subject.class, "My Message"}.to raise_error(FlexmlsApi::ClientError) do |e|
33
+ e.message.should == "My Message"
34
+ e.code.should be == nil
35
+ e.status.should be == nil
36
+ end
14
37
  end
15
38
  end
16
39
 
@@ -92,6 +115,14 @@ describe FlexmlsApi do
92
115
  }]}
93
116
  }']
94
117
  }
118
+ # TEST escaped paths
119
+ stub.get('/v1/test%20path%20with%20spaces?ApiSig=SignedToken&AuthToken=1234') { [200, {}, '{"D": {
120
+ "Success": true,
121
+ "Results": []
122
+ }
123
+ }']
124
+ }
125
+
95
126
  end
96
127
  @connection = test_connection(stubs)
97
128
  end
@@ -144,6 +175,12 @@ describe FlexmlsApi do
144
175
  subject.delete('/contacts/1000').should be(nil)
145
176
  # No validation here, if no error is raised, everything is hunky dory
146
177
  end
178
+
179
+ it "should escape a path correctly" do
180
+ subject.get('/test path with spaces').length.should == 0
181
+ # now try this with an already escaped path. Kaboom!
182
+ expect { subject.get('/test%20path%20with%20spaces') }.to raise_error()
183
+ end
147
184
 
148
185
  it "should give me BigDecimal results for large floating point numbers" do
149
186
  MultiJson.default_engine.should eq(:yajl)
@@ -303,5 +340,5 @@ describe FlexmlsApi do
303
340
  end
304
341
 
305
342
  end
306
-
343
+
307
344
  end