feat(api): implement GET /wikipedia/pages/[id]
This commit is contained in:
parent
376c0fd041
commit
63862b19c0
3
TODO.md
3
TODO.md
@ -32,7 +32,8 @@
|
|||||||
- [x] Init AdonisJS project
|
- [x] Init AdonisJS project
|
||||||
- [x] Create Lucid models and migrations for Wikipedia Database Dump: `pages` and `internal_links` tables
|
- [x] Create Lucid models and migrations for Wikipedia Database Dump: `pages` and `internal_links` tables
|
||||||
- [x] Implement `GET /wikipedia/pages?title=Node.js` to search a page by title (not necessarily with the title sanitized, search with input by user to check if page exists)
|
- [x] Implement `GET /wikipedia/pages?title=Node.js` to search a page by title (not necessarily with the title sanitized, search with input by user to check if page exists)
|
||||||
- [ ] Implement `GET /wikipedia/pages/internal-links/paths?from=Node.js&to=Linux` to get all the possible paths between 2 pages with titles sanitized
|
- [x] Implement `GET /wikipedia/pages/[id]` to get a page and all its internal links with the pageId
|
||||||
|
- [ ] Implement `GET /wikipedia/internal-links/paths?fromPageId=id&toPageId=id` to get all the possible paths between 2 pages
|
||||||
- [x] Setup tests with database + add coverage
|
- [x] Setup tests with database + add coverage
|
||||||
- [x] Setup Health checks
|
- [x] Setup Health checks
|
||||||
- [x] Setup Rate limiting
|
- [x] Setup Rate limiting
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
import "#app/routes/get.js"
|
import "#app/routes/get.js"
|
||||||
import "#app/routes/health/get.js"
|
import "#app/routes/health/get.js"
|
||||||
import "#app/routes/wikipedia/index.js"
|
import "#app/routes/wikipedia/pages/[id]/get.js"
|
||||||
|
import "#app/routes/wikipedia/pages/get.js"
|
||||||
|
@ -1 +0,0 @@
|
|||||||
import "#app/routes/wikipedia/pages/get.js"
|
|
@ -0,0 +1,52 @@
|
|||||||
|
import { PageFactory } from "#database/factories/page_factory.js"
|
||||||
|
import testUtils from "@adonisjs/core/services/test_utils"
|
||||||
|
import db from "@adonisjs/lucid/services/db"
|
||||||
|
import { test } from "@japa/runner"
|
||||||
|
|
||||||
|
test.group("GET /wikipedia/pages/[id]", (group) => {
|
||||||
|
group.each.setup(async () => {
|
||||||
|
return await testUtils.db().truncate()
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should succeeds and get the page with the given id, and get all its internal links", async ({
|
||||||
|
client,
|
||||||
|
}) => {
|
||||||
|
// Arrange - Given
|
||||||
|
const page = await PageFactory.create()
|
||||||
|
const pages = await PageFactory.createMany(10)
|
||||||
|
const internalLinksPages = pages.slice(0, 5)
|
||||||
|
await Promise.all(
|
||||||
|
internalLinksPages.map(async (internalLinkPage) => {
|
||||||
|
await db.table("internal_links").insert({
|
||||||
|
from_page_id: page.id,
|
||||||
|
to_page_id: internalLinkPage.id,
|
||||||
|
})
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
// Act - When
|
||||||
|
const response = await client.get(`/wikipedia/pages/${page.id}`)
|
||||||
|
|
||||||
|
// Assert - Then
|
||||||
|
response.assertStatus(200)
|
||||||
|
response.assertBody({
|
||||||
|
...page.toJSON(),
|
||||||
|
internalLinks: internalLinksPages.map((page) => {
|
||||||
|
return page.toJSON()
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("should fails with a 404 status code when the page with the given id does not exist", async ({
|
||||||
|
client,
|
||||||
|
}) => {
|
||||||
|
// Arrange - Given
|
||||||
|
const page = await PageFactory.create()
|
||||||
|
|
||||||
|
// Act - When
|
||||||
|
const response = await client.get(`/wikipedia/pages/${page.id + 1}`)
|
||||||
|
|
||||||
|
// Assert - Then
|
||||||
|
response.assertStatus(404)
|
||||||
|
})
|
||||||
|
})
|
24
apps/api/src/app/routes/wikipedia/pages/[id]/get.ts
Normal file
24
apps/api/src/app/routes/wikipedia/pages/[id]/get.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import Page from "#app/models/page.js"
|
||||||
|
import { throttle } from "#start/limiter.js"
|
||||||
|
import type { HttpContext } from "@adonisjs/core/http"
|
||||||
|
import router from "@adonisjs/core/services/router"
|
||||||
|
import vine from "@vinejs/vine"
|
||||||
|
|
||||||
|
const requestValidator = vine.compile(
|
||||||
|
vine.object({
|
||||||
|
params: vine.object({
|
||||||
|
id: vine.number().withoutDecimals().positive(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
public async handle(context: HttpContext): Promise<Page> {
|
||||||
|
const payload = await context.request.validateUsing(requestValidator)
|
||||||
|
const page = await Page.findOrFail(payload.params.id)
|
||||||
|
await page.load("internalLinks")
|
||||||
|
return page
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
router.get("/wikipedia/pages/:id", [Controller]).use(throttle)
|
@ -7,7 +7,7 @@ const databaseConfig = defineConfig({
|
|||||||
connection: app.inTest ? "sqlite" : "postgres",
|
connection: app.inTest ? "sqlite" : "postgres",
|
||||||
connections: {
|
connections: {
|
||||||
postgres: {
|
postgres: {
|
||||||
debug: !app.inProduction,
|
debug: app.inDev,
|
||||||
client: "pg",
|
client: "pg",
|
||||||
connection: {
|
connection: {
|
||||||
host: env.get("DATABASE_HOST"),
|
host: env.get("DATABASE_HOST"),
|
||||||
|
@ -8,4 +8,7 @@ export const PageFactory = factory
|
|||||||
title: sanitizePageTitle(faker.commerce.productName()),
|
title: sanitizePageTitle(faker.commerce.productName()),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.relation("internalLinks", () => {
|
||||||
|
return []
|
||||||
|
})
|
||||||
.build()
|
.build()
|
||||||
|
Reference in New Issue
Block a user