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.
- data/.document +5 -0
- data/{test/client/data/1.5/metadata.xml → .gemtest} +0 -0
- data/CHANGELOG +611 -66
- data/CONTRIBUTORS +6 -2
- data/Gemfile +1 -0
- data/LICENSE +22 -0
- data/MANIFEST +63 -0
- data/NEWS +203 -0
- data/{README → README.rdoc} +11 -4
- data/RUBYS +7 -7
- data/Rakefile +48 -0
- data/TODO +5 -1
- data/examples/client_get_object.rb +31 -42
- data/examples/client_login.rb +20 -18
- data/examples/client_mapper.rb +17 -0
- data/examples/client_metadata.rb +28 -28
- data/examples/client_parser.rb +9 -0
- data/examples/client_search.rb +25 -27
- data/examples/settings.yml +114 -0
- data/lib/rets4r.rb +14 -1
- data/lib/rets4r/auth.rb +70 -66
- data/lib/rets4r/client.rb +470 -650
- data/lib/rets4r/client/data.rb +13 -13
- data/lib/rets4r/client/dataobject.rb +27 -19
- data/lib/rets4r/client/exceptions.rb +116 -0
- data/lib/rets4r/client/links.rb +32 -0
- data/lib/rets4r/client/metadata.rb +12 -12
- data/lib/rets4r/client/parsers/compact.rb +42 -0
- data/lib/rets4r/client/parsers/compact_nokogiri.rb +91 -0
- data/lib/rets4r/client/parsers/metadata.rb +92 -0
- data/lib/rets4r/client/parsers/response_parser.rb +100 -0
- data/lib/rets4r/client/requester.rb +143 -0
- data/lib/rets4r/client/transaction.rb +30 -33
- data/lib/rets4r/core_ext/array/extract_options.rb +15 -0
- data/lib/rets4r/core_ext/class/attribute_accessors.rb +58 -0
- data/lib/rets4r/core_ext/hash/keys.rb +46 -0
- data/lib/rets4r/core_ext/hash/slice.rb +39 -0
- data/lib/rets4r/listing_mapper.rb +17 -0
- data/lib/rets4r/listing_service.rb +35 -0
- data/lib/rets4r/loader.rb +8 -0
- data/lib/tasks/annotations.rake +121 -0
- data/lib/tasks/coverage.rake +13 -0
- data/rets4r.gemspec +24 -0
- data/spec/rets4r_compact_data_parser_spec.rb +7 -0
- data/test/data/1.5/bad_compact.xml +7 -0
- data/test/data/1.5/count_only_compact.xml +3 -0
- data/test/{client/data → data}/1.5/error.xml +0 -0
- data/test/{client/data → data}/1.5/invalid_compact.xml +0 -0
- data/test/{client/data → data}/1.5/login.xml +0 -0
- data/test/data/1.5/metadata.xml +0 -0
- data/test/{client/data → data}/1.5/search_compact.xml +0 -0
- data/test/data/1.5/search_compact_big.xml +136 -0
- data/test/{client/data → data}/1.5/search_unescaped_compact.xml +0 -0
- data/test/data/listing_service.yml +36 -0
- data/test/test_auth.rb +68 -0
- data/test/test_client.rb +342 -0
- data/test/test_client_links.rb +39 -0
- data/test/test_compact_nokogiri.rb +64 -0
- data/test/test_helper.rb +12 -0
- data/test/test_listing_mapper.rb +112 -0
- data/test/test_loader.rb +24 -0
- data/test/test_parser.rb +96 -0
- data/test/test_quality.rb +57 -0
- metadata +168 -53
- data/GPL +0 -340
- data/examples/metadata.xml +0 -42
- data/lib/rets4r/client/metadataindex.rb +0 -82
- data/lib/rets4r/client/parser.rb +0 -141
- data/lib/rets4r/client/parser/rexml.rb +0 -75
- data/lib/rets4r/client/parser/xmlparser.rb +0 -95
- data/test/client/parser/tc_rexml.rb +0 -17
- data/test/client/parser/tc_xmlparser.rb +0 -21
- data/test/client/tc_auth.rb +0 -68
- data/test/client/tc_client.rb +0 -320
- data/test/client/tc_metadataindex.rb +0 -36
- data/test/client/test_parser.rb +0 -128
- data/test/client/ts_all.rb +0 -8
- data/test/ts_all.rb +0 -1
- data/test/ts_client.rb +0 -1
data/test/test_client.rb
ADDED
@@ -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
|
data/test/test_helper.rb
ADDED
@@ -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'
|