63 lines
2.4 KiB
TypeScript
63 lines
2.4 KiB
TypeScript
import fs from 'fs'
|
|
import os from 'os'
|
|
import path from 'path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import {
|
|
assertStorageConfiguration,
|
|
deleteImage,
|
|
getPrivateStorageRoot,
|
|
getProtectedCustomerLicenseImageUrl,
|
|
getPublicStorageRoot,
|
|
getStorageRoot,
|
|
resolveStoredFilePath,
|
|
uploadImage,
|
|
} from './storage'
|
|
|
|
const originalEnv = { ...process.env }
|
|
|
|
describe('storage', () => {
|
|
afterEach(() => {
|
|
process.env = { ...originalEnv }
|
|
})
|
|
|
|
it('uses FILE_STORAGE_ROOT when configured and builds protected customer license URLs from dashboard URL', () => {
|
|
process.env.FILE_STORAGE_ROOT = '/tmp/rdg-storage'
|
|
process.env.DASHBOARD_URL = 'https://dashboard.rentaldrivego.test/dashboard/'
|
|
|
|
expect(getStorageRoot()).toBe('/tmp/rdg-storage')
|
|
expect(getPublicStorageRoot()).toBe('/tmp/rdg-storage/public')
|
|
expect(getPrivateStorageRoot()).toBe('/tmp/rdg-storage/private')
|
|
expect(getProtectedCustomerLicenseImageUrl('customer_1')).toBe('https://dashboard.rentaldrivego.test/dashboard/api/v1/customers/customer_1/license-image')
|
|
})
|
|
|
|
it('rejects implicit in-app storage in production', () => {
|
|
delete process.env.FILE_STORAGE_ROOT
|
|
process.env.NODE_ENV = 'production'
|
|
|
|
expect(() => assertStorageConfiguration()).toThrow('FILE_STORAGE_ROOT must be set in production')
|
|
})
|
|
|
|
it('uploads, resolves, and deletes files under the configured storage root', async () => {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'rdg-storage-'))
|
|
process.env.FILE_STORAGE_ROOT = root
|
|
process.env.API_URL = 'https://api.rentaldrivego.test/'
|
|
|
|
const url = await uploadImage(Buffer.from('image-bytes'), 'customers/licenses', 'customer_1')
|
|
|
|
expect(url).toBe('https://api.rentaldrivego.test/storage/customers/licenses/customer_1.jpg')
|
|
const filePath = resolveStoredFilePath(url)
|
|
expect(filePath).toBe(path.join(root, 'private/customers/licenses/customer_1.jpg'))
|
|
expect(fs.readFileSync(filePath!, 'utf8')).toBe('image-bytes')
|
|
|
|
await deleteImage(url)
|
|
expect(fs.existsSync(filePath!)).toBe(false)
|
|
})
|
|
|
|
it('ignores non-storage URLs when resolving or deleting files', async () => {
|
|
process.env.FILE_STORAGE_ROOT = fs.mkdtempSync(path.join(os.tmpdir(), 'rdg-storage-'))
|
|
|
|
expect(resolveStoredFilePath('https://cdn.test/not-storage/file.jpg')).toBeNull()
|
|
await expect(deleteImage('https://cdn.test/not-storage/file.jpg')).resolves.toBeUndefined()
|
|
})
|
|
})
|