mirror of
https://github.com/strapi/strapi.git
synced 2025-11-01 18:33:55 +00:00
fix: create UID from singular name instead of display name (#24408)
* fix: create UID from singular name instead of display name * fix: add e2e tests
This commit is contained in:
parent
becb1565a2
commit
009c0404a1
@ -333,7 +333,7 @@ export const FormModal = () => {
|
||||
get(modifiedData, 'createComponent', false) || isCreatingComponentWhileAddingAField;
|
||||
const isInFirstComponentStep = step === '1';
|
||||
const isPickingAttribute = modalType === 'chooseAttribute';
|
||||
const uid = createUid(modifiedData.displayName || '');
|
||||
const uid = createUid(modifiedData.singularName || '');
|
||||
const attributes = get(type, ['attributes'], null) as {
|
||||
name: string;
|
||||
}[];
|
||||
|
||||
@ -0,0 +1,137 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { resetFiles } from '../../../utils/file-reset';
|
||||
import { sharedSetup } from '../../../utils/setup';
|
||||
import { clickAndWait } from '../../../utils/shared';
|
||||
import { waitForRestart } from '../../../utils/restart';
|
||||
|
||||
test.describe('Content Type UID Generation', () => {
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await sharedSetup('ctb-uid-generation', page, {
|
||||
login: true,
|
||||
resetFiles: true,
|
||||
importData: 'with-admin.tar',
|
||||
});
|
||||
|
||||
await clickAndWait(page, page.getByRole('link', { name: 'Content-Type Builder' }));
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
await resetFiles();
|
||||
});
|
||||
|
||||
test('Should generate UID from singular name, not display name', async ({ page }) => {
|
||||
// Create a new collection type
|
||||
await page.getByRole('button', { name: 'Create new collection type' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Create a collection type' })).toBeVisible();
|
||||
|
||||
// Fill in "Members" as display name
|
||||
const displayName = page.getByLabel('Display name');
|
||||
await displayName.fill('Members');
|
||||
|
||||
// Wait for auto-generation
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// manually change singular name to "member"
|
||||
const singularIdField = page.getByLabel('API ID (Singular)');
|
||||
await singularIdField.clear();
|
||||
await singularIdField.fill('member');
|
||||
|
||||
// Verify it has the value we set
|
||||
await expect(singularIdField).toHaveValue('member');
|
||||
|
||||
// Verify plural name is "members"
|
||||
const pluralIdField = page.getByLabel('API ID (Plural)');
|
||||
await expect(pluralIdField).toHaveValue('members');
|
||||
|
||||
// Continue to add fields
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
// Add a field - use the same selector as the helper function
|
||||
await clickAndWait(page, page.getByRole('button', { name: 'Add new field' }).first());
|
||||
|
||||
// Select Text field type
|
||||
await page.getByRole('button', { name: 'Text Small or long' }).click();
|
||||
|
||||
// Fill in field name
|
||||
await page.getByLabel('Name', { exact: true }).fill('title');
|
||||
|
||||
// Finish adding the field
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
|
||||
// Save the content type
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await waitForRestart(page);
|
||||
|
||||
// After restart, verify the content type appears in the list
|
||||
await expect(page.getByRole('link', { name: 'Members' })).toBeVisible();
|
||||
|
||||
// Navigate to the created content type
|
||||
await clickAndWait(page, page.getByRole('link', { name: 'Members' }));
|
||||
|
||||
// Verify the URL uses the singular name "member" in UID, not "members"
|
||||
await expect(page).toHaveURL(/content-types\/api::member\.member$/);
|
||||
});
|
||||
|
||||
test('Should show error when singular and plural names are the same', async ({ page }) => {
|
||||
// This test verifies that if "Cities" is used as display name and the singular name
|
||||
// is NOT manually corrected to "city", there should be a validation error because
|
||||
// singular and plural names cannot be the same.
|
||||
|
||||
// Create a new collection type
|
||||
await page.getByRole('button', { name: 'Create new collection type' }).click();
|
||||
await expect(page.getByRole('heading', { name: 'Create a collection type' })).toBeVisible();
|
||||
|
||||
// Fill in "Cities" as display name
|
||||
const displayName = page.getByLabel('Display name');
|
||||
await displayName.fill('Cities');
|
||||
|
||||
// Wait for auto-generation
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
// Singular name will be auto-generated as "cities" (just slugified, NOT singularized)
|
||||
const singularIdField = page.getByLabel('API ID (Singular)');
|
||||
await expect(singularIdField).toHaveValue('cities');
|
||||
|
||||
// Plural should also be "cities"
|
||||
const pluralIdField = page.getByLabel('API ID (Plural)');
|
||||
await expect(pluralIdField).toHaveValue('cities');
|
||||
|
||||
// Try to continue - should be blocked due to validation error
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
// Verify validation errors appear
|
||||
await expect(page.getByText('This value cannot be the same as the plural one')).toBeVisible();
|
||||
await expect(page.getByText('This value cannot be the same as the singular one')).toBeVisible();
|
||||
|
||||
// The user should not be able to proceed without fixing this
|
||||
// Let's verify we're still on the same modal
|
||||
await expect(page.getByRole('heading', { name: 'Create a collection type' })).toBeVisible();
|
||||
|
||||
// Now fix it by correcting the singular name to "city"
|
||||
await singularIdField.clear();
|
||||
await singularIdField.fill('city');
|
||||
|
||||
// Now we should be able to continue
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
|
||||
// Verify we moved to the field addition screen
|
||||
await expect(page.getByRole('button', { name: 'Add new field' }).first()).toBeVisible();
|
||||
|
||||
// Add a field
|
||||
await clickAndWait(page, page.getByRole('button', { name: 'Add new field' }).first());
|
||||
await page.getByRole('button', { name: 'Text Small or long' }).click();
|
||||
await page.getByLabel('Name', { exact: true }).fill('name');
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
|
||||
// Save the content type
|
||||
await page.getByRole('button', { name: 'Save' }).click();
|
||||
await waitForRestart(page);
|
||||
|
||||
// After restart, verify the content type was created with the corrected singular name
|
||||
await expect(page.getByRole('link', { name: 'Cities' })).toBeVisible();
|
||||
await clickAndWait(page, page.getByRole('link', { name: 'Cities' }));
|
||||
|
||||
// Verify the URL uses the corrected singular name "city" in the UID
|
||||
await expect(page).toHaveURL(/content-types\/api::city\.city$/);
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user