From 8aec8a80216c81c523596d334d58db94b1051fdb Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Thu, 8 Oct 2020 11:14:26 -0400 Subject: [PATCH] Bug 26633: Add REST API for managing transfer limits Test Plan: 1) prove t/db_dependent/api/v1/transfer_limits.t Signed-off-by: Lisette Scheer Signed-off-by: Lisette Scheer Signed-off-by: Lisette Scheer Signed-off-by: Lisette Scheer Signed-off-by: Katrin Fischer Signed-off-by: Tomas Cohen Arazi Signed-off-by: Katrin Fischer Bug 26633: Convert transfer_limit.json to YAML Signed-off-by: Katrin Fischer Signed-off-by: Jonathan Druart --- Koha/Exceptions/TransferLimit.pm | 17 ++ Koha/Item/Transfer/Limit.pm | 17 ++ Koha/REST/V1/TransferLimits.pm | 191 +++++++++++++ api/v1/swagger/definitions.json | 3 + .../swagger/definitions/transfer_limit.json | 27 ++ api/v1/swagger/parameters.json | 3 + api/v1/swagger/parameters/transfer_limit.json | 9 + api/v1/swagger/paths.json | 9 + api/v1/swagger/paths/transfer_limits.yaml | 254 +++++++++++++++++ api/v1/swagger/x-primitives.json | 4 + t/db_dependent/api/v1/transfer_limits.t | 261 ++++++++++++++++++ 11 files changed, 795 insertions(+) create mode 100644 Koha/Exceptions/TransferLimit.pm create mode 100644 Koha/REST/V1/TransferLimits.pm create mode 100644 api/v1/swagger/definitions/transfer_limit.json create mode 100644 api/v1/swagger/parameters/transfer_limit.json create mode 100644 api/v1/swagger/paths/transfer_limits.yaml create mode 100755 t/db_dependent/api/v1/transfer_limits.t diff --git a/Koha/Exceptions/TransferLimit.pm b/Koha/Exceptions/TransferLimit.pm new file mode 100644 index 0000000000..7b2dab1948 --- /dev/null +++ b/Koha/Exceptions/TransferLimit.pm @@ -0,0 +1,17 @@ +package Koha::Exceptions::TransferLimit; + +use Modern::Perl; + +use Exception::Class ( + + 'Koha::Exceptions::TransferLimit::Exception' => { + description => 'Something went wrong!', + }, + + 'Koha::Exceptions::TransferLimit::Duplicate' => { + isa => 'Koha::Exceptions::TransferLimit::Exception', + description => 'A transfer limit with the given parameters already exists!', + }, +); + +1; diff --git a/Koha/Item/Transfer/Limit.pm b/Koha/Item/Transfer/Limit.pm index 7f5dd33273..db9db5037c 100644 --- a/Koha/Item/Transfer/Limit.pm +++ b/Koha/Item/Transfer/Limit.pm @@ -34,6 +34,23 @@ Koha::Item::Transfer::Limit - Koha Item Transfer Limit Object class =cut +=head3 to_api_mapping + +This method returns the mapping for representing a Koha::Item object +on the API. + +=cut + +sub to_api_mapping { + return { + limitId => 'limit_id', + toBranch => 'to_library_id', + fromBranch => 'from_library_id', + itemtype => 'item_type', + ccode => 'collection_code', + }; +} + =head3 type =cut diff --git a/Koha/REST/V1/TransferLimits.pm b/Koha/REST/V1/TransferLimits.pm new file mode 100644 index 0000000000..c70baf7d8f --- /dev/null +++ b/Koha/REST/V1/TransferLimits.pm @@ -0,0 +1,191 @@ +package Koha::REST::V1::TransferLimits; + +# 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 . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Controller'; +use Koha::Item::Transfer::Limits; +use Koha::Libraries; + +use Koha::Exceptions::TransferLimit; + +use Scalar::Util qw( blessed ); + +use Try::Tiny; + +=head1 NAME + +Koha::REST::V1::TransferLimits - Koha REST API for handling libraries (V1) + +=head1 API + +=head2 Methods + +=cut + +=head3 list + +Controller function that handles listing Koha::Item::Transfer::Limits objects + +=cut + +sub list { + my $c = shift->openapi->valid_input or return; + + return try { + my $limits_set = Koha::Item::Transfer::Limits->new; + my $limits = $c->objects->search( $limits_set ); + return $c->render( status => 200, openapi => $limits ); + } + catch { + $c->unhandled_exception( $_ ); + }; +} + +=head3 add + +Controller function that handles adding a new transfer limit + +=cut + +sub add { + my $c = shift->openapi->valid_input or return; + + return try { + my $params = $c->validation->param( 'body' ); + my $transfer_limit = Koha::Item::Transfer::Limit->new_from_api( $params ); + + if ( Koha::Item::Transfer::Limits->search( $transfer_limit->attributes_from_api($params) )->count == 0 ) { + $transfer_limit->store; + } else { + Koha::Exceptions::TransferLimit::Duplicate->throw() + } + + return $c->render( + status => 201, + openapi => $transfer_limit->to_api + ); + } + catch { + if ( blessed $_ && $_->isa('Koha::Exceptions::Object::DuplicateID') ) { + return $c->render( + status => 409, + openapi => { error => $_->error, conflict => $_->duplicate_id } + ); + } + + $c->unhandled_exception($_); + }; +} + +=head3 delete + +Controller function that handles deleting a transfer limit + +=cut + +sub delete { + + my $c = shift->openapi->valid_input or return; + + my $transfer_limit = Koha::Item::Transfer::Limits->find( $c->validation->param( 'limit_id' ) ); + + if ( not defined $transfer_limit ) { + return $c->render( status => 404, openapi => { error => "Transfer limit not found" } ); + } + + return try { + $transfer_limit->delete; + return $c->render( status => 204, openapi => ''); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 batch_add + +Controller function that handles adding a new transfer limit + +=cut + +sub batch_add { + my $c = shift->openapi->valid_input or return; + + return try { + my $params = $c->validation->param( 'body' ); + + my @libraries = Koha::Libraries->search->as_list; + + my @from_branches = $params->{from_library_id} ? $params->{from_library_id} : map { $_->id } @libraries; + my @to_branches = $params->{to_library_id} ? $params->{to_library_id} : map { $_->id } @libraries; + + my @results; + foreach my $from ( @from_branches ) { + foreach my $to ( @to_branches ) { + my $limit_params = { %$params }; + + $limit_params->{from_library_id} = $from; + $limit_params->{to_library_id} = $to; + + next if $to eq $from; + + my $transfer_limit = Koha::Item::Transfer::Limit->new_from_api( $limit_params ); + my $exists = Koha::Item::Transfer::Limits->search( $transfer_limit->unblessed )->count; + unless ( $exists ) { + $transfer_limit->store; + push( @results, $transfer_limit->to_api()); + } + } + } + my $transfer_limit = Koha::Item::Transfer::Limit->new_from_api( $params ); + + return $c->render( + status => 201, + openapi => \@results + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 batch_delete + +Controller function that handles batch deleting transfer limits + +=cut + +sub batch_delete { + + my $c = shift->openapi->valid_input or return; + + return try { + my $params = $c->validation->param( 'body' ); + my $transfer_limit = Koha::Item::Transfer::Limit->new_from_api( $params ); + my $search_params = $transfer_limit->unblessed; + + Koha::Item::Transfer::Limits->search($search_params)->delete; + + return $c->render( status => 204, openapi => ''); + } + catch { + $c->unhandled_exception($_); + }; +} + +1; diff --git a/api/v1/swagger/definitions.json b/api/v1/swagger/definitions.json index fdd44d9535..c12936736f 100644 --- a/api/v1/swagger/definitions.json +++ b/api/v1/swagger/definitions.json @@ -50,6 +50,9 @@ "library": { "$ref": "definitions/library.json" }, + "transfer_limit": { + "$ref": "definitions/transfer_limit.json" + }, "item": { "$ref": "definitions/item.json" }, diff --git a/api/v1/swagger/definitions/transfer_limit.json b/api/v1/swagger/definitions/transfer_limit.json new file mode 100644 index 0000000000..8a508082c0 --- /dev/null +++ b/api/v1/swagger/definitions/transfer_limit.json @@ -0,0 +1,27 @@ +{ + "type": "object", + "properties": { + "limit_id": { + "type": "integer", + "description": "Internal transfer limit identifier" + }, + "to_library_id": { + "type": "string", + "description": "Internal library id for which library the item is going to" + }, + "from_library_id": { + "type": "string", + "description": "Internal library id for which library the item is coming from" + }, + "item_type": { + "type": ["string", "null"], + "description": "Itemtype defining the type for this limi" + }, + "collection_code": { + "type": ["string", "null"], + "description": "Authorized value for the collection code associated with this limit" + } + }, + "additionalProperties": false, + "required": ["to_library_id", "from_library_id"] +} diff --git a/api/v1/swagger/parameters.json b/api/v1/swagger/parameters.json index ec4e52ef5a..95464e1461 100644 --- a/api/v1/swagger/parameters.json +++ b/api/v1/swagger/parameters.json @@ -8,6 +8,9 @@ "patron_id_pp": { "$ref": "parameters/patron.json#/patron_id_pp" }, + "transfer_limit_id_pp": { + "$ref": "parameters/transfer_limit.json#/transfer_limit_id_pp" + }, "patron_id_qp": { "$ref": "parameters/patron.json#/patron_id_qp" }, diff --git a/api/v1/swagger/parameters/transfer_limit.json b/api/v1/swagger/parameters/transfer_limit.json new file mode 100644 index 0000000000..0965bfb465 --- /dev/null +++ b/api/v1/swagger/parameters/transfer_limit.json @@ -0,0 +1,9 @@ +{ + "transfer_limit_id_pp": { + "name": "limit_id", + "in": "path", + "description": "Internal transfer limit identifier", + "required": true, + "type": "string" + } +} diff --git a/api/v1/swagger/paths.json b/api/v1/swagger/paths.json index 0462a70b56..a845313fc8 100644 --- a/api/v1/swagger/paths.json +++ b/api/v1/swagger/paths.json @@ -80,6 +80,15 @@ "/libraries": { "$ref": "paths/libraries.json#/~1libraries" }, + "/transfer_limits": { + "$ref": "paths/transfer_limits.yaml#/~1transfer_limits" + }, + "/transfer_limits/{limit_id}": { + "$ref": "paths/transfer_limits.yaml#/~1transfer_limits~1{limit_id}" + }, + "/transfer_limits/batch": { + "$ref": "paths/transfer_limits.yaml#/~1transfer_limits~1batch" + }, "/libraries/{library_id}": { "$ref": "paths/libraries.json#/~1libraries~1{library_id}" }, diff --git a/api/v1/swagger/paths/transfer_limits.yaml b/api/v1/swagger/paths/transfer_limits.yaml new file mode 100644 index 0000000000..e83817ff7b --- /dev/null +++ b/api/v1/swagger/paths/transfer_limits.yaml @@ -0,0 +1,254 @@ +--- +"/transfer_limits": + get: + x-mojo-to: TransferLimits#list + operationId: listTransferLimits + tags: + - transfer + parameters: + - name: to_library_id + in: query + description: Search on to_library_id + required: false + type: string + - name: from_library_id + in: query + description: Search on from_library_id + required: false + type: string + - name: item_type + in: query + description: Search on item_type + required: false + type: string + - name: collection_code + in: query + description: Search on collection_code + required: false + type: string + - "$ref": "../parameters.json#/match" + - "$ref": "../parameters.json#/order_by" + - "$ref": "../parameters.json#/page" + - "$ref": "../parameters.json#/per_page" + - "$ref": "../parameters.json#/q_param" + - "$ref": "../parameters.json#/q_body" + - "$ref": "../parameters.json#/q_header" + produces: + - application/json + responses: + '200': + description: A list of transfer limits + schema: + type: array + items: + "$ref": "../definitions.json#/transfer_limit" + '500': + description: Internal error + schema: + "$ref": "../definitions.json#/error" + '503': + description: Under maintenance + schema: + "$ref": "../definitions.json#/error" + x-koha-authorization: + permissions: + parameters: manage_transfers + post: + x-mojo-to: TransferLimits#add + operationId: addTransferLimit + tags: + - transfer + parameters: + - name: body + in: body + description: A JSON object containing information about a new transfer limit + required: true + schema: + "$ref": "../definitions.json#/transfer_limit" + produces: + - application/json + responses: + '201': + description: Transfer limit added + schema: + "$ref": "../definitions.json#/transfer_limit" + '400': + description: Bad request + schema: + "$ref": "../definitions.json#/error" + '401': + description: Authentication required + schema: + "$ref": "../definitions.json#/error" + '403': + description: Access forbidden + schema: + "$ref": "../definitions.json#/error" + '409': + description: Conflict in creating resource + schema: + "$ref": "../definitions.json#/error" + '500': + description: Internal error + schema: + "$ref": "../definitions.json#/error" + '503': + description: Under maintenance + schema: + "$ref": "../definitions.json#/error" + x-koha-authorization: + permissions: + parameters: manage_transfers +"/transfer_limits/{limit_id}": + delete: + x-mojo-to: TransferLimits#delete + operationId: deleteTransferLimit + tags: + - transfer + parameters: + - "$ref": "../parameters.json#/transfer_limit_id_pp" + produces: + - application/json + responses: + '204': + description: Transfer limit deleted + schema: + type: string + '401': + description: Authentication required + schema: + "$ref": "../definitions.json#/error" + '403': + description: Access forbidden + schema: + "$ref": "../definitions.json#/error" + '404': + description: Library not found + schema: + "$ref": "../definitions.json#/error" + '500': + description: Internal error + schema: + "$ref": "../definitions.json#/error" + '503': + description: Under maintenance + schema: + "$ref": "../definitions.json#/error" + x-koha-authorization: + permissions: + parameters: manage_transfers +"/transfer_limits/batch": + post: + x-mojo-to: TransferLimits#batch_add + operationId: batchAddTransferLimits + tags: + - transfer + parameters: + - name: body + in: body + description: A JSON object containing information about new transfer limits. + required: true + schema: + type: object + properties: + to_library_id: + type: string + description: Internal library id for which library the item is going to + from_library_id: + type: string + description: Internal library id for which library the item is coming + from + item_type: + type: + - string + - 'null' + description: Itemtype defining the type for this limi + collection_code: + type: + - string + - 'null' + description: Authorized value for the collection code associated with + this limit + additionalProperties: false + produces: + - application/json + responses: + '201': + description: A list of transfer limits + schema: + type: array + items: + "$ref": "../definitions.json#/transfer_limit" + '500': + description: Internal error + schema: + "$ref": "../definitions.json#/error" + '503': + description: Under maintenance + schema: + "$ref": "../definitions.json#/error" + x-koha-authorization: + permissions: + parameters: manage_transfers + delete: + x-mojo-to: TransferLimits#batch_delete + operationId: batchDeleteTransferLimits + tags: + - transfer + parameters: + - name: body + in: body + description: A JSON object containing information about new transfer limits. + required: true + schema: + type: object + properties: + to_library_id: + type: string + description: Internal library id for which library the item is going to + from_library_id: + type: string + description: Internal library id for which library the item is coming + from + item_type: + type: + - string + - 'null' + description: Itemtype defining the type for this limi + collection_code: + type: + - string + - 'null' + description: Authorized value for the collection code associated with + this limit + additionalProperties: false + produces: + - application/json + responses: + '204': + description: Transfer limits deleted + schema: + type: string + '401': + description: Authentication required + schema: + "$ref": "../definitions.json#/error" + '403': + description: Access forbidden + schema: + "$ref": "../definitions.json#/error" + '404': + description: Library not found + schema: + "$ref": "../definitions.json#/error" + '500': + description: Internal error + schema: + "$ref": "../definitions.json#/error" + '503': + description: Under maintenance + schema: + "$ref": "../definitions.json#/error" + x-koha-authorization: + permissions: + parameters: manage_transfers diff --git a/api/v1/swagger/x-primitives.json b/api/v1/swagger/x-primitives.json index 13cc1da4fc..491f8304ff 100644 --- a/api/v1/swagger/x-primitives.json +++ b/api/v1/swagger/x-primitives.json @@ -18,6 +18,10 @@ "maxLength": 10, "minLength": 1 }, + "limit_id": { + "type": "integer", + "description": "Internal transfer limit identifier" + }, "cardnumber": { "type": ["string", "null"], "description": "library assigned user identifier" diff --git a/t/db_dependent/api/v1/transfer_limits.t b/t/db_dependent/api/v1/transfer_limits.t new file mode 100755 index 0000000000..35eec83baa --- /dev/null +++ b/t/db_dependent/api/v1/transfer_limits.t @@ -0,0 +1,261 @@ +#!/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 . + +use Modern::Perl; + +use Test::More tests => 4; +use Test::Mojo; +use Test::Warn; + +use t::lib::TestBuilder; +use t::lib::Mocks; + +use List::Util qw(min); + +use Koha::Item::Transfer::Limits; +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'); + +subtest 'list() tests' => sub { + plan tests => 3; + + $schema->storage->txn_begin; + + Koha::Item::Transfer::Limits->delete; + + my $patron = $builder->build_object({ + class => 'Koha::Patrons', + value => { flags => 1 } + }); + my $password = 'thePassword123'; + $patron->set_password({ password => $password, skip_validation => 1 }); + my $userid = $patron->userid; + + my $limit = $builder->build_object({ class => 'Koha::Item::Transfer::Limits' }); + + $t->get_ok( "//$userid:$password@/api/v1/transfer_limits" ) + ->status_is( 200, 'SWAGGER3.2.2' ) + ->json_is( [$limit->to_api] ); + + $schema->storage->txn_rollback; +}; + +subtest 'add() tests' => sub { + + plan tests => 8; + + $schema->storage->txn_begin; + + my $authorized_patron = $builder->build_object({ + class => 'Koha::Patrons', + value => { flags => 1 } + }); + 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 => 4 } + }); + $unauthorized_patron->set_password({ password => $password, skip_validation => 1 }); + my $unauth_userid = $unauthorized_patron->userid; + + my $limit = $builder->build_object({ class => 'Koha::Item::Transfer::Limits' }); + my $limit_hashref = $limit->to_api; + delete $limit_hashref->{limit_id}; + $limit->delete; + + # Unauthorized attempt to write + $t->post_ok( "//$unauth_userid:$password@/api/v1/transfer_limits" => json => $limit_hashref ) + ->status_is(403); + + # Authorized attempt to write invalid data + my $limit_with_invalid_field = {'invalid' => 'invalid'}; + + $t->post_ok( "//$auth_userid:$password@/api/v1/transfer_limits" => json => $limit_with_invalid_field ) + ->status_is(400) + ->json_is( + "/errors" => [ + { + message => "Properties not allowed: invalid.", + path => "/body" + } + ] + ); + + # Authorized attempt to write + $t->post_ok( "//$auth_userid:$password@/api/v1/transfer_limits" => json => $limit_hashref ) + ->status_is( 201, 'SWAGGER3.2.1' ) + ->json_has( '' => $limit_hashref, 'SWAGGER3.3.1' ); + + $schema->storage->txn_rollback; +}; + +subtest 'delete() tests' => sub { + plan tests => 7; + + $schema->storage->txn_begin; + + my $authorized_patron = $builder->build_object({ + class => 'Koha::Patrons', + value => { flags => 1 } + }); + 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 => 4 } + }); + $unauthorized_patron->set_password({ password => $password, skip_validation => 1 }); + my $unauth_userid = $unauthorized_patron->userid; + + my $limit = $builder->build_object({ class => 'Koha::Item::Transfer::Limits' }); + my $limit_id = $limit->id; + + # Unauthorized attempt to delete + $t->delete_ok( "//$unauth_userid:$password@/api/v1/transfer_limits/$limit_id" ) + ->status_is(403); + + $t->delete_ok( "//$auth_userid:$password@/api/v1/transfer_limits/$limit_id" ) + ->status_is(204, 'SWAGGER3.2.4') + ->content_is('', 'SWAGGER3.3.4'); + + $t->delete_ok( "//$auth_userid:$password@/api/v1/transfer_limits/$limit_id" ) + ->status_is(404); + + $schema->storage->txn_rollback; +}; + +subtest 'batch_add() and batch_delete() tests' => sub { + plan tests => 26; + + $schema->storage->txn_begin; + + Koha::Item::Transfer::Limits->delete; + + #my $library = $builder->build_object({ class => 'Koha::Libraries' }); + + my $library = Koha::Libraries->search->next; + my $itemtype = Koha::ItemTypes->search->next; + + my $authorized_patron = $builder->build_object({ + class => 'Koha::Patrons', + value => { flags => 1 } + }); + 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 => 4 } + }); + $unauthorized_patron->set_password({ password => $password, skip_validation => 1 }); + my $unauth_userid = $unauthorized_patron->userid; + + my $limit_hashref = { + item_type => $itemtype->id + }; + + # Unauthorized attempt to write + $t->post_ok( "//$unauth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_hashref ) + ->status_is(403); + + # Authorized attempt to write invalid data + my $limit_with_invalid_field = {'invalid' => 'invalid'}; + + $t->post_ok( "//$auth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_with_invalid_field ) + ->status_is(400) + ->json_is( + "/errors" => [ + { + message => "Properties not allowed: invalid.", + path => "/body" + } + ] + ); + + # Create all combinations of to/from libraries + $t->post_ok( "//$auth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_hashref ) + ->status_is( 201, 'SWAGGER3.2.1' ) + ->json_has( '' => $limit_hashref, 'SWAGGER3.3.1' ); + + my $limits = Koha::Item::Transfer::Limits->search; + + my $libraries_count = Koha::Libraries->search->count; + is( $limits->count, $libraries_count * ($libraries_count - 1 ), "Created the correct number of limits" ); + + # Delete all combinations of to/from libraries + $t->delete_ok( "//$auth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_hashref ) + ->status_is( 204, 'SWAGGER3.2.1' ); + + $limits = Koha::Item::Transfer::Limits->search; + + is( $limits->count, 0, "Deleted the correct number of limits" ); + + # Create all combinations of 'to' libraries + $limit_hashref->{to_library_id} = $library->id; + $t->post_ok( "//$auth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_hashref ) + ->status_is( 201, 'SWAGGER3.2.1' ) + ->json_has( '' => $limit_hashref, 'SWAGGER3.3.1' ); + + $limits = Koha::Item::Transfer::Limits->search; + + is( $limits->count, $libraries_count - 1 , "Created the correct number of limits" ); + + # Delete all combinations of 'to' libraries + $t->delete_ok( "//$auth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_hashref ) + ->status_is( 204, 'SWAGGER3.2.1' ); + + $limits = Koha::Item::Transfer::Limits->search; + + is( $limits->count, 0, "Deleted the correct number of limits" ); + + # Create all combinations of 'from' libraries + Koha::Item::Transfer::Limits->search->delete; + + delete $limit_hashref->{to_library_id}; + $limit_hashref->{from_library_id} = $library->id; + $t->post_ok( "//$auth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_hashref ) + ->status_is( 201, 'SWAGGER3.2.1' ) + ->json_has( '' => $limit_hashref, 'SWAGGER3.3.1' ); + + $limits = Koha::Item::Transfer::Limits->search; + + $libraries_count = Koha::Libraries->search->count; + is( $limits->count, $libraries_count - 1 , "Created the correct number of limits" ); + + # Delete all combinations of 'from' libraries + $t->delete_ok( "//$auth_userid:$password@/api/v1/transfer_limits/batch" => json => $limit_hashref ) + ->status_is( 204, 'SWAGGER3.2.1' ); + + $limits = Koha::Item::Transfer::Limits->search; + + $libraries_count = Koha::Libraries->search->count; + is( $limits->count, 0, "Deleted the correct number of limits" ); + + $schema->storage->txn_rollback; +}; -- 2.39.5