fix: tests
This commit is contained in:
parent
4e78b643df
commit
6768b15514
44 changed files with 146 additions and 127 deletions
|
@ -8,7 +8,7 @@
|
|||
"main": "src/index.ts",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "pnpm run -w build-package mtcute",
|
||||
"build": "pnpm run -w build-package core",
|
||||
"gen-client": "node ./scripts/generate-client.cjs",
|
||||
"gen-updates": "node ./scripts/generate-updates.cjs"
|
||||
},
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/require-await */
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
import { MtClient, MtClientOptions } from '../network/client.js'
|
||||
|
@ -5,7 +6,14 @@ import { ConnectionKind, RpcCallOptions } from '../network/network-manager.js'
|
|||
import { StorageManagerExtraOptions } from '../storage/storage.js'
|
||||
import { MtArgumentError } from '../types/errors.js'
|
||||
import { MustEqual } from '../types/utils.js'
|
||||
import { asyncResettable, computeNewPasswordHash, computeSrpParams, readStringSession, StringSessionData, writeStringSession } from '../utils/index.js'
|
||||
import {
|
||||
asyncResettable,
|
||||
computeNewPasswordHash,
|
||||
computeSrpParams,
|
||||
readStringSession,
|
||||
StringSessionData,
|
||||
writeStringSession,
|
||||
} from '../utils/index.js'
|
||||
import { LogManager } from '../utils/logger.js'
|
||||
import { ITelegramClient } from './client.types.js'
|
||||
import { ITelegramStorageProvider } from './storage/provider.js'
|
||||
|
@ -29,7 +37,7 @@ export class BaseTelegramClient implements ITelegramClient {
|
|||
this._serverUpdatesHandler = this.updates.handleUpdate.bind(this.updates)
|
||||
}
|
||||
|
||||
this.mt.on('update', (update) => {
|
||||
this.mt.on('update', (update: tl.TypeUpdates) => {
|
||||
this._serverUpdatesHandler(update)
|
||||
})
|
||||
}
|
||||
|
@ -272,16 +280,10 @@ export class BaseTelegramClient implements ITelegramClient {
|
|||
return this.mt.network.getPrimaryDcId()
|
||||
}
|
||||
|
||||
computeSrpParams(
|
||||
request: tl.account.RawPassword,
|
||||
password: string,
|
||||
): Promise<tl.RawInputCheckPasswordSRP> {
|
||||
computeSrpParams(request: tl.account.RawPassword, password: string): Promise<tl.RawInputCheckPasswordSRP> {
|
||||
return computeSrpParams(this.crypto, request, password)
|
||||
}
|
||||
computeNewPasswordHash(
|
||||
algo: tl.TypePasswordKdfAlgo,
|
||||
password: string,
|
||||
): Promise<Uint8Array> {
|
||||
computeNewPasswordHash(algo: tl.TypePasswordKdfAlgo, password: string): Promise<Uint8Array> {
|
||||
return computeNewPasswordHash(this.crypto, algo, password)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4917,7 +4917,7 @@ export interface TelegramClient extends ITelegramClient {
|
|||
* **Available**: ✅ both users and bots
|
||||
*
|
||||
*/
|
||||
getMyUsername(): string | null
|
||||
getMyUsername(): Promise<string | null>
|
||||
/**
|
||||
* Get a single profile picture of a user by its ID
|
||||
*
|
||||
|
|
|
@ -103,7 +103,7 @@ describe('sendText', () => {
|
|||
it('should correctly handle updateShortSentMessage with cached peer', async () => {
|
||||
const client = new StubTelegramClient()
|
||||
|
||||
client.storage.self.store({
|
||||
await client.storage.self.store({
|
||||
userId: stubUser.id,
|
||||
isBot: false,
|
||||
isPremium: false,
|
||||
|
@ -132,7 +132,7 @@ describe('sendText', () => {
|
|||
it('should correctly handle updateShortSentMessage without cached peer', async () => {
|
||||
const client = new StubTelegramClient()
|
||||
|
||||
client.storage.self.store({
|
||||
await client.storage.self.store({
|
||||
userId: stubUser.id,
|
||||
isBot: false,
|
||||
isPremium: false,
|
||||
|
|
|
@ -6,7 +6,6 @@ import { ITelegramClient } from '../../client.types.js'
|
|||
* This method uses locally available information and
|
||||
* does not call any API methods.
|
||||
*/
|
||||
export function getMyUsername(client: ITelegramClient): string | null {
|
||||
throw new Error('Not implemented')
|
||||
// return getAuthState(client).selfUsername
|
||||
export async function getMyUsername(client: ITelegramClient): Promise<string | null> {
|
||||
return client.storage.self.fetch().then((self) => self?.usernames[0] ?? null)
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ export async function setMyUsername(client: ITelegramClient, username: string |
|
|||
username,
|
||||
})
|
||||
|
||||
client.storage.self.update({ username })
|
||||
await client.storage.self.update({ username })
|
||||
|
||||
return new User(res)
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ function parse(data: Uint8Array): CurrentUserInfo | null {
|
|||
|
||||
if (flags & 2) {
|
||||
const len = reader.int()
|
||||
usernames = new Array(len)
|
||||
usernames = new Array<string>(len)
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
usernames[i] = reader.string()
|
||||
|
@ -143,11 +143,7 @@ export class CurrentUserService extends BaseService {
|
|||
return this._cached
|
||||
}
|
||||
|
||||
async update(params: {
|
||||
username?: string
|
||||
usernames?: string[]
|
||||
isPremium?: boolean
|
||||
}): Promise<void> {
|
||||
async update(params: { username?: string; usernames?: string[]; isPremium?: boolean }): Promise<void> {
|
||||
const info = await this.fetch()
|
||||
if (!info) return
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ export function deserializeError(error: SerializedError): Error {
|
|||
for (const key in custom) {
|
||||
if (key === 'code' || key === 'text') continue
|
||||
// @ts-expect-error lol
|
||||
err2[key] = custom[key]
|
||||
err2[key] = custom[key] // eslint-disable-line
|
||||
}
|
||||
break
|
||||
}
|
||||
|
|
|
@ -8,14 +8,9 @@ export class WorkerInvoker {
|
|||
constructor(private send: SendFn) {}
|
||||
|
||||
private _nextId = 0
|
||||
private _pending = new Map<number, ControllablePromise<unknown>>()
|
||||
private _pending = new Map<number, ControllablePromise>()
|
||||
|
||||
private _invoke(
|
||||
target: InvokeTarget,
|
||||
method: string,
|
||||
args: unknown[],
|
||||
isVoid: boolean,
|
||||
) {
|
||||
private _invoke(target: InvokeTarget, method: string, args: unknown[], isVoid: boolean) {
|
||||
const id = this._nextId++
|
||||
|
||||
this.send({
|
||||
|
@ -36,15 +31,12 @@ export class WorkerInvoker {
|
|||
}
|
||||
}
|
||||
|
||||
invoke(
|
||||
target: InvokeTarget,
|
||||
method: string,
|
||||
args: unknown[],
|
||||
): Promise<unknown> {
|
||||
invoke(target: InvokeTarget, method: string, args: unknown[]): Promise<unknown> {
|
||||
return this._invoke(target, method, args, false) as Promise<unknown>
|
||||
}
|
||||
|
||||
invokeVoid(target: InvokeTarget, method: string, args: unknown[]): void {
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this._invoke(target, method, args, true)
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ export function connectToWorker(worker: SomeWorker, handler: ClientMessageHandle
|
|||
const send: SendFn = worker.postMessage.bind(worker)
|
||||
|
||||
const messageHandler = (ev: MessageEvent) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
handler(ev.data)
|
||||
}
|
||||
|
||||
|
@ -37,6 +38,7 @@ export function connectToWorker(worker: SomeWorker, handler: ClientMessageHandle
|
|||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
handler(ev.data)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ export function registerWorker(handler: WorkerMessageHandler): RespondFn {
|
|||
|
||||
const respond: RespondFn = port.postMessage.bind(port)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
parentPort.on('message', (message) => handler(message, respond))
|
||||
|
||||
return respond
|
||||
|
|
|
@ -10,6 +10,7 @@ export function registerWorker(handler: WorkerMessageHandler): RespondFn {
|
|||
if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
|
||||
const respond: RespondFn = self.postMessage.bind(self)
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
self.addEventListener('message', (message) => handler(message.data, respond))
|
||||
|
||||
return respond
|
||||
|
@ -53,7 +54,7 @@ export function registerWorker(handler: WorkerMessageHandler): RespondFn {
|
|||
// so even if the browser has suspended the timers, we should still get a ping within a minute
|
||||
let timeout = setTimeout(onTimeout, 60000)
|
||||
|
||||
port.addEventListener('message', async (message) => {
|
||||
port.addEventListener('message', (message) => {
|
||||
if (message.data.__type__ === 'close') {
|
||||
onClose()
|
||||
|
||||
|
@ -67,6 +68,7 @@ export function registerWorker(handler: WorkerMessageHandler): RespondFn {
|
|||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
handler(message.data, respond)
|
||||
})
|
||||
}
|
||||
|
|
|
@ -72,14 +72,11 @@ export class TelegramWorkerPort<Custom extends WorkerCustomMethods> implements I
|
|||
this._destroyed = true
|
||||
|
||||
if (terminate && 'terminate' in this.options.worker) {
|
||||
this.options.worker.terminate()
|
||||
Promise.resolve(this.options.worker.terminate()).catch(() => {})
|
||||
}
|
||||
}
|
||||
|
||||
invokeCustom<T extends keyof Custom>(
|
||||
method: T,
|
||||
...args: Parameters<Custom[T]>
|
||||
): Promise<ReturnType<Custom[T]>> {
|
||||
invokeCustom<T extends keyof Custom>(method: T, ...args: Parameters<Custom[T]>): Promise<ReturnType<Custom[T]>> {
|
||||
return this._invoker.invoke('custom', method as string, args) as Promise<ReturnType<Custom[T]>>
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ export function makeTelegramWorker<T extends WorkerCustomMethods>(params: Telegr
|
|||
}
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const method = target[msg.method]
|
||||
|
||||
if (!method) {
|
||||
|
@ -57,6 +58,7 @@ export function makeTelegramWorker<T extends WorkerCustomMethods>(params: Telegr
|
|||
return
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
|
||||
Promise.resolve(method.apply(target, msg.args))
|
||||
.then((res) => {
|
||||
if (msg.void) return
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { afterAll, beforeAll, describe } from 'vitest'
|
||||
|
||||
import { testPeersRepository } from '../../../highlevel/storage/repository/peers.test-utils.js'
|
||||
import { testRefMessagesRepository } from '../../../highlevel/storage/repository/ref-messages.test-utils.js'
|
||||
import { testAuthKeysRepository } from '../../repository/auth-keys.test-utils.js'
|
||||
import { testKeyValueRepository } from '../../repository/key-value.test-utils.js'
|
||||
import {
|
||||
testAuthKeysRepository,
|
||||
testKeyValueRepository,
|
||||
testPeersRepository,
|
||||
testRefMessagesRepository,
|
||||
} from '@mtcute/test'
|
||||
|
||||
import { IdbStorage } from './index.js'
|
||||
|
||||
if (import.meta.env.TEST_ENV === 'browser') {
|
||||
|
@ -20,7 +23,7 @@ if (import.meta.env.TEST_ENV === 'browser') {
|
|||
testRefMessagesRepository(storage.refMessages, storage.driver)
|
||||
|
||||
afterAll(async () => {
|
||||
storage.driver.destroy()
|
||||
await storage.driver.destroy()
|
||||
|
||||
const req = indexedDB.deleteDatabase(idbName)
|
||||
await new Promise<void>((resolve, reject) => {
|
||||
|
|
|
@ -39,7 +39,7 @@ export class IdbAuthKeysRepository implements IAuthKeysRepository {
|
|||
async get(dc: number): Promise<Uint8Array | null> {
|
||||
const os = this.os()
|
||||
|
||||
const it = await reqToPromise<AuthKeyDto>(os.get(dc))
|
||||
const it = await reqToPromise<AuthKeyDto>(os.get(dc) as IDBRequest<AuthKeyDto>)
|
||||
if (it === undefined) return null
|
||||
|
||||
return it.key
|
||||
|
@ -61,7 +61,7 @@ export class IdbAuthKeysRepository implements IAuthKeysRepository {
|
|||
|
||||
async getTemp(dc: number, idx: number, now: number): Promise<Uint8Array | null> {
|
||||
const os = this.osTemp()
|
||||
const row = await reqToPromise<TempAuthKeyDto>(os.get([dc, idx]))
|
||||
const row = await reqToPromise<TempAuthKeyDto>(os.get([dc, idx]) as IDBRequest<TempAuthKeyDto>)
|
||||
|
||||
if (row === undefined || row.expiresAt! < now) return null
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ export class IdbKvRepository implements IKeyValueRepository {
|
|||
|
||||
async get(key: string): Promise<Uint8Array | null> {
|
||||
const os = this.os()
|
||||
const res = await reqToPromise<KeyValueDto>(os.get(key))
|
||||
const res = await reqToPromise<KeyValueDto>(os.get(key) as IDBRequest<KeyValueDto>)
|
||||
if (res === undefined) return null
|
||||
|
||||
return res.value
|
||||
|
|
|
@ -22,19 +22,21 @@ export class IdbPeersRepository implements IPeersRepository {
|
|||
}
|
||||
|
||||
async getById(id: number): Promise<IPeersRepository.PeerInfo | null> {
|
||||
const it = await reqToPromise(this.os().get(id))
|
||||
const it = await reqToPromise(this.os().get(id) as IDBRequest<IPeersRepository.PeerInfo>)
|
||||
|
||||
return it ?? null
|
||||
}
|
||||
|
||||
async getByUsername(username: string): Promise<IPeersRepository.PeerInfo | null> {
|
||||
const it = await reqToPromise(this.os().index('by_username').get(username))
|
||||
const it = await reqToPromise(
|
||||
this.os().index('by_username').get(username) as IDBRequest<IPeersRepository.PeerInfo>,
|
||||
)
|
||||
|
||||
return it ?? null
|
||||
}
|
||||
|
||||
async getByPhone(phone: string): Promise<IPeersRepository.PeerInfo | null> {
|
||||
const it = await reqToPromise(this.os().index('by_phone').get(phone))
|
||||
const it = await reqToPromise(this.os().index('by_phone').get(phone) as IDBRequest<IPeersRepository.PeerInfo>)
|
||||
|
||||
return it ?? null
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ export class IdbRefMsgRepository implements IReferenceMessagesRepository {
|
|||
const os = this.os()
|
||||
const index = os.index('by_peer')
|
||||
|
||||
const it = await reqToPromise<MessageRefDto>(index.get(peerId))
|
||||
const it = await reqToPromise<MessageRefDto>(index.get(peerId) as IDBRequest<MessageRefDto>)
|
||||
if (!it) return null
|
||||
|
||||
return [it.chatId, it.msgId]
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
import { describe } from 'vitest'
|
||||
|
||||
import { testPeersRepository } from '../../../highlevel/storage/repository/peers.test-utils.js'
|
||||
import { testRefMessagesRepository } from '../../../highlevel/storage/repository/ref-messages.test-utils.js'
|
||||
import { testAuthKeysRepository } from '../../repository/auth-keys.test-utils.js'
|
||||
import { testKeyValueRepository } from '../../repository/key-value.test-utils.js'
|
||||
import {
|
||||
testAuthKeysRepository,
|
||||
testKeyValueRepository,
|
||||
testPeersRepository,
|
||||
testRefMessagesRepository,
|
||||
} from '@mtcute/test'
|
||||
|
||||
import { MemoryStorage } from './index.js'
|
||||
|
||||
describe('memory storage', () => {
|
||||
|
|
|
@ -1,4 +1,2 @@
|
|||
export * from '../../highlevel/storage/repository/peers.js'
|
||||
export * from '../../highlevel/storage/repository/ref-messages.js'
|
||||
export * from './auth-keys.js'
|
||||
export * from './key-value.js'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { fakeAuthKeysRepository } from '../repository/auth-keys.test-utils.js'
|
||||
import { fakeKeyValueRepository } from '../repository/key-value.test-utils.js'
|
||||
import { fakeAuthKeysRepository, fakeKeyValueRepository } from '@mtcute/test'
|
||||
|
||||
import { AuthKeysService } from './auth-keys.js'
|
||||
import { FutureSaltsService } from './future-salts.js'
|
||||
import { testServiceOptions } from './utils.test-utils.js'
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { fakeKeyValueRepository } from '../repository/key-value.test-utils.js'
|
||||
import { fakeKeyValueRepository } from '@mtcute/test'
|
||||
|
||||
import { UpdatesStateService } from '../../highlevel/storage/service/updates.js'
|
||||
import { testServiceOptions } from './utils.test-utils.js'
|
||||
|
||||
|
@ -73,10 +74,7 @@ describe('updates state service', () => {
|
|||
it('should write to updates_channel:xxx key', async () => {
|
||||
await service.setChannelPts(123, 0x04030201)
|
||||
|
||||
expect(kv.set).toHaveBeenCalledWith(
|
||||
'updates_channel:123',
|
||||
new Uint8Array([1, 2, 3, 4]),
|
||||
)
|
||||
expect(kv.set).toHaveBeenCalledWith('updates_channel:123', new Uint8Array([1, 2, 3, 4]))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -62,7 +62,9 @@ export class StorageManager {
|
|||
this.driver.setup?.(this.log)
|
||||
|
||||
if (this.options.cleanup ?? true) {
|
||||
this._cleanupRestore = beforeExit(() => this._destroy().catch((err) => this.log.error(err)))
|
||||
this._cleanupRestore = beforeExit(() => {
|
||||
this._destroy().catch((err) => this.log.error('cleanup error: %s', err))
|
||||
})
|
||||
}
|
||||
|
||||
await this.driver.load?.()
|
||||
|
|
|
@ -51,8 +51,9 @@ export function asyncResettable<T extends(...args: any[]) => Promise<any>>(func:
|
|||
return runningPromise
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
runningPromise = func(...args)
|
||||
runningPromise.then(() => {
|
||||
void runningPromise.then(() => {
|
||||
runningPromise = null
|
||||
finished = true
|
||||
})
|
||||
|
|
|
@ -125,7 +125,12 @@ describe('readStringSession', () => {
|
|||
testMode: false,
|
||||
primaryDcs: stubDcs,
|
||||
authKey: stubAuthKey,
|
||||
self: { userId: 12345, isBot: false },
|
||||
self: {
|
||||
userId: 12345,
|
||||
isBot: false,
|
||||
isPremium: false,
|
||||
usernames: [],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -140,7 +145,12 @@ describe('readStringSession', () => {
|
|||
testMode: true,
|
||||
primaryDcs: stubDcs,
|
||||
authKey: stubAuthKey,
|
||||
self: { userId: 12345, isBot: false },
|
||||
self: {
|
||||
userId: 12345,
|
||||
isBot: false,
|
||||
isPremium: false,
|
||||
usernames: [],
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -158,7 +168,12 @@ describe('readStringSession', () => {
|
|||
// v1 didn't have separate media dc
|
||||
primaryDcs: stubDcsSameMedia,
|
||||
authKey: stubAuthKey,
|
||||
self: { userId: 12345, isBot: false },
|
||||
self: {
|
||||
userId: 12345,
|
||||
isBot: false,
|
||||
isPremium: false,
|
||||
usernames: [],
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { CallbackQuery, MtArgumentError, PeersIndex } from '@mtcute/client'
|
||||
import { utf8EncodeToBuffer } from '@mtcute/client/utils.js'
|
||||
import { CallbackQuery, MtArgumentError, PeersIndex } from '@mtcute/core'
|
||||
import { utf8EncodeToBuffer } from '@mtcute/core/utils.js'
|
||||
import { createStub } from '@mtcute/test'
|
||||
|
||||
import { CallbackDataBuilder } from './callback-data-builder.js'
|
||||
|
|
|
@ -20,12 +20,12 @@ describe('filters.command', () => {
|
|||
const ctx = createMessageContext({
|
||||
message: text,
|
||||
})
|
||||
// todo
|
||||
// ctx.client.getAuthState = () => ({
|
||||
// isBot: true,
|
||||
// userId: 0,
|
||||
// selfUsername: 'testbot',
|
||||
// })
|
||||
void ctx.client.storage.self.store({
|
||||
isBot: true,
|
||||
isPremium: false,
|
||||
userId: 0,
|
||||
usernames: ['testbot'],
|
||||
})
|
||||
|
||||
// eslint-disable-next-line
|
||||
if (command(...params)(ctx)) return (ctx as any).command
|
||||
|
@ -39,11 +39,10 @@ describe('filters.command', () => {
|
|||
expect(getParsedCommand('/start', ['start', 'stop'])).toEqual(['start'])
|
||||
})
|
||||
|
||||
// todo
|
||||
// it('should only parse commands to the current bot', () => {
|
||||
// expect(getParsedCommand('/start@testbot', 'start')).toEqual(['start'])
|
||||
// expect(getParsedCommand('/start@otherbot', 'start')).toEqual(null)
|
||||
// })
|
||||
it('should only parse commands to the current bot', () => {
|
||||
expect(getParsedCommand('/start@testbot', 'start')).toEqual(['start'])
|
||||
expect(getParsedCommand('/start@otherbot', 'start')).toEqual(null)
|
||||
})
|
||||
|
||||
it('should parse command arguments', () => {
|
||||
expect(getParsedCommand('/start foo bar baz', 'start')).toEqual(['start', 'foo', 'bar', 'baz'])
|
||||
|
|
|
@ -18,15 +18,14 @@ export class StateService {
|
|||
async load() {
|
||||
await this._load.run()
|
||||
this._vacuumTimer = setInterval(() => {
|
||||
Promise.resolve(this.provider.state.vacuum(Date.now()))
|
||||
.catch(() => {})
|
||||
Promise.resolve(this.provider.state.vacuum(Date.now())).catch(() => {})
|
||||
}, 300_000)
|
||||
}
|
||||
|
||||
async destroy() {
|
||||
await this.provider.driver.save?.()
|
||||
await this.provider.driver.destroy?.()
|
||||
clearInterval(this._vacuumTimer!)
|
||||
clearInterval(this._vacuumTimer)
|
||||
this._loaded = false
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { PeersIndex, TelegramClient } from '@mtcute/client'
|
||||
import { PeersIndex, TelegramClient } from '@mtcute/core'
|
||||
|
||||
import { Dispatcher, PropagationAction } from '../src/index.js'
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Long from 'long'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { MessageEntity, TextWithEntities, tl } from '@mtcute/client'
|
||||
import { MessageEntity, TextWithEntities, tl } from '@mtcute/core'
|
||||
|
||||
// prettier has "html" special-cased which breaks the formatting
|
||||
// this is not an issue when using normally, since we properly handle newlines/spaces,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { Message, PeersIndex } from '@mtcute/client'
|
||||
import { Message, PeersIndex } from '@mtcute/core'
|
||||
import { MessageContext } from '@mtcute/dispatcher'
|
||||
|
||||
import { createMtcuteI18n, OtherLanguageWrap } from '../src/index.js'
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import Long from 'long'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { MessageEntity, TextWithEntities, tl } from '@mtcute/client'
|
||||
import { MessageEntity, TextWithEntities, tl } from '@mtcute/core'
|
||||
|
||||
// md is special cased in prettier, we don't want that here
|
||||
import { md as md_ } from './index.js'
|
||||
|
|
|
@ -18,7 +18,7 @@ function mapPeerDto(dto: PeerDto): IPeersRepository.PeerInfo {
|
|||
return {
|
||||
id: dto.id,
|
||||
accessHash: dto.hash,
|
||||
usernames: JSON.parse(dto.usernames),
|
||||
usernames: JSON.parse(dto.usernames) as string[],
|
||||
updated: dto.updated,
|
||||
phone: dto.phone || undefined,
|
||||
complete: dto.complete,
|
||||
|
@ -47,7 +47,9 @@ export class SqlitePeersRepository implements IPeersRepository {
|
|||
)
|
||||
|
||||
this._getById = db.prepare('select * from peers where id = ?')
|
||||
this._getByUsername = db.prepare('select * from peers where exists (select 1 from json_each(usernames) where value = ?)')
|
||||
this._getByUsername = db.prepare(
|
||||
'select * from peers where exists (select 1 from json_each(usernames) where value = ?)',
|
||||
)
|
||||
this._getByPhone = db.prepare('select * from peers where phone = ?')
|
||||
|
||||
this._delAll = db.prepare('delete from peers')
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
import { afterAll, beforeAll, describe } from 'vitest'
|
||||
|
||||
import { testAuthKeysRepository } from '@mtcute/core/src/storage/repository/auth-keys.test-utils.js'
|
||||
import { testKeyValueRepository } from '@mtcute/core/src/storage/repository/key-value.test-utils.js'
|
||||
import { testPeersRepository } from '@mtcute/core/src/storage/repository/peers.test-utils.js'
|
||||
import { testRefMessagesRepository } from '@mtcute/core/src/storage/repository/ref-messages.test-utils.js'
|
||||
import { LogManager } from '@mtcute/core/utils.js'
|
||||
import {
|
||||
testAuthKeysRepository,
|
||||
testKeyValueRepository,
|
||||
testPeersRepository,
|
||||
testRefMessagesRepository,
|
||||
} from '@mtcute/test'
|
||||
|
||||
import { SqliteStorage } from '../src/index.js'
|
||||
|
||||
|
@ -12,9 +14,9 @@ if (import.meta.env.TEST_ENV === 'node') {
|
|||
describe('SqliteStorage', () => {
|
||||
const storage = new SqliteStorage(':memory:')
|
||||
|
||||
beforeAll(() => {
|
||||
beforeAll(async () => {
|
||||
storage.driver.setup(new LogManager())
|
||||
storage.driver.load()
|
||||
await storage.driver.load()
|
||||
})
|
||||
|
||||
testAuthKeysRepository(storage.authKeys)
|
||||
|
|
|
@ -24,6 +24,7 @@ export class StubTelegramClient extends BaseTelegramClient {
|
|||
apiHash: '',
|
||||
logLevel: 0,
|
||||
storage,
|
||||
disableUpdates: true,
|
||||
transport: () => {
|
||||
const transport = new StubTelegramTransport({
|
||||
onMessage: (data) => {
|
||||
|
@ -279,15 +280,8 @@ export class StubTelegramClient extends BaseTelegramClient {
|
|||
|
||||
// helpers //
|
||||
|
||||
async connectAndWait() {
|
||||
await this.connect()
|
||||
await new Promise((resolve): void => {
|
||||
this.mt.once('usable', resolve)
|
||||
})
|
||||
}
|
||||
|
||||
async with(fn: () => MaybeAsync<void>): Promise<void> {
|
||||
await this.connectAndWait()
|
||||
await this.connect()
|
||||
|
||||
let error: unknown
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export * from './client.js'
|
||||
export * from './crypto.js'
|
||||
export * from './storage.js'
|
||||
// export * from './storage-test.js' // todo
|
||||
export * from './storage/index.js'
|
||||
export * from './stub.js'
|
||||
export * from './transport.js'
|
||||
export * from './types.js'
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { IAuthKeysRepository } from './auth-keys.js'
|
||||
import { IAuthKeysRepository } from '@mtcute/core'
|
||||
|
||||
export function fakeAuthKeysRepository(): IAuthKeysRepository {
|
||||
return {
|
4
packages/test/src/storage/index.ts
Normal file
4
packages/test/src/storage/index.ts
Normal file
|
@ -0,0 +1,4 @@
|
|||
export * from './auth-keys.js'
|
||||
export * from './key-value.js'
|
||||
export * from './peers.js'
|
||||
export * from './ref-messages.js'
|
|
@ -1,7 +1,6 @@
|
|||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { IStorageDriver } from '../driver.js'
|
||||
import { IKeyValueRepository } from './key-value.js'
|
||||
import { IKeyValueRepository, IStorageDriver } from '@mtcute/core'
|
||||
|
||||
export function fakeKeyValueRepository(): IKeyValueRepository {
|
||||
return {
|
|
@ -1,11 +1,10 @@
|
|||
import { describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { createStub } from '@mtcute/test'
|
||||
import { IPeersRepository, IStorageDriver } from '@mtcute/core'
|
||||
import { TlBinaryWriter } from '@mtcute/core/utils.js'
|
||||
import { __tlWriterMap } from '@mtcute/tl/binary/writer.js'
|
||||
import { TlBinaryWriter } from '@mtcute/tl-runtime'
|
||||
|
||||
import { IStorageDriver } from '../../../storage/driver.js'
|
||||
import { IPeersRepository } from './peers.js'
|
||||
import { createStub } from '../stub.js'
|
||||
|
||||
export function fakePeersRepository(): IPeersRepository {
|
||||
return {
|
||||
|
@ -56,8 +55,8 @@ export function testPeersRepository(repo: IPeersRepository, driver: IStorageDriv
|
|||
})
|
||||
|
||||
it('should store and retrieve peers', async () => {
|
||||
repo.store(stubPeerUser)
|
||||
repo.store(stubPeerChannel)
|
||||
await repo.store(stubPeerUser)
|
||||
await repo.store(stubPeerChannel)
|
||||
await driver.save?.()
|
||||
|
||||
expect(fixPeerInfo(await repo.getById(123123))).toEqual(stubPeerUser)
|
||||
|
@ -69,11 +68,11 @@ export function testPeersRepository(repo: IPeersRepository, driver: IStorageDriv
|
|||
})
|
||||
|
||||
it('should update peers usernames', async () => {
|
||||
repo.store(stubPeerUser)
|
||||
await repo.store(stubPeerUser)
|
||||
await driver.save?.()
|
||||
|
||||
const modUser = { ...stubPeerUser, usernames: ['some_user2'] }
|
||||
repo.store(modUser)
|
||||
await repo.store(modUser)
|
||||
await driver.save?.()
|
||||
|
||||
expect(fixPeerInfo(await repo.getById(123123))).toEqual(modUser)
|
|
@ -1,7 +1,6 @@
|
|||
import { afterEach, describe, expect, it, vi } from 'vitest'
|
||||
|
||||
import { IStorageDriver } from '../../../storage/driver.js'
|
||||
import { IReferenceMessagesRepository } from './ref-messages.js'
|
||||
import { IReferenceMessagesRepository, IStorageDriver } from '@mtcute/core'
|
||||
|
||||
export function fakeRefMessagesRepository(): IReferenceMessagesRepository {
|
||||
return {
|
||||
|
@ -27,7 +26,10 @@ export function testRefMessagesRepository(repo: IReferenceMessagesRepository, dr
|
|||
await repo.store(2, 6, 7)
|
||||
await driver.save?.()
|
||||
|
||||
expect(await repo.getByPeer(1)).deep.oneOf([[2, 3], [4, 5]])
|
||||
expect(await repo.getByPeer(1)).deep.oneOf([
|
||||
[2, 3],
|
||||
[4, 5],
|
||||
])
|
||||
expect(await repo.getByPeer(2)).toEqual([6, 7])
|
||||
expect(await repo.getByPeer(3)).toEqual(null)
|
||||
expect(await repo.getByPeer(4)).toEqual(null)
|
||||
|
@ -64,7 +66,11 @@ export function testRefMessagesRepository(repo: IReferenceMessagesRepository, dr
|
|||
await repo.deleteByPeer(1)
|
||||
await driver.save?.()
|
||||
expect(await repo.getByPeer(1)).toEqual(null)
|
||||
expect(await repo.getByPeer(2)).deep.oneOf([[20, 30], [40, 50], [60, 70]])
|
||||
expect(await repo.getByPeer(2)).deep.oneOf([
|
||||
[20, 30],
|
||||
[40, 50],
|
||||
[60, 70],
|
||||
])
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import EventEmitter from 'events'
|
||||
|
||||
import { tl } from '@mtcute/tl'
|
||||
import { ITelegramTransport, TransportState } from '@mtcute/core'
|
||||
import { ICryptoProvider, Logger } from '@mtcute/core/utils.js'
|
||||
import { tl } from '@mtcute/tl'
|
||||
|
||||
export class StubTelegramTransport extends EventEmitter implements ITelegramTransport {
|
||||
constructor(
|
||||
|
|
|
@ -9,6 +9,7 @@ import { readFile, writeFile } from 'fs/promises'
|
|||
import { join } from 'path'
|
||||
import * as readline from 'readline'
|
||||
|
||||
import { hasPresentKey, isPresent } from '@mtcute/core/utils.js'
|
||||
import {
|
||||
generateTlSchemasDifference,
|
||||
mergeTlEntries,
|
||||
|
@ -19,7 +20,6 @@ import {
|
|||
TlFullSchema,
|
||||
writeTlEntryToString,
|
||||
} from '@mtcute/tl-utils'
|
||||
import { hasPresentKey, isPresent } from '@mtcute/core/utils.js'
|
||||
|
||||
import {
|
||||
__dirname,
|
||||
|
|
Loading…
Reference in a new issue