From 3bf57d92a10546929303aacbed2e13630d88693a Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Wed, 16 Mar 2022 16:49:40 +0100 Subject: [PATCH] Bug 32030: ERM - REST API - GET POST PUT DELETE specs Signed-off-by: Jonathan Field Signed-off-by: Martin Renvoize Signed-off-by: Kyle M Hall Signed-off-by: Tomas Cohen Arazi --- Koha/REST/V1/ERM/Agreements.pm | 195 ++++++++++ api/v1/swagger/definitions/erm_agreement.yaml | 10 + .../definitions/erm_agreement_period.yaml | 31 ++ .../definitions/erm_agreement_user_role.yaml | 21 ++ api/v1/swagger/paths/erm_agreements.yaml | 207 ++++++++++- api/v1/swagger/swagger.yaml | 14 + t/db_dependent/api/v1/erm_agreements.t | 351 ++++++++++++++++-- t/lib/TestBuilder.pm | 6 + 8 files changed, 810 insertions(+), 25 deletions(-) create mode 100644 api/v1/swagger/definitions/erm_agreement_period.yaml create mode 100644 api/v1/swagger/definitions/erm_agreement_user_role.yaml mode change 100644 => 100755 t/db_dependent/api/v1/erm_agreements.t diff --git a/Koha/REST/V1/ERM/Agreements.pm b/Koha/REST/V1/ERM/Agreements.pm index f521ca6916..999881f180 100644 --- a/Koha/REST/V1/ERM/Agreements.pm +++ b/Koha/REST/V1/ERM/Agreements.pm @@ -21,6 +21,7 @@ use Mojo::Base 'Mojolicious::Controller'; use Koha::ERM::Agreements; +use Scalar::Util qw( blessed ); use Try::Tiny qw( catch try ); =head1 API @@ -45,4 +46,198 @@ sub list { } +=head3 get + +Controller function that handles retrieving a single Koha::ERM::Agreement object + +=cut + +sub get { + my $c = shift->openapi->valid_input or return; + + return try { + my $agreement_id = $c->validation->param('agreement_id'); + my $agreement = $c->objects->find( Koha::ERM::Agreements->search, $agreement_id ); + + unless ($agreement) { + return $c->render( + status => 404, + openapi => { error => "Agreement not found" } + ); + } + + return $c->render( + status => 200, + openapi => $agreement + ); + } + catch { + $c->unhandled_exception($_); + }; +} + +=head3 add + +Controller function that handles adding a new Koha::ERM::Agreement object + +=cut + +sub add { + my $c = shift->openapi->valid_input or return; + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + my $periods = delete $body->{periods} // []; + my $user_roles = delete $body->{user_roles} // []; + + my $agreement = Koha::ERM::Agreement->new_from_api($body)->store; + $agreement->periods($periods); + $agreement->user_roles($user_roles); + + $c->res->headers->location($c->req->url->to_string . '/' . $agreement->agreement_id); + return $c->render( + status => 201, + openapi => $agreement->to_api + ); + } + ); + } + catch { + + my $to_api_mapping = Koha::ERM::Agreement->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::DuplicateID') ) { + return $c->render( + status => 409, + openapi => { error => $_->error, conflict => $_->duplicate_id } + ); + } + elsif ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + } + + $c->unhandled_exception($_); + }; +} + +=head3 update + +Controller function that handles updating a Koha::ERM::Agreement object + +=cut + +sub update { + my $c = shift->openapi->valid_input or return; + + my $agreement_id = $c->validation->param('agreement_id'); + my $agreement = Koha::ERM::Agreements->find( $agreement_id ); + + unless ($agreement) { + return $c->render( + status => 404, + openapi => { error => "Agreement not found" } + ); + } + + return try { + Koha::Database->new->schema->txn_do( + sub { + + my $body = $c->validation->param('body'); + + my $periods = delete $body->{periods} // []; + my $user_roles = delete $body->{user_roles} // []; + + $agreement->set_from_api($body)->store; + $agreement->periods($periods); + $agreement->user_roles($user_roles); + + $c->res->headers->location($c->req->url->to_string . '/' . $agreement->agreement_id); + return $c->render( + status => 200, + openapi => $agreement->to_api + ); + } + ); + } + catch { + my $to_api_mapping = Koha::ERM::Agreement->new->to_api_mapping; + + if ( blessed $_ ) { + if ( $_->isa('Koha::Exceptions::Object::FKConstraint') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->broken_fk } + . " does not exist" + } + ); + } + elsif ( $_->isa('Koha::Exceptions::BadParameter') ) { + return $c->render( + status => 400, + openapi => { + error => "Given " + . $to_api_mapping->{ $_->parameter } + . " does not exist" + } + ); + } + } + + $c->unhandled_exception($_); + }; +}; + +=head3 delete + +=cut + +sub delete { + my $c = shift->openapi->valid_input or return; + + my $agreement = Koha::ERM::Agreements->find( $c->validation->param('agreement_id') ); + unless ($agreement) { + return $c->render( + status => 404, + openapi => { error => "Agreement not found" } + ); + } + + return try { + $agreement->delete; + return $c->render( + status => 204, + openapi => q{} + ); + } + catch { + $c->unhandled_exception($_); + }; +} + 1; diff --git a/api/v1/swagger/definitions/erm_agreement.yaml b/api/v1/swagger/definitions/erm_agreement.yaml index 180d0e99d9..7451901d90 100644 --- a/api/v1/swagger/definitions/erm_agreement.yaml +++ b/api/v1/swagger/definitions/erm_agreement.yaml @@ -39,6 +39,16 @@ properties: type: - string - "null" + periods: + type: array + description: periods defined for this agreement + items: + $ref: erm_agreement_period.yaml + user_roles: + type: array + description: role for users + items: + $ref: erm_agreement_user_role.yaml additionalProperties: false required: - agreement_id diff --git a/api/v1/swagger/definitions/erm_agreement_period.yaml b/api/v1/swagger/definitions/erm_agreement_period.yaml new file mode 100644 index 0000000000..7695e9d93e --- /dev/null +++ b/api/v1/swagger/definitions/erm_agreement_period.yaml @@ -0,0 +1,31 @@ +--- +type: object +properties: + agreement_period_id: + $ref: ../x-primitives.yaml#/agreement_period_id + agreement_id: + type: integer + description: Internal agreement identifier + started_on: + type: string + format: date + description: Start of the agreement period + ended_on: + type: + - string + - "null" + format: date + description: End of the agreemnent period + cancellation_deadline: + type: + - string + - "null" + format: date + description: Deadline for the cancellation + notes: + type: + - string + - "null" +additionalProperties: false +required: + - started_on diff --git a/api/v1/swagger/definitions/erm_agreement_user_role.yaml b/api/v1/swagger/definitions/erm_agreement_user_role.yaml new file mode 100644 index 0000000000..68c3cb33d5 --- /dev/null +++ b/api/v1/swagger/definitions/erm_agreement_user_role.yaml @@ -0,0 +1,21 @@ +--- +type: object +properties: + agreement_id: + type: integer + description: Internal agreement identifier + user_id: + type: integer + description: Internal patron identifier + role: + description: role of the user + type: + - string + patron: + type: + - object + - "null" +additionalProperties: false +required: + - user_id + - role diff --git a/api/v1/swagger/paths/erm_agreements.yaml b/api/v1/swagger/paths/erm_agreements.yaml index 54ff7ee5ad..4a04eeead7 100644 --- a/api/v1/swagger/paths/erm_agreements.yaml +++ b/api/v1/swagger/paths/erm_agreements.yaml @@ -5,7 +5,7 @@ operationId: listErmAgreements tags: - agreement - summary: List erm_agreements + summary: List agreements produces: - application/json parameters: @@ -85,3 +85,208 @@ x-koha-authorization: permissions: erm: 1 + post: + x-mojo-to: ERM::Agreements#add + operationId: addErmAgreements + tags: + - agreement + summary: Add agreement + consumes: + - application/json + produces: + - application/json + parameters: + - description: A JSON object containing information about the new agreement + in: body + name: body + required: true + schema: + $ref: ../definitions.yaml#/erm_agreement + responses: + 201: + description: A successfully created agreement + schema: + items: + $ref: ../definitions.yaml#/erm_agreement + 400: + description: Bad parameter + schema: + $ref: ../definitions.yaml#/error + 401: + description: Authentication required + schema: + $ref: ../definitions.yaml#/error + 403: + description: Access forbidden + schema: + $ref: ../definitions.yaml#/error + 404: + description: Ressource not found + schema: + $ref: ../definitions.yaml#/error + 409: + description: Conflict in creating resource + schema: + $ref: ../definitions.yaml#/error + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: ../definitions.yaml#/error + 503: + description: Under maintenance + schema: + $ref: ../definitions.yaml#/error + x-koha-authorization: + permissions: + erm: 1 +"/erm/agreements/{agreement_id}": + get: + x-mojo-to: ERM::Agreements#get + operationId: getErmAgreements + tags: + - agreement + summary: Get agreement + produces: + - application/json + parameters: + - $ref: ../parameters.yaml#/agreement_id_pp + responses: + 200: + description: An agreement + schema: + items: + $ref: ../definitions.yaml#/erm_agreement + 401: + description: Authentication required + schema: + $ref: ../definitions.yaml#/error + 403: + description: Access forbidden + schema: + $ref: ../definitions.yaml#/error + 404: + description: Ressource not found + schema: + $ref: ../definitions.yaml#/error + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: ../definitions.yaml#/error + 503: + description: Under maintenance + schema: + $ref: ../definitions.yaml#/error + x-koha-authorization: + permissions: + erm: 1 + x-koha-embed: + - periods + - user_roles + - user_roles.patron + put: + x-mojo-to: ERM::Agreements#update + operationId: updateErmAgreements + tags: + - agreement + summary: Update agreement + consumes: + - application/json + produces: + - application/json + parameters: + - $ref: ../parameters.yaml#/agreement_id_pp + - name: body + in: body + description: A JSON object containing new information about existing agreement + required: true + schema: + $ref: ../definitions.yaml#/erm_agreement + + responses: + 200: + description: A successfully updated agreement + schema: + items: + $ref: ../definitions.yaml#/erm_agreement + 400: + description: Bad parameter + schema: + $ref: ../definitions.yaml#/error + 403: + description: Access forbidden + schema: + $ref: ../definitions.yaml#/error + 404: + description: Ressource not found + schema: + $ref: ../definitions.yaml#/error + 409: + description: Conflict in updating resource + schema: + $ref: ../definitions.yaml#/error + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: ../definitions.yaml#/error + 503: + description: Under maintenance + schema: + $ref: ../definitions.yaml#/error + x-koha-authorization: + permissions: + erm: 1 + x-koha-embed: + - periods + - user_roles + delete: + x-mojo-to: ERM::Agreements#delete + operationId: deleteErmAgreements + tags: + - agreement + summary: Delete agreement + produces: + - application/json + parameters: + - $ref: ../parameters.yaml#/agreement_id_pp + responses: + 204: + description: Agreement deleted + 400: + description: Agreement deletion failed + schema: + $ref: ../definitions.yaml#/error + 401: + description: Authentication required + schema: + $ref: ../definitions.yaml#/error + 403: + description: Access forbidden + schema: + $ref: ../definitions.yaml#/error + 404: + description: Ressource not found + schema: + $ref: ../definitions.yaml#/error + 409: + description: Conflict in deleting resource + schema: + $ref: ../definitions.yaml#/error + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: ../definitions.yaml#/error + 503: + description: Under maintenance + schema: + $ref: ../definitions.yaml#/error + x-koha-authorization: + permissions: + erm: 1 diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 62daad3655..f384dfa73a 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -159,6 +159,8 @@ paths: $ref: "./paths/config_smtp_servers.yaml#/~1config~1smtp_servers~1{smtp_server_id}" /erm/agreements: $ref: ./paths/erm_agreements.yaml#/~1erm~1agreements + "/erm/agreements/{agreement_id}": + $ref: "./paths/erm_agreements.yaml#/~1erm~1agreements~1{agreement_id}" /erm/users: $ref: ./paths/erm_users.yaml#/~1erm~1users /holds: @@ -274,6 +276,18 @@ parameters: name: advancededitormacro_id required: true type: integer + agreement_id_pp: + description: Agreement internal identifier + in: path + name: agreement_id + required: true + type: integer + agreement_period_id_pp: + description: Agreement period internal identifier + in: path + name: agreement_period_id + required: true + type: integer biblio_id_pp: description: Record internal identifier in: path diff --git a/t/db_dependent/api/v1/erm_agreements.t b/t/db_dependent/api/v1/erm_agreements.t old mode 100644 new mode 100755 index 8d1cfb5bc1..99f4c34e4d --- a/t/db_dependent/api/v1/erm_agreements.t +++ b/t/db_dependent/api/v1/erm_agreements.t @@ -17,7 +17,7 @@ use Modern::Perl; -use Test::More tests => 1; +use Test::More tests => 5; use Test::Mojo; use t::lib::TestBuilder; @@ -30,7 +30,6 @@ my $schema = Koha::Database->new->schema; my $builder = t::lib::TestBuilder->new; my $t = Test::Mojo->new('Koha::REST::V1'); -t::lib::Mocks::mock_preference( 'RESTBasicAuth', 1 ); subtest 'list() tests' => sub { @@ -43,7 +42,7 @@ subtest 'list() tests' => sub { my $librarian = $builder->build_object( { class => 'Koha::Patrons', - value => { flags => 27 ** 2 } + value => { flags => 2**28} } ); my $password = 'thePassword123'; @@ -62,40 +61,45 @@ subtest 'list() tests' => sub { ## Authorized user tests # No agreements, so empty array should be returned - $t->get_ok("//$userid:$password@/api/v1/erm/agreements") - ->status_is(200) + $t->get_ok("//$userid:$password@/api/v1/erm/agreements")->status_is(200) ->json_is( [] ); - my $agreement = $builder->build_object({ class => 'Koha::ERM::Agreements' }); + my $agreement = + $builder->build_object( { class => 'Koha::ERM::Agreements' } ); # One agreement created, should get returned - $t->get_ok("//$userid:$password@/api/v1/erm/agreements") - ->status_is(200) - ->json_is( [$agreement->to_api] ); + $t->get_ok("//$userid:$password@/api/v1/erm/agreements")->status_is(200) + ->json_is( [ $agreement->to_api ] ); my $another_agreement = $builder->build_object( - { class => 'Koha::ERM::Agreements', value => { vendor_id => $agreement->vendor_id } } ); - my $agreement_with_another_vendor_id = $builder->build_object({ class => 'Koha::ERM::Agreements' }); + { + class => 'Koha::ERM::Agreements', + value => { vendor_id => $agreement->vendor_id } + } + ); + my $agreement_with_another_vendor_id = + $builder->build_object( { class => 'Koha::ERM::Agreements' } ); # Two agreements created, they should both be returned - $t->get_ok("//$userid:$password@/api/v1/erm/agreements") - ->status_is(200) - ->json_is([$agreement->to_api, - $another_agreement->to_api, - $agreement_with_another_vendor_id->to_api - ] ); + $t->get_ok("//$userid:$password@/api/v1/erm/agreements")->status_is(200) + ->json_is( + [ + $agreement->to_api, + $another_agreement->to_api, + $agreement_with_another_vendor_id->to_api + ] + ); # Filtering works, two agreements sharing vendor_id - $t->get_ok("//$userid:$password@/api/v1/erm/agreements?vendor_id=" . $agreement->vendor_id ) - ->status_is(200) - ->json_is([ $agreement->to_api, - $another_agreement->to_api - ]); + $t->get_ok( "//$userid:$password@/api/v1/erm/agreements?vendor_id=" + . $agreement->vendor_id )->status_is(200) + ->json_is( [ $agreement->to_api, $another_agreement->to_api ] ); # Warn on unsupported query parameter - $t->get_ok("//$userid:$password@/api/v1/erm/agreements?blah=blah" ) + $t->get_ok("//$userid:$password@/api/v1/erm/agreements?blah=blah") ->status_is(400) - ->json_is( [{ path => '/query/blah', message => 'Malformed query string'}] ); + ->json_is( + [ { path => '/query/blah', message => 'Malformed query string' } ] ); # Unauthorized access $t->get_ok("//$unauth_userid:$password@/api/v1/erm/agreements") @@ -104,3 +108,302 @@ subtest 'list() tests' => sub { $schema->storage->txn_rollback; }; +subtest 'get() tests' => sub { + + plan tests => 8; + + $schema->storage->txn_begin; + + my $agreement = + $builder->build_object( { class => 'Koha::ERM::Agreements' } ); + my $librarian = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 2**28 } + } + ); + my $password = 'thePassword123'; + $librarian->set_password( { password => $password, skip_validation => 1 } ); + my $userid = $librarian->userid; + + my $patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 0 } + } + ); + + $patron->set_password( { password => $password, skip_validation => 1 } ); + my $unauth_userid = $patron->userid; + + $t->get_ok( "//$userid:$password@/api/v1/erm/agreements/" + . $agreement->agreement_id )->status_is(200) + ->json_is( $agreement->to_api ); + + $t->get_ok( "//$unauth_userid:$password@/api/v1/erm/agreements/" + . $agreement->agreement_id )->status_is(403); + + my $agreement_to_delete = + $builder->build_object( { class => 'Koha::ERM::Agreements' } ); + my $non_existent_id = $agreement_to_delete->id; + $agreement_to_delete->delete; + + $t->get_ok("//$userid:$password@/api/v1/erm/agreements/$non_existent_id") + ->status_is(404)->json_is( '/error' => 'Agreement not found' ); + + $schema->storage->txn_rollback; +}; + +subtest 'add() tests' => sub { + + plan tests => 22; + + $schema->storage->txn_begin; + + my $librarian = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 2**28 } + } + ); + my $password = 'thePassword123'; + $librarian->set_password( { password => $password, skip_validation => 1 } ); + my $userid = $librarian->userid; + + my $patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 0 } + } + ); + + $patron->set_password( { password => $password, skip_validation => 1 } ); + my $unauth_userid = $patron->userid; + + my $agreement = { + vendor_id => undef, + name => "Agreement name", + description => "Agreement description", + status => "active", + closure_reason => "", + is_perpetual => 1, + renewal_priority => "", + license_info => "Agreement license_info", + }; + + # Unauthorized attempt to write + $t->post_ok( "//$unauth_userid:$password@/api/v1/erm/agreements" => json => + $agreement )->status_is(403); + + # Authorized attempt to write invalid data + my $agreement_with_invalid_field = { + blah => "Agreement Blah", + name => "Agreement name", + description => "Agreement description", + status => "active", + closure_reason => "", + is_perpetual => 1, + renewal_priority => "", + license_info => "Agreement license_info", + }; + + $t->post_ok( "//$userid:$password@/api/v1/erm/agreements" => json => + $agreement_with_invalid_field )->status_is(400)->json_is( + "/errors" => [ + { + message => "Properties not allowed: blah.", + path => "/body" + } + ] + ); + + # Authorized attempt to write + my $agreement_id = + $t->post_ok( + "//$userid:$password@/api/v1/erm/agreements" => json => $agreement ) + ->status_is( 201, 'SWAGGER3.2.1' )->header_like( + Location => qr|^/api/v1/erm/agreements/\d*|, + 'SWAGGER3.4.1' + )->json_is( '/vendor_id' => $agreement->{vendor_id} ) + ->json_is( '/name' => $agreement->{name} ) + ->json_is( '/description' => $agreement->{description} ) + ->json_is( '/status' => $agreement->{status} ) + ->json_is( '/closure_reason' => $agreement->{closure_reason} ) + ->json_is( '/is_perpetual' => $agreement->{is_perpetual} ) + ->json_is( '/renewal_priority' => $agreement->{renewal_priority} ) + ->json_is( '/license_info' => $agreement->{license_info} ) + ->tx->res->json->{agreement_id}; + + # Authorized attempt to create with null id + $agreement->{agreement_id} = undef; + $t->post_ok( + "//$userid:$password@/api/v1/erm/agreements" => json => $agreement ) + ->status_is(400)->json_has('/errors'); + + # Authorized attempt to create with existing id + $agreement->{agreement_id} = $agreement_id; + $t->post_ok( + "//$userid:$password@/api/v1/erm/agreements" => json => $agreement ) + ->status_is(400)->json_is( + "/errors" => [ + { + message => "Read-only.", + path => "/body/agreement_id" + } + ] + ); + + $schema->storage->txn_rollback; +}; + +subtest 'update() tests' => sub { + + plan tests => 15; + + $schema->storage->txn_begin; + + my $librarian = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 2**28 } + } + ); + my $password = 'thePassword123'; + $librarian->set_password( { password => $password, skip_validation => 1 } ); + my $userid = $librarian->userid; + + my $patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 0 } + } + ); + + $patron->set_password( { password => $password, skip_validation => 1 } ); + my $unauth_userid = $patron->userid; + + my $agreement_id = + $builder->build_object( { class => 'Koha::ERM::Agreements' } )->agreement_id; + + # Unauthorized attempt to update + $t->put_ok( + "//$unauth_userid:$password@/api/v1/erm/agreements/$agreement_id" => + json => { name => 'New unauthorized name change' } )->status_is(403); + + # Attempt partial update on a PUT + my $agreement_with_missing_field = { + description => 'New description', + status => 'active', + closure_reason => undef, + is_perpetual => 1, + renewal_priority => undef, + license_info => 'New license_info', + }; + + $t->put_ok( + "//$userid:$password@/api/v1/erm/agreements/$agreement_id" => json => + $agreement_with_missing_field )->status_is(400) + ->json_is( "/errors" => + [ { message => "Missing property.", path => "/body/name" } ] ); + + # Full object update on PUT + my $agreement_with_updated_field = { + vendor_id => undef, + name => 'New name', + description => 'New description', + status => 'closed', + closure_reason => undef, + is_perpetual => 1, + renewal_priority => undef, + license_info => 'New license_info', + }; + + $t->put_ok( + "//$userid:$password@/api/v1/erm/agreements/$agreement_id" => json => + $agreement_with_updated_field )->status_is(200) + ->json_is( '/name' => 'New name' ); + + # Authorized attempt to write invalid data + my $agreement_with_invalid_field = { + blah => "Agreement Blah", + name => "Agreement name", + description => "Agreement description", + status => "closed", + closure_reason => undef, + is_perpetual => 1, + renewal_priority => undef, + license_info => "Agreement license_info", + }; + + $t->put_ok( + "//$userid:$password@/api/v1/erm/agreements/$agreement_id" => json => + $agreement_with_invalid_field )->status_is(400)->json_is( + "/errors" => [ + { + message => "Properties not allowed: blah.", + path => "/body" + } + ] + ); + + my $agreement_to_delete = + $builder->build_object( { class => 'Koha::ERM::Agreements' } ); + my $non_existent_id = $agreement_to_delete->id; + $agreement_to_delete->delete; + + $t->put_ok( "//$userid:$password@/api/v1/erm/agreements/$non_existent_id" => + json => $agreement_with_updated_field )->status_is(404); + + # Wrong method (POST) + $agreement_with_updated_field->{agreement_id} = 2; + + $t->post_ok( + "//$userid:$password@/api/v1/erm/agreements/$agreement_id" => json => + $agreement_with_updated_field )->status_is(404); + + $schema->storage->txn_rollback; +}; + +subtest 'delete() tests' => sub { + + plan tests => 7; + + $schema->storage->txn_begin; + + my $librarian = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 2**28 } + } + ); + my $password = 'thePassword123'; + $librarian->set_password( { password => $password, skip_validation => 1 } ); + my $userid = $librarian->userid; + + my $patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 0 } + } + ); + + $patron->set_password( { password => $password, skip_validation => 1 } ); + my $unauth_userid = $patron->userid; + + my $agreement_id = + $builder->build_object( { class => 'Koha::ERM::Agreements' } )->id; + + # Unauthorized attempt to delete + $t->delete_ok( + "//$unauth_userid:$password@/api/v1/erm/agreements/$agreement_id") + ->status_is(403); + + $t->delete_ok("//$userid:$password@/api/v1/erm/agreements/$agreement_id") + ->status_is( 204, 'SWAGGER3.2.4' )->content_is( '', 'SWAGGER3.3.4' ); + + $t->delete_ok("//$userid:$password@/api/v1/erm/agreements/$agreement_id") + ->status_is(404); + + $schema->storage->txn_rollback; +}; + diff --git a/t/lib/TestBuilder.pm b/t/lib/TestBuilder.pm index e066c2facb..d065835ded 100644 --- a/t/lib/TestBuilder.pm +++ b/t/lib/TestBuilder.pm @@ -637,6 +637,12 @@ sub _gen_default_values { opac => 1, staff_client => 1 }, + ErmAgreement => { + status => 'active', + closure_reason => undef, + renewal_priority => undef, + vendor_id => undef, + }, }; } -- 2.39.5