View | Details | Raw Unified | Return to bug 17170
Collapse All | Expand All

(-)a/Koha/REST/V1/SearchFilter.pm (+153 lines)
Line 0 Link Here
1
package Koha::REST::V1::SearchFilter;
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
17
use Modern::Perl;
18
19
use Mojo::Base 'Mojolicious::Controller';
20
use Koha::SearchFilters;
21
22
use Try::Tiny qw( catch try );
23
24
=head1 Name
25
26
Koha::REST::V1::SearchFilters
27
28
=head1 API
29
30
=head2 Methods
31
32
=head3 list
33
34
Controller function that handles listing Koha::SearchFilter objects
35
36
=cut
37
38
sub list {
39
    my $c = shift->openapi->valid_input or return;
40
    return try {
41
        my $filters_set = Koha::SearchFilters->search({});
42
        my $filters = $c->objects->search( $filters_set );
43
        return $c->render(
44
            status  => 200,
45
            openapi => $filters
46
        );
47
    }
48
    catch {
49
        $c->unhandled_exception($_);
50
    };
51
52
}
53
54
=head3 get
55
56
Controller function that handles retrieving a single Koha::AdvancedEditorMacro
57
58
=cut
59
60
sub get {
61
    my $c = shift->openapi->valid_input or return;
62
    my $filter = Koha::SearchFilters->find({
63
        id => $c->validation->param('search_filter_id'),
64
    });
65
    unless ($filter) {
66
        return $c->render( status  => 404,
67
                           openapi => { error => "Search filter not found" } );
68
    }
69
70
    return $c->render( status => 200, openapi => $filter->to_api );
71
}
72
73
=head3 add
74
75
Controller function that handles adding a new Koha::SearchFilter object
76
77
=cut
78
79
sub add {
80
    my $c = shift->openapi->valid_input or return;
81
82
    return try {
83
        my $filter = Koha::SearchFilter->new_from_api( $c->validation->param('body') );
84
        $filter->store->discard_changes;
85
        $c->res->headers->location( $c->req->url->to_string . '/' . $filter->id );
86
        return $c->render(
87
            status  => 201,
88
            openapi => $filter->to_api
89
        );
90
    }
91
    catch {
92
        if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
93
            return $c->render(
94
                status  => 409,
95
                openapi => { error => $_->error, conflict => $_->duplicate_id }
96
            );
97
        }
98
        $c->unhandled_exception($_);
99
    };
100
}
101
102
=head3 update
103
104
Controller function that handles updating a Koha::SearchFilter object
105
106
=cut
107
108
sub update {
109
    my $c = shift->openapi->valid_input or return;
110
111
    my $filter = Koha::SearchFilters->find( $c->validation->param('search_filter_id') );
112
113
    if ( not defined $filter ) {
114
        return $c->render( status  => 404,
115
                           openapi => { error => "Object not found" } );
116
    }
117
118
    return try {
119
        my $params = $c->req->json;
120
        $filter->set_from_api( $params );
121
        $filter->store->discard_changes;
122
        return $c->render( status => 200, openapi => $filter->to_api );
123
    }
124
    catch {
125
        $c->unhandled_exception($_);
126
    };
127
}
128
129
=head3 delete
130
131
Controller function that handles deleting a Koha::SearchFilter object
132
133
=cut
134
135
sub delete {
136
    my $c = shift->openapi->valid_input or return;
137
138
    my $filter = Koha::SearchFilters->find( $c->validation->param('search_filter_id') );
139
    if ( not defined $filter ) {
140
        return $c->render( status  => 404,
141
                           openapi => { error => "Object not found" } );
142
    }
143
144
    return try {
145
        $filter->delete;
146
        return $c->render( status => 204, openapi => q{} );
147
    }
148
    catch {
149
        $c->unhandled_exception($_);
150
    };
151
}
152
153
1;
(-)a/api/v1/swagger/definitions.yaml (+65 lines)
Line 0 Link Here
1
---
2
account_line:
3
  $ref: definitions/account_line.yaml
4
advancededitormacro:
5
  $ref: definitions/advancededitormacro.yaml
6
allows_renewal:
7
  $ref: definitions/allows_renewal.yaml
8
basket:
9
  $ref: definitions/basket.yaml
10
cashup:
11
  $ref: definitions/cashup.yaml
12
checkout:
13
  $ref: definitions/checkout.yaml
