View | Details | Raw Unified | Return to bug 31801
Collapse All | Expand All

(-)a/Koha/REST/V1/Biblios.pm (-1 / +59 lines)
Lines 22-28 use Mojo::Base 'Mojolicious::Controller'; Link Here
22
use Koha::Biblios;
22
use Koha::Biblios;
23
use Koha::Ratings;
23
use Koha::Ratings;
24
use Koha::RecordProcessor;
24
use Koha::RecordProcessor;
25
use C4::Biblio qw( DelBiblio AddBiblio );
25
use C4::Biblio qw( DelBiblio AddBiblio ModBiblio );
26
use C4::Search qw( FindDuplicate );
26
use C4::Search qw( FindDuplicate );
27
27
28
use List::MoreUtils qw( any );
28
use List::MoreUtils qw( any );
Lines 543-546 sub add { Link Here
543
    };
543
    };
544
}
544
}
545
545
546
=head3 update
547
548
Controller function that handles modifying an biblio object
549
550
=cut
551
552
sub update {
553
    my $c = shift->openapi->valid_input or return;
554
555
    my $biblionumber = $c->validation->param('biblio_id');
556
    my $biblio = Koha::Biblios->find( $biblionumber );
557
558
    if ( not defined $biblio ) {
559
        return $c->render(
560
            status  => 404,
561
            openapi => { error => "Object not found" }
562
        );
563
    }
564
565
    try {
566
        my $body = $c->validation->param('Body');
567
568
        my $flavour =
569
            C4::Context->preference('marcflavour') eq 'UNIMARC'
570
            ? 'UNIMARCAUTH'
571
            : 'MARC21';
572
573
        my $record;
574
        my $frameworkcode = $c->validation->param('x-framework-id') || $biblio->frameworkcode;
575
        if ( $c->req->headers->content_type =~ m/application\/marcxml\+xml/ ) {
576
            $record = MARC::Record->new_from_xml( $body, 'UTF-8', $flavour );
577
        } elsif ( $c->req->headers->content_type =~ m/application\/marc-in-json/ ) {
578
            $record = MARC::Record->new_from_mij_structure( $body );
579
        } elsif ( $c->req->headers->content_type =~ m/application\/marc/ ) {
580
            $record = MARC::Record->new_from_usmarc( $body );
581
        } else {
582
            return $c->render(
583
                status  => 406,
584
                openapi => [
585
                    "application/json",
586
                    "application/marcxml+xml",
587
                    "application/marc-in-json",
588
                    "application/marc"
589
                ]
590
            );
591
        }
592
593
        ModBiblio( $record, $biblionumber, $frameworkcode );
594
595
        $c->render(
596
            status  => 200,
597
            openapi => { id => $biblionumber }
598
        );
599
    }
600
    catch {
601
        $c->unhandled_exception($_);
602
    };
603
}
546
1;
604
1;
(-)a/api/v1/swagger/paths/biblios.yaml (+60 lines)
Lines 148-153 Link Here
148
    x-koha-authorization:
148
    x-koha-authorization:
149
      permissions:
149
      permissions:
150
        editcatalogue: edit_catalogue
150
        editcatalogue: edit_catalogue
151
  put:
152
    x-mojo-to: Biblios#update
153
    operationId: updateBiblio
154
    tags:
155
      - biblios
156
    summary: Update biblio
157
    parameters:
158
      - $ref: "../swagger.yaml#/parameters/biblio_id_pp"
159
      - name: Body
160
        in: body
161
        description: A JSON object or the Marc string describing a biblio
162
        required: true
163
        schema:
164
          type:
165
            - string
166
            - object
167
      - $ref: "../swagger.yaml#/parameters/framework_id_header"
168
      - $ref: "../swagger.yaml#/parameters/confirm_not_duplicate_header"
169
    produces:
170
      - application/json
171
    responses:
172
      "200":
173
        description: A biblio
174
      "400":
175
        description: Bad request
176
        schema:
