Browse Source

initial commit

main
Paul Pound 1 week ago
commit
fa8220f639
  1. 1
      .gitignore
  2. 279
      README.md
  3. 24
      composer.json
  4. 11
      phpunit.xml
  5. 266
      src/InsertRequest.php
  6. 61
      src/InsertResponse.php
  7. 123
      src/RapidIllClient.php
  8. 7
      src/RapidIllException.php
  9. 13
      src/RequestType.php
  10. 160
      tests/RapidIllClientTest.php

1
.gitignore vendored

@ -0,0 +1 @@
.idea/

279
README.md

@ -0,0 +1,279 @@
# RapidILL Request
A PHP library for creating InterLibrary Loan (ILL) requests using the [RapidILL](https://exlibrisgroup.com/products/rapidill-interlibrary-loan/) API `InsertRequest` method.
Built on PHP's native `SoapClient` with no framework dependencies, making it easy to use in any PHP project including Drupal 10.
## Requirements
- PHP 8.1 or higher
- PHP SOAP extension (`ext-soap`)
## Installation
### Composer
```bash
composer require rapidill/request
```
### Drupal 10
Add the package to your Drupal project's `composer.json` as a path repository if installing from a local copy:
```json
{
"repositories": [
{
"type": "path",
"url": "/path/to/rapidILL-request"
}
],
"require": {
"rapidill/request": "*"
}
}
```
Then run:
```bash
composer require rapidill/request
```
## Quick Start
```php
use RapidIll\RapidIllClient;
use RapidIll\InsertRequest;
use RapidIll\RequestType;
// Create a client with your RapidILL credentials.
$client = new RapidIllClient(
username: 'your_username',
password: 'your_password',
rapidCode: 'YOUR_RAPID_CODE',
branchName: 'Main',
);
// Build and submit a request.
$request = (new InsertRequest())
->setRequestType(RequestType::Article)
->setJournalTitle('Nature')
->setArticleTitle('A breakthrough in quantum computing')
->setArticleAuthor('Smith, J.')
->addIssn('0028-0836');
$response = $client->insertRequest($request);
if ($response->isSuccessful) {
echo "Request submitted. Rapid ID: {$response->rapidRequestId}\n";
}
```
## Examples
### Request a journal article
```php
use RapidIll\RapidIllClient;
use RapidIll\InsertRequest;
use RapidIll\RequestType;
$client = new RapidIllClient(
username: 'your_username',
password: 'your_password',
rapidCode: 'YOUR_RAPID_CODE',
branchName: 'Main',
);
$request = (new InsertRequest())
->setRequestType(RequestType::Article)
->setJournalTitle('Nature')
->setJournalYear('2024')
->setJournalVolume('625')
->setJournalIssue('7994')
->setJournalMonth('January')
->setArticleTitle('A breakthrough in quantum computing')
->setArticleAuthor('Smith, J.')
->setArticlePages('100-105')
->addIssn('0028-0836')
->addIssn('1476-4687')
->setOclcNumber('1234567')
->setPatronName('Jane Doe')
->setPatronEmail('jane.doe@university.edu')
->setPatronDepartment('Physics')
->setXrefRequestId('ILL-2024-00042');
$response = $client->insertRequest($request);
if ($response->isSuccessful) {
echo "Request ID: {$response->rapidRequestId}\n";
echo "Match found: " . ($response->foundMatch ? 'yes' : 'no') . "\n";
echo "Available holdings: {$response->numberOfAvailableHoldings}\n";
} else {
echo "Request failed: {$response->verificationNote}\n";
}
```
### Request a book
```php
$request = (new InsertRequest())
->setRequestType(RequestType::Book)
->setJournalTitle('Introduction to Algorithms')
->setArticleAuthor('Cormen, Thomas H.')
->addIsbn('978-0262033848')
->setPublisher('MIT Press')
->setEdition('3rd')
->setPatronName('John Smith')
->setPatronEmail('john.smith@university.edu');
$response = $client->insertRequest($request);
```
### Request a book chapter
```php
$request = (new InsertRequest())
->setRequestType(RequestType::BookChapter)
->setJournalTitle('The Oxford Handbook of Innovation')
->setArticleTitle('Open Innovation')
->setArticleAuthor('Chesbrough, Henry')
->setArticlePages('191-213')
->addIsbn('978-0199286805')
->setPatronName('Alice Johnson')
->setPatronEmail('alice@university.edu');
$response = $client->insertRequest($request);
```
### Check holdings only (without submitting a request)
```php
$request = (new InsertRequest())
->setRequestType(RequestType::Article)
->setHoldingsCheckOnly(true)
->setJournalTitle('Science')
->addIssn('0036-8075');
$response = $client->insertRequest($request);
if ($response->isLocalHolding) {
echo "Item is available locally:\n";
foreach ($response->localHoldings as $holding) {
echo " Branch: {$holding['branchName']}\n";
echo " Location: {$holding['location']}\n";
echo " Call Number: {$holding['callNumber']}\n";
}
} else {
echo "Not held locally. {$response->numberOfAvailableHoldings} remote holdings available.\n";
}
```
### Error handling
```php
use RapidIll\RapidIllException;
try {
$response = $client->insertRequest($request);
} catch (RapidIllException $e) {
// SOAP or connection error.
error_log('RapidILL error: ' . $e->getMessage());
}
```
### Debugging SOAP requests
The client records the raw SOAP XML when `trace` is enabled (the default):
```php
$response = $client->insertRequest($request);
// Inspect the XML that was sent and received.
echo $client->getLastRequest();
echo $client->getLastResponse();
```
## API Reference
### `RapidIllClient`
| Constructor Parameter | Type | Required | Description |
|---|---|---|---|
| `username` | string | yes | RapidILL API username |
| `password` | string | yes | RapidILL API password |
| `rapidCode` | string | yes | Your library's Rapid code |
| `branchName` | string | yes | Your library branch name |
| `wsdlUrl` | string | no | Override the default WSDL URL |
| `soapOptions` | array | no | Additional options passed to `SoapClient` |
### `InsertRequest`
All setters return `$this` for fluent chaining.
| Method | Description |
|---|---|
| `setRequestType(RequestType)` | `Article`, `Book`, or `BookChapter` (default: `Article`) |
| `setHoldingsCheckOnly(bool)` | If true, only checks holdings without submitting |
| `setBlockLocalOnly(bool)` | Block request if only local holdings exist |
| `setInsertLocalHolding(bool)` | Insert a local holding record |
| `addIssn(string)` | Add an ISSN |
| `setIssns(array)` | Set all ISSNs at once |
| `addIsbn(string)` | Add an ISBN |
| `setIsbns(array)` | Set all ISBNs at once |
| `addLccn(string)` | Add an LCCN |
| `setLccns(array)` | Set all LCCNs at once |
| `setOclcNumber(string)` | OCLC number |
| `setJournalTitle(string)` | Journal or book title |
| `setJournalYear(string)` | Publication year |
| `setJournalVolume(string)` | Volume number |
| `setJournalIssue(string)` | Issue number |
| `setJournalMonth(string)` | Publication month |
| `setArticleTitle(string)` | Article or chapter title |
| `setArticleAuthor(string)` | Author name |
| `setArticlePages(string)` | Page range |
| `setEdition(string)` | Edition |
| `setPublisher(string)` | Publisher |
| `setPatronId(string)` | Patron identifier |
| `setPatronName(string)` | Patron full name |
| `setPatronDepartment(string)` | Patron department |
| `setPatronEmail(string)` | Patron email address |
| `setPatronPhone(string)` | Patron phone number |
| `setPatronNotes(string)` | Additional notes |
| `setXrefRequestId(string)` | Cross-reference ID from your ILL system |
### `InsertResponse`
All properties are `readonly`.
| Property | Type | Description |
|---|---|---|
| `isSuccessful` | bool | Whether the API call succeeded |
| `foundMatch` | bool | Whether a lending match was found |
| `rapidRequestId` | int | The assigned Rapid request ID |
| `numberOfAvailableHoldings` | int | Count of available holdings |
| `isLocalHolding` | bool | Whether the item is held locally |
| `verificationNote` | ?string | Error or informational message |
| `matchingStandardNumber` | ?string | The matched ISSN/ISBN |
| `matchingStandardNumberType` | ?string | Type of the matched number |
| `duplicateRequestId` | ?string | ID if request is a duplicate |
| `localHoldings` | array | Array of local holding records |
### `RequestType` (enum)
- `RequestType::Article`
- `RequestType::Book`
- `RequestType::BookChapter`
## Testing
```bash
composer install
vendor/bin/phpunit
```
## License
GPL-2.0-or-later

24
composer.json

@ -0,0 +1,24 @@
{
"name": "rapidill/request",
"description": "PHP library for creating InterLibrary Loan requests via the RapidILL API",
"type": "library",
"license": "GPL-2.0-or-later",
"minimum-stability": "stable",
"require": {
"php": ">=8.1",
"ext-soap": "*"
},
"require-dev": {
"phpunit/phpunit": "^10.0"
},
"autoload": {
"psr-4": {
"RapidIll\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"RapidIll\\Tests\\": "tests/"
}
}
}

11
phpunit.xml

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.0/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>
</phpunit>

266
src/InsertRequest.php

@ -0,0 +1,266 @@
<?php
namespace RapidIll;
/**
* Represents the data for a RapidILL InsertRequest API call.
*
* Build a request using the fluent setter methods, then pass it to
* RapidIllClient::insertRequest().
*/
class InsertRequest
{
private RequestType $requestType = RequestType::Article;
private bool $holdingsCheckOnly = false;
private bool $blockLocalOnly = false;
private bool $insertLocalHolding = false;
// Identifiers.
private array $issns = [];
private array $isbns = [];
private array $lccns = [];
private ?string $oclcNumber = null;
// Bibliographic fields.
private ?string $journalTitle = null;
private ?string $journalYear = null;
private ?string $journalVolume = null;
private ?string $journalIssue = null;
private ?string $journalMonth = null;
private ?string $articleTitle = null;
private ?string $articleAuthor = null;
private ?string $articlePages = null;
private ?string $edition = null;
private ?string $publisher = null;
// Patron fields.
private ?string $patronId = null;
private ?string $patronName = null;
private ?string $patronDepartment = null;
private ?string $patronEmail = null;
private ?string $patronPhone = null;
private ?string $patronNotes = null;
// Cross-reference.
private ?string $xrefRequestId = null;
public function setRequestType(RequestType $type): static
{
$this->requestType = $type;
return $this;
}
public function setHoldingsCheckOnly(bool $value): static
{
$this->holdingsCheckOnly = $value;
return $this;
}
public function setBlockLocalOnly(bool $value): static
{
$this->blockLocalOnly = $value;
return $this;
}
public function setInsertLocalHolding(bool $value): static
{
$this->insertLocalHolding = $value;
return $this;
}
public function addIssn(string $issn): static
{
$this->issns[] = $issn;
return $this;
}
public function setIssns(array $issns): static
{
$this->issns = $issns;
return $this;
}
public function addIsbn(string $isbn): static
{
$this->isbns[] = $isbn;
return $this;
}
public function setIsbns(array $isbns): static
{
$this->isbns = $isbns;
return $this;
}
public function addLccn(string $lccn): static
{
$this->lccns[] = $lccn;
return $this;
}
public function setLccns(array $lccns): static
{
$this->lccns = $lccns;
return $this;
}
public function setOclcNumber(string $number): static
{
$this->oclcNumber = $number;
return $this;
}
public function setJournalTitle(string $title): static
{
$this->journalTitle = $title;
return $this;
}
public function setJournalYear(string $year): static
{
$this->journalYear = $year;
return $this;
}
public function setJournalVolume(string $volume): static
{
$this->journalVolume = $volume;
return $this;
}
public function setJournalIssue(string $issue): static
{
$this->journalIssue = $issue;
return $this;
}
public function setJournalMonth(string $month): static
{
$this->journalMonth = $month;
return $this;
}
public function setArticleTitle(string $title): static
{
$this->articleTitle = $title;
return $this;
}
public function setArticleAuthor(string $author): static
{
$this->articleAuthor = $author;
return $this;
}
public function setArticlePages(string $pages): static
{
$this->articlePages = $pages;
return $this;
}
public function setEdition(string $edition): static
{
$this->edition = $edition;
return $this;
}
public function setPublisher(string $publisher): static
{
$this->publisher = $publisher;
return $this;
}
public function setPatronId(string $id): static
{
$this->patronId = $id;
return $this;
}
public function setPatronName(string $name): static
{
$this->patronName = $name;
return $this;
}
public function setPatronDepartment(string $department): static
{
$this->patronDepartment = $department;
return $this;
}
public function setPatronEmail(string $email): static
{
$this->patronEmail = $email;
return $this;
}
public function setPatronPhone(string $phone): static
{
$this->patronPhone = $phone;
return $this;
}
public function setPatronNotes(string $notes): static
{
$this->patronNotes = $notes;
return $this;
}
public function setXrefRequestId(string $id): static
{
$this->xrefRequestId = $id;
return $this;
}
/**
* Convert to the array structure expected by the SOAP client.
*/
public function toSoapArray(): array
{
$data = [
'RapidRequestType' => $this->requestType->value,
'IsHoldingsCheckOnly' => $this->holdingsCheckOnly,
'DoBlockLocalOnly' => $this->blockLocalOnly,
'DoInsertLocalHolding' => $this->insertLocalHolding,
];
if ($this->issns) {
$data['SuggestedIssns'] = ['string' => $this->issns];
}
if ($this->isbns) {
$data['SuggestedIsbns'] = ['string' => $this->isbns];
}
if ($this->lccns) {
$data['SuggestedLccns'] = ['string' => $this->lccns];
}
$optional = [
'OclcNumber' => $this->oclcNumber,
'PatronJournalTitle' => $this->journalTitle,
'PatronJournalYear' => $this->journalYear,
'JournalVol' => $this->journalVolume,
'JournalIssue' => $this->journalIssue,
'JournalMonth' => $this->journalMonth,
'ArticleTitle' => $this->articleTitle,
'ArticleAuthor' => $this->articleAuthor,
'ArticlePages' => $this->articlePages,
'Edition' => $this->edition,
'Publisher' => $this->publisher,
'PatronId' => $this->patronId,
'PatronName' => $this->patronName,
'PatronDepartment' => $this->patronDepartment,
'PatronEmail' => $this->patronEmail,
'PatronPhone' => $this->patronPhone,
'PatronNotes' => $this->patronNotes,
'XRefRequestId' => $this->xrefRequestId,
];
foreach ($optional as $key => $value) {
if ($value !== null) {
$data[$key] = $value;
}
}
return $data;
}
}

61
src/InsertResponse.php

@ -0,0 +1,61 @@
<?php
namespace RapidIll;
/**
* Represents the response from a RapidILL InsertRequest API call.
*/
class InsertResponse
{
public function __construct(
public readonly bool $isSuccessful,
public readonly bool $foundMatch,
public readonly int $rapidRequestId,
public readonly int $numberOfAvailableHoldings,
public readonly bool $isLocalHolding,
public readonly ?string $verificationNote = null,
public readonly ?string $matchingStandardNumber = null,
public readonly ?string $matchingStandardNumberType = null,
public readonly ?string $duplicateRequestId = null,
public readonly array $localHoldings = [],
) {
}
/**
* Build an InsertResponse from the raw SOAP response object.
*/
public static function fromSoapResponse(object $result): static
{
$r = $result->InsertRequestResult;
$holdings = [];
if (isset($r->LocalHoldings->LocalHoldingItem)) {
$items = $r->LocalHoldings->LocalHoldingItem;
// Normalize single item to array.
if (!is_array($items)) {
$items = [$items];
}
foreach ($items as $item) {
$holdings[] = [
'branchName' => $item->BranchName ?? null,
'location' => $item->LibLocation ?? null,
'callNumber' => $item->CallNumber ?? null,
'redirectUrl' => $item->RapidRedirectUrl ?? null,
];
}
}
return new static(
isSuccessful: (bool) ($r->IsSuccessful ?? false),
foundMatch: (bool) ($r->FoundMatch ?? false),
rapidRequestId: (int) ($r->RapidRequestId ?? 0),
numberOfAvailableHoldings: (int) ($r->NumberOfAvailableHoldings ?? 0),
isLocalHolding: (bool) ($r->IsLocalHolding ?? false),
verificationNote: $r->VerificationNote ?? null,
matchingStandardNumber: $r->MatchingStandardNumber ?? null,
matchingStandardNumberType: $r->MatchingStandardNumberType ?? null,
duplicateRequestId: $r->DuplicateRequestId ?? null,
localHoldings: $holdings,
);
}
}

123
src/RapidIllClient.php

@ -0,0 +1,123 @@
<?php
namespace RapidIll;
/**
* Client for the RapidILL SOAP API.
*
* Usage:
* $client = new RapidIllClient(
* username: 'user',
* password: 'pass',
* rapidCode: 'YOUR_CODE',
* branchName: 'Main',
* );
*
* $request = (new InsertRequest())
* ->setRequestType(RequestType::Article)
* ->setJournalTitle('Nature')
* ->setArticleTitle('Example Article')
* ->setArticleAuthor('Smith, J.')
* ->addIssn('0028-0836');
*
* $response = $client->insertRequest($request);
*/
class RapidIllClient
{
private const WSDL_URL = 'https://rapid.exlibrisgroup.com/rapid5api/apiservice.asmx?wsdl';
private ?\SoapClient $soapClient = null;
public function __construct(
private readonly string $username,
private readonly string $password,
private readonly string $rapidCode,
private readonly string $branchName,
private readonly ?string $wsdlUrl = null,
private readonly array $soapOptions = [],
) {
}
/**
* Submit an ILL request to RapidILL.
*
* @throws RapidIllException
*/
public function insertRequest(InsertRequest $request): InsertResponse
{
$params = $request->toSoapArray();
// Merge authentication fields.
$params['UserName'] = $this->username;
$params['Password'] = $this->password;
$params['RequestingRapidCode'] = $this->rapidCode;
$params['RequestingBranchName'] = $this->branchName;
try {
$result = $this->getSoapClient()->InsertRequest(['req' => $params]);
return InsertResponse::fromSoapResponse($result);
} catch (\SoapFault $e) {
throw new RapidIllException(
'RapidILL API error: ' . $e->getMessage(),
(int) $e->getCode(),
$e,
);
}
}
/**
* Get or create the SOAP client instance.
*
* @throws RapidIllException
*/
private function getSoapClient(): \SoapClient
{
if ($this->soapClient !== null) {
return $this->soapClient;
}
$wsdl = $this->wsdlUrl ?? self::WSDL_URL;
$options = array_merge([
'trace' => true,
'exceptions' => true,
'cache_wsdl' => WSDL_CACHE_BOTH,
], $this->soapOptions);
try {
$this->soapClient = new \SoapClient($wsdl, $options);
} catch (\SoapFault $e) {
throw new RapidIllException(
'Failed to initialize RapidILL SOAP client: ' . $e->getMessage(),
(int) $e->getCode(),
$e,
);
}
return $this->soapClient;
}
/**
* Replace the SOAP client (useful for testing).
*/
public function setSoapClient(\SoapClient $client): void
{
$this->soapClient = $client;
}
/**
* Get the last SOAP request XML (requires trace=true).
*/
public function getLastRequest(): ?string
{
return $this->soapClient?->__getLastRequest();
}
/**
* Get the last SOAP response XML (requires trace=true).
*/
public function getLastResponse(): ?string
{
return $this->soapClient?->__getLastResponse();
}
}

7
src/RapidIllException.php

@ -0,0 +1,7 @@
<?php
namespace RapidIll;
class RapidIllException extends \RuntimeException
{
}

13
src/RequestType.php

@ -0,0 +1,13 @@
<?php
namespace RapidIll;
/**
* RapidILL request types.
*/
enum RequestType: string
{
case Article = 'Article';
case Book = 'Book';
case BookChapter = 'BookChapter';
}

160
tests/RapidIllClientTest.php

@ -0,0 +1,160 @@
<?php
namespace RapidIll\Tests;
use PHPUnit\Framework\TestCase;
use RapidIll\InsertRequest;
use RapidIll\InsertResponse;
use RapidIll\RapidIllClient;
use RapidIll\RapidIllException;
use RapidIll\RequestType;
class RapidIllClientTest extends TestCase
{
public function testInsertRequestBuildsCorrectSoapArray(): void
{
$request = (new InsertRequest())
->setRequestType(RequestType::Article)
->setJournalTitle('Nature')
->setJournalYear('2024')
->setJournalVolume('625')
->setJournalIssue('7994')
->setArticleTitle('A breakthrough in quantum computing')
->setArticleAuthor('Smith, J.')
->setArticlePages('100-105')
->addIssn('0028-0836')
->setPatronName('Jane Doe')
->setPatronEmail('jane@example.edu');
$data = $request->toSoapArray();
$this->assertSame('Article', $data['RapidRequestType']);
$this->assertFalse($data['IsHoldingsCheckOnly']);
$this->assertSame('Nature', $data['PatronJournalTitle']);
$this->assertSame('2024', $data['PatronJournalYear']);
$this->assertSame('625', $data['JournalVol']);
$this->assertSame('7994', $data['JournalIssue']);
$this->assertSame('A breakthrough in quantum computing', $data['ArticleTitle']);
$this->assertSame('Smith, J.', $data['ArticleAuthor']);
$this->assertSame('100-105', $data['ArticlePages']);
$this->assertSame(['string' => ['0028-0836']], $data['SuggestedIssns']);
$this->assertSame('Jane Doe', $data['PatronName']);
$this->assertSame('jane@example.edu', $data['PatronEmail']);
}
public function testInsertRequestOmitsNullFields(): void
{
$request = (new InsertRequest())
->setJournalTitle('Science');
$data = $request->toSoapArray();
$this->assertArrayHasKey('PatronJournalTitle', $data);
$this->assertArrayNotHasKey('ArticleTitle', $data);
$this->assertArrayNotHasKey('PatronEmail', $data);
$this->assertArrayNotHasKey('SuggestedIssns', $data);
}
public function testInsertRequestMultipleIdentifiers(): void
{
$request = (new InsertRequest())
->addIssn('0028-0836')
->addIssn('1476-4687')
->addIsbn('978-0-123456-78-9')
->setOclcNumber('12345678');
$data = $request->toSoapArray();
$this->assertSame(['string' => ['0028-0836', '1476-4687']], $data['SuggestedIssns']);
$this->assertSame(['string' => ['978-0-123456-78-9']], $data['SuggestedIsbns']);
$this->assertSame('12345678', $data['OclcNumber']);
}
public function testInsertResponseFromSoapResponse(): void
{
$soapResult = (object) [
'InsertRequestResult' => (object) [
'IsSuccessful' => true,
'FoundMatch' => true,
'RapidRequestId' => 99999,
'NumberOfAvailableHoldings' => 3,
'IsLocalHolding' => false,
'VerificationNote' => null,
'MatchingStandardNumber' => '0028-0836',
'MatchingStandardNumberType' => 'ISSN',
],
];
$response = InsertResponse::fromSoapResponse($soapResult);
$this->assertTrue($response->isSuccessful);
$this->assertTrue($response->foundMatch);
$this->assertSame(99999, $response->rapidRequestId);
$this->assertSame(3, $response->numberOfAvailableHoldings);
$this->assertFalse($response->isLocalHolding);
$this->assertSame('0028-0836', $response->matchingStandardNumber);
$this->assertSame('ISSN', $response->matchingStandardNumberType);
}
public function testInsertResponseWithLocalHoldings(): void
{
$soapResult = (object) [
'InsertRequestResult' => (object) [
'IsSuccessful' => true,
'FoundMatch' => true,
'RapidRequestId' => 12345,
'NumberOfAvailableHoldings' => 1,
'IsLocalHolding' => true,
'LocalHoldings' => (object) [
'LocalHoldingItem' => (object) [
'BranchName' => 'Main Library',
'LibLocation' => 'Stacks',
'CallNumber' => 'Q1 .N2',
'RapidRedirectUrl' => 'https://example.com/redirect',
],
],
],
];
$response = InsertResponse::fromSoapResponse($soapResult);
$this->assertTrue($response->isLocalHolding);
$this->assertCount(1, $response->localHoldings);
$this->assertSame('Main Library', $response->localHoldings[0]['branchName']);
$this->assertSame('Q1 .N2', $response->localHoldings[0]['callNumber']);
}
public function testClientWrapsSOAPFaultInException(): void
{
$mockSoap = $this->createMock(\SoapClient::class);
$mockSoap->method('__call')
->willThrowException(new \SoapFault('Server', 'Authentication failed'));
$client = new RapidIllClient('user', 'pass', 'CODE', 'Main');
$client->setSoapClient($mockSoap);
$this->expectException(RapidIllException::class);
$this->expectExceptionMessage('RapidILL API error: Authentication failed');
$client->insertRequest(new InsertRequest());
}
public function testBookRequest(): void
{
$request = (new InsertRequest())
->setRequestType(RequestType::Book)
->setJournalTitle('Introduction to Algorithms')
->addIsbn('978-0262033848')
->setArticleAuthor('Cormen, T.H.')
->setPublisher('MIT Press')
->setEdition('3rd')
->setPatronName('John Smith');
$data = $request->toSoapArray();
$this->assertSame('Book', $data['RapidRequestType']);
$this->assertSame('Introduction to Algorithms', $data['PatronJournalTitle']);
$this->assertSame('MIT Press', $data['Publisher']);
$this->assertSame('3rd', $data['Edition']);
}
}
Loading…
Cancel
Save