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
@@ -0,0 +1,69 @@
1
+
2
+ # Lightweight example of an oauth2 provider used by the ruby client.
3
+ class TestOAuth2Provider < FlexmlsApi::Authentication::BaseOAuth2Provider
4
+
5
+ def initialize
6
+ @authorization_uri = "https://test.fbsdata.com/r/oauth2"
7
+ @access_uri = "https://api.test.fbsdata.com/v1/oauth2/grant"
8
+ @redirect_uri = "https://exampleapp.fbsdata.com/oauth-callback"
9
+ @client_id="example-id"
10
+ @client_secret="example-password"
11
+ @session_cache = {}
12
+ end
13
+
14
+ def redirect(url)
15
+ # User redirected to url, signs in, and gets code sent to callback
16
+ self.code="my_code"
17
+ end
18
+
19
+ def load_session()
20
+ @session_cache["test_user_session"]
21
+ end
22
+
23
+ def save_session(session)
24
+ @session_cache["test_user_session"] = session
25
+ nil
26
+ end
27
+
28
+ def session_timeout; 7200; end
29
+
30
+ end
31
+
32
+
33
+ class TestCLIOAuth2Provider < FlexmlsApi::Authentication::BaseOAuth2Provider
34
+ def initialize
35
+ @authorization_uri = "https://test.fbsdata.com/r/oauth2"
36
+ @access_uri = "https://api.test.fbsdata.com/v1/oauth2/grant"
37
+ @client_id="example-id"
38
+ @client_secret="example-secret"
39
+ @username="example-user"
40
+ @password="example-password"
41
+ @session_cache = {}
42
+ end
43
+
44
+ def grant_type
45
+ :password
46
+ end
47
+
48
+ def redirect(url)
49
+ raise "Unsupported in oauth grant_type=password mode"
50
+ end
51
+
52
+ def load_session()
53
+ @session_cache["test_user_session"]
54
+ end
55
+ def save_session(session)
56
+ @session_cache["test_user_session"] = session
57
+ nil
58
+ end
59
+ def session_timeout; 60; end
60
+ end
61
+
62
+
63
+ class InvalidAuth2Provider < FlexmlsApi::Authentication::BaseOAuth2Provider
64
+
65
+ def grant_type
66
+ :not_a_real_type
67
+ end
68
+
69
+ end
data/spec/spec_helper.rb CHANGED
@@ -3,17 +3,13 @@ require "json"
3
3
  require "rspec"
4
4
  require 'webmock/rspec'
5
5
 
6
-
7
- Rspec.configure do |config|
8
- config.include WebMock::API
9
- end
10
-
11
6
  begin require "redgreen" unless ENV['TM_CURRENT_LINE']; rescue LoadError; end
12
7
  path = File.expand_path(File.dirname(__FILE__) + "/../lib/")
13
8
  $LOAD_PATH.unshift(path) unless $LOAD_PATH.include?(path)
14
9
  require path + '/flexmls_api'
15
10
 
16
11
  require 'flexmls_api'
12
+ require File.expand_path('../mock_helper', __FILE__)
17
13
  require File.expand_path('../json_helper', __FILE__)
18
14
 
19
15
 
@@ -32,58 +28,6 @@ end
32
28
 
33
29
  FlexmlsApi.logger.info("Setup gem for rspec testing")
34
30
 
