rets-hack 0.11

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 (60) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +142 -0
  3. data/Manifest.txt +58 -0
  4. data/README.md +129 -0
  5. data/Rakefile +28 -0
  6. data/bin/rets +202 -0
  7. data/example/connect.rb +19 -0
  8. data/example/get-photos.rb +20 -0
  9. data/example/get-property.rb +16 -0
  10. data/lib/rets/client.rb +373 -0
  11. data/lib/rets/client_progress_reporter.rb +48 -0
  12. data/lib/rets/http_client.rb +133 -0
  13. data/lib/rets/locking_http_client.rb +34 -0
  14. data/lib/rets/measuring_http_client.rb +27 -0
  15. data/lib/rets/metadata/caching.rb +59 -0
  16. data/lib/rets/metadata/containers.rb +89 -0
  17. data/lib/rets/metadata/file_cache.rb +29 -0
  18. data/lib/rets/metadata/json_serializer.rb +27 -0
  19. data/lib/rets/metadata/lookup_table.rb +65 -0
  20. data/lib/rets/metadata/lookup_type.rb +19 -0
  21. data/lib/rets/metadata/marshal_serializer.rb +27 -0
  22. data/lib/rets/metadata/multi_lookup_table.rb +70 -0
  23. data/lib/rets/metadata/null_cache.rb +24 -0
  24. data/lib/rets/metadata/resource.rb +103 -0
  25. data/lib/rets/metadata/rets_class.rb +57 -0
  26. data/lib/rets/metadata/rets_object.rb +41 -0
  27. data/lib/rets/metadata/root.rb +155 -0
  28. data/lib/rets/metadata/table.rb +33 -0
  29. data/lib/rets/metadata/table_factory.rb +19 -0
  30. data/lib/rets/metadata/yaml_serializer.rb +27 -0
  31. data/lib/rets/metadata.rb +18 -0
  32. data/lib/rets/parser/compact.rb +117 -0
  33. data/lib/rets/parser/error_checker.rb +56 -0
  34. data/lib/rets/parser/multipart.rb +39 -0
  35. data/lib/rets.rb +269 -0
  36. data/test/fixtures.rb +324 -0
  37. data/test/helper.rb +14 -0
  38. data/test/test_caching.rb +89 -0
  39. data/test/test_client.rb +307 -0
  40. data/test/test_error_checker.rb +87 -0
  41. data/test/test_file_cache.rb +42 -0
  42. data/test/test_http_client.rb +132 -0
  43. data/test/test_json_serializer.rb +26 -0
  44. data/test/test_locking_http_client.rb +29 -0
  45. data/test/test_marshal_serializer.rb +26 -0
  46. data/test/test_metadata.rb +71 -0
  47. data/test/test_metadata_class.rb +50 -0
  48. data/test/test_metadata_lookup_table.rb +21 -0
  49. data/test/test_metadata_lookup_type.rb +21 -0
  50. data/test/test_metadata_multi_lookup_table.rb +60 -0
  51. data/test/test_metadata_object.rb +33 -0
  52. data/test/test_metadata_resource.rb +148 -0
  53. data/test/test_metadata_root.rb +151 -0
  54. data/test/test_metadata_table.rb +21 -0
  55. data/test/test_metadata_table_factory.rb +24 -0
  56. data/test/test_parser_compact.rb +115 -0
  57. data/test/test_parser_multipart.rb +39 -0
  58. data/test/test_yaml_serializer.rb +26 -0
  59. data/test/vcr_cassettes/unauthorized_response.yml +262 -0
  60. metadata +227 -0
