Skip to content

Commit

Permalink
Merge branch 'master' into Shayan/Nada/DSEC-56992/upgrade-happy-dom-t…
Browse files Browse the repository at this point in the history
…o-the-latest-version
  • Loading branch information
shayan-deriv authored Nov 26, 2024
2 parents 6fa8a48 + c4c5b7f commit 4c1e4b4
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/constants/validation.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const patterns = {
* @example ValidationConstants.patterns.addressState.test("New York")
* @example ValidationConstants.patterns.addressState.test("Québec")
**/
addressState: /^[\p{L}\p{Nd}\s'.,-;]{0,100}$/u,
addressState: /^[\p{L}\p{Nd}\s'.,(),-;]{0,100}$/u,
/**
* @regex /^(?=.{1,20}$)[+-]?[0-9]+\.?[0-9]*$/
* @description This pattern matches any string with 0-9 characters (numeric values. i.e. both integers and floats), and may contain a '+' or '-' sign.
Expand Down
52 changes: 29 additions & 23 deletions src/utils/__test__/country.utils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,44 @@
import { describe, beforeEach, afterEach, it, expect, vi } from "vitest";
import { describe, beforeEach, it, expect, vi, Mock } from "vitest";
import { getCountry } from "../country.utils";
import Cookies from "js-cookie";

vi.mock("js-cookie");
global.fetch = vi.fn();

describe("getCountry", () => {
beforeEach(() => {
global.fetch = vi.fn();
});

afterEach(() => {
vi.resetAllMocks();
vi.clearAllMocks();
vi.resetModules();
});

it("should return the country code in lowercase when available", async () => {
// Mock fetch response
(global.fetch as vi.Mock).mockResolvedValue({
text: async () => "loc=US\nother=info\n",
it("should return country code from Cloudflare trace", async () => {
(global.fetch as Mock).mockResolvedValueOnce({
text: () => Promise.resolve("loc=US\nother=value"),
});

const country = await getCountry();
expect(country).toBe("us");
const result = await getCountry();
expect(result).toBe("us");
});

it("should return an empty string if the loc field is not present", async () => {
(global.fetch as vi.Mock).mockResolvedValue({
text: async () => "other=info\n",
});
it("should return country code from cookie when Cloudflare fails", async () => {
vi.clearAllMocks();
vi.resetModules();

const country = await getCountry();
expect(country).toBe("");
});
(global.fetch as Mock).mockRejectedValueOnce(new Error("Network error"));
(Cookies.get as Mock).mockReturnValue(JSON.stringify({ clients_country: "fr" }));

it("should return an empty string if the fetch fails", async () => {
(global.fetch as vi.Mock).mockRejectedValue(new Error("Fetch failed"));
const { getCountry } = await import("../country.utils");
const result = await getCountry();
expect(result).toBe("fr");
});

const country = await getCountry();
expect(country).toBe("");
it("should return empty string if no country data is available", async () => {
vi.clearAllMocks();
vi.resetModules();
(global.fetch as Mock).mockRejectedValueOnce(new Error("Network error"));
(Cookies.get as Mock).mockReturnValue(JSON.stringify({}));
const { getCountry } = await import("../country.utils");
const result = await getCountry();
expect(result).toBe("");
});
});
31 changes: 21 additions & 10 deletions src/utils/country.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { cloudflareTrace } from "../constants/url.constants";
type TraceData = {
loc?: string;
};
let countryPromise: Promise<string> | null = null;

/**
* Fetches the country information based on Cloudflare's trace data or a fallback from cookies.
Expand All @@ -19,14 +20,24 @@ type TraceData = {
*/

export const getCountry = async (): Promise<string> => {
try {
const response = await fetch(cloudflareTrace).catch(() => null);
if (!response) return "";
const text = await response.text().catch(() => "");
const entries = text ? text.split("\n").map((v) => v.split("=", 2)) : [];
const data: TraceData = entries.length ? Object.fromEntries(entries) : {};
return data.loc?.toLowerCase() || JSON.parse(Cookies.get("website_status") || "{}")?.loc || "";
} catch (error) {
return "";
}
if (countryPromise) return countryPromise;

const cookieCountry = JSON.parse(Cookies.get("website_status") || "{}")?.clients_country;

countryPromise = (async () => {
try {
const response = await fetch(cloudflareTrace).catch(() => null);
if (!response) return cookieCountry || "";

const text = await response.text().catch(() => "");
if (!text) return cookieCountry || "";

const data: TraceData = Object.fromEntries(text.split("\n").map((v) => v.split("=", 2)));
return data.loc?.toLowerCase() || cookieCountry || "";
} catch {
return cookieCountry || "";
}
})();

return countryPromise;
};
5 changes: 3 additions & 2 deletions utils-docs/docs/Constants/validation.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,13 @@ addressCity: /^\p{L}[\p{L}\s'.-]{0,49}$/u;

### addressState

This pattern matches any string that contains up to **100** characters composed of Unicode letters, Unicode digits, whitespace characters, apostrophes, periods, commas, hyphens, and semicolons `( '.,-;)`.
This pattern matches any string that contains up to **100** characters composed of Unicode letters, Unicode digits, whitespace characters, apostrophes, periods, commas, hyphens, brackets, and semicolons `( '.,-();)`.

```JS
// @example ValidationConstants.patterns.addressState.test("New York")
// @example ValidationConstants.patterns.addressState.test("Québec")
addressState: /^[\p{L}\p{Nd}\s'.,-;]{0,100}$/u,
// @example ValidationConstants.patterns.addressState.test("Lagunes (Région des)")
addressState: /^[\p{L}\p{Nd}\s'.,(),-;]{0,100}$/u,
```

### barrier
Expand Down

0 comments on commit 4c1e4b4

Please sign in to comment.