14
checkouts:
15
  $ref: definitions/checkouts.yaml
16
circ-rule-kind:
17
  $ref: definitions/circ-rule-kind.yaml
18
city:
19
  $ref: definitions/city.yaml
20
error:
21
  $ref: definitions/error.yaml
22
fund:
23
  $ref: definitions/fund.yaml
24
hold:
25
  $ref: definitions/hold.yaml
26
holds:
27
  $ref: definitions/holds.yaml
28
ill_backend:
29
  $ref: definitions/ill_backend.yaml
30
ill_backends:
31
  $ref: definitions/ill_backends.yaml
32
import_batch_profile:
33
  $ref: definitions/import_batch_profile.yaml
34
import_batch_profiles:
35
  $ref: definitions/import_batch_profiles.yaml
36
invoice:
37
  $ref: definitions/invoice.yaml
38
item:
39
  $ref: definitions/item.yaml
40
library:
41
  $ref: definitions/library.yaml
42
order:
43
  $ref: definitions/order.yaml
44
patron:
45
  $ref: definitions/patron.yaml
46
patron_account_credit:
47
  $ref: definitions/patron_account_credit.yaml
48
patron_balance:
49
  $ref: definitions/patron_balance.yaml
50
patron_extended_attribute:
51
  $ref: definitions/patron_extended_attribute.yaml
52
quote:
53
  $ref: definitions/quote.yaml
54
return_claim:
55
  $ref: definitions/return_claim.yaml
56
smtp_server:
57
  $ref: definitions/smtp_server.yaml
58
suggestion:
59
  $ref: definitions/suggestion.yaml
60
search_filter:
61
  $ref: definitions/search_filter.yaml
62
transfer_limit:
63
  $ref: definitions/transfer_limit.yaml
64
vendor:
65
  $ref: definitions/vendor.yaml
(-)a/api/v1/swagger/definitions/search_filter.yaml (+33 lines)
Line 0 Link Here
1
---
2
type: object
3
properties:
4
  search_filter_id:
5
    type: integer
6
    description: internally assigned search filter identifier
7
    readOnly: true
8
  name:
9
    description: filter name
10
    type: string
11
  filter_query:
12
    description: filter query part
13
    type:
14
    - string
15
    - 'null'
16
  filter_limits:
17
    description: filter limits part
18
    type:
19
    - string
20
    - 'null'
21
  opac:
22
    description: visible on opac
23
    type:
24
    - boolean
25
    - 'null'
26
  staff_client:
27
    description: visible in staff client
28
    type:
29
    - boolean
30
    - 'null'
31
additionalProperties: false
32
required:
33
- name
(-)a/api/v1/swagger/paths/search_filters.yaml (+226 lines)
Line 0 Link Here
1
---
2
"/search_filters":
3
  get:
4
    x-mojo-to: SearchFilter#list
5
    operationId: listFilters
6
    tags:
7
      - search_filters
8
    summary: List search filters
9
    produces:
10
      - application/json
11
    parameters:
12
      - name: name
13
        in: query
14
        description: Case insensitive search on filter name
15
        required: false
16
        type: string
17
      - name: filter_query
18
        in: query
19
        description: Search on filter query part
20
        required: false
21
        type: string
22
      - name: filter_limits
23
        in: query
24
        description: Search on filter limits
25
        required: false
26
        type: string
27
      - name: opac
28
        in: query
29
        description: Display in OPAC
30
        required: false
31
        type: boolean
32
      - name: staff_client
33
        in: query
34
        description: Display on staff client
35
        required: false
36
        type: boolean
37
      - $ref: "../swagger.yaml#/parameters/match"
38
      - $ref: "../swagger.yaml#/parameters/order_by"
39
      - $ref: "../swagger.yaml#/parameters/page"
40
      - $ref: "../swagger.yaml#/parameters/per_page"
41
      - $ref: "../swagger.yaml#/parameters/q_param"
42
      - $ref: "../swagger.yaml#/parameters/q_body"
43
      - $ref: "../swagger.yaml#/parameters/q_header"
44
      - $ref: "../swagger.yaml#/parameters/request_id_header"
45
    responses:
46
      '200':
47
        description: A list of search filters
48
        schema:
49
          type: array
50
          items:
51
            $ref: "../swagger.yaml#/definitions/search_filter"