@@ -0,0 +1,307 @@
1
+ require_relative "helper"
2
+
3
+ class TestClient < MiniTest::Test
4
+
5
+ def setup
6
+ @client = Rets::Client.new(:login_url => "http://example.com/login")
7
+ end
8
+
9
+ def test_extract_capabilities
10
+ assert_equal(
11
+ {"abc" => "123", "def" => "ghi=jk"},
12
+ @client.extract_capabilities(Nokogiri.parse(CAPABILITIES))
13
+ )
14
+ end
15
+
16
+ def test_extract_capabilities_with_whitespace
17
+ assert_equal(
18
+ {"action" => "/RETS/Action"},
19
+ @client.extract_capabilities(Nokogiri.parse(CAPABILITIES_WITH_WHITESPACE))
20
+ )
21
+ end
22
+
23
+ def test_capability_url_returns_parsed_url
24
+ client = Rets::Client.new(:login_url => "http://example.com", :capabilities => { "foo" => "/foo" })
25
+
26
+ assert_equal "http://example.com/foo", client.capability_url("foo")
27
+ end
28
+
29
+ def test_cached_capabilities_case_insensitive
30
+ client = Rets::Client.new(:login_url => "http://example.com", :capabilities => { "foo" => "/foo" })
31
+
32
+ assert_equal client.capabilities.default_proc, Rets::Client::CASE_INSENSITIVE_PROC
33
+ end
34
+
35
+ def test_capabilities_calls_login_when_nil
36
+ @client.expects(:login)
37
+ @client.capabilities
38
+ end
39
+
40
+ def test_capabilities_does_not_call_login_after_login
41
+ response = mock
42
+ response.stubs(:body).returns(CAPABILITIES)
43
+ @client.stubs(:http_get).returns(response)
44
+ @client.login
45
+
46
+ @client.expects(:login).never
47
+ @client.capabilities
48
+ end
49
+
50
+ def test_tries_increments_with_each_call
51
+ assert_equal 1, @client.tries
52
+ assert_equal 2, @client.tries
53
+ end
54
+
55
+ def test_metadata_when_not_initialized_with_metadata
56
+ new_raw_metadata = stub(:new_raw_metadata)
57
+
58
+ client = Rets::Client.new(:login_url => "http://example.com")
59
+ client.stubs(:retrieve_metadata).returns(new_raw_metadata)
60
+
61
+ assert_same new_raw_metadata, client.metadata.marshal_dump
62
+ end
63
+
64
+ def test_initialize_with_old_metadata_cached_contstructs_new_metadata_from_request
65
+ metadata = stub(:current? => false)
66
+ new_raw_metadata = stub(:new_raw_metadata)
67
+
68
+ client = Rets::Client.new(:login_url => "http://example.com", :metadata => metadata)
69
+ client.stubs(:capabilities).returns({})
70
+ client.stubs(:retrieve_metadata).returns(new_raw_metadata)
71
+
72
+ assert_same new_raw_metadata, client.metadata.marshal_dump
73
+ end
74
+
75
+ def test_initialize_with_current_metadata_cached_return_cached_metadata
76
+ metadata = stub(:current? => true)
77
+ client = Rets::Client.new(:login_url => "http://example.com", :metadata => metadata)
78
+ client.stubs(:capabilities => {})
79
+
80
+ assert_same metadata, client.metadata
81
+ end
82
+
83
+ def test_initialize_takes_logger
84
+ logger = Object.new
85
+
86
+ client = Rets::Client.new(:login_url => "http://example.com", :logger => logger)
87
+
88
+ assert_equal logger, client.logger
89
+ end
90
+
91
+ def test_default_logger_returns_api_compatible_silent_logger
92
+ logger = @client.logger
93
+ logger.fatal "foo"
94
+ logger.error "foo"
95
+ logger.warn "foo"
96
+ logger.info "foo"
97
+ logger.debug "foo"
98
+ end
99
+
100
+ def test_find_every_raises_on_missing_required_arguments
101
+ assert_raises ArgumentError do
102
+ @client.find_every({})
103
+ end
104
+ assert_raises ArgumentError do
105
+ @client.find_every(:search_type => "Foo")
106
+ end
107
+ assert_raises ArgumentError do
108
+ @client.find_every(:class => "Bar")
109
+ end
110
+ end
111
+
112
+ def test_find_first_calls_find_every_with_limit_one
113
+ @client.expects(:find_every).with({:limit => 1, :foo => :bar}, nil).returns([1,2,3])
114
+
115
+ assert_equal 1, @client.find(:first, :foo => :bar, :limit => 5), "User-specified limit should be ignored"
116
+ end
117
+
118
+ def test_find_all_calls_find_every
119
+ @client.expects(:find_every).with({:limit => 5, :foo => :bar}, nil).returns([1,2,3])
120
+
121
+ assert_equal [1,2,3], @client.find(:all, :limit => 5, :foo => :bar)
122
+ end
123
+
124
+ def test_find_raises_on_unknown_quantity
125
+ assert_raises ArgumentError do
126
+ @client.find(:incorrect, :foo => :bar)
127
+ end
128
+ end
129
+
130
+ def test_response_text_encoding_from_ascii
131
+ @client.stubs(:capability_url).with("Search").returns("search_url")
132
+ response = mock
133
+ response.stubs(:body).returns("An ascii string".encode("binary", "UTF-8"))
134
+
135
+ assert_equal @client.clean_response(response).body, "An ascii string"
136
+ end
137
+
138
+ def test_response_text_encoding_from_utf_8
139
+ @client.stubs(:capability_url).with("Search").returns("search_url")
140
+ response = mock
141
+ response.stubs(:body).returns("Some string with non-ascii characters \u0119")
142
+
143
+ assert_equal @client.clean_response(response).body, "Some string with non-ascii characters \u0119"
144
+
145
+ end
146
+
147
+ def test_response_text_encoding_from_utf_16
148
+ @client.stubs(:capability_url).with("Search").returns("search_url")
149
+ response = mock
150
+ response.stubs(:body).returns("Some string with non-utf-8 characters \xC2")
151
+
152
+ assert_equal @client.clean_response(response).body, "Some string with non-utf-8 characters \uFFFD"
153
+ end
154
+
155
+ def test_find_retries_when_receiving_no_records_found
156
+ @client.stubs(:find_every).raises(Rets::NoRecordsFound.new('')).then.returns([1])
157
+
158
+ assert_equal [1], @client.find(:all)
159
+ end
160
+
161
+ def test_find_does_not_retry_when_receiving_no_records_found_with_option
162
+ @client.stubs(:find_every).raises(Rets::NoRecordsFound.new(''))
163
+
164
+ assert_equal [], @client.find(:all, no_records_not_an_error: true)
165
+ end
166
+
167
+ def test_find_does_not_retry_and_returns_zero_on_count_request_when_receiving_no_records_found_with_option
168
+ @client.stubs(:find_every).raises(Rets::NoRecordsFound.new(''))
169
+
170
+ assert_equal 0, @client.find(:all, count: 2, no_records_not_an_error: true)
171
+ end
172
+
173
+ def test_find_retries_on_errors
174
+ @client.stubs(:find_every).raises(Rets::AuthorizationFailure.new(401, 'Not Authorized')).then.raises(Rets::InvalidRequest.new(20134, 'Not Found')).then.returns([])
175
+ @client.stubs(:login)
176
+ @client.find(:all, :foo => :bar)
177
+ end
178
+
179
+ def test_find_waits_configured_time_before_next_request
180
+ @client.options[:recoverable_error_wait_secs] = 3.14
181
+ @client.expects(:sleep).with(3.14).times(3)
182
+ @client.stubs(:find_every).raises(Rets::MiscellaneousSearchError.new(0, 'Foo'))
183
+ @client.find(:all, :foo => :bar) rescue nil
184
+ end
185
+
186
+ def test_find_eventually_reraises_errors
187
+ @client.stubs(:find_every).raises(Rets::AuthorizationFailure.new(401, 'Not Authorized'))
188
+ @client.stubs(:login)
189
+
190
+ assert_raises Rets::AuthorizationFailure do
191
+ @client.find(:all, :foo => :bar)
192
+ end
193
+ end
194
+
195
+ def test_find_logs_in_after_auth_error
196
+ @client.stubs(:find_every).raises(Rets::AuthorizationFailure.new(401, 'Not Authorized')).then.returns(["foo"])
197
+
198
+ @client.expects(:login)
199
+ @client.find(:all, :foo => :bar)
200
+ end
201
+
202
+ def test_all_objects_calls_objects
203
+ @client.expects(:objects).with("*", :foo => :bar)
204
+
205
+ @client.all_objects(:foo => :bar)
206
+ end
207
+
208
+ def test_objects_handles_string_argument
209
+ @client.expects(:fetch_object).with("*", :foo => :bar)
210
+ @client.stubs(:create_parts_from_response)
211
+
212
+ @client.objects("*", :foo => :bar)
213
+ end
214
+
215
+ def test_objects_handle_array_argument
216
+ @client.expects(:fetch_object).with("1:2:3", :foo => :bar)
217
+ @client.stubs(:create_parts_from_response)
218
+
219
+ @client.objects([1,2,3], :foo => :bar)
220
+ end
221
+
222
+ def test_objects_raises_on_other_arguments
223
+ assert_raises ArgumentError do
224
+ @client.objects(Object.new, :foo => :bar)
225
+ end
226
+ end
227
+
228
+ def test_create_parts_from_response_returns_multiple_parts_when_multipart_response
229
+ response = {}
230
+ response.stubs(:header => { "content-type" => ['multipart; boundary="simple boundary"']})
231
+ response.stubs(:body => MULITPART_RESPONSE)
232
+
233
+ Rets::Parser::Multipart.expects(:parse).
234
+ with(MULITPART_RESPONSE, "simple boundary").
235
+ returns([])
236
+
237
+ @client.create_parts_from_response(response)
238
+ end
239
+
240
+ def test_parse_boundary_wo_quotes
241
+ response = {}
242
+ response.stubs(:header => { "content-type" => ['multipart; boundary=simple boundary; foo;']})
243
+ response.stubs(:body => MULITPART_RESPONSE)
244
+
245
+ Rets::Parser::Multipart.expects(:parse).
246
+ with(MULITPART_RESPONSE, "simple boundary").
247
+ returns([])
248
+
249
+ @client.create_parts_from_response(response)
250
+ end
251
+
252
+ def test_create_parts_from_response_returns_a_single_part_when_not_multipart_response
253
+ response = {}
254
+ response.stubs(:header => { "content-type" => ['text/plain']})
255
+ response.stubs(:headers => { "Content-Type" => 'text/plain'})
256
+ response.stubs(:body => "fakebody")
257
+
258
+ parts = @client.create_parts_from_response(response)
259
+
260
+ assert_equal 1, parts.size
261
+
262
+ part = parts.first
263
+
264
+ assert_equal "text/plain", part.headers["content-type"]
265
+ assert_equal "fakebody", part.body
266
+ end
267
+
268
+ def test_object_calls_fetch_object
269
+ response = stub(:body => "foo")
270
+
271
+ @client.expects(:fetch_object).with("1", :foo => :bar).returns(response)
272
+
273
+ assert_equal "foo", @client.object("1", :foo => :bar)
274
+ end
275
+
276
+ def test_decorate_result_handles_bad_metadata
277
+ result = {'foo' => 'bar'}
278
+ rets_class = stub
279
+ rets_class.expects(:find_table).with('foo').returns(nil)
280
+ response = @client.decorate_result(result, rets_class)
281
+ assert_equal response, result
282
+ end
283
+
284
+ def test_clean_setup_with_receive_timeout
285
+ HTTPClient.any_instance.expects(:receive_timeout=).with(1234)
286
+ @client = Rets::Client.new(
287
+ login_url: 'http://example.com/login',
288
+ receive_timeout: 1234
289
+ )
290
+ end
291
+
292
+ def test_clean_setup_with_proxy_auth
293
+ @login_url = 'http://example.com/login'
294
+ @proxy_url = 'http://example.com/proxy'
295
+ @proxy_username = 'username'
296
+ @proxy_password = 'password'
297
+ HTTPClient.any_instance.expects(:set_proxy_auth).with(@proxy_username, @proxy_password)
298
+
299
+ @client = Rets::Client.new(
300
+ login_url: @login_url,
301
+ http_proxy: @proxy_url,
302
+ proxy_username: @proxy_username,
303
+ proxy_password: @proxy_password
304
+ )
305
+ end
306
+
307
+ end
@@ -0,0 +1,87 @@
1
+ require_relative "helper"
2
+
3
+ class TestErrorChecker < MiniTest::Test
4
+ def test_check_with_status_code_412
5
+ response = mock
6
+ response.stubs(:status_code).returns(412)
7
+ response.stubs(:body).returns('junk')
8
+ assert_raises Rets::HttpError do
9
+ Rets::Parser::ErrorChecker.check(response)
10
+ end
11
+ end
12
+
13
+ def test_401_with_empty_body_is_auth_failure
14
+ # 401 with no body is an auth failure
15
+ response = mock
16
+ response.stubs(:status_code).returns(401)
17
+ response.stubs(:ok?).returns(false)
18
+ response.stubs(:body).returns('')
19
+ assert_raises Rets::AuthorizationFailure do
20
+ Rets::Parser::ErrorChecker.check(response)
21
+ end
22
+ end
23
+
24
+ def test_401_with_html_body_is_auth_failure
25
+ # 401 with html body returns auth failure
26
+ response = mock
27
+ response.stubs(:status_code).returns(401)
28
+ response.stubs(:ok?).returns(false)
29
+ response.stubs(:body).returns(HTML_AUTH_FAILURE)
30
+ assert_raises Rets::AuthorizationFailure do
31
+ Rets::Parser::ErrorChecker.check(response)
32
+ end
33
+ end
34
+
35
+ def test_401_with_xhtml_body_is_auth_failure
36
+ # 401 with xhtml body returns auth failure
37
+ response = mock
38
+ response.stubs(:status_code).returns(401)
39
+ response.stubs(:ok?).returns(false)
40
+ response.stubs(:body).returns(XHTML_AUTH_FAILURE)
41
+ assert_raises Rets::AuthorizationFailure do
42
+ Rets::Parser::ErrorChecker.check(response)
43
+ end
44
+ end
45
+
46
+ def test_no_records_found_failure
47
+ response = mock
48
+ response.stubs(:body).returns(RETS_NO_RECORDS_ERROR)
49
+ assert_raises Rets::NoRecordsFound do
50
+ Rets::Parser::ErrorChecker.check(response)
51
+ end
52
+ end
53
+
54
+ def test_no_object_found_failure
55
+ response = mock
56
+ response.stubs(:body).returns(RETS_NO_OBJECT_ERROR)
57
+ assert_raises Rets::NoObjectFound do
58
+ Rets::Parser::ErrorChecker.check(response)
59
+ end
60
+ end
61
+
62
+ Rets::Parser::ErrorChecker::INVALID_REQUEST_ERROR_MAPPING.each do |error_code, error_class|
63
+ define_method("test_#{error_class}_failure") do
64
+ response = mock
65
+ response.stubs(:body).returns(error_body_with_code(error_code))
66
+ assert_raises error_class do
67
+ Rets::Parser::ErrorChecker.check(response)
68
+ end
69
+ end
70
+ end
71
+
72
+ def test_invalid_request_failure
73
+ response = mock
74
+ response.stubs(:body).returns(RETS_INVALID_REQUEST_ERROR)
75
+ assert_raises Rets::InvalidRequest do
76
+ Rets::Parser::ErrorChecker.check(response)
77
+ end
78
+ end
79
+
80
+ def error_body_with_code(code)
81
+ <<-XML
82
+ <?xml version="1.0"?>
83
+ <RETS ReplyCode="#{code}" ReplyText="Error message">
84
+ </RETS>
85
+ XML
86
+ end
87
+ end
@@ -0,0 +1,42 @@
1
+ require_relative "helper"
2
+
3
+ require "tempfile"
4
+
5
+ class TestFileCache < MiniTest::Test
6
+
7
+ def with_tempfile(&block)
8
+ Tempfile.open(File.basename(__FILE__), &block)
9
+ end
10
+
11
+ def with_temp_path
12
+ with_tempfile do |file|
13
+ path = file.path
14
+ begin
15
+ file.close!
16
+ yield path
17
+ ensure
18
+ File.delete(path)
19
+ end
20
+ end
21
+ end
22
+
23
+ def test_save
24
+ with_temp_path do |path|
25
+ cache = Rets::Metadata::FileCache.new(path)
26
+ cache.save { |file| file.print "foo" }
27
+ file_contents = File.read(path)
28
+ assert_equal "foo", file_contents
29
+ end
30
+ end
31
+
32
+ def test_load
33
+ with_tempfile do |file|
34
+ file.print "foo"
35
+ file.close
36
+ cache = Rets::Metadata::FileCache.new(file.path)
37
+ file_contents = cache.load(&:read)
38
+ assert_equal "foo", file_contents
39
+ end
40
+ end
41
+
42
+ end
@@ -0,0 +1,132 @@
1
+ require_relative "helper"
2
+
3
+ class TestHttpClient < MiniTest::Test
4
+ def setup
5
+ @cm = WebAgent::CookieManager.new
6
+
7
+ @http = HTTPClient.new
8
+
9
+ @logger = Rets::Client::FakeLogger.new
10
+ @logger.stubs(:debug?).returns(false)
11
+
12
+ @http_client = Rets::HttpClient.new(@http, {}, @logger, "http://rets.rets.com/somestate/login.aspx")
13
+ end
14
+
15
+ def test_http_get_delegates_to_client
16
+ url = 'foo@example.com'
17
+ response = stub(:response)
18
+ response.stubs(:body).returns('response data')
19
+
20
+ @http.stubs(:get).with(url, anything, anything).returns(response)
21
+
22
+ assert_equal @http_client.http_get(url, {}), response
23
+ end
24
+
25
+ def test_http_post_delegates_to_client
26
+ url = 'foo@example.com'
27
+ response = stub(:response)
28
+ response.stubs(:body).returns('response data')
29
+
30
+ @http.stubs(:post).with(url, anything, anything).returns(response)
31
+
32
+ assert_equal @http_client.http_post(url, {}), response
33
+ end
34
+ end
35
+
36
+ class CookieManagement < MiniTest::Test
37
+ def setup
38
+ @logger = Rets::Client::FakeLogger.new
39
+ @logger.stubs(:debug?).returns(false)
40
+
41
+ @cm = WebAgent::CookieManager.new
42
+ http = HTTPClient.new
43
+ http.cookie_manager = @cm
44
+ @client = Rets::HttpClient.new(http, {}, nil, "http://rets.rets.com/somestate/login.aspx")
45
+ end
46
+
47
+ def teardown
48
+ # Empty cookie jar
49
+ @cm.cookies = []
50
+ end
51
+
52
+ def test_http_cookie_with_one_cookie_from_one_domain
53
+ set_cookie = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
54
+ @cm.parse(set_cookie, URI.parse("http://www.rets.rets.com"))
55
+ assert_equal "879392834723043209", @client.http_cookie('RETS-Session-ID')
56
+ end
57
+
58
+ def test_http_cookie_with_multiple_cookies_from_one_domain
59
+ # NOTE: Cookies are ordered alphabetically by name when retrieving
60
+ set_cookie_1 = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
61
+ @cm.parse(set_cookie_1, URI.parse("http://www.rets.rets.com"))
62
+
63
+ set_cookie_2 = "Zoo=Bar; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
64
+ @cm.parse(set_cookie_2, URI.parse("http://www.rets.rets.com"))
65
+
66
+ set_cookie_3 = "Foo=Bar; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
67
+ @cm.parse(set_cookie_3, URI.parse("http://www.rets.rets.com"))
68
+
69
+ assert_equal "879392834723043209", @client.http_cookie('RETS-Session-ID')
70
+ end
71
+
72
+ def test_http_cookie_with_no_cookies_from_domain
73
+ assert_equal nil, @client.http_cookie('RETS-Session-ID')
74
+ end
75
+
76
+ def test_save_cookie_store
77
+ cookie_file = Tempfile.new('cookie_file').path
78
+
79
+ #setup cookie store
80
+ client_a = Rets::HttpClient.from_options({ cookie_store: cookie_file, login_url: "http://rets.rets.com/somestate/login.aspx" }, @logger)
81
+
82
+ #add cookie
83
+ cookie = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
84
+ client_a.http.cookie_manager.parse(cookie, URI.parse("http://www.rets.rets.com"))
85
+
86
+ #save cookie
87
+ client_a.save_cookie_store
88
+
89
+ #create new HTTPCLient with same cookie store
90
+ client_b = Rets::HttpClient.from_options({ cookie_store: cookie_file, login_url: "http://rets.rets.com/somestate/login.aspx" }, @logger)
91
+
92
+ #check added cookie exists
93
+ assert_equal "879392834723043209", client_b.http_cookie('RETS-Session-ID')
94
+ end
95
+
96
+ def test_creates_cookie_store_if_missing_during_initialization
97
+ cookie_file = Tempfile.new('cookie_file')
98
+ cookie_file_path = cookie_file.path
99
+
100
+ #remove cookie store
101
+ cookie_file.unlink
102
+
103
+ client = Rets::HttpClient.from_options({cookie_store: cookie_file_path}, @logger)
104
+
105
+ #add cookie
106
+ cookie = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
107
+ client.http.cookie_manager.parse(cookie, URI.parse("http://www.rets.rets.com"))
108
+
109
+ #check added cookie exists
110
+ assert_equal "879392834723043209", client.http_cookie('RETS-Session-ID')
111
+ end
112
+
113
+ def test_creates_cookie_store_if_missing_during_save
114
+ cookie_file = Tempfile.new('cookie_file')
115
+ cookie_file_path = cookie_file.path
116
+
117
+ client = Rets::HttpClient.from_options({cookie_store: cookie_file_path}, @logger)
118
+
119
+ #remove cookie store
120
+ cookie_file.unlink
121
+
122
+ #add cookie
123
+ cookie = "RETS-Session-ID=879392834723043209; path=/; domain=rets.rets.com; expires=Wednesday, 31-Dec-2037 12:00:00 GMT"
124
+ client.http.cookie_manager.parse(cookie, URI.parse("http://www.rets.rets.com"))
125
+
126
+ #save cookie
127
+ client.save_cookie_store
128
+
129
+ #check added cookie exists
130
+ assert_equal "879392834723043209", client.http_cookie('RETS-Session-ID')
131
+ end
132
+ end
@@ -0,0 +1,26 @@
1
+ require_relative "helper"
2
+
3
+ require "stringio"
4
+
5
+ class TestJsonSerializer < MiniTest::Test
6
+
7
+ def setup
8
+ @serializer = Rets::Metadata::JsonSerializer.new
9
+ end
10
+
11
+ def test_round_trip
12
+ metadata = {"foo" => "bar"}
13
+ file = StringIO.new
14
+ @serializer.save(file, metadata)
15
+ file.rewind
16
+ loaded = @serializer.load(file)
17
+ assert_equal metadata, loaded
18
+ end
19
+
20
+ def test_bad_data
21
+ file = StringIO.new("bad data")
22
+ loaded = @serializer.load(file)
23
+ assert_nil loaded
24
+ end
25
+
26
+ end
@@ -0,0 +1,29 @@
1
+ require_relative "helper"
2
+
3
+ class TestLockingHttpClient < MiniTest::Test
4
+ def setup
5
+ @fake_client = stub('fake_client')
6
+ @locker = stub('locker')
7
+ @locking_client = Rets::LockingHttpClient.new(@fake_client, @locker, 'lock_name')
8
+ @url = "fake rets url"
9
+ @params = {'fake_param' => 'fake_param_value'}
10
+ end
11
+
12
+ def test_locking_client_calls_the_real_client_if_lock_succeeds
13
+ @locker.stubs(:lock).with('lock_name', {}).yields(nil)
14
+ @fake_client.expects(:http_post).with(@url, @params, {})
15
+ @locking_client.http_post(@url, @params)
16
+ end
17
+
18
+ def test_locking_client_does_nothing_if_lock_fails_to_yield
19
+ @fake_client.expects(:http_post).never
20
+ @locker.stubs(:lock).with('lock_name', {})
21
+ @locking_client.http_post(@url, @params)
22
+ end
23
+
24
+ def test_locking_client_returns_result_from_client
25
+ @fake_client.stubs(:http_post).returns('result')
26
+ @locker.stubs(:lock).with('lock_name', {}).yields(nil)
27
+ assert_equal 'result', @locking_client.http_post(@url, @params)
28
+ end
29
+ end
@@ -0,0 +1,26 @@
1
+ require_relative "helper"
2
+
3
+ require "stringio"
4
+
5
+ class TestMarshalSerializer < MiniTest::Test
6
+
7
+ def setup
8
+ @serializer = Rets::Metadata::MarshalSerializer.new
9
+ end
10
+
11
+ def test_round_trip
12
+ metadata = {"foo" => "bar"}
13
+ file = StringIO.new
14
+ @serializer.save(file, metadata)
15
+ file.rewind
16
+ loaded = @serializer.load(file)
17
+ assert_equal metadata, loaded
18
+ end
19
+
20
+ def test_bad_data
21
+ file = StringIO.new("bad data")
22
+ loaded = @serializer.load(file)
23
+ assert_nil loaded
24
+ end
25
+
26
+ end