Skip to content

Commit

Permalink
topic-methods
Browse files Browse the repository at this point in the history
  • Loading branch information
kevinmamaqi committed Nov 13, 2024
1 parent dd9ed6e commit 1623572
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 109 deletions.
Original file line number Diff line number Diff line change
@@ -1,34 +1,33 @@
import cuid from 'cuid'
import supertest from 'supertest'
import { expect, it, describe, beforeAll, afterAll } from 'vitest'
import { Category } from '@prisma/client'
import { server } from '../globalSetup'
import { prisma } from '../../prisma/client'
import { pathRoot } from '../../routes/routes'
import { checkInvalidToken } from '../helpers/checkInvalidToken'
import { authToken } from '../mocks/ssoHandlers/authToken'
import { TCategory } from '../../helpers/wiki/transformResourceToAPI'
import db from '../../db/knex'

let testCategory: Category | null
let testCategory: TCategory | null | undefined

beforeAll(async () => {
await prisma.category.create({
data: {
const categoryId = cuid()
const res: TCategory[] = await db<TCategory>('category')
.returning('*')
.insert({
id: categoryId,
name: 'Node',
slug: 'node',
},
})

testCategory = await prisma.category.findUnique({
where: { slug: 'node' },
})
updated_at: new Date(),
created_at: new Date(),
})
// eslint-disable-next-line prefer-destructuring
testCategory = res[0]
})

afterAll(async () => {
await prisma.topic.deleteMany({
where: { slug: 'node-file-system' },
})
await prisma.category.deleteMany({
where: { slug: 'node' },
})
await db('topic').where({ slug: 'node-file-system' }).del()
await db('category').where({ slug: 'node' }).del()
})

describe('Testing resource creation endpoint', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import supertest from 'supertest'
import { expect, it, describe, beforeAll } from 'vitest'
import { Category } from '@prisma/client'
import { server, testCategoryData } from '../globalSetup'
import { prisma } from '../../prisma/client'
import { pathRoot } from '../../routes/routes'
import db from '../../db/knex'

describe('Testing topics endpoint', () => {
describe('With no query parameteres', () => {
Expand All @@ -20,7 +20,7 @@ describe('Testing topics endpoint', () => {
id: expect.any(String),
name: expect.any(String),
slug: expect.any(String),
categoryId: expect.any(String),
category_id: expect.any(String),
}),
])
)
Expand All @@ -30,9 +30,11 @@ describe('Testing topics endpoint', () => {
let category: Category
beforeAll(async () => {
// A testing Topic on testing Category has been created for this test on globalSetup.
category = (await prisma.category.findUnique({
where: { name: testCategoryData.name },
})) as Category
category = await db('category')
.where({
name: testCategoryData.name,
})
.first()
})

it('Should respond OK status and return topics as an array. when categoryId given', async () => {
Expand All @@ -49,11 +51,12 @@ describe('Testing topics endpoint', () => {
id: expect.any(String),
name: expect.any(String),
slug: expect.any(String),
categoryId: expect.any(String),
category_id: expect.any(String),
}),
])
)
})

it('Should respond OK status and return topics as an array. when category slug given', async () => {
const response = await supertest(server)
.get(`${pathRoot.v1.topics}`)
Expand All @@ -68,7 +71,7 @@ describe('Testing topics endpoint', () => {
id: expect.any(String),
name: expect.any(String),
slug: expect.any(String),
categoryId: expect.any(String),
category_id: expect.any(String),
}),
])
)
Expand All @@ -92,11 +95,12 @@ describe('Testing topics endpoint', () => {
id: expect.any(String),
name: expect.any(String),
slug: expect.any(String),
categoryId: expect.any(String),
category_id: expect.any(String),
}),
])
)
})

