diff --git a/Taskfile b/Taskfile index 9eeaa50..211d1e8 100755 --- a/Taskfile +++ b/Taskfile @@ -12,8 +12,7 @@ refresh_sqlx_db() { rm -f some_user.db for migration in migrations/each_user/*.sql; do echo "Applying $migration..." - echo "BEGIN TRANSACTION;$(cat "$migration");COMMIT TRANSACTION;"\ - | sqlite3 some_user.db + sqlite3 some_user.db < "$migration" done } diff --git a/e2e/custom-expects.ts b/e2e/custom-expects.ts deleted file mode 100644 index 9b169e0..0000000 --- a/e2e/custom-expects.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { expect, type Locator } from '@playwright/test'; -expect.extend({ - async toBeAbove(self: Locator, other: Locator) { - const name = 'toBeAbove'; - let pass: boolean; - let matcherResult: any; - let selfY: number | null = null; - let otherY: number | null = null; - try { - selfY = (await self.boundingBox())?.y ?? null; - otherY = (await self.boundingBox())?.y ?? null; - pass = selfY !== null && otherY !== null && (selfY < otherY); - } catch (e: any) { - matcherResult = e.matcherResult; - pass = false; - } - - if (this.isNot) { - pass =!pass; - } - - const message = () => this.utils.matcherHint(name, undefined, undefined, { isNot: this.isNot }) + - '\n\n' + - `Locator: ${self}\n` + - `Expected: above ${other} (y=${this.utils.printExpected(otherY)})\n` + - (matcherResult ? `Received: y=${this.utils.printReceived(selfY)}` : ''); - - return { - message, - pass, - name, - expected: (this.isNot ? '>=' : '<') + otherY, - actual: selfY, - }; - - } -}); diff --git a/e2e/pages/contact.spec.ts b/e2e/pages/contact.spec.ts deleted file mode 100644 index 25f0798..0000000 --- a/e2e/pages/contact.spec.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { test, expect } from '@playwright/test'; -import { login, verifyCreateUser, todate } from './util'; - -test.beforeEach(async ({ page }) => { - await login(page); - await verifyCreateUser(page, { names: ['Test Testerson'] }); - await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak'); -}); - -test('manual-freshen date is editable', async ({ page }) => { - await page.getByRole('link', { name: /edit/i }).click(); - await expect(page.getByRole('textbox', { name: /freshened/i })).toBeVisible(); -}); - -test('last-contact date on display resolves journal mentions and manual-freshen', async ({ page }) => { - const today = new Date().toISOString().split("T")[0]; - const todayRe = new RegExp(today.substring(0, today.length - 1) + "."); - const entryDate = page.getByPlaceholder(todayRe); - const entryBox = page.getByPlaceholder(/new entry/i); - await entryDate.fill("2025-05-05"); - await entryBox.fill("[[Test Testerson]]"); - await page.getByRole('button', { name: /add entry/i }).click(); - await page.reload(); - await expect(page.locator('#fields')).toContainText("freshened2025-05-05"); -}); - -test.skip("groups wrap nicely", async ({ page }) => { - await page.getByRole('link', { name: /edit/i }).click(); - await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak'); - - const groupBox = page.getByPlaceholder(/group name/i); - await groupBox.fill('this is a long group name'); - await page.getByRole('button', { name: /save/i }).click(); - await expect(page.locator('#alpine-loaded')).not.toHaveAttribute('x-cloak'); - - // TODO: this drives to the right location but i can't figure out how to assert - // that the text is all on one line. Manual inspection looks good at time of writing. -}); - -test('allow marking as hidden', async ({ page }) => { - -}); - -test('allow exempting from stale', async ({ page }) => { - -}); - -test('something is fucky with lives_with insertion triggering mention generation', async ({ page }) => { - -}); - -test('bullet points in free text display well', async ({ page }) => { - -}); - -/* -home: contact list scrolls in screen, not off screen -home: clicking off contact list closes it -home: contact list is sorted ignoring case -home: contact list should scroll to current contact in center of view -journal: saving journal entry should stay in edit -journal: sometimes editing entries fucks up mentions (probably another $1/$2 error) -journal: bullet points don't display -*/ diff --git a/e2e/pages/home.spec.ts b/e2e/pages/home.spec.ts index 13b9fa1..7d70bbb 100644 --- a/e2e/pages/home.spec.ts +++ b/e2e/pages/home.spec.ts @@ -1,26 +1,28 @@ import { test, expect } from '@playwright/test'; import { login, verifyCreateUser, todate } from './util'; -test.beforeEach(async ({ page }) => { - await login(page); -}); - test('can log out', async ({ page }) => { + await login(page); + await page.getByText("Logout").click(); await expect(page.getByLabel("Username")).toBeVisible(); }); test('has no contacts', async ({ page }) => { + await login(page); + await expect(page.getByRole("navigation").getByRole("link")).toHaveCount(0); }); test('can add contacts', async ({ page }) => { + await login(page); await verifyCreateUser(page, { names: ['John Contact'] }); await verifyCreateUser(page, { names: ['Jack Contact'] }); await expect(page.getByRole("navigation").getByRole("link")).toHaveCount(2); }); test('shows "never" for unfreshened contacts', async ({ page }) => { + await login(page); await verifyCreateUser(page, { names: ['John Contact'] }); await page.getByRole('link', { name: 'Mascarpone' }).click(); @@ -28,6 +30,7 @@ test('shows "never" for unfreshened contacts', async ({ page }) => { }); test('shows the date for fresh contacts', async ({ page }) => { + await login(page); await verifyCreateUser(page, { names: ['John Contact'] }); await page.getByRole('link', { name: /edit/i }).click(); await page.getByRole('button', { name: /fresh/i }).click(); @@ -37,6 +40,7 @@ test('shows the date for fresh contacts', async ({ page }) => { }); test('sidebar is sorted alphabetically', async ({ page }) => { + await login(page); await verifyCreateUser(page, { names: ['Zulu'] }); await verifyCreateUser(page, { names: ['Alfa'] }); await verifyCreateUser(page, { names: ['Golf'] }); diff --git a/e2e/playwright.config.ts b/e2e/playwright.config.ts index 1065269..f1295d4 100644 --- a/e2e/playwright.config.ts +++ b/e2e/playwright.config.ts @@ -1,5 +1,4 @@ import { defineConfig, devices } from '@playwright/test'; -import 'custom-expects'; // purposefully not using ??: we want to replace empty empty string with default const BASE_URL = process.env.BASE_URL || 'http://localhost:3000'; diff --git a/migrations/each_user/0012_contact_fresh_type.sql b/migrations/each_user/0012_contact_fresh_type.sql index 7a5f8bb..a9685ef 100644 --- a/migrations/each_user/0012_contact_fresh_type.sql +++ b/migrations/each_user/0012_contact_fresh_type.sql @@ -1,12 +1,5 @@ --- foreign_keys can only up/down outside of transactions --- so we first pre-commit the one started by sqlx... -COMMIT TRANSACTION; --- turn off foreign keys... PRAGMA foreign_keys=OFF; - --- start our own transaction... -BEGIN TRANSACTION; create table if not exists new_contacts ( id integer primary key autoincrement, birthday text, @@ -23,12 +16,4 @@ insert into new_contacts ( drop table contacts; alter table new_contacts rename to contacts; PRAGMA foreign_key_check; - --- commit our own transaction... -COMMIT TRANSACTION; - --- put our own pragmas back... PRAGMA foreign_keys=ON; - --- and start a dummy transaction so sqlx's COMMIT doesn't explode -BEGIN TRANSACTION; diff --git a/src/web/contact/mod.rs b/src/web/contact/mod.rs index 525090c..8eea1b0 100644 --- a/src/web/contact/mod.rs +++ b/src/web/contact/mod.rs @@ -75,7 +75,7 @@ mod get { let entries: Vec = sqlx::query_as( "select distinct j.id, j.value, j.date from journal_entries j join mentions m on j.id = m.entity_id - where m.entity_type = $1 and (m.url = '/contact/'||$2 or m.url in ( + where m.entity_type = $1 and (m.url = '/contact/'||$1 or m.url in ( select '/group/'||slug from groups where contact_id = $2 )) @@ -87,11 +87,6 @@ mod get { .fetch_all(pool) .await?; - let freshened = std::cmp::max( - contact.manually_freshened_at.map(|when| when.date_naive()), - entries.get(0).map(|entry| entry.date), - ); - let phone_numbers: Vec = sqlx::query_as!( PhoneNumber, "select * from phone_numbers where contact_id = $1", @@ -146,8 +141,8 @@ mod get { } label { "freshened" } div { - @if let Some(freshened) = freshened { - (freshened.to_string()) + @if let Some(when) = &contact.manually_freshened_at { + (when.date_naive().to_string()) } @else { "(never)" } diff --git a/src/web/mod.rs b/src/web/mod.rs index bfee974..66ab59c 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -102,7 +102,6 @@ impl Layout { (content) } } - template #alpine-loaded x-cloak {} } } } diff --git a/static/contact.css b/static/contact.css index 765ff62..d725284 100644 --- a/static/contact.css +++ b/static/contact.css @@ -47,7 +47,7 @@ main { #groups { display: flex; flex-direction: column; - width: fit-content; + width: min-content; } #text_body {