Compare commits
2 Commits
4046c31fbd
...
7f6a0f36e9
Author | SHA1 | Date | |
---|---|---|---|
7f6a0f36e9 | |||
377942fe3c |
151
apps/api/src/access-token/access-token.test.ts
Normal file
151
apps/api/src/access-token/access-token.test.ts
Normal file
@ -0,0 +1,151 @@
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'bun:test'
|
||||
import { access_token, db, user } from '@boring.tools/database'
|
||||
import type {
|
||||
AccessTokenCreateInput,
|
||||
AccessTokenListOutput,
|
||||
AccessTokenOutput,
|
||||
ChangelogCreateInput,
|
||||
ChangelogCreateOutput,
|
||||
ChangelogListOutput,
|
||||
ChangelogOutput,
|
||||
UserOutput,
|
||||
} from '@boring.tools/schema'
|
||||
import type { z } from '@hono/zod-openapi'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { fetch } from '../utils/testing/fetch'
|
||||
|
||||
describe('AccessToken', () => {
|
||||
let testUser: z.infer<typeof UserOutput>
|
||||
let testAccessToken: z.infer<typeof AccessTokenOutput>
|
||||
let createdAccessToken: z.infer<typeof AccessTokenOutput>
|
||||
let testChangelog: z.infer<typeof ChangelogOutput>
|
||||
|
||||
beforeAll(async () => {
|
||||
const createdUser = await db
|
||||
.insert(user)
|
||||
.values({ email: 'access_token@test.local', providerId: 'test_000' })
|
||||
.returning()
|
||||
const tAccessToken = await db
|
||||
.insert(access_token)
|
||||
.values({
|
||||
token: '1234567890',
|
||||
userId: createdUser[0].id,
|
||||
name: 'testtoken',
|
||||
})
|
||||
.returning()
|
||||
testAccessToken = tAccessToken[0] as z.infer<typeof AccessTokenOutput>
|
||||
testUser = createdUser[0] as z.infer<typeof UserOutput>
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await db.delete(user).where(eq(user.email, 'access_token@test.local'))
|
||||
})
|
||||
|
||||
describe('Create', () => {
|
||||
test('Success', async () => {
|
||||
const payload: z.infer<typeof AccessTokenCreateInput> = {
|
||||
name: 'Test Token',
|
||||
}
|
||||
|
||||
const res = await fetch(
|
||||
{
|
||||
path: '/v1/access-token',
|
||||
method: 'POST',
|
||||
body: payload,
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
const json = (await res.json()) as z.infer<typeof AccessTokenOutput>
|
||||
|
||||
createdAccessToken = json
|
||||
expect(res.status).toBe(201)
|
||||
})
|
||||
})
|
||||
|
||||
// describe('By Id', () => {
|
||||
// test('Success', async () => {
|
||||
// const res = await fetch(
|
||||
// {
|
||||
// path: `/v1/changelog/${testChangelog.id}`,
|
||||
// method: 'GET',
|
||||
// },
|
||||
// testAccessToken.token as string,
|
||||
// )
|
||||
|
||||
// expect(res.status).toBe(200)
|
||||
// })
|
||||
|
||||
// test('Not Found', async () => {
|
||||
// const res = await fetch(
|
||||
// {
|
||||
// path: '/v1/changelog/635f4aa7-79fc-4d6b-af7d-6731999cc8bb',
|
||||
// method: 'GET',
|
||||
// },
|
||||
// testAccessToken.token as string,
|
||||
// )
|
||||
|
||||
// expect(res.status).toBe(404)
|
||||
// })
|
||||
|
||||
// test('Invalid Id', async () => {
|
||||
// const res = await fetch(
|
||||
// {
|
||||
// path: '/v1/changelog/some',
|
||||
// method: 'GET',
|
||||
// },
|
||||
// testAccessToken.token as string,
|
||||
// )
|
||||
|
||||
// expect(res.status).toBe(400)
|
||||
|
||||
// const json = (await res.json()) as { success: boolean }
|
||||
// expect(json.success).toBeFalse()
|
||||
// })
|
||||
// })
|
||||
|
||||
describe('List', () => {
|
||||
test('Success', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: '/v1/access-token',
|
||||
method: 'GET',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
|
||||
const json = (await res.json()) as z.infer<typeof AccessTokenListOutput>
|
||||
// Check if token is redacted
|
||||
expect(json[0].token).toHaveLength(10)
|
||||
expect(json).toHaveLength(2)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Remove', () => {
|
||||
test('Success', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: `/v1/access-token/${createdAccessToken.id}`,
|
||||
method: 'DELETE',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
test('Not found', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: `/v1/access-token/${createdAccessToken.id}`,
|
||||
method: 'DELETE',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(404)
|
||||
})
|
||||
})
|
||||
})
|
@ -29,7 +29,7 @@ export const registerAccessTokenDelete = (api: typeof accessTokenApi) => {
|
||||
const id = c.req.param('id')
|
||||
const userId = await verifyAuthentication(c)
|
||||
|
||||
const result = await db
|
||||
const [result] = await db
|
||||
.delete(access_token)
|
||||
.where(and(eq(access_token.userId, userId), eq(access_token.id, id)))
|
||||
.returning()
|
||||
|
@ -20,7 +20,7 @@ const route = createRoute({
|
||||
},
|
||||
},
|
||||
responses: {
|
||||
200: {
|
||||
201: {
|
||||
content: {
|
||||
'application/json': {
|
||||
schema: PageOutput,
|
||||
@ -62,6 +62,6 @@ export const registerPageCreate = (api: typeof pageApi) => {
|
||||
)
|
||||
}
|
||||
|
||||
return c.json(PageOutput.parse(result), 200)
|
||||
return c.json(PageOutput.parse(result), 201)
|
||||
})
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ export const registerPageDelete = (api: typeof pageApi) => {
|
||||
const userId = await verifyAuthentication(c)
|
||||
const { id } = c.req.valid('param')
|
||||
|
||||
const result = await db
|
||||
const [result] = await db
|
||||
.delete(page)
|
||||
.where(and(eq(page.userId, userId), eq(page.id, id)))
|
||||
.returning()
|
||||
|
171
apps/api/src/page/page.test.ts
Normal file
171
apps/api/src/page/page.test.ts
Normal file
@ -0,0 +1,171 @@
|
||||
import { afterAll, beforeAll, describe, expect, test } from 'bun:test'
|
||||
import { access_token, db, user } from '@boring.tools/database'
|
||||
import type {
|
||||
AccessTokenCreateInput,
|
||||
AccessTokenListOutput,
|
||||
AccessTokenOutput,
|
||||
ChangelogCreateInput,
|
||||
ChangelogCreateOutput,
|
||||
ChangelogListOutput,
|
||||
ChangelogOutput,
|
||||
PageCreateInput,
|
||||
PageListOutput,
|
||||
PageOutput,
|
||||
PageUpdateInput,
|
||||
UserOutput,
|
||||
} from '@boring.tools/schema'
|
||||
import type { z } from '@hono/zod-openapi'
|
||||
import { eq } from 'drizzle-orm'
|
||||
import { fetch } from '../utils/testing/fetch'
|
||||
|
||||
describe('Page', () => {
|
||||
let testUser: z.infer<typeof UserOutput>
|
||||
let testAccessToken: z.infer<typeof AccessTokenOutput>
|
||||
let createdAccessToken: z.infer<typeof AccessTokenOutput>
|
||||
let testPage: z.infer<typeof PageOutput>
|
||||
|
||||
beforeAll(async () => {
|
||||
const createdUser = await db
|
||||
.insert(user)
|
||||
.values({ email: 'page@test.local', providerId: 'test_000' })
|
||||
.returning()
|
||||
const tAccessToken = await db
|
||||
.insert(access_token)
|
||||
.values({
|
||||
token: '1234567890',
|
||||
userId: createdUser[0].id,
|
||||
name: 'testtoken',
|
||||
})
|
||||
.returning()
|
||||
testAccessToken = tAccessToken[0] as z.infer<typeof AccessTokenOutput>
|
||||
testUser = createdUser[0] as z.infer<typeof UserOutput>
|
||||
})
|
||||
|
||||
afterAll(async () => {
|
||||
await db.delete(user).where(eq(user.email, 'page@test.local'))
|
||||
})
|
||||
|
||||
describe('Create', () => {
|
||||
test('Success', async () => {
|
||||
const payload: z.infer<typeof PageCreateInput> = {
|
||||
title: 'Test Page',
|
||||
changelogIds: [],
|
||||
}
|
||||
|
||||
const res = await fetch(
|
||||
{
|
||||
path: '/v1/page',
|
||||
method: 'POST',
|
||||
body: payload,
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
const json = (await res.json()) as z.infer<typeof PageOutput>
|
||||
testPage = json
|
||||
expect(res.status).toBe(201)
|
||||
})
|
||||
})
|
||||
|
||||
describe('By Id', () => {
|
||||
test('Success', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: `/v1/page/${testPage.id}`,
|
||||
method: 'GET',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
test('Not Found', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: '/v1/page/635f4aa7-79fc-4d6b-af7d-6731999cc8bb',
|
||||
method: 'GET',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(404)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Update', () => {
|
||||
test('Success', async () => {
|
||||
const update: z.infer<typeof PageUpdateInput> = {
|
||||
title: 'Test Update',
|
||||
}
|
||||
const res = await fetch(
|
||||
{
|
||||
path: `/v1/page/${testPage.id}`,
|
||||
method: 'PUT',
|
||||
body: update,
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Public', () => {
|
||||
test('Success', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: `/v1/page/${testPage.id}/public`,
|
||||
method: 'GET',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
})
|
||||
|
||||
describe('List', () => {
|
||||
test('Success', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: '/v1/page',
|
||||
method: 'GET',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
|
||||
const json = (await res.json()) as z.infer<typeof PageListOutput>
|
||||
// Check if token is redacted
|
||||
expect(json).toHaveLength(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('Remove', () => {
|
||||
test('Success', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: `/v1/page/${testPage.id}`,
|
||||
method: 'DELETE',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
|
||||
test('Not found', async () => {
|
||||
const res = await fetch(
|
||||
{
|
||||
path: `/v1/page/${testPage.id}`,
|
||||
method: 'DELETE',
|
||||
},
|
||||
testAccessToken.token as string,
|
||||
)
|
||||
|
||||
expect(res.status).toBe(404)
|
||||
})
|
||||
})
|
||||
})
|
@ -91,6 +91,7 @@ export const registerPagePublic = (api: typeof pageApi) => {
|
||||
}
|
||||
|
||||
redis.set(id, JSON.stringify(mappedResult), { EX: 60 })
|
||||
return c.json(PagePublicOutput.parse(mappedResult), 200)
|
||||
const asd = PagePublicOutput.parse(mappedResult)
|
||||
return c.json(asd, 200)
|
||||
})
|
||||
}
|
||||
|
@ -7,8 +7,8 @@ export const PageOutput = z
|
||||
example: '',
|
||||
}),
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
icon: z.string(),
|
||||
description: z.string().optional().nullable(),
|
||||
icon: z.string().optional().nullable(),
|
||||
changelogs: z.array(ChangelogOutput).optional(),
|
||||
})
|
||||
.openapi('Page')
|
||||
|
@ -5,10 +5,10 @@ export const PageCreateInput = z
|
||||
title: z.string().min(3).openapi({
|
||||
example: 'My page',
|
||||
}),
|
||||
description: z.string().optional().openapi({
|
||||
description: z.string().optional().nullable().openapi({
|
||||
example: '',
|
||||
}),
|
||||
icon: z.string().optional().openapi({
|
||||
icon: z.string().optional().nullable().openapi({
|
||||
example: 'base64...',
|
||||
}),
|
||||
changelogIds: z.array(z.string().uuid()),
|
||||
|
@ -2,21 +2,23 @@ import { z } from '@hono/zod-openapi'
|
||||
|
||||
export const PagePublicOutput = z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
description: z.string().nullable(),
|
||||
icon: z.string(),
|
||||
changelogs: z.array(
|
||||
z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
versions: z.array(
|
||||
z.object({
|
||||
markdown: z.string(),
|
||||
version: z.string(),
|
||||
releasedAt: z.date(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
),
|
||||
changelogs: z
|
||||
.array(
|
||||
z.object({
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
versions: z.array(
|
||||
z.object({
|
||||
markdown: z.string(),
|
||||
version: z.string(),
|
||||
releasedAt: z.date(),
|
||||
}),
|
||||
),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
})
|
||||
|
||||
export const PagePublicParams = z.object({
|
||||
|
Loading…
Reference in New Issue
Block a user