/ clis / zhihu / follow.test.js
follow.test.js
 1  import { describe, expect, it, vi } from 'vitest';
 2  import { getRegistry } from '@jackwener/opencli/registry';
 3  import './follow.js';
 4  describe('zhihu follow', () => {
 5      it('rejects missing --execute before any browser write path', async () => {
 6          const cmd = getRegistry().get('zhihu/follow');
 7          expect(cmd?.func).toBeTypeOf('function');
 8          const page = { goto: vi.fn(), evaluate: vi.fn() };
 9          await expect(cmd.func(page, { target: 'question:123' })).rejects.toMatchObject({ code: 'INVALID_INPUT' });
10          expect(page.goto).not.toHaveBeenCalled();
11          expect(page.evaluate).not.toHaveBeenCalled();
12      });
13      it('rejects user pages where the primary follow control is not uniquely anchored', async () => {
14          const cmd = getRegistry().get('zhihu/follow');
15          const page = {
16              goto: vi.fn().mockResolvedValue(undefined),
17              evaluate: vi.fn().mockResolvedValue({ state: 'ambiguous_user_follow' }),
18          };
19          await expect(cmd.func(page, { target: 'user:alice', execute: true })).rejects.toMatchObject({
20              code: 'ACTION_NOT_AVAILABLE',
21          });
22      });
23      it('returns already_applied when already following', async () => {
24          const cmd = getRegistry().get('zhihu/follow');
25          const page = {
26              goto: vi.fn().mockResolvedValue(undefined),
27              evaluate: vi.fn().mockResolvedValue({ state: 'already_following' }),
28          };
29          await expect(cmd.func(page, { target: 'question:123', execute: true })).resolves.toEqual([
30              expect.objectContaining({ outcome: 'already_applied', target_type: 'question', target: 'question:123' }),
31          ]);
32      });
33      it('rejects question pages where the question follow control is not uniquely anchored', async () => {
34          const cmd = getRegistry().get('zhihu/follow');
35          const page = {
36              goto: vi.fn().mockResolvedValue(undefined),
37              evaluate: vi.fn().mockResolvedValue({ state: 'ambiguous_question_follow' }),
38          };
39          await expect(cmd.func(page, { target: 'question:123', execute: true })).rejects.toMatchObject({
40              code: 'ACTION_NOT_AVAILABLE',
41          });
42          expect(page.evaluate.mock.calls[0][0]).toContain('QuestionHeader');
43          expect(page.evaluate.mock.calls[0][0]).toContain('new Set(');
44      });
45  });