文件预览

cookie.test.mjs

查看 WeRead Import 技能包中的文件内容。

文件内容

tests/cookie.test.mjs

import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { buildCookieHeader, CDP_CONNECT_OPTIONS, cookieMatchesHost, extractCookieFromBrowserWithConnector, normalizeBrowserCookieError } from '../src/cookie.mjs';

describe('cookieMatchesHost', () => {
  it('matches host-only and parent-domain cookies for weread.qq.com', () => {
    assert.equal(cookieMatchesHost({ domain: 'weread.qq.com' }), true);
    assert.equal(cookieMatchesHost({ domain: '.weread.qq.com' }), true);
    assert.equal(cookieMatchesHost({ domain: '.qq.com' }), true);
    assert.equal(cookieMatchesHost({ domain: '.example.com' }), false);
  });
});

describe('buildCookieHeader', () => {
  it('builds a cookie header from all cookies applicable to weread.qq.com', () => {
    const header = buildCookieHeader([
      { name: 'wr_skey', value: 'a', domain: '.weread.qq.com' },
      { name: 'wr_gid', value: 'b', domain: 'weread.qq.com' },
      { name: '_clck', value: 'c', domain: '.qq.com' },
      { name: 'other', value: 'd', domain: '.example.com' },
    ]);
    assert.equal(header, 'wr_skey=a; wr_gid=b; _clck=c');
  });
});

describe('extractCookieFromBrowserWithConnector', () => {
  it('disconnects a CDP browser after extracting cookies without closing the browser process', async () => {
    const calls = [];
    const browser = {
      contexts() {
        calls.push('contexts');
        return [{
          async cookies(...urls) {
            calls.push(['cookies', ...urls]);
            return [
              { name: 'wr_gid', value: 'v', domain: 'weread.qq.com' },
              { name: 'wxuin', value: 'skip', domain: '.qq.com' },
            ];
          },
        }];
      },
      async close() {
        calls.push('browser.close');
      },
    };

    const header = await extractCookieFromBrowserWithConnector('http://127.0.0.1:9222', async (cdpUrl, options) => {
      calls.push(`connect:${cdpUrl}`);
      calls.push(['connectOptions', options]);
      return browser;
    });

    assert.equal(header, 'wr_gid=v; wxuin=skip');
    assert.deepEqual(calls, [
      'connect:http://127.0.0.1:9222',
      ['connectOptions', CDP_CONNECT_OPTIONS],
      'contexts',
      [
        'cookies',
        'https://weread.qq.com/',
        'https://weread.qq.com/api/user/notebook',
        'https://weread.qq.com/web/book/bookmarklist?bookId=1',
        'https://weread.qq.com/web/review/list?bookId=1&listType=4&syncKey=0&mine=1',
      ],
      'browser.close',
    ]);
  });

  it('preserves the primary error when browser cleanup also fails', async () => {
    const browser = {
      async close() {
        throw new Error('cleanup failed');
      },
      contexts() {
        return [];
      },
    };

    await assert.rejects(
      extractCookieFromBrowserWithConnector('http://127.0.0.1:9222', async () => browser),
      /无可用浏览器上下文/,
    );
  });
});

describe('normalizeBrowserCookieError', () => {
  it('explains the first-login requirement in isolated browser mode', () => {
    const error = normalizeBrowserCookieError(new Error('浏览器中未找到 weread.qq.com 的 cookie,请先在该浏览器中登录微信读书'), { profileSyncMode: 'isolated', cookieFrom: 'browser-managed' });
    assert.match(error.message, /隔离浏览器中尚未登录微信读书/);
  });

  it('preserves the original error outside isolated mode', () => {
    const original = new Error('浏览器中未找到 weread.qq.com 的 cookie,请先在该浏览器中登录微信读书');
    const error = normalizeBrowserCookieError(original, { profileSyncMode: 'legacy', cookieFrom: 'browser-managed' });
    assert.equal(error, original);
  });

  it('preserves the original error in browser-live mode', () => {
    const original = new Error('浏览器中未找到 weread.qq.com 的 cookie,请先在该浏览器中登录微信读书');
    const error = normalizeBrowserCookieError(original, { profileSyncMode: 'isolated', cookieFrom: 'browser-live' });
    assert.equal(error, original);
  });
});