177
          $ref: "../swagger.yaml#/definitions/error"
178
      "401":
179
        description: Authentication required
180
        schema:
181
          $ref: "../swagger.yaml#/definitions/error"
182
      "403":
183
        description: Access forbidden
184
        schema:
185
          $ref: "../swagger.yaml#/definitions/error"
186
      "404":
187
        description: Biblio not found
188
        schema:
189
          $ref: "../swagger.yaml#/definitions/error"
190
      "406":
191
        description: Not acceptable
192
        schema:
193
          type: array
194
          description: Accepted content-types
195
          items:
196
            type: string
197
      "500":
198
        description: |
199
          Internal server error. Possible `error_code` attribute values:
200
201
          * `internal_server_error`
202
        schema:
203
          $ref: "../swagger.yaml#/definitions/error"
204
      "503":
205
        description: Under maintenance
206
        schema:
207
          $ref: "../swagger.yaml#/definitions/error"
208
    x-koha-authorization:
209
      permissions:
210
        editcatalogue: edit_catalogue
151
"/biblios/{biblio_id}/checkouts":
211
"/biblios/{biblio_id}/checkouts":
152
  get:
212
  get:
153
    x-mojo-to: Biblios#get_checkouts
213
    x-mojo-to: Biblios#get_checkouts