35
- def mock_session()
36
- FlexmlsApi::Authentication::Session.new("AuthToken" => "1234", "Expires" => (Time.now + 3600).to_s, "Roles" => "['idx']")
37
- end
38
-
39
- def mock_oauth_session()
40
- FlexmlsApi::Authentication::OAuthSession.new("access_token" => "1234", "expires_in" => 3600, "scope" => nil, "refresh_token"=> "1000refresh")
41
- end
42
-
43
- class MockClient < FlexmlsApi::Client
44
- attr_accessor :connection
45
-
46
- def connection(ssl = false)
47
- @connection
48
- end
49
- end
50
-
51
- class MockApiAuthenticator < FlexmlsApi::Authentication::ApiAuth
52
- # Sign a request
53
- def sign(sig)
54
- "SignedToken"
55
- end
56
- end
57
-
58
- def mock_client(stubs)
59
- c = MockClient.new
60
- c.session = mock_session()
61
- c.connection = test_connection(stubs)
62
- c
63
- end
64
-
65
- def mock_expired_session()
66
- FlexmlsApi::Authentication::Session.new("AuthToken" => "1234", "Expires" => (Time.now - 60).to_s, "Roles" => "['idx']")
67
- end
68
-
69
- def test_connection(stubs)
70
- Faraday::Connection.new(nil, {:headers => FlexmlsApi::Client.new.headers}) do |builder|
71
- builder.adapter :test, stubs
72
- builder.use Faraday::Response::ParseJson
73
- builder.use FlexmlsApi::FaradayExt::FlexmlsMiddleware
74
- end
75
- end
76
-
77
- def stub_auth_request()
78
- stub_request(:post, "https://api.flexmls.com/#{FlexmlsApi.version}/session").
79
- with(:query => {:ApiKey => "", :ApiSig => "806737984ab19be2fd08ba36030549ac"}).
80
- to_return(:body => fixture("session.json"))
81
- end
82
-
83
- def fixture(file)
84
- File.new(File.expand_path("../fixtures", __FILE__) + '/' + file)
85
- end
86
-
87
31
  def reset_config()
88
32
  FlexmlsApi.reset
89
33
  FlexmlsApi.configure do |config|
@@ -131,6 +131,7 @@ describe FlexmlsApi::Authentication::ApiAuth do
131
131
 
132
132
  context "when the server says the session is expired (even if we disagree)" do
133
133
  it "should reset the session and reauthenticate" do
134
+ reset_config
134
135
  count = 0
135
136
  # Make sure the auth request goes out twice.
136
137
  stub_request(:post, "https://api.flexmls.com/#{FlexmlsApi.version}/session").
@@ -0,0 +1,10 @@
1
+ require './spec/spec_helper'
2
+ require './spec/oauth2_helper'
3
+
4
+ describe FlexmlsApi::Authentication::OAuth2Impl::GrantTypeBase do
5
+ subject { FlexmlsApi::Authentication::OAuth2Impl::GrantTypeBase }
6
+ # Make sure the client boostraps the right plugin based on configuration.
7
+ it "create should " do
8
+ expect {subject.create(nil, InvalidAuth2Provider.new())}.to raise_error(FlexmlsApi::ClientError){ |e| e.message.should == "Unsupported grant type [not_a_real_type]" }
9
+ end
10
+ end
@@ -1,34 +1,5 @@
1
1
  require './spec/spec_helper'
2
-
3
- # Lightweight example of an oauth2 provider used by the ruby client.
4
- class TestOAuth2Provider < FlexmlsApi::Authentication::BaseOAuth2Provider
5
-
6
- def initialize
7
- @authorization_uri = "https://test.fbsdata.com/r/oauth2"
8
- @access_uri = "https://api.test.fbsdata.com/v1/oauth2/grant"
9
- @redirect_uri = "https://exampleapp.fbsdata.com/oauth-callback"
10
- @client_id="example-id"
11
- @client_secret="example-password"
12
- @session_cache = {}
13
- end
14
-
15
- def redirect(url)
16
- # User redirected to url, signs in, and gets code sent to callback
17
- self.code="my_code"
18
- end
19
-
20
- def load_session()
21
- @session_cache["test_user_session"]
22
- end
23
-
24
- def save_session(session)
25
- @session_cache["test_user_session"] = session
26
- nil
27
- end
28
-
29
- def session_timeout; 7200; end
30
-
31
- end
2
+ require './spec/oauth2_helper'
32
3
 
33
4
  describe FlexmlsApi::Authentication::OAuth2 do
34
5
  let(:provider) { TestOAuth2Provider.new() }
@@ -43,30 +14,20 @@ describe FlexmlsApi::Authentication::OAuth2 do
43
14
  describe "authenticate" do
44
15
  it "should authenticate the api credentials" do
45
16
  stub_request(:post, provider.access_uri).
