From 05daffc2f580ed21f06020168b801fd8ac582d7c Mon Sep 17 00:00:00 2001 From: Ben Date: Mon, 26 May 2025 12:51:16 +0200 Subject: [PATCH] Test updates for mainmenu and datamenu --- src/__mocks__/service.mocks.js | 5 ++ src/__mocks__/ui.mocks.js | 5 ++ src/services/dataService.js | 4 +- src/ui/dataMenu.test.js | 123 +++++++++++++++++++++++++++++++++ src/ui/mainMenu.test.js | 11 ++- 5 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 src/ui/dataMenu.test.js diff --git a/src/__mocks__/service.mocks.js b/src/__mocks__/service.mocks.js index d6416a1..2bf8515 100644 --- a/src/__mocks__/service.mocks.js +++ b/src/__mocks__/service.mocks.js @@ -64,3 +64,8 @@ export const mockCodexApp = { export const mockMarketplaceSetup = { runClientWizard: vi.fn(), }; + +export const mockDataService = { + upload: vi.fn(), + download: vi.fn(), +}; diff --git a/src/__mocks__/ui.mocks.js b/src/__mocks__/ui.mocks.js index 1b0b0e2..4a5be0c 100644 --- a/src/__mocks__/ui.mocks.js +++ b/src/__mocks__/ui.mocks.js @@ -7,3 +7,8 @@ export const mockInstallMenu = { export const mockConfigMenu = { show: vi.fn(), }; + +export const mockDataMenu = { + performUpload: vi.fn(), + performDownload: vi.fn(), +}; diff --git a/src/services/dataService.js b/src/services/dataService.js index ff9ded2..7f1701e 100644 --- a/src/services/dataService.js +++ b/src/services/dataService.js @@ -20,7 +20,7 @@ export class DataService { const metadata = { filename: filename, mimetype: contentType }; - const strategy = new NodeUploadStategy(fileData, metadata); + const strategy = new NodeUploadStategy(fileData, metadata); const uploadResponse = data.upload(strategy); const res = await uploadResponse.result; @@ -31,6 +31,8 @@ export class DataService { }; download = async (cid) => { + throw new Error("Waiting for fix of codex-js sdk"); + const data = this.getCodexData(); const manifest = await data.fetchManifest(cid); const filename = this.getFilename(manifest); diff --git a/src/ui/dataMenu.test.js b/src/ui/dataMenu.test.js new file mode 100644 index 0000000..df60d71 --- /dev/null +++ b/src/ui/dataMenu.test.js @@ -0,0 +1,123 @@ +import { describe, beforeEach, it, expect, vi } from "vitest"; +import { DataMenu } from "./dataMenu.js"; +import { + mockUiService, + mockFsService, + mockDataService, +} from "../__mocks__/service.mocks.js"; + +describe("DataMenu", () => { + let dataMenu; + const filePath = "testfilepath"; + const cid = "testcid"; + + beforeEach(() => { + vi.resetAllMocks(); + + dataMenu = new DataMenu(mockUiService, mockFsService, mockDataService); + }); + + describe("performUpload", () => { + beforeEach(() => { + mockUiService.askPrompt.mockResolvedValue(filePath); + mockDataService.upload.mockResolvedValue(cid); + }); + + it("shows encryption warning", async () => { + await dataMenu.performUpload(); + + expect(mockUiService.showInfoMessage).toHaveBeenCalledWith( + "⚠️ Codex does not encrypt files. Anything uploaded will be available publicly on testnet.", + ); + }); + + it("prompts the user for a filepath", async () => { + await dataMenu.performUpload(); + + expect(mockUiService.askPrompt).toHaveBeenCalledWith( + "Enter the file path", + ); + }); + + it("checks that the provided path is a file", async () => { + await dataMenu.performUpload(); + + expect(mockFsService.isFile).toHaveBeenCalledWith(filePath); + }); + + it("shows an error when the provided path is not a file", async () => { + mockFsService.isFile.mockReturnValue(false); + + await dataMenu.performUpload(); + + expect(mockUiService.showErrorMessage).toHaveBeenCalledWith( + "File not found", + ); + }); + + it("calls the data service if the file does exist", async () => { + mockFsService.isFile.mockReturnValue(true); + + await dataMenu.performUpload(); + + expect(mockDataService.upload).toHaveBeenCalledWith(filePath); + expect(mockUiService.showInfoMessage).toHaveBeenCalledWith( + `Upload successful.\n CID: '${cid}'`, + ); + }); + + it("shows an error message when dataService throws", async () => { + const error = "testError"; + mockFsService.isFile.mockReturnValue(true); + mockDataService.upload.mockRejectedValueOnce(new Error(error)); + + await dataMenu.performUpload(); + + expect(mockUiService.showErrorMessage).toHaveBeenCalledWith( + "Error during upload: Error: " + error, + ); + }); + }); + + describe("performDownload", () => { + beforeEach(() => { + mockUiService.askPrompt.mockResolvedValue(cid); + mockDataService.download.mockResolvedValue(filePath); + }); + + it("prompts the user for a cid", async () => { + await dataMenu.performDownload(); + + expect(mockUiService.askPrompt).toHaveBeenCalledWith("Enter the CID"); + }); + + it("does nothing if provided input is empty", async () => { + mockUiService.askPrompt = vi.fn(); + mockUiService.askPrompt.mockResolvedValue(""); + + await dataMenu.performDownload(); + + expect(mockDataService.download).not.toHaveBeenCalled(); + }); + + it("calls the data service with the provided cid", async () => { + await dataMenu.performDownload(); + + expect(mockDataService.download).toHaveBeenCalledWith(cid); + expect(mockUiService.showInfoMessage).toHaveBeenCalledWith( + `Download successful.\n File: '${filePath}'`, + ); + }); + + it("shows an error message when dataService throws", async () => { + const error = "testError"; + mockDataService.download.mockRejectedValueOnce(new Error(error)); + + await dataMenu.performDownload(); + + expect(mockUiService.showErrorMessage).toHaveBeenCalledWith( + "Error during download: Error: " + error, + ); + }); + }); +}); diff --git a/src/ui/mainMenu.test.js b/src/ui/mainMenu.test.js index 445af30..7b9c6f8 100644 --- a/src/ui/mainMenu.test.js +++ b/src/ui/mainMenu.test.js @@ -1,7 +1,11 @@ import { describe, beforeEach, it, expect, vi } from "vitest"; import { MainMenu } from "./mainMenu.js"; import { mockUiService, mockCodexApp } from "../__mocks__/service.mocks.js"; -import { mockInstallMenu, mockConfigMenu } from "../__mocks__/ui.mocks.js"; +import { + mockInstallMenu, + mockConfigMenu, + mockDataMenu, +} from "../__mocks__/ui.mocks.js"; import { mockInstaller, mockProcessControl, @@ -22,6 +26,7 @@ describe("mainmenu", () => { mockInstaller, mockProcessControl, mockCodexApp, + mockDataMenu, ); }); @@ -102,7 +107,7 @@ describe("mainmenu", () => { }); describe("showRunningMenu", () => { - it("shows a menu with options to stop Codex, open Codex app, or exit", async () => { + it("shows a menu with options to stop Codex, open Codex app, upload, download, or exit", async () => { await mainmenu.showRunningMenu(); expect(mockUiService.askMultipleChoice).toHaveBeenCalledWith( @@ -110,6 +115,8 @@ describe("mainmenu", () => { [ { label: "Open Codex app", action: mockCodexApp.openCodexApp }, { label: "Stop Codex", action: mainmenu.stopCodex }, + { label: "Upload a file", action: mockDataMenu.performUpload }, + { label: "Download a file", action: mockDataMenu.performDownload }, { label: "Exit (Codex keeps running)", action: mockMenuLoop.stopLoop,