(-)a/t/db_dependent/api/v1/biblios.t (-2 / +442 lines)
Lines 20-26 use Modern::Perl; Link Here
20
use utf8;
20
use utf8;
21
use Encode;
21
use Encode;
22
22
23
use Test::More tests => 9;
23
use Test::More tests => 10;
24
use Test::MockModule;
24
use Test::MockModule;
25
use Test::Mojo;
25
use Test::Mojo;
26
use Test::Warn;
26
use Test::Warn;
Lines 1137-1141 subtest 'post() tests' => sub { Link Here
1137
      ->status_is(200)
1137
      ->status_is(200)
1138
      ->json_has('/id');
1138
      ->json_has('/id');
1139
1139
1140
    $schema->storage->txn_rollback;
1141
};
1142
1143
subtest 'put() tests' => sub {
1144
1145
    plan tests => 14;
1146
1147
    $schema->storage->txn_begin;
1148
1149
    my $patron = $builder->build_object(
1150
        {
1151
            class => 'Koha::Patrons',
1152
            value => { flags => 0 } # no permissions
1153
        }
1154
    );
1155
    my $password = 'thePassword123';
1156
    $patron->set_password( { password => $password, skip_validation => 1 } );
1157
    my $userid = $patron->userid;
1158
1159
    my $frameworkcode = 'BKS';
1160
    my $biblio = $builder->build_sample_biblio({frameworkcode => $frameworkcode});
1161
1162
    my $biblionumber = $biblio->biblionumber;
1163
1164
    my $marcxml = q|<?xml version="1.0" encoding="UTF-8"?>
1165
<record
1166
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1167
    xsi:schemaLocation="http://www.loc.gov/MARC21/slim http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd"
1168
    xmlns="http://www.loc.gov/MARC21/slim">
1169
1170
  <leader>01102pam a2200289 a 6500</leader>
1171
  <controlfield tag="001">2504398</controlfield>
1172
  <controlfield tag="005">20200421093816.0</controlfield>
1173
  <controlfield tag="008">920610s1993    caub         s001 0 eng  </controlfield>
1174
  <datafield tag="010" ind1=" " ind2=" ">
1175
    <subfield code="a">   92021731 </subfield>
1176
  </datafield>
1177
  <datafield tag="020" ind1=" " ind2=" ">
1178
    <subfield code="a">05200784384 (Test json)</subfield>
1179
  </datafield>
1180
  <datafield tag="020" ind1=" " ind2=" ">
1181
    <subfield code="a">05200784464 (Test json)</subfield>
1182
  </datafield>
1183
  <datafield tag="040" ind1=" " ind2=" ">
1184
    <subfield code="a">DLC</subfield>
1185
    <subfield code="c">DLC</subfield>
1186
    <subfield code="d">DLC</subfield>
1187
  </datafield>
1188
  <datafield tag="041" ind1="0" ind2=" ">
1189
    <subfield code="a">enggrc</subfield>
1190
  </datafield>
1191
  <datafield tag="050" ind1="0" ind2="0">
1192
    <subfield code="a">PA522</subfield>
1193
    <subfield code="b">.M38 1993</subfield>
1194
  </datafield>
1195
  <datafield tag="082" ind1="0" ind2="0">
1196
    <subfield code="a">480</subfield>
1197
    <subfield code="2">20</subfield>
1198
  </datafield>
1199
  <datafield tag="100" ind1="1" ind2=" ">
1200
    <subfield code="a">Mastronarde, Donald J.</subfield>
1201
    <subfield code="9">389</subfield>
1202
  </datafield>
1203
  <datafield tag="245" ind1="1" ind2="0">
1204
    <subfield code="a">Introduction to Attic Greek  (Using marcxml) /</subfield>
1205
    <subfield code="c">Donald J. Mastronarde.</subfield>
1206
  </datafield>
1207
  <datafield tag="260" ind1=" " ind2=" ">
1208
    <subfield code="a">Berkeley :</subfield>
1209
    <subfield code="b">University of California Press,</subfield>
1210
    <subfield code="c">c1993.</subfield>
1211
  </datafield>
1212
  <datafield tag="300" ind1=" " ind2=" ">
1213
    <subfield code="a">ix, 425 p. :</subfield>
1214
    <subfield code="b">maps ;</subfield>
1215
    <subfield code="c">26 cm.</subfield>
1216
  </datafield>
1217
  <datafield tag="500" ind1=" " ind2=" ">
1218
    <subfield code="a">Includes index.</subfield>
1219
  </datafield>
1220
  <datafield tag="650" ind1=" " ind2="0">
1221
    <subfield code="a">Attic Greek dialect</subfield>
1222
    <subfield code="9">7</subfield>
1223
  </datafield>
1224
  <datafield tag="856" ind1="4" ind2="2">
1225
    <subfield code="3">Contributor biographical information</subfield>
1226
    <subfield code="u">http://www.loc.gov/catdir/bios/ucal051/92021731.html</subfield>
1227
  </datafield>
1228
  <datafield tag="856" ind1="4" ind2="2">
1229
    <subfield code="3">Publisher description</subfield>
1230
    <subfield code="u">http://www.loc.gov/catdir/description/ucal041/92021731.html</subfield>
1231
  </datafield>
1232
  <datafield tag="906" ind1=" " ind2=" ">
1233
    <subfield code="a">7</subfield>
1234
    <subfield code="b">cbc</subfield>
1235
    <subfield code="c">orignew</subfield>
1236
    <subfield code="d">1</subfield>
1237
    <subfield code="e">ocip</subfield>
1238
    <subfield code="f">19</subfield>
1239
    <subfield code="g">y-gencatlg</subfield>
1240
  </datafield>
1241
  <datafield tag="942" ind1=" " ind2=" ">
1242
    <subfield code="2">ddc</subfield>
1243
    <subfield code="c">BK</subfield>
1244
  </datafield>
1245
  <datafield tag="955" ind1=" " ind2=" ">
1246
    <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>
1247
  </datafield>
1248
  <datafield tag="999" ind1=" " ind2=" ">
1249
    <subfield code="c">3</subfield>
1250
    <subfield code="d">3</subfield>
1251
  </datafield>
1252
</record>|;
1253
1254
    my $mij = q|{
1255
  "fields": [
1256
    {
1257
      "001": "2504398"
1258
    },
1259
    {
1260
      "005": "20200421093816.0"
1261
    },
1262
    {
1263
      "008": "920610s1993    caub         s001 0 eng  "
1264
    },
1265
    {
1266
      "010": {
1267
        "ind1": " ",
1268
        "subfields": [
1269
          {
1270
            "a": "   92021731 "
1271
          }
1272
        ],
1273
        "ind2": " "
1274
      }
1275
    },
1276
    {
1277
      "020": {
1278
        "subfields": [
1279
          {
1280
            "a": "05200784382 (Test mij)"
1281
          }
1282
        ],
1283
        "ind2": " ",
1284
        "ind1": " "
1285
      }
1286
    },
1287
    {
1288
      "020": {
1289
        "subfields": [
1290
          {
1291
            "a": "05200784462 (Test mij)"
1292
          }
1293
        ],
1294
        "ind1": " ",
1295
        "ind2": " "
1296
      }
1297
    },
1298
    {
1299
      "040": {
1300
        "subfields": [
1301
          {
1302
            "a": "DLC"
1303
          },
1304
          {
1305
            "c": "DLC"
1306
          },
1307
          {
1308
            "d": "DLC"
1309
          }
1310
        ],
1311
        "ind2": " ",
1312
        "ind1": " "
1313
      }
1314
    },
1315
    {
1316
      "041": {
1317
        "ind2": " ",
1318
        "subfields": [
1319
          {
1320
            "a": "enggrc"
1321
          }
1322
        ],
1323
        "ind1": "0"
1324
      }
1325
    },
1326
    {
1327
      "050": {
1328
        "subfields": [
1329
          {
1330
            "a": "PA522"
1331
          },
1332
          {
1333
            "b": ".M38 1993"
1334
          }
1335
        ],
1336
        "ind1": "0",
1337
        "ind2": "0"
1338
      }
1339
    },
1340
    {
1341
      "082": {
1342
        "subfields": [
1343
          {
1344
            "a": "480"
1345
          },
1346
          {
1347
            "2": "20"
1348
          }
1349
        ],
1350
        "ind2": "0",
1351
        "ind1": "0"
1352
      }
1353
    },
1354
    {
1355
      "100": {
1356
        "ind2": " ",
1357
        "subfields": [
1358
          {
1359
            "a": "Mastronarde, Donald J."
1360
          },
1361
          {
1362
            "9": "389"
1363
          }
1364
        ],
1365
        "ind1": "1"
1366
      }
1367
    },
1368
    {
1369
      "245": {
1370
        "ind1": "1",
1371
        "subfields": [
1372
          {
1373
            "a": "Introduction to Attic Greek  (Using mij) /"
1374
          },
1375
          {
1376
            "c": "Donald J. Mastronarde."
1377
          }
1378
        ],
1379
        "ind2": "0"
1380
      }
1381
    },
1382
    {
1383
      "260": {
1384
        "subfields": [
1385
          {
1386
            "a": "Berkeley :"
1387
          },
1388
          {
1389
            "b": "University of California Press,"
1390
          },
1391
          {
1392
            "c": "c1993."
1393
          }
1394
        ],
1395
        "ind2": " ",
1396
        "ind1": " "
1397
      }
1398
    },
1399
    {
1400
      "300": {
1401
        "ind1": " ",
1402
        "subfields": [
1403
          {
1404
            "a": "ix, 425 p. :"
1405
          },
1406
          {
1407
            "b": "maps ;"
1408
          },
1409
          {
1410
            "c": "26 cm."
1411
          }
1412
        ],
1413
        "ind2": " "
1414
      }
1415
    },
1416
    {
1417
      "500": {
1418
        "subfields": [
1419
          {
1420
            "a": "Includes index."
1421
          }
1422
        ],
1423
        "ind1": " ",
1424
        "ind2": " "
1425
      }
1426
    },
1427
    {
1428
      "650": {
1429
        "subfields": [
1430
          {
1431
            "a": "Attic Greek dialect"
1432
          },
1433
          {
1434
            "9": "7"
1435
          }
1436
        ],
1437
        "ind2": "0",
1438
        "ind1": " "
1439
      }
1440
    },
1441
    {
1442
      "856": {
1443
        "subfields": [
1444
          {
1445
            "3": "Contributor biographical information"
1446
          },
1447
          {
1448
            "u": "http://www.loc.gov/catdir/bios/ucal051/92021731.html"
1449
          }
1450
        ],
1451
        "ind2": "2",
1452
        "ind1": "4"
1453
      }
1454
    },
1455
    {
1456
      "856": {
1457
        "ind1": "4",
1458
        "subfields": [
1459
          {
1460
            "3": "Publisher description"
1461
          },
1462
          {
1463
            "u": "http://www.loc.gov/catdir/description/ucal041/92021731.html"
1464
          }
1465
        ],
1466
        "ind2": "2"
1467
      }
1468
    },
1469
    {
1470
      "906": {
1471
        "subfields": [
1472
          {
1473
            "a": "7"
1474
          },
1475
          {
1476
            "b": "cbc"
1477
          },
1478
          {
1479
            "c": "orignew"
1480
          },
1481
          {
1482
            "d": "1"
1483
          },
1484
          {
1485
            "e": "ocip"
1486
          },
1487
          {
1488
            "f": "19"
1489
          },
1490
          {
1491
            "g": "y-gencatlg"
1492
          }
1493
        ],
1494
        "ind1": " ",
1495
        "ind2": " "
1496
      }
1497
    },
1498
    {
1499
      "942": {
1500
        "subfields": [
1501
          {
1502
            "2": "ddc"
1503
          },
1504
          {
1505
            "c": "BK"
1506
          }
1507
        ],
1508
        "ind2": " ",
1509
        "ind1": " "
1510
      }
1511
    },
1512
    {
1513
      "955": {
1514
        "subfields": [
1515
          {
1516
            "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"
1517
          }
1518
        ],
1519
        "ind2": " ",
1520
        "ind1": " "
1521
      }
1522
    },
1523
    {
1524
      "999": {
1525
        "subfields": [
1526
          {
1527
            "c": "3"
1528
          },
1529
          {
1530
            "d": "3"
1531
          }
1532
        ],
1533
        "ind1": " ",
1534
        "ind2": " "
1535
      }
1536
    }
1537
  ],
1538
  "leader": "01102pam a2200289 a 8500"
1539
}|;
1540
    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|;
1541
1542
    $t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber")
1543
      ->status_is(403, 'Not enough permissions makes it return the right code');
1544
1545
    # Add permissions
1546
    $builder->build(
1547
        {
1548
            source => 'UserPermission',
1549
            value  => {
1550
                borrowernumber => $patron->borrowernumber,
1551
                module_bit     => 9,
1552
                code           => 'edit_catalogue'
1553
            }
1554
        }
1555
    );
1556
1557
    $t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marcxml+xml', 'x-framework-id' => $frameworkcode} => $marcxml)
1558
      ->status_is(200)
1559
      ->json_has('/id');
1560
1561
    $biblio = Koha::Biblios->find($biblionumber);
1562
1563
    is($biblio->title, 'Introduction to Attic Greek  (Using marcxml) /');
1564
1565
    $t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marc-in-json', 'x-framework-id' => $frameworkcode} => $mij)
1566
      ->status_is(200)
1567
      ->json_has('/id');
1568
1569
    $biblio = Koha::Biblios->find($biblionumber);
1570
1571
    is($biblio->title, 'Introduction to Attic Greek  (Using mij) /');
1572
1573
    $t->put_ok("//$userid:$password@/api/v1/biblios/$biblionumber" => {'Content-Type' => 'application/marc', 'x-framework-id' => $frameworkcode} => $marc)
1574
      ->status_is(200)
1575
      ->json_has('/id');
1576
1577
    $biblio = Koha::Biblios->find($biblionumber);
1578
1579
    is($biblio->title, 'Introduction to Attic Greek  (Using usmarc) /');
1580
1140
    $schema->storage->txn_rollback;
1581
    $schema->storage->txn_rollback;
1141
};
1582
};
1142
- 

Return to bug 31801