afterbuy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.travis.yml +4 -0
  4. data/Gemfile +4 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +47 -0
  7. data/Rakefile +6 -0
  8. data/afterbuy.gemspec +31 -0
  9. data/lib/afterbuy.rb +43 -0
  10. data/lib/afterbuy/api.rb +101 -0
  11. data/lib/afterbuy/errors.rb +21 -0
  12. data/lib/afterbuy/middleware/error_detector.rb +15 -0
  13. data/lib/afterbuy/representer/attribute_representer.rb +18 -0
  14. data/lib/afterbuy/representer/catalog_representer.rb +16 -0
  15. data/lib/afterbuy/representer/error_representer.rb +16 -0
  16. data/lib/afterbuy/representer/global_representer.rb +20 -0
  17. data/lib/afterbuy/representer/product_picture_representer.rb +18 -0
  18. data/lib/afterbuy/representer/product_representer.rb +134 -0
  19. data/lib/afterbuy/representer/request_representer.rb +14 -0
  20. data/lib/afterbuy/representer/response_representer.rb +17 -0
  21. data/lib/afterbuy/representer/result_representer.rb +15 -0
  22. data/lib/afterbuy/representer/shop_interface_line_item_representer.rb +22 -0
  23. data/lib/afterbuy/representer/shop_interface_request_representer.rb +97 -0
  24. data/lib/afterbuy/representer/shop_interface_response_representer.rb +33 -0
  25. data/lib/afterbuy/representer/time_response_representer.rb +15 -0
  26. data/lib/afterbuy/representer/update_shop_products_request_representer.rb +10 -0
  27. data/lib/afterbuy/representer/update_shop_products_response_representer.rb +16 -0
  28. data/lib/afterbuy/representer/warning_representer.rb +16 -0
  29. data/lib/afterbuy/version.rb +3 -0
  30. data/spec/api_spec.rb +184 -0
  31. data/spec/fixtures/vcr_cassettes/Afterbuy_API/valid_configuration/_call/GetAfterbuyTime/responds_with_timestamps.yml +57 -0
  32. data/spec/fixtures/vcr_cassettes/Afterbuy_API/valid_configuration/_call/invalid_method_call/responds_with_a_call_not_found_error.yml +58 -0
  33. data/spec/fixtures/vcr_cassettes/Afterbuy_API/valid_configuration/_shop_interface_call/invalid_parameters/fails_with_error.yml +42 -0
  34. data/spec/fixtures/vcr_cassettes/Afterbuy_API/valid_configuration/_shop_interface_call/valid_parameters_with_action_CheckUserId/succeeds_and_returns_the_user_id.yml +42 -0
  35. data/spec/fixtures/vcr_cassettes/Afterbuy_API/valid_configuration/_shop_interface_call/valid_parameters_with_action_new/succeeds.yml +43 -0
  36. data/spec/representer/shop_interface_request_representer_spec.rb +29 -0
  37. data/spec/spec_helper.rb +15 -0
  38. data/spec/support/vcr_config.rb +7 -0
  39. metadata +216 -0
