flexmls_api 0.4.5 → 0.6.4

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 (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