chore: bump version to 2.23.2 and enhance team account creation (#440)
* chore: bump version to 2.23.2 and enhance team account creation - Updated application version from 2.23.1 to 2.23.2 in package.json. - Enhanced team account creation to support slugs for non-Latin names, including validation and UI updates. - Updated localization files to reflect new slug requirements and error messages. - Refactored related schemas and server actions to accommodate slug handling in team account creation and updates. * refactor: remove old trigger and function for adding current user to new account - Dropped the trigger "add_current_user_to_new_account" and the associated function from the database schema. - Updated permissions for the function public.create_team_account to ensure proper access control.
This commit is contained in:
committed by
GitHub
parent
e1bfbc8106
commit
0636f8cf11
@@ -91,13 +91,23 @@ export class TeamAccountsPageObject {
|
||||
}).toPass();
|
||||
}
|
||||
|
||||
async tryCreateTeam(teamName: string) {
|
||||
await this.page.locator('[data-test="create-team-form"] input').fill('');
|
||||
await this.page.waitForTimeout(200);
|
||||
async tryCreateTeam(teamName: string, slug?: string) {
|
||||
const nameInput = this.page.locator(
|
||||
'[data-test="create-team-form"] [data-test="team-name-input"]',
|
||||
);
|
||||
|
||||
await this.page
|
||||
.locator('[data-test="create-team-form"] input')
|
||||
.fill(teamName);
|
||||
await nameInput.fill('');
|
||||
await nameInput.fill(teamName);
|
||||
|
||||
// If slug is provided (for non-Latin names), fill the slug field
|
||||
if (slug) {
|
||||
const slugInput = this.page.locator(
|
||||
'[data-test="create-team-form"] [data-test="team-slug-input"]',
|
||||
);
|
||||
|
||||
await expect(slugInput).toBeVisible();
|
||||
await slugInput.fill(slug);
|
||||
}
|
||||
|
||||
return this.page.click('[data-test="create-team-form"] button:last-child');
|
||||
}
|
||||
@@ -106,7 +116,14 @@ export class TeamAccountsPageObject {
|
||||
await this.openAccountsSelector();
|
||||
|
||||
await this.page.click('[data-test="create-team-account-trigger"]');
|
||||
await this.page.fill('[data-test="create-team-form"] input', teamName);
|
||||
|
||||
await this.page.fill(
|
||||
'[data-test="create-team-form"] [data-test="team-name-input"]',
|
||||
teamName,
|
||||
);
|
||||
|
||||
// Slug field is only shown for non-Latin names, so we don't fill it for Latin names
|
||||
// The database trigger will auto-generate the slug from the name
|
||||
|
||||
const click = this.page.click(
|
||||
'[data-test="create-team-form"] button:last-child',
|
||||
@@ -115,23 +132,77 @@ export class TeamAccountsPageObject {
|
||||
const response = this.page.waitForURL(`/home/${slug}`);
|
||||
|
||||
await Promise.all([click, response]);
|
||||
|
||||
// Verify user landed on the team page
|
||||
await expect(this.page).toHaveURL(`/home/${slug}`);
|
||||
|
||||
// Verify the team was created and appears in the selector
|
||||
await this.openAccountsSelector();
|
||||
await expect(this.getTeamFromSelector(teamName)).toBeVisible();
|
||||
|
||||
// Close the selector
|
||||
await this.page.keyboard.press('Escape');
|
||||
}
|
||||
|
||||
async updateName(name: string, slug: string) {
|
||||
async createTeamWithNonLatinName(teamName: string, slug: string) {
|
||||
await this.openAccountsSelector();
|
||||
|
||||
await this.page.click('[data-test="create-team-account-trigger"]');
|
||||
|
||||
await this.page.fill(
|
||||
'[data-test="create-team-form"] [data-test="team-name-input"]',
|
||||
teamName,
|
||||
);
|
||||
|
||||
// Wait for slug field to appear (triggered by non-Latin name)
|
||||
await expect(this.getSlugField()).toBeVisible();
|
||||
|
||||
await this.page.fill(
|
||||
'[data-test="create-team-form"] [data-test="team-slug-input"]',
|
||||
slug,
|
||||
);
|
||||
|
||||
const click = this.page.click(
|
||||
'[data-test="create-team-form"] button:last-child',
|
||||
);
|
||||
|
||||
const response = this.page.waitForURL(`/home/${slug}`);
|
||||
|
||||
await Promise.all([click, response]);
|
||||
|
||||
// Verify user landed on the team page
|
||||
await expect(this.page).toHaveURL(`/home/${slug}`);
|
||||
|
||||
// Verify the team was created and appears in the selector
|
||||
await this.openAccountsSelector();
|
||||
await expect(this.getTeamFromSelector(teamName)).toBeVisible();
|
||||
|
||||
// Close the selector
|
||||
await this.page.keyboard.press('Escape');
|
||||
}
|
||||
|
||||
getSlugField() {
|
||||
return this.page.locator(
|
||||
'[data-test="create-team-form"] [data-test="team-slug-input"]',
|
||||
);
|
||||
}
|
||||
|
||||
async updateTeamName(name: string) {
|
||||
await expect(async () => {
|
||||
await this.page.fill(
|
||||
'[data-test="update-team-account-name-form"] input',
|
||||
name,
|
||||
);
|
||||
|
||||
const click = this.page.click(
|
||||
'[data-test="update-team-account-name-form"] button',
|
||||
);
|
||||
|
||||
// the slug should be updated to match the new team name
|
||||
const response = this.page.waitForURL(`**/home/${slug}/settings`);
|
||||
|
||||
return Promise.all([click, response]);
|
||||
await Promise.all([
|
||||
this.page.click('[data-test="update-team-account-name-form"] button'),
|
||||
this.page.waitForResponse((response) => {
|
||||
return (
|
||||
response.url().includes('settings') &&
|
||||
response.request().method() === 'POST'
|
||||
);
|
||||
}),
|
||||
]);
|
||||
}).toPass();
|
||||
}
|
||||
|
||||
@@ -165,8 +236,11 @@ export class TeamAccountsPageObject {
|
||||
await this.page.click(`[data-test="role-option-${newRole}"]`);
|
||||
|
||||
// Wait for the update to complete and page to reload
|
||||
const response = this.page.waitForResponse(response => {
|
||||
return response.url().includes('members') && response.request().method() === 'POST'
|
||||
const response = this.page.waitForResponse((response) => {
|
||||
return (
|
||||
response.url().includes('members') &&
|
||||
response.request().method() === 'POST'
|
||||
);
|
||||
});
|
||||
|
||||
return Promise.all([
|
||||
|
||||
@@ -65,22 +65,20 @@ test.describe('Team Accounts', () => {
|
||||
await teamAccounts.setup();
|
||||
});
|
||||
|
||||
test('user can update their team name (and slug)', async ({ page }) => {
|
||||
test('user can update their team name', async ({ page }) => {
|
||||
const teamAccounts = new TeamAccountsPageObject(page);
|
||||
const { teamName, slug } = teamAccounts.createTeamName();
|
||||
const newTeamName = `Updated-Team-${(Math.random() * 100000000).toFixed(0)}`;
|
||||
|
||||
await teamAccounts.goToSettings();
|
||||
|
||||
const request = teamAccounts.updateName(teamName, slug);
|
||||
// Update just the name (slug stays the same for Latin names)
|
||||
await teamAccounts.updateTeamName(newTeamName);
|
||||
|
||||
// the slug should be updated to match the new team name
|
||||
const newUrl = page.waitForURL(`**/home/${slug}/settings`);
|
||||
|
||||
await Promise.all([request, newUrl]);
|
||||
await page.waitForTimeout(500);
|
||||
|
||||
await teamAccounts.openAccountsSelector();
|
||||
|
||||
await expect(teamAccounts.getTeamFromSelector(teamName)).toBeVisible();
|
||||
await expect(teamAccounts.getTeamFromSelector(newTeamName)).toBeVisible();
|
||||
});
|
||||
|
||||
test('cannot create a Team account using reserved names', async ({
|
||||
@@ -176,54 +174,73 @@ test.describe('Team Accounts', () => {
|
||||
await expectError();
|
||||
});
|
||||
|
||||
test('cannot create a Team account using non-latin characters', async ({
|
||||
test('can create a Team account with non-Latin name when providing a slug', async ({
|
||||
page,
|
||||
}) => {
|
||||
const teamAccounts = new TeamAccountsPageObject(page);
|
||||
await teamAccounts.createTeam();
|
||||
|
||||
const random = (Math.random() * 100000000).toFixed(0);
|
||||
const slug = `korean-team-${random}`;
|
||||
|
||||
// Create team with Korean name
|
||||
await teamAccounts.createTeamWithNonLatinName('한국 팀', slug);
|
||||
|
||||
// Verify we're on the team page
|
||||
await expect(page).toHaveURL(`/home/${slug}`);
|
||||
|
||||
// Verify team appears in selector
|
||||
await teamAccounts.openAccountsSelector();
|
||||
await expect(teamAccounts.getTeamFromSelector('한국 팀')).toBeVisible();
|
||||
});
|
||||
|
||||
test('slug validation shows error for invalid characters', async ({
|
||||
page,
|
||||
}) => {
|
||||
const teamAccounts = new TeamAccountsPageObject(page);
|
||||
await teamAccounts.createTeam();
|
||||
|
||||
// Use non-Latin name to trigger the slug field visibility
|
||||
await teamAccounts.openAccountsSelector();
|
||||
await page.click('[data-test="create-team-account-trigger"]');
|
||||
|
||||
function expectNonLatinError() {
|
||||
return expect(
|
||||
page.getByText(
|
||||
'This name can only contain Latin characters (a-z), numbers, spaces, and hyphens.',
|
||||
),
|
||||
).toBeVisible();
|
||||
}
|
||||
await page.fill(
|
||||
'[data-test="create-team-form"] [data-test="team-name-input"]',
|
||||
'テストチーム',
|
||||
);
|
||||
|
||||
// Test Cyrillic characters
|
||||
await teamAccounts.tryCreateTeam('Тест Команда');
|
||||
await expectNonLatinError();
|
||||
// Wait for slug field to appear (triggered by non-Latin name)
|
||||
await expect(teamAccounts.getSlugField()).toBeVisible();
|
||||
|
||||
// Test Chinese characters
|
||||
await teamAccounts.tryCreateTeam('测试团队');
|
||||
await expectNonLatinError();
|
||||
// Test invalid slug with uppercase
|
||||
await page.fill(
|
||||
'[data-test="create-team-form"] [data-test="team-slug-input"]',
|
||||
'Invalid-Slug',
|
||||
);
|
||||
|
||||
// Test Japanese characters
|
||||
await teamAccounts.tryCreateTeam('テストチーム');
|
||||
await expectNonLatinError();
|
||||
await page.click('[data-test="create-team-form"] button:last-child');
|
||||
|
||||
// Test Arabic characters
|
||||
await teamAccounts.tryCreateTeam('فريق اختبار');
|
||||
await expectNonLatinError();
|
||||
|
||||
// Test mixed Latin and non-Latin
|
||||
await teamAccounts.tryCreateTeam('Test Команда');
|
||||
await expectNonLatinError();
|
||||
|
||||
// Test emoji
|
||||
await teamAccounts.tryCreateTeam('Test Team 🚀');
|
||||
await expectNonLatinError();
|
||||
|
||||
// Ensure valid Latin names still work (should NOT show error)
|
||||
await teamAccounts.tryCreateTeam('Valid Team Name 123');
|
||||
await expect(
|
||||
page.getByText(
|
||||
'This name can only contain Latin characters (a-z), numbers, spaces, and hyphens.',
|
||||
'Only English letters (a-z), numbers (0-9), and hyphens (-) are allowed',
|
||||
{ exact: true },
|
||||
),
|
||||
).not.toBeVisible();
|
||||
).toBeVisible();
|
||||
|
||||
// Test invalid slug with non-Latin characters
|
||||
await page.fill(
|
||||
'[data-test="create-team-form"] [data-test="team-slug-input"]',
|
||||
'тест-slug',
|
||||
);
|
||||
|
||||
await page.click('[data-test="create-team-form"] button:last-child');
|
||||
|
||||
await expect(
|
||||
page.getByText(
|
||||
'Only English letters (a-z), numbers (0-9), and hyphens (-) are allowed',
|
||||
{ exact: true },
|
||||
),
|
||||
).toBeVisible();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user