collmex-ruby 0.1.0

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,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
+