client_for_poslynx 0.3.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/CHANGELOG +12 -0
- data/README.md +163 -36
- data/TODO.txt +6 -0
- data/bin/fake_pos_terminal +1 -1
- data/client_for_poslynx.gemspec +3 -1
- data/lib/client_for_poslynx/data/abstract_data.rb +4 -0
- data/lib/client_for_poslynx/data/requests/abstract_request.rb +4 -0
- data/lib/client_for_poslynx/data/requests/can_visit.rb +1 -0
- data/lib/client_for_poslynx/data/requests/pin_pad_reset.rb +17 -0
- data/lib/client_for_poslynx/data/requests.rb +1 -0
- data/lib/client_for_poslynx/data/responses/abstract_response.rb +4 -0
- data/lib/client_for_poslynx/data/responses/pin_pad_reset.rb +17 -0
- data/lib/client_for_poslynx/data/responses.rb +1 -0
- data/lib/client_for_poslynx/example_request_factory.rb +96 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/content_formatter.rb +75 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/is_ui_component.rb +169 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_handler.rb +66 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/abstract_processor.rb +41 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/credit_card_sale_processor.rb +87 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/debit_card_sale_processor.rb +79 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_display_message_processor.rb +43 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_display_specified_form_processor.rb +56 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_initialize_processor.rb +21 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/pin_pad_reset_processor.rb +21 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/processes_card_sale.rb +118 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors/unsupported_processor.rb +20 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/request_processors.rb +22 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/term_manipulator.rb +35 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/ui_context.rb +21 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/user_button_number_selection_fetcher.rb +50 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/user_raw_text_line_fetcher.rb +49 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface/user_text_line_fetcher.rb +55 -0
- data/lib/client_for_poslynx/fake_pos_terminal/console_user_interface.rb +41 -195
- data/lib/client_for_poslynx/fake_pos_terminal/context.rb +10 -0
- data/lib/client_for_poslynx/fake_pos_terminal/keyboard_handler.rb +35 -0
- data/lib/client_for_poslynx/fake_pos_terminal/net_handler.rb +53 -0
- data/lib/client_for_poslynx/fake_pos_terminal/result_assemblers/card_sale_receipt.rb +1 -1
- data/lib/client_for_poslynx/fake_pos_terminal/{format.rb → value_formatting.rb} +1 -1
- data/lib/client_for_poslynx/fake_pos_terminal.rb +32 -8
- data/lib/client_for_poslynx/message_handling/xml_extractor.rb +4 -0
- data/lib/client_for_poslynx/message_handling/xml_lines_buffer.rb +35 -0
- data/lib/client_for_poslynx/message_handling.rb +1 -0
- data/lib/client_for_poslynx/net/em_protocol.rb +46 -0
- data/lib/client_for_poslynx/net/structured_client/em_connection.rb +72 -0
- data/lib/client_for_poslynx/net/structured_client.rb +104 -0
- data/lib/client_for_poslynx/net.rb +11 -0
- data/lib/client_for_poslynx/version.rb +1 -1
- data/lib/client_for_poslynx.rb +2 -0
- data/spec/client_for_poslynx/data/requests/credit_card_sale_spec.rb +1 -1
- data/spec/client_for_poslynx/data/requests/debit_card_sale_spec.rb +1 -1
- data/spec/client_for_poslynx/data/requests/pin_pad_display_message_spec.rb +1 -1
- data/spec/client_for_poslynx/data/requests/pin_pad_display_specified_form_spec.rb +1 -1
- data/spec/client_for_poslynx/data/requests/pin_pad_get_signature_spec.rb +1 -1
- data/spec/client_for_poslynx/data/requests/pin_pad_initialize_spec.rb +1 -1
- data/spec/client_for_poslynx/data/requests/pin_pad_reset_spec.rb +53 -0
- data/spec/client_for_poslynx/data/responses/credit_card_sale_spec.rb +1 -1
- data/spec/client_for_poslynx/data/responses/debit_card_sale_spec.rb +1 -1
- data/spec/client_for_poslynx/data/responses/pin_pad_display_message_spec.rb +1 -1
- data/spec/client_for_poslynx/data/responses/pin_pad_display_specified_form_spec.rb +1 -1
- data/spec/client_for_poslynx/data/responses/pin_pad_initialize_spec.rb +1 -1
- data/spec/client_for_poslynx/data/responses/pin_pad_reset_spec.rb +64 -0
- data/spec/client_for_poslynx/net/em_protocol_spec.rb +52 -0
- data/spec/client_for_poslynx/net/structured_client_spec.rb +118 -0
- data/spec/support/shared_examples.rb +22 -0
- data/spec/support/test_tcp_server.rb +163 -0
- metadata +75 -20
- data/bin/poslynx_client_console +0 -105
- data/lib/client_for_poslynx/fake_pos_terminal/request_dispatcher.rb +0 -36
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/abstract_handler.rb +0 -38
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/credit_card_sale.rb +0 -63
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/debit_card_sale.rb +0 -54
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/handles_card_sale.rb +0 -93
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/pin_pad_display_message.rb +0 -35
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/pin_pad_display_specified_form.rb +0 -49
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers/pin_pad_initialize.rb +0 -19
- data/lib/client_for_poslynx/fake_pos_terminal/request_handlers.rb +0 -18
- data/lib/client_for_poslynx/fake_pos_terminal/server.rb +0 -65
- data/lib/client_for_poslynx/has_client_console_support.rb +0 -109
@@ -1,12 +1,12 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
|
3
3
|
require 'client_for_poslynx'
|
4
|
-
require_relative 'fake_pos_terminal/
|
5
|
-
require_relative 'fake_pos_terminal/
|
6
|
-
require_relative 'fake_pos_terminal/server'
|
7
|
-
require_relative 'fake_pos_terminal/request_dispatcher'
|
4
|
+
require_relative 'fake_pos_terminal/value_formatting'
|
5
|
+
require_relative 'fake_pos_terminal/context'
|
8
6
|
require_relative 'fake_pos_terminal/result_assemblers'
|
9
|
-
require_relative 'fake_pos_terminal/
|
7
|
+
require_relative 'fake_pos_terminal/console_user_interface'
|
8
|
+
require_relative 'fake_pos_terminal/net_handler'
|
9
|
+
require_relative 'fake_pos_terminal/keyboard_handler'
|
10
10
|
|
11
11
|
module ClientForPoslynx
|
12
12
|
|
@@ -17,9 +17,33 @@ module ClientForPoslynx
|
|
17
17
|
module FakePosTerminal
|
18
18
|
|
19
19
|
def self.start(port_number)
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
context = self::Context.new
|
21
|
+
context.port_number = port_number
|
22
|
+
|
23
|
+
user_interface = self::ConsoleUserInterface.new( context )
|
24
|
+
user_interface.engage
|
25
|
+
user_interface.show_starting_up
|
26
|
+
|
27
|
+
EM.run do
|
28
|
+
EM.start_server(
|
29
|
+
"127.0.0.1", port_number, self::NetHandler,
|
30
|
+
user_interface
|
31
|
+
)
|
32
|
+
|
33
|
+
EM.open_keyboard(
|
34
|
+
self::KeyboardHandler,
|
35
|
+
user_interface
|
36
|
+
)
|
37
|
+
|
38
|
+
EM.error_handler do |e|
|
39
|
+
raise e
|
40
|
+
end
|
41
|
+
|
42
|
+
user_interface.client_disconnected
|
43
|
+
end
|
44
|
+
|
45
|
+
ensure
|
46
|
+
user_interface.disengage if user_interface
|
23
47
|
end
|
24
48
|
|
25
49
|
end
|
@@ -3,6 +3,10 @@
|
|
3
3
|
module ClientForPoslynx
|
4
4
|
module MessageHandling
|
5
5
|
|
6
|
+
# TODO: This is now obsolete and being replaced by a combina-
|
7
|
+
# tion of EventMachine's LineProtocol and XmlLinesBuffer.
|
8
|
+
# This class should be removed as soon as the fake POS
|
9
|
+
# terminal code has been re-built as an EM server.
|
6
10
|
class XmlExtractor
|
7
11
|
attr_reader :stream
|
8
12
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
module ClientForPoslynx
|
4
|
+
module MessageHandling
|
5
|
+
|
6
|
+
class XmlLinesBuffer
|
7
|
+
def initialize
|
8
|
+
reset
|
9
|
+
end
|
10
|
+
|
11
|
+
def add_line(line)
|
12
|
+
message << line
|
13
|
+
if (! root_name) && line =~ /^(?:<\?.+?\?>)?<([A-Za-z_][^\s>]*)[ >]/
|
14
|
+
self.root_name = $1
|
15
|
+
end
|
16
|
+
if root_name && line =~ /<\/#{root_name}\s*>\s*$/
|
17
|
+
complete_message = message
|
18
|
+
reset
|
19
|
+
yield complete_message
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :message
|
26
|
+
attr_accessor :root_name
|
27
|
+
|
28
|
+
def reset
|
29
|
+
@message = ''
|
30
|
+
@root_name = nil
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
module EventMachine
|
6
|
+
module Protocols
|
7
|
+
|
8
|
+
# Sends requests to and receives responses from a Precidia
|
9
|
+
# POSLynx system over TCP/IP.
|
10
|
+
module POSLynx
|
11
|
+
include EM::Protocols::LineProtocol
|
12
|
+
|
13
|
+
# Called by user code to send a request to the POSLynx
|
14
|
+
# system.
|
15
|
+
# The request object is expected to behave like an
|
16
|
+
# instance of a descendant class of
|
17
|
+
# ClientForPoslynx::Data::Requests::AbstractRequest.
|
18
|
+
def send_request(request)
|
19
|
+
serial_data = request.xml_serialize
|
20
|
+
send_data serial_data
|
21
|
+
end
|
22
|
+
|
23
|
+
# Invoked with responses received from the POSLynx system.
|
24
|
+
# Each response will be an instance of a descendent class
|
25
|
+
# of
|
26
|
+
# ClientForPoslynx::Data::Responses::AbstractResponse.
|
27
|
+
def receive_response(response)
|
28
|
+
# stub
|
29
|
+
end
|
30
|
+
|
31
|
+
# @private
|
32
|
+
def receive_line(line)
|
33
|
+
_response_buffer.add_line line do |complete_message|
|
34
|
+
response = ClientForPoslynx::Data::AbstractData.xml_parse( complete_message )
|
35
|
+
receive_response response
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @private
|
40
|
+
def _response_buffer
|
41
|
+
@_response_buffer ||= ClientForPoslynx::MessageHandling::XmlLinesBuffer.new
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'eventmachine'
|
4
|
+
|
5
|
+
module ClientForPoslynx
|
6
|
+
module Net
|
7
|
+
class StructuredClient
|
8
|
+
|
9
|
+
class EM_Connection < EM::Connection
|
10
|
+
include EM::Protocols::POSLynx
|
11
|
+
|
12
|
+
attr_reader :use_ssl, :directive_queue, :activity_queue
|
13
|
+
|
14
|
+
def initialize(use_ssl, directive_queue, activity_queue)
|
15
|
+
@use_ssl = use_ssl
|
16
|
+
@directive_queue = directive_queue
|
17
|
+
@activity_queue = activity_queue
|
18
|
+
end
|
19
|
+
|
20
|
+
def connection_completed
|
21
|
+
if use_ssl
|
22
|
+
start_tls verify_peer: false
|
23
|
+
else
|
24
|
+
handle_next_directive
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def ssl_handshake_completed
|
29
|
+
handle_next_directive
|
30
|
+
end
|
31
|
+
|
32
|
+
def unbind
|
33
|
+
EM.stop_event_loop
|
34
|
+
end
|
35
|
+
|
36
|
+
def receive_response(response)
|
37
|
+
activity_queue << [ :received_response, response ]
|
38
|
+
end
|
39
|
+
|
40
|
+
def handle_next_directive
|
41
|
+
EM.defer(
|
42
|
+
->{ directive_queue.shift },
|
43
|
+
->(directive){
|
44
|
+
process_directive directive
|
45
|
+
}
|
46
|
+
)
|
47
|
+
end
|
48
|
+
|
49
|
+
def process_directive(directive)
|
50
|
+
kind, *args = Array( directive )
|
51
|
+
case kind
|
52
|
+
when :end_session
|
53
|
+
end_session
|
54
|
+
when :send_request
|
55
|
+
begin
|
56
|
+
send_request *args
|
57
|
+
ensure
|
58
|
+
handle_next_directive
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def end_session
|
64
|
+
after_writing = true
|
65
|
+
close_connection after_writing
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require_relative 'structured_client/em_connection'
|
4
|
+
|
5
|
+
module ClientForPoslynx
|
6
|
+
module Net
|
7
|
+
|
8
|
+
# A network client API suitable for use in a Structured (as
|
9
|
+
# oppoesed to Event-Driven) context such as from within an
|
10
|
+
# irb console session.
|
11
|
+
class StructuredClient
|
12
|
+
|
13
|
+
class SessionEndedError < StandardError ; end
|
14
|
+
class SessionEndingError < StandardError ; end
|
15
|
+
|
16
|
+
# Initializes a new instance, given a host name or address
|
17
|
+
# and a host IP port number. If an SSL connection is
|
18
|
+
# required, then supply true for the use_ssl argument.
|
19
|
+
def initialize(host, port, use_ssl = false)
|
20
|
+
@directive_queue = Queue.new
|
21
|
+
@activity_queue = Queue.new
|
22
|
+
@em_thread = Thread.new do
|
23
|
+
EM.run do
|
24
|
+
EM.connect host, port, EM_Connection, use_ssl, directive_queue, activity_queue
|
25
|
+
EM.error_handler do |e|
|
26
|
+
raise e
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Close the server connection if it is open and end the
|
33
|
+
# session managed by the receiving instance.
|
34
|
+
def end_session
|
35
|
+
return unless em_thread.status
|
36
|
+
directive_queue << :end_session
|
37
|
+
self.session_end_initiated = true
|
38
|
+
em_thread.join
|
39
|
+
nil
|
40
|
+
end
|
41
|
+
|
42
|
+
# Sends a request to the POSLynx system and returns
|
43
|
+
# immediately.
|
44
|
+
# The request object is expected to behave like an
|
45
|
+
# instance of a descendant class of
|
46
|
+
# ClientForPoslynx::Data::Requests::AbstractRequest.
|
47
|
+
def send_request(request_data)
|
48
|
+
if session_ended?
|
49
|
+
raise SessionEndedError, "The session has been closed and cannot be used to send requests"
|
50
|
+
elsif session_ending?
|
51
|
+
raise SessionEndingError, "The session is ending and cannot be used to send requests"
|
52
|
+
end
|
53
|
+
directive_queue << [ :send_request, request_data ]
|
54
|
+
nil
|
55
|
+
end
|
56
|
+
|
57
|
+
# Returns the next available received response, if any.
|
58
|
+
# Returns nil is there are no remaining received responses
|
59
|
+
# to get.
|
60
|
+
# Each response will be an instance of a descendent class
|
61
|
+
# of
|
62
|
+
# ClientForPoslynx::Data::Responses::AbstractResponse.
|
63
|
+
def get_response
|
64
|
+
process_new_activity
|
65
|
+
received_responses.shift
|
66
|
+
end
|
67
|
+
|
68
|
+
# Returns true if the managed session has ended, either
|
69
|
+
# as a result of a call to #end_session or because the
|
70
|
+
# connection was closed by the server or otherwise lost.
|
71
|
+
def session_ended?
|
72
|
+
! em_thread.status
|
73
|
+
end
|
74
|
+
|
75
|
+
private
|
76
|
+
|
77
|
+
attr_reader :em_thread, :directive_queue, :activity_queue
|
78
|
+
attr_accessor :session_end_initiated
|
79
|
+
|
80
|
+
def session_ending?
|
81
|
+
session_end_initiated && ! session_ended?
|
82
|
+
end
|
83
|
+
|
84
|
+
def process_new_activity
|
85
|
+
until activity_queue.empty?
|
86
|
+
process_activity_entry *activity_queue.shift
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def process_activity_entry(kind, data=nil)
|
91
|
+
case kind
|
92
|
+
when :received_response
|
93
|
+
received_responses << data
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def received_responses
|
98
|
+
@received_responses ||= []
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
data/lib/client_for_poslynx.rb
CHANGED
@@ -5,6 +5,8 @@ require "client_for_poslynx/data"
|
|
5
5
|
require "client_for_poslynx/message_handling"
|
6
6
|
require "client_for_poslynx/bit_sequence"
|
7
7
|
require "client_for_poslynx/signature_image"
|
8
|
+
require "client_for_poslynx/net"
|
9
|
+
require "client_for_poslynx/example_request_factory"
|
8
10
|
|
9
11
|
module ClientForPoslynx
|
10
12
|
|
@@ -4,7 +4,7 @@ module ClientForPoslynx
|
|
4
4
|
|
5
5
|
describe Data::Requests::PinPadDisplayMessage do
|
6
6
|
|
7
|
-
it_behaves_like "a data object"
|
7
|
+
it_behaves_like "a request data object"
|
8
8
|
|
9
9
|
it "Serializes to a PLRequest XML document for a PPDISPLAY request" do
|
10
10
|
mac = Data::Requests::DEFAULT_CLIENT_MAC
|
@@ -4,7 +4,7 @@ module ClientForPoslynx
|
|
4
4
|
|
5
5
|
describe Data::Requests::PinPadDisplaySpecifiedForm do
|
6
6
|
|
7
|
-
it_behaves_like "a data object"
|
7
|
+
it_behaves_like "a request data object"
|
8
8
|
|
9
9
|
it "Serializes to an XML document for a PPSPECIFIEDFORM request" do
|
10
10
|
mac = Data::Requests::DEFAULT_CLIENT_MAC
|
@@ -6,7 +6,7 @@ module ClientForPoslynx
|
|
6
6
|
|
7
7
|
describe Data::Requests::PinPadGetSignature do
|
8
8
|
|
9
|
-
it_behaves_like "a data object"
|
9
|
+
it_behaves_like "a request data object"
|
10
10
|
|
11
11
|
it "Serializes to a PLRequest XML document for a PPGETSIGNATURE request" do
|
12
12
|
mac = Data::Requests::DEFAULT_CLIENT_MAC
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ClientForPoslynx
|
4
|
+
|
5
|
+
describe Data::Requests::PinPadReset do
|
6
|
+
|
7
|
+
it_behaves_like "a request data object"
|
8
|
+
|
9
|
+
it "Serializes to a PLRequest XML document for a PPRESET request" do
|
10
|
+
mac = Data::Requests::DEFAULT_CLIENT_MAC
|
11
|
+
expected_xml =
|
12
|
+
"<PLRequest><Command>PPRESET</Command><ClientMAC>#{mac}</ClientMAC></PLRequest>\n"
|
13
|
+
|
14
|
+
expect( subject.xml_serialize ).to eq( expected_xml )
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
it "Serializes all assigned members to appropriate elements" do
|
19
|
+
subject.client_mac = 'the-mac'
|
20
|
+
|
21
|
+
expected_xml =
|
22
|
+
"<PLRequest><Command>PPRESET</Command><ClientMAC>the-mac</ClientMAC></PLRequest>\n"
|
23
|
+
|
24
|
+
expect( subject.xml_serialize ).to eq( expected_xml )
|
25
|
+
end
|
26
|
+
|
27
|
+
|
28
|
+
it "parses XML data" do
|
29
|
+
xml_input = <<-XML
|
30
|
+
<PLRequest>
|
31
|
+
<Command>PPRESET</Command>
|
32
|
+
</PLRequest>
|
33
|
+
XML
|
34
|
+
|
35
|
+
actual_instance = described_class.xml_deserialize xml_input
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
it "accepts a canonical visitor" do
|
40
|
+
visitor = Object.new
|
41
|
+
visitor.extend Data::Requests::CanVisit
|
42
|
+
expect{ subject.accept_visitor visitor }.not_to raise_exception
|
43
|
+
end
|
44
|
+
|
45
|
+
it "sends itself to an accepted visitor" do
|
46
|
+
visitor = double :visitor
|
47
|
+
expect( visitor ).to receive( :visit_PinPadReset ).with( subject )
|
48
|
+
subject.accept_visitor visitor
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -4,7 +4,7 @@ module ClientForPoslynx
|
|
4
4
|
|
5
5
|
describe Data::Responses::CreditCardSale do
|
6
6
|
|
7
|
-
it_behaves_like "a data object"
|
7
|
+
it_behaves_like "a response data object"
|
8
8
|
|
9
9
|
# At least one revision of the POSLynx returns signature
|
10
10
|
# data surrounded by <[CDATA[...]]> which is obviously
|
@@ -4,7 +4,7 @@ module ClientForPoslynx
|
|
4
4
|
|
5
5
|
describe Data::Responses::DebitCardSale do
|
6
6
|
|
7
|
-
it_behaves_like "a data object"
|
7
|
+
it_behaves_like "a response data object"
|
8
8
|
|
9
9
|
it "Serializes to a PLResponse XML document for a DCSALE response" do
|
10
10
|
expected_xml = "<PLResponse><Command>DCSALE</Command></PLResponse>\n"
|
@@ -4,7 +4,7 @@ module ClientForPoslynx
|
|
4
4
|
|
5
5
|
describe Data::Responses::PinPadGetSignature do
|
6
6
|
|
7
|
-
it_behaves_like "a data object"
|
7
|
+
it_behaves_like "a response data object"
|
8
8
|
|
9
9
|
it "Serializes to a PLResponse XML document for a PPGETSIGNATURE response" do
|
10
10
|
expected_xml = "<PLResponse><Command>PPGETSIGNATURE</Command></PLResponse>\n"
|
@@ -4,7 +4,7 @@ module ClientForPoslynx
|
|
4
4
|
|
5
5
|
describe Data::Responses::PinPadDisplaySpecifiedForm do
|
6
6
|
|
7
|
-
it_behaves_like "a data object"
|
7
|
+
it_behaves_like "a response data object"
|
8
8
|
|
9
9
|
it "Serializes to a PLResponse XML document for a PPSPECIFIEDFORM response" do
|
10
10
|
expected_xml = "<PLResponse><Command>PPSPECIFIEDFORM</Command></PLResponse>\n"
|
@@ -4,7 +4,7 @@ module ClientForPoslynx
|
|
4
4
|
|
5
5
|
describe Data::Responses::PinPadInitialize do
|
6
6
|
|
7
|
-
it_behaves_like "a data object"
|
7
|
+
it_behaves_like "a response data object"
|
8
8
|
|
9
9
|
it "Serializes to a PLResponse XML document for a PPINIT response" do
|
10
10
|
expected_xml = "<PLResponse><Command>PPINIT</Command></PLResponse>\n"
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module ClientForPoslynx
|
4
|
+
|
5
|
+
describe Data::Responses::PinPadReset do
|
6
|
+
|
7
|
+
it_behaves_like "a response data object"
|
8
|
+
|
9
|
+
it "Serializes to a PLResponse XML document for a PPRESET response" do
|
10
|
+
expected_xml = "<PLResponse><Command>PPRESET</Command></PLResponse>\n"
|
11
|
+
expect( subject.xml_serialize ).to eq( expected_xml )
|
12
|
+
end
|
13
|
+
|
14
|
+
|
15
|
+
it "Serializes all assigned members to appropriate elements" do
|
16
|
+
subject.result = 'the-result'
|
17
|
+
subject.result_text = 'the-text'
|
18
|
+
subject.error_code = 'the-code'
|
19
|
+
|
20
|
+
expected_xml =
|
21
|
+
"<PLResponse>" +
|
22
|
+
"<Command>PPRESET</Command>" +
|
23
|
+
"<Result>the-result</Result>" +
|
24
|
+
"<ResultText>the-text</ResultText>" +
|
25
|
+
"<ErrorCode>the-code</ErrorCode>" +
|
26
|
+
"</PLResponse>\n"
|
27
|
+
|
28
|
+
expect( subject.xml_serialize ).to eq( expected_xml )
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
it "parses minimally acceptable XML data" do
|
33
|
+
xml_input = <<-XML
|
34
|
+
<PLResponse>
|
35
|
+
<Command>PPRESET</Command>
|
36
|
+
</PLResponse>
|
37
|
+
XML
|
38
|
+
|
39
|
+
actual_instance = described_class.xml_deserialize xml_input
|
40
|
+
expect( actual_instance.result ).to be_nil
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
it "parses XML data with all property elements supplied" do
|
45
|
+
xml_input = <<-XML
|
46
|
+
<PLResponse>
|
47
|
+
<Command>PPRESET</Command>
|
48
|
+
<Result>the-result</Result>
|
49
|
+
<ResultText>the-text</ResultText>
|
50
|
+
<ErrorCode>the-code</ErrorCode>
|
51
|
+
</PLResponse>
|
52
|
+
XML
|
53
|
+
|
54
|
+
actual_instance = described_class.xml_deserialize xml_input
|
55
|
+
|
56
|
+
expect( actual_instance.result ).to eq( 'the-result' )
|
57
|
+
expect( actual_instance.result_text ).to eq( 'the-text' )
|
58
|
+
expect( actual_instance.error_code ).to eq( 'the-code' )
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'stringio'
|
5
|
+
|
6
|
+
module ClientForPoslynx
|
7
|
+
|
8
|
+
describe EM::Protocols::POSLynx do
|
9
|
+
|
10
|
+
let( :connection_class ) {
|
11
|
+
subj = subject
|
12
|
+
connection_class =
|
13
|
+
Class.new do
|
14
|
+
include subj
|
15
|
+
|
16
|
+
def send_data(data) ; end
|
17
|
+
end
|
18
|
+
}
|
19
|
+
|
20
|
+
let( :connection ) { connection_class.new }
|
21
|
+
|
22
|
+
it "sends a request" do
|
23
|
+
request = Data::Requests::PinPadDisplayMessage.new.tap do |req|
|
24
|
+
req.client_mac = 'cdef'
|
25
|
+
end
|
26
|
+
|
27
|
+
expect( connection ).to receive( :send_data ){ |serial_data|
|
28
|
+
got_data = Data::AbstractData.xml_parse( serial_data )
|
29
|
+
expect( got_data ).to be_kind_of( Data::Requests::PinPadDisplayMessage )
|
30
|
+
expect( got_data.client_mac ).to eq( 'cdef' )
|
31
|
+
}
|
32
|
+
|
33
|
+
connection.send_request request
|
34
|
+
end
|
35
|
+
|
36
|
+
it "receives a response" do
|
37
|
+
response = Data::Responses::PinPadDisplayMessage.new.tap do |req|
|
38
|
+
req.result = "Hooya"
|
39
|
+
end
|
40
|
+
|
41
|
+
expect( connection ).to receive( :receive_response ){ |got_data|
|
42
|
+
expect( got_data ).to be_kind_of( Data::Responses::PinPadDisplayMessage )
|
43
|
+
expect( got_data.result ).to eq( 'Hooya' )
|
44
|
+
}
|
45
|
+
|
46
|
+
connection.receive_data response.xml_serialize.rstrip
|
47
|
+
connection.receive_data "\n"
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|