test bill payment
[working/Evergreen.git] / Open-ILS / src / perlmods / live_t / 05-pay_bills.t
1 #!perl
2
3 use Test::More tests => 10;
4
5 diag("Test bill payment against the admin user.");
6
7 use constant WORKSTATION_NAME => 'BR4-test-05-pay-bills.t';
8 use constant WORKSTATION_LIB => 7;
9 use constant USER_ID => 1;
10 use constant USER_USRNAME => 'admin';
11
12 use strict;
13 use warnings;
14 use Data::Dumper;
15 use OpenSRF::System;
16 use OpenSRF::AppSession;
17 use Digest::MD5 qw(md5_hex);
18 use OpenILS::Utils::Fieldmapper;
19 use OpenILS::Application::AppUtils;
20 use DateTime;
21 use DateTime::Format::ISO8601;
22 use OpenSRF::Utils qw/cleanse_ISO8601/;
23 use OpenSRF::Utils::SettingsClient;
24
25 # Some useful objects
26 our $cache      = "OpenSRF::Utils::Cache";
27 our $apputils   = "OpenILS::Application::AppUtils";
28 our $memcache;
29 our $authtoken;
30 our $authtime;
31
32 #----------------------------------------------------------------
33 # Exit a script
34 #----------------------------------------------------------------
35 sub err {
36     my ($pkg, $file, $line, $sub)  = _caller();
37     no warnings;
38     die "Script halted with error ".
39         "($pkg : $file : $line : $sub):\n" . shift() . "\n";
40 }
41
42 #----------------------------------------------------------------
43 # This is not the function you're looking for
44 #----------------------------------------------------------------
45 sub _caller {
46     my ($pkg, $file, $line, $sub)  = caller(2);
47     if(!$line) {
48         ($pkg, $file, $line)  = caller(1);
49         $sub = "";
50     }
51     return ($pkg, $file, $line, $sub);
52 }
53
54 #----------------------------------------------------------------
55 # Connect to the servers
56 #----------------------------------------------------------------
57 sub osrf_connect {
58     my $config = `osrf_config --sysconfdir`;
59     chomp $config;
60     $config .= '/opensrf_core.xml';
61     err("Bootstrap config required") unless $config;
62     OpenSRF::System->bootstrap_client( config_file => $config );
63     Fieldmapper->import(IDL =>
64         OpenSRF::Utils::SettingsClient->new->config_value("IDL"));
65 }
66
67 #----------------------------------------------------------------
68 # Is the given object an OILS event?
69 #----------------------------------------------------------------
70 sub oils_is_event {
71     my $e = shift;
72     if( $e and ref($e) eq 'HASH' ) {
73         return 1 if defined($e->{ilsevent});
74     }
75     return 0;
76 }
77
78 #----------------------------------------------------------------
79 # If the given object is an event, this prints the event info 
80 # and exits the script
81 #----------------------------------------------------------------
82 sub oils_event_die {
83     my $evt = shift;
84     my ($pkg, $file, $line, $sub)  = _caller();
85     if(oils_is_event($evt)) {
86         if($evt->{ilsevent}) {
87             diag("\nReceived Event($pkg : $file : $line : $sub): \n" . Dumper($evt));
88             exit 1;
89         }
90     }
91 }
92
93 #----------------------------------------------------------------
94 # Login to the auth server and set the global $authtoken var
95 #----------------------------------------------------------------
96 sub oils_login {
97     my( $username, $password, $type, $ws ) = @_;
98
99     $type |= "staff";
100
101     my $seed = $apputils->simplereq( 'open-ils.auth',
102         'open-ils.auth.authenticate.init', $username );
103     err("No auth seed") unless $seed;
104
105     my $response = $apputils->simplereq( 'open-ils.auth',
106         'open-ils.auth.authenticate.complete',
107         {   username => $username,
108             password => md5_hex($seed . md5_hex($password)),
109             type => $type, workstation => $ws });
110
111     err("No auth response returned on login") unless $response;
112
113     oils_event_die($response);
114
115     $authtime  = $response->{payload}->{authtime};
116     $authtoken = $response->{payload}->{authtoken};
117     diag("authtime is $authtime, authtoken is $authtoken");
118     return $authtoken;
119 }
120
121 #----------------------------------------------------------------
122 # Destroys the login session on the server
123 #----------------------------------------------------------------
124 sub oils_logout {
125     $apputils->simplereq(
126         'open-ils.auth',
127         'open-ils.auth.session.delete', (@_ ? shift : $authtoken) );
128 }
129
130 #----------------------------------------------------------------
131 # var $response = simplereq( $service, $method, @params );
132 #----------------------------------------------------------------
133 sub simplereq    { return $apputils->simplereq(@_); }
134 sub osrf_request { return $apputils->simplereq(@_); }
135
136 #----------------------------------------------------------------
137
138 sub register_workstation {
139     my $resp = osrf_request(
140         'open-ils.actor',
141         'open-ils.actor.workstation.register',
142         $authtoken, WORKSTATION_NAME, WORKSTATION_LIB);
143     return $resp;
144 }
145
146 sub fetch_billing_summaries {
147     my $resp = osrf_request(
148         'open-ils.actor',
149         'open-ils.actor.user.transactions.history.have_balance.authoritative',
150         $authtoken,
151         USER_ID
152     );
153     return $resp;
154 }
155
156 sub pay_bills {
157     my ($user_obj, $payment_blob) = (shift, shift);
158     my $resp = osrf_request(
159         'open-ils.circ',
160         'open-ils.circ.money.payment',
161         $authtoken,
162         $payment_blob,
163         $user_obj->last_xact_id
164     );
165     return $resp;
166 }
167
168 #----------------------------------------------------------------
169 # The tests...  assumes stock sample data, full-auto install by
170 # eg_wheezy_installer.sh, etc.
171 #----------------------------------------------------------------
172
173 osrf_connect();
174 my $storage_ses = OpenSRF::AppSession->create('open-ils.storage');
175
176 my $user_obj;
177 my $user_req = $storage_ses->request('open-ils.storage.direct.actor.user.retrieve', USER_ID);
178 if (my $user_resp = $user_req->recv) {
179     if ($user_obj = $user_resp->content) {
180         is(
181             ref $user_obj,
182             'Fieldmapper::actor::user',
183             'open-ils.storage.direct.actor.user.retrieve returned aou object'
184         );
185         is(
186             $user_obj->usrname,
187             USER_USRNAME,
188             'User with id = ' . USER_ID . ' is ' . USER_USRNAME . ' user'
189         );
190     }
191 }
192
193 oils_login('admin','demo123','staff');
194 ok(
195     $authtoken,
196     'Have an authtoken'
197 );
198 my $ws = register_workstation();
199 ok(
200     ! ref $ws,
201     'Registered a new workstation'
202 );
203
204 oils_logout();
205 oils_login('admin','demo123','staff',WORKSTATION_NAME);
206 ok(
207     $authtoken,
208     'Have an authtoken associated with the workstation'
209 );
210
211 my $summaries = fetch_billing_summaries();
212
213 is(
214     scalar(@{ $summaries }),
215     2,
216     'Two billable xacts for ' . USER_USRNAME . ' user from previous tests'
217 );
218
219 is(
220     @{ $summaries }[0]->balance_owed + @{ $summaries }[1]->balance_owed,
221     1.25,
222     'Both transactions combined have a balance owed of 1.25'
223 );
224
225 my $payment_blob = {
226     userid => USER_ID,
227     note => '05-pay_bills.t',
228     payment_type => 'cash_payment',
229     patron_credit => '0.00',
230     payments => [ map { [ $_->id, $_->balance_owed ] } @{ $summaries } ]
231 };
232
233 my $pay_resp = pay_bills($user_obj,$payment_blob);
234
235 is(
236     ref $pay_resp,
237     'HASH',
238     'Payment attempt returned HASH'
239 );
240
241 is(
242     scalar( @{ $pay_resp->{payments} } ),
243     2,
244     'Payment response included two payment ids'
245 );
246
247 my $new_summaries = fetch_billing_summaries();
248 is(
249     scalar(@{ $new_summaries }),
250     0,
251     'Zero billable xacts for ' . USER_USRNAME . ' user after payment'
252 );
253
254 oils_logout();
255
256