cxml-ruby 0.2.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.
Files changed (151) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +23 -0
  3. data/.gitignore +14 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +175 -0
  6. data/Gemfile +2 -0
  7. data/LICENSE +18 -0
  8. data/README.md +94 -0
  9. data/Rakefile +6 -0
  10. data/cxml-ruby.gemspec +27 -0
  11. data/lib/cxml/accounting.rb +27 -0
  12. data/lib/cxml/additional_cost.rb +10 -0
  13. data/lib/cxml/additional_deduction.rb +12 -0
  14. data/lib/cxml/address.rb +16 -0
  15. data/lib/cxml/bill_to.rb +10 -0
  16. data/lib/cxml/browser_form_post.rb +13 -0
  17. data/lib/cxml/charge.rb +9 -0
  18. data/lib/cxml/classification.rb +9 -0
  19. data/lib/cxml/confirmation_header.rb +16 -0
  20. data/lib/cxml/confirmation_item.rb +14 -0
  21. data/lib/cxml/confirmation_request.rb +25 -0
  22. data/lib/cxml/confirmation_status.rb +32 -0
  23. data/lib/cxml/contact.rb +16 -0
  24. data/lib/cxml/country.rb +9 -0
  25. data/lib/cxml/credential.rb +49 -0
  26. data/lib/cxml/credential_mac.rb +26 -0
  27. data/lib/cxml/deducted_price.rb +9 -0
  28. data/lib/cxml/deduction_amount.rb +9 -0
  29. data/lib/cxml/description.rb +9 -0
  30. data/lib/cxml/discount.rb +10 -0
  31. data/lib/cxml/discount_percent.rb +9 -0
  32. data/lib/cxml/distribution.rb +11 -0
  33. data/lib/cxml/document.rb +71 -0
  34. data/lib/cxml/document_node.rb +126 -0
  35. data/lib/cxml/document_reference.rb +9 -0
  36. data/lib/cxml/due_amount.rb +9 -0
  37. data/lib/cxml/email.rb +10 -0
  38. data/lib/cxml/errors.rb +7 -0
  39. data/lib/cxml/extrinsic.rb +10 -0
  40. data/lib/cxml/from.rb +9 -0
  41. data/lib/cxml/gross_amount.rb +9 -0
  42. data/lib/cxml/header.rb +29 -0
  43. data/lib/cxml/id_reference.rb +13 -0
  44. data/lib/cxml/invoice_detail_discount.rb +13 -0
  45. data/lib/cxml/invoice_detail_header_indicator.rb +11 -0
  46. data/lib/cxml/invoice_detail_header_order.rb +24 -0
  47. data/lib/cxml/invoice_detail_item.rb +55 -0
  48. data/lib/cxml/invoice_detail_item_reference.rb +17 -0
  49. data/lib/cxml/invoice_detail_line_indicator.rb +14 -0
  50. data/lib/cxml/invoice_detail_line_shipping.rb +11 -0
  51. data/lib/cxml/invoice_detail_line_special_handling.rb +11 -0
  52. data/lib/cxml/invoice_detail_order.rb +24 -0
  53. data/lib/cxml/invoice_detail_order_info.rb +10 -0
  54. data/lib/cxml/invoice_detail_order_summary.rb +32 -0
  55. data/lib/cxml/invoice_detail_request.rb +40 -0
  56. data/lib/cxml/invoice_detail_request_header.rb +54 -0
  57. data/lib/cxml/invoice_detail_shipping.rb +27 -0
  58. data/lib/cxml/invoice_detail_summary.rb +18 -0
  59. data/lib/cxml/invoice_id_info.rb +10 -0
  60. data/lib/cxml/invoice_partner.rb +10 -0
  61. data/lib/cxml/item_detail.rb +27 -0
  62. data/lib/cxml/item_id.rb +10 -0
  63. data/lib/cxml/item_in.rb +14 -0
  64. data/lib/cxml/item_out.rb +17 -0
  65. data/lib/cxml/master_agreement_reference.rb +9 -0
  66. data/lib/cxml/message.rb +13 -0
  67. data/lib/cxml/modification.rb +15 -0
  68. data/lib/cxml/modification_detail.rb +16 -0
  69. data/lib/cxml/modifications.rb +23 -0
  70. data/lib/cxml/money.rb +35 -0
  71. data/lib/cxml/name.rb +9 -0
  72. data/lib/cxml/net_amount.rb +9 -0
  73. data/lib/cxml/order_reference.rb +12 -0
  74. data/lib/cxml/order_request.rb +33 -0
  75. data/lib/cxml/order_request_header.rb +66 -0
  76. data/lib/cxml/parser.rb +37 -0
  77. data/lib/cxml/payment_term.rb +28 -0
  78. data/lib/cxml/period.rb +10 -0
  79. data/lib/cxml/postal_address.rb +35 -0
  80. data/lib/cxml/protocol.rb +57 -0
  81. data/lib/cxml/punch_out_order_message.rb +33 -0
  82. data/lib/cxml/punch_out_order_message_header.rb +20 -0
  83. data/lib/cxml/punch_out_setup_request.rb +31 -0
  84. data/lib/cxml/punch_out_setup_response.rb +9 -0
  85. data/lib/cxml/request.rb +21 -0
  86. data/lib/cxml/response.rb +20 -0
  87. data/lib/cxml/segment.rb +12 -0
  88. data/lib/cxml/sender.rb +10 -0
  89. data/lib/cxml/ship_to.rb +10 -0
  90. data/lib/cxml/shipping.rb +10 -0
  91. data/lib/cxml/shipping_amount.rb +10 -0
  92. data/lib/cxml/special_handling_amount.rb +11 -0
  93. data/lib/cxml/start_page.rb +13 -0
  94. data/lib/cxml/state.rb +9 -0
  95. data/lib/cxml/status.rb +27 -0
  96. data/lib/cxml/subtotal_amount.rb +9 -0
  97. data/lib/cxml/supplier_setup.rb +13 -0
  98. data/lib/cxml/tax.rb +42 -0
  99. data/lib/cxml/tax_adjustment_amount.rb +9 -0
  100. data/lib/cxml/tax_amount.rb +9 -0
  101. data/lib/cxml/tax_detail.rb +44 -0
  102. data/lib/cxml/tax_location.rb +9 -0
  103. data/lib/cxml/taxable_amount.rb +9 -0
  104. data/lib/cxml/to.rb +9 -0
  105. data/lib/cxml/total.rb +10 -0
  106. data/lib/cxml/total_allowances.rb +9 -0
  107. data/lib/cxml/total_amount_without_tax.rb +9 -0
  108. data/lib/cxml/total_charges.rb +9 -0
  109. data/lib/cxml/unit_price.rb +9 -0
  110. data/lib/cxml/version.rb +5 -0
  111. data/lib/cxml.rb +39 -0
  112. data/spec/credential_spec.rb +37 -0
  113. data/spec/cxml_spec.rb +6 -0
  114. data/spec/document_spec.rb +155 -0
  115. data/spec/fixtures/.gitkeep +0 -0
  116. data/spec/fixtures/envelope.xml +31 -0
  117. data/spec/fixtures/envelope2.xml +36 -0
  118. data/spec/fixtures/invoice_backed_and_unbacked_by_pos.xml +106 -0
  119. data/spec/fixtures/invoice_backed_by_multiple_pos.xml +97 -0
  120. data/spec/fixtures/invoice_taxes_at_line.xml +82 -0
  121. data/spec/fixtures/invoice_taxes_at_line_multiple_taxes.xml +403 -0
  122. data/spec/fixtures/invoice_taxes_at_total.xml +78 -0
  123. data/spec/fixtures/item_in.xml +11 -0
  124. data/spec/fixtures/order_request.cxml +121 -0
  125. data/spec/fixtures/punch_out_order_message_doc.xml +32 -0
  126. data/spec/fixtures/punch_out_setup_request_doc.xml +32 -0
  127. data/spec/fixtures/punch_out_setup_request_doc_coupa.xml +42 -0
  128. data/spec/fixtures/punch_out_setup_request_doc_with_ship_to.xml +46 -0
  129. data/spec/fixtures/purchase_order_request_200.xml +132 -0
  130. data/spec/fixtures/request_doc.xml +79 -0
  131. data/spec/fixtures/response_status_200.xml +11 -0
  132. data/spec/fixtures/response_status_400.xml +5 -0
  133. data/spec/header_spec.rb +54 -0
  134. data/spec/invoice_detail_request_spec.rb +88 -0
  135. data/spec/item_detail_spec.rb +44 -0
  136. data/spec/item_id_spec.rb +40 -0
  137. data/spec/item_in_spec.rb +41 -0
  138. data/spec/money_spec.rb +44 -0
  139. data/spec/parser_spec.rb +6 -0
  140. data/spec/protocol_spec.rb +16 -0
  141. data/spec/punch_out_order_message_header_spec.rb +36 -0
  142. data/spec/punch_out_order_message_spec.rb +43 -0
  143. data/spec/punch_out_setup_request_spec.rb +60 -0
  144. data/spec/purchase_order_request_spec.rb +40 -0
  145. data/spec/request_spec.rb +36 -0
  146. data/spec/response_spec.rb +58 -0
  147. data/spec/sender_spec.rb +32 -0
  148. data/spec/spec_helper.rb +21 -0
  149. data/spec/status_spec.rb +44 -0
  150. data/spec/support/helpers.rb +5 -0
  151. metadata +317 -0
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class PunchOutSetupRequest < DocumentNode
5
+ accessible_attributes %i[
6
+ operation
7
+ ]
8
+ accessible_nodes %i[
9
+ browser_form_post
10
+ supplier_setup
11
+ buyer_cookie
12
+ ship_to
13
+ extrinsics
14
+ contact
15
+ ]
16
+
17
+ def initialize_extrinsic(value)
18
+ value = [value] unless value.is_a?(Array)
19
+ @extrinsics = value.map do |item|
20
+ Extrinsic.new(item)
21
+ end
22
+ end
23
+
24
+ def initialize_extrinsics(value)
25
+ value = [value] unless value.is_a?(Array)
26
+ @extrinsics = value.map do |item|
27
+ Extrinsic.new(item)
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class PunchOutSetupResponse < DocumentNode
5
+ accessible_nodes %i[
6
+ start_page
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Clients send requests for operations. Only one Request element is allowed for each
4
+ # cXML envelope element, which simplifies the server implementations, because no
5
+ # demultiplexing needs to occur when reading cXML documents. The Request element
6
+ # can contain virtually any type of XML data.
7
+
8
+ module CXML
9
+ class Request < DocumentNode
10
+ accessible_attributes %i[
11
+ deployment_mode
12
+ id
13
+ ]
14
+ accessible_nodes %i[
15
+ confirmation_request
16
+ invoice_detail_request
17
+ order_request
18
+ punch_out_setup_request
19
+ ]
20
+ end
21
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Servers send responses to inform clients of the results of operations. Because the
4
+ # result of some requests might not have any data, the Response element can optionally
5
+ # contain nothing but a Status element. A Response element can also contain any
6
+ # application-level data. During PunchOut for example, the application-level data is
7
+ # contained in a PunchOutSetupResponse element.
8
+
9
+ module CXML
10
+ class Response < DocumentNode
11
+ accessible_attributes %i[
12
+ deployment_mode
13
+ id
14
+ ]
15
+ accessible_nodes %i[
16
+ status
17
+ punch_out_setup_response
18
+ ]
19
+ end
20
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ # details for accounting objects
5
+ class Segment < DocumentNode
6
+ accessible_attributes %i[
7
+ id
8
+ description
9
+ type
10
+ ]
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class Sender < DocumentNode
5
+ accessible_nodes %i[
6
+ credential
7
+ user_agent
8
+ ]
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ # shipping details object within punchout setup request
5
+ class ShipTo < DocumentNode
6
+ accessible_nodes %i[
7
+ address
8
+ ]
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class Shipping < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ description
8
+ ]
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class ShippingAmount < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ distribution
8
+ ]
9
+ end
10
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class SpecialHandlingAmount < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ description
8
+ distribution
9
+ ]
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class StartPage < DocumentNode
5
+ accessible_nodes %i[
6
+ url
7
+ ]
8
+
9
+ def render_nodes(node)
10
+ node.URL(url)
11
+ end
12
+ end
13
+ end
data/lib/cxml/state.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class State < DocumentNode
5
+ accessible_attributes %i[
6
+ iso_state_code
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class Status < DocumentNode
5
+ accessible_attributes %i[
6
+ code
7
+ text
8
+ xml_lang
9
+ ]
10
+
11
+ def code
12
+ @code&.to_i
13
+ end
14
+
15
+ # Check if status is success
16
+ # @return [Boolean]
17
+ def success?
18
+ [200, 201, 204, 280, 281].include?(code)
19
+ end
20
+
21
+ # Check if status is failure
22
+ # @return [Boolean]
23
+ def failure?
24
+ !success?
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class SubtotalAmount < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class SupplierSetup < DocumentNode
5
+ accessible_nodes %i[
6
+ url
7
+ ]
8
+
9
+ def render_nodes(node)
10
+ node.URL(url)
11
+ end
12
+ end
13
+ end
data/lib/cxml/tax.rb ADDED
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class Tax < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ tax_adjustment_amount
8
+ description
9
+ tax_details
10
+ distribution
11
+ extrinsics
12
+ ]
13
+
14
+ def initialize_tax_detail(value)
15
+ value = [value] unless value.is_a?(Array)
16
+ @tax_details = value.map do |item|
17
+ TaxDetail.new(item)
18
+ end
19
+ end
20
+
21
+ def initialize_tax_details(value)
22
+ value = [value] unless value.is_a?(Array)
23
+ @tax_details = value.map do |item|
24
+ TaxDetail.new(item)
25
+ end
26
+ end
27
+
28
+ def initialize_extrinsic(value)
29
+ value = [value] unless value.is_a?(Array)
30
+ @extrinsics = value.map do |item|
31
+ Extrinsic.new(item)
32
+ end
33
+ end
34
+
35
+ def initialize_extrinsics(value)
36
+ value = [value] unless value.is_a?(Array)
37
+ @extrinsics = value.map do |item|
38
+ Extrinsic.new(item)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TaxAdjustmentAmount < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TaxAmount < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TaxDetail < DocumentNode
5
+ accessible_attributes %i[
6
+ purpose
7
+ category
8
+ percentage_rate
9
+ is_vat_recoverable
10
+ tax_point_date
11
+ payment_date
12
+ is_triangular_transaction
13
+ exempt_detail
14
+ is_withholding_tax
15
+ tax_rate_type
16
+ base_percentage_rate
17
+ is_included_in_price
18
+ ]
19
+ accessible_nodes %i[
20
+ taxable_amount
21
+ tax_amount
22
+ tax_location
23
+ tax_adjustment_amount
24
+ description
25
+ tax_regime
26
+ tax_exemption
27
+ extrinsics
28
+ ]
29
+
30
+ def initialize_extrinsic(value)
31
+ value = [value] unless value.is_a?(Array)
32
+ @extrinsics = value.map do |item|
33
+ Extrinsic.new(item)
34
+ end
35
+ end
36
+
37
+ def initialize_extrinsics(value)
38
+ value = [value] unless value.is_a?(Array)
39
+ @extrinsics = value.map do |item|
40
+ Extrinsic.new(item)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TaxLocation < DocumentNode
5
+ accessible_attributes %i[
6
+ xml_lang
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TaxableAmount < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
data/lib/cxml/to.rb ADDED
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class To < DocumentNode
5
+ accessible_nodes %i[
6
+ credential
7
+ ]
8
+ end
9
+ end
data/lib/cxml/total.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class Total < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ modifications
8
+ ]
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TotalAllowances < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TotalAmountWithoutTax < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class TotalCharges < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ class UnitPrice < DocumentNode
5
+ accessible_nodes %i[
6
+ money
7
+ ]
8
+ end
9
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module CXML
4
+ VERSION = '0.2.0'
5
+ end
data/lib/cxml.rb ADDED
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require('time')
4
+ require('nokogiri')
5
+ require('logger')
6
+ require('cxml/document_node')
7
+ Dir[File.join(__dir__, 'cxml', '*.rb')].sort.each { |file| require file }
8
+
9
+ module CXML
10
+ def self.parse(str)
11
+ CXML::Parser.new.parse(str)
12
+ end
13
+
14
+ def self.builder
15
+ Nokogiri::XML::Builder.new(encoding: 'UTF-8')
16
+ end
17
+
18
+ def self.configure
19
+ yield(self)
20
+ end
21
+
22
+ def self.raise_unknown_elements
23
+ @raise_unknown_elements.nil? ? @raise_unknown_elements ||= true : @raise_unknown_elements
24
+ end
25
+
26
+ def self.raise_unknown_elements=(setting)
27
+ @raise_unknown_elements = setting
28
+ end
29
+
30
+ def self.logger
31
+ return @logger if @logger
32
+
33
+ @logger ||= Logger.new(STDOUT, level: :warn)
34
+ end
35
+
36
+ def self.logger=(new_logger)
37
+ @logger = new_logger
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe CXML::Credential do
6
+ it { should respond_to :domain }
7
+ it { should respond_to :type }
8
+ it { should respond_to :shared_secret }
9
+ it { should respond_to :credential_mac }
10
+ it { should respond_to :identity }
11
+
12
+ let(:parser) { CXML::Parser.new }
13
+ let(:data) { parser.parse(fixture('punch_out_order_message_doc.xml')) }
14
+ let(:doc) { CXML::Document.new(data) }
15
+ let(:sender) { doc.header.sender }
16
+ let(:credential) { sender.credential }
17
+ let(:builder) { doc.render }
18
+
19
+ describe '#initialize' do
20
+ it 'sets the attributes that are passed' do
21
+ credential.shared_secret.should_not be_nil
22
+ credential.identity.should_not be_nil
23
+ end
24
+ end
25
+
26
+ describe '#render' do
27
+ let(:output_xml) { builder.to_xml }
28
+ let(:output_data) { parser.parse(output_xml) }
29
+ let(:sender_output_data) { output_data[:header][:sender] }
30
+ let(:credential_output_data) { sender_output_data[:credential] }
31
+
32
+ it 'contains the required nodes' do
33
+ credential_output_data[:shared_secret].should_not be_empty
34
+ credential_output_data[:identity].should_not be_empty
35
+ end
36
+ end
37
+ end
data/spec/cxml_spec.rb ADDED
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe CXML do
6
+ end
@@ -0,0 +1,155 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe CXML::Document do
6
+ shared_examples_for :document_has_mandatory_values do
7
+ it 'sets the mandatory attributes' do
8
+ doc.version.should eq(CXML::Protocol::VERSION)
9
+ doc.payload_id.should_not be_nil
10
+ end
11
+ end
12
+
13
+ shared_examples_for :document_has_a_header do
14
+ it 'sets the header attributes' do
15
+ doc.header.should be_a CXML::Header
16
+ end
17
+ end
18
+
19
+ shared_examples_for :document_has_a_timestamp do
20
+ it 'sets the timestamp attributes' do
21
+ doc.timestamp.should be_a Time
22
+ doc.timestamp.should eq(Time.parse('2012-09-04T02:37:49-05:00'))
23
+ end
24
+ end
25
+
26
+ shared_examples_for :document_render_defaults do
27
+ it 'returns xml content' do
28
+ output_xml.should_not be_nil
29
+ end
30
+
31
+ it 'returns xml content with a header xml node' do
32
+ output_data[:header].should_not be_empty
33
+ end
34
+ end
35
+
36
+ let(:parser) { CXML::Parser.new }
37
+
38
+ it { should respond_to :version }
39
+ it { should respond_to :payload_id }
40
+ it { should respond_to :timestamp }
41
+ it { should respond_to :header }
42
+ it { should respond_to :request }
43
+ it { should respond_to :response }
44
+ it { should respond_to :message }
45
+ it { should respond_to :xml_lang }
46
+ it { should respond_to :request? }
47
+ it { should respond_to :response? }
48
+ it { should respond_to :message? }
49
+
50
+ describe '#initialize' do
51
+ let(:doc) { CXML::Document.new(data) }
52
+
53
+ it 'can ingest from_xml' do
54
+ doc = described_class.new.from_xml(fixture('response_status_200.xml'))
55
+ doc.response.status.code.should eq(200)
56
+ end
57
+
58
+ context 'when a request document is passed' do
59
+ let(:data) { parser.parse(fixture('request_doc.xml')) }
60
+ include_examples :document_has_mandatory_values
61
+ include_examples :document_has_a_header
62
+ include_examples :document_has_a_timestamp
63
+
64
+ it 'sets the correct document node attributes' do
65
+ doc.header.should be_a CXML::Header
66
+ doc.request.should be_a CXML::Request
67
+
68
+ doc.response.should be_nil
69
+ doc.message.should be_nil
70
+ end
71
+ end
72
+
73
+ context 'when a response document is passed' do
74
+ let(:data) { parser.parse(fixture('response_status_200.xml')) }
75
+ include_examples :document_has_mandatory_values
76
+ include_examples :document_has_a_timestamp
77
+
78
+ it 'sets the correct document node attributes' do
79
+ doc.response.should be_a CXML::Response
80
+
81
+ doc.header.should be_nil
82
+ doc.request.should be_nil
83
+ doc.message.should be_nil
84
+ end
85
+ end
86
+
87
+ context 'when a punch out order message is passed' do
88
+ let(:data) { parser.parse(fixture('punch_out_order_message_doc.xml')) }
89
+ include_examples :document_has_mandatory_values
90
+ include_examples :document_has_a_header
91
+ include_examples :document_has_a_timestamp
92
+
93
+ it 'sets the correct document node attributes' do
94
+ doc.header.should be_a CXML::Header
95
+ doc.message.punch_out_order_message.should be_a CXML::PunchOutOrderMessage
96
+
97
+ doc.request.should be_nil
98
+ doc.response.should be_nil
99
+ end
100
+ end
101
+ end
102
+
103
+ describe '#render' do
104
+ let(:doc) { CXML::Document.new(data) }
105
+ let(:builder) { doc.render }
106
+ let(:output_xml) { builder.to_xml }
107
+ let(:output_data) { parser.parse(output_xml) }
108
+
109
+ it { should respond_to :render }
110
+
111
+ context 'when a request document is rendered' do
112
+ let(:data) { parser.parse(fixture('request_doc.xml')) }
113
+ include_examples :document_render_defaults
114
+ end
115
+
116
+ context 'when a valid response is rendered' do
117
+ let(:data) { parser.parse(fixture('response_status_200.xml')) }
118
+ it 'returns xml content' do
119
+ output_xml.should_not be_nil
120
+ end
121
+
122
+ it 'outputs the response with a valid status code' do
123
+ output_data[:response].should_not be_empty
124
+ output_data[:response][:status][:code].should eq('200')
125
+ output_data[:response][:status].should eq(data[:response][:status])
126
+ end
127
+
128
+ it 'outputs the punch out setup response' do
129
+ output_data[:response][:punch_out_setup_response].should_not be_empty
130
+ end
131
+ end
132
+
133
+ context 'when a invalid response is rendered' do
134
+ let(:data) { parser.parse(fixture('response_status_400.xml')) }
135
+ it 'returns xml content' do
136
+ output_xml.should_not be_nil
137
+ end
138
+
139
+ it 'outputs the response with a valid status code' do
140
+ output_data[:response].should_not be_empty
141
+ output_data[:response][:status][:code].should eq('400')
142
+ end
143
+ end
144
+
145
+ context 'when a punch out order message document is rendered' do
146
+ let(:data) { parser.parse(fixture('punch_out_order_message_doc.xml')) }
147
+ include_examples :document_render_defaults
148
+
149
+ it 'outputs the punch out order message xml' do
150
+ output_data[:message].should_not be_empty
151
+ output_data[:message][:punch_out_order_message].should_not be_empty
152
+ end
153
+ end
154
+ end
155
+ end
File without changes