52
      '403':
53
        description: Access forbidden
54
        schema:
55
          $ref: "../swagger.yaml#/definitions/error"
56
      '500':
57
        description: Internal error
58
        schema:
59
          $ref: "../swagger.yaml#/definitions/error"
60
      '503':
61
        description: Under maintenance
62
        schema:
63
          $ref: "../swagger.yaml#/definitions/error"
64
    x-koha-authorization:
65
      permissions:
66
        parameters: manage_search_filters
67
  post:
68
    x-mojo-to: SearchFilter#add
69
    operationId: addSearchFilter
70
    tags:
71
      - search_filters
72
    summary: Add search filter
73
    parameters:
74
      - name: body
75
        in: body
76
        description: A JSON object containing informations about the new search filter
77
        required: true
78
        schema:
79
          $ref: "../swagger.yaml#/definitions/search_filter"
80
    produces:
81
      - application/json
82
    responses:
83
      '201':
84
        description: Search filter added
85
        schema:
86
          $ref: "../swagger.yaml#/definitions/search_filter"
87
      '401':
88
        description: Authentication required
89
        schema:
90
          $ref: "../swagger.yaml#/definitions/error"
91
      '403':
92
        description: Access forbidden
93
        schema:
94
          $ref: "../swagger.yaml#/definitions/error"
95
      "409":
96
        description: Conflict in creating the resource
97
        schema:
98
          $ref: ../swagger.yaml#/definitions/error
99
      '500':
100
        description: Internal error
101
        schema:
102
          $ref: "../swagger.yaml#/definitions/error"
103
      '503':
104
        description: Under maintenance
105
        schema:
106
          $ref: "../swagger.yaml#/definitions/error"
107
    x-koha-authorization:
108
      permissions:
109
        parameters: manage_search_filters
110
"/search_filters/{search_filter_id}":
111
  get:
112
    x-mojo-to: SearchFilter#get
113
    operationId: getSearchFilter
114
    tags:
115
    - search_filters
116
    summary: Get search filter
117
    parameters:
118
    - $ref: "../swagger.yaml#/parameters/search_filter_id_pp"
119
    produces:
120
    - application/json
121
    responses:
122
      '200':
123
        description: A search filter
124
        schema:
125
          $ref: "../swagger.yaml#/definitions/search_filter"
126
      '403':
127
        description: Access forbidden
128
        schema:
129
          $ref: "../swagger.yaml#/definitions/error"
130
      '404':
131
        description: SearchFilter not found
132
        schema:
133
          $ref: "../swagger.yaml#/definitions/error"
134
      '500':
135
        description: Internal error
136
        schema:
137
          $ref: "../swagger.yaml#/definitions/error"
138
      '503':
139
        description: Under maintenance
140
        schema:
141
          $ref: "../swagger.yaml#/definitions/error"
142
    x-koha-authorization:
143
      permissions:
144
        parameters: manage_search_filters
145
  put:
146
    x-mojo-to: SearchFilter#update
147
    operationId: updateSearchFilter
148
    tags:
149
    - search_filters
150
    summary: Update search filter
151
    parameters:
152
    - $ref: "../swagger.yaml#/parameters/search_filter_id_pp"
153
    - name: body
154
      in: body
155
      description: A search filter object
156
      required: true
157
      schema:
158
        $ref: "../swagger.yaml#/definitions/search_filter"
159
    produces:
160
    - application/json
161
    responses:
162
      '200':
163
        description: An search_filter
164
        schema:
165
          $ref: "../swagger.yaml#/definitions/search_filter"
166
      '401':
167
        description: Authentication required
168
        schema:
169
          $ref: "../swagger.yaml#/definitions/error"
170
      '403':
171
        description: Access forbidden
172
        schema:
173
          $ref: "../swagger.yaml#/definitions/error"
174
      '404':
175
        description: Search filter not found
176
        schema:
177
          $ref: "../swagger.yaml#/definitions/error"
178
      '500':
179
        description: Internal error
180
        schema:
181
          $ref: "../swagger.yaml#/definitions/error"
182
      '503':
183
        description: Under maintenance
184
        schema:
185
          $ref: "../swagger.yaml#/definitions/error"
186
    x-koha-authorization:
187
      permissions:
188
        parameters: manage_search_filters
189
  delete:
190
    x-mojo-to: SearchFilter#delete
