diff --git a/src/components/GeneratePassword/index.test.tsx b/src/components/GeneratePassword/index.test.tsx
index 9f30f86..d38cc87 100644
--- a/src/components/GeneratePassword/index.test.tsx
+++ b/src/components/GeneratePassword/index.test.tsx
@@ -1,5 +1,6 @@
import React from 'react';
import { PasswordMode } from '@enums/passwordMode';
+import * as generatePasswordModule from '@functions/generate/randomPassword';
import { cleanup, fireEvent, render, screen } from '@testing-library/react';
import { waitFor } from '@testing-library/react';
import { afterEach, describe, expect, it, vi } from 'vitest';
@@ -361,4 +362,141 @@ describe('GeneratePassword', () => {
expect(passwordStrengthIndicatorSecondChild).toHaveClass('bg-green-500');
});
+
+ it('should copy an empty string if the password content is null or undefined', async () => {
+ const mockClipboard = {
+ writeText: vi.fn(),
+ };
+
+ Object.defineProperty(navigator, 'clipboard', {
+ value: mockClipboard,
+ writable: true,
+ });
+
+ render(
+
+ );
+
+ // Mocking to return null for textContent
+ const passwordPre = screen.getByTitle('generated password');
+
+ Object.defineProperty(passwordPre, 'textContent', {
+ get: () => null,
+ });
+
+ const copyIcon = screen.getByTitle('Copy Password');
+
+ fireEvent.click(copyIcon);
+
+ await waitFor(() => {
+ expect(mockClipboard.writeText).toHaveBeenCalledWith('');
+ });
+ });
+});
+
+describe('GeneratePassword Error Handling', () => {
+ afterEach(() => {
+ vi.restoreAllMocks();
+ });
+
+ it('should log "Failed to generate password" when an error occurs during password generation', async () => {
+ vi.spyOn(generatePasswordModule, 'randomPassword').mockImplementation(
+ () => {
+ throw new Error('Simulated error');
+ }
+ );
+
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+
+ render(
+
+ );
+
+ const generateButton = screen.getByRole('button', { name: /Generate/i });
+
+ fireEvent.click(generateButton);
+
+ expect(consoleSpy).toHaveBeenCalledWith('Failed to generate password');
+ });
+
+ it('should log "Error generating password" when an error occurs during password generation from slider change', async () => {
+ vi.spyOn(generatePasswordModule, 'randomPassword').mockImplementation(
+ () => {
+ throw new Error('Simulated slider error');
+ }
+ );
+
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+
+ render(
+
+ );
+
+ const slider = screen.getByRole('slider') as HTMLInputElement;
+
+ fireEvent.change(slider, { target: { value: '20' } });
+
+ expect(consoleSpy).toHaveBeenCalledWith('Error generating password');
+
+ vi.restoreAllMocks();
+ });
+
+ it('should log "Failed to copy password" when an error occurs during password copy', async () => {
+ const mockClipboard = {
+ writeText: vi
+ .fn()
+ .mockRejectedValue(new Error('Simulated clipboard error')),
+ };
+
+ Object.defineProperty(navigator, 'clipboard', {
+ value: mockClipboard,
+ writable: true,
+ });
+
+ render(
+
+ );
+
+ const passwordPre = screen.getByTitle('generated password');
+
+ passwordPre.textContent = 'testPassword123!'; // Ensure there is text to copy
+
+ const copyIcon = screen.getByTitle('Copy Password');
+
+ fireEvent.click(copyIcon);
+
+ const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
+
+ await vi.waitFor(() =>
+ expect(consoleSpy).toHaveBeenCalledWith('Failed to copy password')
+ );
+
+ consoleSpy.mockRestore();
+ });
});
diff --git a/vite.config.ts b/vite.config.ts
index 10a6fdc..eadabd7 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -19,17 +19,17 @@ export default defineConfig({
coverage: {
clean: true,
provider: 'istanbul',
- reporter: ['html', 'text', 'json'],
+ reporter: ['html', 'text'],
include: ['src/**/*.ts?(x)'],
exclude: ['src/**/*.js?(x)', 'src/index.tsx', 'src/**/*.test.ts?(x)'],
all: true,
reportsDirectory: './coverage',
thresholds: {
autoUpdate: true,
- statements: 98.63,
- branches: 96.73,
+ statements: 100,
+ branches: 98.19,
functions: 100,
- lines: 98.6,
+ lines: 100,
},
},
globals: true,
@@ -66,4 +66,4 @@ export default defineConfig({
},
],
},
-});
+});
\ No newline at end of file