@@ -0,0 +1,14 @@
1
+ module Afterbuy
2
+ class Request < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class RequestRepresenter < Roar::Decorator
7
+ include Roar::XML
8
+
9
+ self.representation_wrap = :Request
10
+
11
+ property :afterbuy_global, as: :AfterbuyGlobal, extend: GlobalRepresenter, class: Global
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ module Afterbuy
2
+ class Response < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class ResponseRepresenter < Roar::Decorator
7
+ include Roar::XML
8
+
9
+ self.representation_wrap = :Afterbuy
10
+
11
+ property :call_status, as: :CallStatus
12
+ property :call_name, as: :CallName
13
+ property :version_id, as: :VersionID
14
+ property :result, as: :Result, extend: ResultRepresenter, class: Result
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module Afterbuy
2
+ class Result < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ module ResultRepresenter
7
+ include Roar::XML
8
+
9
+ self.representation_wrap = :Result
10
+
11
+ collection :errors, as: :Error, wrap: :ErrorList, extend: ErrorRepresenter, class: Error
12
+ collection :warnings, as: :Warning, wrap: :WarningList, extend: WarningRepresenter, class: Warning
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ module Afterbuy
2
+ class ShopInterfaceLineItem < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class ShopInterfaceLineItemRepresenter < Roar::Decorator
7
+ include Representable::Hash
8
+
9
+ property :artikel_nr, as: :Artikelnr
10
+ property :altern_artikel_nr1, as: :AlternArtikelNr1
11
+ property :altern_artikel_nr2, as: :AlternArtikelNr2
12
+ property :artikel_name, as: :Artikelname
13
+ property :artikel_e_preis, as: :ArtikelEpreis
14
+ property :artikel_mwst, as: :ArtikelMwSt
15
+ property :artikel_menge, as: :ArtikelMenge
16
+ property :artikel_gewicht, as: :ArtikelGewicht
17
+ property :artikel_link, as: :ArtikelLink
18
+ property :attribute, as: :Attribute
19
+ property :artikel_stamm_id, as: :ArtikelStammID
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,97 @@
1
+ module Afterbuy
2
+ class ShopInterfaceRequest < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class ShopInterfaceRequestRepresenter < Roar::Decorator
7
+ include Representable::Hash
8
+
9
+ property :action, as: :Action
10
+ property :partner_id, as: :PartnerID
11
+ property :partner_pass, as: :PartnerPass
12
+ property :user_id, as: :UserID
13
+ property :pos_anz, as: :PosAnz
14
+ property :k_benutzername, as: :Kbenutzername
15
+ property :k_anrede, as: :Kanrede
16
+ property :k_firma, as: :KFirma
17
+ property :k_vorname, as: :KVorname
18
+ property :k_nachname, as: :KNachname
19
+ property :k_strasse, as: :KStrasse
20
+ property :k_strasse2, as: :KStrasse2
21
+ property :k_plz, as: :KPLZ
22
+ property :k_ort, as: :KOrt
23
+ property :k_bundesland, as: :KBundesland
24
+ property :k_telefon, as: :Ktelefon
25
+ property :k_fax, as: :Kfax
26
+ property :k_email, as: :Kemail
27
+ property :k_land, as: :KLand
28
+ property :k_birthday, as: :KBirthday
29
+ property :lieferanschrift, as: :Lieferanschrift
30
+ property :kl_firma, as: :KLFirma
31
+ property :kl_vorname, as: :KLVorname
32
+ property :kl_nachname, as: :KLNachname
33
+ property :kl_strasse, as: :KLStrasse
34
+ property :kl_strasse2, as: :KLStrasse2
35
+ property :kl_plz, as: :KLPLZ
36
+ property :kl_ort, as: :KLOrt
37
+ property :kl_land, as: :KLLand
38
+ property :kl_telefon, as: :KLTelefon
39
+ property :haendler, as: :Haendler
40
+ property :kommentar, as: :Kommentar
41
+ property :use_compl_weight, as: :UseComplWeight
42
+ property :buy_date, as: :BuyDate
43
+ property :bestandart, as: :Bestandart
44
+ property :versandart, as: :Versandart
45
+ property :versandkosten, as: :Versandkosten
46
+ property :zahlarten_aufschlag, as: :ZahlartenAufschlag
47
+ property :zahlart, as: :Zahlart
48
+ property :z_funktions_id, as: :ZFunktionsID
49
+ property :bankname, as: :Bankname
50
+ property :blz, as: :BLZ
51
+ property :kontonummer, as: :Kontonummer
52
+ property :kontoinhaber, as: :Kontoinhaber
53
+ property :usst_id, as: :UsStID
54
+ property :no_feedback, as: :NoFeedback
55
+ property :no_versand_calc, as: :NoVersandCalc
56
+ property :versandgruppe, as: :Versandgruppe
57
+ property :mwst_nicht_ausweisen, as: :MwStNichtAusweisen
58
+ property :markierung_id, as: :MarkierungID
59
+ property :e_kunden_nr, as: :EKundenNr
60
+ property :kunden_erkennung, as: :Kundenerkennung
61
+ property :no_ebay_name_aktu, as: :NoeBayNameAktu
62
+ property :artikel_erkennung, as: :Artikelerkennung
63
+ property :v_memo, as: :VMemo
64
+ property :vid, as: :VID
65
+ property :sold_currency, as: :SoldCurrency
66
+ property :set_pay, as: :SetPay
67
+ property :pay_date, as: :PayDate
68
+ property :check_vid, as: :CheckVID
69
+ property :check_packstation, as: :CheckPackstation
70
+ property :override_mark_id, as: :OverrideMarkID
71
+ property :billsafe_transaction_id, as: :BillsafeTransactionID
72
+ property :billsafe_ordernumber, as: :BillsafeOrdernumber
73
+ property :bic, as: :BIC
74
+ property :iban, as: :IBAN
75
+ property :reference, as: :reference
76
+ property :payment_status, as: :PaymentStatus
77
+ property :payment_transaction_id, as: :PaymentTransactionId
78
+
79
+ collection :line_items, extend: ShopInterfaceLineItemRepresenter, class: ShopInterfaceLineItem
80
+
81
+ def to_hash
82
+ super.tap do |hash|
83
+ if hash.has_key? 'line_items'
84
+ hash['PosAnz'] = hash['line_items'].count
85
+
86
+ hash.delete('line_items').each.with_index do |line_item, index|
87
+ line_item.map do |k, v|
88
+ hash["#{k}_#{index+1}"] = v
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,33 @@
1
+ module Afterbuy
2
+ class ShopInterfaceResponse < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class ShopInterfaceResponseRepresenter < Roar::Decorator
7
+ include Roar::XML
8
+
9
+ self.representation_wrap = :result
10
+
11
+ property :success
12
+ property :action, as: :Action
13
+
14
+ nested :errorlist do
15
+ collection :errors, as: :error
16
+ property :order_id, as: :OrderID
17
+ property :vid, as: :VID
18
+ end
19
+
20
+ nested :data do
21
+ # data receive when action is CheckUserId
22
+ property :user_id, as: :UserID
23
+
24
+ # data receive when action is new
25
+ property :aid, as: :AID
26
+ property :uid, as: :UID
27
+ property :kunden_nr, as: :KundenNr
28
+ property :e_kunden_nr, as: :EKundenNr
29
+ property :coupon_used, as: :CouponUsed
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,15 @@
1
+ module Afterbuy
2
+ class TimeResponse < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class TimeResponseRepresenter < ResponseRepresenter
7
+ property :result, as: :Result, class: Result do
8
+ include ResultRepresenter
9
+
10
+ property :afterbuy_timestamp, as: :AfterbuyTimeStamp
11
+ property :afterbuy_universal_timestamp, as: :AfterbuyUniversalTimeStamp
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ module Afterbuy
2
+ class UpdateShopProductsRequest < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class UpdateShopProductsRequestRepresenter < RequestRepresenter
7
+ collection :products, as: :Product, wrap: :Products, extend: ProductRepresenter, class: Product
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,16 @@
1
+ module Afterbuy
2
+ class UpdateShopProductsResponse < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class UpdateShopProductsResponseRepresenter < ResponseRepresenter
7
+ property :result, as: :Result, class: Result do
8
+ include ResultRepresenter
9
+
10
+ property :parts_found, as: :PartsFound
11
+ property :skus_found, as: :SkusFound
12
+ collection :new_products, as: :NewProduct, wrap: :NewProducts, extend: ProductRepresenter, class: Product
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ module Afterbuy
2
+ class Warning < OpenStruct
3
+ end
4
+
5
+ module Representer
6
+ class WarningRepresenter < Roar::Decorator
7
+ include Roar::XML
8
+
9
+ self.representation_wrap = :Warning
10
+
11
+ property :code, as: :WarningCode
12
+ property :description, as: :WarningDescription
13
+ property :long_description, as: :WarningLongDescription
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,3 @@
1
+ module Afterbuy
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,184 @@
1
+ require 'spec_helper'
2
+
3
+ describe Afterbuy::API do
4
+
5
+ describe 'missing configuration' do
6
+ before(:all) do
7
+ Afterbuy.configure do |c|
8
+ c.partner_id = nil
9
+ c.partner_password = nil
10
+ c.user_id = nil
11
+ c.user_password = nil
12
+ end
13
+ end
14
+ specify do
15
+ expect{ described_class.new }.to raise_error Afterbuy::ConfigMissingPartnerIDError
16
+ expect{ described_class.new(partner_id: 'valid_partner_id') }.to raise_error Afterbuy::ConfigMissingPartnerPasswordError
17
+ expect{ described_class.new(partner_id: 'valid_partner_id', partner_password: 'valid_partner_password') }.to raise_error Afterbuy::ConfigMissingUserIDError
18
+ expect{ described_class.new(partner_id: 'valid_partner_id', partner_password: 'valid_partner_password', user_id: 'valid_user_id') }.to raise_error Afterbuy::ConfigMissingUserPasswordError
19
+ end
20
+
21
+ it 'allows to supply credentials via initialize' do
22
+ expect{ described_class.new(partner_id: 'valid_partner_id', partner_password: 'valid_partner_password', user_id: 'valid_user_id', user_password: 'valid_user_password') }.not_to raise_error
23
+ end
24
+
25
+ it 'sets credentials from parameters' do
26
+ api = described_class.new(partner_id: 'valid_partner_id', partner_password: 'valid_partner_password', user_id: 'valid_user_id', user_password: 'valid_user_password')
27
+ expect(api.instance_variable_get(:@partner_id)).to eq 'valid_partner_id'
28
+ expect(api.instance_variable_get(:@partner_password)).to eq 'valid_partner_password'
29
+ expect(api.instance_variable_get(:@user_id)).to eq 'valid_user_id'
30
+ expect(api.instance_variable_get(:@user_password)).to eq 'valid_user_password'
31
+ end
32
+ end
33
+
34
+ describe 'valid configuration' do
35
+ before(:all) do
36
+ Afterbuy.configure do |c|
37
+ c.partner_id = 'valid_partner_id'
38
+ c.partner_password = 'valid_partner_password'
39
+ c.user_id = 'valid_user_id'
40
+ c.user_password = 'valid_user_password'
41
+ end
42
+ end
43
+
44
+ describe '#initialize' do
45
+ it 'initializes correctly' do
46
+ expect{ subject }.not_to raise_error
47
+ expect(subject).to be_kind_of Afterbuy::API
48
+ end
49
+
50
+ it 'sets instance variables' do
51
+ expect(subject.instance_variable_get(:@partner_id)).to eq 'valid_partner_id'
52
+ expect(subject.instance_variable_get(:@partner_password)).to eq 'valid_partner_password'
53
+ expect(subject.instance_variable_get(:@user_id)).to eq 'valid_user_id'
54
+ expect(subject.instance_variable_get(:@user_password)).to eq 'valid_user_password'
55
+ expect(subject.instance_variable_get(:@api_url)).to eq Afterbuy.afterbuy_api_url
56
+ end
57
+ end
58
+
59
+ describe '#call', :vcr do
60
+ context 'invalid method call' do
61
+ specify 'responds with a call not found error' do
62
+ response = subject.call('DoSomething')
63
+ expect(response.call_status).to eql 'Error'
64
+ expect(response.result.errors).to_not be_empty
65
+ expect(response.result.errors.first.description).to eql 'Unsupported CallName.'
66
+ end
67
+ end
68
+
69
+ context 'GetAfterbuyTime' do
70
+ specify 'responds with timestamps' do
71
+ response = subject.call('GetAfterbuyTime')
72
+ expect(response.call_status).to eql 'Success'
73
+ expect(response.result.errors).to be_nil
74
+ expect(response.result.afterbuy_timestamp).to_not be_nil
75
+ expect(response.result.afterbuy_universal_timestamp).to_not be_nil
76
+ end
77
+ end
78
+ end
79
+
80
+ describe '#shop_interface_call', :vcr do
81
+ context 'invalid parameters' do
82
+ specify 'fails with error' do
83
+ response = subject.shop_interface_call(request: Afterbuy::ShopInterfaceRequest.new(action: 'new'))
84
+ expect(response.success).to eql '0'
85
+ expect(response.errors).to_not be_empty
86
+ end
87
+ end
88
+
89
+ context 'valid parameters with action CheckUserId' do
90
+ specify 'succeeds and returns the user_id' do
91
+ response = subject.shop_interface_call(request: Afterbuy::ShopInterfaceRequest.new(action: 'CheckUserId'))
92
+ expect(response.success).to eql '1'
93
+ expect(response.user_id).to eql '123456'
94
+ end
95
+ end
96
+
97
+ context 'valid parameters with action new' do
98
+ specify 'succeeds' do
99
+ request = Afterbuy::ShopInterfaceRequest.new({
100
+ action: 'new',
101
+ k_benutzername: 'carl_client',
102
+ k_email: 'client@mail.de',
103
+ k_vorname: 'Carl',
104
+ k_nachname: 'Client',
105
+ k_strasse: 'Clientstr. 4',
106
+ k_plz: '12345',
107
+ k_ort: 'Carlhausen',
108
+ k_land: 'D',
109
+ line_items: [
110
+ Afterbuy::ShopInterfaceLineItem.new(
111
+ artikel_nr: 1,
112
+ artikel_name: 'Product 1',
113
+ artikel_mwst: 19,
114
+ artikel_menge: 1,
115
+ artikel_e_preis: '9,99'
116
+ ),
117
+ Afterbuy::ShopInterfaceLineItem.new(
118
+ artikel_nr: 2,
119
+ artikel_name: 'Product 2',
120
+ artikel_mwst: 19,
121
+ artikel_menge: 2,
122
+ artikel_e_preis: '6,99'
123
+ )
124
+ ]
125
+ })
126
+ response = subject.shop_interface_call(request: request)
127
+ expect(response.success).to eql '1'
128
+ expect(response.aid).to_not be_nil
129
+ expect(response.uid).to_not be_nil
130
+ expect(response.kunden_nr).to_not be_nil
131
+ expect(response.e_kunden_nr).to_not be_nil
132
+ expect(response.coupon_used).to_not be_nil
133
+ end
134
+ end
135
+ end
136
+
137
+ describe '#request_params' do
138
+ context 'without a payload' do
139
+ specify do
140
+ expect(subject.send(:request_params, 'DoSomething')).to eql %q|<Request>
141
+ <AfterbuyGlobal>
142
+ <PartnerID>valid_partner_id</PartnerID>
143
+ <PartnerPassword>valid_partner_password</PartnerPassword>
144
+ <UserID>valid_user_id</UserID>
145
+ <UserPassword>valid_user_password</UserPassword>
146
+ <CallName>DoSomething</CallName>
147
+ <DetailLevel>0</DetailLevel>
148
+ <ErrorLanguage>EN</ErrorLanguage>
149
+ </AfterbuyGlobal>
150
+ </Request>|
151
+ end
152
+ end
153
+
154
+ context 'with extra global_params and payload' do
155
+ specify do
156
+ payload = { products: [] }
157
+ payload[:products] << Afterbuy::Product.new({
158
+ product_ident: OpenStruct.new(product_id: 123),
159
+ name: "a product"
160
+ })
161
+ expect(subject.send(:request_params, 'UpdateShopProducts', { error_language: 'DE'}, payload)).to eql %q|<Request>
162
+ <AfterbuyGlobal>
163
+ <PartnerID>valid_partner_id</PartnerID>
164
+ <PartnerPassword>valid_partner_password</PartnerPassword>
165
+ <UserID>valid_user_id</UserID>
166
+ <UserPassword>valid_user_password</UserPassword>
167
+ <CallName>UpdateShopProducts</CallName>
168
+ <DetailLevel>0</DetailLevel>
169
+ <ErrorLanguage>EN</ErrorLanguage>
170
+ </AfterbuyGlobal>
171
+ <Products>
172
+ <Product>
173
+ <ProductIdent>
174
+ <ProductID>123</ProductID>
175
+ </ProductIdent>
176
+ <Name>a product</Name>
177
+ </Product>
178
+ </Products>
179
+ </Request>|
180
+ end
181
+ end
182
+ end
183
+ end
184
+ end