Jelajahi Sumber

add enumManager.test.ts and imageManager.test.ts

Olivier Massot 2 tahun lalu
induk
melakukan
62e305d67f

+ 23 - 5
services/data/imageManager.ts

@@ -6,7 +6,7 @@ import ImageUtils from "~/services/utils/imageUtils";
  */
 class ImageManager {
     private apiRequestService: ApiRequestService;
-    public readonly defaultImage = '/images/default/picture.jpeg'
+    public static readonly defaultImage = '/images/default/picture.jpeg'
 
     public constructor(apiRequestService: ApiRequestService) {
         this.apiRequestService = apiRequestService
@@ -31,7 +31,7 @@ class ImageManager {
         width: number = 0
     ): Promise<string | ArrayBuffer> {
 
-        const defaultUrl = defaultImage ?? this.defaultImage
+        const defaultUrl = defaultImage ?? ImageManager.defaultImage
 
         if (id === null) {
             return defaultUrl
@@ -47,7 +47,7 @@ class ImageManager {
         }
 
         // Une image doit toujours avoir le time en options pour éviter les problèmes de cache
-        const query = [new Date().getTime().toString()]
+        const query = [this.getCacheKey()]
 
         const response: any = await this.apiRequestService.get(imageUrl, query)
 
@@ -56,8 +56,26 @@ class ImageManager {
             return defaultUrl
         }
 
-        const blob = await ImageUtils.newBlob(response)
-        return await ImageUtils.blobToBase64(blob) ?? ''
+        return await this.toBase64(response)
+    }
+
+    /**
+     * Convert the API response into base64
+     * @param data
+     * @protected
+     */
+    protected async toBase64(data: string) {
+        const blob = ImageUtils.newBlob(data)
+        return  await ImageUtils.blobToBase64(blob) ?? ''
+    }
+
+    /**
+     * On passe cette clé en paramètres des requêtes pour éviter les problèmes de cache
+     *
+     * @protected
+     */
+    protected getCacheKey() {
+        return new Date().getTime().toString()
     }
 }
 

+ 1 - 0
services/utils/imageUtils.ts

@@ -18,6 +18,7 @@ class ImageUtils {
      * @param {Blob} blob
      */
     public static async blobToBase64(blob: Blob): Promise<string> {
+        // /!\ Attention: lors de tests unitaires, 'blob.text' plantera si utilisée en même temps que vi.useFakeTimers()
         const content = Buffer.from(await blob.text()).toString('base64');
         return `data:${blob.type};base64,${content}`
     }

+ 57 - 0
tests/units/services/data/enumManager.test.ts

@@ -0,0 +1,57 @@
+import { describe, test, it, expect } from 'vitest'
+import ApiRequestService from "~/services/data/apiRequestService";
+import EnumManager from "~/services/data/enumManager";
+import {VueI18n} from "vue-i18n";
+
+let apiRequestService: ApiRequestService
+let i18n: VueI18n
+let enumManager: EnumManager
+
+beforeEach(() => {
+    // @ts-ignore
+    apiRequestService = vi.fn() as ApiRequestService
+    // @ts-ignore
+    i18n = vi.fn() as VueI18n
+
+    enumManager = new EnumManager(apiRequestService, i18n)
+})
+
+describe('fetch', () => {
+    test('simple call', async () => {
+
+        const hydraData = {
+            "@context": "/api/contexts/Enum",
+            "@id": "/api/enum/contact_point_type",
+            "@type": "Enum",
+            "name": "contact_point_type",
+            "items": {
+                "PRINCIPAL": "PRINCIPAL",
+                "BILL": "BILL",
+                "OTHER": "OTHER",
+                "CONTACT": "CONTACT"
+            }
+        }
+
+        const translationOf = {
+            "PRINCIPAL": "Principal",
+            "BILL": "Facture",
+            "OTHER": "Autre",
+            "CONTACT": "Contact"
+        }
+
+        // @ts-ignore
+        apiRequestService.get = vi.fn((url: string) => hydraData)
+        // @ts-ignore
+        i18n.t = vi.fn((key: string) => translationOf[key])
+
+        const result = await enumManager.fetch('contact_point_type')
+
+        expect(apiRequestService.get).toHaveBeenCalledWith('api/enum/contact_point_type')
+        expect(result).toEqual([
+            { "label": "Principal", "value": "PRINCIPAL" },
+            { "label": "Facture", "value": "BILL" },
+            { "label": "Autre", "value": "OTHER" },
+            { "label": "Contact", "value": "CONTACT" },
+        ])
+    })
+})

+ 110 - 0
tests/units/services/data/imageManager.test.ts

@@ -0,0 +1,110 @@
+import { describe, test, it, expect } from 'vitest'
+import ApiRequestService from "~/services/data/apiRequestService";
+import ImageManager from "~/services/data/imageManager";
+import 'blob-polyfill';
+
+let apiRequestService: ApiRequestService
+let imageManager: TestableImageManager
+
+class TestableImageManager extends ImageManager {
+    public async toBase64(data: string) { return super.toBase64(data) }
+    public getCacheKey() { return super.getCacheKey() }
+}
+
+let init_console_error: any
+
+beforeEach(() => {
+    // @ts-ignore
+    apiRequestService = vi.fn() as ApiRequestService
+
+    imageManager = new TestableImageManager(apiRequestService)
+
+    // Important : Restore console error after mocking
+    init_console_error = console.error
+})
+
+afterEach(() => {
+    vi.restoreAllMocks()
+    console.error = init_console_error
+})
+
+describe('get', () => {
+    test('simple call', async () => {
+        const data = "azerty"
+
+        // @ts-ignore
+        apiRequestService.get = vi.fn((url: string) => data)
+
+        imageManager.getCacheKey = vi.fn(() => '123456')
+
+        // @ts-ignore
+        imageManager.toBase64 = vi.fn((data: string) => 'base64:' + data)
+
+        const result = await imageManager.get(1)
+
+        expect(apiRequestService.get).toHaveBeenCalledWith('api/download/1', ['123456'])
+
+        expect(result).toEqual('base64:azerty')
+    })
+
+    test('no id, no default image provided', async () => {
+        expect(await imageManager.get(null)).toEqual(ImageManager.defaultImage)
+    })
+
+    test('no id, default image provided', async () => {
+        const defaultImage = 'a_picture.jpg'
+
+        expect(await imageManager.get(null, defaultImage)).toEqual(defaultImage)
+    })
+
+    test('no response, no default image', async () => {
+        // @ts-ignore
+        apiRequestService.get = vi.fn((url: string) => '')
+
+        imageManager.getCacheKey = vi.fn(() => '123456')
+        // @ts-ignore
+        imageManager.toBase64 = vi.fn()
+
+        console.error = vi.fn()
+
+        const result = await imageManager.get(1)
+
+        expect(apiRequestService.get).toHaveBeenCalledWith('api/download/1', ['123456'])
+        expect(console.error).toHaveBeenCalledWith('Error: image 1 not found or invalid')
+        expect(imageManager.toBase64).toHaveBeenCalledTimes(0)
+
+        expect(result).toEqual(ImageManager.defaultImage)
+    })
+
+    test('no response, default image', async () => {
+        // @ts-ignore
+        apiRequestService.get = vi.fn((url: string) => '')
+
+        imageManager.getCacheKey = vi.fn(() => '123456')
+
+        // @ts-ignore
+        imageManager.toBase64 = vi.fn()
+
+        console.error = vi.fn()
+
+        const result = await imageManager.get(1, 'some_default.jpg')
+
+        expect(apiRequestService.get).toHaveBeenCalledWith('api/download/1', ['123456'])
+        expect(console.error).toHaveBeenCalledWith('Error: image 1 not found or invalid')
+        expect(imageManager.toBase64).toHaveBeenCalledTimes(0)
+
+        expect(result).toEqual('some_default.jpg')
+    })
+})
+
+describe('toBase64', () => {
+    test('simple call', async () => {
+        expect(await imageManager.toBase64('some_data')).toEqual('data:image/jpeg;base64,c29tZV9kYXRh')
+    })
+})
+
+describe('getCacheKey', () => {
+    test('simple call', () => {
+        expect(imageManager.getCacheKey()).toMatch(/\d{10,}/)
+    })
+})