ываыв

This commit is contained in:
Kirill
2026-05-28 21:46:17 +05:00
parent ba375aee12
commit f34c05095a
12 changed files with 1039 additions and 18 deletions
Binary file not shown.
@@ -0,0 +1,118 @@
import jwt from '@fastify/jwt'
import Fastify from 'fastify'
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
import { prisma } from '../../../lib/prisma.js'
import { registerAdminOrderRoutes } from '../admin-orders.js'
const JWT_SECRET = 'test-secret'
const ADMIN_EMAIL = `admin-orders-${Date.now()}@example.com`
const USER_EMAIL = `admin-orders-user-${Date.now()}@example.com`
let app
let adminUser
let buyer
async function signToken(user) {
return app.jwt.sign({ sub: user.id, email: user.email })
}
async function buildApp() {
const fastify = Fastify({ logger: false })
await fastify.register(jwt, { secret: JWT_SECRET })
fastify.decorate('eventBus', { emit: vi.fn() })
fastify.decorate('verifyAdmin', async (request, reply) => {
try {
await request.jwtVerify()
} catch {
return reply.code(401).send({ error: 'Unauthorized' })
}
if (request.user.email !== ADMIN_EMAIL) {
return reply.code(401).send({ error: 'Admin only' })
}
})
await registerAdminOrderRoutes(fastify)
await fastify.ready()
return fastify
}
async function createOrder(data = {}) {
return prisma.order.create({
data: {
userId: buyer.id,
status: 'PENDING_PAYMENT',
deliveryType: 'delivery',
deliveryFeeLocked: false,
paymentMethod: 'online',
itemsSubtotalCents: 10000,
deliveryFeeCents: 50000,
totalCents: 60000,
currency: 'RUB',
...data,
},
})
}
describe('admin order routes', () => {
beforeAll(async () => {
await prisma.payment.deleteMany()
await prisma.order.deleteMany({ where: { user: { email: { in: [ADMIN_EMAIL, USER_EMAIL] } } } })
await prisma.user.deleteMany({ where: { email: { in: [ADMIN_EMAIL, USER_EMAIL] } } })
adminUser = await prisma.user.create({ data: { email: ADMIN_EMAIL } })
buyer = await prisma.user.create({ data: { email: USER_EMAIL } })
})
beforeEach(async () => {
await prisma.order.deleteMany({ where: { userId: buyer.id } })
app = await buildApp()
})
afterEach(async () => {
await app.close()
vi.clearAllMocks()
})
afterAll(async () => {
await prisma.order.deleteMany({ where: { userId: buyer.id } })
await prisma.user.deleteMany({ where: { id: { in: [adminUser.id, buyer.id] } } })
})
it('summary counts only delivery orders waiting for price approval', async () => {
const token = await signToken(adminUser)
const beforeRes = await app.inject({
method: 'GET',
url: '/api/admin/orders/summary',
headers: { authorization: `Bearer ${token}` },
})
const baseline = beforeRes.json().attentionCount
await createOrder({ deliveryFeeLocked: false, deliveryType: 'delivery' })
await createOrder({ deliveryFeeLocked: true, deliveryType: 'delivery' })
await createOrder({ deliveryFeeLocked: false, deliveryType: 'pickup' })
await createOrder({ deliveryFeeLocked: false, deliveryType: 'delivery', status: 'PAID' })
const res = await app.inject({
method: 'GET',
url: '/api/admin/orders/summary',
headers: { authorization: `Bearer ${token}` },
})
expect(res.statusCode).toBe(200)
expect(res.json()).toEqual({ attentionCount: baseline + 1 })
})
it('rejects PAID transition while delivery fee is not locked', async () => {
const order = await createOrder({ deliveryFeeLocked: false, deliveryType: 'delivery' })
const token = await signToken(adminUser)
const res = await app.inject({
method: 'PATCH',
url: `/api/admin/orders/${order.id}/status`,
headers: { authorization: `Bearer ${token}` },
payload: { status: 'PAID' },
})
expect(res.statusCode).toBe(409)
expect(res.json().error).toContain('стоимость доставки')
})
})
+7
View File
@@ -7,6 +7,8 @@ export async function registerAdminOrderRoutes(fastify) {
const attentionCount = await prisma.order.count({
where: {
status: 'PENDING_PAYMENT',
deliveryType: 'delivery',
deliveryFeeLocked: false,
},
})
return { attentionCount }
@@ -97,6 +99,11 @@ export async function registerAdminOrderRoutes(fastify) {
error: `Нельзя сменить статус ${existing.status}${next}`,
})
}
if (next === 'PAID' && existing.deliveryType === 'delivery' && existing.deliveryFeeLocked === false) {
return reply.code(409).send({
error: 'Сначала подтвердите итоговую стоимость доставки',
})
}
const updated = await prisma.order.update({
where: { id },