fix: unify use case usage (#654)

This commit is contained in:
Karol Sójko
2023-07-11 17:05:45 +02:00
committed by GitHub
parent 108408a944
commit 4d1e2dec26
13 changed files with 168 additions and 191 deletions
@@ -42,95 +42,86 @@ describe('CheckIntegrity', () => {
})
it('should return an empty result if there are no integrity mismatches', async () => {
expect(
await createUseCase().execute({
userUuid: '1-2-3',
freeUser: false,
integrityPayloads: [
{
uuid: '1-2-3',
updated_at_timestamp: 1,
},
{
uuid: '2-3-4',
updated_at_timestamp: 2,
},
{
uuid: '3-4-5',
updated_at_timestamp: 3,
},
{
uuid: '5-6-7',
updated_at_timestamp: 5,
},
],
}),
).toEqual({
mismatches: [],
})
})
it('should return a mismatch item that has a different update at timemstap', async () => {
expect(
await createUseCase().execute({
userUuid: '1-2-3',
freeUser: false,
integrityPayloads: [
{
uuid: '1-2-3',
updated_at_timestamp: 1,
},
{
uuid: '2-3-4',
updated_at_timestamp: 1,
},
{
uuid: '3-4-5',
updated_at_timestamp: 3,
},
{
uuid: '5-6-7',
updated_at_timestamp: 5,
},
],
}),
).toEqual({
mismatches: [
const result = await createUseCase().execute({
userUuid: '1-2-3',
freeUser: false,
integrityPayloads: [
{
uuid: '1-2-3',
updated_at_timestamp: 1,
},
{
uuid: '2-3-4',
updated_at_timestamp: 2,
},
],
})
})
it('should return a mismatch item that is missing on the client side', async () => {
expect(
await createUseCase().execute({
userUuid: '1-2-3',
freeUser: false,
integrityPayloads: [
{
uuid: '1-2-3',
updated_at_timestamp: 1,
},
{
uuid: '2-3-4',
updated_at_timestamp: 2,
},
{
uuid: '5-6-7',
updated_at_timestamp: 5,
},
],
}),
).toEqual({
mismatches: [
{
uuid: '3-4-5',
updated_at_timestamp: 3,
},
{
uuid: '5-6-7',
updated_at_timestamp: 5,
},
],
})
expect(result.getValue()).toEqual([])
})
it('should return a mismatch item that has a different update at timemstap', async () => {
const result = await createUseCase().execute({
userUuid: '1-2-3',
freeUser: false,
integrityPayloads: [
{
uuid: '1-2-3',
updated_at_timestamp: 1,
},
{
uuid: '2-3-4',
updated_at_timestamp: 1,
},
{
uuid: '3-4-5',
updated_at_timestamp: 3,
},
{
uuid: '5-6-7',
updated_at_timestamp: 5,
},
],
})
expect(result.getValue()).toEqual([
{
uuid: '2-3-4',
updated_at_timestamp: 2,
},
])
})
it('should return a mismatch item that is missing on the client side', async () => {
const result = await createUseCase().execute({
userUuid: '1-2-3',
freeUser: false,
integrityPayloads: [
{
uuid: '1-2-3',
updated_at_timestamp: 1,
},
{
uuid: '2-3-4',
updated_at_timestamp: 2,
},
{
uuid: '5-6-7',
updated_at_timestamp: 5,
},
],
})
expect(result.getValue()).toEqual([
{
uuid: '3-4-5',
updated_at_timestamp: 3,
},
])
})
})
@@ -1,16 +1,15 @@
import { IntegrityPayload } from '@standardnotes/responses'
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
import { ContentType } from '@standardnotes/common'
import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface'
import { UseCaseInterface } from '../../UseCaseInterface'
import { CheckIntegrityDTO } from './CheckIntegrityDTO'
import { CheckIntegrityResponse } from './CheckIntegrityResponse'
import { ExtendedIntegrityPayload } from '../../../Item/ExtendedIntegrityPayload'
export class CheckIntegrity implements UseCaseInterface {
export class CheckIntegrity implements UseCaseInterface<IntegrityPayload[]> {
constructor(private itemRepository: ItemRepositoryInterface) {}
async execute(dto: CheckIntegrityDTO): Promise<CheckIntegrityResponse> {
async execute(dto: CheckIntegrityDTO): Promise<Result<IntegrityPayload[]>> {
const serverItemIntegrityPayloads = await this.itemRepository.findItemsForComputingIntegrityPayloads(dto.userUuid)
const serverItemIntegrityPayloadsMap = new Map<string, ExtendedIntegrityPayload>()
@@ -59,8 +58,6 @@ export class CheckIntegrity implements UseCaseInterface {
}
}
return {
mismatches,
}
return Result.ok(mismatches)
}
}
@@ -1,5 +0,0 @@
import { IntegrityPayload } from '@standardnotes/responses'
export type CheckIntegrityResponse = {
mismatches: IntegrityPayload[]
}
@@ -15,23 +15,23 @@ describe('GetItem', () => {
})
it('should fail if item is not found', async () => {
expect(
await createUseCase().execute({
userUuid: '1-2-3',
itemUuid: '2-3-4',
}),
).toEqual({ success: false, message: 'Could not find item with uuid 2-3-4' })
const result = await createUseCase().execute({
userUuid: '1-2-3',
itemUuid: '2-3-4',
})
expect(result.isFailed()).toBeTruthy()
expect(result.getError()).toEqual('Could not find item with uuid 2-3-4')
})
it('should succeed if item is found', async () => {
const item = {} as jest.Mocked<Item>
itemRepository.findByUuidAndUserUuid = jest.fn().mockReturnValue(item)
expect(
await createUseCase().execute({
userUuid: '1-2-3',
itemUuid: '2-3-4',
}),
).toEqual({ success: true, item })
const result = await createUseCase().execute({
userUuid: '1-2-3',
itemUuid: '2-3-4',
})
expect(result.getValue()).toEqual(item)
})
})
@@ -1,24 +1,19 @@
import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface'
import { UseCaseInterface } from '../../UseCaseInterface'
import { GetItemDTO } from './GetItemDTO'
import { GetItemResponse } from './GetItemResponse'
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
export class GetItem implements UseCaseInterface {
import { ItemRepositoryInterface } from '../../../Item/ItemRepositoryInterface'
import { GetItemDTO } from './GetItemDTO'
import { Item } from '../../../Item/Item'
export class GetItem implements UseCaseInterface<Item> {
constructor(private itemRepository: ItemRepositoryInterface) {}
async execute(dto: GetItemDTO): Promise<GetItemResponse> {
async execute(dto: GetItemDTO): Promise<Result<Item>> {
const item = await this.itemRepository.findByUuidAndUserUuid(dto.itemUuid, dto.userUuid)
if (item === null) {
return {
success: false,
message: `Could not find item with uuid ${dto.itemUuid}`,
}
return Result.fail(`Could not find item with uuid ${dto.itemUuid}`)
}
return {
success: true,
item,
}
return Result.ok(item)
}
}
@@ -1,11 +0,0 @@
import { Item } from '../../../Item/Item'
export type GetItemResponse =
| {
success: true
item: Item
}
| {
success: false
message: string
}
@@ -54,20 +54,20 @@ describe('SyncItems', () => {
})
it('should sync items', async () => {
expect(
await createUseCase().execute({
userUuid: '1-2-3',
itemHashes: [itemHash],
computeIntegrityHash: false,
syncToken: 'foo',
cursorToken: 'bar',
limit: 10,
readOnlyAccess: false,
contentType: 'Note',
apiVersion: ApiVersion.v20200115,
sessionUuid: null,
}),
).toEqual({
const result = await createUseCase().execute({
userUuid: '1-2-3',
itemHashes: [itemHash],
computeIntegrityHash: false,
syncToken: 'foo',
cursorToken: 'bar',
limit: 10,
readOnlyAccess: false,
contentType: 'Note',
apiVersion: ApiVersion.v20200115,
sessionUuid: null,
snjsVersion: '1.2.3',
})
expect(result.getValue()).toEqual({
conflicts: [],
cursorToken: 'asdzxc',
retrievedItems: [item1],
@@ -93,18 +93,18 @@ describe('SyncItems', () => {
})
it('should sync items and return items keys on top for first sync', async () => {
expect(
await createUseCase().execute({
userUuid: '1-2-3',
itemHashes: [itemHash],
computeIntegrityHash: false,
limit: 10,
readOnlyAccess: false,
sessionUuid: '2-3-4',
contentType: 'Note',
apiVersion: ApiVersion.v20200115,
}),
).toEqual({
const result = await createUseCase().execute({
userUuid: '1-2-3',
itemHashes: [itemHash],
computeIntegrityHash: false,
limit: 10,
readOnlyAccess: false,
sessionUuid: '2-3-4',
contentType: 'Note',
apiVersion: ApiVersion.v20200115,
snjsVersion: '1.2.3',
})
expect(result.getValue()).toEqual({
conflicts: [],
cursorToken: 'asdzxc',
retrievedItems: [item3, item1],
@@ -134,20 +134,21 @@ describe('SyncItems', () => {
syncToken: 'qwerty',
})
expect(
await createUseCase().execute({
userUuid: '1-2-3',
itemHashes: [itemHash],
computeIntegrityHash: false,
syncToken: 'foo',
readOnlyAccess: false,
sessionUuid: '2-3-4',
cursorToken: 'bar',
limit: 10,
contentType: 'Note',
apiVersion: ApiVersion.v20200115,
}),
).toEqual({
const result = await createUseCase().execute({
userUuid: '1-2-3',
itemHashes: [itemHash],
computeIntegrityHash: false,
syncToken: 'foo',
readOnlyAccess: false,
sessionUuid: '2-3-4',
cursorToken: 'bar',
limit: 10,
contentType: 'Note',
apiVersion: ApiVersion.v20200115,
snjsVersion: '1.2.3',
})
expect(result.getValue()).toEqual({
conflicts: [
{
serverItem: item2,
@@ -1,14 +1,14 @@
import { Result, UseCaseInterface } from '@standardnotes/domain-core'
import { Item } from '../../../Item/Item'
import { ItemConflict } from '../../../Item/ItemConflict'
import { ItemServiceInterface } from '../../../Item/ItemServiceInterface'
import { UseCaseInterface } from '../../UseCaseInterface'
import { SyncItemsDTO } from './SyncItemsDTO'
import { SyncItemsResponse } from './SyncItemsResponse'
export class SyncItems implements UseCaseInterface {
export class SyncItems implements UseCaseInterface<SyncItemsResponse> {
constructor(private itemService: ItemServiceInterface) {}
async execute(dto: SyncItemsDTO): Promise<SyncItemsResponse> {
async execute(dto: SyncItemsDTO): Promise<Result<SyncItemsResponse>> {
const getItemsResult = await this.itemService.getItems({
userUuid: dto.userUuid,
syncToken: dto.syncToken,
@@ -38,7 +38,7 @@ export class SyncItems implements UseCaseInterface {
cursorToken: getItemsResult.cursorToken,
}
return syncResponse
return Result.ok(syncResponse)
}
private isFirstSync(dto: SyncItemsDTO): boolean {
@@ -5,10 +5,12 @@ export type SyncItemsDTO = {
itemHashes: Array<ItemHash>
computeIntegrityHash: boolean
limit: number
sharedVaultUuids?: string[] | null
syncToken?: string | null
cursorToken?: string | null
contentType?: string
apiVersion: string
snjsVersion: string
readOnlyAccess: boolean
sessionUuid: string | null
}
@@ -1,3 +0,0 @@
export interface UseCaseInterface {
execute(...args: any[]): Promise<Record<string, unknown>>
}