diff --git a/src/app/services/opfs.spec.ts b/src/app/services/opfs.spec.ts new file mode 100644 index 0000000..63b4b07 --- /dev/null +++ b/src/app/services/opfs.spec.ts @@ -0,0 +1,66 @@ +import { TestBed } from '@angular/core/testing'; +import { vi } from 'vitest'; +import { OPFS } from './opfs'; + +describe('OPFS', () => { + + let service: OPFS; + let dirHandleMock: Partial + let fileHandleMock: Partial; + let writeable: Partial + + let FILENAME_MOCK: string; + let DIR_MOCK: string; + beforeEach(() => { + + FILENAME_MOCK = 'FILENAME_MOCK'; + DIR_MOCK = 'DIR_MOCK'; + + writeable = { + write: vi.fn().mockResolvedValue(undefined), + close: vi.fn().mockResolvedValue(undefined) + }; + fileHandleMock = { + createWritable: vi.fn().mockResolvedValue(writeable), + getFile: vi.fn().mockResolvedValue({arrayBuffer: vi.fn()}), + }; + dirHandleMock = { + getDirectoryHandle: vi.fn().mockResolvedValue(dirHandleMock), + getFileHandle: vi.fn().mockResolvedValue(fileHandleMock), + removeEntry: vi.fn() + }; + (globalThis.navigator).storage = { + getDirectory: vi.fn().mockResolvedValue(dirHandleMock), + persist: vi.fn().mockResolvedValue(true), + persisted: vi.fn().mockResolvedValue(true), + estimate: vi.fn().mockResolvedValue({ usage: 100, quota: 1000 }), + }; + + TestBed.configureTestingModule({}); + service = TestBed.inject(OPFS); + + }); + + it('should be created', () => { + expect(service).toBeTruthy(); + }); + + it('should get a dir handle to write a file to storage', async() => { + const getDirHandlerSpy = vi.spyOn(service, 'getDirHandle'); + const BUFFER_MOCK = new ArrayBuffer(); + await service.writeTo(FILENAME_MOCK, DIR_MOCK, BUFFER_MOCK) + expect(getDirHandlerSpy).toHaveBeenCalledOnce(); + }); + + it('should get a dir handle to read a file from storage', async () => { + const getDirHandlerSpy = vi.spyOn(service, 'getDirHandle'); + await service.readFrom(FILENAME_MOCK, DIR_MOCK); + expect(getDirHandlerSpy).toHaveBeenCalledOnce(); + }); + + it('should get a dir handle to delete a file in storage', async () => { + const getDirHandlerSpy = vi.spyOn(service, 'getDirHandle'); + await service.delete(FILENAME_MOCK, DIR_MOCK); + expect(getDirHandlerSpy).toHaveBeenCalledOnce(); + }); +}); diff --git a/src/app/services/opfs.ts b/src/app/services/opfs.ts new file mode 100644 index 0000000..aff210c --- /dev/null +++ b/src/app/services/opfs.ts @@ -0,0 +1,32 @@ +import { Injectable } from '@angular/core'; + +@Injectable({ + providedIn: 'root', +}) +export class OPFS { + + async writeTo(filename: string, dir: string, data: ArrayBuffer) { + const dirHandler = await this.getDirHandle(dir); + const file = await dirHandler.getFileHandle(filename, { create: true }); + const writable = await file.createWritable(); + await writable.write(data); + await writable.close(); + } + + async readFrom(filename: string, dir: string) { + const dirHandler = await this.getDirHandle(dir); + const file = await dirHandler.getFileHandle(filename); + const fileData = await file.getFile(); + return await fileData.arrayBuffer(); + } + + async delete(filename: string, dir: string) { + const dirHandler = await this.getDirHandle(dir); + await dirHandler.removeEntry(filename); + } + + private async getDirHandle(dir: string) { + const root = await navigator.storage.getDirectory(); + return await root.getDirectoryHandle(dir, { create: true }); + } +}