diff --git a/services/wiki/src/__tests__/resources/post.test.ts b/services/wiki/src/__tests__/resources/post.test.ts index 6abf24d7c..6e8b75028 100644 --- a/services/wiki/src/__tests__/resources/post.test.ts +++ b/services/wiki/src/__tests__/resources/post.test.ts @@ -1,38 +1,41 @@ import supertest from 'supertest' -import { expect, test, describe, beforeAll, afterAll } from 'vitest' +import { expect, describe, beforeAll, afterAll, test } from 'vitest' +import cuid from 'cuid' import { server, testCategoryData } 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 { KnexResource } from '../../db/knexTypes' let topicIds: string[] = [] beforeAll(async () => { - topicIds = (await prisma.topic.findMany()).map((topic) => topic.id) + topicIds = (await db('topic').select('id')).map((topic) => topic.id) }) afterAll(async () => { - await prisma.topicsOnResources.deleteMany({ - where: { resource: { slug: 'test-resource' } }, - }) - await prisma.resource.deleteMany({ - where: { slug: 'test-resource' }, - }) + await db('topic_resource') + // eslint-disable-next-line func-names + .whereIn('resource_id', function () { + this.select('id').from('resource').where({ slug: 'test-resource' }) + }) + .del() + await db('resource').where({ slug: 'test-resource' }).del() }) - describe('Testing resource creation endpoint', async () => { - const category = await prisma.category.findUnique({ - where: { slug: testCategoryData.slug }, - }) + const category = await db('category') + .where({ slug: testCategoryData.slug }) + .first() const newResource = { + id: cuid(), title: 'Test Resource', description: 'This is a new resource', url: 'https://example.com/resource', - resourceType: 'BLOG', + resource_type: KnexResource.BLOG, + category_id: category?.id, topics: topicIds, - categoryId: category?.id, } test('should create a new resource with topics', async () => { newResource.topics = topicIds @@ -40,7 +43,6 @@ describe('Testing resource creation endpoint', async () => { .post(`${pathRoot.v1.resources}`) .set('Cookie', [`authToken=${authToken.admin}`]) .send(newResource) - expect(response.status).toBe(204) }) @@ -50,25 +52,24 @@ describe('Testing resource creation endpoint', async () => { .post(`${pathRoot.v1.resources}`) .set('Cookie', [`authToken=${authToken.admin}`]) .send(newResource) - expect(response.status).toBe(422) }) test('should fail with wrong resource type', async () => { + const id2 = cuid() const invalidResource = { + id: id2, title: 'Invalid Resource', description: 'This is a new resource', url: 'https://example.com/resource', - resourceType: 'INVALIDE-RESOURCE', - topicId: topicIds, - status: 'NOT_SEEN', + resource_type: 'INVALIDE-RESOURCE', + topics: topicIds, } const response = await supertest(server) .post(`${pathRoot.v1.resources}`) .set('Cookie', [`authToken=${authToken.admin}`]) .send(invalidResource) - expect(response.status).toBe(400) expect(response.body.message[0].received).toBe('INVALIDE-RESOURCE') }) diff --git a/services/wiki/src/controllers/index.ts b/services/wiki/src/controllers/index.ts index 1253a3e97..74476837d 100644 --- a/services/wiki/src/controllers/index.ts +++ b/services/wiki/src/controllers/index.ts @@ -2,7 +2,7 @@ export { loginController } from './auth/loginController' export { logoutController } from './auth/logoutController' export { registerController } from './auth/register' export { authMeController } from './auth/authMeController' -export { postResource } from './resources/postResource' +export { postResource } from './resources/post' export { listResources } from './resources/list' export { getResourcesById } from './resources/getResourcesById' export { getResourcesByUserId } from './resources/getResourcesByUserId' diff --git a/services/wiki/src/controllers/resources/post.ts b/services/wiki/src/controllers/resources/post.ts new file mode 100644 index 000000000..04d2bdc29 --- /dev/null +++ b/services/wiki/src/controllers/resources/post.ts @@ -0,0 +1,36 @@ +import Koa, { Middleware } from 'koa' +import slugify from 'slugify' +import { MissingParamError } from '../../helpers/errors' +import db from '../../db/knex' +import { User } from '../../db/knexTypes' +import { createResourceTopics } from '../../helpers/wiki/createResourceTopics' + +export const postResource: Middleware = async (ctx: Koa.Context) => { + const { id: userId } = ctx.user as User + // eslint-disable-next-line @typescript-eslint/naming-convention + const { category_id, topics, ...rest } = ctx.request.body + + const resource = rest + + const slug = slugify(resource.title, { lower: true }) + + if (topics.length === 0) throw new MissingParamError('topics') + + const resourceTopics = await db('topic').whereIn( + 'id', + topics.map((id: any) => id) + ) + + await db('resource').insert({ + ...resource, + user_id: userId, + slug, + created_at: new Date(), + updated_at: new Date(), + category_id, + }) + + await createResourceTopics(resource?.id, resourceTopics) + + ctx.status = 204 +} diff --git a/services/wiki/src/controllers/resources/postResource.ts b/services/wiki/src/controllers/resources/postResource.ts deleted file mode 100644 index 82e6a4433..000000000 --- a/services/wiki/src/controllers/resources/postResource.ts +++ /dev/null @@ -1,43 +0,0 @@ -import Koa, { Middleware } from 'koa' -import slugify from 'slugify' -import { User } from '@prisma/client' -import { prisma } from '../../prisma/client' -import { MissingParamError } from '../../helpers/errors' - -export const postResource: Middleware = async (ctx: Koa.Context) => { - const { id: userId } = ctx.user as User - const resource = ctx.request.body - - const slug = slugify(resource.title, { lower: true }) - const { categoryId } = resource as { categoryId: string } - const topicIds: string[] = resource.topics - - if (topicIds.length === 0) throw new MissingParamError('topics') - - const databaseTopics = await prisma.topic.findMany({ - where: { - id: { - in: topicIds, - }, - }, - }) - - if (topicIds.length !== databaseTopics.length) - throw new MissingParamError('valid topic/s') - - resource.topics = { - create: resource.topics.map((topicId: string) => ({ - topic: { - connect: { - id: topicId, - }, - }, - })), - } - - await prisma.resource.create({ - data: { ...resource, userId, categoryId, slug }, - }) - - ctx.status = 204 -} diff --git a/services/wiki/src/helpers/wiki/createResourceTopics.ts b/services/wiki/src/helpers/wiki/createResourceTopics.ts new file mode 100644 index 000000000..e392d76e2 --- /dev/null +++ b/services/wiki/src/helpers/wiki/createResourceTopics.ts @@ -0,0 +1,15 @@ +import db from '../../db/knex' +import { Topic } from '../../db/knexTypes' + +export const createResourceTopics = async ( + resourceId: string, + topicIds: Topic[] +) => { + const resourceTopics = topicIds.map((topicId) => ({ + resource_id: resourceId, + topic_id: topicId.id, + created_at: new Date(), + })) + + await db('topic_resource').insert(resourceTopics) +} diff --git a/services/wiki/src/routes/resourcesRouter.ts b/services/wiki/src/routes/resourcesRouter.ts index 1f4612501..d1ca1724e 100644 --- a/services/wiki/src/routes/resourcesRouter.ts +++ b/services/wiki/src/routes/resourcesRouter.ts @@ -8,10 +8,11 @@ import { getFavoriteResources, postResource, } from '../controllers' -import { resourceCreateSchema, resourcesListParamsSchema } from '../schemas' +import { resourcesListParamsSchema } from '../schemas' import { pathRoot } from './routes' import { patchResource } from '../controllers/resources/patchResource' import { resourcePatchSchema } from '../schemas/resource/resourcePatchSchema' +import { knexResourceCreateSchema } from '../schemas/resource/resourceCreateSchema' const resourcesRouter = new Router() @@ -20,7 +21,7 @@ resourcesRouter.prefix(pathRoot.v1.resources) resourcesRouter.post( '/', authenticate, - validate(z.object({ body: resourceCreateSchema })), + validate(z.object({ body: knexResourceCreateSchema })), postResource )