Repository navigation
Default the return date of a loan request to the configured loan duration #485
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
eba51aa
Default the return date of a loan request to the configured loan dura…
fabiodalez-dev 8ad6c6b
Give the app the loan duration a loan request adds to its start
fabiodalez-dev 5dbd8fd
Put the whole advanced and email settings back after the role-boundar…
fabiodalez-dev f94dc0f
Document the helpers of the loan-request default-end spec
fabiodalez-dev 453e651
Put the guarded settings back in one transaction after the role-bound…
fabiodalez-dev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| // @ts-check | ||
| // Regression: a loan request sent without touching the calendars must ask for the | ||
| // default loan duration. The return-date picker inherited the start picker's | ||
| // defaultDate, so it showed the start date and the request went out with | ||
| // end_date = start_date: a one-day loan. The expected duration comes from the | ||
| // settings in the database, with the same cap the reservation endpoint applies. | ||
| const { test, expect } = require('@playwright/test'); | ||
| const { execFileSync } = require('child_process'); | ||
|
|
||
| const BASE = process.env.E2E_BASE_URL || 'http://localhost:8081'; | ||
| const ADMIN_EMAIL = process.env.E2E_ADMIN_EMAIL || ''; | ||
| const ADMIN_PASS = process.env.E2E_ADMIN_PASS || ''; | ||
|
|
||
| const DB_USER = process.env.E2E_DB_USER || ''; | ||
| const DB_PASS = process.env.E2E_DB_PASS || ''; | ||
| const DB_HOST = process.env.E2E_DB_HOST || ''; | ||
| const DB_PORT = process.env.E2E_DB_PORT || ''; | ||
| const DB_SOCKET = process.env.E2E_DB_SOCKET || ''; | ||
| const DB_NAME = process.env.E2E_DB_NAME || ''; | ||
|
|
||
| test.skip( | ||
| !ADMIN_EMAIL || !ADMIN_PASS || !DB_USER || !DB_NAME, | ||
| 'E2E credentials not configured (set E2E_ADMIN_EMAIL, E2E_ADMIN_PASS, E2E_DB_USER, E2E_DB_NAME)', | ||
| ); | ||
|
|
||
| /** | ||
| * Runs one statement against the test database (TCP when E2E_DB_HOST is set, else the | ||
| * socket) and returns its tab-separated output, trimmed. | ||
| * @param {string} sql | ||
| * @returns {string} | ||
| */ | ||
| function dbQuery(sql) { | ||
| const args = []; | ||
| if (DB_HOST) { | ||
| args.push('-h', DB_HOST); | ||
| if (DB_PORT) args.push('-P', DB_PORT); | ||
| } else if (DB_SOCKET) { | ||
| args.push('-S', DB_SOCKET); | ||
| } | ||
| args.push('-u', DB_USER, DB_NAME, '-N', '-B', '-e', sql); | ||
| return execFileSync('mysql', args, { | ||
| encoding: 'utf-8', timeout: 10000, | ||
| env: { ...process.env, MYSQL_PWD: DB_PASS }, | ||
| }).trim(); | ||
| } | ||
|
|
||
| /** | ||
| * A loans setting as a positive integer, or the fallback the server uses when it is | ||
| * missing or below 1. | ||
| * @param {string} key | ||
| * @param {number} fallback | ||
| * @returns {number} | ||
| */ | ||
| function setting(key, fallback) { | ||
| const value = parseInt( | ||
| dbQuery(`SELECT setting_value FROM system_settings WHERE category='loans' AND setting_key='${key}' LIMIT 1`) || '', | ||
| 10, | ||
| ); | ||
| return Number.isFinite(value) && value >= 1 ? value : fallback; | ||
| } | ||
|
|
||
| /** | ||
| * yyyy-mm-dd plus a number of days, computed in UTC so no time zone shifts the day. | ||
| * @param {string} iso | ||
| * @param {number} days | ||
| * @returns {string} | ||
| */ | ||
| function addDays(iso, days) { | ||
| const [y, m, d] = iso.split('-').map(Number); | ||
| const date = new Date(Date.UTC(y, m - 1, d)); | ||
| date.setUTCDate(date.getUTCDate() + days); | ||
| return date.toISOString().slice(0, 10); | ||
| } | ||
|
|
||
| test.describe('Book page: loan request return date', () => { | ||
| let bookId = 0; | ||
| let expectedDays = 0; | ||
|
|
||
| test.beforeAll(() => { | ||
| bookId = parseInt( | ||
| dbQuery( | ||
| "SELECT c.libro_id FROM copie c JOIN libri l ON l.id=c.libro_id " + | ||
| "WHERE c.stato='disponibile' AND l.deleted_at IS NULL LIMIT 1", | ||
| ) || '0', | ||
| 10, | ||
| ); | ||
| expectedDays = Math.min(setting('loan_duration_days', 30), setting('max_loan_duration_days', 90)); | ||
| }); | ||
|
|
||
| test('without touching the calendars, the return date is start + the default loan duration', async ({ page }) => { | ||
| test.skip(!bookId, 'No available book to open the loan request on'); | ||
|
|
||
| await page.goto(`${BASE}/accedi`); | ||
| await page.fill('input[name="email"]', ADMIN_EMAIL); | ||
| await page.fill('input[name="password"]', ADMIN_PASS); | ||
| await page.locator('button[type="submit"]').click(); | ||
| await page.waitForURL(/(\/$|admin|profilo|account)/, { timeout: 15000 }).catch(() => {}); | ||
|
|
||
| await page.goto(`${BASE}/libro/${bookId}`); | ||
| const btn = page.locator('#btn-request-loan'); | ||
| test.skip((await btn.count()) === 0, 'This book has no request-loan button'); | ||
|
|
||
| await btn.click(); | ||
| await page.waitForSelector('.swal2-popup', { timeout: 8000 }); | ||
| await page.waitForFunction( | ||
| () => { | ||
| const start = document.querySelector('#swal-date-start'); | ||
| const end = document.querySelector('#swal-date-end'); | ||
| return start && end && /** @type {any} */ (start)._flatpickr && /** @type {any} */ (end)._flatpickr; | ||
| }, | ||
| { timeout: 8000 }, | ||
| ); | ||
|
|
||
| const start = await page.locator('#swal-date-start').inputValue(); | ||
| const end = await page.locator('#swal-date-end').inputValue(); | ||
| expect(start).toMatch(/^\d{4}-\d{2}-\d{2}$/); | ||
| expect(end, 'the return date must not repeat the start date').not.toBe(start); | ||
| expect(end).toBe(addDays(start, expectedDays)); | ||
| // What the visitor reads is the same date, not an empty field. | ||
| await expect(page.locator('#swal-date-end-display')).not.toHaveValue(''); | ||
|
|
||
| }); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.