diff --git a/config/vufind/Demo.ini b/config/vufind/Demo.ini index 072695824ce..2796aaa59b9 100644 --- a/config/vufind/Demo.ini +++ b/config/vufind/Demo.ini @@ -53,6 +53,16 @@ services[] = 'custom' ; driver. ;historicTransactions = '[{"id":"1234", ... "dueDate": "01/01/2017"}]'; +; This setting can be used to create fake fines for specific records. +; The value is a JSON document representing the fine information returned by the +; driver. +;fines = '[{"amount": 123, "checkout": "2024-12-01", "createdate": "2024-12-19", "description": "Overdue fee", "id":"1234", "title": "Record"}]'; + +; This setting can be used to create fake holds for specific records. +; The value is a JSON document representing the hold information returned by the +; driver. +;holds = '[{"reqnum": 1, "location": "Main Library", "create": "2024-12-01", "expire": "2025-12-01", "available": false, "id":"1234", "title": "Record"}]'; + ; This setting can be used to flag specific records as recently returned; if ; commented out, a random set of IDs will be selected. ;recently_returned[] = myBibId001 diff --git a/module/VuFind/src/VuFind/ILS/Driver/Demo.php b/module/VuFind/src/VuFind/ILS/Driver/Demo.php index 6776841e0e7..03f60dd81ad 100644 --- a/module/VuFind/src/VuFind/ILS/Driver/Demo.php +++ b/module/VuFind/src/VuFind/ILS/Driver/Demo.php @@ -570,6 +570,11 @@ protected function getRandomItemIdentifier() */ protected function createRequestList($requestType) { + $key = strtolower($requestType); + if ($records = $this->config['Records'][$key] ?? null) { + return json_decode($records, true); + } + // How many items are there? %10 - 1 = 10% chance of none, // 90% of 1-9 (give or take some odd maths) $items = rand() % 10 - 1; @@ -1053,6 +1058,64 @@ public function getMyProfile($patron) return $patron; } + /** + * Generate random fines + * + * @return array + */ + protected function getRandomFines(): array + { + // How many items are there? %20 - 2 = 10% chance of none, + // 90% of 1-18 (give or take some odd maths) + $fines = rand() % 20 - 2; + + $fineList = []; + for ($i = 0; $i < $fines; $i++) { + // How many days overdue is the item? + $day_overdue = rand() % 30 + 5; + // Calculate checkout date: + $checkout = strtotime('now - ' . ($day_overdue + 14) . ' days'); + // 1 in 10 chance of this being a "Manual Fee": + if (rand(1, 10) === 1) { + $fine = 2.50; + $type = 'Manual Fee'; + } else { + // 50c a day fine + $fine = $day_overdue * 0.50; + // After 20 days it becomes 'Long Overdue' + $type = $day_overdue > 20 ? 'Long Overdue' : 'Overdue'; + } + + $fineList[] = [ + 'amount' => $fine * 100, + 'checkout' => $this->dateConverter + ->convertToDisplayDate('U', $checkout), + 'createdate' => $this->dateConverter + ->convertToDisplayDate('U', time()), + 'fine' => $type, + // Additional description for long overdue fines: + 'description' => 'Manual Fee' === $type ? 'Interlibrary loan request fee' : '', + // 50% chance they've paid half of it + 'balance' => (rand() % 100 > 49 ? $fine / 2 : $fine) * 100, + 'duedate' => $this->dateConverter->convertToDisplayDate( + 'U', + strtotime("now - $day_overdue days") + ), + ]; + // Some fines will have no id or title: + if (rand() % 3 != 1) { + if ($this->idsInMyResearch) { + [$fineList[$i]['id'], $fineList[$i]['title']] + = $this->getRandomBibIdAndTitle(); + $fineList[$i]['source'] = $this->getRecordSource(); + } else { + $fineList[$i]['title'] = 'Demo Title ' . $i; + } + } + } + return $fineList; + } + /** * Get Patron Fines * @@ -1069,55 +1132,9 @@ public function getMyFines($patron) $this->checkIntermittentFailure(); $session = $this->getSession($patron['id'] ?? null); if (!isset($session->fines)) { - // How many items are there? %20 - 2 = 10% chance of none, - // 90% of 1-18 (give or take some odd maths) - $fines = rand() % 20 - 2; - - $fineList = []; - for ($i = 0; $i < $fines; $i++) { - // How many days overdue is the item? - $day_overdue = rand() % 30 + 5; - // Calculate checkout date: - $checkout = strtotime('now - ' . ($day_overdue + 14) . ' days'); - // 1 in 10 chance of this being a "Manual Fee": - if (rand(1, 10) === 1) { - $fine = 2.50; - $type = 'Manual Fee'; - } else { - // 50c a day fine - $fine = $day_overdue * 0.50; - // After 20 days it becomes 'Long Overdue' - $type = $day_overdue > 20 ? 'Long Overdue' : 'Overdue'; - } - - $fineList[] = [ - 'amount' => $fine * 100, - 'checkout' => $this->dateConverter - ->convertToDisplayDate('U', $checkout), - 'createdate' => $this->dateConverter - ->convertToDisplayDate('U', time()), - 'fine' => $type, - // Additional description for long overdue fines: - 'description' => 'Manual Fee' === $type ? 'Interlibrary loan request fee' : '', - // 50% chance they've paid half of it - 'balance' => (rand() % 100 > 49 ? $fine / 2 : $fine) * 100, - 'duedate' => $this->dateConverter->convertToDisplayDate( - 'U', - strtotime("now - $day_overdue days") - ), - ]; - // Some fines will have no id or title: - if (rand() % 3 != 1) { - if ($this->idsInMyResearch) { - [$fineList[$i]['id'], $fineList[$i]['title']] - = $this->getRandomBibIdAndTitle(); - $fineList[$i]['source'] = $this->getRecordSource(); - } else { - $fineList[$i]['title'] = 'Demo Title ' . $i; - } - } - } - $session->fines = $fineList; + $session->fines = ($records = $this->config['Records']['fines'] ?? null) + ? json_decode($records, true) + : $this->getRandomFines(); } return $session->fines; } diff --git a/module/VuFind/src/VuFindTest/Feature/DemoDriverTestTrait.php b/module/VuFind/src/VuFindTest/Feature/DemoDriverTestTrait.php index 4c024a76de4..614e05b92d1 100644 --- a/module/VuFind/src/VuFindTest/Feature/DemoDriverTestTrait.php +++ b/module/VuFind/src/VuFindTest/Feature/DemoDriverTestTrait.php @@ -120,6 +120,106 @@ protected function getFakeHistoricTransactions($bibId, $bibId2) ); } + /** + * Get fine JSON for Demo.ini. + * + * @param string $bibId Bibliographic record ID to create fake item info for. + * + * @return array + */ + protected function getFakeFines(string $bibId) + { + $checkoutDate = strtotime('now -30 days'); + $returnDate = strtotime('now -2 days'); + $dueDate = strtotime('now -5 days'); + return json_encode([ + [ + 'amount' => 123, + 'balance' => 123, + 'checkout' => date('Y-m-d', $checkoutDate), + 'createdate' => date('Y-m-d', $returnDate), + 'duedate' => date('Y-m-d', $dueDate), + 'description' => 'Overdue fee', + 'id' => $bibId, + ], + ]); + } + + /** + * Get hold JSON for Demo.ini. + * + * @param string $bibId Bibliographic record ID to create fake item info for. + * @param string $bibId2 Second bibliographic record ID to create fake item info for. + * + * @return array + */ + protected function getFakeHolds(string $bibId, string $bibId2) + { + $createDate = strtotime('now -30 days'); + $expireDate = strtotime('now +1 year'); + return json_encode([ + [ + 'reqnum' => 1, + 'location' => 'Main Library', + 'create' => date('Y-m-d', $createDate), + 'expire' => date('Y-m-d', $expireDate), + 'id' => $bibId, + 'available' => true, + 'in_transit' => false, + ], + [ + 'reqnum' => 2, + 'item_id' => 1, + 'location' => 'Main Library', + 'create' => date('Y-m-d', $createDate), + 'expire' => date('Y-m-d', $expireDate), + 'id' => $bibId2, + 'available' => false, + 'in_transit' => true, + ], + [ + 'reqnum' => 3, + 'item_id' => 3, + 'location' => 'Main Library', + 'create' => date('Y-m-d', $createDate), + 'expire' => date('Y-m-d', $expireDate), + 'id' => $bibId2, + 'available' => false, + 'in_transit' => true, + ], + [ + 'reqnum' => 4, + 'item_id' => 7, + 'location' => 'Main Library', + 'create' => date('Y-m-d', $createDate), + 'expire' => date('Y-m-d', $expireDate), + 'id' => $bibId2, + 'available' => false, + 'in_transit' => false, + ], + [ + 'reqnum' => 5, + 'item_id' => 17, + 'location' => 'Main Library', + 'create' => date('Y-m-d', $createDate), + 'expire' => date('Y-m-d', $expireDate), + 'id' => $bibId2, + 'available' => false, + 'in_transit' => false, + ], + [ + 'reqnum' => 6, + 'item_id' => 27, + 'location' => 'Main Library', + 'create' => date('Y-m-d', $createDate), + 'expire' => date('Y-m-d', $expireDate), + 'id' => $bibId2, + 'available' => false, + 'in_transit' => false, + ], + ]); + } + /** * Get Demo.ini override settings for testing ILS functions. * @@ -136,8 +236,9 @@ protected function getDemoIniOverrides( return [ 'Records' => [ 'transactions' => $this->getFakeTransactions($bibId), - 'historicTransactions' - => $this->getFakeHistoricTransactions($bibId, $bibId2), + 'historicTransactions' => $this->getFakeHistoricTransactions($bibId, $bibId2), + 'fines' => $this->getFakeFines($bibId), + 'holds' => $this->getFakeHolds($bibId, $bibId2), ], 'Failure_Probabilities' => [ 'cancelHolds' => 0, diff --git a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php index 9c381e2e139..9dd99e94668 100644 --- a/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php +++ b/module/VuFind/tests/integration-tests/src/VuFindTest/Mink/AccountMenuTest.php @@ -29,6 +29,8 @@ namespace VuFindTest\Mink; +use function count; + /** * Mink account ajax menu test class. * @@ -56,30 +58,6 @@ public static function setUpBeforeClass(): void static::failIfDataExists(); } - /** - * Standard setup + login - * - * @return void - */ - public function setUp(): void - { - parent::setUp(); - - // Setup config - $this->changeConfigs( - [ - 'Demo' => $this->getDemoIniOverrides(), - 'config' => [ - 'Catalog' => ['driver' => 'Demo'], - 'Authentication' => [ - 'enableAjax' => true, - 'enableDropdown' => false, - ], - ], - ] - ); - } - /** * Create a specific state in the account ajax storage. * @@ -136,113 +114,73 @@ protected function setUpFinesEnvironment() } /** - * Test that the menu is absent when enableAjax is true and enableDropdown - * is false. + * Data provider for menu configuration tests * - * @return void + * @return array */ - public function testMenuOffAjaxNoDropdown() + public static function menuConfigurationProvider(): array { - // Create user - $session = $this->getMinkSession(); - $session->visit($this->getVuFindUrl()); - $page = $session->getPage(); - $this->clickCss($page, '#loginOptions a'); - $this->clickCss($page, '.modal-body .createAccountLink'); - $this->fillInAccountForm($page); - $this->clickCss($page, '.modal-body .btn.btn-primary'); - $this->waitForPageLoad($page); - - // Seed some fines - $page = $this->setUpFinesEnvironment(); - $menu = $page->findAll('css', '#login-dropdown'); - $this->assertCount(0, $menu); - $stati = $page->findAll('css', '.account-menu .fines-status.hidden'); - $this->assertCount(0, $stati); + return [ + 'no ajax, no dropdown' => [ + false, + false, + 0, + ], + 'ajax, no dropdown' => [ + true, + false, + 1, + ], + 'no ajax, dropdown' => [ + false, + true, + 0, + ], + 'ajax, dropdown' => [ + true, + true, + 2, + ], + ]; } /** - * Test that the menu is absent when enableAjax is false and enableDropdown - * is false. - * - * @depends testMenuOffAjaxNoDropdown + * Test the menu configuration. * - * @return void - */ - public function testMenuOffNoAjaxNoDropdown() - { - // Nothing on - $this->changeConfigs( - [ - 'config' => [ - 'Authentication' => [ - 'enableAjax' => false, - 'enableDropdown' => false, - ], - ], - ] - ); - $this->login(); - $page = $this->setUpFinesEnvironment(); - $menu = $page->findAll('css', '#login-dropdown'); - $this->assertCount(0, $menu); - $stati = $page->findAll('css', '.account-menu .fines-status.hidden'); - $this->assertCount(1, $stati); - } - - /** - * Test that the menu is absent when enableAjax is false and enableDropdown - * is true. + * @param bool $ajax Enable account ajax? + * @param bool $dropdown Enable navbar dropdown menu? + * @param int $expectedStatusCount How many instances of status badge to expect * - * @depends testMenuOffAjaxNoDropdown + * @dataProvider menuConfigurationProvider * * @return void */ - public function testMenuOffNoAjaxDropdown() + public function testMenuConfiguration(bool $ajax, bool $dropdown, int $expectedStatusCount) { $this->changeConfigs( [ + 'Demo' => $this->getDemoIniOverrides(), 'config' => [ + 'Catalog' => ['driver' => 'Demo'], 'Authentication' => [ - 'enableAjax' => false, - 'enableDropdown' => true, + 'method' => 'ILS', + 'enableAjax' => $ajax, + 'enableDropdown' => $dropdown, ], ], ] ); - $this->login(); - $page = $this->setUpFinesEnvironment(); - $menu = $page->findAll('css', '#login-dropdown'); - $this->assertCount(1, $menu); - $stati = $page->findAll('css', '.account-menu .fines-status.hidden'); - $this->assertCount(2, $stati); // one in menu, one in dropdown - } - /** - * Test that the menu is absent when enableAjax is true and enableDropdown - * is true. - * - * @depends testMenuOffAjaxNoDropdown - * - * @return void - */ - public function testMenuOffAjaxDropdown() - { - $this->changeConfigs( - [ - 'config' => [ - 'Authentication' => [ - 'enableAjax' => true, - 'enableDropdown' => true, - ], - ], - ] - ); - $this->login(); - $page = $this->setUpFinesEnvironment(); + $page = $this->login('catuser', 'catpass')->getPage(); $menu = $page->findAll('css', '#login-dropdown'); - $this->assertCount(1, $menu); - $this->unFindCss($page, '.account-menu .fines-status.hidden'); + $this->assertCount($dropdown ? 1 : 0, $menu); + $this->findCss($page, '.account-menu .fines'); + $this->assertEqualsWithTimeout( + $expectedStatusCount, + function () use ($page) { + return count($page->findAll('css', '.account-menu .fines-status')); + } + ); } /** @@ -275,36 +213,108 @@ public function testIndividualCacheClearing() */ public function testGlobalCacheClearing() { - $session = $this->login(); - // Seed some fines - $this->setJSStorage(['fines' => ['value' => 30.5, 'display' => '$30.50']]); + $session = $this->getMinkSession(); + $session->visit($this->getVuFindUrl()); + $page = $session->getPage(); + + // This needs a valid list of caches, so create a user without ILS access: + $this->clickCss($page, '#loginOptions a'); + $this->clickCss($page, '.modal-body .createAccountLink'); + $this->fillInAccountForm($page); + $this->clickCss($page, '.modal-body .btn.btn-primary'); + $this->waitForPageLoad($page); + + $page = $this->setUpFinesEnvironment(); $storage = $this->getJSStorage(); $this->assertNotNull($storage['fines']); // Clear all cache $session->evaluateScript('VuFind.account.clearCache();'); // Wait for reload - $this->waitForPageLoad($this->getMinkSession()->getPage()); + $this->waitForPageLoad($page); $storage = $this->getJSStorage(); // Status code MISSING is -2 * Math.PI, but we just round it here to avoid trouble $this->assertEquals(-6, ceil($storage['fines'])); } /** - * Utility class to login + * Data provider for testAccountIcon * - * @return \Behat\Mink\Session + * @return array */ - protected function login() + public static function accountIconProvider(): array { - $session = $this->getMinkSession(); - $session->visit($this->getVuFindUrl()); - $page = $session->getPage(); - $this->clickCss($page, '#loginOptions a'); - $this->waitForPageLoad($page); - $this->fillInLoginForm($page, 'username1', 'test'); - $this->clickCss($page, '.modal-body .btn.btn-primary'); - $this->waitForPageLoad($page); - return $session; + return [ + 'no icon' => [ + [ + // No fines + ['fines' => ['total' => 0, 'display' => 'ZILTCH']], + // Holds in transit only + ['holds' => ['in_transit' => 1, 'available' => 0, 'other' => 0]], + // ILL Requests in transit only + ['illRequests' => ['in_transit' => 1, 'available' => 0, 'other' => 0]], + // Storage Retrievals in transit only + ['storageRetrievalRequests' => ['in_transit' => 1, 'available' => 0, 'other' => 0]], + ], + '.account-status-none', + ], + 'good' => [ + [ + // Holds available + ['holds' => ['in_transit' => 0, 'available' => 1, 'level' => 1]], + // ILL Requests available + ['illRequests' => ['in_transit' => 0, 'available' => 1, 'level' => 1]], + // Storage Retrievals available + ['storageRetrievalRequests' => ['in_transit' => 0, 'available' => 1, 'level' => 1]], + ], + '.account-status-good', + ], + 'warning' => [ + [ + ['checkedOut' => ['warn' => 1, 'level' => 2]], + ], + '.account-status-warning', + ], + 'danger' => [ + [ + // User has fines + ['fines' => ['value' => 1000000, 'display' => '$...yikes', 'level' => 3]], + // Checkedout overdue + ['checkedOut' => ['overdue' => 1, 'level' => 3]], + ], + '.account-status-danger', + ], + 'danger overrides warning' => [ + [['checkedOut' => ['warn' => 2, 'overdue' => 1, 'level' => 3]]], + '.account-status-danger', + ], + 'danger overrides good' => [ + [ + [ + 'checkedOut' => ['overdue' => 1, 'level' => 3], + 'holds' => ['available' => 1, 'level' => 1], + ], + ], + '.account-status-danger', + ], + 'warning overrides good' => [ + [ + [ + 'checkedOut' => ['warn' => 1, 'level' => 2], + 'holds' => ['available' => 1, 'level' => 1], + ], + ], + '.account-status-warning', + ], + 'good overrides none' => [ + [ + [ + 'holds' => ['available' => 1, 'level' => 1], + 'fines' => ['total' => 0, 'display' => 'none', 'level' => 0], + ], + ], + '.account-status-good', + ], + ]; } /** @@ -313,173 +323,203 @@ protected function login() * @param array $storage Array of storage values to test * @param string $checkClass Icon class to check * + * @dataProvider accountIconProvider + * * @return void */ - protected function checkIcon($storage, $checkClass) + public function testAccountIcon(array $storage, string $checkClass): void { - $session = $this->getMinkSession(); - $session->visit($this->getVuFindUrl()); + $this->changeConfigs( + [ + 'config' => [ + 'Authentication' => [ + 'enableAjax' => true, + ], + 'Catalog' => ['driver' => 'Demo'], + ], + ] + ); + $session = $this->login(); foreach ($storage as $item) { $this->setJSStorage($item); $session->reload(); $page = $session->getPage(); - $this->waitForPageLoad($page); $this->findCss($page, '#account-icon ' . $checkClass); - foreach ($item as $key => $value) { + foreach (array_keys($item) as $key) { $session->evaluateScript('VuFind.account.clearCache("' . $key . '");'); } } } /** - * Check cases that don't change the account icon + * Test status badges * * @return void */ - public function testIconNone() + public function testStatusBadges(): void { - $this->login(); - $storage = [ - // No fines - [ - 'fines' => [ - 'total' => 0, - 'display' => 'ZILTCH', - ], - ], - // Holds in transit only - [ - 'holds' => [ - 'in_transit' => 1, - 'available' => 0, - 'other' => 0, - ], - ], - // ILL Requests in transit only - [ - 'illRequests' => [ - 'in_transit' => 1, - 'available' => 0, - 'other' => 0, - ], - ], - // Storage Retrievals in transit only + $this->changeConfigs( [ - 'storageRetrievalRequests' => [ - 'in_transit' => 1, - 'available' => 0, - 'other' => 0, + 'Demo' => $this->getDemoIniOverrides(), + 'config' => [ + 'Catalog' => ['driver' => 'Demo'], + 'Authentication' => [ + 'method' => 'ILS', + 'enableAjax' => true, + ], ], - ], - ]; - $this->checkIcon($storage, '.account-status-none'); - } + ] + ); - /** - * Check cases that change the account icon to a happy bell - * - * @return void - */ - public function testIconGood() - { - $this->login(); - $storage = [ - // Holds available - ['holds' => ['in_transit' => 0, 'available' => 1, 'level' => 1]], - // ILL Requests available - ['illRequests' => ['in_transit' => 0, 'available' => 1, 'level' => 1]], - // Storage Retrievals available - ['storageRetrievalRequests' => ['in_transit' => 0, 'available' => 1, 'level' => 1]], - ]; - $this->checkIcon($storage, '.account-status-good'); + $session = $this->login('catuser', 'catpass'); + $page = $session->getPage(); + $this->waitForPageLoad($page); + + // Checkouts + $checkoutsStatus = $this->findCss($page, '.myresearch-menu .checkedout-status'); + $this->assertEquals( + '1', + $this->findCssAndGetText($checkoutsStatus, '.badge.account-info') + ); + $this->assertEquals( + 'Items due later: 1 ,', + $this->findCssAndGetText($checkoutsStatus, '.visually-hidden, .sr-only') + ); + + $this->assertEquals( + '2', + $this->findCssAndGetText($checkoutsStatus, ' .badge.account-warning') + ); + $this->assertEquals( + 'Items due soon: 2 ,', + $this->findCssAndGetText($checkoutsStatus, '.visually-hidden, .sr-only', null, 1) + ); + + $this->assertEquals( + '3', + $this->findCssAndGetText($checkoutsStatus, '.badge.account-alert') + ); + $this->assertEquals( + 'Items overdue: 3 ,', + $this->findCssAndGetText($checkoutsStatus, '.visually-hidden, .sr-only', null, 2) + ); + + // Holds + $holdsStatus = $this->findCss($page, '.myresearch-menu .holds-status'); + $this->assertEquals( + '1', + $this->findCssAndGetText($holdsStatus, '.badge.account-info') + ); + $this->assertEquals( + 'Available for Pickup: 1 ,', + $this->findCssAndGetText($holdsStatus, '.visually-hidden, .sr-only') + ); + + $this->assertEquals( + '2', + $this->findCssAndGetText($holdsStatus, '.badge.account-warning') + ); + $this->assertEquals( + 'In Transit: 2 ,', + $this->findCssAndGetText($holdsStatus, '.visually-hidden, .sr-only', null, 1) + ); + + $this->assertEquals( + '3', + $this->findCssAndGetText($holdsStatus, '.badge.account-none') + ); + $this->assertEquals( + 'Other Status: 3 ,', + $this->findCssAndGetText($holdsStatus, '.visually-hidden, .sr-only', null, 2) + ); + + // Fines + $this->assertEquals( + '$1.23', + $this->findCssAndGetText($page, '.myresearch-menu .fines-status .badge.account-alert') + ); } /** - * Check cases that change the account icon to a concerned bell + * Standard teardown method. * * @return void */ - public function testIconWarning() + public static function tearDownAfterClass(): void { - $this->login(); - $storage = [ - // Checked out due soon - ['checkedOut' => ['warn' => 1, 'level' => 2]], - ]; - $this->checkIcon($storage, '.account-status-warning'); + static::removeUsers(['username1', 'catuser']); } /** - * Check cases that change the account icon to an alarming triangle + * Utility method to login * - * @return void + * @param string $user Username + * @param string $password Password + * + * @return \Behat\Mink\Session */ - public function testIconDanger() + protected function login($user = 'username1', $password = 'test') { - $this->login(); - $storage = [ - // User has fines - ['fines' => ['value' => 1000000, 'display' => '$...yikes', 'level' => 3]], - // Checkedout overdue - ['checkedOut' => ['overdue' => 1, 'level' => 3]], - ]; - $this->checkIcon($storage, '.account-status-danger'); + $session = $this->getMinkSession(); + $session->visit($this->getVuFindUrl()); + $page = $session->getPage(); + $this->clickCss($page, '#loginOptions a'); + $this->waitForPageLoad($page); + $this->fillInLoginForm($page, $user, $password); + $this->clickCss($page, '.modal-body .btn.btn-primary'); + $this->waitForPageLoad($page); + return $session; } /** - * More urgent cases should override lower cases + * Get transaction JSON for Demo.ini. * - * Danger > Warning > Good > None + * @param string $bibId Bibliographic record ID to create fake item info for. * - * @return void + * @return array */ - public function testIconClashes() + protected function getFakeTransactions($bibId) { - $this->login(); - // Danger overrides warning - $this->checkIcon( - [['checkedOut' => ['warn' => 2, 'overdue' => 1, 'level' => 3]]], - '.account-status-danger' - ); - // Danger overrides good - $this->checkIcon( + $transactions = []; + $template = [ + 'barcode' => 1234567890, + 'renew' => 0, + 'renewLimit' => 1, + 'request' => 0, + 'id' => $bibId, + 'source' => 'Solr', + 'item_id' => 0, + 'renewable' => true, + ]; + $params = [ [ - [ - 'checkedOut' => ['overdue' => 1, 'level' => 3], - 'holds' => ['available' => 1, 'level' => 1], - ], + 'dueStatus' => 'due', + 'duedate' => strtotime('now +5 days'), ], - '.account-status-danger' - ); - // Warning overrides good - $this->checkIcon( [ - [ - 'checkedOut' => ['warn' => 1, 'level' => 2], - 'holds' => ['available' => 1, 'level' => 1], - ], + 'dueStatus' => 'due', + 'duedate' => strtotime('now +5 days'), ], - '.account-status-warning' - ); - // Good overrides none - $this->checkIcon( [ - [ - 'holds' => ['available' => 1, 'level' => 1], - 'fines' => ['total' => 0, 'display' => 'none', 'level' => 0], - ], + 'dueStatus' => 'overdue', + 'duedate' => strtotime('now -1 days'), ], - '.account-status-good' - ); - } - - /** - * Standard teardown method. - * - * @return void - */ - public static function tearDownAfterClass(): void - { - static::removeUsers(['username1']); + [ + 'dueStatus' => 'overdue', + 'duedate' => strtotime('now -1 days'), + ], + [ + 'dueStatus' => 'overdue', + 'duedate' => strtotime('now -2 days'), + ], + [ + 'dueStatus' => false, + 'duedate' => strtotime('now +20 days'), + ], + ]; + foreach ($params as $current) { + $transactions[] = [...$template, ...$current]; + } + return json_encode($transactions); } }