fantasy-manager/cypress/e2e/download.cy.js
Lukas Schaefer 139541434b
Update nextjs to v16, enable react compiler, and fix tests (#938)
* Update to next16 and fix lint errors

Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>

* Enable react compiler and fix cypress

Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>

---------

Signed-off-by: Lukas Schaefer <lukas@lschaefer.xyz>
2026-02-04 17:14:34 -05:00

170 lines
4.6 KiB
JavaScript

describe("Download Bundesliga data as JSON and CSV", () => {
const LEAGUE = "Bundesliga";
const EXPECTED_JSON_FIELDS = [
"uid",
"name",
"nameAscii",
"club",
"pictureUrl",
"value",
"sale_price",
"position",
"forecast",
"total_points",
"average_points",
"last_match",
"exists",
"league",
];
const EXPECTED_CSV_HEADERS = [
"Playeruid",
"Name",
"Ascii Name",
"Club",
"Picture Url",
"Value",
"Sale Price",
"Position",
"Forecast",
"Total Points",
"Average Points",
"Last Match Points",
"Exists",
"League",
];
before(() => {
cy.exec(
"export APP_ENV=test; ts-node --project=./tsconfig2.json cypress/e2e/download1.ts",
);
});
it("downloads JSON and verifies format", () => {
cy.request({
method: "GET",
url: `/api/download`,
qs: { type: "json", league: LEAGUE },
failOnStatusCode: false,
}).then((response) => {
expect(response.status).to.eq(200);
expect(response.headers["content-type"]).to.include("application/json");
expect(response.headers["content-disposition"]).to.include(
"filename=players.json",
);
const data = response.body;
expect(data).to.be.an("array");
expect(data.length).to.be.greaterThan(0);
data.forEach((player, index) => {
expect(player, `Player at index ${index}`).to.be.an("object");
EXPECTED_JSON_FIELDS.forEach((field) => {
expect(
player,
`Player at index ${index} should have field '${field}'`,
).to.have.property(field);
});
expect(player.league).to.eq(LEAGUE);
expect(player.uid).to.be.a("string");
expect(player.name).to.be.a("string");
expect(player.club).to.be.a("string");
expect(player.value).to.be.a("number");
expect(player.total_points).to.be.a("number");
expect(player.average_points).to.be.a("number");
expect(player.pictureUrl).to.include(
encodeURIComponent("/api/picture/"),
);
});
});
});
it("downloads CSV and verifies format", () => {
cy.request({
method: "GET",
url: `/api/download`,
qs: { type: "csv", league: LEAGUE },
failOnStatusCode: false,
}).then((response) => {
expect(response.status).to.eq(200);
expect(response.headers["content-type"]).to.include("application/csv");
expect(response.headers["content-disposition"]).to.include(".csv");
const csvText = response.body;
expect(csvText).to.be.a("string");
expect(csvText.length).to.be.greaterThan(0);
const lines = csvText.trim().split("\n");
expect(lines.length).to.be.greaterThan(
1,
"CSV should have header + data",
);
const headerLine = lines[0];
const headers = parseCSVLine(headerLine);
EXPECTED_CSV_HEADERS.forEach((expectedHeader) => {
expect(
headers,
`CSV should contain header '${expectedHeader}'`,
).to.include(expectedHeader);
});
});
});
it("verifies JSON and CSV contain consistent data", () => {
cy.request({
method: "GET",
url: `/api/download`,
qs: { type: "json", league: LEAGUE },
}).then((jsonResponse) => {
cy.request({
method: "GET",
url: `/api/download`,
qs: { type: "csv", league: LEAGUE },
}).then((csvResponse) => {
const jsonData = jsonResponse.body;
const csvLines = csvResponse.body.trim().split("\n");
const csvHeaders = parseCSVLine(csvLines[0]);
const csvRows = csvLines.slice(1).map((line) => parseCSVLine(line));
expect(jsonData.length).to.eq(
csvRows.length,
"JSON and CSV should have same number of players",
);
const uidIndex = csvHeaders.indexOf("Playeruid");
const nameIndex = csvHeaders.indexOf("Name");
expect(uidIndex).to.be.greaterThan(-1);
expect(nameIndex).to.be.greaterThan(-1);
jsonData.forEach((player, index) => {
const csvRow = csvRows[index];
expect(csvRow[uidIndex]).to.eq(player.uid);
expect(csvRow[nameIndex]).to.eq(player.name);
});
});
});
});
});
function parseCSVLine(line) {
const result = [];
let current = "";
let inQuotes = false;
for (let i = 0; i < line.length; i++) {
const char = line[i];
if (char === '"') {
inQuotes = !inQuotes;
} else if ((char === "," && !inQuotes) || char === "\r") {
result.push(current.trim());
current = "";
} else {
current += char;
}
}
result.push(current.trim());
return result;
}