import type { UpdateFilter } from './filters/index.js' import { CallbackQuery, MtArgumentError, PeersIndex } from '@mtcute/core' import { createStub } from '@mtcute/test' import { describe, expect, it } from 'vitest' import { CallbackDataBuilder } from './callback-data-builder.js' describe('CallbackDataBuilder', () => { it('should correctly build data', () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(cdb.build({ foo: 'foo', bar: 'bar' })).toEqual('prefix:foo:bar') }) it('should correctly throw on invalid data when building', () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(() => cdb.build({ foo: 'foo:1', bar: 'bar' })).toThrow(MtArgumentError) }) it('should correctly throw on too long data when building', () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(() => cdb.build({ foo: 'foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo', bar: 'bar', }), ).toThrow(MtArgumentError) }) it('should correctly parse data', () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(cdb.parse('prefix:foo:bar')).toEqual({ foo: 'foo', bar: 'bar' }) }) it('should throw on invalid prefix when parsing', () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(() => cdb.parse('123:foo:bar')).toThrow(MtArgumentError) }) it('should throw on invalid parts count when parsing', () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(() => cdb.parse('prefix:foo:bar:baz')).toThrow(MtArgumentError) }) describe('filter', () => { const createCb = (data: string) => new CallbackQuery( createStub('updateBotCallbackQuery', { data: new TextEncoder().encode(data), }), new PeersIndex(), ) const getFilterMatch = async (filter: UpdateFilter, data: string) => { const cb = createCb(data) const matched = await filter(cb) if (!matched) return null // eslint-disable-next-line return (cb as any).match } it('should create a filter without params', async () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(await getFilterMatch(cdb.filter(), 'prefix:foo:bar')).toEqual({ foo: 'foo', bar: 'bar', }) expect(await getFilterMatch(cdb.filter(), 'prefix:foo:bar:baz')).toEqual(null) }) it('should create a filter with params', async () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(await getFilterMatch(cdb.filter({ foo: 'foo' }), 'prefix:foo:bar')).toEqual({ foo: 'foo', bar: 'bar', }) expect(await getFilterMatch(cdb.filter({ foo: 'foo' }), 'prefix:bar:bar')).toEqual(null) }) it('should create a filter with regex params', async () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect(await getFilterMatch(cdb.filter({ foo: /\d+/ }), 'prefix:123:bar')).toEqual({ foo: '123', bar: 'bar', }) expect(await getFilterMatch(cdb.filter({ foo: /\d+/ }), 'prefix:bar:bar')).toEqual(null) }) it('should create a filter with dynamic params', async () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect( await getFilterMatch( cdb.filter(() => ({ foo: 'foo' })), 'prefix:foo:bar', ), ).toEqual({ foo: 'foo', bar: 'bar', }) expect( await getFilterMatch( cdb.filter(() => ({ foo: 'foo' })), 'prefix:bar:baz', ), ).toEqual(null) }) it('should create a filter with a predicate matcher', async () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') expect( await getFilterMatch( cdb.filter((_, data) => data.foo === 'foo'), 'prefix:foo:bar', ), ).toEqual({ foo: 'foo', bar: 'bar', }) expect( await getFilterMatch( cdb.filter((_, data) => data.foo === 'foo'), 'prefix:bar:baz', ), ).toEqual(null) }) it('should not throw on invalid data', async () => { const cdb = new CallbackDataBuilder('prefix', 'foo', 'bar') await expect(getFilterMatch(cdb.filter(), 'wrong-prefix:foo:bar')).resolves.toEqual(null) await expect(getFilterMatch(cdb.filter(), 'prefix:foo:bar:baz')).resolves.toEqual(null) }) }) })