You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
4.5 KiB
119 lines
4.5 KiB
import { describe, expect, it } from "vitest";
|
|
import { getInitialMarriageProfile } from "@/hooks/marriage/use-profile-main";
|
|
import type { MarriageProfileResponse } from "@/hooks/marriage/types";
|
|
|
|
/**
|
|
* Robust parser replicating the layout.tsx and auth-bridge.ts cookie resolution strategy.
|
|
*/
|
|
export function parseMarriageCookie(
|
|
rawCookie: string | null | undefined,
|
|
): { parsedJson: any; profile?: MarriageProfileResponse } | null {
|
|
if (!rawCookie || !rawCookie.trim()) return null;
|
|
|
|
const trimmed = rawCookie.trim();
|
|
|
|
// Strategy 1: Try decoding URI component first (Standard RFC-6265 percent-encoded cookie from Flutter)
|
|
try {
|
|
const decoded = decodeURIComponent(trimmed);
|
|
const parsed = JSON.parse(decoded);
|
|
return {
|
|
parsedJson: parsed,
|
|
profile: getInitialMarriageProfile(parsed),
|
|
};
|
|
} catch {
|
|
// Strategy 2: Fallback for legacy raw unencoded JSON cookies
|
|
try {
|
|
const parsed = JSON.parse(trimmed);
|
|
return {
|
|
parsedJson: parsed,
|
|
profile: getInitialMarriageProfile(parsed),
|
|
};
|
|
} catch {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
describe("HABIB_MARRIAGE_DATA Cookie Encoding & Decoding Suite", () => {
|
|
it("successfully parses standard URL-encoded JSON with Persian characters (Uri.encodeComponent)", () => {
|
|
const originalData = {
|
|
id: 101,
|
|
status: "match_found",
|
|
gender: "male",
|
|
city: "تهران",
|
|
bio: "مهندس کامپیوتر، علاقهمند به کتابخوانی و طبیعتگردی",
|
|
match_summary: {
|
|
id: 202,
|
|
gender: "female",
|
|
public_info: [
|
|
{ label: "شهر", value: "اصفهان" },
|
|
{ label: "تحصیلات", value: "کارشناسی ارشد" },
|
|
],
|
|
},
|
|
};
|
|
|
|
// Simulate Flutter: Uri.encodeComponent(json.encode(marriageData))
|
|
const encodedCookie = encodeURIComponent(JSON.stringify(originalData));
|
|
|
|
// Verify it's purely US-ASCII
|
|
expect(/^[\x00-\x7F]*$/.test(encodedCookie)).toBe(true);
|
|
|
|
const result = parseMarriageCookie(encodedCookie);
|
|
expect(result).not.toBeNull();
|
|
expect(result?.parsedJson.city).toBe("تهران");
|
|
expect(result?.parsedJson.bio).toBe("مهندس کامپیوتر، علاقهمند به کتابخوانی و طبیعتگردی");
|
|
expect(result?.parsedJson.match_summary.public_info[0].value).toBe("اصفهان");
|
|
expect(result?.profile?.status).toBe("match_found");
|
|
});
|
|
|
|
it("successfully parses legacy raw unencoded JSON with Persian characters", () => {
|
|
const legacyRawCookie = JSON.stringify({
|
|
id: 102,
|
|
status: "active",
|
|
gender: "female",
|
|
city: "مشهد",
|
|
interests: ["زیارت", "خانواده"],
|
|
});
|
|
|
|
const result = parseMarriageCookie(legacyRawCookie);
|
|
expect(result).not.toBeNull();
|
|
expect(result?.parsedJson.city).toBe("مشهد");
|
|
expect(result?.parsedJson.interests).toEqual(["زیارت", "خانواده"]);
|
|
});
|
|
|
|
it("handles complex strings with percentage signs, quotes, and emojis without crashing", () => {
|
|
const complexData = {
|
|
id: 103,
|
|
status: "match_found",
|
|
note: "تطابق با دقت ۱۰۰% و رضایت ۹۵% 💍❤️",
|
|
query: "param1=val¶m2=50%off",
|
|
};
|
|
|
|
const encodedCookie = encodeURIComponent(JSON.stringify(complexData));
|
|
const result = parseMarriageCookie(encodedCookie);
|
|
|
|
expect(result).not.toBeNull();
|
|
expect(result?.parsedJson.note).toBe("تطابق با دقت ۱۰۰% و رضایت ۹۵% 💍❤️");
|
|
expect(result?.parsedJson.query).toBe("param1=val¶m2=50%off");
|
|
});
|
|
|
|
it("handles unencoded JSON containing raw percent sign gracefully via fallback", () => {
|
|
// If an unencoded cookie contains raw %, decodeURIComponent will throw URIError.
|
|
// The parser MUST catch it and fallback to JSON.parse directly.
|
|
const rawWithPercent = '{"status":"active","progress":"100% completed","city":"شیراز"}';
|
|
|
|
const result = parseMarriageCookie(rawWithPercent);
|
|
expect(result).not.toBeNull();
|
|
expect(result?.parsedJson.progress).toBe("100% completed");
|
|
expect(result?.parsedJson.city).toBe("شیراز");
|
|
});
|
|
|
|
it("returns null safely for corrupted, empty, or invalid cookies", () => {
|
|
expect(parseMarriageCookie(null)).toBeNull();
|
|
expect(parseMarriageCookie("")).toBeNull();
|
|
expect(parseMarriageCookie(" ")).toBeNull();
|
|
expect(parseMarriageCookie("undefined")).toBeNull();
|
|
expect(parseMarriageCookie("invalid-not-json")).toBeNull();
|
|
expect(parseMarriageCookie("%E0%A4%A")).toBeNull(); // Malformed URI sequence
|
|
});
|
|
});
|