mirror of
https://github.com/Frooodle/Stirling-PDF.git
synced 2026-03-04 02:20:19 +01:00
Add Remove Password UI into V2 (#4214)
# Description of Changes - Add UI for Remove Password tool - Fix more translation warnings that were being thrown in the console - Add an encrypted PDF thumbnail and refactor thumbnail generation code
This commit is contained in:
@@ -49,7 +49,7 @@ const LandingPage = () => {
|
||||
activateOnClick={false}
|
||||
styles={{
|
||||
root: {
|
||||
'&[data-accept]': {
|
||||
'&[dataAccept]': {
|
||||
backgroundColor: 'var(--landing-drop-paper-bg)',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { describe, expect, test, vi, beforeEach } from 'vitest';
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { MantineProvider } from '@mantine/core';
|
||||
import RemovePasswordSettings from './RemovePasswordSettings';
|
||||
import { defaultParameters } from '../../../hooks/tools/removePassword/useRemovePasswordParameters';
|
||||
|
||||
// Mock useTranslation with predictable return values
|
||||
const mockT = vi.fn((key: string) => `mock-${key}`);
|
||||
vi.mock('react-i18next', () => ({
|
||||
useTranslation: () => ({ t: mockT })
|
||||
}));
|
||||
|
||||
// Wrapper component to provide Mantine context
|
||||
const TestWrapper = ({ children }: { children: React.ReactNode }) => (
|
||||
<MantineProvider>{children}</MantineProvider>
|
||||
);
|
||||
|
||||
describe('RemovePasswordSettings', () => {
|
||||
const mockOnParameterChange = vi.fn();
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
test('should render password input field', () => {
|
||||
render(
|
||||
<TestWrapper>
|
||||
<RemovePasswordSettings
|
||||
parameters={defaultParameters}
|
||||
onParameterChange={mockOnParameterChange}
|
||||
/>
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
expect(screen.getByText('mock-removePassword.password.label')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
test('should call onParameterChange when password is entered', () => {
|
||||
render(
|
||||
<TestWrapper>
|
||||
<RemovePasswordSettings
|
||||
parameters={defaultParameters}
|
||||
onParameterChange={mockOnParameterChange}
|
||||
/>
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
const passwordInput = screen.getByPlaceholderText('mock-removePassword.password.placeholder');
|
||||
fireEvent.change(passwordInput, { target: { value: 'test-password' } });
|
||||
|
||||
expect(mockOnParameterChange).toHaveBeenCalledWith('password', 'test-password');
|
||||
});
|
||||
|
||||
test('should display current password value', () => {
|
||||
const parametersWithPassword = { ...defaultParameters, password: 'current-password' };
|
||||
|
||||
render(
|
||||
<TestWrapper>
|
||||
<RemovePasswordSettings
|
||||
parameters={parametersWithPassword}
|
||||
onParameterChange={mockOnParameterChange}
|
||||
/>
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
const passwordInput = screen.getByPlaceholderText('mock-removePassword.password.placeholder') as HTMLInputElement;
|
||||
expect(passwordInput.value).toBe('current-password');
|
||||
});
|
||||
|
||||
test('should disable password input when disabled prop is true', () => {
|
||||
render(
|
||||
<TestWrapper>
|
||||
<RemovePasswordSettings
|
||||
parameters={defaultParameters}
|
||||
onParameterChange={mockOnParameterChange}
|
||||
disabled={true}
|
||||
/>
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
const passwordInput = screen.getByPlaceholderText('mock-removePassword.password.placeholder');
|
||||
expect(passwordInput).toBeDisabled();
|
||||
});
|
||||
|
||||
test('should enable password input when disabled prop is false', () => {
|
||||
render(
|
||||
<TestWrapper>
|
||||
<RemovePasswordSettings
|
||||
parameters={defaultParameters}
|
||||
onParameterChange={mockOnParameterChange}
|
||||
disabled={false}
|
||||
/>
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
const passwordInput = screen.getByPlaceholderText('mock-removePassword.password.placeholder');
|
||||
expect(passwordInput).not.toBeDisabled();
|
||||
});
|
||||
|
||||
test('should show password input as required', () => {
|
||||
render(
|
||||
<TestWrapper>
|
||||
<RemovePasswordSettings
|
||||
parameters={defaultParameters}
|
||||
onParameterChange={mockOnParameterChange}
|
||||
/>
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
const passwordInput = screen.getByPlaceholderText('mock-removePassword.password.placeholder');
|
||||
expect(passwordInput).toHaveAttribute('required');
|
||||
});
|
||||
|
||||
test('should call translation function with correct keys', () => {
|
||||
render(
|
||||
<TestWrapper>
|
||||
<RemovePasswordSettings
|
||||
parameters={defaultParameters}
|
||||
onParameterChange={mockOnParameterChange}
|
||||
/>
|
||||
</TestWrapper>
|
||||
);
|
||||
|
||||
expect(mockT).toHaveBeenCalledWith('removePassword.password.label', 'Current Password');
|
||||
expect(mockT).toHaveBeenCalledWith('removePassword.password.placeholder', 'Enter current password');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Stack, Text, PasswordInput } from "@mantine/core";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { RemovePasswordParameters } from "../../../hooks/tools/removePassword/useRemovePasswordParameters";
|
||||
|
||||
interface RemovePasswordSettingsProps {
|
||||
parameters: RemovePasswordParameters;
|
||||
onParameterChange: (key: keyof RemovePasswordParameters, value: string) => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const RemovePasswordSettings = ({ parameters, onParameterChange, disabled = false }: RemovePasswordSettingsProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Stack gap="sm">
|
||||
<PasswordInput
|
||||
label={t('removePassword.password.label', 'Current Password')}
|
||||
placeholder={t('removePassword.password.placeholder', 'Enter current password')}
|
||||
value={parameters.password}
|
||||
onChange={(e) => onParameterChange('password', e.target.value)}
|
||||
disabled={disabled}
|
||||
required
|
||||
/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default RemovePasswordSettings;
|
||||
@@ -11,9 +11,9 @@ export function SuggestedToolsSection(): React.ReactElement {
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<Divider />
|
||||
|
||||
|
||||
<Text size="lg" fw={600}>
|
||||
{t('editYourNewFiles', 'Edit your new File(s)')}
|
||||
{t('editYourNewFiles', 'Edit your new file(s)')}
|
||||
</Text>
|
||||
|
||||
<Stack gap="xs">
|
||||
@@ -39,4 +39,4 @@ export function SuggestedToolsSection(): React.ReactElement {
|
||||
</Stack>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export const useAddPasswordPermissionsTips = (): TooltipContent => {
|
||||
|
||||
return {
|
||||
header: {
|
||||
title: t("addPassword.tooltip.permissions.title", "Document Permissions")
|
||||
title: t("addPassword.tooltip.permissions.title", "Change Permissions")
|
||||
},
|
||||
tips: [
|
||||
{
|
||||
|
||||
20
frontend/src/components/tooltips/useRemovePasswordTips.ts
Normal file
20
frontend/src/components/tooltips/useRemovePasswordTips.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { TooltipContent } from '../../types/tips';
|
||||
|
||||
export const useRemovePasswordTips = (): TooltipContent => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return {
|
||||
header: {
|
||||
title: t("removePassword.title", "Remove Password")
|
||||
},
|
||||
tips: [
|
||||
{
|
||||
description: t(
|
||||
"removePassword.tooltip.description",
|
||||
"Removing password protection requires the current password that was used to encrypt the PDF. This will decrypt the document, making it accessible without a password."
|
||||
)
|
||||
}
|
||||
]
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user