dhl-get_quote 0.4.25

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.
@@ -0,0 +1,104 @@
1
+ require 'spec_helper'
2
+ require 'dhl-get_quote'
3
+
4
+ describe Dhl::GetQuote::Piece do
5
+
6
+ let(:valid_params) do
7
+ { :height => 1, :weight => 2, :width => 3, :depth => 4 }
8
+ end
9
+
10
+ let(:klass) { Dhl::GetQuote::Piece }
11
+
12
+ subject do
13
+ klass.new(valid_params)
14
+ end
15
+
16
+ describe ".new" do
17
+ it "must return an instance of Dhl::Piece" do
18
+ klass.new(valid_params).must be_an_instance_of(klass)
19
+ end
20
+
21
+ it "must throw an error if a weight is not passed" do
22
+ lambda do
23
+ klass.new(valid_params.merge(:weight => nil))
24
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
25
+ end
26
+
27
+ it "must allow only weight to be passed" do
28
+ klass.new( { :weight => 1 } ).must be_an_instance_of(klass)
29
+ end
30
+
31
+ it "must throw an error if a height is passed but width or depth is not" do
32
+ lambda do
33
+ klass.new(valid_params.merge(:width => nil))
34
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
35
+ lambda do
36
+ klass.new(valid_params.merge(:depth => nil))
37
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
38
+ end
39
+
40
+ it "must throw an error if a width is passed but height or depth is not" do
41
+ lambda do
42
+ klass.new(valid_params.merge(:height => nil))
43
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
44
+ lambda do
45
+ klass.new(valid_params.merge(:depth => nil))
46
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
47
+ end
48
+
49
+ it "must throw an error if a depth is passed but height or width is not" do
50
+ lambda do
51
+ klass.new(valid_params.merge(:height => nil))
52
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
53
+ lambda do
54
+ klass.new(valid_params.merge(:width => nil))
55
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
56
+ end
57
+ end
58
+
59
+ describe "#to_h" do
60
+ it "must return a hash representing the object" do
61
+ subject.to_h.must == {
62
+ "Height" => 1,
63
+ "Weight" => 2,
64
+ "Width" => 3,
65
+ "Depth" => 4
66
+ }
67
+ end
68
+ end
69
+
70
+ describe "#to_xml" do
71
+ it "must return an xml string representing the object" do
72
+ subject.to_xml.must == <<eos
73
+ <Piece>
74
+ <PieceID>1</PieceID>
75
+ <Height>1</Height>
76
+ <Depth>4</Depth>
77
+ <Width>3</Width>
78
+ <Weight>2</Weight>
79
+ </Piece>
80
+ eos
81
+ end
82
+
83
+ it "must generate a xml with only weight and PieceID" do
84
+ dhl = klass.new( { :weight => 99 } )
85
+ dhl.to_xml.must == <<eos
86
+ <Piece>
87
+ <PieceID>1</PieceID>
88
+ <Weight>99</Weight>
89
+ </Piece>
90
+ eos
91
+ end
92
+
93
+ it "must allow PieceID to be overridd" do
94
+ dhl = klass.new( { :weight => 1 } )
95
+ dhl.piece_id = 88
96
+ dhl.to_xml.must == <<eos
97
+ <Piece>
98
+ <PieceID>88</PieceID>
99
+ <Weight>1</Weight>
100
+ </Piece>
101
+ eos
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,482 @@
1
+ require 'spec_helper'
2
+ require 'dhl-get_quote'
3
+
4
+ describe Dhl::GetQuote::Request do
5
+
6
+ let(:valid_params) do
7
+ {
8
+ :site_id => 'SomeId',
9
+ :password => 'p4ssw0rd'
10
+ }
11
+ end
12
+
13
+ let(:klass) { Dhl::GetQuote::Request }
14
+
15
+ subject do
16
+ klass.new(valid_params)
17
+ end
18
+
19
+ describe ".new" do
20
+ it "must return an instance of Dhl::GetQuote" do
21
+ klass.new(valid_params).must be_an_instance_of(Dhl::GetQuote::Request)
22
+ end
23
+
24
+ it "must throw an error if a site id is not passed" do
25
+ lambda do
26
+ klass.new(valid_params.merge(:site_id => nil))
27
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
28
+ end
29
+
30
+ it "must throw an error if a password is not passed" do
31
+ lambda do
32
+ klass.new(valid_params.merge(:password => nil))
33
+ end.must raise_exception(Dhl::GetQuote::OptionsError)
34
+ end
35
+ end
36
+
37
+ describe '#from' do
38
+ it 'requires a country code as and postal code as parameters' do
39
+ subject.from('US', '84111')
40
+
41
+ subject.from_country_code.must == 'US'
42
+ subject.from_postal_code.must == '84111'
43
+ end
44
+
45
+ it 'converts postal codes to strings' do
46
+ subject.from('US', 84111)
47
+
48
+ subject.from_postal_code.must == '84111'
49
+ end
50
+
51
+ it 'must raise error if country code is not 2 letters long' do
52
+ lambda do
53
+ subject.from('DDF', '84111')
54
+ end.must raise_exception(Dhl::GetQuote::CountryCodeError)
55
+
56
+ lambda do
57
+ subject.from('D', '84111')
58
+ end.must raise_exception(Dhl::GetQuote::CountryCodeError)
59
+ end
60
+
61
+ it 'must raise error if country code is not upper case' do
62
+ lambda do
63
+ subject.from('us', '84111')
64
+ end.must raise_exception(Dhl::GetQuote::CountryCodeError)
65
+ end
66
+ end
67
+
68
+ describe '#to' do
69
+ it 'requires a country code as and postal code as parameters' do
70
+ subject.to('CA', 'T1H 0A1')
71
+
72
+ subject.to_country_code.must == 'CA'
73
+ subject.to_postal_code.must == 'T1H 0A1'
74
+ end
75
+
76
+ it 'converts postal codes to strings' do
77
+ subject.to('CA', 1111)
78
+
79
+ subject.to_postal_code.must == '1111'
80
+ end
81
+
82
+ it 'must raise error if country code is not 2 letters long' do
83
+ lambda do
84
+ subject.from('DDF', 'T1H 0A1')
85
+ end.must raise_exception(Dhl::GetQuote::CountryCodeError)
86
+
87
+ lambda do
88
+ subject.from('D', 'T1H 0A1')
89
+ end.must raise_exception(Dhl::GetQuote::CountryCodeError)
90
+ end
91
+
92
+ it 'must raise error if country code is not upper case' do
93
+ lambda do
94
+ subject.from('ca', 'T1H 0A1')
95
+ end.must raise_exception(Dhl::GetQuote::CountryCodeError)
96
+ end
97
+ end
98
+
99
+ describe "#dutiable?" do
100
+ it "must be true if dutiable set to yes" do
101
+ subject.instance_variable_set(:@is_dutiable, true)
102
+ subject.dutiable?.must be_true
103
+ end
104
+
105
+ it "must be false if dutiable set to no" do
106
+ subject.instance_variable_set(:@is_dutiable, false)
107
+ subject.dutiable?.must be_false
108
+ end
109
+
110
+ it "must default to false" do
111
+ subject.dutiable?.must be_false
112
+ end
113
+ end
114
+
115
+ describe "#dutiable" do
116
+ it "must set dutiable to true if passed a true value" do
117
+ subject.dutiable(true)
118
+ subject.dutiable?.must be_true
119
+ end
120
+
121
+ it "must set dutiable to false if passed a false value" do
122
+ subject.dutiable(false)
123
+ subject.dutiable?.must be_false
124
+ end
125
+ end
126
+
127
+ describe "#dutiable!" do
128
+ it "must set dutiable() to true" do
129
+ subject.dutiable?.must be_false #sanity
130
+
131
+ subject.dutiable!
132
+ subject.dutiable?.must be_true
133
+ end
134
+ end
135
+
136
+ describe "#not_dutiable!" do
137
+ it "must set dutiable() to false" do
138
+ subject.instance_variable_set(:@is_dutiable, true)
139
+ subject.dutiable?.must be_true #sanity
140
+
141
+ subject.not_dutiable!
142
+ subject.dutiable?.must be_false
143
+ end
144
+ end
145
+
146
+ describe "#weight_unit" do
147
+ it "must return the set weight unit" do
148
+ subject.instance_variable_set(:@weight_unit, "LB")
149
+ subject.weight_unit.must == "LB"
150
+ end
151
+
152
+ it "must default to KG if not otherwise set" do
153
+ subject.instance_variable_set(:@weight_unit, nil)
154
+ subject.weight_unit.must == "KG"
155
+ end
156
+ end
157
+
158
+ describe "#dimensions_unit" do
159
+ it "must return the set weight unit" do
160
+ subject.instance_variable_set(:@dimensions_unit, "IN")
161
+ subject.dimensions_unit.must == "IN"
162
+ end
163
+
164
+ it "must default to CM if not otherwise set" do
165
+ subject.instance_variable_set(:@dimensions_unit, nil)
166
+ subject.dimensions_unit.must == "CM"
167
+ end
168
+ end
169
+
170
+ describe "#centimeters!" do
171
+ it "must set the dimensions_unit to centimeters" do
172
+ subject.instance_variable_set(:@dimensions_unit, nil)
173
+
174
+ subject.centimeters!
175
+ subject.dimensions_unit.must == "CM"
176
+ end
177
+ end
178
+
179
+ describe "#inches!" do
180
+ it "must set the dimensions_unit to inches" do
181
+ subject.instance_variable_set(:@dimensions_unit, nil)
182
+
183
+ subject.inches!
184
+ subject.dimensions_unit.must == "IN"
185
+ end
186
+ end
187
+
188
+ describe "#inches?" do
189
+ it "must be true if dimensions unit is set to inches" do
190
+ subject.instance_variable_set(:@dimensions_unit, "IN")
191
+ subject.inches?.must be_true
192
+ end
193
+
194
+ it "must be false if dimensions unit is not set to inches" do
195
+ subject.instance_variable_set(:@dimensions_unit, "CM")
196
+ subject.inches?.must be_false
197
+ end
198
+ end
199
+
200
+ describe "#centimeters?" do
201
+ it "must be true if dimensions unit is set to centimeters" do
202
+ subject.instance_variable_set(:@dimensions_unit, "CM")
203
+ subject.centimeters?.must be_true
204
+ end
205
+
206
+ it "must be false if dimensions unit is not set to centimeters" do
207
+ subject.instance_variable_set(:@dimensions_unit, "IN")
208
+ subject.centimeters?.must be_false
209
+ end
210
+ end
211
+
212
+ describe "#kilograms!" do
213
+ it "must set the weight unit to kilograms" do
214
+ subject.instance_variable_set(:@weight_unit, nil)
215
+
216
+ subject.kilograms!
217
+ subject.weight_unit.must == "KG"
218
+ end
219
+ end
220
+
221
+ describe "#pounds!" do
222
+ it "must set the weight unit to pounds" do
223
+ subject.instance_variable_set(:@weight_unit, nil)
224
+
225
+ subject.pounds!
226
+ subject.weight_unit.must == "LB"
227
+ end
228
+ end
229
+
230
+ describe "#kilograms?" do
231
+ it "must be true if weight unit is set to kilograms" do
232
+ subject.instance_variable_set(:@weight_unit, "KG")
233
+ subject.kilograms?.must be_true
234
+ end
235
+
236
+ it "must be false if dimensions unit is not set to inches" do
237
+ subject.instance_variable_set(:@weight_unit, "LB")
238
+ subject.kilograms?.must be_false
239
+ end
240
+ end
241
+
242
+ describe "#pounds?" do
243
+ it "must be true if weight unit is set to pounds" do
244
+ subject.instance_variable_set(:@weight_unit, "LB")
245
+ subject.pounds?.must be_true
246
+ end
247
+
248
+ it "must be false if weight unit is not set to pounds" do
249
+ subject.instance_variable_set(:@weight_unit, "KG")
250
+ subject.pounds?.must be_false
251
+ end
252
+ end
253
+
254
+ describe "#to_xml" do
255
+ before(:each) do
256
+ subject.from('US', 84010)
257
+ subject.to('CA', 'T1H 0A1')
258
+ end
259
+
260
+ let(:time) { Time.now }
261
+
262
+ let(:mock_piece) do
263
+ mock(:piece,
264
+ :to_xml => [
265
+ "<Piece>",
266
+ "#{" "*20}<Height>20</Height>",
267
+ "#{" "*20}<Depth>20</Depth>",
268
+ "#{" "*20}<Width>20</Width>",
269
+ "#{" "*20}<Weight>19</Weight>",
270
+ "#{" "*16}</Piece>"
271
+ ].join("\n"),
272
+ :validate! => nil,
273
+ :piece_id= => nil
274
+ )
275
+ end
276
+
277
+ # gsub here removes leading whitespace which may be variable.
278
+ let(:xml_output) { subject.to_xml.gsub(/^\s+/, '') }
279
+
280
+ it "must return an XML version of the object including Pieces" do
281
+
282
+ subject.pieces << mock_piece
283
+ subject.stub(:validate!)
284
+
285
+ correct_response = <<eos
286
+ <?xml version="1.0" encoding="UTF-8"?>
287
+ <p:DCTRequest xmlns:p="http://www.dhl.com" xmlns:p1="http://www.dhl.com/datatypes" xmlns:p2="http://www.dhl.com/DCTRequestdatatypes" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.dhl.com DCT-req.xsd ">
288
+ <GetQuote>
289
+ <Request>
290
+ <ServiceHeader>
291
+ <SiteID>SomeId</SiteID>
292
+ <Password>p4ssw0rd</Password>
293
+ </ServiceHeader>
294
+ </Request>
295
+ <From>
296
+ <CountryCode>US</CountryCode>
297
+ <Postalcode>84010</Postalcode>
298
+ </From>
299
+ <BkgDetails>
300
+ <PaymentCountryCode>US</PaymentCountryCode>
301
+ <Date>#{time.strftime("%Y-%m-%d")}</Date>
302
+ <ReadyTime>#{subject.ready_time(time)}</ReadyTime>
303
+ <ReadyTimeGMTOffset>+00:00</ReadyTimeGMTOffset>
304
+ <DimensionUnit>#{subject.dimensions_unit}</DimensionUnit>
305
+ <WeightUnit>#{subject.weight_unit}</WeightUnit>
306
+ <Pieces>
307
+ <Piece>
308
+ <Height>20</Height>
309
+ <Depth>20</Depth>
310
+ <Width>20</Width>
311
+ <Weight>19</Weight>
312
+ </Piece>
313
+ </Pieces>
314
+ <IsDutiable>N</IsDutiable>
315
+ </BkgDetails>
316
+ <To>
317
+ <CountryCode>CA</CountryCode>
318
+ <Postalcode>T1H 0A1</Postalcode>
319
+ </To>
320
+ </GetQuote>
321
+ </p:DCTRequest>
322
+ eos
323
+ xml_output.must == correct_response
324
+ end
325
+
326
+ context "one special service is specified" do
327
+
328
+ before(:each) { subject.add_special_service("D") }
329
+
330
+ it "must add SpecialServiceType tags to XML" do
331
+ sst_xml = "<QtdShp>
332
+ <QtdShpExChrg>
333
+ <SpecialServiceType>D</SpecialServiceType>
334
+ </QtdShpExChrg>
335
+ </QtdShp>"
336
+ xml_output.must =~ /#{(sst_xml.gsub(/^\s+/, ''))}/
337
+ end
338
+ end
339
+
340
+ context "many special services are specified" do
341
+
342
+ before(:each) do
343
+ subject.add_special_service("D")
344
+ subject.add_special_service("SA")
345
+ end
346
+
347
+ it "must add SpecialServiceType tags to XML" do
348
+ sst_xml = <<eos
349
+ <QtdShp>
350
+ <QtdShpExChrg>
351
+ <SpecialServiceType>D</SpecialServiceType>
352
+ </QtdShpExChrg>
353
+ <QtdShpExChrg>
354
+ <SpecialServiceType>SA</SpecialServiceType>
355
+ </QtdShpExChrg>
356
+ </QtdShp>
357
+ eos
358
+ xml_output.must =~ /#{(sst_xml.gsub(/^\s+/, ''))}/
359
+ end
360
+ end
361
+ end
362
+
363
+ describe "#post" do
364
+ let(:mock_httparty_response) do
365
+ mock(:httparty_response, :body => nil)
366
+ end
367
+ let(:mock_response_object) { mock(:response_object) }
368
+ before(:each) do
369
+ subject.stub(:to_xml).and_return('<xml></xml>')
370
+ subject.stub!(:validate!)
371
+ HTTParty.stub!(:post).and_return(
372
+ mock(:httparty, :response => mock_httparty_response)
373
+ )
374
+ Dhl::GetQuote::Response.stub!(:new).and_return(mock_response_object)
375
+ end
376
+
377
+ it "must validate the object" do
378
+ subject.must_receive(:validate!)
379
+
380
+ subject.post
381
+ end
382
+
383
+ it "must post to server" do
384
+ HTTParty.must_receive(:post).with(
385
+ Dhl::GetQuote::Request::URLS[:production],
386
+ {
387
+ :body => '<xml></xml>',
388
+ :headers => { 'Content-Type' => 'application/xml' }
389
+ }
390
+ )
391
+
392
+ subject.post
393
+ end
394
+
395
+ it "must return a new Response object" do
396
+ subject.post.must == mock_response_object
397
+ end
398
+
399
+ end
400
+
401
+ describe "#add_special_service" do
402
+ before(:each) { subject.special_services.must == [] }
403
+ it "should accept a single string of the special service type code and add it to the list" do
404
+ subject.add_special_service("D")
405
+ subject.special_services.must == ["D"] #sanity
406
+ end
407
+
408
+ it "should not add the same service twice" do
409
+ subject.add_special_service("SA")
410
+ subject.add_special_service("SA")
411
+ subject.special_services.must == ["SA"]
412
+ end
413
+
414
+ it "should not add anything if service type code passed is blank" do
415
+ subject.add_special_service("")
416
+ subject.special_services.must == []
417
+ end
418
+ end
419
+
420
+ describe "#remove_special_service" do
421
+ before(:each) do
422
+ subject.instance_variable_set(:@special_services_list, Set.new(["D"]))
423
+ end
424
+
425
+ it "should accept a single string of the special service type code and remove it from the list" do
426
+ subject.remove_special_service("D")
427
+ subject.special_services.must == [] #sanity
428
+ end
429
+
430
+ it "should throw an error if service to be removed does not exist in list" do
431
+ subject.remove_special_service("SA")
432
+ subject.special_services.must == ["D"]
433
+ end
434
+
435
+ it "should not add anything if service type code passed is blank" do
436
+ subject.remove_special_service("")
437
+ subject.special_services.must == ["D"]
438
+ end
439
+ end
440
+
441
+ describe "#special_services" do
442
+ before(:each) do
443
+ subject.instance_variable_set(:@special_services_list, Set.new(["D"]))
444
+ end
445
+
446
+ it "must return an array of the special service codes" do
447
+ subject.special_services.must == ["D"]
448
+ end
449
+ end
450
+
451
+ describe "#test_mode?" do
452
+ it "must be false if not in test mode" do
453
+ subject.instance_variable_set(:@test_mode, false)
454
+
455
+ subject.test_mode?.must be_false
456
+ end
457
+
458
+ it "must be false if not in test mode" do
459
+ subject.instance_variable_set(:@test_mode, true)
460
+
461
+ subject.test_mode?.must be_true
462
+ end
463
+ end
464
+
465
+ describe "#test_mode!" do
466
+ it "must set test_mode to true" do
467
+ subject.instance_variable_set(:@test_mode, false)
468
+
469
+ subject.test_mode!
470
+ subject.instance_variable_get(:@test_mode).must be_true
471
+ end
472
+ end
473
+
474
+ describe "#production_mode!" do
475
+ it "must set test_mode to false" do
476
+ subject.instance_variable_set(:@test_mode, true)
477
+
478
+ subject.production_mode!
479
+ subject.instance_variable_get(:@test_mode).must be_false
480
+ end
481
+ end
482
+ end