///
const tenderId = "507f1f77bcf86cd799439055";
/** Visible title only — layout probe duplicates `
` off-screen for measurement */
const tenderTitleHeading = () => cy.get("main h1").filter(":visible");
const makeTenderDetailsResponse = (
overrides: Partial> = {},
) => ({
success: true,
message: "ok",
data: {
id: tenderId,
buyer_organization: { name: "ACME Procurement" },
application_deadline: 1710001000,
country_code: "IR",
currency: "USD",
description: "Original description",
duration: "12",
duration_unit: "month",
estimated_value: 100000,
notice_publication_id: "NP-123",
procedure_code: "OPEN",
procurement_type_code: "GOODS",
publication_date: 1710000000,
status: "open",
submission_deadline: 1710002000,
submission_url: "https://example.com/submit",
tender_deadline: 1710003000,
created_at: 1710000000,
tender_id: "TDR-9001",
title: "Original title",
...overrides,
},
});
describe("tender details - translation and summary", () => {
beforeEach(() => {
cy.setAuthCookies();
});
it("renders details with summary fallback and translated metadata", () => {
cy.intercept("GET", `**/api/proxy/tenders/${tenderId}**`, (req) => {
expect(req.query.lang).to.eq("en");
req.reply({
statusCode: 200,
body: makeTenderDetailsResponse({
title: "Translated title EN",
description: "Translated description EN",
language: "en",
overall_summary: undefined,
}),
});
}).as("getTenderDetailsEn");
cy.visit(`/tenders/${tenderId}?lang=en`);
cy.wait("@getTenderDetailsEn");
tenderTitleHeading().should("contain.text", "Translated title EN");
cy.get("#tender-section-translation")
.should("be.visible")
.and("contain.text", "Resolved language")
.and("contain.text", "en");
cy.get("#tender-section-ai-summary")
.should("be.visible")
.and("contain.text", "AI summary")
.and("contain.text", "Summary not ready yet");
cy.get("#tender-section-description")
.should("be.visible")
.and("contain.text", "Translated description EN");
});
it("switches language from selector and reloads details with new lang query", () => {
cy.intercept("GET", `**/api/proxy/tenders/${tenderId}**`, (req) => {
const lang = String(req.query.lang ?? "en");
req.alias = lang === "fr" ? "getTenderDetailsFr" : "getTenderDetailsEn";
req.reply({
statusCode: 200,
body: makeTenderDetailsResponse({
title: lang === "fr" ? "Titre FR" : "Title EN",
description: lang === "fr" ? "Description FR" : "Description EN",
language: lang,
overall_summary: lang === "fr" ? "Resume FR" : "Summary EN",
}),
});
});
cy.visit(`/tenders/${tenderId}?lang=en`);
cy.wait("@getTenderDetailsEn");
cy.get('select[name="lang"]').select("fr");
cy.location("search").should("include", "lang=fr");
cy.wait("@getTenderDetailsFr");
tenderTitleHeading().should("contain.text", "Titre FR");
cy.contains("Resume FR").should("be.visible");
});
it("triggers translate endpoint with selected language", () => {
cy.intercept("GET", `**/api/proxy/tenders/${tenderId}**`, {
statusCode: 200,
body: makeTenderDetailsResponse({
title: "Before translate",
description: "Before translate description",
language: "de",
}),
}).as("getTenderDetails");
cy.intercept(
"POST",
`**/api/proxy/tenders/${tenderId}/ai-translate`,
(req) => {
expect(req.body).to.deep.equal({ language: "de" });
req.reply({
statusCode: 200,
body: {
success: true,
message: "ok",
data: {
notice_id: "NP-123",
language: "de",
translated_title: "Ubersetzter Titel",
translated_description: "Ubersetzte Beschreibung",
},
},
});
},
).as("translateTender");
cy.visit(`/tenders/${tenderId}?lang=de`);
cy.wait("@getTenderDetails");
cy.contains("button", "Translate metadata").click();
cy.wait("@translateTender");
});
it("loads tender details with lang query on the canonical URL", () => {
cy.intercept("GET", `**/api/proxy/tenders/${tenderId}**`, {
statusCode: 200,
body: makeTenderDetailsResponse({
title: "Lang query check",
language: "fa",
}),
}).as("getTenderWithLang");
cy.visit(`/tenders/${tenderId}?lang=fa`);
cy.location("pathname").should("eq", `/tenders/${tenderId}`);
cy.location("search").should("include", "lang=fa");
cy.wait("@getTenderWithLang");
tenderTitleHeading().should("contain.text", "Lang query check");
});
});