191
    operationId: deleteSearchFilter
192
    tags:
193
    - macros
194
    summary: Delete search filter
195
    parameters:
196
    - $ref: "../swagger.yaml#/parameters/search_filter_id_pp"
197
    produces:
198
    - application/json
199
    responses:
200
      '204':
201
        description: Searc filter deleted
202
        schema:
203
          type: string
204
      '401':
205
        description: Authentication required
206
        schema:
207
          $ref: "../swagger.yaml#/definitions/error"
208
      '403':
209
        description: Access forbidden
210
        schema:
211
          $ref: "../swagger.yaml#/definitions/error"
212
      '404':
213
        description: Search filter not found
214
        schema:
215
          $ref: "../swagger.yaml#/definitions/error"
216
      '500':
217
        description: Internal error
218
        schema:
219
          $ref: "../swagger.yaml#/definitions/error"
220
      '503':
221
        description: Under maintenance
222
        schema:
223
          $ref: "../swagger.yaml#/definitions/error"
224
    x-koha-authorization:
225
      permissions:
226
        parameters: manage_search_filters
(-)a/api/v1/swagger/swagger.yaml (+12 lines)
Lines 62-67 definitions: Link Here
62
    $ref: ./definitions/renewals.yaml
62
    $ref: ./definitions/renewals.yaml
63
  return_claim:
63
  return_claim:
64
    $ref: ./definitions/return_claim.yaml
64
    $ref: ./definitions/return_claim.yaml
65
  search_filter:
66
    $ref: ./definitions/search_filter.yaml
65
  smtp_server:
67
  smtp_server:
66
    $ref: ./definitions/smtp_server.yaml
68
    $ref: ./definitions/smtp_server.yaml
67
  suggestion:
69
  suggestion:
Lines 91-96 paths: Link Here
91
    $ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros
93
    $ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros
92
  /advanced_editor/macros/shared:
94
  /advanced_editor/macros/shared:
93
    $ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared
95
    $ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared
96
  /search_filters:
97
    $ref: ./paths/search_filters.yaml#/~1search_filters
98
  "/search_filters/{search_filter_id}":
99
    $ref: "./paths/search_filters.yaml#/~1search_filters~1{search_filter_id}"
94
  "/advanced_editor/macros/shared/{advancededitormacro_id}":
100
  "/advanced_editor/macros/shared/{advancededitormacro_id}":
95
    $ref: "./paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared~1{advancededitormacro_id}"
101
    $ref: "./paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared~1{advancededitormacro_id}"
96
  "/advanced_editor/macros/{advancededitormacro_id}":
102
  "/advanced_editor/macros/{advancededitormacro_id}":
Lines 395-400 parameters: Link Here
395
    name: x-koha-request-id
401
    name: x-koha-request-id
396
    required: false
402
    required: false
397
    type: integer
403
    type: integer
404
  search_filter_id_pp:
405
    name: search_filter_id
406
    in: path
407
    description: Search filter internal identifier
408
    required: true
409
    type: integer
398
  seen_pp:
410
  seen_pp:
399
    description: Item was seen flag
411
    description: Item was seen flag
400
    in: query
412
    in: query
(-)a/t/db_dependent/api/v1/search_filters.t (+353 lines)
Line 0 Link Here
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 under the
6
# terms of the GNU General Public License as published by the Free Software
7
# Foundation; either version 3 of the License, or (at your option) any later
8
# version.
9
#
10
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12
# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with Koha; if not, see <http://www.gnu.org/licenses>.
16
17
use Modern::Perl;
18
19
use Test::More tests => 5;
20
use Test::Mojo;
21
use Test::Warn;
22
23
use t::lib::TestBuilder;
24
use t::lib::Mocks;
25
26
use Koha::SearchFilters;
27
use Koha::Database;
28
29
my $schema  = Koha::Database->new->schema;
30
my $builder = t::lib::TestBuilder->new;
31
32
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
33
34
my $t = Test::Mojo->new('Koha::REST::V1');
35
36
$schema->storage->txn_begin;
37
38
subtest 'list() tests' => sub {
39
    plan tests => 10;
40
41
    Koha::SearchFilters->search()->delete();
42
43
    my $patron_1 = $builder->build_object({
44
        class => 'Koha::Patrons',
45
        value => { flags => 3 }
46
    });
47
    my $password = 'thePassword123';
48
    $patron_1->set_password({ password => $password, skip_validation => 1 });
49
    my $userid = $patron_1->userid;
50
51
    # Create test context
52
    my $search_filter_1 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
53
        {
54
            name => 'Test1',
55
            query => 'kw:this',
56
            limits => 'mc-itype,phr:BK',
57
            opac => 1,
58
            staff_client => 1
59
        }
60
    });
