Files
privacy.sexy/tests/unit/infrastructure/Dialog/LoggingDialogDecorator.spec.ts
undergroundwires a721e82a4f Bump TypeScript to 5.3 with verbatimModuleSyntax
This commit upgrades TypeScript to the latest version 5.3 and introduces
`verbatimModuleSyntax` in line with the official Vue guide
recommendatinos (vuejs/docs#2592).

By enforcing `import type` for type-only imports, this commit improves
code clarity and supports tooling optimization, ensuring imports are
only bundled when necessary for runtime.

Changes:

- Bump TypeScript to 5.3.3 across the project.
- Adjust import statements to utilize `import type` where applicable,
  promoting cleaner and more efficient code.
2024-02-27 04:20:22 +01:00

164 lines
5.5 KiB
TypeScript

import { describe, it, expect } from 'vitest';
import type { Logger } from '@/application/Common/Log/Logger';
import { decorateWithLogging } from '@/infrastructure/Dialog/LoggingDialogDecorator';
import { type Dialog, FileType, type SaveFileOutcome } from '@/presentation/common/Dialog';
import { expectExists } from '@tests/shared/Assertions/ExpectExists';
import { DialogStub } from '@tests/unit/shared/Stubs/DialogStub';
import { LoggerStub } from '@tests/unit/shared/Stubs/LoggerStub';
describe('LoggingDialogDecorator', () => {
describe('decorateWithLogging', () => {
describe('saveFile', () => {
it('delegates call to dialog', async () => {
// arrange
const expectedArguments = createTestSaveFileArguments();
const dialog = new DialogStub();
const context = new LoggingDialogDecoratorTestSetup()
.withDialog(dialog);
// act
const decorator = context.decorateWithLogging();
await decorator.saveFile(...expectedArguments);
// assert
expect(dialog.callHistory).to.have.lengthOf(1);
const call = dialog.callHistory.find((c) => c.methodName === 'saveFile');
expectExists(call);
const actualArguments = call.args;
expect(expectedArguments).to.deep.equal(actualArguments);
});
it('returns dialog\'s response', async () => {
// arrange
const expectedResult: SaveFileOutcome = { success: true };
const dialog = new DialogStub();
dialog.saveFile = () => Promise.resolve(expectedResult);
const context = new LoggingDialogDecoratorTestSetup()
.withDialog(dialog);
// act
const decorator = context.decorateWithLogging();
const actualResult = await decorator.saveFile(...createTestSaveFileArguments());
// assert
expect(expectedResult).to.equal(actualResult);
});
it('logs information on invocation', async () => {
// arrange
const expectedLogMessagePart = 'Opening save file dialog';
const loggerStub = new LoggerStub();
const context = new LoggingDialogDecoratorTestSetup()
.withLogger(loggerStub);
// act
const decorator = context.decorateWithLogging();
await decorator.saveFile(...createTestSaveFileArguments());
// assert
loggerStub.assertLogsContainMessagePart('info', expectedLogMessagePart);
});
it('logs information on success', async () => {
// arrange
const expectedLogMessagePart = 'completed successfully';
const loggerStub = new LoggerStub();
const context = new LoggingDialogDecoratorTestSetup()
.withLogger(loggerStub);
// act
const decorator = context.decorateWithLogging();
await decorator.saveFile(...createTestSaveFileArguments());
// assert
loggerStub.assertLogsContainMessagePart('info', expectedLogMessagePart);
});
it('logs error on save failure', async () => {
// arrange
const expectedLogMessagePart = 'Error encountered';
const loggerStub = new LoggerStub();
const dialog = new DialogStub();
dialog.saveFile = () => Promise.resolve({ success: false, error: { message: 'error', type: 'DialogDisplayError' } });
const context = new LoggingDialogDecoratorTestSetup()
.withLogger(loggerStub);
// act
const decorator = context.decorateWithLogging();
await decorator.saveFile(...createTestSaveFileArguments());
// assert
loggerStub.assertLogsContainMessagePart('error', expectedLogMessagePart);
});
});
describe('showError', () => {
it('delegates call to the dialog', () => {
// arrange
const expectedArguments = createTestShowErrorArguments();
const dialog = new DialogStub();
const context = new LoggingDialogDecoratorTestSetup()
.withDialog(dialog);
// act
const decorator = context.decorateWithLogging();
decorator.showError(...expectedArguments);
// assert
expect(dialog.callHistory).to.have.lengthOf(1);
const call = dialog.callHistory.find((c) => c.methodName === 'showError');
expectExists(call);
const actualArguments = call.args;
expect(expectedArguments).to.deep.equal(actualArguments);
});
it('logs error message', () => {
// arrange
const expectedLogMessagePart = 'Showing error dialog';
const loggerStub = new LoggerStub();
const context = new LoggingDialogDecoratorTestSetup()
.withLogger(loggerStub);
// act
const decorator = context.decorateWithLogging();
decorator.showError(...createTestShowErrorArguments());
// assert
loggerStub.assertLogsContainMessagePart('error', expectedLogMessagePart);
});
});
});
});
class LoggingDialogDecoratorTestSetup {
private dialog: Dialog = new DialogStub();
private logger: Logger = new LoggerStub();
public withDialog(dialog: Dialog): this {
this.dialog = dialog;
return this;
}
public withLogger(logger: Logger): this {
this.logger = logger;
return this;
}
public decorateWithLogging() {
return decorateWithLogging(
this.dialog,
this.logger,
);
}
}
function createTestSaveFileArguments(): Parameters<Dialog['saveFile']> {
return [
'test-file-contents',
'test-default-filename',
FileType.BatchFile,
];
}
function createTestShowErrorArguments(): Parameters<Dialog['showError']> {
return [
'test-error-title',
'test-error-message',
];
}