File size: 1,972 Bytes
46252cd
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { decideRestoreTarget, isNearBottom } from './useChatScrollPosition.ts';

test('isNearBottom: exactly at the bottom counts as near', () => {
  assert.equal(isNearBottom(1000, 2000, 1000), true); // 2000-1000-1000 = 0
});

test('isNearBottom: within the 24px tolerance counts as near', () => {
  assert.equal(isNearBottom(980, 2000, 1000), true); // 20px above bottom
});

test('isNearBottom: beyond the tolerance does not count', () => {
  assert.equal(isNearBottom(500, 2000, 1000), false); // 500px above bottom
});

test('isNearBottom: a scrolled-to-top container is not near the bottom', () => {
  assert.equal(isNearBottom(0, 20000, 800), false);
});

test('first render with no saved position: restore to bottom when loaded', () => {
  assert.deepEqual(decideRestoreTarget('A', true, undefined), { restore: 'bottom' });
});

test('first render still loading: no restore', () => {
  assert.deepEqual(decideRestoreTarget('A', false, undefined), { restore: null });
});

test('cold open: loading transition then loaded → restore to bottom', () => {
  assert.deepEqual(decideRestoreTarget('A', false, undefined), { restore: null });
  assert.deepEqual(decideRestoreTarget('A', true, undefined), { restore: 'bottom' });
});

test('returning to a chat with a saved position restores it (never bottom-jumps)', () => {
  // The scroll listener saves the live scrollTop continuously, so a round trip A → B → A finds A's
  // real last position in the map and restores it exactly.
  assert.deepEqual(decideRestoreTarget('A', true, 250), { restore: 'saved' });
});

test('a saved position of 0 is still a saved position (top of thread is a real place)', () => {
  assert.deepEqual(decideRestoreTarget('A', true, 0), { restore: 'saved' });
});

test('deselect chat (next is null): no restore', () => {
  assert.deepEqual(decideRestoreTarget(null, false, undefined), { restore: null });
});