Files
Zumri-Backend/tests/unit/phase10-support-recommendation.test.js
T
Sathira Sri Sathara f920ca8920
CI / test (push) Successful in 10m22s
CI / test (pull_request) Successful in 10m53s
feat: Implement Phase 10 support and recommendations features
- Added models for support messages, SLA policies, tickets, ticket events, and ticket links.
- Created routes for help, help admin, newsletter, recommendations, and support for both customer and admin.
- Developed services for help, marketing (newsletter), and recommendations.
- Introduced support service for ticket management, including creation, replies, transitions, and attachments.
- Added validation schemas for support recommendations and ticket management.
- Implemented a cron job for support reconciliation and recommendation cleanup.
- Created migration for new support and recommendation database tables.
- Added unit tests for validation and policy checks related to Phase 10 features.
2026-09-09 16:07:31 +05:30

21 lines
2.9 KiB
JavaScript

jest.mock("../../app/services/activity.service",()=>({logActivity:jest.fn()}));
const schemas=require("../../app/validation/supportRecommendation.schemas"),newsletter=require("../../app/services/marketing/newsletter.service"),help=require("../../app/services/help/help.service"),support=require("../../app/services/support/support.service"),permissions=require("../../app/constants/permissions");
const parse=(schema,body)=>schema.safeParse({body,params:{},query:{}});
describe("Phase 10 validation and policy",()=>{
test("ticket accepts safe customer fields",()=>expect(parse(schemas.ticketCreate,{subject:"Missing parcel",message:"Please check this order",attachmentIds:[],source:"WEB"}).success).toBe(true));
test("ticket rejects ownership injection",()=>expect(parse(schemas.ticketCreate,{subject:"Missing parcel",message:"Please check",customerUserId:"other"}).success).toBe(false));
test("customer cannot submit priority",()=>expect(parse(schemas.ticketCreate,{subject:"Urgent parcel",message:"Please check",priority:"URGENT"}).success).toBe(false));
test("empty support messages are rejected",()=>expect(parse(schemas.message,{message:" "}).success).toBe(false));
test("support attachments are bounded",()=>expect(parse(schemas.message,{message:"ok",attachmentIds:[1,2,3,4,5,6]}).success).toBe(false));
test("ticket links use a strict resource allowlist",()=>expect(parse(schemas.link,{type:"USER",id:"x"}).success).toBe(false));
test("closed tickets have no outbound transitions",()=>expect(support.transitions.CLOSED).toEqual([]));
test("resolved tickets may explicitly reopen",()=>expect(support.transitions.RESOLVED).toContain("WAITING_FOR_SUPPORT"));
test("newsletter email normalization is deterministic",()=>expect(newsletter.normalize(" PERSON@Example.COM ")).toBe("person@example.com"));
test("newsletter authorization tokens are hashable without storage of raw token",()=>{const token="a-secure-random-token";expect(newsletter.hash(token)).toMatch(/^[a-f0-9]{64}$/);expect(newsletter.hash(token)).not.toBe(token);});
test("newsletter source is allowlisted",()=>expect(parse(schemas.newsletter,{email:"a@example.com",source:"SCRAPED_LIST"}).success).toBe(false));
test("client event schema only accepts product views",()=>expect(parse(schemas.viewEvent,{eventId:"evt-1",productId:"p1",eventType:"PURCHASE"}).success).toBe(false));
test("client event rejects unknown mutation fields",()=>expect(parse(schemas.viewEvent,{eventId:"evt-1",productId:"p1",source:"WEB",email:"private@example.com"}).success).toBe(false));
test("help content strips HTML tags",()=>expect(help.clean("<script>alert(1)</script>Safe")).toBe("alert(1)Safe"));
test("all privileged Phase 10 permissions are explicit",()=>expect([permissions.SUPPORT_TICKETS_READ,permissions.HELP_MANAGE,permissions.NEWSLETTER_SUBSCRIBERS_READ,permissions.RECOMMENDATIONS_MANAGE]).toEqual(["support.tickets.read","help.manage","newsletter.subscribers.read","recommendations.manage"]));
});