describe('Testing fail cases', () => {
it('Should 404 if category is not found, by slug', async () => {
const response = await supertest(server)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,59 +1,58 @@
import supertest from 'supertest'
import { expect, it, describe, beforeAll, afterAll } from 'vitest'
import { Category, Topic } from '@prisma/client'
import cuid from 'cuid'
import slugify from 'slugify'
import { server } from '../globalSetup'
import { prisma } from '../../prisma/client'
import { pathRoot } from '../../routes/routes'
import { checkInvalidToken } from '../helpers/checkInvalidToken'
import { authToken } from '../mocks/ssoHandlers/authToken'
import db from '../../db/knex'
import { TTopic, TCategory } from '../../helpers/wiki/transformResourceToAPI'

let testCategory1: Category | null
let testCategory2: Category | null
let testTopicToPatch: Topic | null
let testCategory1: TCategory | null | undefined
let testTopicToPatch: TTopic | null | undefined

beforeAll(async () => {
await prisma.category.createMany({
data: [
{
name: 'Node',
slug: 'node',
},
{
name: 'Deno',
slug: 'deno',
},
],
})

testCategory1 = await prisma.category.findUnique({
where: { slug: 'node' },
})
testCategory2 = await prisma.category.findUnique({
where: { slug: 'deno' },
})
const nodeCUID = cuid()
const denoCUID = cuid()
const topicCUID = cuid()

await prisma.topic.create({
// Suppose a topic is mistakenly created with wrong name and categoryId
data: {
name: 'Nottttte File System',
slug: 'nottttte-file-system',
categoryId: testCategory2!.id,
await db('category').insert([
{
id: nodeCUID,
name: 'Node',
slug: 'node',
updated_at: new Date(),
created_at: new Date(),
},
})
{
id: denoCUID,
name: 'Deno',
slug: 'deno',
updated_at: new Date(),
created_at: new Date(),
},
])

testTopicToPatch = await prisma.topic.findFirst({
where: { slug: 'nottttte-file-system' },
testCategory1 = await db<TCategory>('category')
.where({ id: nodeCUID })
.first()

await db('topic').insert({
id: topicCUID,
name: 'Nottttte File System',
slug: 'nottttte-file-system',
category_id: denoCUID,
updated_at: new Date(),
created_at: new Date(),
})

testTopicToPatch = await db<TTopic>('topic').where({ id: topicCUID }).first()
})

afterAll(async () => {
await prisma.topic.deleteMany({
where: { id: testTopicToPatch!.id },
})
await prisma.category.deleteMany({
where: { OR: [{ slug: 'node' }, { slug: 'deno' }] },
})
await db('topic').where({ id: testTopicToPatch?.id }).del()
await db('category').whereIn('slug', ['node', 'deno']).del()
})

describe('Testing topic patch endpoint', () => {
Expand All @@ -68,18 +67,18 @@ describe('Testing topic patch endpoint', () => {
.patch(`${pathRoot.v1.topics}`)
.set('Cookie', [`authToken=${authToken.mentor}`])
.send(modifiedTopic)

const updatedTopic = await prisma.topic.findFirst({
where: { id: testTopicToPatch!.id },
})
const updatedTopic = await db<TTopic>('topic')
.where({ id: testTopicToPatch?.id })
.first()

expect(updatedTopic!.name).toEqual(modifiedTopic.name)
expect(updatedTopic!.slug).toEqual(
slugify(modifiedTopic.name, { lower: true })
)
expect(updatedTopic!.categoryId).toEqual(modifiedTopic.categoryId)
expect(updatedTopic!.category_id).toEqual(modifiedTopic.categoryId)
expect(response.status).toBe(204)
})

it('A user lower than mentor should not be able to modify a topic', async () => {
const modifiedTopic = {
id: testTopicToPatch!.id,
Expand All @@ -94,6 +93,7 @@ describe('Testing topic patch endpoint', () => {

expect(response.status).toBe(403)
})

it('Should return 401 status if no token is provided', async () => {
const response = await supertest(server)
.patch(`${pathRoot.v1.topics}`)
Expand All @@ -105,6 +105,7 @@ describe('Testing topic patch endpoint', () => {
expect(response.status).toBe(401)
expect(response.body.message).toBe('Missing token')
})

it('Check invalid token ', async () => {
checkInvalidToken(`${pathRoot.v1.topics}`, 'patch', {
id: testTopicToPatch!.id,
Expand Down
14 changes: 9 additions & 5 deletions services/wiki/src/controllers/topics/create.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import cuid from 'cuid'
import Koa, { Middleware } from 'koa'
import slugify from 'slugify'
import { prisma } from '../../prisma/client'
import db from '../../db/knex'

export const createTopic: Middleware = async (ctx: Koa.Context) => {
const topic = ctx.request.body

const slug = slugify(topic.name, { lower: true })

await prisma.topic.create({
data: { ...topic, slug },
await db('topic').insert({
id: cuid(),
name: topic.name,
slug: slugify(topic.name, { lower: true }),
category_id: topic.categoryId,
updated_at: new Date(),
created_at: new Date(),
})

ctx.status = 204
Expand Down
41 changes: 24 additions & 17 deletions services/wiki/src/controllers/topics/get.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Prisma } from '@prisma/client'
import Koa, { Middleware } from 'koa'
import { prisma } from '../../prisma/client'
import db from '../../db/knex'
import { NotFoundError } from '../../helpers/errors'

export const getTopics: Middleware = async (ctx: Koa.Context) => {
Expand All @@ -9,30 +8,38 @@ export const getTopics: Middleware = async (ctx: Koa.Context) => {
slug?: string
}

const where: Prisma.TopicWhereInput = {}
let where: Record<string, any> = {}

// Check if categoryId is provided and valid
if (categoryId) {
const exists = await prisma.category.findUnique({
where: { id: categoryId },
})
const exists = await db('category').where({ id: categoryId }).first()
if (!exists) throw new NotFoundError('No category found with this id')

where.categoryId = categoryId
} else if (slug) {
const exists = await prisma.category.findUnique({ where: { slug } })
// Check if slug is provided and valid
const exists = await db('category').where({ slug }).first()
if (!exists) throw new NotFoundError('No category found with this slug')

where.category = { slug }
where = { 'category.slug': slug }
}

const topics = await prisma.topic.findMany({
where,
select: {
id: true,
name: true,
slug: true,
categoryId: true,
},
})
const topics = await db('topic')
.select(
'topic.id as id',
'topic.name as name',
'topic.slug as slug',
'topic.category_id as category_id'
)
.modify((queryBuilder) => {
if (categoryId) {
queryBuilder.where({ category_id: categoryId })
} else if (slug) {
queryBuilder
.join('category', 'topic.category_id', 'category.id')
.where('category.slug', slug)
}
})
ctx.status = 200
ctx.body = topics
}
27 changes: 10 additions & 17 deletions services/wiki/src/controllers/topics/patch.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import Koa, { Middleware } from 'koa'
import slugify from 'slugify'
import { prisma } from '../../prisma/client'
import { NotFoundError } from '../../helpers/errors'
import db from '../../db/knex'
import { TTopic } from '../../helpers/wiki/transformResourceToAPI'

export const patchTopic: Middleware = async (ctx: Koa.Context) => {
const { id, ...newData } = ctx.request.body

const topic = await prisma.topic.findFirst({
where: { id },
})
const topic = await db<TTopic>('topic').where({ id }).first()

if (!topic) {
throw new NotFoundError('Topic not found')
Expand All @@ -21,21 +19,16 @@ export const patchTopic: Middleware = async (ctx: Koa.Context) => {
updatedName = newData.name
}

let updatedCategoryId: string = topic.categoryId
if (topic.categoryId !== newData.categoryId) {
let updatedCategoryId: string = topic.category_id
if (topic.category_id !== newData.categoryId) {
updatedCategoryId = newData.categoryId
}

await prisma.$transaction(async (tx) => {
await tx.topic.update({
where: { id },
data: {
id,
name: updatedName,
slug: updatedSlug,
categoryId: updatedCategoryId,
},
})
await db('topic').where({ id }).update({
name: updatedName,
slug: updatedSlug,
category_id: updatedCategoryId,
updated_at: new Date(),
})

ctx.status = 204
Expand Down
Loading

0 comments on commit 1623572

Please sign in to comment.