test: tests Vitest pour les extensions Directus (18 tests, 0 échec)
- disallow-votes (13 tests) : mock knex chaînable + VersionsService - versionId manquant, version introuvable, version > 3j, version obsolète - échec non bloquant de compare(), collection ignorée si ≠ votes - items.delete : voteId manquant, vote introuvable, version associée ancienne - new-user (5 tests) : mock MailService + database - MailService absent, EMAIL_NEW_USER absent, email déjà utilisé - envoi e-mail admin, fallback URL par défaut, erreur SMTP non bloquante - vitest.config.mjs : pointe sur extensions/*/src/__tests__/**/*.test.js Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
import {describe, it, expect, vi, beforeEach} from 'vitest'
|
||||
import hookFactory from '../index.js'
|
||||
|
||||
// Helpers --------------------------------------------------------------------
|
||||
|
||||
const makeDatabase = (existingUser) => {
|
||||
const db = vi.fn(() => db)
|
||||
db.select = vi.fn(() => db)
|
||||
db.where = vi.fn(() => db)
|
||||
db.first = vi.fn(() => Promise.resolve(existingUser))
|
||||
return db
|
||||
}
|
||||
|
||||
/**
|
||||
* Monte le hook et capture le callback `users.create`.
|
||||
*/
|
||||
const mountHook = ({services, env}) => {
|
||||
let callback
|
||||
const filter = (event, handler) => {
|
||||
if (event === 'users.create') {
|
||||
callback = handler
|
||||
}
|
||||
}
|
||||
|
||||
hookFactory({filter}, {services, env})
|
||||
return callback
|
||||
}
|
||||
|
||||
const SCHEMA = {}
|
||||
const BASE_ENV = {
|
||||
EMAIL_NEW_USER: 'admin@example.com',
|
||||
DIRECTUS_URL: 'http://localhost:8055',
|
||||
}
|
||||
|
||||
// Tests ----------------------------------------------------------------------
|
||||
|
||||
describe('new-user — users.create', () => {
|
||||
let sendMock
|
||||
let services
|
||||
|
||||
beforeEach(() => {
|
||||
sendMock = vi.fn()
|
||||
services = {
|
||||
MailService: class {
|
||||
send(options) {
|
||||
return sendMock(options)
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
||||
|
||||
it('renvoie input sans envoyer d\'e-mail si MailService est absent', async () => {
|
||||
const db = makeDatabase(undefined)
|
||||
const callback = mountHook({services: {}, env: BASE_ENV})
|
||||
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
const input = {email: 'user@example.com'}
|
||||
|
||||
const result = await callback(input, {schema: SCHEMA}, {database: db})
|
||||
|
||||
expect(result).toBe(input)
|
||||
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('MailService'))
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
it('renvoie input sans envoyer d\'e-mail si EMAIL_NEW_USER est absent', async () => {
|
||||
const db = makeDatabase(undefined)
|
||||
const callback = mountHook({services, env: {}})
|
||||
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
const input = {email: 'user@example.com'}
|
||||
|
||||
const result = await callback(input, {schema: SCHEMA}, {database: db})
|
||||
|
||||
expect(result).toBe(input)
|
||||
expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining('EMAIL_NEW_USER'))
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
it('renvoie input sans envoyer d\'e-mail si l\'adresse existe déjà', async () => {
|
||||
const db = makeDatabase({id: 'existing-user-id'}) // utilisateur trouvé
|
||||
const callback = mountHook({services, env: BASE_ENV})
|
||||
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
const input = {email: 'existing@example.com'}
|
||||
|
||||
const result = await callback(input, {schema: SCHEMA}, {database: db})
|
||||
|
||||
expect(result).toBe(input)
|
||||
expect(sendMock).not.toHaveBeenCalled()
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
|
||||
it('envoie un e-mail à l\'admin pour un nouvel utilisateur valide', async () => {
|
||||
const db = makeDatabase(undefined) // aucun utilisateur existant
|
||||
const callback = mountHook({services, env: BASE_ENV})
|
||||
const input = {email: 'new@example.com', first_name: 'Alice'}
|
||||
|
||||
const result = await callback(input, {schema: SCHEMA}, {database: db})
|
||||
|
||||
expect(result).toBe(input)
|
||||
expect(sendMock).toHaveBeenCalledOnce()
|
||||
const callArgs = sendMock.mock.calls[0][0]
|
||||
expect(callArgs.to).toBe('admin@example.com')
|
||||
expect(callArgs.subject).toContain('new@example.com')
|
||||
})
|
||||
|
||||
it('utilise l\'URL Directus par défaut si DIRECTUS_URL est absent', async () => {
|
||||
const db = makeDatabase(undefined)
|
||||
const envWithoutUrl = {EMAIL_NEW_USER: 'admin@example.com'}
|
||||
const callback = mountHook({services, env: envWithoutUrl})
|
||||
const input = {email: 'new@example.com'}
|
||||
|
||||
await callback(input, {schema: SCHEMA}, {database: db})
|
||||
|
||||
const callArgs = sendMock.mock.calls[0][0]
|
||||
expect(callArgs.html).toContain('http://0.0.0.0:8055')
|
||||
})
|
||||
|
||||
it('renvoie input si l\'envoi de mail échoue (non bloquant)', async () => {
|
||||
const db = makeDatabase(undefined)
|
||||
const brokenServices = {
|
||||
MailService: class {
|
||||
send() {
|
||||
throw new Error('SMTP error')
|
||||
}
|
||||
},
|
||||
}
|
||||
const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {})
|
||||
const callback = mountHook({services: brokenServices, env: BASE_ENV})
|
||||
const input = {email: 'new@example.com'}
|
||||
|
||||
const result = await callback(input, {schema: SCHEMA}, {database: db})
|
||||
|
||||
expect(result).toBe(input)
|
||||
expect(consoleSpy).toHaveBeenCalledWith(
|
||||
expect.stringContaining('Erreur'),
|
||||
expect.any(Error),
|
||||
)
|
||||
consoleSpy.mockRestore()
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user