From ca6c984816ecf2eab799b84d046023cd886258cc Mon Sep 17 00:00:00 2001 From: Jonathan Druart Date: Thu, 16 Feb 2023 11:45:20 +0100 Subject: [PATCH] Bug 32981: Add endpoint to get AV for given category For, at least, the ERM module we would like to retrieve the authorised values for a given category to build a dropdown list with the different options. It has been decided on bug 17390 to use GET /authorised_value_categories/:authorised_value_category_id/values Test plan: curl -v -s -u koha:koha --request GET http://kohadev-intra.mydnsname.org:8081/api/v1/authorised_value_categories/LOC/values Should display the list of LOC curl -v -s -u koha:koha --request GET http://kohadev-intra.mydnsname.org:8081/api/v1/authorised_value_categories/xLOCx/values Should return a 404 Signed-off-by: Pedro Amorim Signed-off-by: Nick Clemens Signed-off-by: Tomas Cohen Arazi (cherry picked from commit 7e5c75549fe66eb16eb365ea3a79ee8d7fb6946b) Signed-off-by: Matt Blenkinsop --- Koha/AuthorisedValue.pm | 18 ++++ Koha/REST/V1/AuthorisedValues.pm | 59 +++++++++++++ .../swagger/definitions/authorised_value.yaml | 32 +++++++ api/v1/swagger/paths/authorised_values.yaml | 85 ++++++++++++++++++ api/v1/swagger/swagger.yaml | 10 +++ t/db_dependent/api/v1/authorised_values.t | 87 +++++++++++++++++++ 6 files changed, 291 insertions(+) create mode 100644 Koha/REST/V1/AuthorisedValues.pm create mode 100644 api/v1/swagger/definitions/authorised_value.yaml create mode 100644 api/v1/swagger/paths/authorised_values.yaml create mode 100644 t/db_dependent/api/v1/authorised_values.t diff --git a/Koha/AuthorisedValue.pm b/Koha/AuthorisedValue.pm index 8f97bb1ede..06de1fe743 100644 --- a/Koha/AuthorisedValue.pm +++ b/Koha/AuthorisedValue.pm @@ -46,6 +46,24 @@ sub opac_description { return $self->lib_opac() || $self->lib(); } +=head3 to_api_mapping + +This method returns the mapping for representing a Koha::AuthorisedValue object +on the API. + +=cut + +sub to_api_mapping { + return { + id => 'authorised_value_id', + category => 'category_name', + authorised_value => 'value', + lib => 'description', + lib_opac => 'opac_description', + imageurl => 'image_url', + }; +} + =head2 Internal methods =head3 _type diff --git a/Koha/REST/V1/AuthorisedValues.pm b/Koha/REST/V1/AuthorisedValues.pm new file mode 100644 index 0000000000..39d108900b --- /dev/null +++ b/Koha/REST/V1/AuthorisedValues.pm @@ -0,0 +1,59 @@ +package Koha::REST::V1::AuthorisedValues; + +# 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::AuthorisedValues; +use Koha::AuthorisedValueCategories; + +use Try::Tiny; + +=head1 API + +=head2 Methods + +=head3 list + +=cut + +sub list_av_from_category { + my $c = shift->openapi->valid_input or return; + + my $category_name = $c->validation->param('authorised_value_category_name'); + + my $category = Koha::AuthorisedValueCategories->find($category_name); + + unless ($category) { + return $c->render( + status => 404, + openapi => { error => "Category not found" } + ); + } + + return try { + my $av_set = Koha::AuthorisedValues->search( { category => $category_name } )->search_with_library_limits; + my $avs = $c->objects->search($av_set); + return $c->render( status => 200, openapi => $avs ); + } catch { + $c->unhandled_exception($_); + }; + +} + +1; diff --git a/api/v1/swagger/definitions/authorised_value.yaml b/api/v1/swagger/definitions/authorised_value.yaml new file mode 100644 index 0000000000..0f11eb36b9 --- /dev/null +++ b/api/v1/swagger/definitions/authorised_value.yaml @@ -0,0 +1,32 @@ +--- +type: object +properties: + authorised_value_id: + type: integer + description: internally assigned authorised value identifier + readOnly: true + category_name: + description: the category of this authorised value + type: string + value: + description: The code for this authorised value + type: string + description: + description: The staff interface description for this authorised value + type: string + opac_description: + description: The public interface description of this authorised value, if set" + type: + - string + - "null" + image_url: + description: The url of the image associated with this authorised value, if any + type: + - string + - "null" + +additionalProperties: false +required: + - category_name + - value + - description diff --git a/api/v1/swagger/paths/authorised_values.yaml b/api/v1/swagger/paths/authorised_values.yaml new file mode 100644 index 0000000000..243729ceb7 --- /dev/null +++ b/api/v1/swagger/paths/authorised_values.yaml @@ -0,0 +1,85 @@ +--- +"/authorised_value_categories/{authorised_value_category_name}/values": + get: + x-mojo-to: AuthorisedValues#list_av_from_category + operationId: listAuthorisedValues + tags: + - authorised_values + summary: List authorised values for a given category + produces: + - application/json + parameters: + - description: category name + in: path + name: authorised_value_category_name + required: true + type: string + - description: Case insensitive search on authorised value id + in: query + name: authorised_value_id + required: false + type: integer + - description: Case insensitive search on authorised value category name + in: query + name: category_name + required: false + type: string + - description: Case insensitive search on value + in: query + name: value + required: false + type: string + - description: Case insensitive search on description + in: query + name: description + required: false + type: string + - description: Case insensitive search on opac description + in: query + name: opac_description + required: false + type: string + - description: Case insensitive search on image url + in: query + name: image_url + required: false + type: string + - $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" + responses: + 200: + description: A list of authorised values + schema: + items: + $ref: "../swagger.yaml#/definitions/authorised_value" + type: array + 400: + description: Bad request + schema: + $ref: "../swagger.yaml#/definitions/error" + 403: + description: Access forbidden + schema: + $ref: "../swagger.yaml#/definitions/error" + 404: + description: Ressource not found + schema: + $ref: "../swagger.yaml#/definitions/error" + 500: + description: |- + Internal server error. Possible `error_code` attribute values: + * `internal_server_error` + schema: + $ref: "../swagger.yaml#/definitions/error" + 503: + description: Under maintenance + schema: + $ref: "../swagger.yaml#/definitions/error" + x-koha-authorization: + permissions: + catalogue: 1 diff --git a/api/v1/swagger/swagger.yaml b/api/v1/swagger/swagger.yaml index 479c4d710b..d27ffcdbad 100644 --- a/api/v1/swagger/swagger.yaml +++ b/api/v1/swagger/swagger.yaml @@ -8,6 +8,8 @@ definitions: $ref: ./definitions/advancededitormacro.yaml allows_renewal: $ref: ./definitions/allows_renewal.yaml + authorised_value: + $ref: ./definitions/authorised_value.yaml identity_provider: "$ref": ./definitions/identity_provider.yaml identity_provider_domain: @@ -139,6 +141,8 @@ paths: $ref: paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1domains "/auth/identity_providers/{identity_provider_id}/domains/{identity_provider_domain_id}": $ref: paths/auth.yaml#/~1auth~1identity_providers~1{identity_provider_id}~1domains~1{identity_provider_domain_id} + "/authorised_value_categories/{authorised_value_category_name}/values": + $ref: "./paths/authorised_values.yaml#/~1authorised_value_categories~1{authorised_value_category_name}~1values" "/biblios/{biblio_id}": $ref: "./paths/biblios.yaml#/~1biblios~1{biblio_id}" "/biblios/{biblio_id}/checkouts": @@ -338,6 +342,12 @@ parameters: name: agreement_period_id required: true type: integer + authorised_value_id_pp: + description: Authorised value internal identifier + in: path + name: authorised_value_id + required: true + type: integer identity_provider_id_pp: description: Authentication provider internal identifier in: path diff --git a/t/db_dependent/api/v1/authorised_values.t b/t/db_dependent/api/v1/authorised_values.t new file mode 100644 index 0000000000..cb6d829821 --- /dev/null +++ b/t/db_dependent/api/v1/authorised_values.t @@ -0,0 +1,87 @@ +#!/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 => 1; +use Test::Mojo; + +use t::lib::TestBuilder; +use t::lib::Mocks; + +use Koha::AuthorisedValues; +use Koha::Database; + +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_av_from_category() tests' => sub { + + plan tests => 11; + + $schema->storage->txn_begin; + + my $librarian = $builder->build_object( + { + class => 'Koha::Patrons', + value => { flags => 2 ** 2 } # catalogue flag = 2 + } + ); + 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; + + ## Authorized user tests + # No category, 404 expected + $t->get_ok("//$userid:$password@/api/v1/authorised_value_categories/NON_EXISTS/values") + ->status_is(404) + ->json_is( '/error' => 'Category not found' ); + + my $av_cat = $builder->build_object({ class => 'Koha::AuthorisedValueCategories' })->category_name; + + # No AVs, so empty array should be returned + $t->get_ok("//$userid:$password@/api/v1/authorised_value_categories/$av_cat/values") + ->status_is(200) + ->json_is( [] ); + + my $av = $builder->build_object( + { class => 'Koha::AuthorisedValues', value => { category => $av_cat } } ); + + # One av created, should get returned + $t->get_ok("//$userid:$password@/api/v1/authorised_value_categories/$av_cat/values") + ->status_is(200) + ->json_is( [$av->to_api] ); + + # Unauthorized access + $t->get_ok("//$unauth_userid:$password@/api/v1/authorised_value_categories/$av_cat/values") + ->status_is(403); + + $schema->storage->txn_rollback; +}; -- 2.39.5