Bug 31801: Add REST endpoint to modify a biblio
To test: 1. Apply patch 2. Set RESTBasicAuth preference to true 3. Pick a biblio to modify, and modify it's marc record 4. Make a PUT request to /api/v1/biblios/:biblionumber with one of the following content type header - application/marcxml+xml - application/marc-in-json - application/marc 5. Add the following header in the request 'x-framework-id: <framework id>' 5. Check that the biblio was modified 6. Sign off Signed-off-by: Hammat Wele <hammat.wele@inlibro.com> Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com> Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
parent
587615fd9f
commit
4438c4da2e
3 changed files with 560 additions and 2 deletions
|
@ -22,7 +22,7 @@ use Mojo::Base 'Mojolicious::Controller';
|
|||
use Koha::Biblios;
|
||||
use Koha::Ratings;
|
||||
use Koha::RecordProcessor;
|
||||
use C4::Biblio qw( DelBiblio AddBiblio );
|
||||
use C4::Biblio qw( DelBiblio AddBiblio ModBiblio );
|
||||
use C4::Search qw( FindDuplicate );
|
||||
|
||||
use List::MoreUtils qw( any );
|
||||
|
@ -541,4 +541,60 @@ sub add {
|
|||
};
|
||||
}
|
||||
|
||||
=head3 update
|
||||
|
||||
Controller function that handles modifying an biblio object
|
||||
|
||||
=cut
|
||||
|
||||
sub update {
|
||||
my $c = shift->openapi->valid_input or return;
|
||||
|
||||
my $biblionumber = $c->validation->param('biblio_id');
|
||||
my $biblio = Koha::Biblios->find( $biblionumber );
|
||||
|
||||
if ( not defined $biblio ) {
|
||||
return $c->render(
|
||||
status => 404,
|
||||
openapi => { error => "Object not found" }
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
my $body = $c->validation->param('Body');
|
||||
|
||||
my $flavour = $c->validation->param('x-marc-schema');
|
||||
$flavour = C4::Context->preference('marcflavour') unless $flavour;
|
||||
|
||||
my $record;
|
||||
my $frameworkcode = $c->validation->param('x-framework-id') || $biblio->frameworkcode;
|
||||
if ( $c->req->headers->content_type =~ m/application\/marcxml\+xml/ ) {
|
||||
$record = MARC::Record->new_from_xml( $body, 'UTF-8', $flavour );
|
||||
} elsif ( $c->req->headers->content_type =~ m/application\/marc-in-json/ ) {
|
||||
$record = MARC::Record->new_from_mij_structure( $body );
|
||||
} elsif ( $c->req->headers->content_type =~ m/application\/marc/ ) {
|
||||
$record = MARC::Record->new_from_usmarc( $body );
|
||||
} else {
|
||||
return $c->render(
|
||||
status => 406,
|
||||
openapi => [
|
||||
"application/json",
|
||||
"application/marcxml+xml",
|
||||
"application/marc-in-json",
|
||||
"application/marc"
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
ModBiblio( $record, $biblionumber, $frameworkcode );
|
||||
|
||||
$c->render(
|
||||
status => 200,
|
||||
openapi => { id => $biblionumber }
|
||||
);
|
||||
}
|
||||
catch {
|
||||
$c->unhandled_exception($_);
|
||||
};
|
||||
}
|
||||
1;
|
||||
|
|
|
@ -149,6 +149,67 @@
|
|||
x-koha-authorization:
|
||||
permissions:
|
||||
editcatalogue: edit_catalogue
|
||||
put:
|
||||
x-mojo-to: Biblios#update
|
||||
operationId: updateBiblio
|
||||
tags:
|
||||
- biblios
|
||||
summary: Update biblio
|
||||
parameters:
|
||||
- $ref: "../swagger.yaml#/parameters/biblio_id_pp"
|
||||
- name: Body
|
||||
in: body
|
||||
description: A JSON object or the Marc string describing a biblio
|
||||
required: true
|
||||
schema:
|
||||
type:
|
||||
- string
|
||||
- object
|
||||
- $ref: "../swagger.yaml#/parameters/framework_id_header"
|
||||
- $ref: "../swagger.yaml#/parameters/marc_schema_header"
|
||||
- $ref: "../swagger.yaml#/parameters/confirm_not_duplicate_header"
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
"200":
|
||||
description: A biblio
|
||||
"400":
|
||||
description: Bad request
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"401":
|
||||
description: Authentication required
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"403":
|
||||
description: Access forbidden
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"404":
|
||||
description: Biblio not found
|
||||
schema:
|
||||
$ref: "../swagger.yaml#/definitions/error"
|
||||
"406":
|
||||
description: Not acceptable
|
||||
schema:
|
||||
type: array
|
||||
description: Accepted content-types
|
||||
items:
|
||||
type: string
|
||||
"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:
|
||||
editcatalogue: edit_catalogue
|
||||
"/biblios/{biblio_id}/checkouts":
|
||||
get:
|
||||
x-mojo-to: Biblios#get_checkouts
|
||||
|
|
|
@ -20,7 +20,7 @@ use Modern::Perl;
|
|||
use utf8;
|
||||
use Encode;
|
||||
|
||||
use Test::More tests => 9;
|
||||
use Test::More tests => 10;
|
||||
use Test::MockModule;
|
||||
use Test::Mojo;
|
||||
use Test::Warn;
|
||||
|
@ -1140,5 +1140,446 @@ subtest 'post() tests' => sub {
|
|||
->status_is(200)
|
||||
->json_has('/id');
|
||||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
||||
|
||||
subtest 'put() tests' => sub {
|
||||
|
||||
plan tests => 14;
|
||||
|
||||
$schema->storage->txn_begin;
|
||||
|
||||
my $patron = $builder->build_object(
|
||||
{
|
||||
class => 'Koha::Patrons',
|
||||
value => { flags => 0 } # no permissions
|
||||
}
|
||||
);
|
||||
my $password = 'thePassword123';
|
||||
$patron->set_password( { password => $password, skip_validation => 1 } );
|
||||
my $userid = $patron->userid;
|
||||
|
||||
my $frameworkcode = 'BKS';
|
||||
my $biblio = $builder->build_sample_biblio({frameworkcode => $frameworkcode});
|
||||
|
||||
my $biblionumber = $biblio->biblionumber;
|
||||
|
||||
my $marcxml = q|<?xml version="1.0" encoding="UTF-8"?>
|
||||
<record
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
|
||||
xmlns="http://www.loc.gov/MARC21/slim">
|
||||
|
||||
<leader>01102pam a2200289 a 6500</leader>
|
||||
<controlfield tag="001">2504398</controlfield>
|
||||
<controlfield tag="005">20200421093816.0</controlfield>
|
||||
<controlfield tag="008">920610s1993 caub s001 0 eng </controlfield>
|
||||
<datafield tag="010" ind1=" " ind2=" ">
|
||||
<subfield code="a"> 92021731 </subfield>
|
||||
</datafield>
|
||||
<datafield tag="020" ind1=" " ind2=" ">
|
||||
<subfield code="a">05200784384 (Test json)</subfield>
|
||||
</datafield>
|
||||
<datafield tag="020" ind1=" " ind2=" ">
|
||||
<subfield code="a">05200784464 (Test json)</subfield>
|
||||
</datafield>
|
||||
<datafield tag="040" ind1=" " ind2=" ">
|
||||
<subfield code="a">DLC</subfield>
|
||||
<subfield code="c">DLC</subfield>
|
||||
<subfield code="d">DLC</subfield>
|
||||
</datafield>
|
||||
<datafield tag="041" ind1="0" ind2=" ">
|
||||
<subfield code="a">enggrc</subfield>
|
||||
</datafield>
|
||||
<datafield tag="050" ind1="0" ind2="0">
|
||||
<subfield code="a">PA522</subfield>
|
||||
<subfield code="b">.M38 1993</subfield>
|
||||
</datafield>
|
||||
<datafield tag="082" ind1="0" ind2="0">
|
||||
<subfield code="a">480</subfield>
|
||||
<subfield code="2">20</subfield>
|
||||
</datafield>
|
||||
<datafield tag="100" ind1="1" ind2=" ">
|
||||
<subfield code="a">Mastronarde, Donald J.</subfield>
|
||||
<subfield code="9">389</subfield>
|
||||
</datafield>
|
||||
<datafield tag="245" ind1="1" ind2="0">
|
||||
<subfield code="a">Introduction to Attic Greek (Using marcxml) /</subfield>
|
||||
<subfield code="c">Donald J. Mastronarde.</subfield>
|
||||
</datafield>
|
||||
<datafield tag="260" ind1=" " ind2=" ">
|
||||
<subfield code="a">Berkeley :</subfield>
|
||||
<subfield code="b">University of California Press,</subfield>
|
||||
<subfield code="c">c1993.</subfield>
|
||||
</datafield>
|
||||
<datafield tag="300" ind1=" " ind2=" ">
|
||||
<subfield code="a">ix, 425 p. :</subfield>
|
||||
<subfield code="b">maps ;</subfield>
|
||||
<subfield code="c">26 cm.</subfield>
|
||||
</datafield>
|
||||
<datafield tag="500" ind1=" " ind2=" ">
|
||||
<subfield code="a">Includes index.</subfield>
|
||||
</datafield>
|
||||
<datafield tag="650" ind1=" " ind2="0">
|
||||
<subfield code="a">Attic Greek dialect</subfield>
|
||||
<subfield code="9">7</subfield>
|
||||
</datafield>
|
||||
<datafield tag="856" ind1="4" ind2="2">
|
||||
<subfield code="3">Contributor biographical information</subfield>
|
||||
<subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
|
||||
</datafield>
|
||||
<datafield tag="856" ind1="4" ind2="2">
|
||||
<subfield code="3">Publisher description</subfield>
|
||||
<subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
|
||||
</datafield>
|
||||
<datafield tag="906" ind1=" " ind2=" ">
|
||||
<subfield code="a">7</subfield>
|
||||
<subfield code="b">cbc</subfield>
|
||||
<subfield code="c">orignew</subfield>
|
||||
<subfield code="d">1</subfield>
|
||||
<subfield code="e">ocip</subfield>
|
||||
<subfield code="f">19</subfield>
|
||||
<subfield code="g">y-gencatlg</subfield>
|
||||
</datafield>
|
||||
<datafield tag="942" ind1=" " ind2=" ">
|
||||
<subfield code="2">ddc</subfield>
|
||||
<subfield code="c">BK</subfield>
|
||||
</datafield>
|
||||
<datafield tag="955" ind1=" " ind2=" ">
|
||||
<subfield code="a">pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93</subfield>
|
||||
</datafield>
|
||||
<datafield tag="999" ind1=" " ind2=" ">
|
||||
<subfield code="c">3</subfield>
|
||||
<subfield code="d">3</subfield>
|
||||
</datafield>
|
||||
</record>|;
|
||||
|
||||
my $mij = q|{
|
||||
"fields": [
|
||||
{
|
||||
"001": "2504398"
|
||||
},
|
||||
{
|
||||
"005": "20200421093816.0"
|
||||
},
|
||||
{
|
||||
"008": "920610s1993 caub s001 0 eng "
|
||||
},
|
||||
{
|
||||
"010": {
|
||||
"ind1": " ",
|
||||
"subfields": [
|
||||
{
|
||||
"a": " 92021731 "
|
||||
}
|
||||
],
|
||||
"ind2": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"020": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "05200784382 (Test mij)"
|
||||
}
|
||||
],
|
||||
"ind2": " ",
|
||||
"ind1": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"020": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "05200784462 (Test mij)"
|
||||
}
|
||||
],
|
||||
"ind1": " ",
|
||||
"ind2": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"040": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "DLC"
|
||||
},
|
||||
{
|
||||
"c": "DLC"
|
||||
},
|
||||
{
|
||||
"d": "DLC"
|
||||
}
|
||||
],
|
||||
"ind2": " ",
|
||||
"ind1": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"041": {
|
||||
"ind2": " ",
|
||||
"subfields": [
|
||||
{
|
||||
"a": "enggrc"
|
||||
}
|
||||
],
|
||||
"ind1": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"050": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "PA522"
|
||||
},
|
||||
{
|
||||
"b": ".M38 1993"
|
||||
}
|
||||
],
|
||||
"ind1": "0",
|
||||
"ind2": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"082": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "480"
|
||||
},
|
||||
{
|
||||
"2": "20"
|
||||
}
|
||||
],
|
||||
"ind2": "0",
|
||||
"ind1": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"100": {
|
||||
"ind2": " ",
|
||||
"subfields": [
|
||||
{
|
||||
"a": "Mastronarde, Donald J."
|
||||
},
|
||||
{
|
||||
"9": "389"
|
||||
}
|
||||
],
|
||||
"ind1": "1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"245": {
|
||||
"ind1": "1",
|
||||
"subfields": [
|
||||
{
|
||||
"a": "Introduction to Attic Greek (Using mij) /"
|
||||
},
|
||||
{
|
||||
"c": "Donald J. Mastronarde."
|
||||
}
|
||||
],
|
||||
"ind2": "0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"260": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "Berkeley :"
|
||||
},
|
||||
{
|
||||
"b": "University of California Press,"
|
||||
},
|
||||
{
|
||||
"c": "c1993."
|
||||
}
|
||||
],
|
||||
"ind2": " ",
|
||||
"ind1": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"300": {
|
||||
"ind1": " ",
|
||||
"subfields": [
|
||||
{
|
||||
"a": "ix, 425 p. :"
|
||||
},
|
||||
{
|
||||
"b": "maps ;"
|
||||
},
|
||||
{
|
||||
"c": "26 cm."
|
||||
}
|
||||
],
|
||||
"ind2": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"500": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "Includes index."
|
||||
}
|
||||
],
|
||||
"ind1": " ",
|
||||
"ind2": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"650": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "Attic Greek dialect"
|
||||
},
|
||||
{
|
||||
"9": "7"
|
||||
}
|
||||
],
|
||||
"ind2": "0",
|
||||
"ind1": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"856": {
|
||||
"subfields": [
|
||||
{
|
||||
"3": "Contributor biographical information"
|
||||
},
|
||||
{
|
||||
"u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
|
||||
}
|
||||
],
|
||||
"ind2": "2",
|
||||
"ind1": "4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"856": {
|
||||
"ind1": "4",
|
||||
"subfields": [
|
||||
{
|
||||
"3": "Publisher description"
|
||||
},
|
||||
{
|
||||
"u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
|
||||
}
|
||||
],
|
||||
"ind2": "2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"906": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "7"
|
||||
},
|
||||
{
|
||||
"b": "cbc"
|
||||
},
|
||||
{
|
||||
"c": "orignew"
|
||||
},
|
||||
{
|
||||
"d": "1"
|
||||
},
|
||||
{
|
||||
"e": "ocip"
|
||||
},
|
||||
{
|
||||
"f": "19"
|
||||
},
|
||||
{
|
||||
"g": "y-gencatlg"
|
||||
}
|
||||
],
|
||||
"ind1": " ",
|
||||
"ind2": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"942": {
|
||||
"subfields": [
|
||||
{
|
||||
"2": "ddc"
|
||||
},
|
||||
{
|
||||
"c": "BK"
|
||||
}
|
||||
],
|
||||
"ind2": " ",
|
||||
"ind1": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"955": {
|
||||
"subfields": [
|
||||
{
|
||||
"a": "pc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93"
|
||||
}
|
||||
],
|
||||
"ind2": " ",
|
||||
"ind1": " "
|
||||
}
|
||||
},
|
||||
{
|
||||
"999": {
|
||||
"subfields": [
|
||||
{
|
||||
"c": "3"
|
||||
},
|
||||
{
|
||||
"d": "3"
|
||||
}
|
||||
],
|
||||
"ind1": " ",
|
||||
"ind2": " "
|
||||
}
|
||||
}
|
||||
],
|
||||
"leader": "01102pam a2200289 a 8500"
|
||||
}|;
|
||||
my $marc = q|01116pam a2200289 a 4500001000800000005001700008008004100025010001700066020002800083020002800111040001800139041001100157050002100168082001200189100003200201245007500233260005600308300003300364500002000397650002700417856009500444856008700539906004500626942001200671955013000683999001300813250439820221223213433.0920610s1993 caub s001 0 eng a 92021731 a05200784384 (Test json) a05200784464 (Test json) aDLCcDLCdDLC0 aenggrc00aPA522b.M38 199300a4802201 aMastronarde, Donald J.938910aIntroduction to Attic Greek (Using usmarc) /cDonald J. Mastronarde. aBerkeley :bUniversity of California Press,cc1993. aix, 425 p. :bmaps ;c26 cm. aIncludes index. 0aAttic Greek dialect97423Contributor biographical informationuhttp://www.loc.gov/catdir/bios/ucal051/92021731.html423Publisher descriptionuhttp://www.loc.gov/catdir/description/ucal041/92021731.html a7bcbccorignewd1eocipf19gy-gencatlg 2ddccBK apc05 to ea00 06-11-92; ea04 to SCD 06-11-92; fd11 06-11-92 (PA522.M...); fr21 06-12-92; fs62 06-15-92; CIP ver. pv07 11-12-93 c715d715|;
|
||||
|
||||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber")
|
||||
->status_is(403, 'Not enough permissions makes it return the right code');
|
||||
|
||||
# Add permissions
|
||||
$builder->build(
|
||||
{
|
||||
source => 'UserPermission',
|
||||
value => {
|
||||
borrowernumber => $patron->borrowernumber,
|
||||
module_bit => 9,
|
||||
code => 'edit_catalogue'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marcxml+xml', 'x-framework-id' => $frameworkcode} => $marcxml)
|
||||
->status_is(200)
|
||||
->json_has('/id');
|
||||
|
||||
$biblio = Koha::Biblios->find($biblionumber);
|
||||
|
||||
is($biblio->title, 'Introduction to Attic Greek (Using marcxml) /');
|
||||
|
||||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marc-in-json', 'x-framework-id' => $frameworkcode} => $mij)
|
||||
->status_is(200)
|
||||
->json_has('/id');
|
||||
|
||||
$biblio = Koha::Biblios->find($biblionumber);
|
||||
|
||||
is($biblio->title, 'Introduction to Attic Greek (Using mij) /');
|
||||
|
||||
$t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marc', 'x-framework-id' => $frameworkcode} => $marc)
|
||||
->status_is(200)
|
||||
->json_has('/id');
|
||||
|
||||
$biblio = Koha::Biblios->find($biblionumber);
|
||||
|
||||
is($biblio->title, 'Introduction to Attic Greek (Using usmarc) /');
|
||||
|
||||
$schema->storage->txn_rollback;
|
||||
};
|
Loading…
Reference in a new issue