dhl-get_quote 0.4.25

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