Skip to content

Commit 1298b88

Browse files
fix: fix condition in Dialog.decodeDialogId for monoforum ID (#23)
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
1 parent 2c69306 commit 1298b88

File tree

3 files changed

+132
-1
lines changed

3 files changed

+132
-1
lines changed

eslint.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,8 @@ export default antfu({
2424
'yoda': 'off',
2525
'ts/no-namespace': 'off',
2626
'ts/no-redeclare': 'off',
27+
'test/prefer-lowercase-title': ['error', {
28+
ignore: ['describe'],
29+
}],
2730
},
2831
})

src/internal/dialog.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export const decodeDialogId = (dialogId: number): Option.Option<
2323
if (-1997852516352 <= dialogId && dialogId <= -1000000000001) {
2424
return Option.some({ peer: 'supergroup', id: -(dialogId + 1000000000000) as Dialog.SupergroupId })
2525
}
26-
if (-2002147483649 <= dialogId && dialogId <= -4000000000000) {
26+
if (-4000000000000 <= dialogId && dialogId <= -2002147483649) {
2727
return Option.some({ peer: 'monoforum', id: -(dialogId + 1000000000000) })
2828
}
2929
if (-2002147483648 <= dialogId && dialogId <= -1997852516353) {

test/Dialog.test.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import * as Option from 'effect/Option'
2+
import { describe, expect, it } from 'vitest'
3+
import { Dialog } from '../src/index.ts'
4+
5+
describe('Dialog', () => {
6+
describe('decodeDialogId', () => {
7+
it('should decode IDs at the range edges correctly', () => {
8+
expect(Option.getOrThrow(Dialog.decodeDialogId(-4000000000000))).toEqual({ peer: 'monoforum', id: 3000000000000 })
9+
expect(Option.getOrThrow(Dialog.decodeDialogId(-2002147483649))).toEqual({ peer: 'monoforum', id: 1002147483649 })
10+
expect(Option.getOrThrow(Dialog.decodeDialogId(-2002147483648))).toEqual({ peer: 'secret-chat', id: -2147483648 })
11+
expect(Option.getOrThrow(Dialog.decodeDialogId(-1997852516353))).toEqual({ peer: 'secret-chat', id: 2147483647 })
12+
expect(Option.getOrThrow(Dialog.decodeDialogId(-1997852516352))).toEqual({ peer: 'supergroup', id: 997852516352 })
13+
expect(Option.getOrThrow(Dialog.decodeDialogId(-1000000000001))).toEqual({ peer: 'supergroup', id: 1 })
14+
expect(Option.getOrThrow(Dialog.decodeDialogId(-999999999999))).toEqual({ peer: 'group', id: 999999999999 })
15+
expect(Option.getOrThrow(Dialog.decodeDialogId(-1))).toEqual({ peer: 'group', id: 1 })
16+
expect(Option.getOrThrow(Dialog.decodeDialogId(1))).toEqual({ peer: 'user', id: 1 })
17+
expect(Option.getOrThrow(Dialog.decodeDialogId(0xFFFFFFFFFF))).toEqual({ peer: 'user', id: 1099511627775 })
18+
})
19+
20+
it('should decode valid IDs correctly', () => {
21+
expect(Option.getOrThrow(Dialog.decodeDialogId(500000000000))).toEqual({ peer: 'user', id: 500000000000 })
22+
expect(Option.getOrThrow(Dialog.decodeDialogId(-500000000000))).toEqual({ peer: 'group', id: 500000000000 })
23+
expect(Option.getOrThrow(Dialog.decodeDialogId(-1500000000000))).toEqual({ peer: 'supergroup', id: 500000000000 })
24+
expect(Option.getOrThrow(Dialog.decodeDialogId(-3500000000000))).toEqual({ peer: 'monoforum', id: 2500000000000 })
25+
expect(Option.getOrThrow(Dialog.decodeDialogId(-2000000000000))).toEqual({ peer: 'secret-chat', id: 0 })
26+
})
27+
28+
it('should return None for holes', () => {
29+
expect(Option.isNone(Dialog.decodeDialogId(0))).toBe(true)
30+
expect(Option.isNone(Dialog.decodeDialogId(-1000000000000))).toBe(true)
31+
})
32+
33+
it('should return None for non-safe integers', () => {
34+
expect(Option.isNone(Dialog.decodeDialogId(Number.MAX_SAFE_INTEGER + 1))).toBe(true)
35+
expect(Option.isNone(Dialog.decodeDialogId(Number.MIN_SAFE_INTEGER - 1))).toBe(true)
36+
expect(Option.isNone(Dialog.decodeDialogId(Infinity))).toBe(true)
37+
expect(Option.isNone(Dialog.decodeDialogId(-Infinity))).toBe(true)
38+
expect(Option.isNone(Dialog.decodeDialogId(Number.NaN))).toBe(true)
39+
expect(Option.isNone(Dialog.decodeDialogId(10.2))).toBe(true)
40+
})
41+
})
42+
43+
describe('decodePeerId', () => {
44+
it('should decode IDs at the range edges correctly', () => {
45+
expect(Option.getOrThrow(Dialog.decodePeerId('monoforum', -4000000000000))).toBe(3000000000000)
46+
expect(Option.getOrThrow(Dialog.decodePeerId('monoforum', -2002147483649))).toBe(1002147483649)
47+
expect(Option.getOrThrow(Dialog.decodePeerId('secret-chat', -2002147483648))).toBe(-2147483648)
48+
expect(Option.getOrThrow(Dialog.decodePeerId('secret-chat', -1997852516353))).toBe(2147483647)
49+
expect(Option.getOrThrow(Dialog.decodePeerId('supergroup', -1997852516352))).toBe(997852516352)
50+
expect(Option.getOrThrow(Dialog.decodePeerId('supergroup', -1000000000001))).toBe(1)
51+
expect(Option.getOrThrow(Dialog.decodePeerId('group', -999999999999))).toBe(999999999999)
52+
expect(Option.getOrThrow(Dialog.decodePeerId('group', -1))).toBe(1)
53+
expect(Option.getOrThrow(Dialog.decodePeerId('user', 1))).toBe(1)
54+
expect(Option.getOrThrow(Dialog.decodePeerId('user', 1099511627775))).toBe(0xFFFFFFFFFF)
55+
})
56+
57+
it('should decode valid IDs correctly', () => {
58+
expect(Option.getOrThrow(Dialog.decodePeerId('monoforum', -3500000000000))).toBe(2500000000000)
59+
expect(Option.getOrThrow(Dialog.decodePeerId('secret-chat', -2000000000000))).toBe(0)
60+
expect(Option.getOrThrow(Dialog.decodePeerId('supergroup', -1500000000000))).toBe(500000000000)
61+
expect(Option.getOrThrow(Dialog.decodePeerId('group', -500000000000))).toBe(500000000000)
62+
expect(Option.getOrThrow(Dialog.decodePeerId('user', 500000000000))).toBe(500000000000)
63+
})
64+
65+
it('should return None for mismatched peer type', () => {
66+
expect(Option.isNone(Dialog.decodePeerId('user', -1))).toBe(true)
67+
expect(Option.isNone(Dialog.decodePeerId('group', 1))).toBe(true)
68+
expect(Option.isNone(Dialog.decodePeerId('supergroup', -1))).toBe(true)
69+
expect(Option.isNone(Dialog.decodePeerId('monoforum', -1))).toBe(true)
70+
expect(Option.isNone(Dialog.decodePeerId('secret-chat', -1))).toBe(true)
71+
})
72+
})
73+
74+
describe('encodePeerId', () => {
75+
it('should encode IDs at range edges correctly', () => {
76+
expect(Option.getOrThrow(Dialog.encodePeerId('user', 1))).toBe(1)
77+
expect(Option.getOrThrow(Dialog.encodePeerId('user', 0xFFFFFFFFFF))).toBe(1099511627775)
78+
expect(Option.getOrThrow(Dialog.encodePeerId('group', 1))).toBe(-1)
79+
expect(Option.getOrThrow(Dialog.encodePeerId('group', 999999999999))).toBe(-999999999999)
80+
expect(Option.getOrThrow(Dialog.encodePeerId('supergroup', 1))).toBe(-1000000000001)
81+
expect(Option.getOrThrow(Dialog.encodePeerId('supergroup', 997852516352))).toBe(-1997852516352)
82+
expect(Option.getOrThrow(Dialog.encodePeerId('monoforum', 1002147483649))).toBe(-2002147483649)
83+
expect(Option.getOrThrow(Dialog.encodePeerId('monoforum', 3000000000000))).toBe(-4000000000000)
84+
expect(Option.getOrThrow(Dialog.encodePeerId('secret-chat', -2147483648))).toBe(-2002147483648)
85+
expect(Option.getOrThrow(Dialog.encodePeerId('secret-chat', 2147483647))).toBe(-1997852516353)
86+
})
87+
88+
it('should encode valid IDs correctly', () => {
89+
expect(Option.getOrThrow(Dialog.encodePeerId('user', 500000000000))).toBe(500000000000)
90+
expect(Option.getOrThrow(Dialog.encodePeerId('group', 500000000000))).toBe(-500000000000)
91+
expect(Option.getOrThrow(Dialog.encodePeerId('supergroup', 500000000000))).toBe(-1500000000000)
92+
expect(Option.getOrThrow(Dialog.encodePeerId('monoforum', 2500000000000))).toBe(-3500000000000)
93+
expect(Option.getOrThrow(Dialog.encodePeerId('secret-chat', 0))).toBe(-2000000000000)
94+
})
95+
96+
it('should return None for IDs outside valid range', () => {
97+
expect(Option.isNone(Dialog.encodePeerId('user', 0))).toBe(true)
98+
expect(Option.isNone(Dialog.encodePeerId('user', 1099511627776))).toBe(true)
99+
expect(Option.isNone(Dialog.encodePeerId('group', 0))).toBe(true)
100+
expect(Option.isNone(Dialog.encodePeerId('group', 1000000000000))).toBe(true)
101+
expect(Option.isNone(Dialog.encodePeerId('supergroup', 0))).toBe(true)
102+
expect(Option.isNone(Dialog.encodePeerId('supergroup', 997852516353))).toBe(true)
103+
expect(Option.isNone(Dialog.encodePeerId('monoforum', 1002147483648))).toBe(true)
104+
expect(Option.isNone(Dialog.encodePeerId('monoforum', 3000000000001))).toBe(true)
105+
expect(Option.isNone(Dialog.encodePeerId('secret-chat', -2147483649))).toBe(true)
106+
expect(Option.isNone(Dialog.encodePeerId('secret-chat', 2147483648))).toBe(true)
107+
})
108+
109+
it('should return None for non-safe integers', () => {
110+
expect(Option.isNone(Dialog.encodePeerId('user', Number.MAX_SAFE_INTEGER + 1))).toBe(true)
111+
expect(Option.isNone(Dialog.encodePeerId('user', Infinity))).toBe(true)
112+
expect(Option.isNone(Dialog.encodePeerId('user', Number.NaN))).toBe(true)
113+
expect(Option.isNone(Dialog.encodePeerId('user', 123.456))).toBe(true)
114+
})
115+
116+
it.each([
117+
['user', 9091348234],
118+
['group', 43138491],
119+
['supergroup', 12729042939],
120+
['monoforum', 2987658076159],
121+
['secret-chat', 2140000000],
122+
] as const)('should roundtrip %s ID', (peer, peerId) => {
123+
const encoded = Option.getOrThrow(Dialog.encodePeerId(peer, peerId))
124+
const decoded = Option.getOrThrow(Dialog.decodePeerId(peer as any, encoded))
125+
expect(decoded).toBe(peerId)
126+
})
127+
})
128+
})

0 commit comments

Comments
 (0)