feat(fase-10): CU-H07 rename collective + change emoji
Admin gets an editable name input + emoji picker at the top of /collective/manage. Enter / blur / Save button all flush the PostgREST UPDATE; Esc reverts to the persisted value. The response payload feeds both $currentCollective and $userCollectives so the sidebar updates without reload. Members and guests see no editing affordances at all (the section is admin-gated; UPDATE policies were already in place from Fase 2a so no migration is needed). MC-01a: Ana renames + picks a new emoji, reload preserves both, DB reflects the change. MC-01b: Borja never sees the editable fields. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
65
apps/web/tests/e2e/rename-collective.test.ts
Normal file
65
apps/web/tests/e2e/rename-collective.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* MC-01 (rescued from Fase 7) — /collective/manage rename + emoji change.
|
||||
*
|
||||
* Admin (Ana) edits name + emoji inline; the value persists across reload.
|
||||
* Member (Borja) does not see the editable inputs.
|
||||
*
|
||||
* Cleanup: restore the seed name + emoji in afterAll so downstream suites
|
||||
* that hard-match "Casa García-López" / "🏠" don't break.
|
||||
*/
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { USERS } from '../fixtures/users.js';
|
||||
import { loginAs } from '../fixtures/login.js';
|
||||
import { closePool, sql, COLLECTIVE_ID } from '@colectivo/test-utils';
|
||||
|
||||
test.describe.configure({ mode: 'serial' });
|
||||
|
||||
test.describe('Rename collective (CU-H07)', () => {
|
||||
test.afterAll(async () => {
|
||||
await sql(`UPDATE public.collectives SET name = $1, emoji = $2 WHERE id = $3`, [
|
||||
'Casa García-López',
|
||||
'🏠',
|
||||
COLLECTIVE_ID
|
||||
]);
|
||||
await closePool();
|
||||
});
|
||||
|
||||
test('MC-01a: admin renames + changes emoji; value persists across reload', async ({
|
||||
page
|
||||
}) => {
|
||||
await loginAs(page, USERS.ana);
|
||||
await page.goto('/collective/manage');
|
||||
|
||||
const newName = `Casa renamed ${Date.now()}`;
|
||||
const nameInput = page.getByTestId('collective-name-edit');
|
||||
await expect(nameInput).toBeVisible({ timeout: 15_000 });
|
||||
await nameInput.fill(newName);
|
||||
await page.getByTestId('collective-name-save').click();
|
||||
|
||||
// Pick a different emoji.
|
||||
await page.getByTestId('collective-emoji-toggle').click();
|
||||
await page.getByTestId('collective-emoji-option-🏡').click();
|
||||
|
||||
// Reload and verify the inputs reflect the persisted value.
|
||||
await page.reload();
|
||||
await expect(page.getByTestId('collective-name-edit')).toHaveValue(newName, {
|
||||
timeout: 15_000
|
||||
});
|
||||
|
||||
const row = await sql('SELECT name, emoji FROM public.collectives WHERE id = $1', [
|
||||
COLLECTIVE_ID
|
||||
]);
|
||||
expect(row.rows[0].name).toBe(newName);
|
||||
expect(row.rows[0].emoji).toBe('🏡');
|
||||
});
|
||||
|
||||
test('MC-01b: non-admin (Borja) does not see editable inputs', async ({ page }) => {
|
||||
await loginAs(page, USERS.borja);
|
||||
await page.goto('/collective/manage');
|
||||
|
||||
// Members list loads → page is hydrated; editable name input must be absent.
|
||||
await expect(page.getByTestId(`member-row-${USERS.ana.id}`)).toBeVisible({ timeout: 15_000 });
|
||||
await expect(page.getByTestId('collective-name-edit')).toHaveCount(0);
|
||||
await expect(page.getByTestId('collective-emoji-toggle')).toHaveCount(0);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user