chore: vault tests refactors and lint (#2374)

This commit is contained in:
Karol Sójko
2023-08-02 00:23:56 +02:00
committed by GitHub
parent a0bc1d2488
commit 247daddf5a
96 changed files with 1463 additions and 751 deletions

View File

@@ -51,10 +51,6 @@ const SubscriptionPaths = {
subscriptionTokens: '/v1/subscription-tokens',
}
const SubscriptionPathsV2 = {
subscriptions: '/v2/subscriptions',
}
const UserPathsV2 = {
keyParams: '/v2/login-params',
signIn: '/v2/login',
@@ -75,7 +71,6 @@ export const Paths = {
...UserPaths,
},
v2: {
...SubscriptionPathsV2,
...UserPathsV2,
},
}

View File

@@ -13,6 +13,7 @@ import { ItemManager } from '@Lib/Services/Items/ItemManager'
import { FeaturesService } from '@Lib/Services/Features/FeaturesService'
import { SNComponentManager } from './ComponentManager'
import { SyncService } from '../Sync/SyncService'
import { LoggerInterface } from '@standardnotes/utils'
describe('featuresService', () => {
let items: ItemManagerInterface
@@ -23,6 +24,7 @@ describe('featuresService', () => {
let prefs: PreferenceServiceInterface
let eventBus: InternalEventBusInterface
let device: DeviceInterface
let logger: LoggerInterface
const createManager = (environment: Environment, platform: Platform) => {
const manager = new SNComponentManager(
@@ -35,6 +37,7 @@ describe('featuresService', () => {
environment,
platform,
device,
logger,
eventBus,
)
@@ -46,6 +49,8 @@ describe('featuresService', () => {
addEventListener: jest.fn(),
attachEvent: jest.fn(),
} as unknown as Window & typeof globalThis
logger = {} as jest.Mocked<LoggerInterface>
logger.info = jest.fn()
sync = {} as jest.Mocked<SyncService>
sync.sync = jest.fn()

View File

@@ -29,7 +29,7 @@ import {
GetNativeThemes,
NativeFeatureIdentifier,
} from '@standardnotes/features'
import { Copy, removeFromArray, sleep, isNotUndefined } from '@standardnotes/utils'
import { Copy, removeFromArray, sleep, isNotUndefined, LoggerInterface } from '@standardnotes/utils'
import { ComponentViewer } from '@Lib/Services/ComponentManager/ComponentViewer'
import {
AbstractService,
@@ -98,6 +98,7 @@ export class SNComponentManager
private environment: Environment,
private platform: Platform,
private device: DeviceInterface,
private logger: LoggerInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
@@ -177,6 +178,7 @@ export class SNComponentManager
alerts: this.alerts,
preferences: this.preferences,
features: this.features,
logger: this.logger,
},
{
url: this.urlForFeature(component) ?? '',
@@ -312,7 +314,7 @@ export class SNComponentManager
onWindowMessage = (event: MessageEvent): void => {
const data = event.data as ComponentMessage
if (data.sessionKey) {
this.log('Component manager received message', data)
this.logger.info('Component manager received message', data)
this.componentViewerForSessionKey(data.sessionKey)?.handleMessage(data)
}
}
@@ -369,7 +371,7 @@ export class SNComponentManager
}
public async toggleTheme(uiFeature: UIFeature<ThemeFeatureDescription>): Promise<void> {
this.log('Toggling theme', uiFeature.uniqueIdentifier)
this.logger.info('Toggling theme', uiFeature.uniqueIdentifier)
if (this.isThemeActive(uiFeature)) {
await this.removeActiveTheme(uiFeature)
@@ -449,7 +451,7 @@ export class SNComponentManager
}
public async toggleComponent(component: ComponentInterface): Promise<void> {
this.log('Toggling component', component.uuid)
this.logger.info('Toggling component', component.uuid)
if (this.isComponentActive(component)) {
await this.removeActiveComponent(component)

View File

@@ -65,13 +65,13 @@ import {
extendArray,
Copy,
removeFromArray,
log,
nonSecureRandomIdentifier,
UuidGenerator,
Uuids,
sureSearchArray,
isNotUndefined,
uniqueArray,
LoggerInterface,
} from '@standardnotes/utils'
import { ContentType, Uuid } from '@standardnotes/domain-core'
@@ -80,7 +80,6 @@ export class ComponentViewer implements ComponentViewerInterface {
private streamContextItemOriginalMessage?: ComponentMessage
private streamItemsOriginalMessage?: ComponentMessage
private removeItemObserver: () => void
private loggingEnabled = false
public identifier = nonSecureRandomIdentifier()
private actionObservers: ActionObserver[] = []
@@ -102,6 +101,7 @@ export class ComponentViewer implements ComponentViewerInterface {
alerts: AlertService
preferences: PreferenceServiceInterface
features: FeaturesService
logger: LoggerInterface
},
private options: {
item: ComponentViewerItem
@@ -143,7 +143,7 @@ export class ComponentViewer implements ComponentViewerInterface {
}
})
this.log('Constructor', this)
this.services.logger.info('Constructor', this)
}
public getComponentOrFeatureItem(): UIFeature<IframeComponentFeatureDescription> {
@@ -163,7 +163,7 @@ export class ComponentViewer implements ComponentViewerInterface {
}
public destroy(): void {
this.log('Destroying', this)
this.services.logger.info('Destroying', this)
this.deinit()
}
@@ -347,7 +347,7 @@ export class ComponentViewer implements ComponentViewerInterface {
this.componentUniqueIdentifier.value,
requiredContextPermissions,
() => {
this.log(
this.services.logger.info(
'Send context item in reply',
'component:',
this.componentOrFeature,
@@ -364,18 +364,12 @@ export class ComponentViewer implements ComponentViewerInterface {
)
}
private log(message: string, ...args: unknown[]): void {
if (this.loggingEnabled) {
log('ComponentViewer', message, args)
}
}
private sendItemsInReply(
items: (DecryptedItemInterface | DeletedItemInterface)[],
message: ComponentMessage,
source?: PayloadEmitSource,
): void {
this.log('Send items in reply', this.componentOrFeature, items, message)
this.services.logger.info('Send items in reply', this.componentOrFeature, items, message)
const responseData: MessageReplyData = {}
@@ -453,10 +447,14 @@ export class ComponentViewer implements ComponentViewerInterface {
*/
private sendMessage(message: ComponentMessage | MessageReply, essential = true): void {
if (!this.window && message.action === ComponentAction.Reply) {
this.log('Component has been deallocated in between message send and reply', this.componentOrFeature, message)
this.services.logger.info(
'Component has been deallocated in between message send and reply',
this.componentOrFeature,
message,
)
return
}
this.log('Send message to component', this.componentOrFeature, 'message: ', message)
this.services.logger.info('Send message to component', this.componentOrFeature, 'message: ', message)
if (!this.window) {
if (essential) {
@@ -518,7 +516,7 @@ export class ComponentViewer implements ComponentViewerInterface {
throw Error('Attempting to override component viewer window. Create a new component viewer instead.')
}
this.log('setWindow', 'component: ', this.componentOrFeature, 'window: ', window)
this.services.logger.info('setWindow', 'component: ', this.componentOrFeature, 'window: ', window)
this.window = window
this.sessionKey = UuidGenerator.GenerateUuid()
@@ -537,7 +535,7 @@ export class ComponentViewer implements ComponentViewerInterface {
},
})
this.log('setWindow got new sessionKey', this.sessionKey)
this.services.logger.info('setWindow got new sessionKey', this.sessionKey)
this.postActiveThemes()
}
@@ -557,9 +555,9 @@ export class ComponentViewer implements ComponentViewerInterface {
}
handleMessage(message: ComponentMessage): void {
this.log('Handle message', message, this)
this.services.logger.info('Handle message', message, this)
if (!this.componentOrFeature) {
this.log('Component not defined for message, returning', message)
this.services.logger.info('Component not defined for message, returning', message)
void this.services.alerts.alert(
'A component is trying to communicate with Standard Notes, ' +
'but there is an error establishing a bridge. Please restart the app and try again.',

View File

@@ -27,6 +27,7 @@ import { LegacyApiService, SessionManager } from '../Api'
import { ItemManager } from '../Items'
import { DiskStorageService } from '../Storage/DiskStorageService'
import { SettingsClientInterface } from '../Settings/SettingsClientInterface'
import { LoggerInterface } from '@standardnotes/utils'
describe('FeaturesService', () => {
let storageService: StorageServiceInterface
@@ -45,26 +46,12 @@ describe('FeaturesService', () => {
let items: ItemInterface[]
let internalEventBus: InternalEventBusInterface
let featureService: FeaturesService
const createService = () => {
return new FeaturesService(
storageService,
itemManager,
mutator,
subscriptions,
apiService,
webSocketsService,
settingsService,
userService,
syncService,
alertService,
sessionManager,
crypto,
internalEventBus,
)
}
let logger: LoggerInterface
beforeEach(() => {
logger = {} as jest.Mocked<LoggerInterface>
logger.info = jest.fn()
roles = [RoleName.NAMES.CoreUser, RoleName.NAMES.PlusUser]
items = [] as jest.Mocked<ItemInterface[]>
@@ -133,6 +120,7 @@ describe('FeaturesService', () => {
alertService,
sessionManager,
crypto,
logger,
internalEventBus,
)
})
@@ -199,6 +187,25 @@ describe('FeaturesService', () => {
describe('loadUserRoles()', () => {
it('retrieves user roles and features from storage', async () => {
const createService = () => {
return new FeaturesService(
storageService,
itemManager,
mutator,
subscriptions,
apiService,
webSocketsService,
settingsService,
userService,
syncService,
alertService,
sessionManager,
crypto,
logger,
internalEventBus,
)
}
createService().initializeFromDisk()
expect(storageService.getValue).toHaveBeenCalledWith(StorageKey.UserRoles, undefined, [])
})

View File

@@ -1,5 +1,5 @@
import { MigrateFeatureRepoToUserSettingUseCase } from './UseCase/MigrateFeatureRepoToUserSetting'
import { arraysEqual, removeFromArray, lastElement } from '@standardnotes/utils'
import { arraysEqual, removeFromArray, lastElement, LoggerInterface } from '@standardnotes/utils'
import { ClientDisplayableError } from '@standardnotes/responses'
import { RoleName, ContentType, Uuid } from '@standardnotes/domain-core'
import { PROD_OFFLINE_FEATURES_URL } from '../../Hosts'
@@ -81,6 +81,7 @@ export class FeaturesService
private alerts: AlertService,
private sessions: SessionsClientInterface,
private crypto: PureCryptoInterface,
private logger: LoggerInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
@@ -146,7 +147,7 @@ export class FeaturesService
switch (event.type) {
case ApiServiceEvent.MetaReceived: {
if (!this.sync) {
this.log('Handling events interrupted. Sync service is not yet initialized.', event)
this.logger.warn('Handling events interrupted. Sync service is not yet initialized.', event)
return
}

View File

@@ -2,7 +2,7 @@ import { ContentType } from '@standardnotes/domain-core'
import { AlertService, InternalEventBusInterface, ItemRelationshipDirection } from '@standardnotes/services'
import { ItemManager } from './ItemManager'
import { PayloadManager } from '../Payloads/PayloadManager'
import { UuidGenerator, assert } from '@standardnotes/utils'
import { LoggerInterface, UuidGenerator, assert } from '@standardnotes/utils'
import * as Models from '@standardnotes/models'
import {
DecryptedPayload,
@@ -48,14 +48,18 @@ describe('itemManager', () => {
let payloadManager: PayloadManager
let itemManager: ItemManager
let internalEventBus: InternalEventBusInterface
let logger: LoggerInterface
beforeEach(() => {
setupRandomUuid()
logger = {} as jest.Mocked<LoggerInterface>
logger.debug = jest.fn()
internalEventBus = {} as jest.Mocked<InternalEventBusInterface>
internalEventBus.publish = jest.fn()
payloadManager = new PayloadManager(internalEventBus)
payloadManager = new PayloadManager(logger, internalEventBus)
itemManager = new ItemManager(payloadManager, internalEventBus)
mutator = new MutatorService(itemManager, payloadManager, {} as jest.Mocked<AlertService>, internalEventBus)

View File

@@ -11,7 +11,7 @@ import {
import { ContentType } from '@standardnotes/domain-core'
import { AlertService, InternalEventBusInterface } from '@standardnotes/services'
import { MutatorService, PayloadManager, ItemManager } from '../'
import { UuidGenerator, sleep } from '@standardnotes/utils'
import { UuidGenerator, sleep, LoggerInterface } from '@standardnotes/utils'
const setupRandomUuid = () => {
UuidGenerator.SetGenerator(() => String(Math.random()))
@@ -23,13 +23,17 @@ describe('mutator service', () => {
let itemManager: ItemManager
let internalEventBus: InternalEventBusInterface
let logger: LoggerInterface
beforeEach(() => {
setupRandomUuid()
internalEventBus = {} as jest.Mocked<InternalEventBusInterface>
internalEventBus.publish = jest.fn()
payloadManager = new PayloadManager(internalEventBus)
logger = {} as jest.Mocked<LoggerInterface>
logger.debug = jest.fn()
payloadManager = new PayloadManager(logger, internalEventBus)
itemManager = new ItemManager(payloadManager, internalEventBus)
const alerts = {} as jest.Mocked<AlertService>

View File

@@ -8,16 +8,21 @@ import {
import { PayloadManager } from './PayloadManager'
import { InternalEventBusInterface } from '@standardnotes/services'
import { ContentType } from '@standardnotes/domain-core'
import { LoggerInterface } from '@standardnotes/utils'
describe('payload manager', () => {
let payloadManager: PayloadManager
let internalEventBus: InternalEventBusInterface
let logger: LoggerInterface
beforeEach(() => {
internalEventBus = {} as jest.Mocked<InternalEventBusInterface>
internalEventBus.publish = jest.fn()
payloadManager = new PayloadManager(internalEventBus)
logger = {} as jest.Mocked<LoggerInterface>
logger.debug = jest.fn()
payloadManager = new PayloadManager(logger, internalEventBus)
})
it('emitting a payload should emit as-is and not merge on top of existing payload', async () => {

View File

@@ -1,6 +1,6 @@
import { ContentType } from '@standardnotes/domain-core'
import { PayloadsChangeObserver, QueueElement, PayloadsChangeObserverCallback, EmitQueue } from './Types'
import { removeFromArray, Uuids } from '@standardnotes/utils'
import { LoggerInterface, removeFromArray, Uuids } from '@standardnotes/utils'
import {
DeltaFileImport,
isDeletedPayload,
@@ -42,7 +42,10 @@ export class PayloadManager extends AbstractService implements PayloadManagerInt
public collection: PayloadCollection<FullyFormedPayloadInterface>
private emitQueue: EmitQueue<FullyFormedPayloadInterface> = []
constructor(protected override internalEventBus: InternalEventBusInterface) {
constructor(
private logger: LoggerInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
this.collection = new PayloadCollection()
}
@@ -183,7 +186,7 @@ export class PayloadManager extends AbstractService implements PayloadManagerInt
continue
}
this.log(
this.logger.debug(
'applying payload',
apply.uuid,
'globalDirtyIndexAtLastSync',

View File

@@ -7,7 +7,7 @@ import {
HttpResponse,
isErrorResponse,
RawSyncResponse,
UserEventServerHash,
NotificationServerHash,
AsymmetricMessageServerHash,
getErrorFromErrorResponse,
} from '@standardnotes/responses'
@@ -29,7 +29,7 @@ export class ServerSyncResponse {
readonly asymmetricMessages: AsymmetricMessageServerHash[]
readonly vaults: SharedVaultServerHash[]
readonly vaultInvites: SharedVaultInviteServerHash[]
readonly userEvents: UserEventServerHash[]
readonly userEvents: NotificationServerHash[]
private readonly rawConflictObjects: ConflictParams[]

View File

@@ -1,7 +1,7 @@
import { ConflictParams, ConflictType } from '@standardnotes/responses'
import { log, LoggingDomain } from './../../Logging'
import { AccountSyncOperation } from '@Lib/Services/Sync/Account/Operation'
import {
LoggerInterface,
Uuids,
extendArray,
isNotUndefined,
@@ -80,7 +80,7 @@ import {
isChunkFullEntry,
SyncEventReceivedSharedVaultInvitesData,
SyncEventReceivedRemoteSharedVaultsData,
SyncEventReceivedUserEventsData,
SyncEventReceivedNotificationsData,
SyncEventReceivedAsymmetricMessagesData,
SyncOpStatus,
} from '@standardnotes/services'
@@ -160,6 +160,7 @@ export class SyncService
private device: DeviceInterface,
private identifier: string,
private readonly options: ApplicationSyncOptions,
private logger: LoggerInterface,
protected override internalEventBus: InternalEventBusInterface,
) {
super(internalEventBus)
@@ -258,7 +259,7 @@ export class SyncService
}
public async loadDatabasePayloads(): Promise<void> {
log(LoggingDomain.DatabaseLoad, 'Loading database payloads')
this.logger.debug('Loading database payloads')
if (this.databaseLoaded) {
throw 'Attempting to initialize already initialized local database.'
@@ -353,7 +354,7 @@ export class SyncService
currentPosition?: number,
payloadCount?: number,
) {
log(LoggingDomain.DatabaseLoad, 'Processing batch at index', currentPosition, 'length', batch.length)
this.logger.debug('Processing batch at index', currentPosition, 'length', batch.length)
const encrypted: EncryptedPayloadInterface[] = []
const nonencrypted: (DecryptedPayloadInterface | DeletedPayloadInterface)[] = []
@@ -419,7 +420,7 @@ export class SyncService
}
public async markAllItemsAsNeedingSyncAndPersist(): Promise<void> {
log(LoggingDomain.Sync, 'Marking all items as needing sync')
this.logger.debug('Marking all items as needing sync')
const items = this.itemManager.items
const payloads = items.map((item) => {
@@ -485,7 +486,7 @@ export class SyncService
const promise = this.spawnQueue[0]
removeFromIndex(this.spawnQueue, 0)
log(LoggingDomain.Sync, 'Syncing again from spawn queue')
this.logger.debug('Syncing again from spawn queue')
return this.sync({
queueStrategy: SyncQueueStrategy.ForceSpawnNew,
@@ -547,7 +548,7 @@ export class SyncService
public async sync(options: Partial<SyncOptions> = {}): Promise<unknown> {
if (this.clientLocked) {
log(LoggingDomain.Sync, 'Sync locked by client')
this.logger.debug('Sync locked by client')
return
}
@@ -613,8 +614,7 @@ export class SyncService
if (shouldExecuteSync) {
this.syncLock = true
} else {
log(
LoggingDomain.Sync,
this.logger.debug(
!canExecuteSync
? 'Another function call has begun preparing for sync.'
: syncInProgress
@@ -727,8 +727,7 @@ export class SyncService
payloads: (DeletedPayloadInterface | DecryptedPayloadInterface)[],
options: SyncOptions,
) {
log(
LoggingDomain.Sync,
this.logger.debug(
'Syncing offline user',
'source:',
SyncSource[options.source],
@@ -812,8 +811,7 @@ export class SyncService
},
)
log(
LoggingDomain.Sync,
this.logger.debug(
'Syncing online user',
'source',
SyncSource[options.source],
@@ -925,7 +923,7 @@ export class SyncService
}
private async handleOfflineResponse(response: OfflineSyncResponse) {
log(LoggingDomain.Sync, 'Offline Sync Response', response)
this.logger.debug('Offline Sync Response', response)
const masterCollection = this.payloadManager.getMasterCollection()
@@ -943,7 +941,7 @@ export class SyncService
}
private handleErrorServerResponse(response: ServerSyncResponse) {
log(LoggingDomain.Sync, 'Sync Error', response)
this.logger.debug('Sync Error', response)
if (response.status === INVALID_SESSION_RESPONSE_STATUS) {
void this.notifyEvent(SyncEvent.InvalidSession)
@@ -968,7 +966,10 @@ export class SyncService
const historyMap = this.historyService.getHistoryMapCopy()
if (response.userEvents && response.userEvents.length > 0) {
await this.notifyEventSync(SyncEvent.ReceivedUserEvents, response.userEvents as SyncEventReceivedUserEventsData)
await this.notifyEventSync(
SyncEvent.ReceivedNotifications,
response.userEvents as SyncEventReceivedNotificationsData,
)
}
if (response.asymmetricMessages && response.asymmetricMessages.length > 0) {
@@ -1003,8 +1004,7 @@ export class SyncService
historyMap,
)
log(
LoggingDomain.Sync,
this.logger.debug(
'Online Sync Response',
'Operator ID',
operation.id,
@@ -1263,7 +1263,7 @@ export class SyncService
}
private async syncAgainByHandlingRequestsWaitingInResolveQueue(options: SyncOptions) {
log(LoggingDomain.Sync, 'Syncing again from resolve queue')
this.logger.debug('Syncing again from resolve queue')
const promise = this.sync({
source: SyncSource.ResolveQueue,
checkIntegrity: options.checkIntegrity,