rets4r 0.8.5 → 1.1.18

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 (79) hide show
  1. data/.document +5 -0
  2. data/{test/client/data/1.5/metadata.xml → .gemtest} +0 -0
  3. data/CHANGELOG +611 -66
  4. data/CONTRIBUTORS +6 -2
  5. data/Gemfile +1 -0
  6. data/LICENSE +22 -0
  7. data/MANIFEST +63 -0
  8. data/NEWS +203 -0
  9. data/{README → README.rdoc} +11 -4
  10. data/RUBYS +7 -7
  11. data/Rakefile +48 -0
  12. data/TODO +5 -1
  13. data/examples/client_get_object.rb +31 -42
  14. data/examples/client_login.rb +20 -18
  15. data/examples/client_mapper.rb +17 -0
  16. data/examples/client_metadata.rb +28 -28
  17. data/examples/client_parser.rb +9 -0
  18. data/examples/client_search.rb +25 -27
  19. data/examples/settings.yml +114 -0
  20. data/lib/rets4r.rb +14 -1
  21. data/lib/rets4r/auth.rb +70 -66
  22. data/lib/rets4r/client.rb +470 -650
  23. data/lib/rets4r/client/data.rb +13 -13
  24. data/lib/rets4r/client/dataobject.rb +27 -19
  25. data/lib/rets4r/client/exceptions.rb +116 -0
  26. data/lib/rets4r/client/links.rb +32 -0
  27. data/lib/rets4r/client/metadata.rb +12 -12
  28. data/lib/rets4r/client/parsers/compact.rb +42 -0
  29. data/lib/rets4r/client/parsers/compact_nokogiri.rb +91 -0
  30. data/lib/rets4r/client/parsers/metadata.rb +92 -0
  31. data/lib/rets4r/client/parsers/response_parser.rb +100 -0
  32. data/lib/rets4r/client/requester.rb +143 -0
  33. data/lib/rets4r/client/transaction.rb +30 -33
  34. data/lib/rets4r/core_ext/array/extract_options.rb +15 -0
  35. data/lib/rets4r/core_ext/class/attribute_accessors.rb +58 -0
  36. data/lib/rets4r/core_ext/hash/keys.rb +46 -0
  37. data/lib/rets4r/core_ext/hash/slice.rb +39 -0
  38. data/lib/rets4r/listing_mapper.rb +17 -0
  39. data/lib/rets4r/listing_service.rb +35 -0
  40. data/lib/rets4r/loader.rb +8 -0
  41. data/lib/tasks/annotations.rake +121 -0
  42. data/lib/tasks/coverage.rake +13 -0
  43. data/rets4r.gemspec +24 -0
  44. data/spec/rets4r_compact_data_parser_spec.rb +7 -0
  45. data/test/data/1.5/bad_compact.xml +7 -0
  46. data/test/data/1.5/count_only_compact.xml +3 -0
  47. data/test/{client/data → data}/1.5/error.xml +0 -0
  48. data/test/{client/data → data}/1.5/invalid_compact.xml +0 -0
  49. data/test/{client/data → data}/1.5/login.xml +0 -0
  50. data/test/data/1.5/metadata.xml +0 -0
  51. data/test/{client/data → data}/1.5/search_compact.xml +0 -0
  52. data/test/data/1.5/search_compact_big.xml +136 -0
  53. data/test/{client/data → data}/1.5/search_unescaped_compact.xml +0 -0
  54. data/test/data/listing_service.yml +36 -0
  55. data/test/test_auth.rb +68 -0
  56. data/test/test_client.rb +342 -0
  57. data/test/test_client_links.rb +39 -0
  58. data/test/test_compact_nokogiri.rb +64 -0
  59. data/test/test_helper.rb +12 -0
  60. data/test/test_listing_mapper.rb +112 -0
  61. data/test/test_loader.rb +24 -0
  62. data/test/test_parser.rb +96 -0
  63. data/test/test_quality.rb +57 -0
  64. metadata +168 -53
  65. data/GPL +0 -340
  66. data/examples/metadata.xml +0 -42
  67. data/lib/rets4r/client/metadataindex.rb +0 -82
  68. data/lib/rets4r/client/parser.rb +0 -141
  69. data/lib/rets4r/client/parser/rexml.rb +0 -75
  70. data/lib/rets4r/client/parser/xmlparser.rb +0 -95
  71. data/test/client/parser/tc_rexml.rb +0 -17
  72. data/test/client/parser/tc_xmlparser.rb +0 -21
  73. data/test/client/tc_auth.rb +0 -68
  74. data/test/client/tc_client.rb +0 -320
  75. data/test/client/tc_metadataindex.rb +0 -36
  76. data/test/client/test_parser.rb +0 -128
  77. data/test/client/ts_all.rb +0 -8
  78. data/test/ts_all.rb +0 -1
  79. data/test/ts_client.rb +0 -1
