feat: add filter and sort controller

This commit is contained in:
2026-04-20 20:07:53 +08:00
parent 98dc078a15
commit 26bdff8daa
3 changed files with 201 additions and 0 deletions
+96
View File
@@ -0,0 +1,96 @@
import { describe, expect, test } from "vitest";
import { applyFilterAndSort } from "../src/content/market/filter-sort-controller";
import type { MarketRecord } from "../src/content/market/types";
const baseRecords: MarketRecord[] = [
{
authorId: "a",
authorName: "Alpha",
status: "success",
rates: {
singleVideoAfterSearchRate: "0.02% - 0.1%",
personalVideoAfterSearchRate: "0.03% - 0.2%"
}
},
{
authorId: "b",
authorName: "Beta",
status: "success",
rates: {
singleVideoAfterSearchRate: "0.5% - 1%",
personalVideoAfterSearchRate: "0.01% - 0.1%"
}
},
{
authorId: "c",
authorName: "Gamma",
status: "failed",
failureReason: "request-failed"
}
];
describe("filter-sort-controller", () => {
test("passes only when the lower bound meets the single-rate threshold", () => {
const result = applyFilterAndSort(baseRecords, {
filters: {
singleVideoAfterSearchRateMin: 0.1
}
});
expect(result.map((record) => record.authorId)).toEqual(["b"]);
});
test("passes only when the lower bound meets the personal-rate threshold", () => {
const result = applyFilterAndSort(baseRecords, {
filters: {
personalVideoAfterSearchRateMin: 0.02
}
});
expect(result.map((record) => record.authorId)).toEqual(["a"]);
});
test("sorts by single-rate descending using the lower bound", () => {
const result = applyFilterAndSort(baseRecords, {
sort: {
direction: "desc",
field: "singleVideoAfterSearchRate"
}
});
expect(result.map((record) => record.authorId)).toEqual(["b", "a", "c"]);
});
test("sorts by personal-rate ascending using the lower bound", () => {
const result = applyFilterAndSort(baseRecords, {
sort: {
direction: "asc",
field: "personalVideoAfterSearchRate"
}
});
expect(result.map((record) => record.authorId)).toEqual(["b", "a", "c"]);
});
test("keeps failed and missing rows at the end", () => {
const result = applyFilterAndSort(
[
...baseRecords,
{
authorId: "d",
authorName: "Delta",
status: "missing"
}
],
{
sort: {
direction: "desc",
field: "singleVideoAfterSearchRate"
}
}
);
expect(result.slice(-2).map((record) => record.authorId)).toEqual(["c", "d"]);
});
});