2aaf22318d1c41953f97f97f4a28c564d582f523
[Business-OnlinePayment.git] / t / bop.t
1 #!/usr/bin/perl
2 # $Id: bop.t,v 1.9 2006-11-20 06:27:14 plobbes Exp $
3
4 use strict;
5 use warnings;
6 use Test::More tests => 60;
7
8 BEGIN { use_ok("Business::OnlinePayment") or exit; }
9
10 {    # fake test driver 1 (no submit method)
11
12     package Business::OnlinePayment::MOCK1;
13     use strict;
14     use warnings;
15     use base qw(Business::OnlinePayment);
16 }
17
18 {    # fake test driver 2 (with submit method that dies)
19
20     package Business::OnlinePayment::MOCK2;
21     use base qw(Business::OnlinePayment::MOCK1);
22     sub submit { my $self = shift; die("in processor submit\n"); }
23 }
24
25 {    # fake test driver 3 (with submit method)
26
27     package Business::OnlinePayment::MOCK3;
28     use base qw(Business::OnlinePayment::MOCK1);
29     sub submit { my $self = shift; return 1; }
30 }
31
32 my $package = "Business::OnlinePayment";
33 my @drivers = qw(MOCK1 MOCK2 MOCK3);
34 my $driver  = $drivers[0];
35
36 # trick to make use() happy (called in Business::OnlinePayment->new)
37 foreach my $drv (@drivers) {
38     $INC{"Business/OnlinePayment/${drv}.pm"} = "testing";
39 }
40
41 {    # new
42     can_ok( $package, qw(new) );
43     my $obj;
44
45     eval { $obj = $package->new(); };
46     like( $@, qr/^unspecified processor/, "new() without a processor croaks" );
47
48     eval { $obj = $package->new("__BOP BOGUS PROCESSOR__"); };
49     like( $@, qr/^unknown processor/,
50         "new() with an unknown processor croaks" );
51
52     $obj = $package->new($driver);
53     isa_ok( $obj, $package );
54     isa_ok( $obj, $package . "::" . $driver );
55
56     # build_subs(%fields)
57     can_ok(
58         $obj, qw(
59           authorization
60           error_message
61           failure_status
62           fraud_detect
63           is_success
64           maximum_risk
65           path
66           port
67           require_avs
68           result_code
69           server
70           server_response
71           test_transaction
72           transaction_type
73           )
74     );
75
76     # new (via build_subs) automatically creates accessors for arguments
77     $obj = $package->new( $driver, "proc1" => "value1" );
78     can_ok( $package, "proc1" );
79     can_ok( $obj,     "proc1" );
80
81     # new (via build_subs) automatically creates accessors for arguments
82     $obj = $package->new( $driver, qw(key1 v1 Key2 v2 -Key3 v3 --KEY4 v4) );
83     can_ok( $package, qw(key1 key2 key3 key4) );
84     can_ok( $obj,     qw(key1 key2 key3 key4) );
85
86     # new makes all accessors lowercase and removes leading dash(es)
87     is( $obj->key1, "v1", "value of key1   (method key1) is v1" );
88     is( $obj->key2, "v2", "value of Key2   (method key2) is v2" );
89     is( $obj->key3, "v3", "value of -Key3  (method key3) is v3" );
90     is( $obj->key4, "v4", "value of --KEY4 (method key4) is v4" );
91 }
92
93 # XXX
94 # {    # _risk_detect }
95
96 {    # _pre_submit
97
98     my $s_orig = Business::OnlinePayment::MOCK3->can("submit");
99     is( ref $s_orig, "CODE", "MOCK3 submit code ref $s_orig" );
100
101     # test to ensure we do not go recursive when wrapping submit
102     my $obj1   = $package->new("MOCK3");
103     my $s_new1 = $obj1->can("submit");
104
105     isnt( $s_new1, $s_orig, "MOCK3 submit code ref $s_new1 (wrapped)" );
106     is( $obj1->submit, "1", "MOCK3(obj1) submit returns 1" );
107
108     my $obj2   = $package->new("MOCK3");
109     my $s_new2 = $obj2->can("submit");
110     is( $obj2->submit, "1", "MOCK3(obj2) submit returns 1" );
111
112     # fraud detection failure modes
113     my $obj  = $package->new("MOCK3");
114     my $proc = "__BOGUS_PROCESSOR";
115
116     is( $obj->fraud_detect($proc), $proc, "fraud_detect set to '$proc'" );
117     eval { $obj->submit; };
118     is( $@, "", "fraud_detect ignores non-existant processors" );
119
120     # XXX: need more test cases for when fraud detection is enabled
121 }
122
123 {    # content
124     my $obj;
125
126     $obj = $package->new($driver);
127     can_ok( $package, qw(content) );
128     can_ok( $obj,     qw(content) );
129
130     is( $obj->content, (), "default content is empty" );
131
132     my %data = qw(k1 v1 type test -k2 v2 K3 v3);
133     is_deeply( { $obj->content(%data) }, \%data, "content is set properly" );
134     is( $obj->transaction_type, "test", "content sets transaction_type" );
135
136     %data = ( type => undef );
137     is_deeply( { $obj->content(%data) }, \%data, "content with type=>undef" );
138     is( $obj->transaction_type, "test", "transaction_type not reset" );
139 }
140
141 {    # required_fields
142     my $obj = $package->new($driver);
143     can_ok( $package, qw(required_fields) );
144     can_ok( $obj,     qw(required_fields) );
145
146     is( $obj->required_fields, 0, "no required fields" );
147
148     eval { $obj->required_fields("field1"); };
149     like( $@, qr/^missing required field/, "missing required_fields croaks" );
150 }
151
152 {    # get_fields
153     my $obj = $package->new($driver);
154     can_ok( $package, qw(get_fields) );
155     can_ok( $obj,     qw(get_fields) );
156
157     my %data = ( a => 1, b => 2, c => undef, d => 4 );
158     $obj->content(%data);
159
160     my ( @want, %get );
161
162     @want = qw(a b);
163     %get = map { $_ => $data{$_} } @want;
164     is_deeply( { $obj->get_fields(@want) },
165         \%get, "get_fields with defined vals" );
166
167     @want = qw(a c d);
168     %get = map { defined $data{$_} ? ( $_ => $data{$_} ) : () } @want;
169
170     is_deeply( { $obj->get_fields(@want) },
171         \%get, "get_fields does not get fields with undef values" );
172 }
173
174 {    # remap_fields
175     my $obj = $package->new($driver);
176     can_ok( $package, qw(remap_fields) );
177     can_ok( $obj,     qw(remap_fields) );
178
179     my %data = ( a => 1, b => 2, c => undef, d => 4 );
180     $obj->content(%data);
181
182     my %map = ( a => "Aa", d => "Dd" );
183     my %get = ( a => 1, Aa => 1, b => 2, c => undef, d => 4, Dd => 4 );
184
185     $obj->remap_fields(%map);
186     is_deeply( { $obj->content }, \%get, "remap_fields" );
187 }
188
189 {    # submit
190     my $obj = $package->new($driver);
191     can_ok( $package, qw(submit) );
192     can_ok( $obj,     qw(submit) );
193
194     eval { $obj->submit; };
195     like( $@, qr/^Processor subclass did not /, "missing submit() croaks" );
196     isnt( $obj->can("submit"), $package->can("submit"), "submit changed" );
197
198     my $mock2 = $package->new("MOCK2");
199     can_ok( $mock2, qw(submit) );
200
201     isnt( $mock2->can("submit"), $package->can("submit"), "submit changed" );
202     eval { $mock2->submit; };
203     like( $@, qr/^in processor submit/, "processor submit() is called" );
204 }
205
206 {    # dump_contents
207     my $obj = $package->new($driver);
208     can_ok( $package, qw(dump_contents) );
209     can_ok( $obj,     qw(dump_contents) );
210 }
211
212 {    # build_subs
213     my $obj;
214
215     $obj = $package->new($driver);
216     can_ok( $package, qw(build_subs) );
217     can_ok( $obj,     qw(build_subs) );
218
219     # build_subs creates accessors for arguments
220     my %data = qw(key1 v1 Key2 v2 -Key3 v3 --KEY4 v4);
221     my @subs =
222       sort { lc( ( $a =~ /(\w+)/ )[0] ) cmp lc( ( $b =~ /(\w+)/ )[0] ) }
223       keys %data;
224
225     $obj->build_subs(@subs);
226
227     # perl does not allow dashes ("-") in subroutine names
228     foreach my $sub (@subs) {
229         if ( $sub !~ /^\w+/ ) {
230             is( ref $package->can($sub), "", "$package can NOT $sub" );
231             is( ref $obj->can($sub),     "", ref($obj) . " can NOT $sub" );
232         }
233         else {
234             can_ok( $package, $sub );
235             can_ok( $obj,     $sub );
236             $obj->$sub( $data{$sub} );
237             is( $obj->$sub, $data{$sub}, "$sub accessor returns $data{$sub}" );
238         }
239     }
240 }