feat: replace browser login with imported Reddit sessions
This commit is contained in:
1 parent
2b0545afcf
commit
c483c7b8be
76 files changed
+2048
-2828
No files matched your search
@@ -1,98 +1,14 @@
|
||||
import { describe, expect, it, vi } from 'vitest';
|
||||
import type { BrowserContext } from 'playwright';
|
||||
import { createMockLogger } from './mockLogger.js';
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import {
|
||||
MatrixRemoteLoginRequiredError,
|
||||
MatrixTokenRefresher,
|
||||
} from '../src/services/chat/matrix/token-refresher.js';
|
||||
import { MatrixBrowserLoginRequiredError } from '../src/services/chat/matrix/token-extractor.js';
|
||||
import type { MatrixCredentials } from '../src/services/chat/matrix/types.js';
|
||||
|
||||
const credentials: MatrixCredentials = {
|
||||
homeserver: 'https://matrix.redditspace.com',
|
||||
accessToken: 'fresh-token',
|
||||
userId: '@t2_bot:reddit.com',
|
||||
capturedAt: 123,
|
||||
};
|
||||
|
||||
function setup(options: { sessionValid?: boolean; loginSucceeds?: boolean } = {}) {
|
||||
const context = {} as BrowserContext;
|
||||
const browser = {
|
||||
getContext: vi.fn(() => context),
|
||||
isSessionValid: vi.fn(async () => options.sessionValid ?? true),
|
||||
login: vi.fn(async () => options.loginSucceeds ?? true),
|
||||
};
|
||||
const extract = vi.fn(async () => credentials);
|
||||
const applyCredentials = vi.fn();
|
||||
const logger = createMockLogger();
|
||||
const refresher = new MatrixTokenRefresher(
|
||||
browser,
|
||||
logger,
|
||||
applyCredentials,
|
||||
extract,
|
||||
);
|
||||
|
||||
return { refresher, browser, context, extract, applyCredentials, logger };
|
||||
}
|
||||
|
||||
describe('MatrixTokenRefresher', () => {
|
||||
it('repairs an expired Reddit browser session before capturing a Matrix token', async () => {
|
||||
const { refresher, browser, context, extract, applyCredentials } = setup({
|
||||
sessionValid: false,
|
||||
loginSucceeds: true,
|
||||
});
|
||||
|
||||
await refresher.refresh();
|
||||
|
||||
expect(browser.login).toHaveBeenCalledOnce();
|
||||
expect(extract).toHaveBeenCalledWith(context, expect.anything());
|
||||
expect(applyCredentials).toHaveBeenCalledWith(credentials);
|
||||
});
|
||||
|
||||
it('fails fast with remote-login guidance when the Reddit session cannot be restored', async () => {
|
||||
const { refresher, browser, extract } = setup({
|
||||
sessionValid: false,
|
||||
loginSucceeds: false,
|
||||
});
|
||||
it('requires a new extension dump instead of opening a login browser', async () => {
|
||||
const refresher = new MatrixTokenRefresher();
|
||||
|
||||
await expect(refresher.refresh()).rejects.toBeInstanceOf(MatrixRemoteLoginRequiredError);
|
||||
await expect(refresher.refresh()).rejects.toThrow(/dashboard.*noVNC/i);
|
||||
expect(browser.login).toHaveBeenCalledTimes(2);
|
||||
expect(extract).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('coalesces concurrent refreshes so only one browser capture runs', async () => {
|
||||
const { refresher, extract, applyCredentials } = setup();
|
||||
let release: ((value: MatrixCredentials) => void) | undefined;
|
||||
extract.mockImplementation(
|
||||
() => new Promise<MatrixCredentials>((resolve) => { release = resolve; }),
|
||||
);
|
||||
|
||||
const first = refresher.refresh();
|
||||
const second = refresher.refresh();
|
||||
await vi.waitFor(() => expect(extract).toHaveBeenCalledOnce());
|
||||
release?.(credentials);
|
||||
await Promise.all([first, second]);
|
||||
|
||||
expect(applyCredentials).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it('repairs and retries when chat redirects to login despite a valid Reddit API session', async () => {
|
||||
const { refresher, browser, context, extract, applyCredentials } = setup({
|
||||
sessionValid: true,
|
||||
loginSucceeds: true,
|
||||
});
|
||||
extract
|
||||
.mockRejectedValueOnce(
|
||||
new MatrixBrowserLoginRequiredError('https://www.reddit.com/login/?dest=/chat/'),
|
||||
)
|
||||
.mockResolvedValueOnce(credentials);
|
||||
|
||||
await refresher.refresh();
|
||||
|
||||
expect(browser.login).toHaveBeenCalledOnce();
|
||||
expect(extract).toHaveBeenCalledTimes(2);
|
||||
expect(extract).toHaveBeenNthCalledWith(2, context, expect.anything());
|
||||
expect(applyCredentials).toHaveBeenCalledWith(credentials);
|
||||
await expect(refresher.refresh()).rejects.toThrow(/session dump.*extension/i);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user