rets-hack 0.11

Sign up to get free protection for your applications and to get access to all the features.
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