feat: add shared unstable listing classifier
This commit is contained in:
84
packages/core/test/unstable-listing-mode.test.ts
Normal file
84
packages/core/test/unstable-listing-mode.test.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import type { ListingDetails } from "../src/types/common";
|
||||
import { classifyUnstableListings } from "../src/utils/unstable";
|
||||
|
||||
interface TestListing extends ListingDetails {
|
||||
id: string;
|
||||
}
|
||||
|
||||
function makeListing(id: string, cents: number): TestListing {
|
||||
return {
|
||||
id,
|
||||
url: `https://example.com/${id}`,
|
||||
title: id,
|
||||
listingPrice: {
|
||||
amountFormatted: `$${(cents / 100).toFixed(2)}`,
|
||||
cents,
|
||||
currency: "CAD",
|
||||
},
|
||||
listingType: "test",
|
||||
listingStatus: "active",
|
||||
};
|
||||
}
|
||||
|
||||
describe("classifyUnstableListings", () => {
|
||||
test("moves listings below 80% of median into unstableResults", () => {
|
||||
const listings = [
|
||||
makeListing("stable-1", 100_00),
|
||||
makeListing("stable-2", 110_00),
|
||||
makeListing("unstable", 70_00),
|
||||
];
|
||||
|
||||
const buckets = classifyUnstableListings(listings);
|
||||
|
||||
expect(buckets.results.map((listing) => listing.id)).toEqual(["stable-1", "stable-2"]);
|
||||
expect(buckets.unstableResults.map((listing) => listing.id)).toEqual(["unstable"]);
|
||||
});
|
||||
|
||||
test("uses the midpoint median for even-sized priced inputs", () => {
|
||||
const listings = [
|
||||
makeListing("low", 79_00),
|
||||
makeListing("mid-low", 100_00),
|
||||
makeListing("mid-high", 120_00),
|
||||
makeListing("high", 140_00),
|
||||
];
|
||||
|
||||
const buckets = classifyUnstableListings(listings);
|
||||
|
||||
expect(buckets.results.map((listing) => listing.id)).toEqual(["mid-low", "mid-high", "high"]);
|
||||
expect(buckets.unstableResults.map((listing) => listing.id)).toEqual(["low"]);
|
||||
});
|
||||
|
||||
test("keeps non-positive prices in results and excludes them from the median input", () => {
|
||||
const listings = [
|
||||
makeListing("zero", 0),
|
||||
makeListing("negative", -500),
|
||||
makeListing("stable-1", 100_00),
|
||||
makeListing("stable-2", 120_00),
|
||||
makeListing("unstable", 70_00),
|
||||
];
|
||||
|
||||
const buckets = classifyUnstableListings(listings);
|
||||
|
||||
expect(buckets.results.map((listing) => listing.id)).toEqual([
|
||||
"zero",
|
||||
"negative",
|
||||
"stable-1",
|
||||
"stable-2",
|
||||
]);
|
||||
expect(buckets.unstableResults.map((listing) => listing.id)).toEqual(["unstable"]);
|
||||
});
|
||||
|
||||
test("returns all listings in results when fewer than two valid prices are present", () => {
|
||||
const listings = [
|
||||
makeListing("zero", 0),
|
||||
makeListing("negative", -100),
|
||||
makeListing("only-valid", 150_00),
|
||||
];
|
||||
|
||||
const buckets = classifyUnstableListings(listings);
|
||||
|
||||
expect(buckets.results.map((listing) => listing.id)).toEqual(["zero", "negative", "only-valid"]);
|
||||
expect(buckets.unstableResults).toEqual([]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user