ship_compliant 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.travis.yml +8 -0
  4. data/Gemfile +7 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +50 -0
  7. data/Rakefile +47 -0
  8. data/cucumber.yml +9 -0
  9. data/features/add_update_brand.feature +20 -0
  10. data/features/add_update_product.feature +24 -0
  11. data/features/check_compliance_of_sales_order_with_address_validations.feature +18 -0
  12. data/features/commit_sales_order.feature +6 -0
  13. data/features/get_inventory_details.feature +7 -0
  14. data/features/get_sales_order_extended.feature +15 -0
  15. data/features/search_sales_orders.feature +13 -0
  16. data/features/step_definitions/brand_steps.rb +73 -0
  17. data/features/step_definitions/commit_sales_order/all_shipments.rb +15 -0
  18. data/features/step_definitions/compliance_check/available_product_steps.rb +175 -0
  19. data/features/step_definitions/compliance_check/missing_product_steps.rb +102 -0
  20. data/features/step_definitions/compliance_check/noncompliant_product.rb +102 -0
  21. data/features/step_definitions/credential_steps.rb +8 -0
  22. data/features/step_definitions/inventory_steps.rb +36 -0
  23. data/features/step_definitions/product_steps.rb +140 -0
  24. data/features/step_definitions/sales_order_extended_steps.rb +79 -0
  25. data/features/step_definitions/search_order_steps.rb +87 -0
  26. data/features/step_definitions/void_order_steps.rb +27 -0
  27. data/features/support/env.rb +14 -0
  28. data/features/void_sales_order.feature +11 -0
  29. data/fixtures/vcr_cassettes/brand_already_exists.yml +1038 -0
  30. data/fixtures/vcr_cassettes/brand_ignore_existing.yml +1037 -0
  31. data/fixtures/vcr_cassettes/brand_update_existing.yml +1037 -0
  32. data/fixtures/vcr_cassettes/brand_valid.yml +1037 -0
  33. data/fixtures/vcr_cassettes/commit_salesorder_all_shipments.yml +1034 -0
  34. data/fixtures/vcr_cassettes/compliance_available_product.yml +1075 -0
  35. data/fixtures/vcr_cassettes/compliance_missing_product.yml +1046 -0
  36. data/fixtures/vcr_cassettes/compliance_noncompliant_product.yml +1082 -0
  37. data/fixtures/vcr_cassettes/ignore_existing_product.yml +1035 -0
  38. data/fixtures/vcr_cassettes/invalid_search_sales_orders.yml +1038 -0
  39. data/fixtures/vcr_cassettes/inventory_details_for_everything.yml +1037 -0
  40. data/fixtures/vcr_cassettes/product_already_exists.yml +1036 -0
  41. data/fixtures/vcr_cassettes/product_invalid_brand.yml +1036 -0
  42. data/fixtures/vcr_cassettes/product_valid_brand.yml +1035 -0
  43. data/fixtures/vcr_cassettes/sales_order_extended.yml +1042 -0
  44. data/fixtures/vcr_cassettes/sales_order_missing.yml +1034 -0
  45. data/fixtures/vcr_cassettes/search_sales_orders.yml +1039 -0
  46. data/fixtures/vcr_cassettes/update_product.yml +1035 -0
  47. data/fixtures/vcr_cassettes/void_order.yml +1033 -0
  48. data/fixtures/vcr_cassettes/void_voided_order.yml +1034 -0
  49. data/lib/ship_compliant.rb +62 -0
  50. data/lib/ship_compliant/add_update_brand.rb +50 -0
  51. data/lib/ship_compliant/add_update_brand_result.rb +6 -0
  52. data/lib/ship_compliant/add_update_product.rb +66 -0
  53. data/lib/ship_compliant/add_update_product_result.rb +6 -0
  54. data/lib/ship_compliant/address.rb +87 -0
  55. data/lib/ship_compliant/address/suggested_address.rb +37 -0
  56. data/lib/ship_compliant/base_result.rb +43 -0
  57. data/lib/ship_compliant/channel_details.rb +31 -0
  58. data/lib/ship_compliant/check_compliance.rb +41 -0
  59. data/lib/ship_compliant/check_compliance_result.rb +95 -0
  60. data/lib/ship_compliant/client.rb +54 -0
  61. data/lib/ship_compliant/commit_sales_order.rb +48 -0
  62. data/lib/ship_compliant/commit_sales_order_result.rb +30 -0
  63. data/lib/ship_compliant/compliance_rule.rb +30 -0
  64. data/lib/ship_compliant/configuration.rb +46 -0
  65. data/lib/ship_compliant/error_result.rb +41 -0
  66. data/lib/ship_compliant/freight_sales_tax_rate.rb +8 -0
  67. data/lib/ship_compliant/get_inventory_details.rb +31 -0
  68. data/lib/ship_compliant/get_inventory_details_result.rb +41 -0
  69. data/lib/ship_compliant/get_sales_order_extended.rb +23 -0
  70. data/lib/ship_compliant/get_sales_order_extended_result.rb +65 -0
  71. data/lib/ship_compliant/inventory_product.rb +95 -0
  72. data/lib/ship_compliant/order_search.rb +92 -0
  73. data/lib/ship_compliant/package.rb +13 -0
  74. data/lib/ship_compliant/product_attributes.rb +98 -0
  75. data/lib/ship_compliant/product_sales_tax_rate.rb +23 -0
  76. data/lib/ship_compliant/sales_tax_rate.rb +22 -0
  77. data/lib/ship_compliant/search_sales_order_summary.rb +30 -0
  78. data/lib/ship_compliant/search_sales_orders.rb +53 -0
  79. data/lib/ship_compliant/search_sales_orders_result.rb +106 -0
  80. data/lib/ship_compliant/shipment.rb +59 -0
  81. data/lib/ship_compliant/shipment_compliance.rb +28 -0
  82. data/lib/ship_compliant/shipment_sales_tax_rate.rb +15 -0
  83. data/lib/ship_compliant/version.rb +3 -0
  84. data/lib/ship_compliant/void_sales_order.rb +42 -0
  85. data/lib/ship_compliant/void_sales_order_result.rb +20 -0
  86. data/ship_compliant.gemspec +33 -0
  87. data/spec/fixtures/add_update_product.xml +22 -0
  88. data/spec/fixtures/check_compliance.xml +125 -0
  89. data/spec/fixtures/coreservice.wsdl +1341 -0
  90. data/spec/fixtures/search_sales_orders.xml +52 -0
  91. data/spec/fixtures/void_order_failure.xml +31 -0
  92. data/spec/fixtures/void_order_success.xml +22 -0
  93. data/spec/lib/ship_compliant/add_update_brand_result_spec.rb +7 -0
  94. data/spec/lib/ship_compliant/add_update_brand_spec.rb +58 -0
  95. data/spec/lib/ship_compliant/add_update_product_result_spec.rb +7 -0
  96. data/spec/lib/ship_compliant/add_update_product_spec.rb +52 -0
  97. data/spec/lib/ship_compliant/address/suggested_address_spec.rb +28 -0
  98. data/spec/lib/ship_compliant/address_spec.rb +123 -0
  99. data/spec/lib/ship_compliant/base_result_spec.rb +127 -0
  100. data/spec/lib/ship_compliant/channel_details_spec.rb +40 -0
  101. data/spec/lib/ship_compliant/check_compliance_result_spec.rb +135 -0
  102. data/spec/lib/ship_compliant/check_compliance_spec.rb +43 -0
  103. data/spec/lib/ship_compliant/client_spec.rb +73 -0
  104. data/spec/lib/ship_compliant/commit_sales_order_result_spec.rb +32 -0
  105. data/spec/lib/ship_compliant/commit_sales_order_spec.rb +38 -0
  106. data/spec/lib/ship_compliant/compliance_rule_spec.rb +47 -0
  107. data/spec/lib/ship_compliant/configuration_spec.rb +47 -0
  108. data/spec/lib/ship_compliant/error_result_spec.rb +47 -0
  109. data/spec/lib/ship_compliant/freight_sales_tax_rate_spec.rb +7 -0
  110. data/spec/lib/ship_compliant/get_inventory_details_result_spec.rb +87 -0
  111. data/spec/lib/ship_compliant/get_inventory_details_spec.rb +35 -0
  112. data/spec/lib/ship_compliant/get_sales_order_extended_result_spec.rb +84 -0
  113. data/spec/lib/ship_compliant/get_sales_order_extended_spec.rb +39 -0
  114. data/spec/lib/ship_compliant/inventory_product_spec.rb +116 -0
  115. data/spec/lib/ship_compliant/order_search_spec.rb +21 -0
  116. data/spec/lib/ship_compliant/package_spec.rb +26 -0
  117. data/spec/lib/ship_compliant/product_attributes_spec.rb +36 -0
  118. data/spec/lib/ship_compliant/product_sales_tax_rate_spec.rb +22 -0
  119. data/spec/lib/ship_compliant/sales_tax_rate_spec.rb +21 -0
  120. data/spec/lib/ship_compliant/search_sales_order_summary_spec.rb +56 -0
  121. data/spec/lib/ship_compliant/search_sales_orders_result_spec.rb +121 -0
  122. data/spec/lib/ship_compliant/search_sales_orders_spec.rb +42 -0
  123. data/spec/lib/ship_compliant/shipment_compliance_spec.rb +46 -0
  124. data/spec/lib/ship_compliant/shipment_sales_tax_rate_spec.rb +20 -0
  125. data/spec/lib/ship_compliant/shipment_spec.rb +106 -0
  126. data/spec/lib/ship_compliant/void_sales_order_result_spec.rb +7 -0
  127. data/spec/lib/ship_compliant/void_sales_order_spec.rb +41 -0
  128. data/spec/spec_helper.rb +50 -0
  129. metadata +366 -0