@@ -0,0 +1,342 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "."))
3
+ require 'test_helper'
4
+
5
+ module RETS4R
6
+ class Client
7
+ public :process_content_type
8
+ end
9
+
10
+ class TestClientGetMetadata < Test::Unit::TestCase
11
+ RETS_PORT = '9080'
12
+ RETS_URL = "http://localhost:#{RETS_PORT}"
13
+ RETS_LOGIN = 'login'
14
+ RETS_PASSWORD = 'password'
15
+
16
+ class CustomError < StandardError; end
17
+
18
+ def setup
19
+ @logfile = StringIO.open
20
+ @rets = RETS4R::Client.new(RETS_URL)
21
+ @rets.logger = Logger.new(@logfile)
22
+ @rets.logger.level = Logger::DEBUG
23
+
24
+ @rets.stubs(:request).returns(@response = mock("response"))
25
+ @response.stubs(:body).returns(:body)
26
+ @rets.stubs(:parse).returns(@results = mock("results"))
27
+ Client::ResponseParser.any_instance.stubs(:parse_metadata).returns(@results = mock("results"))
28
+ end
29
+
30
+ def teardown
31
+ @logfile.close
32
+ end
33
+
34
+ def test_get_metadata_yields_the_results_if_given_a_block
35
+ in_block = false
36
+ @rets.get_metadata do |results|
37
+ in_block = true
38
+ assert_equal @results, results
39
+ end
40
+
41
+ assert in_block, "Block was never yielded to"
42
+ end
43
+
44
+ def test_useragent
45
+ assert_match /^rets4r/, RETS4R::Client::Requester::DEFAULT_USER_AGENT
46
+ assert_match /#{::RETS4R::VERSION}/, RETS4R::Client::Requester::DEFAULT_USER_AGENT
47
+ end
48
+
49
+ def test_get_metadata_returns_the_metadata_when_no_block_given
50
+ rval = @rets.get_metadata
51
+
52
+ assert_equal @results, rval
53
+ end
54
+
55
+ def test_get_metadata_returns_the_blocks_value_when_given_a_block
56
+ rval = @rets.get_metadata do |results|
57
+ :block_value
58
+ end
59
+
60
+ assert_equal :block_value, rval
61
+ end
62
+ end
63
+
64
+ class TestClientGetObject < Test::Unit::TestCase
65
+ RETS_PORT = '9080'
66
+ RETS_URL = "http://localhost:#{RETS_PORT}"
67
+ RETS_LOGIN = 'login'
68
+ RETS_PASSWORD = 'password'
69
+
70
+ class CustomError < StandardError; end
71
+
72
+ def setup
73
+ @logfile = StringIO.open
74
+ @rets = RETS4R::Client.new(RETS_URL)
75
+ @rets.logger = Logger.new(@logfile)
76
+ @rets.logger.level = Logger::DEBUG
77
+
78
+ @rets.stubs(:request).returns(@response = mock("response"))
79
+ end
80
+
81
+ def test_returns_multipart_parallel_objects_in_a_single_array(boundary = "1231")
82
+ @response.expects(:[]).with('content-type').at_least_once.returns("multipart/parallel; boundary=#{boundary}")
83
+ @response.expects(:body).returns("\r\n--1231\r\nContent-ID: 392103\r\nObject-ID: 1\r\nContent-Type: image/jpeg\r\n\r\n" + "\000"*120 + "\r\n--1231\r\nContent-ID: 392103\r\nObject-ID: 2\r\nContent-Type: image/gif\r\n\r\n" + "\000"*140 + "\r\n--1231--")
84
+ results = @rets.get_object("Property", "Photo", "392103:*")
85
+ assert_equal 2, results.size, "Client should parse two objects out of the request"
86
+ assert_kind_of RETS4R::Client::DataObject, results[0], "First result isn't a DataObject"
87
+ assert_kind_of RETS4R::Client::DataObject, results[1], "Second result isn't a DataObject"
88
+ assert_equal "image/jpeg", results[0].type["Content-Type"], "First object isn't an image/jpeg"
89
+ assert_equal 120, results[0].data.size, "First object isn't 120 bytes in length"
90
+ assert_equal "image/gif", results[1].type["Content-Type"], "Second object isn't an image/gif"
91
+ assert_equal 140, results[1].data.size, "Second object isn't 140 bytes in length"
92
+ end
93
+
94
+ def test_returns_multipart_parallel_objects_in_a_single_array_boundary_with_double_quotes
95
+ test_returns_multipart_parallel_objects_in_a_single_array('"1231"')
96
+ end
97
+
98
+ def test_returns_multipart_parallel_objects_in_a_single_array_boundary_with_single_quotes
99
+ test_returns_multipart_parallel_objects_in_a_single_array("'1231'")
100
+ end
101
+
102
+ def test_returns_single_entity_object_in_a_single_element_array
103
+ @response.expects(:[]).with('content-type').at_least_once.returns("image/jpeg")
104
+ @response.expects(:[]).with('Transfer-Encoding').at_least_once.returns("")
105
+ @response.expects(:[]).with('Content-Length').at_least_once.returns(241)
106
+ @response.expects(:[]).with('Object-ID').at_least_once.returns("25478")
107
+ @response.expects(:[]).with('Content-ID').at_least_once.returns("5589")
108
+ @response.expects(:body).returns("\000"*241)
109
+
110
+ results = @rets.get_object("Property", "Photo", "392103:*")
111
+ assert_equal 1, results.size, "Client parsed one object out of the request"
112
+ assert_kind_of RETS4R::Client::DataObject, results[0], "First result isn't a DataObject"
113
+ assert_equal "image/jpeg", results[0].type["Content-Type"], "Content-Type not copied"
114
+ assert_equal "5589", results[0].type["Content-ID"], "Content-ID not copied"
115
+ assert_equal "25478", results[0].type["Object-ID"], "Object-ID not copied"
116
+ assert_equal 241, results[0].data.size, "First object isn't 241 bytes in length"
117
+ end
118
+
119
+ def test_returns_single_entity_object_as_chunked_encoding_in_a_single_element_array
120
+ @response.expects(:[]).with('content-type').at_least_once.returns("image/jpeg")
121
+ @response.expects(:[]).with('Transfer-Encoding').at_least_once.returns("chunked")
122
+ @response.expects(:[]).with('Object-ID').at_least_once.returns("25478")
123
+ @response.expects(:[]).with('Content-ID').at_least_once.returns("5589")
124
+ @response.expects(:body).returns("\000"*241)
125
+
126
+ results = @rets.get_object("Property", "Photo", "392103:*")
127
+ assert_equal 1, results.size, "Client parsed one object out of the request"
128
+ assert_kind_of RETS4R::Client::DataObject, results[0], "First result isn't a DataObject"
129
+ assert_equal "image/jpeg", results[0].type["Content-Type"], "Content-Type not copied"
130
+ assert_equal "5589", results[0].type["Content-ID"], "Content-ID not copied"
131
+ assert_equal "25478", results[0].type["Object-ID"], "Object-ID not copied"
132
+ assert_equal 241, results[0].data.size, "First object isn't 241 bytes in length"
133
+ end
134
+
135
+ def test_yields_data_objects_to_block_and_returns_blocks_value
136
+ @response.expects(:[]).with('content-type').at_least_once.returns("image/jpeg")
137
+ @response.expects(:[]).with('Transfer-Encoding').at_least_once.returns("")
138
+ @response.expects(:[]).with('Content-Length').at_least_once.returns(241)
139
+ @response.expects(:[]).with('Object-ID').at_least_once.returns("25478")
140
+ @response.expects(:[]).with('Content-ID').at_least_once.returns("5589")
141
+ @response.expects(:body).returns("\000"*241)
142
+
143
+ yielded_count = 0
144
+
145
+ value = @rets.get_object("Property", "VRImage", "912:0") do |result|
146
+ assert_kind_of RETS4R::Client::DataObject, result
147
+ yielded_count += 1
148
+ :return_value
149
+ end
150
+
151
+ assert_equal yielded_count, value
152
+ end
153
+ def test_correcly_handles_location_header_url
154
+ @response.expects(:[]).with('content-type').at_least_once.returns("multipart/parallel; boundary='1231'")
155
+ @response.expects(:body).returns(
156
+ "\r\n--1231\r\nContent-ID: 392103\r\nObject-ID: 1\r\nContent-Type: image/jpeg\r\nLocation: http://example.com/391203-1.jpg\r\n\r\n" +
157
+ "\000"*120 +
158
+ "\r\n--1231\r\nContent-ID: 392103\r\nObject-ID: 2\r\nContent-Type: image/gif\r\nLocation: http://example.com/391203-2.gif\r\n\r\n" +
159
+ "\000"*140 +
160
+ "\r\n--1231--"
161
+ )
162
+ results = @rets.get_object("Property", "Photo", "392103:*", true)
163
+
164
+ assert_equal 'http://example.com/391203-1.jpg', results.first.info['Location'], "incorrect location"
165
+ assert_equal 'http://example.com/391203-2.gif', results.last.info['Location'], "incorrect location"
166
+ end
167
+ end
168
+
169
+ class TestClientLogin < Test::Unit::TestCase
170
+ RETS_PORT = '9080'
171
+ RETS_URL = "http://localhost:#{RETS_PORT}"
172
+ RETS_LOGIN = 'login'
173
+ RETS_PASSWORD = 'password'
174
+
175
+ class CustomError < StandardError; end
176
+
177
+ def setup
178
+ @logfile = StringIO.open
179
+ @rets = RETS4R::Client.new(RETS_URL)
180
+ @rets.logger = Logger.new(@logfile)
181
+ @rets.logger.level = Logger::DEBUG
182
+
183
+ @rets.stubs(:request).returns(@response = mock("response"))
184
+ @response.stubs(:body).returns(:body)
185
+ Client::ResponseParser.any_instance.stubs(:parse_key_value).returns(@results = mock("results"))
186
+ @results.stubs(:success?).returns(true)
187
+ @results.stubs(:response).returns(Hash.new)
188
+ @results.stubs(:secondary_response=)
189
+ end
190
+
191
+ def teardown
192
+ @logfile.close
193
+ end
194
+
195
+ def test_successful_login_yields_the_results_to_the_block
196
+ @rets.expects(:request).with {|arg| arg.kind_of?(URI)}.returns(@response)
197
+ Client::ResponseParser.any_instance.expects(:parse_key_value).returns(@results)
198
+ @results.expects(:success?).returns(true)
199
+ @rets.expects(:logout)
200
+
201
+ in_block = false
202
+ @rets.login("user", "pass") do |results|
203
+ assert_equal @results, results
204
+ in_block = true
205
+ end
206
+
207
+ assert in_block, "Block was never yielded to"
208
+ end
209
+
210
+ def test_logout_called_after_block_execution_if_block_raises
211
+ assert_raises(CustomError) do
212
+ @rets.expects(:logout)
213
+ @rets.login("user", "pass") do |results|
214
+ raise CustomError
215
+ end
216
+ end
217
+ end
218
+
219
+ def test_login_returns_the_blocks_value
220
+ rval = @rets.login("user", "pass") do |results|
221
+ :value
222
+ end
223
+
224
+ assert_equal :value, rval
225
+ end
226
+
227
+ def test_login_without_a_block_returns_the_results
228
+ results = @rets.login("user", "pass")
229
+ assert_equal @results, results
230
+ end
231
+ end
232
+
233
+ class TestClient < Test::Unit::TestCase
234
+ RETS_PORT = '9080'
235
+ RETS_URL = "http://localhost:#{RETS_PORT}"
236
+ RETS_LOGIN = 'login'
237
+ RETS_PASSWORD = 'password'
238
+
239
+ def setup
240
+ @logfile = StringIO.open
241
+ @rets = RETS4R::Client.new(RETS_URL)
242
+ @rets.logger = Logger.new(@logfile)
243
+ @rets.logger.level = Logger::DEBUG
244
+ end
245
+
246
+ def teardown
247
+ @logfile.close
248
+ end
249
+
250
+ def test_setup
251
+ assert_nothing_raised() { @rets.user_agent = 'ACK/2.1' }
252
+ assert_equal('ACK/2.1', @rets.user_agent)
253
+
254
+ assert_nothing_raised() { @rets.user_agent = 'SPRETS/0.1' }
255
+ assert_nothing_raised() { @rets.request_method = 'GET' }
256
+
257
+ assert_raise(RETS4R::Client::Unsupported) { @rets.rets_version = '1.4.0' }
258
+ assert_nothing_raised() { @rets.rets_version = '1.5' }
259
+ assert_equal("1.5", @rets.rets_version)
260
+ assert_equal("RETS/1.5", @rets.get_header("RETS-Version"))
261
+ assert_nothing_raised() { @rets.rets_version = '1.7' }
262
+ assert_equal("RETS/1.7", @rets.get_header("RETS-Version"))
263
+
264
+ assert_equal('SPRETS/0.1', @rets.user_agent)
265
+ assert_equal('GET', @rets.request_method)
266
+ assert_equal('1.7', @rets.rets_version)
267
+
268
+ assert_nothing_raised() { @rets.request_method = 'POST' }
269
+
270
+ assert_equal('POST', @rets.request_method)
271
+
272
+
273
+ # Check that our changes were logged when in debug mode
274
+ assert @logfile.length > 0
275
+ end
276
+
277
+ # Just to make sure that we're okay when we don't have a logger, we set it to nil and
278
+ # make a change that would trigger a debug mode log.
279
+ def test_without_logger
280
+ @rets.logger = nil
281
+
282
+ assert_nothing_raised() { @rets.request_method = 'GET' }
283
+ end
284
+
285
+ def test_content_type_parsing
286
+ ct = 'multipart/parallel; boundary=cc2631bb.0165.3b32.8a7d.a8453f662101; charset=utf-8'
287
+
288
+ results = @rets.process_content_type(ct)
289
+
290
+ assert_equal('cc2631bb.0165.3b32.8a7d.a8453f662101', results['boundary'])
291
+ assert_equal('multipart/parallel', results['content-type'])
292
+ assert_equal('utf-8', results['charset'])
293
+ end
294
+
295
+ def test_performs_get_request
296
+ assert_nothing_raised() {@rets.request_method = 'GET'}
297
+ assert_equal('GET', @rets.request_method)
298
+
299
+ http = mock('http')
300
+ response = mock('response')
301
+ response.stubs(:to_hash).returns({})
302
+ response.stubs(:code).returns('500')
303
+ response.stubs(:message).returns('Move along, nothing to see here.')
304
+
305
+ http.expects(:get).with('', {'User-Agent' => @rets.user_agent, 'RETS-Version' => "RETS/#{@rets.rets_version}", 'Accept' => '*/*'}).at_least_once.returns(response)
306
+ http.expects(:post).never
307
+ Net::HTTP.any_instance.expects(:start).at_least_once.yields(http)
308
+
309
+ assert_raises(RETS4R::Client::HTTPError) {@rets.login('user', 'pass')}
310
+ end
311
+
312
+ def test_performs_post_request
313
+ assert_nothing_raised() {@rets.request_method = 'POST'}
314
+ assert_equal('POST', @rets.request_method)
315
+
316
+ http = mock('http')
317
+ response = mock('response')
318
+ response.stubs(:to_hash).returns({})
319
+ response.stubs(:code).returns('500')
320
+ response.stubs(:message).returns('Move along, nothing to see here.')
321
+
322
+ http.expects(:post).with('', '', {'User-Agent' => @rets.user_agent, 'RETS-Version' => "RETS/#{@rets.rets_version}", 'Accept' => '*/*'}).at_least_once.returns(response)
323
+ http.expects(:get).never
324
+ Net::HTTP.any_instance.expects(:start).at_least_once.yields(http)
325
+
326
+ assert_raises(RETS4R::Client::HTTPError) {@rets.login('user', 'pass')}
327
+ end
328
+
329
+ def test_search_without_query_should_not_raise_no_metho_error
330
+ client = RETS4R::Client.new('http://demo.crt.realtors.org:6103/rets/login')
331
+ client.login('Joe', 'Schmoe')
332
+ begin
333
+ client.search('', '', nil)
334
+ # search_uri = URI.parse("http://demo.crt.realtors.org:6103/rets/search")
335
+ # client.send :request, search_uri,
336
+ # {"Query"=>nil, "Format"=>"COMPACT", "Count"=>"0", "QueryType"=>"DMQL2", "Class"=>"", "SearchType"=>""}
337
+ rescue Exception => e
338
+ assert_not_equal "NoMethodError", e.class.to_s
339
+ end
340
+ end
341
+ end
342
+ end
@@ -0,0 +1,39 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "test"))
3
+ require 'test_helper'
4
+ require 'rets4r/client/links'
5
+
6
+ class TestClientLinks < Test::Unit::TestCase
7
+ def setup
8
+ @links = RETS4R::Client::Links.from_login_url('http://example.com/login')
9
+ @links['Logout'] = URI.parse('http://example.com/logout')
10
+ @links['GetMetadata'] = URI.parse('http://example.com/metadata')
11
+ @links['GetObject'] = URI.parse('http://example.com/objects')
12
+ @links['Search'] = URI.parse('http://example.com/search')
13
+ @links['Action'] = URI.parse('http://example.com/action')
14
+ end
15
+ def test_should_build_from_login_url
16
+ assert_equal normalize_url('http://example.com/login'), @links['Login'].to_s
17
+ end
18
+ def test_should_access_login
19
+ assert_equal normalize_url('http://example.com/login'), @links.login.to_s
20
+ end
21
+ def test_should_access_logout
22
+ assert_equal normalize_url('http://example.com/logout'), @links.logout.to_s
23
+ end
24
+ def test_should_access_metadata
25
+ assert_equal normalize_url('http://example.com/metadata'), @links.metadata.to_s
26
+ end
27
+ def test_should_access_object
28
+ assert_equal normalize_url('http://example.com/objects'), @links.objects.to_s
29
+ end
30
+ def test_should_access_search
31
+ assert_equal normalize_url('http://example.com/search'), @links.search.to_s
32
+ end
33
+ def test_should_access_action
34
+ assert_equal normalize_url('http://example.com/action'), @links.action.to_s
35
+ end
36
+ def normalize_url(url)
37
+ URI.parse(url).to_s
38
+ end
39
+ end
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "."))
3
+ require 'test_helper'
4
+
5
+ class CompactNokogiriTest < Test::Unit::TestCase
6
+ def test_should_do_stuff
7
+ file = File.expand_path(File.join('test', 'data', '1.5', 'search_compact.xml'))
8
+ listings = RETS4R::Client::CompactNokogiriParser.new(open(file)).to_a
9
+ assert_equal({"Third"=>"Datum3", "Second"=>"Datum2", "First"=>"Datum1"}, listings[0])
10
+ assert_equal({"Third"=>"Datum6", "Second"=>"Datum5", "First"=>"Datum4"}, listings[1])
11
+ end
12
+ def test_should_handle_big_data
13
+ file = File.expand_path(File.join('test', 'data', '1.5', 'bad_compact.xml'))
14
+ listings = RETS4R::Client::CompactNokogiriParser.new(open(file)).to_a
15
+ assert_equal 1, listings.length
16
+ assert_equal 79, listings.first.keys.length
17
+ end
18
+ def test_each_should_yield_between_results
19
+ file = File.expand_path(
20
+ File.join('test', 'data', '1.5', 'search_compact_big.xml'))
21
+ stat = File::Stat.new(file)
22
+ unless stat.size > stat.blksize
23
+ flunk "This test probably won't work on this machine.
24
+ It needs a test input file larger than the native block size."
25
+ end
26
+ stream = open(file)
27
+ positions = []
28
+ listings = RETS4R::Client::CompactNokogiriParser.new(stream).each do |row|
29
+ positions << stream.pos
30
+ end
31
+ assert positions.first < positions.last,
32
+ "data was yielded durring the reading of the stream"
33
+ end
34
+ def test_should_not_include_column_elements_in_keys
35
+ response = "<RETS ReplyCode=\"0\" ReplyText=\"Operation Successful\">\r\n<DELIMITER value=\"09\" />\r\n<COLUMNS>\tDISPLAYORDER\tINPUTDATE\tMEDIADESCR\tMEDIANAME\tMEDIASOURCE\tMEDIATYPE\tMODIFIED\tPICCOUNT\tPRIMARYPIC\tTABLEUID\tUID\t</COLUMNS>\r\n<DATA>\t7\t2009-09-17 07:08:19 \t\tNew 023.jpg\t3155895-11.jpg\tpic\t2009-09-17 07:09:32 \t11\tn\t3155895\t9601458\t</DATA>\r\n<MAXROWS />\r\n</RETS>\r\n"
36
+
37
+ assert RETS4R::Client::CompactNokogiriParser.new(StringIO.new(response)).map.first.keys.grep( /COLUMN/ ).empty?
38
+ end
39
+ context 'non-zero reply code' do
40
+ setup do
41
+ @response = <<-BODY
42
+ <?xml version="1.0"?>
43
+ <RETS ReplyCode="20203" ReplyText="User does not have access to Class named RES. Reference ID: 3fe82558-8015-4d9d-ab0c-776d9e4b5943" />
44
+ BODY
45
+ @parser = RETS4R::Client::CompactNokogiriParser.new(StringIO.new(@response))
46
+ end
47
+ should "raise the execption" do
48
+ assert_raise RETS4R::Client::MiscellaneousSearchErrorException do
49
+ @parser.to_a
50
+ end
51
+ end
52
+ context 'when i parse' do
53
+ should "contain the reply text in the exception message" do
54
+ message = ''
55
+ begin
56
+ @parser.to_a
57
+ rescue Exception => e
58
+ message = e.message
59
+ end
60
+ assert_equal "User does not have access to Class named RES. Reference ID: 3fe82558-8015-4d9d-ab0c-776d9e4b5943", message
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,12 @@
1
+ $:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
2
+
3
+ require 'test/unit'
4
+ require 'rets4r'
5
+ require 'mocha'
6
+ require 'shoulda'
7
+ require 'rubygems'
8
+
9
+ # Configure ListingService
10
+ listing_service_config_file = File.expand_path(File.join('test', 'data', 'listing_service.yml'))
11
+ RETS4R::ListingService.configurations = YAML.load_file(listing_service_config_file)
12
+ RETS4R::ListingService.env = 'test'