From 4e6cc77a286c1e307a8ccf9285b415d09267303c Mon Sep 17 00:00:00 2001 From: divy-11 Date: Mon, 20 Oct 2025 16:39:45 +0530 Subject: [PATCH] Removed new state pdfDocs - update reverse-pages function - updated test-case --- src/js/handlers/fileHandler.ts | 9 +++--- src/js/logic/reverse-pages.ts | 9 ++++-- src/js/state.ts | 2 -- src/tests/reversePages.multi.test.ts | 47 +++++++++++++++------------- 4 files changed, 35 insertions(+), 32 deletions(-) diff --git a/src/js/handlers/fileHandler.ts b/src/js/handlers/fileHandler.ts index 5515926..b5cfc68 100644 --- a/src/js/handlers/fileHandler.ts +++ b/src/js/handlers/fileHandler.ts @@ -25,9 +25,9 @@ async function handleSinglePdfUpload(toolId, file) { showLoader('Loading PDF...'); try { const pdfBytes = await readFileAsArrayBuffer(file); - const pdfDoc = await PDFLibDocument.load(pdfBytes as ArrayBuffer, { ignoreEncryption: true }); - state.pdfDocs = [pdfDoc]; - state.pdfDoc = pdfDoc; + state.pdfDoc = await PDFLibDocument.load(pdfBytes as ArrayBuffer, { + ignoreEncryption: true + }); hideLoader(); if ( @@ -324,7 +324,6 @@ async function handleSinglePdfUpload(toolId, file) { } async function handleMultiFileUpload(toolId) { - console.log(toolId); if (toolId === 'merge' || toolId === 'alternate-merge' || toolId === 'reverse-pages') { const pdfFilesUnloaded: File[] = []; @@ -347,7 +346,7 @@ async function handleMultiFileUpload(toolId) { }; }) ); - state.pdfDocs = pdfFilesLoaded.map(p => p.pdfDoc); + const foundEncryptedPDFs = pdfFilesLoaded.filter( (pdf) => pdf.pdfDoc.isEncrypted ); diff --git a/src/js/logic/reverse-pages.ts b/src/js/logic/reverse-pages.ts index 08bed23..2b47278 100644 --- a/src/js/logic/reverse-pages.ts +++ b/src/js/logic/reverse-pages.ts @@ -6,7 +6,7 @@ import { PDFDocument as PDFLibDocument } from 'pdf-lib'; import JSZip from 'jszip'; export async function reversePages() { - const pdfDocs = Array.isArray(state.pdfDocs) ? state.pdfDocs : state.pdfDoc ? [state.pdfDoc] : []; + const pdfDocs = state.files.filter((file: File) => file.type === 'application/pdf'); if (!pdfDocs.length) { showAlert('Error', 'PDF not loaded.'); return; @@ -15,7 +15,9 @@ export async function reversePages() { try { const zip = new JSZip(); for (let j = 0; j < pdfDocs.length; j++) { - const pdfDoc = pdfDocs[j]; + const file = pdfDocs[j]; + const arrayBuffer = await file.arrayBuffer(); + const pdfDoc = await PDFLibDocument.load(arrayBuffer); const newPdf = await PDFLibDocument.create(); const pageCount = pdfDoc.getPageCount(); const reversedIndices = Array.from( @@ -27,7 +29,8 @@ export async function reversePages() { copiedPages.forEach((page: any) => newPdf.addPage(page)); const newPdfBytes = await newPdf.save(); - const fileName = pdfDocs.length > 1 ? `reversed_${j + 1}.pdf` : 'reversed.pdf'; + const originalName = file.name.replace(/\.pdf$/i, ''); + const fileName = `${originalName}_reversed.pdf`; zip.file(fileName, newPdfBytes); } const zipBlob = await zip.generateAsync({ type: 'blob' }); diff --git a/src/js/state.ts b/src/js/state.ts index 9b07460..4950b43 100644 --- a/src/js/state.ts +++ b/src/js/state.ts @@ -1,7 +1,6 @@ export const state = { activeTool: null, files: [], - pdfDocs: [], pdfDoc: null, pdfPages: [], currentPdfUrl: null, @@ -11,7 +10,6 @@ export const state = { export function resetState() { state.activeTool = null; state.files = []; - state.pdfDocs = []; state.pdfDoc = null; state.pdfPages = []; state.currentPdfUrl = null; diff --git a/src/tests/reversePages.multi.test.ts b/src/tests/reversePages.multi.test.ts index fcee27b..c25bce1 100644 --- a/src/tests/reversePages.multi.test.ts +++ b/src/tests/reversePages.multi.test.ts @@ -6,7 +6,6 @@ import * as helpers from '../js/utils/helpers'; import * as ui from '../js/ui'; import JSZip from 'jszip'; -// -------------------- Mock Modules -------------------- vi.mock('../js/ui', () => ({ showLoader: vi.fn(), hideLoader: vi.fn(), @@ -20,18 +19,21 @@ vi.mock('../js/utils/helpers', () => ({ vi.mock('pdf-lib', () => ({ PDFDocument: { create: vi.fn(), + load: vi.fn().mockResolvedValue({ + getPageCount: vi.fn(() => 2), + copyPages: vi.fn((_, indices) => + Promise.resolve(indices.map((i) => ({ page: `page-${i}` }))) + ), + }), }, })); -// -------------------- Test Suite -------------------- describe('reversePages - multi PDF support', () => { let mockNewDoc: any; beforeEach(() => { - // Reset state - state.pdfDocs = []; + state.files = []; // ✅ now using files, not pdfDocs - // Mock PDFDocument.create mockNewDoc = { copyPages: vi.fn((doc: any, indices: number[]) => Promise.resolve(indices.map((i: number) => ({ page: `page-${i}` }))) @@ -41,7 +43,6 @@ describe('reversePages - multi PDF support', () => { }; vi.mocked(PDFLibDocument.create).mockResolvedValue(mockNewDoc); - // Mock helpers vi.mocked(helpers.downloadFile).mockImplementation(() => {}); vi.mocked(ui.showLoader).mockImplementation(() => {}); vi.mocked(ui.hideLoader).mockImplementation(() => {}); @@ -53,35 +54,33 @@ describe('reversePages - multi PDF support', () => { }); it('should reverse pages for multiple PDFs and create a zip', async () => { - // Mock 2 PDFs - const pdf1 = { getPageCount: () => 2 }; - const pdf2 = { getPageCount: () => 3 }; - state.pdfDocs = [pdf1, pdf2]; + const mockFile = (name: string) => ({ + name, + type: 'application/pdf', + arrayBuffer: vi.fn().mockResolvedValue(new ArrayBuffer(8)), + }); + + state.files = [mockFile('a.pdf'), mockFile('b.pdf')]; // ✅ now matches function await reversePages(); - // downloadFile called expect(helpers.downloadFile).toHaveBeenCalledWith(expect.any(Blob), 'reversed_pdfs.zip'); - - // copyPages called for each PDF expect(mockNewDoc.copyPages).toHaveBeenCalledTimes(2); - - // addPage called correct number of times expect(mockNewDoc.addPage).toHaveBeenCalled(); - - // save called for each PDF expect(mockNewDoc.save).toHaveBeenCalledTimes(2); }); it('should handle empty PDF list gracefully', async () => { - state.pdfDocs = []; + state.files = []; await reversePages(); expect(ui.showAlert).toHaveBeenCalledWith('Error', 'PDF not loaded.'); }); it('should handle PDF creation errors', async () => { vi.mocked(PDFLibDocument.create).mockRejectedValue(new Error('Create failed')); - state.pdfDocs = [{ getPageCount: () => 2 }]; + state.files = [ + { name: 'x.pdf', type: 'application/pdf', arrayBuffer: vi.fn().mockResolvedValue(new ArrayBuffer(8)) }, + ]; await reversePages(); @@ -91,7 +90,9 @@ describe('reversePages - multi PDF support', () => { it('should handle PDF processing errors', async () => { mockNewDoc.copyPages.mockRejectedValue(new Error('Copy failed')); - state.pdfDocs = [{ getPageCount: () => 2 }]; + state.files = [ + { name: 'y.pdf', type: 'application/pdf', arrayBuffer: vi.fn().mockResolvedValue(new ArrayBuffer(8)) }, + ]; await reversePages(); @@ -101,11 +102,13 @@ describe('reversePages - multi PDF support', () => { it('should handle save errors', async () => { mockNewDoc.save.mockRejectedValue(new Error('Save failed')); - state.pdfDocs = [{ getPageCount: () => 2 }]; + state.files = [ + { name: 'z.pdf', type: 'application/pdf', arrayBuffer: vi.fn().mockResolvedValue(new ArrayBuffer(8)) }, + ]; await reversePages(); expect(ui.showAlert).toHaveBeenCalledWith('Error', 'Could not reverse the PDF pages.'); expect(ui.hideLoader).toHaveBeenCalled(); }); -}); +}); \ No newline at end of file