collmex-ruby 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,582 @@
1
+ require "spec_helper"
2
+
3
+ sample_spec = [
4
+ { name: :identifyer, type: :string, fix: "BLA" },
5
+ { name: :b, type: :currency },
6
+ { name: :c, type: :float },
7
+ { name: :d, type: :integer },
8
+ { name: :e, type: :date },
9
+ ]
10
+
11
+ empty_hash = { identifyer: "BLA", b: nil, c: nil, d: nil, e: nil }
12
+
13
+ empty_array = ["BLA", nil, nil, nil, nil]
14
+
15
+ filled_array = ["BLA", 20, 5.1, 10, Date.parse("12.10.1985")]
16
+
17
+ filled_csv = "BLA;0,20;5,10;10;19851012\n"
18
+
19
+
20
+ describe Collmex::Api do
21
+
22
+ describe ".is_a_collmex_api_line_obj?" do
23
+ it "should fail for an array" do
24
+ a = Array.new
25
+ described_class.is_a_collmex_api_line_obj?(a).should be_false
26
+ end
27
+
28
+ it "should succeed for a Collmex::Api Object" do
29
+ b = Collmex::Api::AccdocGet.new()
30
+ described_class.is_a_collmex_api_line_obj?(b).should be_true
31
+ end
32
+ end
33
+
34
+ describe ".line_class_exists?" do
35
+ it "should be true for a existing class" do
36
+ Collmex::Api.line_class_exists?("Line").should be true
37
+ end
38
+
39
+ it "should be false for a non existant class" do
40
+ Collmex::Api.line_class_exists?("asdasdasdasdaaBla").should be false
41
+ end
42
+ end
43
+
44
+ describe ".stringify_field" do
45
+ tests = [
46
+ { type: :string, input: "asd", outcome: "asd" },
47
+ { type: :string, input: "", outcome: "" },
48
+ { type: :string, input: nil, outcome: "" },
49
+
50
+ { type: :integer, input: nil, outcome: "" },
51
+ { type: :integer, input: 2, outcome: "2" },
52
+ { type: :integer, input: 2.2, outcome: "2" },
53
+ { type: :integer, input: -2.2, outcome: "-2" },
54
+ { type: :integer, input: "-2.2", outcome: "-2" },
55
+
56
+ { type: :float, input: 2.2, outcome: "2,20" },
57
+ { type: :float, input: 2, outcome: "2,00" },
58
+ { type: :float, input: "2", outcome: "2,00" },
59
+ { type: :float, input: "-2.00", outcome: "-2,00" },
60
+ { type: :float, input: -2.00, outcome: "-2,00" },
61
+
62
+ { type: :currency, input: 2, outcome: "0,02" },
63
+ { type: :currency, input: "2", outcome: "0,02" },
64
+ { type: :currency, input: "-2.23", outcome: "-2,23" }, # <= WARNING
65
+ { type: :currency, input: "-2,23", outcome: "-2,23" }, # <= WARNING
66
+ { type: :currency, input: -2.00, outcome: "-2,00" },
67
+ { type: :currency, input: -2.90, outcome: "-2,90" },
68
+ { type: :currency, input: -2.999, outcome: "-3,00" },
69
+ { type: :currency, input: -102.90, outcome: "-102,90" }, # <= WARNING
70
+
71
+
72
+ ]
73
+ tests.each do |test|
74
+ it "should represent #{test[:type]} \"#{test[:input].inspect}\" as \"#{test[:outcome]}\"" do
75
+ described_class.stringify(test[:input],test[:type]).should === test[:outcome]
76
+ end
77
+ end
78
+ end
79
+
80
+
81
+ describe ".parse_line" do
82
+ context "when given a valid line" do
83
+ context "as an array" do
84
+ it "should instanciate an api line object" do
85
+ line = Collmex::Api::Login.new([12,34]).to_a
86
+ described_class.parse_line(line).should be_a Collmex::Api::Line
87
+ end
88
+ end
89
+ context "as n csv string" do
90
+ it "should instanciate an api line object" do
91
+ line = Collmex::Api::Login.new([12,34]).to_csv
92
+ described_class.parse_line(line).should be_a Collmex::Api::Line
93
+ end
94
+ end
95
+ end
96
+
97
+ context "when given an invalid line" do
98
+ it "should throw an error" do
99
+ line = ["OMG", 2,3,4,5,6]
100
+ lambda { described_class.parse_line(line) }.should raise_error 'Could not find a Collmex::Api::Line class for "Omg"'
101
+ end
102
+ end
103
+ end
104
+
105
+ describe ".parse_field" do
106
+ tests = [
107
+ { type: :string, input: "asd", outcome: "asd" },
108
+ { type: :string, input: "2", outcome: "2" },
109
+ { type: :string, input: "2", outcome: "2" },
110
+ { type: :string, input: 2, outcome: "2" },
111
+ { type: :string, input: "-2.3", outcome: "-2.3" },
112
+ { type: :string, input: nil, outcome: "" },
113
+
114
+ { type: :date, input: nil, outcome: nil },
115
+ { type: :date, input: "19851012", outcome: Date.parse("12.10.1985") },
116
+ { type: :date, input: "1985/10/12", outcome: Date.parse("12.10.1985") },
117
+ { type: :date, input: "1985-10-12", outcome: Date.parse("12.10.1985") },
118
+
119
+
120
+ { type: :integer, input: "2,3", outcome: 2 }, # <= WARNING
121
+ { type: :integer, input: "2", outcome: 2 },
122
+ { type: :integer, input: "2.2", outcome: 2 },
123
+ { type: :integer, input: 2, outcome: 2 },
124
+ { type: :integer, input: 2.2, outcome: 2 },
125
+ { type: :integer, input: nil, outcome: nil }, # <= WARNING
126
+
127
+ { type: :float, input: "2", outcome: 2.0 },
128
+ { type: :float, input: 2, outcome: 2.0 },
129
+ { type: :float, input: 2.2, outcome: 2.2 },
130
+ { type: :float, input: "2,0", outcome: 2.0 },
131
+ { type: :float, input: "2.0", outcome: 2.0 },
132
+ { type: :float, input: "2,3", outcome: 2.3 },
133
+ { type: :float, input: "-2,3", outcome: -2.3 },
134
+ { type: :float, input: "2.2", outcome: 2.2 },
135
+ { type: :float, input: nil, outcome: nil },
136
+
137
+ { type: :currency, input: "2", outcome: 2 },
138
+ { type: :currency, input: 0, outcome: 0 },
139
+ { type: :currency, input: 2, outcome: 2 },
140
+ { type: :currency, input: 2.20, outcome: 220 },
141
+ { type: :currency, input: "0", outcome: 0 },
142
+ { type: :currency, input: "0000", outcome: 0 },
143
+ { type: :currency, input: "2,0", outcome: 200 },
144
+ { type: :currency, input: "2,1", outcome: 210 },
145
+ { type: :currency, input: "-2,1", outcome: -210 },
146
+ { type: :currency, input: "-2,1", outcome: -210 },
147
+ { type: :currency, input: "20,00", outcome: 2000 },
148
+ { type: :currency, input: "20,12", outcome: 2012 },
149
+ { type: :currency, input: "-20,12", outcome: -2012 },
150
+ { type: :currency, input: nil, outcome: nil },
151
+ { type: :currency, input: "-20.12", outcome: -2012 },
152
+ { type: :currency, input: "-20.", outcome: -2000 },
153
+ { type: :currency, input: "20.", outcome: 2000 },
154
+ { type: :currency, input: ".20", outcome: 20 },
155
+ { type: :currency, input: "-,20", outcome: -20 },
156
+ { type: :currency, input: ",20", outcome: 20 },
157
+
158
+ { type: :currency, input: "20,000", outcome: 2000000 },
159
+ { type: :currency, input: "123,456", outcome: 12345600 },
160
+ { type: :currency, input: "123,456,789", outcome: 12345678900 },
161
+ { type: :currency, input: "123.456.789", outcome: 12345678900 },
162
+ { type: :currency, input: "23.456.789", outcome: 2345678900 },
163
+ { type: :currency, input: "-23.456.000", outcome: -2345600000},
164
+ { type: :currency, input: "-23,456,000", outcome: -2345600000 },
165
+
166
+ { type: :currency, input: "-23,456.00", outcome: -2345600 },
167
+ { type: :currency, input: "23,456.13", outcome: 2345613 },
168
+
169
+ { type: :currency, input: "21,000", outcome: 2100000 },
170
+ { type: :currency, input: "12.345,20", outcome: 1234520 },
171
+
172
+ ]
173
+ tests.each_with_index do |t,i|
174
+ it "should parse #{t[:type]} value for \"#{t[:input]}\"" do
175
+ described_class.parse_field( t[:input], t[:type]).should === t[:outcome]
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ shared_examples_for "Collmex Api Command" do
182
+
183
+ describe ".hashify" do
184
+
185
+ it "should parse the fields" do
186
+ string = "BLA"
187
+ integer = 421
188
+ float = 123.23
189
+ currency = 200
190
+ date = Date.parse("12.10.1985")
191
+
192
+ output = { identifyer: string, b: currency, c: float, d: integer, e: Date.parse("12.10.1985") }
193
+
194
+ described_class.stub(:specification).and_return(sample_spec)
195
+ Collmex::Api.stub(:parse_field).with(anything(),:string).and_return string
196
+ Collmex::Api.stub(:parse_field).with(anything(),:float).and_return float
197
+ Collmex::Api.stub(:parse_field).with(anything(),:integer).and_return integer
198
+ Collmex::Api.stub(:parse_field).with(anything(),:currency).and_return currency
199
+ Collmex::Api.stub(:parse_field).with(anything(),:date).and_return date
200
+
201
+ tests = [
202
+ [1,2,3,4],
203
+ [1,nil,3],
204
+ [1],
205
+ {a: 1, b:nil},
206
+ {},
207
+ {c: 3},
208
+ "1;2;3",
209
+ "1;-2;3",
210
+ "1;-2,5;3",
211
+ ";;3",
212
+ ]
213
+
214
+ tests.each do |testdata|
215
+ described_class.hashify(testdata).should eql output
216
+ end
217
+ end
218
+
219
+ it "should set default values when nothing given" do
220
+ sample_default_spec = [
221
+ { name: :a, type: :string, default: "fixvalue" },
222
+ { name: :b, type: :currency, default: 899 },
223
+ { name: :c, type: :integer, default: 10 },
224
+ { name: :d, type: :float, default: 2.99 },
225
+ ]
226
+ sample_default_outcome = {a: "fixvalue", b: 899, c: 10, d: 2.99}
227
+ described_class.stub(:specification).and_return sample_default_spec
228
+ described_class.hashify([]).should eql sample_default_outcome
229
+ end
230
+
231
+ it "should overwrite default values when data is given" do
232
+ sample_default_spec = [
233
+ { name: :a, type: :string, default: "fixvalue" },
234
+ { name: :b, type: :currency, default: 899 },
235
+ { name: :c, type: :integer, default: 10 },
236
+ { name: :d, type: :float, default: 2.99 },
237
+ ]
238
+ sample_default_outcome = {a: "asd", b: 12, c: 1, d: 1.0}
239
+ described_class.stub(:specification).and_return sample_default_spec
240
+ described_class.hashify({a: "asd", b: 12, c: 1, d: 1}).should eql sample_default_outcome
241
+ end
242
+
243
+ it "should ignore given values for fix-value-fields" do
244
+ sample_fix_spec = [
245
+ { name: :a, type: :string, fix: "fixvalue" },
246
+ { name: :b, type: :currency, fix: 899 },
247
+ { name: :c, type: :integer, fix: 10 },
248
+ { name: :d, type: :float, fix: 2.99 },
249
+ ]
250
+ sample_fix_outcome = {a: "fixvalue", b: 899, c: 10, d: 2.99}
251
+ described_class.stub(:specification).and_return sample_fix_spec
252
+ described_class.hashify([]).should eql sample_fix_outcome
253
+ end
254
+ end
255
+
256
+ describe ".default_hash" do
257
+ it "should hold a specification" do
258
+ described_class.stub(:specification).and_return([])
259
+ described_class.default_hash.should eql({})
260
+
261
+ described_class.stub(:specification).and_return(sample_spec)
262
+ described_class.default_hash.should eql(empty_hash)
263
+ end
264
+ end
265
+
266
+ subject { described_class.new }
267
+
268
+ it { should respond_to :to_csv }
269
+ it { should respond_to :to_a }
270
+ it { should respond_to :to_s }
271
+ it { should respond_to :to_h }
272
+
273
+ describe "#initialize" do
274
+ it "should raise an error if the specification is empty and the class is not Collmex::Api::Line" do
275
+ described_class.stub(:specification).and_return({})
276
+ if described_class.name == "Collmex::Api::Line"
277
+ lambda { described_class.new }.should_not raise_error
278
+ else
279
+ lambda { described_class.new }.should raise_error "#{described_class.name} has no specification"
280
+ end
281
+ end
282
+
283
+ it "should set the instance_variable hash" do
284
+ subject.instance_variable_get(:@hash).should be_a Hash
285
+ end
286
+
287
+ context "no params given" do
288
+ it "should build the specified but empty hash" do
289
+ described_class.stub(:default_hash).and_return(empty_hash)
290
+ line = described_class.new
291
+ line.to_h.should eql(empty_hash)
292
+ end
293
+ end
294
+
295
+ context "something given" do
296
+ it "should build the specified and filled hash" do
297
+ input = {:a => "bla" }
298
+ output = empty_hash.merge(input)
299
+
300
+ described_class.stub(:default_hash).and_return(empty_hash)
301
+ described_class.stub(:hashify).and_return(output)
302
+ line = described_class.new(input)
303
+ line.to_h.should eql (output)
304
+ end
305
+ end
306
+ end
307
+
308
+ describe "#to_csv" do
309
+ it "should represent the request as csv" do
310
+ described_class.stub(:specification).and_return(sample_spec)
311
+ subject.instance_variable_set(:@hash, described_class.hashify(filled_array))
312
+ subject.to_csv.should eql filled_csv
313
+ end
314
+ end
315
+
316
+ describe "#to_h" do
317
+ it "should return the hash" do
318
+ h = { first: 1, second: 2 }
319
+ subject.instance_variable_set(:@hash, h)
320
+ subject.to_h.should eql h
321
+ end
322
+ end
323
+
324
+ describe "#to_a" do
325
+ it "should return the empty_hash translated to an array" do
326
+ described_class.stub(:specification).and_return(sample_spec)
327
+ subject.to_a.should eql empty_array
328
+ end
329
+ end
330
+
331
+
332
+ end
333
+
334
+ describe Collmex::Api::Line do
335
+ it_behaves_like "Collmex Api Command"
336
+ end
337
+
338
+ describe Collmex::Api::Login do
339
+ subject { Collmex::Api::Login.new({:username => 12, :password => 34}) }
340
+ it_behaves_like "Collmex Api Command"
341
+ spec =
342
+ [
343
+ { name: :identifyer, type: :string, fix: "LOGIN" },
344
+ { name: :username, type: :integer },
345
+ { name: :password, type: :integer }
346
+ ]
347
+
348
+ specify { described_class.specification.should eql spec }
349
+
350
+ output = ["LOGIN", 12, 34]
351
+ specify { subject.to_a.should eql output }
352
+ end
353
+
354
+ describe Collmex::Api::CustomerGet do
355
+ it_behaves_like "Collmex Api Command"
356
+
357
+ spec =
358
+ [
359
+ { name: :identifyer , type: :string , fix: "CUSTOMER_GET" },
360
+ { name: :id , type: :integer },
361
+ { name: :company_id , type: :integer , default: 1 },
362
+ { name: :searchtext , type: :string },
363
+ { name: :due_to_review , type: :integer },
364
+ { name: :zip_code , type: :string },
365
+ { name: :adress_group , type: :integer },
366
+ { name: :price_group , type: :integer },
367
+ { name: :discout_group , type: :integer },
368
+ { name: :agent , type: :integer },
369
+ { name: :only_changed , type: :integer },
370
+ { name: :system_name , type: :string },
371
+ { name: :inactive , type: :integer },
372
+ ]
373
+
374
+ specify { described_class.specification.should eql spec }
375
+
376
+ subject { described_class.new( {:customer_id => 9999} ) }
377
+
378
+ output = ["CUSTOMER_GET", nil, 1, "", nil, "", nil, nil, nil, nil, nil, "", nil]
379
+
380
+ specify { subject.to_a.should eql output }
381
+ end
382
+
383
+ describe Collmex::Api::AccdocGet do
384
+ it_behaves_like "Collmex Api Command"
385
+
386
+ spec =
387
+ [
388
+ { name: :identifyer , type: :string , fix: "ACCDOC_GET" },
389
+ { name: :company_id , type: :integer , default: 1 },
390
+ { name: :business_year , type: :integer },
391
+ { name: :id , type: :integer },
392
+ { name: :account_id , type: :integer },
393
+ { name: :cost_unit , type: :integer },
394
+ { name: :customer_id , type: :integer },
395
+ { name: :provider_id , type: :integer },
396
+ { name: :asset_id , type: :integer },
397
+ { name: :invoice_id , type: :integer },
398
+ { name: :jorney_id , type: :integer },
399
+ { name: :text , type: :string },
400
+ { name: :date_start , type: :date },
401
+ { name: :date_end , type: :date },
402
+ { name: :cancellattion , type: :integer },
403
+ { name: :changed_only , type: :integer },
404
+ { name: :system_name , type: :string },
405
+ ]
406
+
407
+
408
+
409
+ specify { described_class.specification.should eql spec }
410
+
411
+ subject { described_class.new( {id: 1} ) }
412
+
413
+ output = ["ACCDOC_GET", 1, nil, 1, nil, nil, nil, nil, nil, nil, nil, "", nil, nil, nil, nil, ""]
414
+
415
+ specify { subject.to_a.should eql output }
416
+ end
417
+
418
+
419
+ describe Collmex::Api::Cmxknd do
420
+
421
+ it_behaves_like "Collmex Api Command"
422
+ spec =
423
+ [
424
+ { name: :identifyer , type: :string , fix: "CMXKND" },
425
+ { name: :customer_id , type: :integer },
426
+ { name: :company_id , type: :integer , default: 1 },
427
+ { name: :salutation , type: :string },
428
+ { name: :title , type: :string },
429
+ { name: :firstname , type: :string },
430
+ { name: :lastname , type: :string },
431
+ { name: :comapyn , type: :string },
432
+ { name: :department , type: :string },
433
+ { name: :street , type: :string },
434
+ { name: :zipcode , type: :string },
435
+ { name: :city , type: :string },
436
+ { name: :annotation , type: :string },
437
+ { name: :inactive , type: :integer },
438
+ { name: :country , type: :string },
439
+ { name: :phone , type: :string },
440
+ { name: :fax , type: :string },
441
+ { name: :email , type: :string },
442
+ { name: :account_id , type: :string },
443
+ { name: :blz , type: :string },
444
+ { name: :iban , type: :string },
445
+ { name: :bic , type: :string },
446
+ { name: :bank_name , type: :string },
447
+ { name: :vat_id , type: :string },
448
+ { name: :payment_condition, type: :integer },
449
+ { name: :dscout_group , type: :integer },
450
+ { name: :deliver_conditions, type: :string },
451
+ { name: :deliver_conditions_additions, type: :string },
452
+ { name: :output_media , type: :integer },
453
+ { name: :account_owner , type: :string },
454
+ { name: :address_group , type: :integer },
455
+ { name: :ebay_member , type: :string },
456
+ { name: :price_group , type: :integer },
457
+ { name: :currency , type: :string },
458
+ { name: :agent , type: :integer },
459
+ { name: :cost_unit , type: :string },
460
+ { name: :due_to , type: :date },
461
+ { name: :delivery_ban , type: :integer },
462
+ { name: :building_servant , type: :integer },
463
+ { name: :account_id_at_customer, type: :string },
464
+ { name: :output_language , type: :integer },
465
+ { name: :email_cc , type: :string },
466
+ { name: :phone_2 , type: :string },
467
+ ]
468
+
469
+ specify { described_class.specification.should eql spec }
470
+
471
+ subject { described_class.new( {id: 1} ) }
472
+
473
+ output = ["CMXKND", nil, 1, "", "", "", "", "", "", "", "", "", "", nil, "", "", "", "", "", "", "", "", "", "", nil, nil, "", "", nil, "", nil, "", nil, "", nil, "", nil, nil, nil, "", nil, "", ""]
474
+
475
+ specify { subject.to_a.should eql output }
476
+ end
477
+
478
+
479
+ describe Collmex::Api::Message do
480
+
481
+ it_behaves_like "Collmex Api Command"
482
+
483
+ spec =
484
+ [
485
+ { name: :identifyer , type: :string , fix: "MESSAGE" },
486
+ { name: :type , type: :string },
487
+ { name: :id , type: :integer },
488
+ { name: :text , type: :string },
489
+ { name: :line , type: :integer },
490
+ ]
491
+
492
+ specify { described_class.specification.should eql spec }
493
+
494
+ subject { described_class.new( ) }
495
+
496
+ output = ["MESSAGE", "", nil, "", nil]
497
+
498
+ specify { subject.to_a.should eql output }
499
+
500
+ context "success" do
501
+ subject { described_class.new(type: "S") }
502
+ specify do
503
+ subject.success?.should eql true
504
+ subject.result.should eql :success
505
+ end
506
+ end
507
+
508
+ context "warning" do
509
+ subject { described_class.new(type: "W") }
510
+ specify do
511
+ subject.success?.should eql false
512
+ subject.result.should eql :warning
513
+ end
514
+ end
515
+
516
+ context "error" do
517
+ subject { described_class.new(type: "E") }
518
+ specify do
519
+ subject.success?.should eql false
520
+ subject.result.should eql :error
521
+ end
522
+ end
523
+
524
+ context "undefined" do
525
+ subject { described_class.new() }
526
+ specify do
527
+ subject.success?.should eql false
528
+ subject.result.should eql :undefined
529
+ end
530
+ end
531
+
532
+
533
+ end
534
+
535
+
536
+ describe Collmex::Api::Accdoc do # fixme ACCDOC
537
+
538
+ it_behaves_like "Collmex Api Command"
539
+
540
+ spec =
541
+ [
542
+ { name: :identifyer , type: :string , fix: "ACCDOC" },
543
+ { name: :company_id , type: :integer , default: 1 },
544
+ { name: :business_year , type: :integer },
545
+ { name: :id , type: :integer },
546
+ { name: :accdoc_date , type: :date },
547
+ { name: :accounted_date , type: :date },
548
+ { name: :test , type: :string },
549
+ { name: :position_id , type: :integer },
550
+ { name: :account_id , type: :integer },
551
+ { name: :account_name , type: :string },
552
+ { name: :should_have , type: :integer },
553
+ { name: :amount , type: :currency },
554
+ { name: :customer_id , type: :integer },
555
+ { name: :customer_name , type: :string },
556
+ { name: :provider_id , type: :integer },
557
+ { name: :provider_name , type: :string },
558
+ { name: :asset_id , type: :integer },
559
+ { name: :asset_name , type: :string },
560
+ { name: :canceled_accdoc , type: :integer },
561
+ { name: :cost_unit , type: :string },
562
+ { name: :invoice_id , type: :string },
563
+ { name: :customer_order_id, type: :integer },
564
+ { name: :jorney_id , type: :integer },
565
+ { name: :belongs_to_id , type: :integer },
566
+ { name: :belongs_to_year , type: :integer },
567
+ { name: :belongs_to_pos , type: :integer },
568
+ ]
569
+
570
+
571
+
572
+ specify { described_class.specification.should eql spec }
573
+
574
+ subject { described_class.new( {id: 1} ) }
575
+
576
+ output = ["ACCDOC", 1, nil, 1, nil, nil, "", nil, nil, "", nil, nil, nil, "", nil, "", nil, "", nil, "", "", nil, nil, nil, nil, nil]
577
+
578
+ specify { subject.to_a.should eql output }
579
+ end
580
+
581
+
582
+