diff --git a/src/routes/getSearchSegments.ts b/src/routes/getSearchSegments.ts index cbfb1f7..e3a6d27 100644 --- a/src/routes/getSearchSegments.ts +++ b/src/routes/getSearchSegments.ts @@ -1,8 +1,8 @@ import { Request, Response } from "express"; import { db } from "../databases/databases"; -import { ActionType, Category, DBSegment, Service, VideoID } from "../types/segments.model"; +import { ActionType, Category, DBSegment, Service, VideoID, SortableFields } from "../types/segments.model"; import { getService } from "../utils/getService"; -const segmentsPerPage = 10; +const maxSegmentsPerPage = 100; type searchSegmentResponse = { segmentCount: number, @@ -19,6 +19,22 @@ function getSegmentsFromDBByVideoID(videoID: VideoID, service: Service): Promise ) as Promise; } +function getSortField(...value: T[]): SortableFields { + const fieldByName = Object.values(SortableFields).reduce((acc, fieldName) => { + acc[fieldName.toLowerCase()] = fieldName; + + return acc; + }, {} as Record); + + for (const name of value) { + if (name?.trim().toLowerCase() in fieldByName) { + return fieldByName[name.trim().toLowerCase()]; + } + } + + return SortableFields.timeSubmitted; +} + /** * * Returns what would be sent to the client. @@ -64,6 +80,10 @@ async function handleGetSegments(req: Request, res: Response): Promise maxSegmentsPerPage ? maxSegmentsPerPage : Number(limit); + const sortBy: SortableFields = getSortField(req.query.sortBy, req.body.sortBy); + const sortDir: string = req.query.sortDir ?? req.body.sortDir ?? "asc"; const minVotes: number = req.query.minVotes ?? req.body.minVotes ?? -3; const maxVotes: number = req.query.maxVotes ?? req.body.maxVotes ?? Infinity; @@ -99,11 +119,11 @@ async function handleGetSegments(req: Request, res: Response): Promise) { - const startIndex = 0+(page*segmentsPerPage); - const endIndex = segmentsPerPage+(page*segmentsPerPage); +function filterSegments(segments: DBSegment[], filters: Record, page: number, limit: number, sortBy: SortableFields, sortDir: string) { + const startIndex = 0+(page*limit); + const endIndex = limit+(page*limit); const filteredSegments = segments.filter((segment) => !((segment.votes < filters.minVotes || segment.votes > filters.maxVotes) || (segment.views < filters.minViews || segment.views > filters.maxViews) @@ -114,10 +134,27 @@ function filterSegments(segments: DBSegment[], page: number, filters: Record { + const key = sortDir === "desc" ? 1 : -1; + if (a[sortBy] < b[sortBy]) { + return key; + } + + if (a[sortBy] > b[sortBy]) { + return -key; + } + + return 0; + }); + } + return { segmentCount: filteredSegments.length, page, segments: filteredSegments.slice(startIndex, endIndex) + }; } diff --git a/src/types/segments.model.ts b/src/types/segments.model.ts index a94bd8e..ba613c4 100644 --- a/src/types/segments.model.ts +++ b/src/types/segments.model.ts @@ -107,4 +107,12 @@ export interface LockCategory { reason: string, videoID: VideoID, userID: UserID -} \ No newline at end of file +} + +export enum SortableFields { + timeSubmitted = "timeSubmitted", + startTime = "startTime", + endTime = "endTime", + votes = "votes", + views = "views", +} diff --git a/test/cases/getSearchSegments.ts b/test/cases/getSearchSegments.ts index d330f55..dc8a3d8 100644 --- a/test/cases/getSearchSegments.ts +++ b/test/cases/getSearchSegments.ts @@ -282,4 +282,70 @@ describe("getSearchSegments", () => { }) .catch(err => done(err)); }); + + it("Should be able to get with custom limit", (done) => { + client.get(endpoint, { params: { videoID: "searchTest4", limit: 2 } }) + .then(res => { + assert.strictEqual(res.status, 200); + const data = res.data; + const segments = data.segments; + assert.strictEqual(data.segmentCount, 12); + assert.strictEqual(data.page, 0); + assert.strictEqual(segments.length, 2); + done(); + }) + .catch(err => done(err)); + }); + + it("Should be able to get with custom limit(2) and page(2)", (done) => { + client.get(endpoint, { params: { videoID: "searchTest4", limit: 2, page: 2 } }) + .then(res => { + assert.strictEqual(res.status, 200); + const data = res.data; + const segments = data.segments; + assert.strictEqual(data.segmentCount, 12); + assert.strictEqual(data.page, 2); + assert.strictEqual(segments.length, 2); + assert.strictEqual(segments[0].UUID, "search-page1-5"); + assert.strictEqual(segments[1].UUID, "search-page1-6"); + done(); + }) + .catch(err => done(err)); + }); + + it("Should be able to get sorted result (desc)", (done) => { + client.get(endpoint, { params: { videoID: "searchTest4", sortBy: "endTime", sortDir: "desc" } }) + .then(res => { + assert.strictEqual(res.status, 200); + const data = res.data; + const segments = data.segments; + assert.strictEqual(data.segmentCount, 12); + assert.strictEqual(data.page, 0); + assert.strictEqual(segments[0].UUID, "search-page2-2"); + assert.strictEqual(segments[1].UUID, "search-page2-1"); + assert.strictEqual(segments[2].UUID, "search-page1-10"); + assert.strictEqual(segments[3].UUID, "search-page1-9"); + assert.strictEqual(segments[4].UUID, "search-page1-8"); + done(); + }) + .catch(err => done(err)); + }); + + it("Should be able to get sorted result (asc)", (done) => { + client.get(endpoint, { params: { videoID: "searchTest4", sortBy: "endTime" } }) + .then(res => { + assert.strictEqual(res.status, 200); + const data = res.data; + const segments = data.segments; + assert.strictEqual(data.segmentCount, 12); + assert.strictEqual(data.page, 0); + assert.strictEqual(segments[0].UUID, "search-page1-1"); + assert.strictEqual(segments[1].UUID, "search-page1-2"); + assert.strictEqual(segments[2].UUID, "search-page1-3"); + assert.strictEqual(segments[3].UUID, "search-page1-4"); + assert.strictEqual(segments[4].UUID, "search-page1-5"); + done(); + }) + .catch(err => done(err)); + }); });