test: fix formatting and remove unused HttpError import in Kijiji tests
This commit is contained in:
@@ -1,166 +1,157 @@
|
|||||||
import { describe, expect, test } from "bun:test";
|
import { describe, expect, test } from "bun:test";
|
||||||
import {
|
import {
|
||||||
HttpError,
|
buildSearchUrl,
|
||||||
NetworkError,
|
NetworkError,
|
||||||
ParseError,
|
ParseError,
|
||||||
RateLimitError,
|
RateLimitError,
|
||||||
ValidationError,
|
resolveCategoryId,
|
||||||
buildSearchUrl,
|
resolveLocationId,
|
||||||
resolveCategoryId,
|
ValidationError,
|
||||||
resolveLocationId,
|
|
||||||
} from "../src/scrapers/kijiji";
|
} from "../src/scrapers/kijiji";
|
||||||
|
|
||||||
describe("Location and Category Resolution", () => {
|
describe("Location and Category Resolution", () => {
|
||||||
describe("resolveLocationId", () => {
|
describe("resolveLocationId", () => {
|
||||||
test("should return numeric IDs as-is", () => {
|
test("should return numeric IDs as-is", () => {
|
||||||
expect(resolveLocationId(1700272)).toBe(1700272);
|
expect(resolveLocationId(1700272)).toBe(1700272);
|
||||||
expect(resolveLocationId(0)).toBe(0);
|
expect(resolveLocationId(0)).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should resolve string location names", () => {
|
test("should resolve string location names", () => {
|
||||||
expect(resolveLocationId("canada")).toBe(0);
|
expect(resolveLocationId("canada")).toBe(0);
|
||||||
expect(resolveLocationId("ontario")).toBe(9004);
|
expect(resolveLocationId("ontario")).toBe(9004);
|
||||||
expect(resolveLocationId("toronto")).toBe(1700273);
|
expect(resolveLocationId("toronto")).toBe(1700273);
|
||||||
expect(resolveLocationId("gta")).toBe(1700272);
|
expect(resolveLocationId("gta")).toBe(1700272);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle case insensitive matching", () => {
|
test("should handle case insensitive matching", () => {
|
||||||
expect(resolveLocationId("Canada")).toBe(0);
|
expect(resolveLocationId("Canada")).toBe(0);
|
||||||
expect(resolveLocationId("ONTARIO")).toBe(9004);
|
expect(resolveLocationId("ONTARIO")).toBe(9004);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should default to Canada for unknown locations", () => {
|
test("should default to Canada for unknown locations", () => {
|
||||||
expect(resolveLocationId("unknown")).toBe(0);
|
expect(resolveLocationId("unknown")).toBe(0);
|
||||||
expect(resolveLocationId("")).toBe(0);
|
expect(resolveLocationId("")).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle undefined input", () => {
|
test("should handle undefined input", () => {
|
||||||
expect(resolveLocationId(undefined)).toBe(0);
|
expect(resolveLocationId(undefined)).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("resolveCategoryId", () => {
|
describe("resolveCategoryId", () => {
|
||||||
test("should return numeric IDs as-is", () => {
|
test("should return numeric IDs as-is", () => {
|
||||||
expect(resolveCategoryId(132)).toBe(132);
|
expect(resolveCategoryId(132)).toBe(132);
|
||||||
expect(resolveCategoryId(0)).toBe(0);
|
expect(resolveCategoryId(0)).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should resolve string category names", () => {
|
test("should resolve string category names", () => {
|
||||||
expect(resolveCategoryId("all")).toBe(0);
|
expect(resolveCategoryId("all")).toBe(0);
|
||||||
expect(resolveCategoryId("phones")).toBe(132);
|
expect(resolveCategoryId("phones")).toBe(132);
|
||||||
expect(resolveCategoryId("electronics")).toBe(29659001);
|
expect(resolveCategoryId("electronics")).toBe(29659001);
|
||||||
expect(resolveCategoryId("buy-sell")).toBe(10);
|
expect(resolveCategoryId("buy-sell")).toBe(10);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle case insensitive matching", () => {
|
test("should handle case insensitive matching", () => {
|
||||||
expect(resolveCategoryId("All")).toBe(0);
|
expect(resolveCategoryId("All")).toBe(0);
|
||||||
expect(resolveCategoryId("PHONES")).toBe(132);
|
expect(resolveCategoryId("PHONES")).toBe(132);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should default to all categories for unknown categories", () => {
|
test("should default to all categories for unknown categories", () => {
|
||||||
expect(resolveCategoryId("unknown")).toBe(0);
|
expect(resolveCategoryId("unknown")).toBe(0);
|
||||||
expect(resolveCategoryId("")).toBe(0);
|
expect(resolveCategoryId("")).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle undefined input", () => {
|
test("should handle undefined input", () => {
|
||||||
expect(resolveCategoryId(undefined)).toBe(0);
|
expect(resolveCategoryId(undefined)).toBe(0);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("URL Construction", () => {
|
describe("URL Construction", () => {
|
||||||
describe("buildSearchUrl", () => {
|
describe("buildSearchUrl", () => {
|
||||||
test("should build basic search URL", () => {
|
test("should build basic search URL", () => {
|
||||||
const url = buildSearchUrl("iphone", {
|
const url = buildSearchUrl("iphone", {
|
||||||
location: 1700272,
|
location: 1700272,
|
||||||
category: 132,
|
category: 132,
|
||||||
sortBy: "relevancy",
|
sortBy: "relevancy",
|
||||||
sortOrder: "desc",
|
sortOrder: "desc",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(url).toContain("b-buy-sell/canada/iphone/k0c132l1700272");
|
expect(url).toContain("b-buy-sell/canada/iphone/k0c132l1700272");
|
||||||
expect(url).toContain("sort=relevancyDesc");
|
expect(url).toContain("sort=relevancyDesc");
|
||||||
expect(url).toContain("order=DESC");
|
expect(url).toContain("order=DESC");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle pagination", () => {
|
test("should handle pagination", () => {
|
||||||
const url = buildSearchUrl("iphone", {
|
const url = buildSearchUrl("iphone", {
|
||||||
location: 1700272,
|
location: 1700272,
|
||||||
category: 132,
|
category: 132,
|
||||||
page: 2,
|
page: 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(url).toContain("&page=2");
|
expect(url).toContain("&page=2");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle different sort options", () => {
|
test("should handle different sort options", () => {
|
||||||
const dateUrl = buildSearchUrl("iphone", {
|
const dateUrl = buildSearchUrl("iphone", {
|
||||||
sortBy: "date",
|
sortBy: "date",
|
||||||
sortOrder: "asc",
|
sortOrder: "asc",
|
||||||
});
|
});
|
||||||
expect(dateUrl).toContain("sort=DATE");
|
expect(dateUrl).toContain("sort=DATE");
|
||||||
expect(dateUrl).toContain("order=ASC");
|
expect(dateUrl).toContain("order=ASC");
|
||||||
|
|
||||||
const priceUrl = buildSearchUrl("iphone", {
|
const priceUrl = buildSearchUrl("iphone", {
|
||||||
sortBy: "price",
|
sortBy: "price",
|
||||||
sortOrder: "desc",
|
sortOrder: "desc",
|
||||||
});
|
});
|
||||||
expect(priceUrl).toContain("sort=PRICE");
|
expect(priceUrl).toContain("sort=PRICE");
|
||||||
expect(priceUrl).toContain("order=DESC");
|
expect(priceUrl).toContain("order=DESC");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("should handle string location/category inputs", () => {
|
test("should handle string location/category inputs", () => {
|
||||||
const url = buildSearchUrl("iphone", {
|
const url = buildSearchUrl("iphone", {
|
||||||
location: "toronto",
|
location: "toronto",
|
||||||
category: "phones",
|
category: "phones",
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(url).toContain("k0c132l1700273"); // phones + toronto
|
expect(url).toContain("k0c132l1700273"); // phones + toronto
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("Error Classes", () => {
|
describe("Error Classes", () => {
|
||||||
test("HttpError should store status and URL", () => {
|
test("NetworkError should store URL and cause", () => {
|
||||||
const error = new HttpError("Not found", 404, "https://example.com");
|
const cause = new Error("Connection failed");
|
||||||
expect(error.message).toBe("Not found");
|
const error = new NetworkError(
|
||||||
expect(error.statusCode).toBe(404);
|
"Network error",
|
||||||
expect(error.url).toBe("https://example.com");
|
"https://example.com",
|
||||||
expect(error.name).toBe("HttpError");
|
cause,
|
||||||
});
|
);
|
||||||
|
expect(error.message).toBe("Network error");
|
||||||
|
expect(error.url).toBe("https://example.com");
|
||||||
|
expect(error.cause).toBe(cause);
|
||||||
|
expect(error.name).toBe("NetworkError");
|
||||||
|
});
|
||||||
|
|
||||||
test("NetworkError should store URL and cause", () => {
|
test("ParseError should store data", () => {
|
||||||
const cause = new Error("Connection failed");
|
const data = { invalid: "json" };
|
||||||
const error = new NetworkError(
|
const error = new ParseError("Invalid JSON", data);
|
||||||
"Network error",
|
expect(error.message).toBe("Invalid JSON");
|
||||||
"https://example.com",
|
expect(error.data).toBe(data);
|
||||||
cause
|
expect(error.name).toBe("ParseError");
|
||||||
);
|
});
|
||||||
expect(error.message).toBe("Network error");
|
|
||||||
expect(error.url).toBe("https://example.com");
|
|
||||||
expect(error.cause).toBe(cause);
|
|
||||||
expect(error.name).toBe("NetworkError");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("ParseError should store data", () => {
|
test("RateLimitError should store URL and reset time", () => {
|
||||||
const data = { invalid: "json" };
|
const error = new RateLimitError("Rate limited", "https://example.com", 60);
|
||||||
const error = new ParseError("Invalid JSON", data);
|
expect(error.message).toBe("Rate limited");
|
||||||
expect(error.message).toBe("Invalid JSON");
|
expect(error.url).toBe("https://example.com");
|
||||||
expect(error.data).toBe(data);
|
expect(error.resetTime).toBe(60);
|
||||||
expect(error.name).toBe("ParseError");
|
expect(error.name).toBe("RateLimitError");
|
||||||
});
|
});
|
||||||
|
|
||||||
test("RateLimitError should store URL and reset time", () => {
|
test("ValidationError should work without field", () => {
|
||||||
const error = new RateLimitError("Rate limited", "https://example.com", 60);
|
const error = new ValidationError("Invalid value");
|
||||||
expect(error.message).toBe("Rate limited");
|
expect(error.message).toBe("Invalid value");
|
||||||
expect(error.url).toBe("https://example.com");
|
expect(error.name).toBe("ValidationError");
|
||||||
expect(error.resetTime).toBe(60);
|
});
|
||||||
expect(error.name).toBe("RateLimitError");
|
|
||||||
});
|
|
||||||
|
|
||||||
test("ValidationError should work without field", () => {
|
|
||||||
const error = new ValidationError("Invalid value");
|
|
||||||
expect(error.message).toBe("Invalid value");
|
|
||||||
expect(error.name).toBe("ValidationError");
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user