61
    my $search_filter_2 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
62
        {
63
            name => 'Test2',
64
            query => 'kw:that',
65
            limits => 'mc-itype,phr:BK',
66
            opac => 0,
67
            staff_client => 1
68
        }
69
    });
70
    my $search_filter_3 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
71
        {
72
            name => 'Test3',
73
            query => 'kw:any',
74
            limits => 'mc-itype,phr:CD',
75
            opac => 0,
76
            staff_client => 0
77
        }
78
    });
79
    my $search_filter_4 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
80
        {
81
            name => 'Test4',
82
            query => 'kw:some',
83
            limits => 'mc-itype,phr:CD',
84
            opac => 1,
85
            staff_client => 0
86
        }
87
    });
88
89
    # Make sure we are returned with the correct amount of macros
90
    $t->get_ok( "//$userid:$password@/api/v1/search_filters" )
91
      ->status_is( 200, 'SWAGGER3.2.2' )
92
      ->json_has('/0/search_filter_id')
93
      ->json_has('/1/search_filter_id')
94
      ->json_has('/2/search_filter_id')
95
      ->json_has('/3/search_filter_id');
96
97
    subtest 'query parameters' => sub {
98
99
        plan tests => 12;
100
        $t->get_ok("//$userid:$password@/api/v1/search_filters?name=" . $search_filter_2->name)
101
          ->status_is(200)
102
          ->json_is( [ $search_filter_2->to_api ] );
103
        $t->get_ok("//$userid:$password@/api/v1/search_filters?name=NotAName")
104
          ->status_is(200)
105
          ->json_is( [ ] );
106
        $t->get_ok("//$userid:$password@/api/v1/search_filters?filter_query=kw:any")
107
          ->status_is(200)
108
          ->json_is( [ $search_filter_3->to_api ] );
109
        $t->get_ok("//$userid:$password@/api/v1/search_filters?filter_limits=mc-itype,phr:BK")
110
          ->status_is(200)
111
          ->json_is( [ $search_filter_1->to_api, $search_filter_2->to_api ] );
112
    };
113
114
    # Warn on unsupported query parameter
115
    $t->get_ok( "//$userid:$password@/api/v1/search_filters?filter_blah=blah" )
116
      ->status_is(400)
117
      ->json_is( [{ path => '/query/filter_blah', message => 'Malformed query string'}] );
