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

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

Return to bug 31801