-
Notifications
You must be signed in to change notification settings - Fork 1
Reject duplicate collection field labels #270
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -93,24 +93,22 @@ | |
|
|
||
| function addField(event: SubmitEvent): void { | ||
| event.preventDefault(); | ||
| const label = newFieldLabel.trim(); | ||
| if (!label) return; | ||
| const field: PropertyDefinition = { | ||
| key: nanoid(8), | ||
| label, | ||
| label: newFieldLabel, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Associate field-label validation errors with their inputs.
🤖 Prompt for AI Agents |
||
| type: newFieldType, | ||
| options: newFieldType === 'select' ? [] : undefined, | ||
| targetCollectionId: | ||
| newFieldType === 'relation' ? newFieldTargetCollectionId || undefined : undefined | ||
| }; | ||
| try { | ||
| appendCollectionField(getShardDoc(shardId), collectionId, field); | ||
| const result = appendCollectionField(getShardDoc(shardId), collectionId, field); | ||
| if (result.ok) { | ||
| newFieldLabel = ''; | ||
| newFieldType = 'text'; | ||
| newFieldTargetCollectionId = ''; | ||
| errorMessage = ''; | ||
| } catch { | ||
| errorMessage = 'Could not add the field. Please try again.'; | ||
| } else { | ||
| errorMessage = result.error; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; | ||
| import { render, screen, within } from '@testing-library/svelte'; | ||
| import { fireEvent, render, screen, within } from '@testing-library/svelte'; | ||
| import userEvent from '@testing-library/user-event'; | ||
| import * as Y from 'yjs'; | ||
| import { createCollection, deleteCollection, getCollection } from '$lib/data/collection-ops'; | ||
|
|
@@ -120,6 +120,42 @@ describe('FieldManagerDialog', () => { | |
| ]); | ||
| }); | ||
|
|
||
| it('rejects a case-insensitively duplicate field label with an inline error', async () => { | ||
| const collection = createCollection(ydoc, { | ||
| title: 'T', | ||
| schema: [{ key: 'status', label: 'Status', type: 'select' }] | ||
| }); | ||
| const user = userEvent.setup(); | ||
| render(FieldManagerDialog, { | ||
| open: true, | ||
| collectionId: collection.id, | ||
| shardId: 'test-shard', | ||
| onClose: vi.fn() | ||
| }); | ||
|
|
||
| await user.type(screen.getByPlaceholderText('Field name…'), ' status '); | ||
| await user.click(screen.getByRole('button', { name: 'Add field' })); | ||
|
|
||
| expect(screen.getByRole('alert')).toHaveTextContent('A field named "status" already exists'); | ||
| expect(getCollection(ydoc, collection.id)?.schema).toHaveLength(1); | ||
| }); | ||
|
|
||
| it('shows an inline error for a blank field label', async () => { | ||
| const collection = createCollection(ydoc, { title: 'T', schema: [] }); | ||
| const user = userEvent.setup(); | ||
| render(FieldManagerDialog, { | ||
| open: true, | ||
| collectionId: collection.id, | ||
| shardId: 'test-shard', | ||
| onClose: vi.fn() | ||
| }); | ||
|
|
||
| await user.type(screen.getByPlaceholderText('Field name…'), ' '); | ||
| await fireEvent.submit(screen.getByRole('button', { name: 'Add field' }).closest('form')!); | ||
|
|
||
| expect(screen.getByRole('alert')).toHaveTextContent('Field label cannot be blank'); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Assert that rejected submissions preserve the schema. The blank-label tests for 🤖 Prompt for AI Agents |
||
| }); | ||
|
|
||
| it("adds a relation field with a target collection, and doesn't offer the picker for other types (issue #15)", async () => { | ||
| const people = createCollection(ydoc, { title: 'People', schema: [] }); | ||
| const collection = createCollection(ydoc, { title: 'T', schema: [] }); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.