refactor: format v2 API managed user timeZone (#15273)
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import { plainToClass } from "class-transformer";
|
||||
import { IsOptional, IsString } from "class-validator";
|
||||
|
||||
import { CapitalizeTimeZone } from "./capitalize-timezone";
|
||||
|
||||
class TestDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@CapitalizeTimeZone()
|
||||
timeZone?: string;
|
||||
}
|
||||
|
||||
describe("CapitalizeTimeZone", () => {
|
||||
it("should capitalize single part time zone correctly", () => {
|
||||
const input = { timeZone: "egypt" };
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBe("Egypt");
|
||||
});
|
||||
|
||||
it("should capitalize one-part time zone correctly", () => {
|
||||
const input = { timeZone: "europe/rome" };
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBe("Europe/Rome");
|
||||
});
|
||||
|
||||
it("should capitalize multi-part time zone correctly", () => {
|
||||
const input = { timeZone: "america/new_york" };
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBe("America/New_York");
|
||||
});
|
||||
|
||||
it("should capitalize complex time zone correctly", () => {
|
||||
const input = { timeZone: "europe/isle_of_man" };
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBe("Europe/Isle_Of_Man");
|
||||
});
|
||||
|
||||
it("should handle already capitalized time zones correctly", () => {
|
||||
const input = { timeZone: "Asia/Tokyo" };
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBe("Asia/Tokyo");
|
||||
});
|
||||
|
||||
it("should handle missing time zone correctly", () => {
|
||||
const input = {};
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should capitalize EST at the end of the string", () => {
|
||||
const input = { email: "test@example.com", timeZone: "utc/est" };
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBe("UTC/EST");
|
||||
});
|
||||
|
||||
it("should capitalize UTC when surrounded by non-alphabetical characters", () => {
|
||||
const input = { email: "test@example.com", timeZone: "utc/gmt+3_est" };
|
||||
const output = plainToClass(TestDto, input);
|
||||
expect(output.timeZone).toBe("UTC/GMT+3_EST");
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { Transform } from "class-transformer";
|
||||
|
||||
export function CapitalizeTimeZone(): PropertyDecorator {
|
||||
return Transform(({ value }) => {
|
||||
if (typeof value === "string") {
|
||||
const parts = value.split("/");
|
||||
const normalizedParts = parts.map((part) =>
|
||||
part
|
||||
.split("_")
|
||||
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||
.join("_")
|
||||
);
|
||||
let normalizedTimeZone = normalizedParts.join("/");
|
||||
|
||||
// note(Lauris): regex matching GMT, EST, UTC at the start, end, or surrounded by non-letters and capitalizing them
|
||||
const specialCases = ["GMT", "EST", "UTC"];
|
||||
specialCases.forEach((specialCase) => {
|
||||
const regex = new RegExp(`(^|[^a-zA-Z])(${specialCase})([^a-zA-Z]|$)`, "gi");
|
||||
normalizedTimeZone = normalizedTimeZone.replace(regex, (match, p1, p2, p3) => {
|
||||
return `${p1}${specialCase}${p3}`;
|
||||
});
|
||||
});
|
||||
|
||||
return normalizedTimeZone;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
import { CapitalizeTimeZone } from "@/lib/inputs/capitalize-timezone";
|
||||
import { ApiProperty } from "@nestjs/swagger";
|
||||
import { IsOptional, IsTimeZone, IsString } from "class-validator";
|
||||
|
||||
@@ -26,6 +27,7 @@ export class CreateManagedUserInput {
|
||||
|
||||
@IsTimeZone()
|
||||
@IsOptional()
|
||||
@CapitalizeTimeZone()
|
||||
@ApiProperty({ example: "America/New_York" })
|
||||
timeZone?: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user