fix: allow dots in username (#11706)
* fix: allow dots in username * test: added unit tests for slugify * test: add test for username change * tests: add test for username and dynamic booking * fix: type error --------- Co-authored-by: Peer Richelsen <peeroke@gmail.com>pull/12038/head^2
parent
0014ca6865
commit
aa54c013f8
|
@ -43,9 +43,40 @@ test.describe("Change username on settings", () => {
|
|||
id: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(newUpdatedUser.username).toBe("demousernamex");
|
||||
});
|
||||
|
||||
test("User can change username to include periods(or dots)", async ({ page, users, prisma }) => {
|
||||
const user = await users.create();
|
||||
|
||||
await user.apiLogin();
|
||||
// Try to go homepage
|
||||
await page.goto("/settings/my-account/profile");
|
||||
// Change username from normal to normal
|
||||
const usernameInput = page.locator("[data-testid=username-input]");
|
||||
// User can change username to include dots(or periods)
|
||||
await usernameInput.fill("demo.username");
|
||||
await page.click("[data-testid=update-username-btn]");
|
||||
await Promise.all([
|
||||
page.click("[data-testid=save-username]"),
|
||||
page.getByTestId("toast-success").waitFor(),
|
||||
]);
|
||||
await page.waitForLoadState("networkidle");
|
||||
|
||||
const updatedUser = await prisma.user.findUniqueOrThrow({
|
||||
where: {
|
||||
id: user.id,
|
||||
},
|
||||
});
|
||||
|
||||
expect(updatedUser.username).toBe("demo.username");
|
||||
|
||||
// Check if user avatar can be accessed and response headers contain 'image/' in the content type
|
||||
const response = await page.goto("/demo.username/avatar.png");
|
||||
expect(response?.headers()?.["content-type"]).toContain("image/");
|
||||
});
|
||||
|
||||
test("User can update to PREMIUM username", async ({ page, users }, testInfo) => {
|
||||
// eslint-disable-next-line playwright/no-skipped-test
|
||||
test.skip(!IS_STRIPE_ENABLED, "It should only run if Stripe is installed");
|
||||
|
|
|
@ -13,7 +13,7 @@ test("dynamic booking", async ({ page, users }) => {
|
|||
const pro = await users.create();
|
||||
await pro.apiLogin();
|
||||
|
||||
const free = await users.create({ username: "free" });
|
||||
const free = await users.create({ username: "free.example" });
|
||||
await page.goto(`/${pro.username}+${free.username}`);
|
||||
|
||||
await test.step("book an event first day in next month", async () => {
|
||||
|
|
|
@ -635,7 +635,7 @@ export const TestData = {
|
|||
example: {
|
||||
name: "Example",
|
||||
email: "example@example.com",
|
||||
username: "example",
|
||||
username: "example.username",
|
||||
defaultScheduleId: 1,
|
||||
timeZone: Timezones["+5:30"],
|
||||
},
|
||||
|
|
|
@ -30,6 +30,21 @@ describe("slugify", () => {
|
|||
expect(slugify("$hello-there_")).toEqual("hello-there");
|
||||
});
|
||||
|
||||
it("should keep periods as is except the start and end", () => {
|
||||
expect(slugify("hello.there")).toEqual("hello.there");
|
||||
expect(slugify("h.e.l.l.o.t.h.e.r.e")).toEqual("h.e.l.l.o.t.h.e.r.e");
|
||||
});
|
||||
it("should remove consecutive periods", () => {
|
||||
expect(slugify("hello...there")).toEqual("hello.there");
|
||||
expect(slugify("hello....there")).toEqual("hello.there");
|
||||
expect(slugify("hello..there")).toEqual("hello.there");
|
||||
});
|
||||
it("should remove periods from start and end", () => {
|
||||
expect(slugify(".hello.there")).toEqual("hello.there");
|
||||
expect(slugify(".hello.there.")).toEqual("hello.there");
|
||||
expect(slugify("hellothere.")).toEqual("hellothere");
|
||||
});
|
||||
|
||||
// This is failing, if we want to fix it, one approach is as used in getValidRhfFieldName
|
||||
it.skip("should remove unicode and emoji characters", () => {
|
||||
expect(slugify("Hello 📚🕯️®️ There")).toEqual("hello---------there");
|
||||
|
|
|
@ -7,11 +7,13 @@ export const slugify = (str: string, forDisplayingInput?: boolean) => {
|
|||
.trim() // Remove whitespace from both sides
|
||||
.normalize("NFD") // Normalize to decomposed form for handling accents
|
||||
.replace(/\p{Diacritic}/gu, "") // Remove any diacritics (accents) from characters
|
||||
.replace(/[^\p{L}\p{N}\p{Zs}\p{Emoji}]+/gu, "-") // Replace any non-alphanumeric characters (including Unicode) with a dash
|
||||
.replace(/[^.\p{L}\p{N}\p{Zs}\p{Emoji}]+/gu, "-") // Replace any non-alphanumeric characters (including Unicode and except "." period) with a dash
|
||||
.replace(/[\s_#]+/g, "-") // Replace whitespace, # and underscores with a single dash
|
||||
.replace(/^-+/, ""); // Remove dashes from start
|
||||
.replace(/^-+/, "") // Remove dashes from start
|
||||
.replace(/\.{2,}/g, ".") // Replace consecutive periods with a single period
|
||||
.replace(/^\.+/, ""); // Remove periods from the start
|
||||
|
||||
return forDisplayingInput ? s : s.replace(/-+$/, ""); // Remove dashes from end
|
||||
return forDisplayingInput ? s : s.replace(/-+$/, "").replace(/\.*$/, ""); // Remove dashes and period from end
|
||||
};
|
||||
|
||||
export default slugify;
|
||||
|
|
Loading…
Reference in New Issue