From b5e135ae5d37bd19643c119c60ab01ce182b04f1 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 --- Koha/Exceptions/TransferLimit.pm | 17 ++ Koha/Item/Transfer/Limit.pm | 17 ++ Koha/REST/V1/TransferLimits.pm | 191 +++++++++++++ api/v1/swagger/definitions.json | 3 + api/v1/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.json | 376 +++++++++++++++++++++++++ api/v1/swagger/x-primitives.json | 4 + t/db_dependent/api/v1/transfer_limits.t | 261 +++++++++++++++++ 11 files changed, 917 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.json 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 61e6c15306..b8c0818a9c 100644 --- a/api/v1/swagger/definitions.json +++ b/api/v1/swagger/definitions.json @@ -41,6 +41,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 a39a439ad7..8516f2527d 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 8ba95189dc..0392eed856 100644 --- a/api/v1/swagger/paths.json +++ b/api/v1/swagger/paths.json @@ -68,6 +68,15 @@ "/libraries": { "$ref": "paths/libraries.json#/~1libraries" }, + "/transfer_limits": { + "$ref": "paths/transfer_limits.json#/~1transfer_limits" + }, + "/transfer_limits/{limit_id}": { + "$ref": "paths/transfer_limits.json#/~1transfer_limits~1{limit_id}" + }, + "/transfer_limits/batch": { + "$ref": "paths/transfer_limits.json#/~1transfer_limits~1batch" + }, "/libraries/{library_id}": { "$ref": "paths/libraries.json#/~1libraries~1{library_id}" }, diff --git a/api/v1/swagger/paths/transfer_limits.json b/api/v1/swagger/paths/transfer_limits.json new file mode 100644 index 0000000000..d0f89559ac --- /dev/null +++ b/api/v1/swagger/paths/transfer_limits.json @@ -0,0 +1,376 @@ +{ + "/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 0594264be9..e3a70bdd08 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.11.0