diff --git a/apps/readest-app/src/__tests__/services/readwise/ReadwiseClient.test.ts b/apps/readest-app/src/__tests__/services/readwise/ReadwiseClient.test.ts index 639c7fd0..801d5f88 100644 --- a/apps/readest-app/src/__tests__/services/readwise/ReadwiseClient.test.ts +++ b/apps/readest-app/src/__tests__/services/readwise/ReadwiseClient.test.ts @@ -1,9 +1,19 @@ import { describe, test, expect, vi, beforeEach, afterEach } from 'vitest'; +import { fetch as tauriFetch } from '@tauri-apps/plugin-http'; import { ReadwiseClient } from '@/services/readwise/ReadwiseClient'; import { READWISE_API_BASE_URL } from '@/services/constants'; +import { isTauriAppPlatform } from '@/services/environment'; import type { ReadwiseSettings } from '@/types/settings'; import type { Book, BookNote } from '@/types/book'; +vi.mock('@tauri-apps/plugin-http', () => ({ + fetch: vi.fn(), +})); + +vi.mock('@/services/environment', () => ({ + isTauriAppPlatform: vi.fn(() => false), +})); + const makeSettings = (overrides: Partial = {}): ReadwiseSettings => ({ enabled: true, accessToken: 'test-token', @@ -37,6 +47,10 @@ describe('ReadwiseClient base URL', () => { beforeEach(() => { fetchMock = vi.fn().mockResolvedValue(new Response(null, { status: 204 })); vi.stubGlobal('fetch', fetchMock); + vi.mocked(tauriFetch) + .mockReset() + .mockResolvedValue(new Response(null, { status: 204 })); + vi.mocked(isTauriAppPlatform).mockReturnValue(false); }); afterEach(() => { @@ -79,4 +93,20 @@ describe('ReadwiseClient base URL', () => { expect(init.method).toBe('POST'); expect((init.headers as Record)['Authorization']).toBe('Token test-token'); }); + + test('validateToken uses the Tauri HTTP transport in the desktop app', async () => { + vi.mocked(isTauriAppPlatform).mockReturnValue(true); + const client = new ReadwiseClient(makeSettings({ baseUrl: 'https://example.com/api/v2' })); + + await client.validateToken(); + + expect(tauriFetch).toHaveBeenCalledWith('https://example.com/api/v2/auth/', { + method: 'GET', + headers: { + Authorization: 'Token test-token', + }, + body: undefined, + }); + expect(fetchMock).not.toHaveBeenCalled(); + }); }); diff --git a/apps/readest-app/src/services/readwise/ReadwiseClient.ts b/apps/readest-app/src/services/readwise/ReadwiseClient.ts index c6e4202e..4a8e8a8f 100644 --- a/apps/readest-app/src/services/readwise/ReadwiseClient.ts +++ b/apps/readest-app/src/services/readwise/ReadwiseClient.ts @@ -1,7 +1,9 @@ import { Book, BookNote, HighlightColor } from '@/types/book'; import { ReadwiseSettings } from '@/types/settings'; import { READWISE_API_BASE_URL } from '@/services/constants'; +import { isTauriAppPlatform } from '@/services/environment'; import { buildAnnotationWebUrl } from '@/utils/deeplink'; +import { fetch as tauriFetch } from '@tauri-apps/plugin-http'; const READEST_TO_READWISE_COLOR: Record = { red: 'pink', @@ -34,7 +36,8 @@ export class ReadwiseClient { options: { method?: 'GET' | 'POST'; body?: string } = {}, ): Promise { const { method = 'GET', body } = options; - return fetch(`${this.baseUrl}${endpoint}`, { + const fetchFn = isTauriAppPlatform() ? tauriFetch : globalThis.fetch; + return fetchFn(`${this.baseUrl}${endpoint}`, { method, headers: { Authorization: `Token ${this.config.accessToken}`,