46
- with(:query => {
47
- :client_id => provider.client_id,
48
- :client_secret => provider.client_secret,
49
- :grant_type => "authorization_code",
50
- :redirect_uri => provider.redirect_uri,
51
- :code => "my_code"
52
- }
17
+ with(:body =>
18
+ '{"code":"my_code","client_secret":"example-password","client_id":"example-id","redirect_uri":"https://exampleapp.fbsdata.com/oauth-callback","grant_type":"authorization_code"}'
53
19
  ).
54
- to_return(:body => fixture("oauth2_access.json"), :status=>200)
20
+ to_return(:body => fixture("oauth2/access.json"), :status=>200)
55
21
  subject.authenticate.access_token.should eq("04u7h-4cc355-70k3n")
56
22
  subject.authenticate.expires_in.should eq(7200)
57
23
  end
58
24
 
59
25
  it "should raise an error when api credentials are invalid" do
60
- stub_request(:post, provider.access_uri).
61
- with(:query => {
62
- :client_id => provider.client_id,
63
- :client_secret => provider.client_secret,
64
- :grant_type => "authorization_code",
65
- :redirect_uri => provider.redirect_uri,
66
- :code => "my_code"
67
- }
26
+ s=stub_request(:post, provider.access_uri).
27
+ with(:body =>
28
+ '{"code":"my_code","client_secret":"example-password","client_id":"example-id","redirect_uri":"https://exampleapp.fbsdata.com/oauth-callback","grant_type":"authorization_code"}'
68
29
  ).
69
- to_return(:body => fixture("oauth2_error.json"), :status=>400)
30
+ to_return(:body => fixture("oauth2/error.json"), :status=>400)
70
31
  expect {subject.authenticate()}.to raise_error(FlexmlsApi::ClientError){ |e| e.status.should == 400 }
71
32
  end
72
33
 
@@ -89,6 +50,7 @@ describe FlexmlsApi::Authentication::OAuth2 do
89
50
  end
90
51
  end
91
52
 
53
+
92
54
  describe "logout" do
93
55
  let(:session) { mock_oauth_session }
94
56
  it "should logout when there is an active session" do
@@ -112,7 +74,7 @@ describe FlexmlsApi::Authentication::OAuth2 do
112
74
  :_pagination => '1'
113
75
  }
114
76
  c = stub_request(:get, "https://api.flexmls.com/#{FlexmlsApi.version}/listings").
115
- with(:query => {:access_token => "1234"}.merge(args)).
77
+ with(:query => args).
116
78
  to_return(:body => fixture("listing_no_subresources.json"))
117
79
  subject.session = session
118
80
  subject.request(:get, "/#{FlexmlsApi.version}/listings", nil, args).status.should eq(200)
@@ -122,9 +84,7 @@ describe FlexmlsApi::Authentication::OAuth2 do
122
84
  args = {}
123
85
  contact = '{"D":{"Contacts":[{"DisplayName":"Contact Four","PrimaryEmail":"contact4@fbsdata.com"}]}}'
124
86
  stub_request(:post, "https://api.flexmls.com/#{FlexmlsApi.version}/contacts").
125
- with(:query => {:access_token => "1234"}.merge(args),
126
- :body => contact
127
- ).
87
+ with(:body => contact).
128
88
  to_return(:body => '{"D": {
129
89
  "Success": true,
130
90
  "Results": [
@@ -137,41 +97,61 @@ describe FlexmlsApi::Authentication::OAuth2 do
137
97
  end
138
98
  end
139
99
 
140
- context "when the server says the session is expired (even if we disagree)" do
141
- it "should reset the session and reauthenticate" do
142
- count = 0
143
- stub_request(:post, provider.access_uri).
144
- with(:query => {
145
- :client_id => provider.client_id,
146
- :client_secret => provider.client_secret,
147
- :grant_type => "authorization_code",
148
- :redirect_uri => provider.redirect_uri,
149
- :code => "my_code"
150
- }
151
- ).
152
- to_return do
153
- count += 1
154
- {:body => fixture("oauth2_access.json"), :status=>200}
155
- end
156
- # Make sure the auth request goes out twice.
157
- # Fail the first time, but then return the correct value after reauthentication
158
- stub_request(:get, "https://api.flexmls.com/#{FlexmlsApi.version}/listings/1234").
159
- with(:query => {:access_token => "04u7h-4cc355-70k3n"}).
160
- to_return(:body => fixture('errors/expired.json'), :status => 401).times(1).then.
161
- to_return(:body => fixture('listing_with_documents.json'))
162
-
163
- client.get("/listings/1234")
164
- count.should eq(2)
165
- client.session.expired?.should eq(false)
100
+ context "with an expired session" do
101
+ context "and a valid refresh token" do
102
+ it "should reset the session and reauthenticate" do
103
+ count = 0
104
+ refresh_count = 0
105
+ stub_request(:post, provider.access_uri).
106
+ with(:body => '{"code":"my_code","client_secret":"example-password","client_id":"example-id","redirect_uri":"https://exampleapp.fbsdata.com/oauth-callback","grant_type":"authorization_code"}').
107
+ to_return do
108
+ count += 1
109
+ {:body => fixture("oauth2/access_with_old_refresh.json"), :status=>200}
110
+ end
111
+ stub_request(:post, provider.access_uri).
112
+ with(:body => '{"client_id":"example-id","client_secret":"example-password","grant_type":"refresh_token","redirect_uri":"https://exampleapp.fbsdata.com/oauth-callback","refresh_token":"0ld-r3fr35h-70k3n"}').
113
+ to_return do
114
+ refresh_count += 1
115
+ {:body => fixture("oauth2/access_with_refresh.json"), :status=>200}
116
+ end
117
+ # Make sure the auth request goes out twice.
118
+ # Fail the first time, but then return the correct value after reauthentication
119
+ stub_request(:get, "https://api.flexmls.com/#{FlexmlsApi.version}/listings/1234").
120
+ to_return(:body => fixture('errors/expired.json'), :status => 401).times(1).then.
121
+ to_return(:body => fixture('listing_with_documents.json'))
122
+ client.get("/listings/1234")
123
+ count.should eq(1)
124
+ refresh_count.should eq(1)
125
+ client.session.expired?.should eq(false)
126
+ end
127
+ end
128
+ context "and an invalid refresh token" do
129
+ it "should reset the session and reauthenticate" do
130
+ count = 0
131
+ stub_request(:post, provider.access_uri).
132
+ with(:body => '{"code":"my_code","client_secret":"example-password","client_id":"example-id","redirect_uri":"https://exampleapp.fbsdata.com/oauth-callback","grant_type":"authorization_code"}').
133
+ to_return do
134
+ count += 1
135
+ {:body => fixture("oauth2/access.json"), :status=>200}
136
+ end
137
+ # Make sure the auth request goes out twice.
138
+ # Fail the first time, but then return the correct value after reauthentication
139
+ stub_request(:get, "https://api.flexmls.com/#{FlexmlsApi.version}/listings/1234").
140
+ to_return(:body => fixture('errors/expired.json'), :status => 401).times(1).then.
141
+ to_return(:body => fixture('listing_with_documents.json'))
142
+
143
+ client.get("/listings/1234")
144
+ count.should eq(2)
145
+ client.session.expired?.should eq(false)
146
+ end
166
147
  end
167
148
  end
168
-
169
149
  end
170
150
 
171
151
  describe FlexmlsApi::Authentication::BaseOAuth2Provider do
172
152
  context "session_timeout" do
173
153
  it "should provide a default" do
174
- subject.session_timeout.should eq(3600)
154
+ subject.session_timeout.should eq(86400)
175
155
  end
176
156
  describe TestOAuth2Provider do
177
157
  subject { TestOAuth2Provider.new }
@@ -181,3 +161,18 @@ describe FlexmlsApi::Authentication::BaseOAuth2Provider do
181
161
  end
182
162
  end
183
163
  end
164
+
165
+ describe "password authentication" do
166
+ let(:provider) { TestCLIOAuth2Provider.new() }
167
+ let(:client) { FlexmlsApi::Client.new({:authentication_mode => FlexmlsApi::Authentication::OAuth2,:oauth2_provider => provider}) }
168
+ subject {client.authenticator }
169
+ it "should authenticate the api credentials with username and password" do
170
+ stub_request(:post, provider.access_uri).
171
+ with(:body =>
172
+ '{"username":"example-user","client_secret":"example-secret","client_id":"example-id","password":"example-password","grant_type":"password"}'
173
+ ).
174
+ to_return(:body => fixture("oauth2/access.json"), :status=>200)
175
+ subject.authenticate.access_token.should eq("04u7h-4cc355-70k3n")
176
+ subject.authenticate.expires_in.should eq(60)
177
+ end
178
+ end
@@ -11,7 +11,7 @@ describe FlexmlsApi::Client, "Client config" do
11
11
  FlexmlsApi.api_secret.should be_nil
12
12
  FlexmlsApi.version.should match("v1")
13
13
  FlexmlsApi.endpoint.should match("api.flexmls.com")
14
-
14
+ FlexmlsApi.user_agent.should match(/flexmls API Ruby Gem .*/)
15
15
  FlexmlsApi.api_key = "my_api_key"
16
16
  FlexmlsApi.api_key.should match("my_api_key")
17
17
  end
@@ -79,7 +79,6 @@ describe FlexmlsApi::Client, "Client config" do
79
79
  to_return(:body => '{"D":{"Success": true,"Results": [{"SSL":false}]}}')
80
80
 
81
81
  FlexmlsApi.client.get('/connections')[0]["SSL"].should eq(false)
82
-
83
82
  end
84
83
 
85
84
  it "should use https when ssl is enabled" do
@@ -90,11 +89,33 @@ describe FlexmlsApi::Client, "Client config" do
90
89
  :AuthToken => "c401736bf3d3f754f07c04e460e09573"
91
90
  }).
92
91
  to_return(:body => '{"D":{"Success": true,"Results": [{"SSL":true}]}}')
93
- c = FlexmlsApi::Client.new(:endpoint => "https://api.flexmls.com",
94
- :ssl => true)
92
+
93
+ c = FlexmlsApi::Client.new(:endpoint => "https://api.flexmls.com", :ssl => true)
95
94
  c.get('/connections')[0]["SSL"].should eq(true)
96
95
  end
97
96
 
97
+ it "should have correct headers based on configuration" do
98
+ stub_auth_request
99
+ stub_request(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}/headers").
100
+ with(:query => {
101
+ :ApiSig => "6f0cfef263e0bfe7a9ae1f60063a8ad9",
102
+ :AuthToken => "c401736bf3d3f754f07c04e460e09573"
103
+ }).
104
+ to_return(:body => '{"D":{"Success": true,"Results": []}}')
105
+ FlexmlsApi.reset
106
+ FlexmlsApi.configure do |config|
107
+ config.user_agent = "my useragent"
108
+ end
109
+ FlexmlsApi.client.get '/headers'
110
+ WebMock.should have_requested(:get, "#{FlexmlsApi.endpoint}/#{FlexmlsApi.version}/headers?ApiSig=6f0cfef263e0bfe7a9ae1f60063a8ad9&AuthToken=c401736bf3d3f754f07c04e460e09573").
111
+ with(:headers => {
112
+ 'User-Agent' => FlexmlsApi::Configuration::DEFAULT_USER_AGENT,
113
+ FlexmlsApi::Configuration::X_FLEXMLS_API_USER_AGENT => "my useragent",
114
+ 'Accept'=>'application/json',
115
+ 'Content-Type'=>'application/json'
116
+ })
117
+ end
118
+
98
119
  end
99
120
 
100
121
  end
@@ -1,96 +1,163 @@
1
1
  require './spec/spec_helper'
2
2
 
3
3
  describe Account do
4
- before(:each) do
5
- @account = Account.new({
6
- "Name"=>"Sample User",
7
- "Id"=>"20000426173054342350000000",
8
- "Office"=>"Sample Office",
9
- "Mls"=>"Sample MLS",
10
- "MlsId"=>"20000426143505724628000000",
11
- "Emails"=>[
12
- {
13
- "Type"=>"Work",
14
- "Name"=>"My Work E-mail",
15
- "Address"=>"work@test.com",
16
- "Primary"=>true
17
- },
18
- {
19
- "Type"=>"Home",
20
- "Name"=>"My Home E-mail",
21
- "Address"=>"home@test.com"
22
- }
23
- ],
24
- "Phones"=>[
25
- {
26
- "Type"=>"Work",
27
- "Name"=>"My Work Phone",
28
- "Number"=>"701-555-1212",
29
- "Primary"=>true
30
- },
31
- {
32
- "Type"=>"Home",
33
- "Name"=>"My Home Phone",
34
- "Number"=>"702-555-1313"
35
- }
36
- ],
37
- "Websites"=>[
38
- {
39
- "Type"=>"Work",
40
- "Name"=>"My Work Website",
41
- "Uri"=>"http://iamthebestagent.com",
42
- "Primary"=>true
43
- },
44
- {
45
- "Type"=>"Home",
46
- "Name"=>"My Home Website",
47
- "Uri"=>"http://myspace.com/lolcats"
48
- }
49
- ],
50
- "Addresses"=>[
51
- {
52
- "Type"=>"Work",
53
- "Name"=>"My Work Address",
54
- "Address"=>"101 Main Ave, Phoenix, AZ 12345",
55
- "Primary"=>true
56
- },
57
- {
58
- "Type"=>"Home",
59
- "Name"=>"My Home Address",
60
- "Address"=>"102 Main Ave, Gilbert, AZ 54321"
61
- }
62
- ],
63
- "Images"=>[
64
- {
65
- "Type"=>"Photo",
66
- "Name"=>"My Photo",
67
- "Uri"=>"http://photos.flexmls.com/az/...."
68
- },
69
- {
70
- "Type"=>"Logo",
71
- "Name"=>"My Logo",
72
- "Uri"=>"http://photos.flexmls.com/az/...."
73
- }
74
- ]
75
- })
4
+ describe "units" do
5
+ before(:each) do
6
+ @account = Account.new({
7
+ "Name"=>"Sample User",
8
+ "Id"=>"20000426173054342350000000",
9
+ "Office"=>"Sample Office",
10
+ "Mls"=>"Sample MLS",
11
+ "MlsId"=>"20000426143505724628000000",
12
+ "Emails"=>[
13
+ {
14
+ "Type"=>"Work",
15
+ "Name"=>"My Work E-mail",
16
+ "Address"=>"work@test.com",
17
+ "Primary"=>true
18
+ },
19
+ {
20
+ "Type"=>"Home",
21
+ "Name"=>"My Home E-mail",
22
+ "Address"=>"home@test.com"
23
+ }
24
+ ],
25
+ "Phones"=>[
26
+ {
27
+ "Type"=>"Work",
28
+ "Name"=>"My Work Phone",
29
+ "Number"=>"701-555-1212",
30
+ "Primary"=>true
31
+ },
32
+ {
33
+ "Type"=>"Home",
34
+ "Name"=>"My Home Phone",
35
+ "Number"=>"702-555-1313"
36
+ }
37
+ ],
38
+ "Websites"=>[
39
+ {
40
+ "Type"=>"Work",
41
+ "Name"=>"My Work Website",
42
+ "Uri"=>"http://iamthebestagent.com",
43
+ "Primary"=>true
44
+ },
45
+ {
46
+ "Type"=>"Home",
47
+ "Name"=>"My Home Website",
48
+ "Uri"=>"http://myspace.com/lolcats"
49
+ }
50
+ ],
51
+ "Addresses"=>[
52
+ {
53
+ "Type"=>"Work",
54
+ "Name"=>"My Work Address",
55
+ "Address"=>"101 Main Ave, Phoenix, AZ 12345",
56
+ "Primary"=>true
57
+ },
58
+ {
59
+ "Type"=>"Home",
60
+ "Name"=>"My Home Address",
61
+ "Address"=>"102 Main Ave, Gilbert, AZ 54321"
62
+ }
63
+ ],
64
+ "Images"=>[
65
+ {
66
+ "Type"=>"Photo",
67
+ "Name"=>"My Photo 1",
68
+ "Uri"=>"http://photos.flexmls.com/az/...."
69
+ },
70
+ {
71
+ "Type"=>"Photo",
72
+ "Name"=>"My Photo two",
73
+ "Uri"=>"http://photos.flexmls.com/az/...."
74
+ },
75
+ {
76
+ "Type"=>"Logo",
77
+ "Name"=>"1 My Logo",
78
+ "Uri"=>"http://photos.flexmls.com/az/...."
79
+ },
80
+ {
81
+ "Type"=>"Logo",
82
+ "Name"=>"My Other Logo",
83
+ "Uri"=>"http://photos.flexmls.com/az/...."
84
+ },
85
+ {
86
+ "Type"=>"Logo",
87
+ "Name"=>"My Logo",
88
+ "Uri"=>"http://photos.flexmls.com/az/...."
89
+ }
90
+ ]
91
+ })
92
+ end
93
+
94
+ it "should respond to attributes" do
95
+ ['Name','Id','Mls','MlsId','Office'].each do |k|
96
+ (@account.send k.to_sym).should be_a(String)
97
+ end
98
+ end
99
+
100
+ it "should have primary subresources" do
101
+ @account.emails.primary.Address.should eq("work@test.com")
102
+ @account.phones.primary.Number.should eq("701-555-1212")
103
+ @account.addresses.primary.Address.should eq("101 Main Ave, Phoenix, AZ 12345")
104
+ @account.websites.primary.Uri.should eq("http://iamthebestagent.com")
105
+ end
106
+
107
+ it "should be able to provide a primary image" do
108
+ @account.primary_img("Photo").Name.should == 'My Photo 1'
109
+ @account.primary_img("Logo").Name.should == '1 My Logo'
110
+ end
111
+
112
+ after(:each) do
113
+ @acount = nil
114
+ end
76
115
  end
77
116
 
78
- it "should respond to attributes" do
79
- ['Name','Id','Mls','MlsId','Office'].each do |k|
80
- (@account.send k.to_sym).should be_a(String)
117
+ describe "functionals" do
118
+ before(:each) do
119
+ stub_auth_request
81
120
  end
82
- end
83
121
 
84
- it "should have primary subresources" do
85
- @account.emails.primary.Address.should eq("work@test.com")
86
- @account.phones.primary.Number.should eq("701-555-1212")
87
- @account.addresses.primary.Address.should eq("101 Main Ave, Phoenix, AZ 12345")
88
- @account.websites.primary.Uri.should eq("http://iamthebestagent.com")
89
- @account.images.primary.should be(nil)
90
- end
122
+ it "should get my account" do
123
+ stub_api_get("/my/account", 'accounts/my.json')
124
+ account = Account.my
125
+ account.Id.should eq("20000426173054342350000000")
126
+ account.websites.first.Name.should == 'My Work Website'
127
+ end
128
+
129
+ it "should get all accounts" do
130
+ stub_api_get("/accounts", 'accounts/all.json')
131
+ accounts = Account.get
132
+ accounts.should be_an(Array)
133
+ accounts.length.should eq(3)
134
+ accounts.first.Id.should eq("20000426173054342350000000")
135
+ accounts.last.Id.should eq("20110126173054382350000000")
136
+ end
137
+
138
+ it "should all office accounts" do
139
+ stub_api_get("/accounts/by/office/20030426173014239760000000", 'accounts/office.json')
140
+ accounts = Account.by_office("20030426173014239760000000")
141
+ accounts.should be_an(Array)
142
+ accounts.length.should eq(2)
143
+ accounts.each do |account|
144
+ accounts.first.OfficeId.should eq("20030426173014239760000000")
145
+ end
146
+ end
147
+
148
+ it "should save my portal account" do
149
+ stub_api_get("/my/account", 'accounts/my_portal.json')
150
+ stub_api_put("/my/account", 'accounts/my_save.json', 'accounts/my_put.json')
151
+ account = Account.my
152
+ account.Id.should eq("20110426173054342350000000")
153
+ account.GetEmailUpdates.should eq(false)
154
+ account.GetEmailUpdates = true
155
+ account.save!
156
+ account.GetEmailUpdates.should eq(true)
157
+ end
91
158
 
92
- after(:each) do
93
- @acount = nil
159
+
94
160
  end
95
161
 
96
162
  end
163
+