TSK-421: Improve Core testing and coverage (#2387)

* Improve coverage for clients.ts

Signed-off-by: Denis Maslennikov <denis.maslennikov@gmail.com>

* Refactor and fix comments

Signed-off-by: Denis Maslennikov <denis.maslennikov@gmail.com>

* Fix typo

Signed-off-by: Denis Maslennikov <denis.maslennikov@gmail.com>

* Fix formatting

Signed-off-by: Denis Maslennikov <denis.maslennikov@gmail.com>

* Added 2 tests for hierarchy.ts

Signed-off-by: Denis Maslennikov <denis.maslennikov@gmail.com>

Signed-off-by: Denis Maslennikov <denis.maslennikov@gmail.com>
This commit is contained in:
Denis Maslennikov 2022-11-23 21:45:08 +07:00 committed by GitHub
parent 13ba272718
commit 2238986bdb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 170 additions and 5 deletions

View File

@ -1,6 +1,6 @@
//
// Copyright © 2020, 2021 Anticrm Platform Contributors.
// Copyright © 2021 Hardcore Engineering, Inc.
// Copyright © 2021, 2022 Hardcore Engineering, Inc.
//
// Licensed under the Eclipse Public License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. You may
@ -13,15 +13,21 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
import { Space } from '../classes'
import { createClient } from '../client'
import { Plugin, IntlString } from '@hcengineering/platform'
import type { Class, Doc, Domain, Ref } from '../classes'
import { Space, ClassifierKind, DOMAIN_MODEL } from '../classes'
import { createClient, ClientConnection } from '../client'
import core from '../component'
import { Hierarchy } from '../hierarchy'
import { ModelDb, TxDb } from '../memdb'
import { TxOperations } from '../operations'
import type { DocumentQuery, FindResult, TxResult } from '../storage'
import { Tx, TxFactory, TxProcessor } from '../tx'
import { connect } from './connection'
import { genMinModel } from './minmodel'
describe('client', () => {
it('client', async () => {
it('should create client and spaces', async () => {
const klass = core.class.Space
const client = new TxOperations(await createClient(connect), core.account.System)
const result = await client.findAll(klass, {})
@ -46,5 +52,127 @@ describe('client', () => {
})
const result3 = await client.findAll(klass, {})
expect(result3).toHaveLength(4)
const result4 = await client.findOne(klass, {})
expect(result4).toEqual(result3[0])
})
it('should create client with plugins', async () => {
const txFactory = new TxFactory(core.account.System)
const txes = genMinModel()
txes.push(
txFactory.createTxCreateDoc(
core.class.Class,
core.space.Model,
{
label: 'PluginConfiguration' as IntlString,
extends: core.class.Doc,
kind: ClassifierKind.CLASS,
domain: DOMAIN_MODEL
},
core.class.PluginConfiguration
)
)
async function connectPlugin (handler: (tx: Tx) => void): Promise<ClientConnection> {
const hierarchy = new Hierarchy()
for (const tx of txes) hierarchy.tx(tx)
const transactions = new TxDb(hierarchy)
const model = new ModelDb(hierarchy)
for (const tx of txes) {
await transactions.tx(tx)
await model.tx(tx)
}
async function findAll<T extends Doc> (_class: Ref<Class<T>>, query: DocumentQuery<T>): Promise<FindResult<T>> {
return await transactions.findAll(_class, query)
}
return {
findAll,
tx: async (tx: Tx): Promise<TxResult> => {
if (tx.objectSpace === core.space.Model) {
hierarchy.tx(tx)
}
const result = await Promise.all([transactions.tx(tx)])
return result[0]
},
close: async () => {},
loadChunk: async (domain: Domain, idx?: number) => ({
idx: -1,
index: -1,
docs: {},
finished: true,
digest: ''
}),
closeChunk: async (idx: number) => {},
loadDocs: async (domain: Domain, docs: Ref<Doc>[]) => [],
upload: async (domain: Domain, docs: Doc[]) => {},
clean: async (domain: Domain, docs: Ref<Doc>[]) => {}
}
}
const spyCreate = jest.spyOn(TxProcessor, 'createDoc2Doc')
const spyUpdate = jest.spyOn(TxProcessor, 'updateDoc2Doc')
const pluginData1 = {
pluginId: 'testPlugin1',
transactions: []
}
const txCreateDoc1 = txFactory.createTxCreateDoc(core.class.PluginConfiguration, core.space.Model, pluginData1)
txes.push(txCreateDoc1)
const client1 = new TxOperations(await createClient(connectPlugin, ['testPlugin1' as Plugin]), core.account.System)
const result1 = await client1.findAll(core.class.PluginConfiguration, {})
expect(result1).toHaveLength(1)
expect(result1[0]._id).toStrictEqual(txCreateDoc1.objectId)
expect(spyCreate).toHaveBeenLastCalledWith(txCreateDoc1)
expect(spyUpdate).toBeCalledTimes(0)
await client1.close()
const pluginData2 = {
pluginId: 'testPlugin2',
transactions: []
}
const txCreateDoc2 = txFactory.createTxCreateDoc(core.class.PluginConfiguration, core.space.Model, pluginData2)
txes.push(txCreateDoc2)
const client2 = new TxOperations(await createClient(connectPlugin, ['testPlugin1' as Plugin]), core.account.System)
const result2 = await client2.findAll(core.class.PluginConfiguration, {})
expect(result2).toHaveLength(2)
expect(result2[0]._id).toStrictEqual(txCreateDoc1.objectId)
expect(result2[1]._id).toStrictEqual(txCreateDoc2.objectId)
expect(spyCreate).toHaveBeenLastCalledWith(txCreateDoc2)
expect(spyUpdate).toBeCalledTimes(0)
await client2.close()
const pluginData3 = {
pluginId: 'testPlugin3',
transactions: [txCreateDoc1._id]
}
const txUpdateDoc = txFactory.createTxUpdateDoc(
core.class.PluginConfiguration,
core.space.Model,
txCreateDoc1.objectId,
pluginData3
)
txes.push(txUpdateDoc)
const client3 = new TxOperations(await createClient(connectPlugin, ['testPlugin2' as Plugin]), core.account.System)
const result3 = await client3.findAll(core.class.PluginConfiguration, {})
expect(result3).toHaveLength(1)
expect(result3[0]._id).toStrictEqual(txCreateDoc2.objectId)
expect(spyCreate).toHaveBeenLastCalledWith(txCreateDoc2)
expect(spyUpdate.mock.calls[1][1]).toStrictEqual(txUpdateDoc)
expect(spyUpdate).toBeCalledTimes(2)
await client3.close()
spyCreate.mockReset()
spyCreate.mockRestore()
spyUpdate.mockReset()
spyUpdate.mockRestore()
})
})

View File

@ -17,6 +17,7 @@ import type { Class, Doc, Obj, Ref } from '../classes'
import type { TxCreateDoc } from '../tx'
import core from '../component'
import { Hierarchy } from '../hierarchy'
import * as Proxy from '../proxy'
import { genMinModel, test } from './minmodel'
const txes = genMinModel()
@ -69,4 +70,40 @@ describe('hierarchy', () => {
const modelDomain = hierarchy.getDomain(core.class.Class)
expect(modelDomain).toBe('model')
})
it('should create Mixin proxy', async () => {
const spyProxy = jest.spyOn(Proxy, '_createMixinProxy')
const hierarchy = prepare()
hierarchy.as(txes[0], test.mixin.TestMixin)
expect(spyProxy).toBeCalledTimes(1)
hierarchy.as(txes[0], test.mixin.TestMixin)
expect(spyProxy).toBeCalledTimes(1)
spyProxy.mockReset()
spyProxy.mockRestore()
})
it('should call static methods', async () => {
const spyToDoc = jest.spyOn(Proxy, '_toDoc')
Hierarchy.toDoc(txes[0])
expect(spyToDoc).toBeCalledTimes(1)
spyToDoc.mockReset()
spyToDoc.mockRestore()
const spyMixinClass = jest.spyOn(Proxy, '_mixinClass')
Hierarchy.mixinClass(txes[0])
expect(spyMixinClass).toBeCalledTimes(1)
spyMixinClass.mockImplementationOnce(() => undefined).mockImplementationOnce(() => test.mixin.TestMixin)
let result = Hierarchy.mixinOrClass(txes[0])
expect(result).toStrictEqual(txes[0]._class)
result = Hierarchy.mixinOrClass(txes[0])
expect(result).toStrictEqual(test.mixin.TestMixin)
expect(spyMixinClass).toBeCalledTimes(3)
spyMixinClass.mockReset()
spyMixinClass.mockRestore()
})
})