Bug 17170: Add API route for SearchFilters
This adds the API routes and tests Sponsored-by: Sponsored by: Round Rock Public Library [https://www.roundrocktexas.gov/departments/library/] Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
b306b1d4ca
commit
adf252d96c
7 changed files with 846 additions and 0 deletions
153
Koha/REST/V1/SearchFilter.pm
Normal file
153
Koha/REST/V1/SearchFilter.pm
Normal file
|
@ -0,0 +1,153 @@
|
|||
package Koha::REST::V1::SearchFilter;
|
||||
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Mojo::Base 'Mojolicious::Controller';
|
||||
use Koha::SearchFilters;
|
||||
|
||||
use Try::Tiny qw( catch try );
|
||||
|
||||
=head1 Name
|
||||
|
||||
Koha::REST::V1::SearchFilters
|
||||
|
||||
=head1 API
|
||||
|
||||
=head2 Methods
|
||||
|
||||
=head3 list
|
||||
|
||||
Controller function that handles listing Koha::SearchFilter objects
|
||||
|
||||
=cut
|
||||
|
||||
sub list {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
return try {
|
||||
my $filters_set = Koha::SearchFilters->search({});
|
||||
my $filters = $c->objects->search( $filters_set );
|
||||
return $c->render(
|
||||
status => 200,
|
||||
openapi => $filters
|
||||
);
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
=head3 get
|
||||
|
||||
Controller function that handles retrieving a single Koha::AdvancedEditorMacro
|
||||
|
||||
=cut
|
||||
|
||||
sub get {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
my $filter = Koha::SearchFilters->find({
|
||||
id => $c->validation->param('search_filter_id'),
|
||||
});
|
||||
unless ($filter) {
|
||||
return $c->render( status => 404,
|
||||
openapi => { error => "Search filter not found" } );
|
||||
}
|
||||
|
||||
return $c->render( status => 200, openapi => $filter->to_api );
|
||||
}
|
||||
|
||||
=head3 add
|
||||
|
||||
Controller function that handles adding a new Koha::SearchFilter object
|
||||
|
||||
=cut
|
||||
|
||||
sub add {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
return try {
|
||||
my $filter = Koha::SearchFilter->new_from_api( $c->validation->param('body') );
|
||||
$filter->store->discard_changes;
|
||||
$c->res->headers->location( $c->req->url->to_string . '/' . $filter->id );
|
||||
return $c->render(
|
||||
status => 201,
|
||||
openapi => $filter->to_api
|
||||
);
|
||||
}
|
||||
catch {
|
||||
if ( blessed $_ and $_->isa('Koha::Exceptions::Object::DuplicateID') ) {
|
||||
return $c->render(
|
||||
status => 409,
|
||||
openapi => { error => $_->error, conflict => $_->duplicate_id }
|
||||
);
|
||||
}
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 update
|
||||
|
||||
Controller function that handles updating a Koha::SearchFilter object
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $filter = Koha::SearchFilters->find( $c->validation->param('search_filter_id') );
|
||||
|
||||
if ( not defined $filter ) {
|
||||
return $c->render( status => 404,
|
||||
openapi => { error => "Object not found" } );
|
||||
}
|
||||
|
||||
return try {
|
||||
my $params = $c->req->json;
|
||||
$filter->set_from_api( $params );
|
||||
$filter->store->discard_changes;
|
||||
return $c->render( status => 200, openapi => $filter->to_api );
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
=head3 delete
|
||||
|
||||
Controller function that handles deleting a Koha::SearchFilter object
|
||||
|
||||
=cut
|
||||
|
||||
sub delete {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $filter = Koha::SearchFilters->find( $c->validation->param('search_filter_id') );
|
||||
if ( not defined $filter ) {
|
||||
return $c->render( status => 404,
|
||||
openapi => { error => "Object not found" } );
|
||||
}
|
||||
|
||||
return try {
|
||||
$filter->delete;
|
||||
return $c->render( status => 204, openapi => q{} );
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
|
||||
1;
|
65
api/v1/swagger/definitions.yaml
Normal file
65
api/v1/swagger/definitions.yaml
Normal file
|
@ -0,0 +1,65 @@
|
|||
---
|
||||
account_line:
|
||||
$ref: definitions/account_line.yaml
|
||||
advancededitormacro:
|
||||
$ref: definitions/advancededitormacro.yaml
|
||||
allows_renewal:
|
||||
$ref: definitions/allows_renewal.yaml
|
||||
basket:
|
||||
$ref: definitions/basket.yaml
|
||||
cashup:
|
||||
$ref: definitions/cashup.yaml
|
||||
checkout:
|
||||
$ref: definitions/checkout.yaml
|
||||
checkouts:
|
||||
$ref: definitions/checkouts.yaml
|
||||
circ-rule-kind:
|
||||
$ref: definitions/circ-rule-kind.yaml
|
||||
city:
|
||||
$ref: definitions/city.yaml
|
||||
error:
|
||||
$ref: definitions/error.yaml
|
||||
fund:
|
||||
$ref: definitions/fund.yaml
|
||||
hold:
|
||||
$ref: definitions/hold.yaml
|
||||
holds:
|
||||
$ref: definitions/holds.yaml
|
||||
ill_backend:
|
||||
$ref: definitions/ill_backend.yaml
|
||||
ill_backends:
|
||||
$ref: definitions/ill_backends.yaml
|
||||
import_batch_profile:
|
||||
$ref: definitions/import_batch_profile.yaml
|
||||
import_batch_profiles:
|
||||
$ref: definitions/import_batch_profiles.yaml
|
||||
invoice:
|
||||
$ref: definitions/invoice.yaml
|
||||
item:
|
||||
$ref: definitions/item.yaml
|
||||
library:
|
||||
$ref: definitions/library.yaml
|
||||
order:
|
||||
$ref: definitions/order.yaml
|
||||
patron:
|
||||
$ref: definitions/patron.yaml
|
||||
patron_account_credit:
|
||||
$ref: definitions/patron_account_credit.yaml
|
||||
patron_balance:
|
||||
$ref: definitions/patron_balance.yaml
|
||||
patron_extended_attribute:
|
||||
$ref: definitions/patron_extended_attribute.yaml
|
||||
quote:
|
||||
$ref: definitions/quote.yaml
|
||||
return_claim:
|
||||
$ref: definitions/return_claim.yaml
|
||||
smtp_server:
|
||||
$ref: definitions/smtp_server.yaml
|
||||
suggestion:
|
||||
$ref: definitions/suggestion.yaml
|
||||
search_filter:
|
||||
$ref: definitions/search_filter.yaml
|
||||
transfer_limit:
|
||||
$ref: definitions/transfer_limit.yaml
|
||||
vendor:
|
||||
$ref: definitions/vendor.yaml
|
33
api/v1/swagger/definitions/search_filter.yaml
Normal file
33
api/v1/swagger/definitions/search_filter.yaml
Normal file
|
@ -0,0 +1,33 @@
|
|||
---
|
||||
type: object
|
||||
properties:
|
||||
search_filter_id:
|
||||
type: integer
|
||||
description: internally assigned search filter identifier
|
||||
readOnly: true
|
||||
name:
|
||||
description: filter name
|
||||
type: string
|
||||
filter_query:
|
||||
description: filter query part
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
filter_limits:
|
||||
description: filter limits part
|
||||
type:
|
||||
- string
|
||||
- 'null'
|
||||
opac:
|
||||
description: visible on opac
|
||||
type:
|
||||
- boolean
|
||||
- 'null'
|
||||
staff_client:
|
||||
description: visible in staff client
|
||||
type:
|
||||
- boolean
|
||||
- 'null'
|
||||
additionalProperties: false
|
||||
required:
|
||||
- name
|
226
api/v1/swagger/paths/search_filters.yaml
Normal file
226
api/v1/swagger/paths/search_filters.yaml
Normal file
|
@ -0,0 +1,226 @@
|
|||
---
|
||||
"/search_filters":
|
||||
get:
|
||||
x-mojo-to: SearchFilter#list
|
||||
operationId: listFilters
|
||||
tags:
|
||||
- search_filters
|
||||
summary: List search filters
|
||||
produces:
|
||||
- application/json
|
||||
parameters:
|
||||
- name: name
|
||||
in: query
|
||||
description: Case insensitive search on filter name
|
||||
required: false
|
||||
type: string
|
||||
- name: filter_query
|
||||
in: query
|
||||
description: Search on filter query part
|
||||
required: false
|
||||
type: string
|
||||
- name: filter_limits
|
||||
in: query
|
||||
description: Search on filter limits
|
||||
required: false
|
||||
type: string
|
||||
- name: opac
|
||||
in: query
|
||||
description: Display in OPAC
|
||||
required: false
|
||||
type: boolean
|
||||
- name: staff_client
|
||||
in: query
|
||||
description: Display on staff client
|
||||
required: false
|
||||
type: boolean
|
||||
- $ref: "../swagger.yaml#/parameters/match"
|
||||
- $ref: "../swagger.yaml#/parameters/order_by"
|
||||
- $ref: "../swagger.yaml#/parameters/page"
|
||||
- $ref: "../swagger.yaml#/parameters/per_page"
|
||||
- $ref: "../swagger.yaml#/parameters/q_param"
|
||||
- $ref: "../swagger.yaml#/parameters/q_body"
|
||||
- $ref: "../swagger.yaml#/parameters/q_header"
|
||||
- $ref: "../swagger.yaml#/parameters/request_id_header"
|
||||
responses:
|
||||
'200':
|
||||
description: A list of search filters
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: "../swagger.yaml#/definitions/search_filter"
|
||||
'403':
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'500':
|
||||
description: Internal error
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'503':
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
parameters: manage_search_filters
|
||||
post:
|
||||
x-mojo-to: SearchFilter#add
|
||||
operationId: addSearchFilter
|
||||
tags:
|
||||
- search_filters
|
||||
summary: Add search filter
|
||||
parameters:
|
||||
- name: body
|
||||
in: body
|
||||
description: A JSON object containing informations about the new search filter
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/search_filter"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
'201':
|
||||
description: Search filter added
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/search_filter"
|
||||
'401':
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'403':
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"409":
|
||||
description: Conflict in creating the resource
|
||||
schema:
|
||||
$ref: ../swagger.yaml#/definitions/error
|
||||
'500':
|
||||
description: Internal error
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'503':
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
parameters: manage_search_filters
|
||||
"/search_filters/{search_filter_id}":
|
||||
get:
|
||||
x-mojo-to: SearchFilter#get
|
||||
operationId: getSearchFilter
|
||||
tags:
|
||||
- search_filters
|
||||
summary: Get search filter
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/search_filter_id_pp"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
'200':
|
||||
description: A search filter
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/search_filter"
|
||||
'403':
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'404':
|
||||
description: SearchFilter not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'500':
|
||||
description: Internal error
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'503':
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
parameters: manage_search_filters
|
||||
put:
|
||||
x-mojo-to: SearchFilter#update
|
||||
operationId: updateSearchFilter
|
||||
tags:
|
||||
- search_filters
|
||||
summary: Update search filter
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/search_filter_id_pp"
|
||||
- name: body
|
||||
in: body
|
||||
description: A search filter object
|
||||
required: true
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/search_filter"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
'200':
|
||||
description: An search_filter
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/search_filter"
|
||||
'401':
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'403':
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'404':
|
||||
description: Search filter not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'500':
|
||||
description: Internal error
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'503':
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
parameters: manage_search_filters
|
||||
delete:
|
||||
x-mojo-to: SearchFilter#delete
|
||||
operationId: deleteSearchFilter
|
||||
tags:
|
||||
- macros
|
||||
summary: Delete search filter
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/search_filter_id_pp"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
'204':
|
||||
description: Searc filter deleted
|
||||
schema:
|
||||
type: string
|
||||
'401':
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'403':
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'404':
|
||||
description: Search filter not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'500':
|
||||
description: Internal error
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
'503':
|
||||
description: Under maintenance
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
x-koha-authorization:
|
||||
permissions:
|
||||
parameters: manage_search_filters
|
|
@ -68,6 +68,8 @@ definitions:
|
|||
$ref: ./definitions/renewals.yaml
|
||||
return_claim:
|
||||
$ref: ./definitions/return_claim.yaml
|
||||
search_filter:
|
||||
$ref: ./definitions/search_filter.yaml
|
||||
smtp_server:
|
||||
$ref: ./definitions/smtp_server.yaml
|
||||
suggestion:
|
||||
|
@ -97,6 +99,10 @@ paths:
|
|||
$ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros
|
||||
/advanced_editor/macros/shared:
|
||||
$ref: ./paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared
|
||||
/search_filters:
|
||||
$ref: ./paths/search_filters.yaml#/~1search_filters
|
||||
"/search_filters/{search_filter_id}":
|
||||
$ref: "./paths/search_filters.yaml#/~1search_filters~1{search_filter_id}"
|
||||
"/advanced_editor/macros/shared/{advancededitormacro_id}":
|
||||
$ref: "./paths/advancededitormacros.yaml#/~1advanced_editor~1macros~1shared~1{advancededitormacro_id}"
|
||||
"/advanced_editor/macros/{advancededitormacro_id}":
|
||||
|
@ -427,6 +433,12 @@ parameters:
|
|||
name: x-koha-request-id
|
||||
required: false
|
||||
type: integer
|
||||
search_filter_id_pp:
|
||||
name: search_filter_id
|
||||
in: path
|
||||
description: Search filter internal identifier
|
||||
required: true
|
||||
type: integer
|
||||
seen_pp:
|
||||
description: Item was seen flag
|
||||
in: query
|
||||
|
|
353
t/db_dependent/api/v1/search_filters.t
Executable file
353
t/db_dependent/api/v1/search_filters.t
Executable file
|
@ -0,0 +1,353 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
# This file is part of Koha.
|
||||
#
|
||||
# Koha is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Koha; if not, see <http://www.gnu.org/licenses>.
|
||||
|
||||
use Modern::Perl;
|
||||
|
||||
use Test::More tests => 5;
|
||||
use Test::Mojo;
|
||||
use Test::Warn;
|
||||
|
||||
use t::lib::TestBuilder;
|
||||
use t::lib::Mocks;
|
||||
|
||||
use Koha::SearchFilters;
|
||||
use Koha::Database;
|
||||
|
||||
my $schema = Koha::Database->new->schema;
|
||||
my $builder = t::lib::TestBuilder->new;
|
||||
|
||||
t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 );
|
||||
|
||||
my $t = Test::Mojo->new('Koha::REST::V1');
|
||||
|
||||
$schema->storage->txn_begin;
|
||||
|
||||
subtest 'list() tests' => sub {
|
||||
plan tests => 10;
|
||||
|
||||
Koha::SearchFilters->search()->delete();
|
||||
|
||||
my $patron_1 = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 3 }
|
||||
});
|
||||
my $password = 'thePassword123';
|
||||
$patron_1->set_password({ password => $password, skip_validation => 1 });
|
||||
my $userid = $patron_1->userid;
|
||||
|
||||
# Create test context
|
||||
my $search_filter_1 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
|
||||
{
|
||||
name => 'Test1',
|
||||
query => 'kw:this',
|
||||
limits => 'mc-itype,phr:BK',
|
||||
opac => 1,
|
||||
staff_client => 1
|
||||
}
|
||||
});
|
||||
my $search_filter_2 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
|
||||
{
|
||||
name => 'Test2',
|
||||
query => 'kw:that',
|
||||
limits => 'mc-itype,phr:BK',
|
||||
opac => 0,
|
||||
staff_client => 1
|
||||
}
|
||||
});
|
||||
my $search_filter_3 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
|
||||
{
|
||||
name => 'Test3',
|
||||
query => 'kw:any',
|
||||
limits => 'mc-itype,phr:CD',
|
||||
opac => 0,
|
||||
staff_client => 0
|
||||
}
|
||||
});
|
||||
my $search_filter_4 = $builder->build_object({ class => 'Koha::SearchFilters', value =>
|
||||
{
|
||||
name => 'Test4',
|
||||
query => 'kw:some',
|
||||
limits => 'mc-itype,phr:CD',
|
||||
opac => 1,
|
||||
staff_client => 0
|
||||
}
|
||||
});
|
||||
|
||||
# Make sure we are returned with the correct amount of macros
|
||||
$t->get_ok( "//$userid:$password@/api/v1/search_filters" )
|
||||
->status_is( 200, 'SWAGGER3.2.2' )
|
||||
->json_has('/0/search_filter_id')
|
||||
->json_has('/1/search_filter_id')
|
||||
->json_has('/2/search_filter_id')
|
||||
->json_has('/3/search_filter_id');
|
||||
|
||||
subtest 'query parameters' => sub {
|
||||
|
||||
plan tests => 12;
|
||||
$t->get_ok("//$userid:$password@/api/v1/search_filters?name=" . $search_filter_2->name)
|
||||
->status_is(200)
|
||||
->json_is( [ $search_filter_2->to_api ] );
|
||||
$t->get_ok("//$userid:$password@/api/v1/search_filters?name=NotAName")
|
||||
->status_is(200)
|
||||
->json_is( [ ] );
|
||||
$t->get_ok("//$userid:$password@/api/v1/search_filters?filter_query=kw:any")
|
||||
->status_is(200)
|
||||
->json_is( [ $search_filter_3->to_api ] );
|
||||
$t->get_ok("//$userid:$password@/api/v1/search_filters?filter_limits=mc-itype,phr:BK")
|
||||
->status_is(200)
|
||||
->json_is( [ $search_filter_1->to_api, $search_filter_2->to_api ] );
|
||||
};
|
||||
|
||||
# Warn on unsupported query parameter
|
||||
$t->get_ok( "//$userid:$password@/api/v1/search_filters?filter_blah=blah" )
|
||||
->status_is(400)
|
||||
->json_is( [{ path => '/query/filter_blah', message => 'Malformed query string'}] );
|
||||
|
||||
};
|
||||
|
||||
subtest 'get() tests' => sub {
|
||||
|
||||
plan tests => 9;
|
||||
|
||||
my $patron = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 3 }
|
||||
});
|
||||
my $password = 'thePassword123';
|
||||
$patron->set_password({ password => $password, skip_validation => 1 });
|
||||
my $userid = $patron->userid;
|
||||
|
||||
my $search_filter_1 = $builder->build_object( { class => 'Koha::SearchFilters' } );
|
||||
my $search_filter_2 = $builder->build_object( { class => 'Koha::SearchFilters' } );
|
||||
my $search_filter_3 = $builder->build_object( { class => 'Koha::SearchFilters' } );
|
||||
|
||||
$t->get_ok( "//$userid:$password@/api/v1/search_filters/" . $search_filter_1->id )
|
||||
->status_is( 200, 'Filter retrieved correctly' )
|
||||
->json_is( $search_filter_1->to_api );
|
||||
|
||||
my $non_existent_code = $search_filter_1->id;
|
||||
$search_filter_1->delete;
|
||||
|
||||
$t->get_ok( "//$userid:$password@/api/v1/search_filters/" . $non_existent_code )
|
||||
->status_is(404)
|
||||
->json_is( '/error' => 'Search filter not found' );
|
||||
|
||||
$patron->flags(4)->store;
|
||||
$t->get_ok( "//$userid:$password/api/v1/search_filters/" . $search_filter_2->id )
|
||||
->status_is( 401, 'Cannot search filters without permission' )
|
||||
->json_is( '/error' => 'Authentication failure.' );
|
||||
|
||||
};
|
||||
|
||||
subtest 'add() tests' => sub {
|
||||
|
||||
plan tests => 17;
|
||||
|
||||
my $authorized_patron = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 }
|
||||
});
|
||||
$builder->build({
|
||||
source => 'UserPermission',
|
||||
value => {
|
||||
borrowernumber => $authorized_patron->borrowernumber,
|
||||
module_bit => 3,
|
||||
code => 'manage_search_filters',
|
||||
},
|
||||
});
|
||||
|
||||
my $password = 'thePassword123';
|
||||
$authorized_patron->set_password({ password => $password, skip_validation => 1 });
|
||||
my $auth_userid = $authorized_patron->userid;
|
||||
|
||||
my $unauthorized_patron = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 }
|
||||
});
|
||||
$unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
|
||||
my $unauth_userid = $unauthorized_patron->userid;
|
||||
|
||||
my $search_filter = $builder->build_object({ class => 'Koha::SearchFilters' });
|
||||
my $search_filter_values = $search_filter->to_api;
|
||||
delete $search_filter_values->{search_filter_id};
|
||||
$search_filter->delete;
|
||||
|
||||
# Unauthorized attempt to write
|
||||
$t->post_ok( "//$unauth_userid:$password@/api/v1/search_filters" => json => $search_filter_values )
|
||||
->status_is(403);
|
||||
|
||||
# Authorized attempt to write invalid data
|
||||
my $search_filter_with_invalid_field = { %$search_filter_values };
|
||||
$search_filter_with_invalid_field->{'coffee_filter'} = 'Chemex';
|
||||
|
||||
$t->post_ok( "//$auth_userid:$password@/api/v1/search_filters" => json => $search_filter_with_invalid_field )
|
||||
->status_is(400)
|
||||
->json_is(
|
||||
"/errors" => [
|
||||
{
|
||||
message => "Properties not allowed: coffee_filter.",
|
||||
path => "/body"
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
# Authorized attempt to write
|
||||
$t->post_ok( "//$auth_userid:$password@/api/v1/search_filters" => json => $search_filter_values )
|
||||
->status_is( 201, 'SWAGGER3.2.1' )
|
||||
->json_has( '/search_filter_id', 'We generated a new id' )
|
||||
->json_is( '/name' => $search_filter_values->{name}, 'The name matches what we supplied' )
|
||||
->json_is( '/query' => $search_filter_values->{query}, 'The query matches what we supplied' )
|
||||
->json_is( '/limits' => $search_filter_values->{limits}, 'The limits match what we supplied' )
|
||||
->json_is( '/opac' => $search_filter_values->{opac}, 'The limits match what we supplied' )
|
||||
->json_is( '/staff_client' => $search_filter_values->{staff_client}, 'The limits match what we supplied' )
|
||||
->header_like( Location => qr|^\/api\/v1\/search_filters\/d*|, 'Correct location' );
|
||||
|
||||
# save the library_id
|
||||
my $search_filter_id = 999;
|
||||
|
||||
# Authorized attempt to create with existing id
|
||||
$search_filter_values->{search_filter_id} = $search_filter_id;
|
||||
|
||||
$t->post_ok( "//$auth_userid:$password@/api/v1/search_filters" => json => $search_filter_values )
|
||||
->status_is(400)
|
||||
->json_is( '/errors' => [
|
||||
{
|
||||
message => "Read-only.",
|
||||
path => "/body/search_filter_id"
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
subtest 'update() tests' => sub {
|
||||
plan tests => 15;
|
||||
|
||||
my $authorized_patron = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 }
|
||||
});
|
||||
$builder->build({
|
||||
source => 'UserPermission',
|
||||
value => {
|
||||
borrowernumber => $authorized_patron->borrowernumber,
|
||||
module_bit => 3,
|
||||
code => 'manage_search_filters',
|
||||
},
|
||||
});
|
||||
|
||||
my $password = 'thePassword123';
|
||||
$authorized_patron->set_password({ password => $password, skip_validation => 1 });
|
||||
my $auth_userid = $authorized_patron->userid;
|
||||
|
||||
my $unauthorized_patron = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 }
|
||||
});
|
||||
$unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
|
||||
my $unauth_userid = $unauthorized_patron->userid;
|
||||
|
||||
my $search_filter = $builder->build_object({ class => 'Koha::SearchFilters' });
|
||||
my $search_filter_id = $search_filter->id;
|
||||
my $search_filter_values = $search_filter->to_api;
|
||||
delete $search_filter_values->{search_filter_id};
|
||||
|
||||
# Unauthorized attempt to update
|
||||
$t->put_ok( "//$unauth_userid:$password@/api/v1/search_filters/$search_filter_id"
|
||||
=> json => { name => 'New unauthorized name change' } )
|
||||
->status_is(403);
|
||||
|
||||
my $search_filter_update = {
|
||||
name => "Filter update",
|
||||
filter_query => "ti:The hobbit",
|
||||
filter_limits => "mc-ccode:fantasy",
|
||||
};
|
||||
|
||||
my $test = $t->put_ok( "//$auth_userid:$password@/api/v1/search_filters/$search_filter_id" => json => $search_filter_update )
|
||||
->status_is(200, 'Authorized user can update a macro')
|
||||
->json_is( '/search_filter_id' => $search_filter_id, 'We get back the id' )
|
||||
->json_is( '/name' => $search_filter_update->{name}, 'We get back the name' )
|
||||
->json_is( '/filter_query' => $search_filter_update->{filter_query}, 'We get back our query' )
|
||||
->json_is( '/filter_limits' => $search_filter_update->{filter_limits}, 'We get back our limits' )
|
||||
->json_is( '/opac' => 1, 'We get back our opac visibility unchanged' )
|
||||
->json_is( '/staff_client' => 1, 'We get back our staff client visibility unchanged' );
|
||||
|
||||
# Authorized attempt to write invalid data
|
||||
my $search_filter_with_invalid_field = { %$search_filter_update };
|
||||
$search_filter_with_invalid_field->{'coffee_filter'} = 'Chemex';
|
||||
|
||||
$t->put_ok( "//$auth_userid:$password@/api/v1/search_filters/$search_filter_id" => json => $search_filter_with_invalid_field )
|
||||
->status_is(400)
|
||||
->json_is(
|
||||
"/errors" => [
|
||||
{
|
||||
message => "Properties not allowed: coffee_filter.",
|
||||
path => "/body"
|
||||
}
|
||||
]
|
||||
);
|
||||
|
||||
my $non_existent_macro = $builder->build_object({class => 'Koha::SearchFilters'});
|
||||
my $non_existent_code = $non_existent_macro->id;
|
||||
$non_existent_macro->delete;
|
||||
|
||||
$t->put_ok("//$auth_userid:$password@/api/v1/search_filters/$non_existent_code" => json => $search_filter_update)
|
||||
->status_is(404);
|
||||
|
||||
};
|
||||
|
||||
subtest 'delete() tests' => sub {
|
||||
plan tests => 4;
|
||||
|
||||
my $authorized_patron = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 }
|
||||
});
|
||||
$builder->build({
|
||||
source => 'UserPermission',
|
||||
value => {
|
||||
borrowernumber => $authorized_patron->borrowernumber,
|
||||
module_bit => 3,
|
||||
code => 'manage_search_filters',
|
||||
},
|
||||
});
|
||||
|
||||
my $password = 'thePassword123';
|
||||
$authorized_patron->set_password({ password => $password, skip_validation => 1 });
|
||||
my $auth_userid = $authorized_patron->userid;
|
||||
|
||||
my $unauthorized_patron = $builder->build_object({
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 }
|
||||
});
|
||||
$unauthorized_patron->set_password({ password => $password, skip_validation => 1 });
|
||||
my $unauth_userid = $unauthorized_patron->userid;
|
||||
|
||||
my $search_filter = $builder->build_object({ class => 'Koha::SearchFilters' });
|
||||
my $search_filter_2 = $builder->build_object({ class => 'Koha::SearchFilters' });
|
||||
my $search_filter_id = $search_filter->id;
|
||||
my $search_filter_2_id = $search_filter_2->id;
|
||||
|
||||
# Unauthorized attempt to delete
|
||||
$t->delete_ok( "//$unauth_userid:$password@/api/v1/search_filters/$search_filter_2_id")
|
||||
->status_is(403, "Cannot delete search filter without permission");
|
||||
|
||||
$t->delete_ok( "//$auth_userid:$password@/api/v1/search_filters/$search_filter_id")
|
||||
->status_is( 204, 'Can delete search filter with permission');
|
||||
|
||||
};
|
||||
|
||||
$schema->storage->txn_rollback;
|
|
@ -628,6 +628,10 @@ sub _gen_default_values {
|
|||
status => 'staged',
|
||||
import_error => undef
|
||||
},
|
||||
SearchFilter => {
|
||||
opac => 1,
|
||||
staff_client => 1
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue