feat: consolidate backend and docker-compose setup

This commit is contained in:
Rafhan Mazaya Fathurrahman committed 2026-06-30 21:09:08 +07:00
commit ff3753a745
306 files changed
+35450

No files matched your search

@@ -0,0 +1,176 @@
import { describe, it, expect, beforeAll, afterAll } from 'vitest'
import request from 'supertest'
import { app } from '../../src/app'
import { PrismaClient } from '@prisma/client'
import path from 'path'
import fs from 'fs'
const prisma = new PrismaClient()
describe('Document Integration Tests', () => {
let authToken: string
let userId: string
const testUsername = `doc_user_${Date.now()}`
const dummyFilePath = path.join(__dirname, 'dummy_test_image.png')
beforeAll(async () => {
// Clear old data
await prisma.documentItem.deleteMany({})
await prisma.document.deleteMany({})
await prisma.user.deleteMany({
where: { username: { startsWith: 'doc_user_' } }
})
// Create a dummy image file for testing
fs.writeFileSync(dummyFilePath, 'dummy_png_content_data_here')
// Create a user and get auth token
const regRes = await request(app)
.post('/api/v1/auth/register')
.send({
username: testUsername,
password: 'Password123'
})
userId = regRes.body.data.id
const loginRes = await request(app)
.post('/api/v1/auth/login')
.send({
username: testUsername,
password: 'Password123'
})
authToken = loginRes.body.data.token
})
afterAll(async () => {
// Clean up dummy file
if (fs.existsSync(dummyFilePath)) {
fs.unlinkSync(dummyFilePath)
}
// Clean up uploaded files in test environment if any
const uploadsDir = path.join(__dirname, '../../uploads')
if (fs.existsSync(uploadsDir)) {
const files = fs.readdirSync(uploadsDir)
for (const file of files) {
if (file.startsWith('test-')) {
fs.unlinkSync(path.join(uploadsDir, file))
}
}
}
await prisma.documentItem.deleteMany({})
await prisma.document.deleteMany({})
await prisma.user.deleteMany({
where: { username: { startsWith: 'doc_user_' } }
})
await prisma.$disconnect()
})
describe('POST /api/v1/documents/upload', () => {
it('should fail upload without authentication', async () => {
const res = await request(app)
.post('/api/v1/documents/upload')
.attach('image', dummyFilePath)
expect(res.status).toBe(401)
expect(res.body.message).toMatch(/token/i)
})
it('should upload document and return structured JSON with coordinates', async () => {
const res = await request(app)
.post('/api/v1/documents/upload')
.set('Authorization', `Bearer ${authToken}`)
.field('latitude', '-6.2088')
.field('longitude', '106.8456')
.attach('image', dummyFilePath)
expect(res.status).toBe(201)
expect(res.body).toHaveProperty('status', 'success')
expect(res.body.data).toHaveProperty('header')
expect(res.body.data.header).toHaveProperty('tanggal')
expect(res.body.data.header).toHaveProperty('no_po')
expect(res.body.data).toHaveProperty('shipment')
expect(res.body.data.shipment).toHaveProperty('kepada_yth')
expect(res.body.data).toHaveProperty('latitude', -6.2088)
expect(res.body.data).toHaveProperty('longitude', 106.8456)
expect(res.body.data).toHaveProperty('items')
expect(res.body.data.items.length).toBeGreaterThan(0)
const firstItem = res.body.data.items[0]
expect(firstItem).toHaveProperty('nomor_sku')
expect(firstItem).toHaveProperty('nama_barang')
expect(firstItem).toHaveProperty('banyak')
expect(firstItem).toHaveProperty('jumlah')
})
})
describe('GET /api/v1/documents', () => {
it('should fail listing without authentication', async () => {
const res = await request(app)
.get('/api/v1/documents')
expect(res.status).toBe(401)
})
it('should retrieve list of uploaded documents', async () => {
const res = await request(app)
.get('/api/v1/documents')
.set('Authorization', `Bearer ${authToken}`)
expect(res.status).toBe(200)
expect(res.body).toHaveProperty('status', 'success')
expect(Array.isArray(res.body.data)).toBe(true)
expect(res.body.data.length).toBeGreaterThan(0)
expect(res.body.data[0]).toHaveProperty('filePath')
expect(res.body.data[0]).toHaveProperty('items')
})
})
describe('PUT /api/v1/documents/:id', () => {
it('should update document successfully', async () => {
const uploadRes = await request(app)
.post('/api/v1/documents/upload')
.set('Authorization', `Bearer ${authToken}`)
.attach('image', dummyFilePath)
const docId = uploadRes.body.data.id
const updateRes = await request(app)
.put(`/api/v1/documents/${docId}`)
.set('Authorization', `Bearer ${authToken}`)
.send({
tanggal: '29 Juni 2026',
noPo: 'PO/26/0000999999',
noSo: '1122334455',
noDo: '5544332211',
kepadaYth: 'PT. PRIMAFOOD BEKASI',
orderUntuk: 'PRIMA FRESH MART',
alamat: 'JL. BEKASI RAYA NO. 1',
platTruk: 'B 1234 XYZ',
namaDriver: 'Sopir Baru',
namaPenerima: 'Penerima Toko Baru',
latitude: -6.1234,
longitude: 106.5678,
items: [
{
nomor_sku: '12010112',
nama_barang: 'FIESTA CHICKEN NUGGET 400 GR/PAC',
banyak: '5 BOX',
jumlah: '60 PAC'
}
]
})
expect(updateRes.status).toBe(200)
expect(updateRes.body).toHaveProperty('status', 'success')
expect(updateRes.body.data).toHaveProperty('header')
expect(updateRes.body.data.header).toHaveProperty('no_po', 'PO/26/0000999999')
expect(updateRes.body.data.shipment).toHaveProperty('nama_driver', 'Sopir Baru')
expect(updateRes.body.data.shipment).toHaveProperty('nama_penerima', 'Penerima Toko Baru')
expect(updateRes.body.data).toHaveProperty('latitude', -6.1234)
expect(updateRes.body.data).toHaveProperty('longitude', 106.5678)
expect(updateRes.body.data.items[0]).toHaveProperty('nomor_sku', '12010112')
})
})
})