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

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&param2=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&param2=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
});
});