fix: restructure use cases (#650)

This commit is contained in:
Karol Sójko
2023-07-10 12:43:20 +02:00
committed by GitHub
parent 8f90dc172b
commit 04d09582d4
77 changed files with 175 additions and 218 deletions
@@ -0,0 +1,118 @@
import { TimerInterface } from '@standardnotes/time'
import { SharedVaultRepositoryInterface } from '../../../SharedVault/SharedVaultRepositoryInterface'
import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface'
import { AddUserToSharedVault } from './AddUserToSharedVault'
import { Result } from '@standardnotes/domain-core'
import { SharedVault } from '../../../SharedVault/SharedVault'
import { SharedVaultUser } from '../../../SharedVault/User/SharedVaultUser'
describe('AddUserToSharedVault', () => {
let sharedVaultRepository: SharedVaultRepositoryInterface
let sharedVaultUserRepository: SharedVaultUserRepositoryInterface
let timer: TimerInterface
let sharedVault: SharedVault
const validUuid = '00000000-0000-0000-0000-000000000000'
const createUseCase = () => new AddUserToSharedVault(sharedVaultRepository, sharedVaultUserRepository, timer)
beforeEach(() => {
sharedVault = {} as jest.Mocked<SharedVault>
sharedVaultRepository = {} as jest.Mocked<SharedVaultRepositoryInterface>
sharedVaultRepository.findByUuid = jest.fn().mockResolvedValue(sharedVault)
sharedVaultUserRepository = {} as jest.Mocked<SharedVaultUserRepositoryInterface>
sharedVaultUserRepository.save = jest.fn()
timer = {} as jest.Mocked<TimerInterface>
timer.getTimestampInMicroseconds = jest.fn().mockReturnValue(123456789)
})
it('should return a failure result if the shared vault uuid is invalid', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: 'invalid-uuid',
userUuid: validUuid,
permission: 'read',
})
expect(result.isFailed()).toBe(true)
expect(result.getError()).toBe('Given value is not a valid uuid: invalid-uuid')
})
it('should return a failure result if the user uuid is invalid', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: validUuid,
userUuid: 'invalid-uuid',
permission: 'read',
})
expect(result.isFailed()).toBe(true)
expect(result.getError()).toBe('Given value is not a valid uuid: invalid-uuid')
})
it('should return a failure result if the permission is invalid', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: validUuid,
userUuid: validUuid,
permission: 'test',
})
expect(result.isFailed()).toBe(true)
expect(result.getError()).toBe('Invalid shared vault user permission test')
})
it('should return a failure result if the shared vault does not exist', async () => {
const useCase = createUseCase()
sharedVaultRepository.findByUuid = jest.fn().mockResolvedValueOnce(null)
const result = await useCase.execute({
sharedVaultUuid: validUuid,
userUuid: validUuid,
permission: 'read',
})
expect(result.isFailed()).toBe(true)
expect(result.getError()).toBe('Attempting to add a shared vault user to a non-existent shared vault')
})
it('should return a failure result if creating the shared vault user fails', async () => {
const useCase = createUseCase()
const mockSharedVaultUser = jest.spyOn(SharedVaultUser, 'create')
mockSharedVaultUser.mockImplementation(() => {
return Result.fail('Oops')
})
const result = await useCase.execute({
sharedVaultUuid: validUuid,
userUuid: validUuid,
permission: 'read',
})
expect(result.isFailed()).toBe(true)
expect(result.getError()).toBe('Oops')
mockSharedVaultUser.mockRestore()
})
it('should add a user to a shared vault', async () => {
const useCase = createUseCase()
const result = await useCase.execute({
sharedVaultUuid: validUuid,
userUuid: validUuid,
permission: 'read',
})
expect(result.isFailed()).toBe(false)
expect(sharedVaultUserRepository.save).toHaveBeenCalled()
})
})
@@ -0,0 +1,61 @@
import { Result, Timestamps, UseCaseInterface, Uuid } from '@standardnotes/domain-core'
import { TimerInterface } from '@standardnotes/time'
import { AddUserToSharedVaultDTO } from './AddUserToSharedVaultDTO'
import { SharedVaultRepositoryInterface } from '../../../SharedVault/SharedVaultRepositoryInterface'
import { SharedVaultUser } from '../../../SharedVault/User/SharedVaultUser'
import { SharedVaultUserRepositoryInterface } from '../../../SharedVault/User/SharedVaultUserRepositoryInterface'
import { SharedVaultUserPermission } from '../../../SharedVault/User/SharedVaultUserPermission'
export class AddUserToSharedVault implements UseCaseInterface<SharedVaultUser> {
constructor(
private sharedVaultRepository: SharedVaultRepositoryInterface,
private sharedVaultUserRepository: SharedVaultUserRepositoryInterface,
private timer: TimerInterface,
) {}
async execute(dto: AddUserToSharedVaultDTO): Promise<Result<SharedVaultUser>> {
const sharedVaultUuidOrError = Uuid.create(dto.sharedVaultUuid)
if (sharedVaultUuidOrError.isFailed()) {
return Result.fail(sharedVaultUuidOrError.getError())
}
const sharedVaultUuid = sharedVaultUuidOrError.getValue()
const sharedVault = await this.sharedVaultRepository.findByUuid(sharedVaultUuid)
if (!sharedVault) {
return Result.fail('Attempting to add a shared vault user to a non-existent shared vault')
}
const userUuidOrError = Uuid.create(dto.userUuid)
if (userUuidOrError.isFailed()) {
return Result.fail(userUuidOrError.getError())
}
const userUuid = userUuidOrError.getValue()
const permissionOrError = SharedVaultUserPermission.create(dto.permission)
if (permissionOrError.isFailed()) {
return Result.fail(permissionOrError.getError())
}
const permission = permissionOrError.getValue()
const timestamps = Timestamps.create(
this.timer.getTimestampInMicroseconds(),
this.timer.getTimestampInMicroseconds(),
).getValue()
const sharedVaultUserOrError = SharedVaultUser.create({
userUuid,
sharedVaultUuid,
permission,
timestamps,
})
if (sharedVaultUserOrError.isFailed()) {
return Result.fail(sharedVaultUserOrError.getError())
}
const sharedVaultUser = sharedVaultUserOrError.getValue()
await this.sharedVaultUserRepository.save(sharedVaultUser)
return Result.ok(sharedVaultUser)
}
}
@@ -0,0 +1,5 @@
export interface AddUserToSharedVaultDTO {
sharedVaultUuid: string
userUuid: string
permission: string
}