move automation out of core
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { AuthenticationState } from '../../domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from '../../domain/value-objects/BrowserAuthenticationState';
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
|
||||
/**
|
||||
* Port for authentication services implementing zero-knowledge login.
|
||||
@@ -2,7 +2,7 @@ export type AutomationEvent = {
|
||||
actionId?: string
|
||||
type: 'panel-attached'|'modal-opened'|'action-started'|'action-complete'|'action-failed'|'panel-missing'
|
||||
timestamp: number
|
||||
payload?: any
|
||||
payload?: unknown
|
||||
}
|
||||
|
||||
export interface AutomationEventPublisherPort {
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import { CheckoutConfirmation } from '../../domain/value-objects/CheckoutConfirmation';
|
||||
import type { CheckoutConfirmationRequestDTO } from '../dto/CheckoutConfirmationRequestDTO';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import type { CheckoutInfoDTO } from '../dto/CheckoutInfoDTO';
|
||||
|
||||
export interface CheckoutServicePort {
|
||||
@@ -2,7 +2,7 @@ export type AutomationEvent = {
|
||||
actionId?: string
|
||||
type: 'panel-attached'|'modal-opened'|'action-started'|'action-complete'|'action-failed'|'panel-missing'
|
||||
timestamp: number
|
||||
payload?: any
|
||||
payload?: unknown
|
||||
}
|
||||
|
||||
export interface IAutomationEventPublisher {
|
||||
@@ -1,3 +1,4 @@
|
||||
import { SessionStateValue } from '@/automation/domain/value-objects/SessionState';
|
||||
import { AutomationSession } from '../../domain/entities/AutomationSession';
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Result } from '../../../shared/result/Result';
|
||||
import type { Result } from '@gridpilot/shared/result/Result';
|
||||
|
||||
export interface SessionValidatorPort {
|
||||
validateSession(): Promise<Result<boolean>>;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { describe, expect, test } from 'vitest'
|
||||
import { OverlayAction } from '@core/automation/application/ports/IOverlaySyncPort'
|
||||
import { OverlayAction } from 'apps/companion/main/automation/application/ports/IOverlaySyncPort'
|
||||
import { IAutomationLifecycleEmitter, LifecycleCallback } from '@core/automation/infrastructure//IAutomationLifecycleEmitter'
|
||||
import { OverlaySyncService } from '@core/automation/application/services/OverlaySyncService'
|
||||
import { OverlaySyncService } from 'apps/companion/main/automation/application/services/OverlaySyncService'
|
||||
|
||||
class MockLifecycleEmitter implements IAutomationLifecycleEmitter {
|
||||
private callbacks: Set<LifecycleCallback> = new Set()
|
||||
@@ -3,6 +3,8 @@ import { AutomationEventPublisherPort, AutomationEvent } from '../ports/Automati
|
||||
import { AutomationLifecycleEmitterPort, LifecycleCallback } from '../ports/AutomationLifecycleEmitterPort';
|
||||
import { LoggerPort } from '../ports/LoggerPort';
|
||||
import type { IAsyncApplicationService } from '@core/shared/application';
|
||||
import { OverlayAction, OverlaySyncPort } from '../ports/OverlaySyncPort';
|
||||
import { ActionAck } from '../ports/IOverlaySyncPort';
|
||||
|
||||
type ConstructorArgs = {
|
||||
lifecycleEmitter: AutomationLifecycleEmitterPort
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { CheckAuthenticationUseCase } from '@core/automation/application/use-cases/CheckAuthenticationUseCase';
|
||||
import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import { CheckAuthenticationUseCase } from 'apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase';
|
||||
import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import { Result } from '@core/shared/result/Result';
|
||||
import type { AuthenticationServicePort } from '@core/automation/application/ports/AuthenticationServicePort';
|
||||
import type { AuthenticationServicePort } from 'apps/companion/main/automation/application/ports/AuthenticationServicePort';
|
||||
|
||||
interface ISessionValidator {
|
||||
validateSession(): Promise<Result<boolean>>;
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AuthenticationState } from '../../domain/value-objects/AuthenticationState';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort';
|
||||
import { SessionLifetime } from '../../domain/value-objects/SessionLifetime';
|
||||
import type { SessionValidatorPort } from '../ports/SessionValidatorPort';
|
||||
@@ -38,7 +38,7 @@ export class CheckAuthenticationUseCase {
|
||||
this.logger.debug('Performing file-based authentication check.');
|
||||
const fileResult = await this.authService.checkSession();
|
||||
if (fileResult.isErr()) {
|
||||
this.logger.error('File-based authentication check failed.', { error: fileResult.unwrapErr() });
|
||||
this.logger.error('File-based authentication check failed.', fileResult.unwrapErr());
|
||||
return fileResult;
|
||||
}
|
||||
this.logger.info('File-based authentication check succeeded.');
|
||||
@@ -66,7 +66,7 @@ export class CheckAuthenticationUseCase {
|
||||
}
|
||||
this.logger.debug('Session is not expired.');
|
||||
} catch (error) {
|
||||
this.logger.error('Invalid expiry date encountered, treating session as expired.', { expiry, error });
|
||||
this.logger.error('Invalid expiry date encountered, treating session as expired.', error as Error, { expiry });
|
||||
// Invalid expiry date, treat as expired for safety
|
||||
return Result.ok(AuthenticationState.EXPIRED);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ export class CheckAuthenticationUseCase {
|
||||
this.logger.info(`CheckAuthenticationUseCase completed successfully with state: ${fileState}`);
|
||||
return Result.ok(fileState);
|
||||
} catch (error) {
|
||||
this.logger.error('An unexpected error occurred during authentication check.', { error });
|
||||
this.logger.error('An unexpected error occurred during authentication check.', error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
import { vi, Mock } from 'vitest';
|
||||
import { ClearSessionUseCase } from './ClearSessionUseCase';
|
||||
import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
|
||||
describe('ClearSessionUseCase', () => {
|
||||
let useCase: ClearSessionUseCase;
|
||||
let authService: AuthenticationServicePort;
|
||||
let logger: Logger;
|
||||
|
||||
beforeEach(() => {
|
||||
const mockAuthService = {
|
||||
clearSession: vi.fn(),
|
||||
checkSession: vi.fn(),
|
||||
initiateLogin: vi.fn(),
|
||||
getState: vi.fn(),
|
||||
validateServerSide: vi.fn(),
|
||||
refreshSession: vi.fn(),
|
||||
getSessionExpiry: vi.fn(),
|
||||
verifyPageAuthentication: vi.fn(),
|
||||
};
|
||||
|
||||
const mockLogger = {
|
||||
debug: vi.fn(),
|
||||
info: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
};
|
||||
|
||||
authService = mockAuthService as unknown as AuthenticationServicePort;
|
||||
logger = mockLogger as Logger;
|
||||
|
||||
useCase = new ClearSessionUseCase(authService, logger);
|
||||
});
|
||||
|
||||
describe('execute', () => {
|
||||
it('should clear session successfully and return ok result', async () => {
|
||||
const successResult = Result.ok<void>(undefined);
|
||||
(authService.clearSession as Mock).mockResolvedValue(successResult);
|
||||
|
||||
const result = await useCase.execute();
|
||||
|
||||
expect(authService.clearSession).toHaveBeenCalledTimes(1);
|
||||
expect(logger.debug).toHaveBeenCalledWith('Attempting to clear user session.', {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
expect(logger.info).toHaveBeenCalledWith('User session cleared successfully.', {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
expect(result.isOk()).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle clearSession failure and return err result', async () => {
|
||||
const error = new Error('Clear session failed');
|
||||
const failureResult = Result.err<void>(error);
|
||||
(authService.clearSession as Mock).mockResolvedValue(failureResult);
|
||||
|
||||
const result = await useCase.execute();
|
||||
|
||||
expect(authService.clearSession).toHaveBeenCalledTimes(1);
|
||||
expect(logger.debug).toHaveBeenCalledWith('Attempting to clear user session.', {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
expect(logger.warn).toHaveBeenCalledWith('Failed to clear user session.', {
|
||||
useCase: 'ClearSessionUseCase',
|
||||
error: error,
|
||||
});
|
||||
expect(result.isErr()).toBe(true);
|
||||
expect(result.error).toBe(error);
|
||||
});
|
||||
|
||||
it('should handle unexpected errors and return err result with Error', async () => {
|
||||
const thrownError = new Error('Unexpected error');
|
||||
(authService.clearSession as Mock).mockRejectedValue(thrownError);
|
||||
|
||||
const result = await useCase.execute();
|
||||
|
||||
expect(authService.clearSession).toHaveBeenCalledTimes(1);
|
||||
expect(logger.debug).toHaveBeenCalledWith('Attempting to clear user session.', {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
expect(logger.error).toHaveBeenCalledWith('Error clearing user session.', thrownError, {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
expect(result.isErr()).toBe(true);
|
||||
expect(result.error).toBeInstanceOf(Error);
|
||||
expect(result.error?.message).toBe('Unexpected error');
|
||||
});
|
||||
|
||||
it('should handle non-Error thrown values and convert to Error', async () => {
|
||||
const thrownValue = 'String error';
|
||||
(authService.clearSession as Mock).mockRejectedValue(thrownValue);
|
||||
|
||||
const result = await useCase.execute();
|
||||
|
||||
expect(authService.clearSession).toHaveBeenCalledTimes(1);
|
||||
expect(logger.error).toHaveBeenCalledWith('Error clearing user session.', expect.any(Error), {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
expect(result.isErr()).toBe(true);
|
||||
expect(result.error).toBeInstanceOf(Error);
|
||||
expect(result.error?.message).toBe('String error');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
|
||||
@@ -26,7 +26,7 @@ export class ClearSessionUseCase {
|
||||
try {
|
||||
const result = await this.authService.clearSession();
|
||||
|
||||
if (result.isSuccess) {
|
||||
if (result.isOk()) {
|
||||
this.logger.info('User session cleared successfully.', {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
@@ -38,10 +38,11 @@ export class ClearSessionUseCase {
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error('Error clearing user session.', error, {
|
||||
const err = error instanceof Error ? error : new Error(String(error));
|
||||
this.logger.error('Error clearing user session.', err, {
|
||||
useCase: 'ClearSessionUseCase'
|
||||
});
|
||||
return Result.fail(error.message);
|
||||
return Result.err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
||||
import { CompleteRaceCreationUseCase } from '@core/automation/application/use-cases/CompleteRaceCreationUseCase';
|
||||
import { CompleteRaceCreationUseCase } from 'apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase';
|
||||
import { Result } from '@core/shared/result/Result';
|
||||
import { RaceCreationResult } from '@core/automation/domain/value-objects/RaceCreationResult';
|
||||
import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice';
|
||||
import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort';
|
||||
import { CheckoutState } from '@core/automation/domain/value-objects/CheckoutState';
|
||||
import { RaceCreationResult } from 'apps/companion/main/automation/domain/value-objects/RaceCreationResult';
|
||||
import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice';
|
||||
import type { CheckoutServicePort } from 'apps/companion/main/automation/application/ports/CheckoutServicePort';
|
||||
import { CheckoutState } from 'apps/companion/main/automation/domain/value-objects/CheckoutState';
|
||||
|
||||
describe('CompleteRaceCreationUseCase', () => {
|
||||
let mockCheckoutService: CheckoutServicePort;
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import { RaceCreationResult } from '../../domain/value-objects/RaceCreationResult';
|
||||
import type { CheckoutServicePort } from '../ports/CheckoutServicePort';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
@@ -1,12 +1,12 @@
|
||||
import { describe, it, expect, beforeEach, vi, Mock } from 'vitest';
|
||||
import { Result } from '@core/shared/result/Result';
|
||||
import { ConfirmCheckoutUseCase } from '@core/automation/application/use-cases/ConfirmCheckoutUseCase';
|
||||
import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort';
|
||||
import type { CheckoutConfirmationPort } from '@core/automation/application/ports/CheckoutConfirmationPort';
|
||||
import type { CheckoutInfoDTO } from '@core/automation/application/dto/CheckoutInfoDTO';
|
||||
import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice';
|
||||
|
||||
import { CheckoutConfirmation } from '@core/automation/domain/value-objects/CheckoutConfirmation';
|
||||
import { ConfirmCheckoutUseCase } from 'apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase';
|
||||
import type { CheckoutServicePort } from 'apps/companion/main/automation/application/ports/CheckoutServicePort';
|
||||
import type { CheckoutConfirmationPort } from 'apps/companion/main/automation/application/ports/CheckoutConfirmationPort';
|
||||
import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice';
|
||||
import { CheckoutState } from 'apps/companion/main/automation/domain/value-objects/CheckoutState';
|
||||
import { CheckoutConfirmation } from 'apps/companion/main/automation/domain/value-objects/CheckoutConfirmation';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
|
||||
/**
|
||||
* ConfirmCheckoutUseCase - GREEN PHASE
|
||||
@@ -23,6 +23,7 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
let mockConfirmationPort: {
|
||||
requestCheckoutConfirmation: Mock;
|
||||
};
|
||||
let mockLogger: Logger;
|
||||
let mockPrice: CheckoutPrice;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -30,11 +31,21 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
extractCheckoutInfo: vi.fn(),
|
||||
proceedWithCheckout: vi.fn(),
|
||||
};
|
||||
|
||||
|
||||
mockConfirmationPort = {
|
||||
requestCheckoutConfirmation: vi.fn(),
|
||||
};
|
||||
|
||||
|
||||
mockLogger = {
|
||||
debug: vi.fn(),
|
||||
info: vi.fn(),
|
||||
error: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
fatal: vi.fn(),
|
||||
child: vi.fn(() => mockLogger),
|
||||
flush: vi.fn(),
|
||||
} as Logger;
|
||||
|
||||
mockPrice = {
|
||||
getAmount: vi.fn(() => 0.50),
|
||||
toDisplayString: vi.fn(() => '$0.50'),
|
||||
@@ -46,7 +57,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should extract price, get user confirmation, and proceed with checkout', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -75,7 +87,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should include price in confirmation message', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -102,7 +115,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should abort checkout when user cancels confirmation', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -126,7 +140,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should not proceed with checkout after cancellation', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -150,7 +165,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should return error when checkout state is INSUFFICIENT_FUNDS', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -172,7 +188,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should not ask for confirmation when funds are insufficient', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -193,7 +210,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should return error when price cannot be extracted', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -215,7 +233,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should return error when extraction service fails', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -239,7 +258,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -272,7 +292,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -297,7 +318,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('should return error when proceedWithCheckout fails', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -325,7 +347,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('Given checkout price $0.50 and READY state, When user confirms, Then checkout proceeds', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -348,7 +371,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('Given checkout price $0.50, When user cancels, Then checkout is aborted', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -371,7 +395,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('Given INSUFFICIENT_FUNDS state, When executing, Then error is returned', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -390,7 +415,8 @@ describe('ConfirmCheckoutUseCase', () => {
|
||||
it('Given price extraction failure, When executing, Then error is returned', async () => {
|
||||
const useCase = new ConfirmCheckoutUseCase(
|
||||
mockCheckoutService as unknown as CheckoutServicePort,
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort
|
||||
mockConfirmationPort as unknown as CheckoutConfirmationPort,
|
||||
mockLogger
|
||||
);
|
||||
|
||||
mockCheckoutService.extractCheckoutInfo.mockResolvedValue(
|
||||
@@ -1,7 +1,8 @@
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import type { CheckoutServicePort } from '../ports/CheckoutServicePort';
|
||||
import type { CheckoutConfirmationPort } from '../ports/CheckoutConfirmationPort';
|
||||
import { CheckoutStateEnum } from '../../domain/value-objects/CheckoutState';
|
||||
|
||||
|
||||
interface SessionMetadata {
|
||||
@@ -25,7 +26,7 @@ export class ConfirmCheckoutUseCase {
|
||||
const infoResult = await this.checkoutService.extractCheckoutInfo();
|
||||
|
||||
if (infoResult.isErr()) {
|
||||
this.logger.error('Failed to extract checkout info', { error: infoResult.unwrapErr() });
|
||||
this.logger.error('Failed to extract checkout info', infoResult.unwrapErr());
|
||||
return Result.err(infoResult.unwrapErr());
|
||||
}
|
||||
|
||||
@@ -58,7 +59,7 @@ export class ConfirmCheckoutUseCase {
|
||||
});
|
||||
|
||||
if (confirmationResult.isErr()) {
|
||||
this.logger.error('Checkout confirmation failed', { error: confirmationResult.unwrapErr() });
|
||||
this.logger.error('Checkout confirmation failed', confirmationResult.unwrapErr());
|
||||
return Result.err(confirmationResult.unwrapErr());
|
||||
}
|
||||
|
||||
@@ -81,7 +82,7 @@ export class ConfirmCheckoutUseCase {
|
||||
if (checkoutResult.isOk()) {
|
||||
this.logger.info('Checkout process completed successfully.');
|
||||
} else {
|
||||
this.logger.error('Checkout process failed', { error: checkoutResult.unwrapErr() });
|
||||
this.logger.error('Checkout process failed', checkoutResult.unwrapErr());
|
||||
}
|
||||
return checkoutResult;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort';
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
|
||||
@@ -32,8 +32,9 @@ export class InitiateLoginUseCase {
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error('Error initiating login flow.', error);
|
||||
return Result.fail(error.message || 'Unknown error during login initiation.');
|
||||
const err = error instanceof Error ? error : new Error(String(error));
|
||||
this.logger.error('Error initiating login flow.', err);
|
||||
return Result.err(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import { describe, it, expect, vi, beforeEach, Mock } from 'vitest';
|
||||
import { StartAutomationSessionUseCase } from '@core/automation/application/use-cases/StartAutomationSessionUseCase';
|
||||
import { AutomationEnginePort as IAutomationEngine } from '@core/automation/application/ports/AutomationEnginePort';
|
||||
import { IBrowserAutomation as IScreenAutomation } from '@core/automation/application/ports/ScreenAutomationPort';
|
||||
import { SessionRepositoryPort as ISessionRepository } from '@core/automation/application/ports/SessionRepositoryPort';
|
||||
import { AutomationSession } from '@core/automation/domain/entities/AutomationSession';
|
||||
import { StartAutomationSessionUseCase } from 'apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase';
|
||||
import { AutomationEnginePort as IAutomationEngine } from 'apps/companion/main/automation/application/ports/AutomationEnginePort';
|
||||
import { IBrowserAutomation as IScreenAutomation } from 'apps/companion/main/automation/application/ports/ScreenAutomationPort';
|
||||
import { SessionRepositoryPort as ISessionRepository } from 'apps/companion/main/automation/application/ports/SessionRepositoryPort';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import { AutomationSession } from 'apps/companion/main/automation/domain/entities/AutomationSession';
|
||||
|
||||
describe('StartAutomationSessionUseCase', () => {
|
||||
let mockAutomationEngine: {
|
||||
@@ -23,6 +24,12 @@ describe('StartAutomationSessionUseCase', () => {
|
||||
update: Mock;
|
||||
delete: Mock;
|
||||
};
|
||||
let mockLogger: {
|
||||
debug: Mock;
|
||||
info: Mock;
|
||||
warn: Mock;
|
||||
error: Mock;
|
||||
};
|
||||
let useCase: StartAutomationSessionUseCase;
|
||||
|
||||
beforeEach(() => {
|
||||
@@ -46,10 +53,18 @@ describe('StartAutomationSessionUseCase', () => {
|
||||
delete: vi.fn(),
|
||||
};
|
||||
|
||||
mockLogger = {
|
||||
debug: vi.fn(),
|
||||
info: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
};
|
||||
|
||||
useCase = new StartAutomationSessionUseCase(
|
||||
mockAutomationEngine as unknown as IAutomationEngine,
|
||||
mockBrowserAutomation as unknown as IScreenAutomation,
|
||||
mockSessionRepository as unknown as ISessionRepository
|
||||
mockSessionRepository as unknown as ISessionRepository,
|
||||
mockLogger as unknown as Logger
|
||||
);
|
||||
});
|
||||
|
||||
@@ -25,7 +25,6 @@ export class StartAutomationSessionUseCase
|
||||
const validationResult = await this.automationEngine.validateConfiguration(config);
|
||||
if (!validationResult.isValid) {
|
||||
this.logger.warn('Automation session configuration validation failed', { config, error: validationResult.error });
|
||||
this.logger.error('Automation session configuration validation failed', { config, error: validationResult.error });
|
||||
throw new Error(validationResult.error);
|
||||
}
|
||||
this.logger.debug('Automation session configuration validated successfully.');
|
||||
@@ -1,9 +1,9 @@
|
||||
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
||||
import { VerifyAuthenticatedPageUseCase } from '@core/automation/application/use-cases/VerifyAuthenticatedPageUseCase';
|
||||
import { AuthenticationServicePort as IAuthenticationService } from '@core/automation/application/ports/AuthenticationServicePort';
|
||||
import { VerifyAuthenticatedPageUseCase } from 'apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase';
|
||||
import { AuthenticationServicePort as IAuthenticationService } from 'apps/companion/main/automation/application/ports/AuthenticationServicePort';
|
||||
import { Result } from '@core/shared/result/Result';
|
||||
import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState';
|
||||
|
||||
describe('VerifyAuthenticatedPageUseCase', () => {
|
||||
let useCase: VerifyAuthenticatedPageUseCase;
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort';
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import { BrowserAuthenticationState } from '../../domain/value-objects/BrowserAuthenticationState';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
|
||||
@@ -29,7 +29,7 @@ export class VerifyAuthenticatedPageUseCase {
|
||||
return Result.ok<BrowserAuthenticationState>(browserState);
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error);
|
||||
this.logger.error(`Page verification failed unexpectedly: ${message}`, error);
|
||||
this.logger.error(`Page verification failed unexpectedly: ${message}`, error instanceof Error ? error : undefined);
|
||||
return Result.err<BrowserAuthenticationState>(new Error(`Page verification failed: ${message}`));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { AutomationSession } from '@core/automation/domain/entities/AutomationSession';
|
||||
import { StepId } from '@core/automation/domain/value-objects/StepId';
|
||||
import { AutomationSession } from 'apps/companion/main/automation/domain/entities/AutomationSession';
|
||||
import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId';
|
||||
|
||||
describe('AutomationSession Entity', () => {
|
||||
describe('create', () => {
|
||||
@@ -4,6 +4,7 @@ import { StepId } from '../value-objects/StepId';
|
||||
|
||||
import type { HostedSessionConfig } from '../types/HostedSessionConfig';
|
||||
import { AutomationDomainError } from '../errors/AutomationDomainError';
|
||||
import { SessionState } from '../value-objects/SessionState';
|
||||
|
||||
export class AutomationSession implements IEntity<string> {
|
||||
private readonly _id: string;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { PageStateValidator } from '@core/automation/domain/services/PageStateValidator';
|
||||
import { PageStateValidator } from 'apps/companion/main/automation/domain/services/PageStateValidator';
|
||||
|
||||
describe('PageStateValidator', () => {
|
||||
const validator = new PageStateValidator();
|
||||
@@ -7,7 +7,7 @@ describe('PageStateValidator', () => {
|
||||
describe('validateState', () => {
|
||||
it('should return valid when all required selectors are present', () => {
|
||||
// Arrange
|
||||
const actualState = (_selector: string) => {
|
||||
const actualState = (selector: string) => {
|
||||
return ['#add-car-button', '#cars-list'].includes(selector);
|
||||
};
|
||||
|
||||
@@ -27,7 +27,7 @@ describe('PageStateValidator', () => {
|
||||
|
||||
it('should return invalid when required selectors are missing', () => {
|
||||
// Arrange
|
||||
const actualState = (_selector: string) => {
|
||||
const actualState = (selector: string) => {
|
||||
return selector === '#add-car-button'; // Only one of two selectors present
|
||||
};
|
||||
|
||||
@@ -48,7 +48,7 @@ describe('PageStateValidator', () => {
|
||||
|
||||
it('should return invalid when forbidden selectors are present', () => {
|
||||
// Arrange
|
||||
const actualState = (_selector: string) => {
|
||||
const actualState = (selector: string) => {
|
||||
return ['#add-car-button', '#set-track'].includes(selector);
|
||||
};
|
||||
|
||||
@@ -70,7 +70,7 @@ describe('PageStateValidator', () => {
|
||||
|
||||
it('should handle empty forbidden selectors array', () => {
|
||||
// Arrange
|
||||
const actualState = (_selector: string) => {
|
||||
const actualState = (selector: string) => {
|
||||
return selector === '#add-car-button';
|
||||
};
|
||||
|
||||
@@ -89,7 +89,7 @@ describe('PageStateValidator', () => {
|
||||
|
||||
it('should handle undefined forbidden selectors', () => {
|
||||
// Arrange
|
||||
const actualState = (_selector: string) => {
|
||||
const actualState = (selector: string) => {
|
||||
return selector === '#add-car-button';
|
||||
};
|
||||
|
||||
@@ -108,7 +108,7 @@ describe('PageStateValidator', () => {
|
||||
|
||||
it('should return error result when actualState function throws', () => {
|
||||
// Arrange
|
||||
const actualState = (_selector: string) => {
|
||||
const actualState = () => {
|
||||
throw new Error('Selector evaluation failed');
|
||||
};
|
||||
|
||||
@@ -144,7 +144,7 @@ describe('PageStateValidator', () => {
|
||||
|
||||
it('should validate complex state with both required and forbidden selectors', () => {
|
||||
// Arrange - Simulate being on Cars page but Track page elements leaked through
|
||||
const actualState = (_selector: string) => {
|
||||
const actualState = (selector: string) => {
|
||||
const presentSelectors = ['#add-car-button', '#cars-list', '#set-track'];
|
||||
return presentSelectors.includes(selector);
|
||||
};
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { IDomainValidationService } from '@core/shared/domain';
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
|
||||
/**
|
||||
* Configuration for page state validation.
|
||||
@@ -183,7 +183,7 @@ export class PageStateValidator
|
||||
}
|
||||
|
||||
// Check required selectors are present (with fallbacks for real mode)
|
||||
const missingSelectors = requiredSelectors.filter(_selector => {
|
||||
const missingSelectors = requiredSelectors.filter(selector => {
|
||||
if (realMode) {
|
||||
const relatedSelectors = selectorsToCheck.filter(s =>
|
||||
s.includes(expectedStep) ||
|
||||
@@ -1,7 +1,8 @@
|
||||
import { StepId } from '../value-objects/StepId';
|
||||
|
||||
import type { IDomainValidationService } from '@core/shared/domain';
|
||||
import { Result } from '../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import { SessionState } from '../value-objects/SessionState';
|
||||
|
||||
export interface ValidationResult {
|
||||
isValid: boolean;
|
||||
@@ -90,13 +91,11 @@ export class StepTransitionValidator
|
||||
}
|
||||
|
||||
static validateModalStepTransition(
|
||||
currentStep: StepId,
|
||||
nextStep: StepId
|
||||
): ValidationResult {
|
||||
return { isValid: true };
|
||||
}
|
||||
|
||||
static shouldStopAtStep18(_nextStep: StepId): boolean {
|
||||
static shouldStopAtStep18(nextStep: StepId): boolean {
|
||||
return nextStep.isFinalStep();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState';
|
||||
|
||||
describe('BrowserAuthenticationState', () => {
|
||||
describe('isFullyAuthenticated()', () => {
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { CheckoutConfirmation } from '@core/automation/domain/value-objects/CheckoutConfirmation';
|
||||
import { CheckoutConfirmation } from 'apps/companion/main/automation/domain/value-objects/CheckoutConfirmation';
|
||||
|
||||
describe('CheckoutConfirmation Value Object', () => {
|
||||
describe('create', () => {
|
||||
@@ -19,7 +19,8 @@ describe('CheckoutConfirmation Value Object', () => {
|
||||
});
|
||||
|
||||
it('should throw error for invalid decision', () => {
|
||||
expect(() => CheckoutConfirmation.create('invalid' as unknown)).toThrow(
|
||||
// @ts-expect-error Testing invalid input
|
||||
expect(() => CheckoutConfirmation.create('invalid')).toThrow(
|
||||
'Invalid checkout confirmation decision',
|
||||
);
|
||||
});
|
||||
@@ -24,7 +24,7 @@ export class CheckoutConfirmation {
|
||||
return CheckoutConfirmation.create('confirmed');
|
||||
}
|
||||
|
||||
static cancelled(__reason?: string): CheckoutConfirmation {
|
||||
static cancelled(): CheckoutConfirmation {
|
||||
return CheckoutConfirmation.create('cancelled');
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice';
|
||||
import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice';
|
||||
|
||||
/**
|
||||
* CheckoutPrice Value Object - GREEN PHASE
|
||||
@@ -1,4 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { CheckoutState, CheckoutStateEnum } from './CheckoutState';
|
||||
|
||||
|
||||
/**
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, test, expect } from 'vitest';
|
||||
import { CookieConfiguration } from '@core/automation/domain/value-objects/CookieConfiguration';
|
||||
import { CookieConfiguration } from 'apps/companion/main/automation/domain/value-objects/CookieConfiguration';
|
||||
|
||||
describe('CookieConfiguration', () => {
|
||||
const validTargetUrl = 'https://members-ng.iracing.com/jjwtauth/success';
|
||||
@@ -16,7 +16,7 @@ export class CookieConfiguration {
|
||||
this.cookie = cookie;
|
||||
try {
|
||||
this.targetUrl = new URL(targetUrl);
|
||||
} catch (error) {
|
||||
} catch {
|
||||
throw new Error(`Invalid target URL: ${targetUrl}`);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { RaceCreationResult } from '@core/automation/domain/value-objects/RaceCreationResult';
|
||||
import { RaceCreationResult } from 'apps/companion/main/automation/domain/value-objects/RaceCreationResult';
|
||||
|
||||
describe('RaceCreationResult Value Object', () => {
|
||||
describe('create', () => {
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { SessionLifetime } from '@core/automation/domain/value-objects/SessionLifetime';
|
||||
import { SessionLifetime } from 'apps/companion/main/automation/domain/value-objects/SessionLifetime';
|
||||
|
||||
describe('SessionLifetime Value Object', () => {
|
||||
describe('Construction', () => {
|
||||
@@ -1,4 +1,6 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { SessionState } from './SessionState';
|
||||
import type { SessionStateValue } from './SessionState';
|
||||
|
||||
|
||||
describe('SessionState Value Object', () => {
|
||||
@@ -44,11 +46,11 @@ describe('SessionState Value Object', () => {
|
||||
});
|
||||
|
||||
it('should throw error for invalid state', () => {
|
||||
expect(() => SessionState.create('INVALID' as unknown)).toThrow('Invalid session state');
|
||||
expect(() => SessionState.create('INVALID' as SessionStateValue)).toThrow('Invalid session state');
|
||||
});
|
||||
|
||||
it('should throw error for empty string', () => {
|
||||
expect(() => SessionState.create('' as unknown)).toThrow('Invalid session state');
|
||||
expect(() => SessionState.create('' as SessionStateValue)).toThrow('Invalid session state');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { StepId } from '@core/automation/domain/value-objects/StepId';
|
||||
import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId';
|
||||
|
||||
describe('StepId Value Object', () => {
|
||||
describe('create', () => {
|
||||
@@ -10,8 +10,8 @@ vi.mock('electron', () => ({
|
||||
}));
|
||||
|
||||
import { ElectronCheckoutConfirmationAdapter } from '@core/automation/infrastructure//ipc/ElectronCheckoutConfirmationAdapter';
|
||||
import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice';
|
||||
import { CheckoutState } from '@core/automation/domain/value-objects/CheckoutState';
|
||||
import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice';
|
||||
import { CheckoutState } from 'apps/companion/main/automation/domain/value-objects/CheckoutState';
|
||||
import { ipcMain } from 'electron';
|
||||
|
||||
describe('ElectronCheckoutConfirmationAdapter', () => {
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AutomationEvent } from '@core/automation/application/ports/AutomationEventPublisherPort';
|
||||
import { AutomationEvent } from 'apps/companion/main/automation/application/ports/AutomationEventPublisherPort';
|
||||
|
||||
export type LifecycleCallback = (event: AutomationEvent) => Promise<void> | void;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Result } from '../../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import { CheckoutPrice } from '../../../domain/value-objects/CheckoutPrice';
|
||||
import { CheckoutState } from '../../../domain/value-objects/CheckoutState';
|
||||
import type { CheckoutInfoDTO } from '../../../application/dto/CheckoutInfoDTO';
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, test, expect, beforeEach, vi } from 'vitest';
|
||||
import type { Page } from 'playwright';
|
||||
import { AuthenticationGuard } from '@core/automation/infrastructure//automation/auth/AuthenticationGuard';
|
||||
import { AuthenticationGuard } from './AuthenticationGuard';
|
||||
|
||||
describe('AuthenticationGuard', () => {
|
||||
let mockPage: Page;
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Page } from 'playwright';
|
||||
import { LoggerPort } from '@core/automation/application/ports/LoggerPort';
|
||||
import { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort';
|
||||
|
||||
export class AuthenticationGuard {
|
||||
constructor(
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Page } from 'playwright';
|
||||
import type { LoggerPort } from '@core/automation/application/ports/LoggerPort';
|
||||
import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort';
|
||||
import type { IPlaywrightAuthFlow } from './PlaywrightAuthFlow';
|
||||
import { IRACING_URLS, IRACING_SELECTORS, IRACING_TIMEOUTS } from '../dom/IRacingSelectors';
|
||||
import { AuthenticationGuard } from './AuthenticationGuard';
|
||||
@@ -1,12 +1,11 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import type { Page, BrowserContext } from 'playwright';
|
||||
import { PlaywrightAuthSessionService } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthSessionService';
|
||||
import type { PlaywrightBrowserSession } from '@core/automation/infrastructure//automation/core/PlaywrightBrowserSession';
|
||||
import type { SessionCookieStore } from '@core/automation/infrastructure//automation/auth/SessionCookieStore';
|
||||
import type { IPlaywrightAuthFlow } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthFlow';
|
||||
import type { LoggerPort as Logger } from '@core/automation/application/ports/LoggerPort';
|
||||
import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState';
|
||||
import { Result } from '@core/shared/result/Result';
|
||||
import type { LoggerPort as Logger } from 'apps/companion/main/automation/application/ports/LoggerPort';
|
||||
import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState';
|
||||
import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession';
|
||||
import { IPlaywrightAuthFlow } from './PlaywrightAuthFlow';
|
||||
import { PlaywrightAuthSessionService } from './PlaywrightAuthSessionService';
|
||||
import { SessionCookieStore } from './SessionCookieStore';
|
||||
|
||||
describe('PlaywrightAuthSessionService.initiateLogin browser mode behaviour', () => {
|
||||
const originalEnv = { ...process.env };
|
||||
@@ -5,7 +5,7 @@ import type { AuthenticationServicePort } from '../../../../application/ports/Au
|
||||
import type { LoggerPort } from '../../../../application/ports/LoggerPort';
|
||||
import { AuthenticationState } from '../../../../domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from '../../../../domain/value-objects/BrowserAuthenticationState';
|
||||
import { Result } from '../../../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession';
|
||||
import { SessionCookieStore } from './SessionCookieStore';
|
||||
import type { IPlaywrightAuthFlow } from './PlaywrightAuthFlow';
|
||||
@@ -1,13 +1,13 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import type { Page, Locator } from 'playwright';
|
||||
import { PlaywrightAuthSessionService } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthSessionService';
|
||||
import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import type { LoggerPort as Logger } from '@core/automation/application/ports/LoggerPort';
|
||||
import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState';
|
||||
import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState';
|
||||
import type { LoggerPort as Logger } from 'apps/companion/main/automation/application/ports/LoggerPort';
|
||||
import type { Result } from '@core/shared/result/Result';
|
||||
import type { PlaywrightBrowserSession } from '@core/automation/infrastructure//automation/core/PlaywrightBrowserSession';
|
||||
import type { SessionCookieStore } from '@core/automation/infrastructure//automation/auth/SessionCookieStore';
|
||||
import type { IPlaywrightAuthFlow } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthFlow';
|
||||
import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession';
|
||||
import { IPlaywrightAuthFlow } from './PlaywrightAuthFlow';
|
||||
import { PlaywrightAuthSessionService } from './PlaywrightAuthSessionService';
|
||||
import { SessionCookieStore } from './SessionCookieStore';
|
||||
|
||||
describe('PlaywrightAuthSessionService.verifyPageAuthentication', () => {
|
||||
function createService(deps: {
|
||||
@@ -1,6 +1,6 @@
|
||||
import { describe, test, expect, beforeEach } from 'vitest';
|
||||
import { SessionCookieStore } from '@core/automation/infrastructure//automation/auth/SessionCookieStore';
|
||||
import type { Cookie } from 'playwright';
|
||||
import { SessionCookieStore } from './SessionCookieStore';
|
||||
|
||||
const logger = console as unknown;
|
||||
|
||||
@@ -2,7 +2,7 @@ import * as fs from 'fs/promises';
|
||||
import * as path from 'path';
|
||||
import { AuthenticationState } from '../../../../domain/value-objects/AuthenticationState';
|
||||
import { CookieConfiguration } from '../../../../domain/value-objects/CookieConfiguration';
|
||||
import { Result } from '../../../../../shared/result/Result';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import type { LoggerPort } from '../../../../application/ports/LoggerPort';
|
||||
|
||||
interface Cookie {
|
||||
@@ -16,14 +16,12 @@ import type { ModalResultDTO } from '../../../../application/dto/ModalResultDTO'
|
||||
import type { AutomationResultDTO } from '../../../../application/dto/AutomationResultDTO';
|
||||
import type { AuthenticationServicePort } from '../../../../application/ports/AuthenticationServicePort';
|
||||
import type { LoggerPort } from '../../../../application/ports/LoggerPort';
|
||||
import { Result } from '../../../../../shared/result/Result';
|
||||
import { IRACING_SELECTORS, IRACING_URLS, IRACING_TIMEOUTS, ALL_BLOCKED_SELECTORS, BLOCKED_KEYWORDS } from '../dom/IRacingSelectors';
|
||||
import { Result } from '@gridpilot/shared/result/Result';
|
||||
import { IRACING_SELECTORS, IRACING_URLS, IRACING_TIMEOUTS, BLOCKED_KEYWORDS } from '../dom/IRacingSelectors';
|
||||
import { SessionCookieStore } from '../auth/SessionCookieStore';
|
||||
import { PlaywrightBrowserSession } from './PlaywrightBrowserSession';
|
||||
|
||||
import { BrowserModeConfigLoader, BrowserMode } from '../../../config/BrowserModeConfig';
|
||||
|
||||
import { PageStateValidator, PageStateValidation, PageStateValidationResult } from '@core/automation/domain/services/PageStateValidator';
|
||||
import { PageStateValidator, PageStateValidation, PageStateValidationResult } from 'apps/companion/main/automation/domain/services/PageStateValidator';
|
||||
import { IRacingDomNavigator } from '../dom/IRacingDomNavigator';
|
||||
import { SafeClickService } from '../dom/SafeClickService';
|
||||
import { IRacingDomInteractor } from '../dom/IRacingDomInteractor';
|
||||
@@ -4,8 +4,7 @@ import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
|
||||
import type { LoggerPort } from '@core/automation/application/ports/LoggerPort';
|
||||
import { BrowserModeConfigLoader, BrowserMode } from '../../../config/BrowserModeConfig';
|
||||
import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort';
|
||||
|
||||
import type { PlaywrightConfig } from './PlaywrightAutomationAdapter';
|
||||
import { PlaywrightAutomationAdapter } from './PlaywrightAutomationAdapter';
|
||||
@@ -18,7 +18,7 @@ import type {
|
||||
PageStateValidation,
|
||||
PageStateValidationResult,
|
||||
} from '../../../../domain/services/PageStateValidator';
|
||||
import type { Result } from '../../../../../shared/result/Result';
|
||||
import type { Result } from '@gridpilot/shared/result/Result';
|
||||
|
||||
interface WizardStepOrchestratorDeps {
|
||||
config: Required<PlaywrightConfig>;
|
||||
@@ -167,7 +167,7 @@ export class WizardStepOrchestrator {
|
||||
await this.navigator.waitForWizardStep(stepName);
|
||||
}
|
||||
|
||||
private async checkWizardDismissed(_currentStep: number): Promise<void> {
|
||||
private async checkWizardDismissed(currentStep: number): Promise<void> {
|
||||
await this.navigator.checkWizardDismissed(currentStep);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { Page } from 'playwright';
|
||||
import type { LoggerPort } from '@core/automation/application/ports/LoggerPort';
|
||||
import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort';
|
||||
import { IRACING_SELECTORS, BLOCKED_KEYWORDS } from './IRacingSelectors';
|
||||
import type { PlaywrightConfig } from '../core/PlaywrightAutomationAdapter';
|
||||
import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession';
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user