Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 21 additions & 3 deletions backend/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,10 +201,10 @@ const resolvers = {
sortOrder = { titleSort: -1, id: 1 };
break;
case "ARTIST_ASC":
sortOrder = { artist_display: 1, id: 1 };
sortOrder = { artistUnknown: 1, artist_display: 1, id: 1 };
break;
case "ARTIST_DESC":
sortOrder = { artist_display: -1, id: 1 };
sortOrder = { artistUnknown: 1, artist_display: -1, id: 1 };
break;
default:
sortOrder = { id: 1 };
Expand All @@ -217,6 +217,24 @@ const resolvers = {
{ $match: filter },
{
$set: {
artistUnknown: {
$cond: [
{
$in: [
{
$toLower: {
$trim: {
input: { $ifNull: ["$artist_display", ""] },
},
},
},
["", "unknown"],
],
},
1,
0,
],
},
titleSort: {
$reduce: {
input: ['"', "“", "”"],
Expand All @@ -235,7 +253,7 @@ const resolvers = {
{ $sort: sortOrder },
{ $skip: offset },
{ $limit: limit },
{ $unset: "titleSort" },
{ $unset: ["titleSort", "artistUnknown"] },
],
{
collation: { locale: "en", strength: 1 },
Expand Down
42 changes: 42 additions & 0 deletions backend/tests/artworks-sorting.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,12 @@ async function fetchArtworks(
return result.data.artworks;
}

function isUnknownArtist(artist: string | null | undefined): boolean {
const name = artist?.trim().toLowerCase() ?? "";

return name === "" || name === "unknown";
}

describe("Artwork sorting API", () => {
it("sorts by ascending ID when no sorting option is provided", async () => {
const result = await fetchArtworks();
Expand Down Expand Up @@ -178,6 +184,7 @@ describe("Artwork sorting API", () => {
},
]);
});

it("ignores curly double quotes when sorting titles", async () => {
const result = await fetchArtworks("TITLE_ASC", 100, 0, "painting");

Expand All @@ -198,4 +205,39 @@ describe("Artwork sorting API", () => {
"“Bamboo” section, from the Mustard Seed Garden Manual of Painting",
);
});

it.each<ArtworkSort>(["ARTIST_ASC", "ARTIST_DESC"])(
"places unknown artists last across pages with %s",
async (sort) => {
const pageSize = 100;
const firstPage = await fetchArtworks(sort, pageSize, 0);
const artworks = [...firstPage.artworks];

for (
let offset = pageSize;
offset < firstPage.totalCount;
offset += pageSize
) {
const page = await fetchArtworks(sort, pageSize, offset);

expect(page.totalCount).toBe(firstPage.totalCount);
artworks.push(...page.artworks);
}

expect(artworks).toHaveLength(firstPage.totalCount);

const firstUnknownIndex = artworks.findIndex((artwork) =>
isUnknownArtist(artwork.artist_display),
);

expect(firstUnknownIndex).toBeGreaterThan(0);

for (const artwork of artworks.slice(firstUnknownIndex)) {
expect(isUnknownArtist(artwork.artist_display)).toBe(true);
}

const ids = artworks.map((artwork) => artwork.id);
expect(new Set(ids).size).toBe(artworks.length);
},
);
});