@@ -0,0 +1,40 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe ChannelDetails do
5
+
6
+ context "order_channel" do
7
+ it "gets the order_channel" do
8
+ subject.order_channel.should == 'order-channel'
9
+ end
10
+ end
11
+
12
+ context "advertiser_key" do
13
+ it "gets the advertiser_key" do
14
+ subject.advertiser_key.should == 'advertiser-key'
15
+ end
16
+ end
17
+
18
+ context "advertiser_name" do
19
+ it "gets the advertiser_name" do
20
+ subject.advertiser_name.should == 'advertiser-name'
21
+ end
22
+ end
23
+
24
+ context "meta" do
25
+ it "gets channel meta" do
26
+ subject.meta.should == 'channel-meta'
27
+ end
28
+ end
29
+
30
+ subject do
31
+ ChannelDetails.new({
32
+ order_channel: 'order-channel',
33
+ advertiser_key: 'advertiser-key',
34
+ advertiser_name: 'advertiser-name',
35
+ meta: 'channel-meta'
36
+ })
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,135 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe CheckComplianceResult do
5
+ it_behaves_like "BaseResult"
6
+
7
+ context "compliant?" do
8
+ it "successed if the salesorder was compliant" do
9
+ subject.compliant?.should be_true
10
+ end
11
+
12
+ it "fails if the salesorder was not compliant" do
13
+ result = CheckComplianceResult.new({
14
+ sales_order: { is_compliant: false }
15
+ })
16
+
17
+ result.compliant?.should be_false
18
+ end
19
+ end
20
+
21
+ context "recommended_tax_due" do
22
+ it "gets the tax due as a float" do
23
+ subject.recommended_tax_due.should == 1372.34
24
+ end
25
+ end
26
+
27
+ context "shipment_sales_tax_rates" do
28
+ it "returns an array of sales tax rates" do
29
+ subject.shipment_sales_tax_rates.should == [
30
+ {
31
+ :@shipment_key => 'ORDER-KEY',
32
+ freight_sales_tax_rate: {
33
+ :@sales_tax_due => 100.5,
34
+ :@sales_tax_rate => 10.34
35
+ },
36
+ product_sales_tax_rates: {
37
+ product_sales_tax_rate: {
38
+ :@brand_key => 'ABC',
39
+ :@product_key => '123',
40
+ :@sales_tax_due => 12.332,
41
+ :@sales_tax_rate => 0.844
42
+ }
43
+ }
44
+ }
45
+ ]
46
+ end
47
+ end
48
+
49
+ context "taxes_for_shipment" do
50
+ it "finds taxes from shipment_key" do
51
+ subject.taxes_for_shipment('ORDER-KEY').should == ShipmentSalesTaxRate.new(
52
+ shipment_key = 'ORDER-KEY',
53
+ freight = FreightSalesTaxRate.new({ sales_tax_due: 100.5, sales_tax_rate: 10.34 }),
54
+ products = [
55
+ ProductSalesTaxRate.new({ brand_key: 'ABC', product_key: '123', sales_tax_due: 12.332, sales_tax_rate: 0.844 })
56
+ ]
57
+ )
58
+ end
59
+ end
60
+
61
+ context "shipment_compliance_rules" do
62
+ it "returns compliance rules as an array" do
63
+ subject.shipment_compliance_rules.should == [
64
+ {
65
+ is_compliant: true,
66
+ key: 'ORDER-KEY'
67
+ }
68
+ ]
69
+ end
70
+ end
71
+
72
+ context "compliance_rules_for_shipment" do
73
+ it "finds compliance rules for shipment" do
74
+ subject.compliance_rules_for_shipment('ORDER-KEY').should == ShipmentCompliance.new({
75
+ is_compliant: true,
76
+ key: 'ORDER-KEY'
77
+ })
78
+ end
79
+ end
80
+
81
+ context "address_validation_result" do
82
+ it "gets the address validation result" do
83
+ subject.address_validation_result.should == 'AddressValidated'
84
+ end
85
+ end
86
+
87
+ context "suggested_address" do
88
+ it "returns the suggested address" do
89
+ subject.suggested_address.should == SuggestedAddress.new({
90
+ city: 'Bluebell',
91
+ state: 'Ice Cream'
92
+ })
93
+ end
94
+ end
95
+
96
+ subject do
97
+ CheckComplianceResult.new({
98
+ sales_order: {
99
+ is_compliant: true,
100
+ sales_tax_rates: {
101
+ recommended_sales_tax_due: '1372.34',
102
+ shipment_sales_tax_rates: {
103
+ shipment_sales_tax_rate: {
104
+ :@shipment_key => 'ORDER-KEY',
105
+ freight_sales_tax_rate: {
106
+ :@sales_tax_due => 100.5,
107
+ :@sales_tax_rate => 10.34
108
+ },
109
+ product_sales_tax_rates: {
110
+ product_sales_tax_rate: {
111
+ :@brand_key => 'ABC',
112
+ :@product_key => '123',
113
+ :@sales_tax_due => 12.332,
114
+ :@sales_tax_rate => 0.844
115
+ }
116
+ }
117
+ }
118
+ }
119
+ },
120
+ shipments: {
121
+ shipment_compliance_response: {
122
+ is_compliant: true,
123
+ key: 'ORDER-KEY'
124
+ }
125
+ }
126
+ },
127
+ address_validation_result: 'AddressValidated',
128
+ suggested_address: {
129
+ city: 'Bluebell',
130
+ state: 'Ice Cream'
131
+ }
132
+ })
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,43 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe CheckCompliance do
5
+
6
+ before { savon.mock! }
7
+ after { savon.unmock! }
8
+
9
+ context "of_sales_order" do
10
+ let(:message) do
11
+ {
12
+ 'Request' => {
13
+ 'Security' => {
14
+ 'PartnerKey' => 'abc-123',
15
+ 'Username' => 'bob@example.com',
16
+ 'Password' => 'secret'
17
+ },
18
+ 'IncludeSalesTax' => true,
19
+ 'CustomerKey' => 'CUST-1',
20
+ 'FooBar' => {
21
+ 'Baz' => false
22
+ }
23
+ }
24
+ }
25
+ end
26
+ let(:response) { File.read('spec/fixtures/check_compliance.xml') }
27
+
28
+ it "queries the client with product information" do
29
+ savon.expects(:check_compliance_of_sales_order_with_address_validation)
30
+ .with(message: message).returns(response)
31
+
32
+ result = CheckCompliance.of_sales_order({
33
+ include_sales_tax: true,
34
+ customer_key: 'CUST-1',
35
+ foo_bar: { baz: false }
36
+ })
37
+
38
+ result.should be_kind_of(CheckComplianceResult)
39
+ end
40
+ end
41
+
42
+ end
43
+ end
@@ -0,0 +1,73 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe Client do
5
+
6
+ it "inherits from Savon::Client" do
7
+ ShipCompliant.client.should be_kind_of(Savon::Client)
8
+ end
9
+
10
+ it "uses wsdl from configuration" do
11
+ ShipCompliant.configure do |c|
12
+ c.wsdl = 'http://example.com'
13
+ end
14
+
15
+ ShipCompliant.client.globals[:wsdl].should == 'http://example.com'
16
+ end
17
+
18
+ it "uses log value from configuration" do
19
+ # configuration is defined in spec_helper.rb
20
+ ShipCompliant.client.globals[:log].should == false
21
+ end
22
+
23
+ context "call" do
24
+ before { savon.mock! }
25
+ after { savon.unmock! }
26
+
27
+ it "simplifies the actual api" do
28
+ message = {
29
+ 'Request' => {
30
+ 'Security' => ShipCompliant.configuration.credentials,
31
+ 'InventoryType' => 'All',
32
+ 'FulfillmentLocation' => 'WineShipping'
33
+ }
34
+ }
35
+ savon.expects(:search_sales_orders)
36
+ .with(message: message)
37
+ .returns(File.read('spec/fixtures/search_sales_orders.xml'))
38
+
39
+ ShipCompliant.client.call(:search_sales_orders, {
40
+ 'InventoryType' => 'All',
41
+ 'FulfillmentLocation' => 'WineShipping'
42
+ })
43
+ end
44
+
45
+ it "the response's result directly" do
46
+ ShipCompliant.client.stub(:savon_call) do
47
+ stub(to_hash: {
48
+ a_method_response: {
49
+ a_method_result: {
50
+ response_status: 'Success'
51
+ }
52
+ }
53
+ })
54
+ end
55
+
56
+ result = ShipCompliant.client.call(:a_method, {})
57
+ result.should == {
58
+ response_status: 'Success'
59
+ }
60
+ end
61
+ end
62
+
63
+ context "wsdl=" do
64
+ it "changes the default wsdl" do
65
+ ShipCompliant.configuration = nil
66
+ ShipCompliant.client.globals[:wsdl].should == 'https://ws-dev.shipcompliant.com/services/1.2/coreservice.asmx?WSDL'
67
+ ShipCompliant.wsdl = 'http://ws.example.com?WSDL'
68
+ ShipCompliant.client.globals[:wsdl].should == 'http://ws.example.com?WSDL'
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,32 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe CommitSalesOrderResult do
5
+ it_behaves_like "BaseResult"
6
+
7
+ context "shipments" do
8
+ it "returns the shipments as an array" do
9
+ subject.shipments.should == [
10
+ { key: 'SHIPMENT-KEY', is_committed: true }
11
+ ]
12
+ end
13
+ end
14
+
15
+ context "committed_shipments" do
16
+ it "returns the shipment keys for committed shipments" do
17
+ subject.committed_shipments.should == ['SHIPMENT-KEY']
18
+ end
19
+ end
20
+
21
+ subject do
22
+ CommitSalesOrderResult.new({
23
+ shipments: {
24
+ shipment_commit_response: {
25
+ key: "SHIPMENT-KEY",
26
+ is_committed: true
27
+ }
28
+ }
29
+ })
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,38 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe CommitSalesOrder do
5
+
6
+ before { savon.mock! }
7
+ after { savon.unmock! }
8
+
9
+ it "commits a sales order" do
10
+ message = {
11
+ 'Request' => {
12
+ 'Security' => {
13
+ 'PartnerKey' => 'abc-123',
14
+ 'Username' => 'bob@example.com',
15
+ 'Password' => 'secret'
16
+ },
17
+ 'CommitOptions' => 'AllShipments',
18
+ 'Payments' => nil,
19
+ 'SalesTaxCollected' => 0,
20
+ 'SalesOrderKey' => 'ORDER-KEY'
21
+ }
22
+ }
23
+
24
+ savon.expects(:commit_sales_order)
25
+ .with(message: message)
26
+ .returns(File.read('spec/fixtures/void_order_success.xml'))
27
+
28
+ result = ShipCompliant::CommitSalesOrder.call({
29
+ commit_options: 'AllShipments',
30
+ payments: nil,
31
+ sales_tax_collected: 0,
32
+ sales_order_key: 'ORDER-KEY'
33
+ })
34
+
35
+ result.should be_kind_of(CommitSalesOrderResult)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe ComplianceRule do
5
+
6
+ context "compliance_description" do
7
+ it "gets the description" do
8
+ subject.compliance_description.should == 'Howdy Stranger'
9
+ end
10
+ end
11
+
12
+ context "rule_description" do
13
+ it "gets the rule" do
14
+ subject.rule_description.should == 'Must say hi to people you do not know.'
15
+ end
16
+ end
17
+
18
+ context "compliant?" do
19
+ it "check this rule passed" do
20
+ subject.compliant?.should be_true
21
+ end
22
+ end
23
+
24
+ context "license_relationship" do
25
+ it "gets the relationship" do
26
+ subject.license_relationship.should == 'StrangerToFriend'
27
+ end
28
+ end
29
+
30
+ context "rule_type" do
31
+ it "gets the rule type" do
32
+ subject.rule_type.should == 'BeCourteous'
33
+ end
34
+ end
35
+
36
+ subject do
37
+ ComplianceRule.new(
38
+ compliance_description: 'Howdy Stranger',
39
+ is_compliant: true,
40
+ license_relationship: 'StrangerToFriend',
41
+ rule_description: 'Must say hi to people you do not know.',
42
+ rule_type: 'BeCourteous'
43
+ )
44
+ end
45
+
46
+ end
47
+ end
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ module ShipCompliant
4
+ describe Configuration do
5
+
6
+ before do
7
+ ShipCompliant.configuration = nil
8
+ ShipCompliant.configure do |c|
9
+ c.partner_key = 'abc-123'
10
+ c.username = 'bob@example.com'
11
+ c.password = 'secret'
12
+ end
13
+ end
14
+
15
+ it "stores user credentials" do
16
+ ShipCompliant.configuration.partner_key.should == 'abc-123'
17
+ ShipCompliant.configuration.username.should == 'bob@example.com'
18
+ ShipCompliant.configuration.password.should == 'secret'
19
+ end
20
+
21
+ it "creates authentication hash" do
22
+ ShipCompliant.configuration.credentials.should == {
23
+ 'PartnerKey' => 'abc-123',
24
+ 'Username' => 'bob@example.com',
25
+ 'Password' => 'secret'
26
+ }
27
+ end
28
+
29
+ it "defaults log to true" do
30
+ ShipCompliant.configuration.log.should == true
31
+ end
32
+
33
+ context "wsdl" do
34
+ it "defaults to core services" do
35
+ ShipCompliant.configuration.wsdl.should == 'https://ws-dev.shipcompliant.com/services/1.2/coreservice.asmx?WSDL'
36
+ end
37
+
38
+ it "can be changed" do
39
+ ShipCompliant.configure do |c|
40
+ c.wsdl = 'http://example.com'
41
+ end
42
+ ShipCompliant.configuration.wsdl.should == 'http://example.com'
43
+ end
44
+ end
45
+
46
+ end
47
+ end