Bug 22785: Allow option to choose which record match is applied during import
[koha.git] / t / db_dependent / api / v1 / import_record_matches.t
1 #!/usr/bin/env perl
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20 use Test::More tests => 1;
21 use Test::Mojo;
22 use Test::Warn;
23
24 use t::lib::TestBuilder;
25 use t::lib::Mocks;
26
27 use C4::Auth;
28 use Koha::Import::Record::Matches;
29
30 my $schema  = Koha::Database->new->schema;
31 my $builder = t::lib::TestBuilder->new;
32
33 # FIXME: sessionStorage defaults to mysql, but it seems to break transaction handling
34 # this affects the other REST api tests
35 t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' );
36
37 my $remote_address = '127.0.0.1';
38 my $t              = Test::Mojo->new('Koha::REST::V1');
39
40 subtest 'import record matches tests' => sub {
41
42     plan tests => 13;
43
44     $schema->storage->txn_begin;
45
46     my ( $unauthorized_borrowernumber, $unauthorized_session_id ) =
47       create_user_and_session( { authorized => 0 } );
48     my ( $authorized_borrowernumber, $authorized_session_id ) =
49       create_user_and_session( { authorized => 1 } );
50
51     my $match_1 = $builder->build_object({
52         class => 'Koha::Import::Record::Matches',
53         value => {
54             chosen => 0,
55         }
56     });
57     my $match_2 = $builder->build_object({
58         class => 'Koha::Import::Record::Matches',
59         value => {
60             import_record_id => $match_1->import_record_id,
61             chosen => 1,
62         }
63     });
64     my $del_match = $builder->build_object({ class => 'Koha::Import::Record::Matches' });
65     my $del_import_batch_id = $del_match->import_record->import_batch_id;
66     my $del_match_id = $del_match->import_record_id;
67
68     # Unauthorized attempt to update
69     my $tx = $t->ua->build_tx(
70       PUT => "/api/v1/import/".$match_1->import_record->import_batch_id."/records/".$match_1->import_record_id."/matches/chosen"=>
71       json => {
72           candidate_match_id => $match_1->candidate_match_id
73       }
74     );
75     $tx->req->cookies(
76         { name => 'CGISESSID', value => $unauthorized_session_id } );
77     $tx->req->env( { REMOTE_ADDR => $remote_address } );
78     $t->request_ok($tx)->status_is(403);
79
80     # Invalid attempt to allow match on a non-existent record
81     $tx = $t->ua->build_tx(
82       PUT => "/api/v1/import/".$del_import_batch_id."/records/".$del_match_id."/matches/chosen" =>
83       json => {
84           candidate_match_id => $match_1->candidate_match_id
85       }
86     );
87
88     $tx->req->cookies(
89         { name => 'CGISESSID', value => $authorized_session_id } );
90     $tx->req->env( { REMOTE_ADDR => $remote_address } );
91     $del_match->delete();
92     $t->request_ok($tx)->status_is(404)
93       ->json_is( '/error' => "Match not found" );
94
95     # Valid, authorised update
96     $tx = $t->ua->build_tx(
97       PUT => "/api/v1/import/".$match_1->import_record->import_batch_id."/records/".$match_1->import_record_id."/matches/chosen" =>
98       json => {
99           candidate_match_id => $match_1->candidate_match_id
100       }
101     );
102     $tx->req->cookies(
103         { name => 'CGISESSID', value => $authorized_session_id } );
104     $tx->req->env( { REMOTE_ADDR => $remote_address } );
105     $t->request_ok($tx)->status_is(200);
106
107     $match_1->discard_changes;
108     $match_2->discard_changes;
109     ok( $match_1->chosen,"Match 1 is correctly set to chosen");
110     ok( !$match_2->chosen,"Match 2 correctly unset when match 1 is set");
111
112     # Valid unsetting
113     $tx = $t->ua->build_tx(
114       DELETE => "/api/v1/import/".$match_1->import_record->import_batch_id."/records/".$match_1->import_record_id."/matches/chosen" =>
115       json => {
116       }
117     );
118     $tx->req->cookies(
119         { name => 'CGISESSID', value => $authorized_session_id } );
120     $tx->req->env( { REMOTE_ADDR => $remote_address } );
121     $t->request_ok($tx)->status_is(204);
122
123     $match_1->discard_changes;
124     $match_2->discard_changes;
125     ok( !$match_1->chosen,"Match 1 is correctly unset to chosen");
126     ok( !$match_2->chosen,"Match 2 is correctly unset to chosen");
127
128     $schema->storage->txn_rollback;
129 };
130
131 sub create_user_and_session {
132
133     my $args  = shift;
134     my $dbh   = C4::Context->dbh;
135
136     my $user = $builder->build(
137         {
138             source => 'Borrower',
139             value  => {
140                 flags => 0
141             }
142         }
143     );
144
145     # Create a session for the authorized user
146     my $session = C4::Auth::get_session('');
147     $session->param( 'number',   $user->{borrowernumber} );
148     $session->param( 'id',       $user->{userid} );
149     $session->param( 'ip',       '127.0.0.1' );
150     $session->param( 'lasttime', time() );
151     $session->flush;
152
153     if ( $args->{authorized} ) {
154         $builder->build({
155             source => 'UserPermission',
156             value  => {
157                 borrowernumber => $user->{borrowernumber},
158                 module_bit     => 13,
159                 code           => 'manage_staged_marc',
160             }
161         });
162     }
163
164     return ( $user->{borrowernumber}, $session->id );
165 }
166
167 1;