7 use vars
qw(@ISA $VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS);
14 auth
=> [qw(&api_auth)],
15 basic
=> [qw($datepat $textpat $login_test $sc_status_test
16 $instid $instid2 $currency $server $username $password)],
17 # duplicate user1 and item1 as user2 and item2
18 # w/ tags like $user2_pin instead of $user_pin
19 user1 => [qw($user_barcode $user_pin $user_fullname $user_homeaddr $user_email
20 $user_phone $user_birthday $user_ptype $user_inet)],
21 user2 => [qw($user2_barcode $user._pin $user2_fullname $user2_homeaddr $user2_email
22 $user2_phone $user2_birthday $user2_ptype $user2_inet)],
23 item1 => [qw($item_barcode $item_title $item_owner )],
24 item2 => [qw($item2_barcode $item2_title $item2_owner )],
25 # we've got item3_* also
26 item3 => [qw($item3_barcode $item3_title $item3_owner )],
27 diacritic => [qw($item_diacritic_barcode $item_diacritic_title $item_diacritic_owner)],
29 # From perldoc Exporter
30 # Add all the other ":class" tags to the ":all" class, deleting duplicates
32 push @{$EXPORT_TAGS{all}},
33 grep {!$seen{$_}++} @{$EXPORT_TAGS{$_}} foreach keys %EXPORT_TAGS;
34 Exporter::export_ok_tags('all'); # Anything in a tag is in OK_EXPORT
35 # print Dumper(\%EXPORT_TAGS); # Uncomment if you want to see the results of these tricks.
38 # The number of tests is set in run_sip_tests() below, based
39 # on the size of the array of tests.
44 use C4::SIP::Sip qw(:all);
45 use C4
::SIP
::Sip
::Checksum
qw(verify_cksum);
46 use C4
::SIP
::Sip
::Constants
qw(:all);
48 use C4
::Auth
qw(&check_api_auth);
51 # TODO: just read SIPconfig.xml and extract what we can....
53 # Configuration parameters to run the test suite
55 our $instid = 'CPL'; # branchcode
56 our $instid2 = 'FPL'; # branchcode
57 our $currency = 'USD'; # 'CAD';
58 our $server = 'localhost:6001'; # Address of the SIP server
60 # SIP username and password to connect to the server.
61 # See SIPconfig.xml for the correct values.
62 our $username = 'term1';
63 our $password = 'term1';
67 # NOTE: make sure to escape the data for use in RegExp.
68 # Valid user barcode and corresponding user password/pin and full name
69 our $user_barcode = '23529001000463';
70 our $user_pin = 'fn5zS';
71 our $user_fullname= 'Edna Acosta';
72 our $user_homeaddr= '7896 Library Rd\.';
73 our $user_email = 'patron\@liblime\.com';
74 our $user_phone = '\(212\) 555-1212';
75 our $user_birthday= '19800424'; # YYYYMMDD, ANSI X3.30
76 our $user_ptype = 'PT';
80 our $user2_barcode = '23529000240482';
81 our $user2_pin = 'jw937';
82 our $user2_fullname= 'Jamie White';
83 our $user2_homeaddr= '937 Library Rd\.';
84 our $user2_email = 'patron\@liblime\.com';
85 our $user2_phone = '\(212\) 555-1212';
86 our $user2_birthday= '19500422'; # YYYYMMDD, ANSI X3.30
87 our $user2_ptype = 'T';
88 our $user2_inet = 'Y';
90 # Valid item barcode and corresponding title
91 our $item_barcode = '502326000005';
92 our $item_title = 'How I became a pirate /';
93 our $item_owner = 'CPL';
96 our $item2_barcode = '502326000011';
97 our $item2_title = 'The biggest, smallest, fastest, tallest things you\'ve ever heard of /';
98 our $item2_owner = 'CPL';
101 our $item3_barcode = '502326000240';
102 our $item3_title = 'The girl who owned a city /';
103 our $item3_owner = 'FPL';
105 # An item with a diacritical in the title
106 our $item_diacritic_barcode = '502326001030';
107 our $item_diacritic_titlea = 'Hari Poṭer u-geviʻa ha-esh /';
108 our $item_diacritic_owner = 'CPL';
112 # Pattern for a SIP datestamp, to be used by individual tests to
113 # match timestamp fields (duh).
114 our $datepat = '\d{8} {4}\d{6}';
116 # Pattern for a random text field (may be empty)
117 our $textpat = qr/^[^|]*$/;
120 (FID_SCREEN_MSG
) => { field
=> FID_SCREEN_MSG
,
123 (FID_PRINT_LINE
) => { field
=> FID_PRINT_LINE
,
126 (FID_INST_ID
) => { field
=> FID_INST_ID
,
127 pat
=> qr/^$instid$/o,
129 (FID_HOLD_ITEMS_LMT
)=> { field
=> FID_HOLD_ITEMS_LMT
,
132 (FID_OVERDUE_ITEMS_LMT
)=> { field
=> FID_OVERDUE_ITEMS_LMT
,
135 (FID_CHARGED_ITEMS_LMT
)=> { field
=> FID_CHARGED_ITEMS_LMT
,
138 (FID_VALID_PATRON
) => { field
=> FID_VALID_PATRON
,
141 (FID_VALID_PATRON_PWD
)=> { field
=> FID_VALID_PATRON_PWD
,
144 (FID_CURRENCY
) => { field
=> FID_CURRENCY
,
145 pat
=> qr/^$currency$/io,
149 # Login and SC Status are always the first two messages that
150 # the terminal sends to the server, so just create the test
151 # cases here and reference them in the individual test files.
153 our $login_test = { id
=> 'login',
154 msg
=> "9300CN$username|CO$password|CPThe floor|",
158 our $sc_status_test = { id
=> 'SC status',
160 pat
=> qr/^98[YN]{6}\d{3}\d{3}$datepat(2\.00|1\.00)/,
162 $field_specs{(FID_SCREEN_MSG
)},
163 $field_specs{(FID_PRINT_LINE
)},
164 $field_specs{(FID_INST_ID
)},
169 pat
=> qr/^[YN]{16}$/,
178 my ($sock, $test, $seqno) = @_;
182 # If reading or writing fails, then the server's dead,
183 # so there's no point in continuing.
184 if ( !write_msg
( { seqno
=> $seqno }, $test->{msg
}, $sock ) ) {
185 BAIL_OUT
("Write failure in $test->{id}");
188 my $rv = sysread( $sock, $resp, 10000000 ); # 10000000 is a big number
191 BAIL_OUT
("Read failure in $test->{id}");
196 $resp =~ s/\015?\012$//;
199 if (!verify_cksum
($resp)) {
200 fail
("$test->{id} checksum($resp)");
203 if ($resp !~ $test->{pat
}) {
204 fail
("match leader $test->{id}");
205 diag
("Response '$resp' doesn't match pattern '$test->{pat}'");
209 # Split the tagged fields of the response into (name, value)
210 # pairs and stuff them into the hash.
211 $resp =~ $test->{pat
};
212 %fields = substr($resp, $+[0]) =~ /(..)([^|]*)\|/go;
214 # print STDERR "one_msg ( test ) : " . Dumper($test) . "\n" .
215 # "one_msg (fields) : " . Dumper(\%fields);
216 if (!defined($test->{fields
})) {
217 diag
("TODO: $test->{id} field tests not written yet");
219 # If there are no tagged fields, then 'fields' should be an
220 # empty list which will automatically skip this loop
221 foreach my $ftest (@
{$test->{fields
}}) {
222 my $field = $ftest->{field
};
224 if ($ftest->{required
} && !exists($fields{$field})) {
225 fail
("$test->{id}: required field '$field' not found in '$resp'");
229 if (exists($fields{$field}) && ($fields{$field} !~ $ftest->{pat
})) {
230 fail
("$test->{id} field test $field");
231 diag
("Field '$field' pattern '$ftest->{pat}' fails to match value '$fields{$field}' in message '$resp'");
242 $ENV{REMOTE_USER
} = $username;
243 my $query = CGI
->new();
244 $query->param(userid
=> $username);
245 $query->param(password
=> $password);
246 my ($status, $cookie, $sessionID) = check_api_auth
($query, {circulate
=>1}, "intranet");
247 print STDERR
"check_api_auth returns " . ($status || 'undef') . "\n";
248 # print STDERR "api_auth userenv = " . &dump_userenv;
253 my $userenv = C4
::Context
->userenv;
254 return "# userenv: EMPTY\n" unless ($userenv);
255 my $userbranch = $userenv->{branch
};
256 return "# userenv: " . Dumper
($userenv)
257 . ($userbranch ?
"BRANCH FOUND: $userbranch\n" : "NO BRANCH FOUND\n");
263 $Sip::error_detection
= 1;
264 $/ = "\015\012"; # must use correct record separator
266 $sock = new IO
::Socket
::INET
(PeerAddr
=> $server,
267 Type
=> SOCK_STREAM
);
269 BAIL_OUT
('failed to create connection to server') unless $sock;
272 # print STDERR "Number of tests : ", scalar (@_), "\n";
273 plan tests
=> scalar(@_);
274 foreach my $test (@_) {
275 # print STDERR "Test $seqno:" . Dumper($test);
276 one_msg
($sock, $test, $seqno++);
277 $seqno %= 10; # sequence number is one digit