118
119
};
120
121
subtest 'get() tests' => sub {
122
123
    plan tests => 9;
124
125
    my $patron = $builder->build_object({
126
        class => 'Koha::Patrons',
127
        value => { flags => 3 }
128
    });
129
    my $password = 'thePassword123';
130
    $patron->set_password({ password => $password, skip_validation => 1 });
131
    my $userid = $patron->userid;
132
133
    my $search_filter_1 = $builder->build_object( { class => 'Koha::SearchFilters' } );
134
    my $search_filter_2 = $builder->build_object( { class => 'Koha::SearchFilters' } );
135
    my $search_filter_3 = $builder->build_object( { class => 'Koha::SearchFilters' } );
136
137
    $t->get_ok( "//$userid:$password@/api/v1/search_filters/" . $search_filter_1->id )
138
      ->status_is( 200, 'Filter retrieved correctly' )
139
      ->json_is( $search_filter_1->to_api );
140
141
    my $non_existent_code = $search_filter_1->id;
142
    $search_filter_1->delete;
143
144
    $t->get_ok( "//$userid:$password@/api/v1/search_filters/" . $non_existent_code )
145
      ->status_is(404)
146
      ->json_is( '/error' => 'Search filter not found' );
147
148
    $patron->flags(4)->store;
149
    $t->get_ok( "//$userid:$password/api/v1/search_filters/" . $search_filter_2->id )
150
      ->status_is( 401, 'Cannot search filters without permission' )
151
      ->json_is( '/error' => 'Authentication failure.' );
152
153
};
154
155
subtest 'add() tests' => sub {
156
157
    plan tests => 17;
158
159
    my $authorized_patron = $builder->build_object({
160
        class => 'Koha::Patrons',
161
        value => { flags => 0 }
162
    });
163
    $builder->build({
164
        source => 'UserPermission',
165
        value  => {
166
            borrowernumber => $authorized_patron->borrowernumber,
167
            module_bit     => 3,
168
            code           => 'manage_search_filters',
169
        },
170
    });
171
172
    my $password = 'thePassword123';
173
    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
174
    my $auth_userid = $authorized_patron->userid;
175
176
    my $unauthorized_patron = $builder->build_object({
177
        class => 'Koha::Patrons',
178
        value => { flags => 0 }
179
    });
180
    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
181
    my $unauth_userid = $unauthorized_patron->userid;
182
183
    my $search_filter = $builder->build_object({ class => 'Koha::SearchFilters' });
184
    my $search_filter_values = $search_filter->to_api;
185
    delete $search_filter_values->{search_filter_id};
186
    $search_filter->delete;
187
188
    # Unauthorized attempt to write
189
    $t->post_ok( "//$unauth_userid:$password@/api/v1/search_filters" => json => $search_filter_values )
190
      ->status_is(403);
191
192
    # Authorized attempt to write invalid data
193
    my $search_filter_with_invalid_field = { %$search_filter_values };
194
    $search_filter_with_invalid_field->{'coffee_filter'} = 'Chemex';
195
196
    $t->post_ok( "//$auth_userid:$password@/api/v1/search_filters" => json => $search_filter_with_invalid_field )
197
      ->status_is(400)
198
      ->json_is(
199
        "/errors" => [
200
            {
201
                message => "Properties not allowed: coffee_filter.",
202
                path    => "/body"
203
            }
204
        ]
205
    );
206
207
    # Authorized attempt to write
208
    $t->post_ok( "//$auth_userid:$password@/api/v1/search_filters" => json => $search_filter_values )
209
      ->status_is( 201, 'SWAGGER3.2.1' )
210
      ->json_has( '/search_filter_id', 'We generated a new id' )
211
      ->json_is( '/name' => $search_filter_values->{name}, 'The name matches what we supplied' )
212
      ->json_is( '/query' => $search_filter_values->{query}, 'The query matches what we supplied' )
213
      ->json_is( '/limits' => $search_filter_values->{limits}, 'The limits match what we supplied' )
214
      ->json_is( '/opac' => $search_filter_values->{opac}, 'The limits match what we supplied' )
215
      ->json_is( '/staff_client' => $search_filter_values->{staff_client}, 'The limits match what we supplied' )
216
      ->header_like( Location => qr|^\/api\/v1\/search_filters\/d*|, 'Correct location' );
217
218
    # save the library_id
219
    my $search_filter_id = 999;
220
221
    # Authorized attempt to create with existing id
222
    $search_filter_values->{search_filter_id} = $search_filter_id;
223
224
    $t->post_ok( "//$auth_userid:$password@/api/v1/search_filters" => json => $search_filter_values )
225
      ->status_is(400)
226
      ->json_is( '/errors' => [
227
            {
228
                message => "Read-only.",
229
                path   => "/body/search_filter_id"
230
            }
231
        ]
232
    );
233
234
};
235
236
subtest 'update() tests' => sub {
237
    plan tests => 15;
238
239
    my $authorized_patron = $builder->build_object({
240
        class => 'Koha::Patrons',
241
        value => { flags => 0 }
242
    });
243
    $builder->build({
244
        source => 'UserPermission',
245
        value  => {
246
            borrowernumber => $authorized_patron->borrowernumber,
247
            module_bit     => 3,
248
            code           => 'manage_search_filters',
249
        },
250
    });
251
252
    my $password = 'thePassword123';
253
    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
254
    my $auth_userid = $authorized_patron->userid;
255
256
    my $unauthorized_patron = $builder->build_object({
257
        class => 'Koha::Patrons',
258
        value => { flags => 0 }
259
    });
260
    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
261
    my $unauth_userid = $unauthorized_patron->userid;
262
263
    my $search_filter = $builder->build_object({ class => 'Koha::SearchFilters' });
264
    my $search_filter_id = $search_filter->id;
265
    my $search_filter_values = $search_filter->to_api;
266
    delete $search_filter_values->{search_filter_id};
267
268
    # Unauthorized attempt to update
269
    $t->put_ok( "//$unauth_userid:$password@/api/v1/search_filters/$search_filter_id"
270
                    => json => { name => 'New unauthorized name change' } )
271
      ->status_is(403);
272
273
    my $search_filter_update = {
274
        name => "Filter update",
275
        filter_query => "ti:The hobbit",
276
        filter_limits => "mc-ccode:fantasy",
277
    };
278
279
    my $test = $t->put_ok( "//$auth_userid:$password@/api/v1/search_filters/$search_filter_id" => json => $search_filter_update )
280
      ->status_is(200, 'Authorized user can update a macro')
281
      ->json_is( '/search_filter_id' => $search_filter_id, 'We get back the id' )
282
      ->json_is( '/name' => $search_filter_update->{name}, 'We get back the name' )
283
      ->json_is( '/filter_query' => $search_filter_update->{filter_query}, 'We get back our query' )
284
      ->json_is( '/filter_limits' => $search_filter_update->{filter_limits}, 'We get back our limits' )
285
      ->json_is( '/opac' => 1, 'We get back our opac visibility unchanged' )
286
      ->json_is( '/staff_client' => 1, 'We get back our staff client visibility unchanged' );
287
288
    # Authorized attempt to write invalid data
289
    my $search_filter_with_invalid_field = { %$search_filter_update };
290
    $search_filter_with_invalid_field->{'coffee_filter'} = 'Chemex';
291
292
    $t->put_ok( "//$auth_userid:$password@/api/v1/search_filters/$search_filter_id" => json => $search_filter_with_invalid_field )
293
      ->status_is(400)
294
      ->json_is(
295
        "/errors" => [
296
            {
297
                message => "Properties not allowed: coffee_filter.",
298
                path    => "/body"
299
            }
300
        ]
301
    );
302
303
    my $non_existent_macro = $builder->build_object({class => 'Koha::SearchFilters'});
304
    my $non_existent_code = $non_existent_macro->id;
305
    $non_existent_macro->delete;
306
307
    $t->put_ok("//$auth_userid:$password@/api/v1/search_filters/$non_existent_code" => json => $search_filter_update)
308
      ->status_is(404);
309
310
};
311
312
subtest 'delete() tests' => sub {
313
    plan tests => 4;
314
315
    my $authorized_patron = $builder->build_object({
316
        class => 'Koha::Patrons',
317
        value => { flags => 0 }
318
    });
319
    $builder->build({
320
        source => 'UserPermission',
321
        value  => {
322
            borrowernumber => $authorized_patron->borrowernumber,
323
            module_bit     => 3,
324
            code           => 'manage_search_filters',
325
        },
326
    });
327
328
    my $password = 'thePassword123';
329
    $authorized_patron->set_password({ password => $password, skip_validation => 1 });
330
    my $auth_userid = $authorized_patron->userid;
331
332
    my $unauthorized_patron = $builder->build_object({
333
        class => 'Koha::Patrons',
334
        value => { flags => 0 }
335
    });
336
    $unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
337
    my $unauth_userid = $unauthorized_patron->userid;
338
339
    my $search_filter = $builder->build_object({ class => 'Koha::SearchFilters' });
340
    my $search_filter_2 = $builder->build_object({ class => 'Koha::SearchFilters' });
341
    my $search_filter_id = $search_filter->id;
342
    my $search_filter_2_id = $search_filter_2->id;
343
344
    # Unauthorized attempt to delete
345
    $t->delete_ok( "//$unauth_userid:$password@/api/v1/search_filters/$search_filter_2_id")
346
      ->status_is(403, "Cannot delete search filter without permission");
347
348
    $t->delete_ok( "//$auth_userid:$password@/api/v1/search_filters/$search_filter_id")
349
      ->status_is( 204, 'Can delete search filter with permission');
350
351
};
352
353
$schema->storage->txn_rollback;
(-)a/t/lib/TestBuilder.pm (-1 / +4 lines)
Lines 609-614 sub _gen_default_values { Link Here
609
            status => 'staged',
609
            status => 'staged',
610
            import_error => undef
610
            import_error => undef
611
        },
611
        },
612
        SearchFilter => {
613
            opac => 1,
614
            staff_client => 1
615
        },
612
    };
616
    };
613
}
617
}
614
618
615
- 

Return to bug 17170