Skip to content

Commit

Permalink
NEW: Implement sorting in REST API (#130)
Browse files Browse the repository at this point in the history
Partially implements #130
  • Loading branch information
dwhieb committed Jul 14, 2024
1 parent 326ee5c commit 2832ad2
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 22 deletions.
11 changes: 6 additions & 5 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"citation-js": "^0.7.12",
"csv-parse": "^5.5.6",
"csv-stringify": "^6.5.0",
"cypress": "^13.10.0",
"cypress": "^13.13.0",
"esbuild": "^0.21.3",
"esbuild-plugin-browserslist": "^0.12.0",
"esbuild-plugin-less": "^1.3.4",
Expand Down
49 changes: 39 additions & 10 deletions pages/Search/Search.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,26 +35,55 @@ export function Search(req, res) {
q,
} = req.query

limit = Number(limit)
offset = Number(offset)
q = q.trim().toLowerCase()
// Search

q = q.trim().toLowerCase()

const allResults = req.app.db.search(q)
const results = allResults.slice(offset, offset + limit)
const url = new URL(req.originalUrl, `${ req.protocol }://${ req.host }`)

// Sort

if (req.query.sort) {

const sortDirectives = req.query.sort
.split(`,`)
.map(directive => ({
ascending: !directive.startsWith(`-`),
field: directive.replace(/^-/v, ``),
}))

allResults.sort((a, b) => {

const comparisons = sortDirectives.map(({ ascending, field }) => {
const comparison = (a[field] || ``).localeCompare(b[field] || ``)
return ascending ? comparison : comparison * -1
})

return comparisons.reduce((state, comparison) => state ? state : comparison, 0)

})

}

// Pagination

const lastPageOffset = Math.floor(allResults.length / limit) * limit
const nextPageOffset = Math.min(offset + limit, allResults.length)
const prevPageOffset = Math.max(offset - limit, 0)
limit = Number(limit)
offset = Number(offset)

const results = allResults.slice(offset, offset + limit)

const numAdjacentPages = 5
const lastPageOffset = Math.floor(allResults.length / limit) * limit
const nextPageOffset = Math.min(offset + limit, allResults.length)
const prevPageOffset = Math.max(offset - limit, 0)
const url = new URL(req.originalUrl, `${ req.protocol }://${ req.host }`)

const prevPages = []
const nextPages = []

let prevOffset = offset - limit

while (prevOffset >= 0 && prevPages.length < 5) {
while (prevOffset >= 0 && prevPages.length < numAdjacentPages) {

prevPages.unshift({
link: changeParam(url, `offset`, prevOffset),
Expand All @@ -73,7 +102,7 @@ export function Search(req, res) {

let nextOffset = offset + limit

while (nextOffset <= allResults.length && nextPages.length <= 5) {
while (nextOffset <= allResults.length && nextPages.length <= numAdjacentPages) {

nextPages.push({
link: changeParam(url, `offset`, nextOffset),
Expand Down
31 changes: 25 additions & 6 deletions pages/Search/Search.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,16 +135,35 @@ describe(`Search`, function() {
cy.get(`.results tbody tr`).should(`have.length.of.at.least`, 12000)
})

// NB: Currently testing using querystring
// TODO: Once the page links are implemented, test using that instead.
it(`offset`, function() {
cy.visit(`/search?offset=10&q=`)
// NB: The 11th result in the database is currently Eastern Abenaki Component #5.
cy.get(`.results td`).first().should(`have.text`, `Eastern Abenaki`)
cy.visit(`/search`)
cy.get(`form`).submit()
cy.contains(`.pagination li`, `2`).click()
// NB: The 101st result in the database is currently Arapaho "-nooθ-".
cy.get(`.results td`).first().should(`have.text`, `Arapaho`)
.next()
.should(`have.text`, `-nooθ-`)
})

})

describe(`Sorting`, function() {

// NB: Currently testing using querystring.
// TODO: Once column sorting UI is implemented, test with that instead.
it(`single-column sort`, function() {

cy.visit(`/search?sort=-form&q=`)
cy.get(`.results td`).first().should(`have.text`, `Arapaho`)
.next()
.should(`have.text`, `-ahte`)
.should(`have.text`, `θooxoneeʔ-`)

})

// Wait to test this until Advanced Search is implemented.
// This will make it easier to select a small set of components for testing.
it(`multi-column sort`)

})

})

0 comments on commit 2832ad2

Please sign in to comment.