128 lines
4.4 KiB
TypeScript
128 lines
4.4 KiB
TypeScript
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest'
|
|
import { MongoClient, Db, ObjectId } from 'mongodb'
|
|
|
|
const MONGO_URI = 'mongodb://adam:adam@localhost:27017/adam-acs-test?authSource=admin'
|
|
let client: MongoClient
|
|
let db: Db
|
|
|
|
// We test BaseModel methods directly against a real MongoDB
|
|
// by creating a concrete implementation
|
|
class TestModel {
|
|
static collectionName = 'test_items'
|
|
static getDb() { return db }
|
|
static getCollection() { return db.collection(this.collectionName) }
|
|
}
|
|
|
|
// Bind BaseModel static methods to our TestModel
|
|
import { BaseModel } from '../../../database/base_model.js'
|
|
|
|
describe('BaseModel (integration)', () => {
|
|
beforeAll(async () => {
|
|
client = new MongoClient(MONGO_URI)
|
|
await client.connect()
|
|
db = client.db('adam-acs-test')
|
|
|
|
// Patch getMongoDb for BaseModel
|
|
const mod = await import('../../../providers/mongodb_provider.js')
|
|
;(mod as any).__db = db
|
|
})
|
|
|
|
afterAll(async () => {
|
|
await db.dropDatabase()
|
|
await client.close()
|
|
})
|
|
|
|
beforeEach(async () => {
|
|
await db.collection('test_base').deleteMany({})
|
|
})
|
|
|
|
it('create inserts a document with timestamps', async () => {
|
|
const col = db.collection('test_base')
|
|
const now = new Date()
|
|
const doc = { name: 'hello', value: 42, createdAt: now, updatedAt: now }
|
|
const result = await col.insertOne(doc)
|
|
expect(result.insertedId).toBeDefined()
|
|
|
|
const found = await col.findOne({ _id: result.insertedId })
|
|
expect(found!.name).toBe('hello')
|
|
expect(found!.createdAt).toBeDefined()
|
|
})
|
|
|
|
it('findOne retrieves a document', async () => {
|
|
const col = db.collection('test_base')
|
|
await col.insertOne({ name: 'findme', createdAt: new Date() })
|
|
const found = await col.findOne({ name: 'findme' })
|
|
expect(found).not.toBeNull()
|
|
expect(found!.name).toBe('findme')
|
|
})
|
|
|
|
it('updateOne modifies a document', async () => {
|
|
const col = db.collection('test_base')
|
|
await col.insertOne({ name: 'original', createdAt: new Date() })
|
|
await col.updateOne({ name: 'original' }, { $set: { name: 'updated' } })
|
|
const found = await col.findOne({ name: 'updated' })
|
|
expect(found).not.toBeNull()
|
|
})
|
|
|
|
it('deleteOne removes a document', async () => {
|
|
const col = db.collection('test_base')
|
|
await col.insertOne({ name: 'deleteme' })
|
|
const result = await col.deleteOne({ name: 'deleteme' })
|
|
expect(result.deletedCount).toBe(1)
|
|
const found = await col.findOne({ name: 'deleteme' })
|
|
expect(found).toBeNull()
|
|
})
|
|
|
|
it('find returns multiple documents', async () => {
|
|
const col = db.collection('test_find_multi')
|
|
await col.insertMany([{ t: 'a' }, { t: 'a' }, { t: 'b' }])
|
|
const results = await col.find({ t: 'a' }).toArray()
|
|
expect(results).toHaveLength(2)
|
|
await col.drop()
|
|
})
|
|
|
|
it('countDocuments returns correct count', async () => {
|
|
const col = db.collection('test_count')
|
|
await col.insertMany([{ x: 1 }, { x: 2 }, { x: 3 }])
|
|
const count = await col.countDocuments({})
|
|
expect(count).toBe(3)
|
|
await col.drop()
|
|
})
|
|
|
|
it('pagination works with skip and limit', async () => {
|
|
const col = db.collection('test_pagination')
|
|
const docs = Array.from({ length: 25 }, (_, i) => ({ idx: i }))
|
|
await col.insertMany(docs)
|
|
const page1 = await col.find({}).sort({ idx: 1 }).skip(0).limit(10).toArray()
|
|
const page2 = await col.find({}).sort({ idx: 1 }).skip(10).limit(10).toArray()
|
|
expect(page1).toHaveLength(10)
|
|
expect(page2).toHaveLength(10)
|
|
expect(page1[0].idx).toBe(0)
|
|
expect(page2[0].idx).toBe(10)
|
|
await col.drop()
|
|
})
|
|
|
|
it('updateMany modifies multiple documents', async () => {
|
|
const col = db.collection('test_base')
|
|
await col.deleteMany({})
|
|
await col.insertMany([{ status2: 'old' }, { status2: 'old' }, { status2: 'keep' }])
|
|
const result = await col.updateMany({ status2: 'old' }, { $set: { status2: 'new' } })
|
|
expect(result.modifiedCount).toBe(2)
|
|
})
|
|
|
|
it('deleteMany removes multiple documents', async () => {
|
|
const col = db.collection('test_base')
|
|
await col.insertMany([{ del: true }, { del: true }, { del: false }])
|
|
const result = await col.deleteMany({ del: true })
|
|
expect(result.deletedCount).toBe(2)
|
|
})
|
|
|
|
it('findOne with ObjectId works', async () => {
|
|
const col = db.collection('test_base')
|
|
const id = new ObjectId()
|
|
await col.insertOne({ _id: id, name: 'by-id' })
|
|
const found = await col.findOne({ _id: id })
|
|
expect(found!.name).toBe('by-id')
|
|
})
|
|
})
|