@debriefer/sources 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -0
- package/dist/__tests__/archives/chronicling-america.test.d.ts +8 -0
- package/dist/__tests__/archives/chronicling-america.test.d.ts.map +1 -0
- package/dist/__tests__/archives/chronicling-america.test.js +151 -0
- package/dist/__tests__/archives/chronicling-america.test.js.map +1 -0
- package/dist/__tests__/archives/europeana.test.d.ts +8 -0
- package/dist/__tests__/archives/europeana.test.d.ts.map +1 -0
- package/dist/__tests__/archives/europeana.test.js +200 -0
- package/dist/__tests__/archives/europeana.test.js.map +1 -0
- package/dist/__tests__/archives/internet-archive.test.d.ts +8 -0
- package/dist/__tests__/archives/internet-archive.test.d.ts.map +1 -0
- package/dist/__tests__/archives/internet-archive.test.js +189 -0
- package/dist/__tests__/archives/internet-archive.test.js.map +1 -0
- package/dist/__tests__/archives/trove.test.d.ts +8 -0
- package/dist/__tests__/archives/trove.test.d.ts.map +1 -0
- package/dist/__tests__/archives/trove.test.js +202 -0
- package/dist/__tests__/archives/trove.test.js.map +1 -0
- package/dist/__tests__/books/google-books.test.d.ts +8 -0
- package/dist/__tests__/books/google-books.test.d.ts.map +1 -0
- package/dist/__tests__/books/google-books.test.js +221 -0
- package/dist/__tests__/books/google-books.test.js.map +1 -0
- package/dist/__tests__/books/open-library.test.d.ts +8 -0
- package/dist/__tests__/books/open-library.test.d.ts.map +1 -0
- package/dist/__tests__/books/open-library.test.js +159 -0
- package/dist/__tests__/books/open-library.test.js.map +1 -0
- package/dist/__tests__/news/guardian.test.d.ts +9 -0
- package/dist/__tests__/news/guardian.test.d.ts.map +1 -0
- package/dist/__tests__/news/guardian.test.js +224 -0
- package/dist/__tests__/news/guardian.test.js.map +1 -0
- package/dist/__tests__/news/nytimes.test.d.ts +9 -0
- package/dist/__tests__/news/nytimes.test.d.ts.map +1 -0
- package/dist/__tests__/news/nytimes.test.js +271 -0
- package/dist/__tests__/news/nytimes.test.js.map +1 -0
- package/dist/__tests__/news/site-search-source.test.d.ts +9 -0
- package/dist/__tests__/news/site-search-source.test.d.ts.map +1 -0
- package/dist/__tests__/news/site-search-source.test.js +342 -0
- package/dist/__tests__/news/site-search-source.test.js.map +1 -0
- package/dist/__tests__/obituary/find-a-grave.test.d.ts +8 -0
- package/dist/__tests__/obituary/find-a-grave.test.d.ts.map +1 -0
- package/dist/__tests__/obituary/find-a-grave.test.js +238 -0
- package/dist/__tests__/obituary/find-a-grave.test.js.map +1 -0
- package/dist/__tests__/shared/duckduckgo-search.test.d.ts +9 -0
- package/dist/__tests__/shared/duckduckgo-search.test.d.ts.map +1 -0
- package/dist/__tests__/shared/duckduckgo-search.test.js +218 -0
- package/dist/__tests__/shared/duckduckgo-search.test.js.map +1 -0
- package/dist/__tests__/shared/fetch-page.test.d.ts +9 -0
- package/dist/__tests__/shared/fetch-page.test.d.ts.map +1 -0
- package/dist/__tests__/shared/fetch-page.test.js +281 -0
- package/dist/__tests__/shared/fetch-page.test.js.map +1 -0
- package/dist/__tests__/shared/html-utils.test.d.ts +2 -0
- package/dist/__tests__/shared/html-utils.test.d.ts.map +1 -0
- package/dist/__tests__/shared/html-utils.test.js +169 -0
- package/dist/__tests__/shared/html-utils.test.js.map +1 -0
- package/dist/__tests__/shared/readability-extract.test.d.ts +2 -0
- package/dist/__tests__/shared/readability-extract.test.d.ts.map +1 -0
- package/dist/__tests__/shared/readability-extract.test.js +107 -0
- package/dist/__tests__/shared/readability-extract.test.js.map +1 -0
- package/dist/__tests__/shared/sanitize-text.test.d.ts +2 -0
- package/dist/__tests__/shared/sanitize-text.test.d.ts.map +1 -0
- package/dist/__tests__/shared/sanitize-text.test.js +77 -0
- package/dist/__tests__/shared/sanitize-text.test.js.map +1 -0
- package/dist/__tests__/shared/search-utils.test.d.ts +2 -0
- package/dist/__tests__/shared/search-utils.test.d.ts.map +1 -0
- package/dist/__tests__/shared/search-utils.test.js +26 -0
- package/dist/__tests__/shared/search-utils.test.js.map +1 -0
- package/dist/__tests__/structured/wikidata.test.d.ts +9 -0
- package/dist/__tests__/structured/wikidata.test.d.ts.map +1 -0
- package/dist/__tests__/structured/wikidata.test.js +509 -0
- package/dist/__tests__/structured/wikidata.test.js.map +1 -0
- package/dist/__tests__/structured/wikipedia.test.d.ts +9 -0
- package/dist/__tests__/structured/wikipedia.test.d.ts.map +1 -0
- package/dist/__tests__/structured/wikipedia.test.js +643 -0
- package/dist/__tests__/structured/wikipedia.test.js.map +1 -0
- package/dist/__tests__/web-search/base.test.d.ts +9 -0
- package/dist/__tests__/web-search/base.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/base.test.js +622 -0
- package/dist/__tests__/web-search/base.test.js.map +1 -0
- package/dist/__tests__/web-search/bing.test.d.ts +10 -0
- package/dist/__tests__/web-search/bing.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/bing.test.js +277 -0
- package/dist/__tests__/web-search/bing.test.js.map +1 -0
- package/dist/__tests__/web-search/brave.test.d.ts +10 -0
- package/dist/__tests__/web-search/brave.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/brave.test.js +264 -0
- package/dist/__tests__/web-search/brave.test.js.map +1 -0
- package/dist/__tests__/web-search/duckduckgo.test.d.ts +10 -0
- package/dist/__tests__/web-search/duckduckgo.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/duckduckgo.test.js +107 -0
- package/dist/__tests__/web-search/duckduckgo.test.js.map +1 -0
- package/dist/__tests__/web-search/google.test.d.ts +9 -0
- package/dist/__tests__/web-search/google.test.d.ts.map +1 -0
- package/dist/__tests__/web-search/google.test.js +189 -0
- package/dist/__tests__/web-search/google.test.js.map +1 -0
- package/dist/archives/chronicling-america.d.ts +33 -0
- package/dist/archives/chronicling-america.d.ts.map +1 -0
- package/dist/archives/chronicling-america.js +85 -0
- package/dist/archives/chronicling-america.js.map +1 -0
- package/dist/archives/europeana.d.ts +37 -0
- package/dist/archives/europeana.d.ts.map +1 -0
- package/dist/archives/europeana.js +92 -0
- package/dist/archives/europeana.js.map +1 -0
- package/dist/archives/internet-archive.d.ts +32 -0
- package/dist/archives/internet-archive.d.ts.map +1 -0
- package/dist/archives/internet-archive.js +90 -0
- package/dist/archives/internet-archive.js.map +1 -0
- package/dist/archives/trove.d.ts +37 -0
- package/dist/archives/trove.d.ts.map +1 -0
- package/dist/archives/trove.js +97 -0
- package/dist/archives/trove.js.map +1 -0
- package/dist/books/google-books.d.ts +48 -0
- package/dist/books/google-books.d.ts.map +1 -0
- package/dist/books/google-books.js +111 -0
- package/dist/books/google-books.js.map +1 -0
- package/dist/books/open-library.d.ts +44 -0
- package/dist/books/open-library.d.ts.map +1 -0
- package/dist/books/open-library.js +103 -0
- package/dist/books/open-library.js.map +1 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/news/guardian.d.ts +51 -0
- package/dist/news/guardian.d.ts.map +1 -0
- package/dist/news/guardian.js +131 -0
- package/dist/news/guardian.js.map +1 -0
- package/dist/news/nytimes.d.ts +27 -0
- package/dist/news/nytimes.d.ts.map +1 -0
- package/dist/news/nytimes.js +104 -0
- package/dist/news/nytimes.js.map +1 -0
- package/dist/news/site-search-source.d.ts +89 -0
- package/dist/news/site-search-source.d.ts.map +1 -0
- package/dist/news/site-search-source.js +182 -0
- package/dist/news/site-search-source.js.map +1 -0
- package/dist/news/sources.d.ts +52 -0
- package/dist/news/sources.d.ts.map +1 -0
- package/dist/news/sources.js +276 -0
- package/dist/news/sources.js.map +1 -0
- package/dist/obituary/find-a-grave.d.ts +43 -0
- package/dist/obituary/find-a-grave.d.ts.map +1 -0
- package/dist/obituary/find-a-grave.js +173 -0
- package/dist/obituary/find-a-grave.js.map +1 -0
- package/dist/shared/duckduckgo-search.d.ts +86 -0
- package/dist/shared/duckduckgo-search.d.ts.map +1 -0
- package/dist/shared/duckduckgo-search.js +218 -0
- package/dist/shared/duckduckgo-search.js.map +1 -0
- package/dist/shared/fetch-page.d.ts +50 -0
- package/dist/shared/fetch-page.d.ts.map +1 -0
- package/dist/shared/fetch-page.js +212 -0
- package/dist/shared/fetch-page.js.map +1 -0
- package/dist/shared/html-utils.d.ts +99 -0
- package/dist/shared/html-utils.d.ts.map +1 -0
- package/dist/shared/html-utils.js +246 -0
- package/dist/shared/html-utils.js.map +1 -0
- package/dist/shared/readability-extract.d.ts +33 -0
- package/dist/shared/readability-extract.d.ts.map +1 -0
- package/dist/shared/readability-extract.js +45 -0
- package/dist/shared/readability-extract.js.map +1 -0
- package/dist/shared/sanitize-text.d.ts +24 -0
- package/dist/shared/sanitize-text.d.ts.map +1 -0
- package/dist/shared/sanitize-text.js +49 -0
- package/dist/shared/sanitize-text.js.map +1 -0
- package/dist/shared/search-utils.d.ts +18 -0
- package/dist/shared/search-utils.d.ts.map +1 -0
- package/dist/shared/search-utils.js +20 -0
- package/dist/shared/search-utils.js.map +1 -0
- package/dist/structured/wikidata.d.ts +128 -0
- package/dist/structured/wikidata.d.ts.map +1 -0
- package/dist/structured/wikidata.js +361 -0
- package/dist/structured/wikidata.js.map +1 -0
- package/dist/structured/wikipedia.d.ts +184 -0
- package/dist/structured/wikipedia.d.ts.map +1 -0
- package/dist/structured/wikipedia.js +275 -0
- package/dist/structured/wikipedia.js.map +1 -0
- package/dist/web-search/base.d.ts +128 -0
- package/dist/web-search/base.d.ts.map +1 -0
- package/dist/web-search/base.js +251 -0
- package/dist/web-search/base.js.map +1 -0
- package/dist/web-search/bing.d.ts +21 -0
- package/dist/web-search/bing.d.ts.map +1 -0
- package/dist/web-search/bing.js +53 -0
- package/dist/web-search/bing.js.map +1 -0
- package/dist/web-search/brave.d.ts +21 -0
- package/dist/web-search/brave.d.ts.map +1 -0
- package/dist/web-search/brave.js +56 -0
- package/dist/web-search/brave.js.map +1 -0
- package/dist/web-search/duckduckgo.d.ts +15 -0
- package/dist/web-search/duckduckgo.d.ts.map +1 -0
- package/dist/web-search/duckduckgo.js +21 -0
- package/dist/web-search/duckduckgo.js.map +1 -0
- package/dist/web-search/google.d.ts +24 -0
- package/dist/web-search/google.d.ts.map +1 -0
- package/dist/web-search/google.js +48 -0
- package/dist/web-search/google.js.map +1 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @debriefer/sources
|
|
2
|
+
|
|
3
|
+
Built-in research source integrations for [@debriefer/core](https://github.com/chenders/debriefer): Wikipedia, Wikidata, web search, news, archives, and more.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @debriefer/core @debriefer/sources
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Source Categories
|
|
12
|
+
|
|
13
|
+
| Category | Count | Cost | Sources |
|
|
14
|
+
| --------------- | ----- | ----------- | --------------------------------------------------------------------------------------------------------- |
|
|
15
|
+
| Structured data | 2 | Free | Wikipedia, Wikidata |
|
|
16
|
+
| News | 22 | Mostly free | AP, BBC, Reuters, NPR, Guardian, NYT, Washington Post, LA Times, Rolling Stone, Britannica, TCM, and more |
|
|
17
|
+
| Web search | 4 | Mixed | DuckDuckGo (free), Google, Bing, Brave (API key required) |
|
|
18
|
+
| Books | 2 | Mixed | Open Library (free), Google Books (API key required) |
|
|
19
|
+
| Archives | 4 | Free | Chronicling America, Trove, Europeana, Internet Archive |
|
|
20
|
+
| Obituary | 2 | Free | Find a Grave, Legacy.com |
|
|
21
|
+
|
|
22
|
+
News sources marked "mostly free" use DuckDuckGo site-search under the hood and require no API keys. The Guardian and New York Times sources use their official APIs and require keys.
|
|
23
|
+
|
|
24
|
+
## Example
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { ResearchOrchestrator, NoopSynthesizer } from "@debriefer/core"
|
|
28
|
+
import { wikipedia, apNews, guardian, wikidata } from "@debriefer/sources"
|
|
29
|
+
|
|
30
|
+
const orchestrator = new ResearchOrchestrator(
|
|
31
|
+
[
|
|
32
|
+
{ phase: 1, name: "Structured", sources: [wikidata(), wikipedia()] },
|
|
33
|
+
{ phase: 2, name: "News", sources: [apNews(), guardian()] },
|
|
34
|
+
],
|
|
35
|
+
new NoopSynthesizer()
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
const result = await orchestrator.debrief({ id: "ada-lovelace", name: "Ada Lovelace" })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Shared Utilities
|
|
42
|
+
|
|
43
|
+
`@debriefer/sources` exports utilities useful when building custom sources:
|
|
44
|
+
|
|
45
|
+
| Utility | Description |
|
|
46
|
+
| ----------------------- | ---------------------------------------------------------- |
|
|
47
|
+
| `fetchPage` | HTTP fetch with timeout, User-Agent, and redirect handling |
|
|
48
|
+
| `extractArticleContent` | Mozilla Readability extraction from raw HTML |
|
|
49
|
+
| `sanitizeSourceText` | Clean extracted text for use as research findings |
|
|
50
|
+
| `htmlToText` | Convert HTML to plain text |
|
|
51
|
+
| `searchDuckDuckGo` | Run a DuckDuckGo search and return result URLs |
|
|
52
|
+
|
|
53
|
+
## Documentation
|
|
54
|
+
|
|
55
|
+
See the [monorepo README](https://github.com/chenders/debriefer) for full documentation including orchestrator configuration, reliability scoring, and adding custom sources.
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chronicling-america.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/archives/chronicling-america.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for ChroniclingAmericaSource.
|
|
3
|
+
*
|
|
4
|
+
* Mocks the global fetch API. sanitizeSourceText is mocked to isolate
|
|
5
|
+
* source-specific logic from shared sanitization behavior.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
8
|
+
import { ReliabilityTier } from "@debriefer/core";
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Mocks — must be declared before importing the module under test
|
|
11
|
+
// ============================================================================
|
|
12
|
+
const mockSanitize = vi.fn();
|
|
13
|
+
vi.mock("../../shared/sanitize-text.js", () => ({
|
|
14
|
+
sanitizeSourceText: (...args) => mockSanitize(...args),
|
|
15
|
+
}));
|
|
16
|
+
import { ChroniclingAmericaSource, chroniclingAmerica } from "../../archives/chronicling-america.js";
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Helpers
|
|
19
|
+
// ============================================================================
|
|
20
|
+
/** Standard test subject. */
|
|
21
|
+
const subject = { id: 1, name: "John Wayne" };
|
|
22
|
+
/** Standard abort signal for tests. */
|
|
23
|
+
const signal = AbortSignal.timeout(5000);
|
|
24
|
+
/** Build a mock LOC API response. */
|
|
25
|
+
function makeLocResponse(results) {
|
|
26
|
+
return {
|
|
27
|
+
ok: true,
|
|
28
|
+
status: 200,
|
|
29
|
+
statusText: "OK",
|
|
30
|
+
json: async () => ({ results }),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Lifecycle
|
|
35
|
+
// ============================================================================
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
mockSanitize.mockReset();
|
|
38
|
+
vi.stubGlobal("fetch", vi.fn());
|
|
39
|
+
});
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
vi.restoreAllMocks();
|
|
42
|
+
vi.unstubAllGlobals();
|
|
43
|
+
});
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Tests
|
|
46
|
+
// ============================================================================
|
|
47
|
+
describe("ChroniclingAmericaSource", () => {
|
|
48
|
+
// ==========================================================================
|
|
49
|
+
// Metadata
|
|
50
|
+
// ==========================================================================
|
|
51
|
+
describe("metadata", () => {
|
|
52
|
+
it("has correct name, type, tier, domain, isFree, and cost", () => {
|
|
53
|
+
const source = new ChroniclingAmericaSource();
|
|
54
|
+
expect(source.name).toBe("Chronicling America");
|
|
55
|
+
expect(source.type).toBe("chronicling-america");
|
|
56
|
+
expect(source.reliabilityTier).toBe(ReliabilityTier.ARCHIVAL);
|
|
57
|
+
expect(source.domain).toBe("www.loc.gov");
|
|
58
|
+
expect(source.isFree).toBe(true);
|
|
59
|
+
expect(source.estimatedCostPerQuery).toBe(0);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
// ==========================================================================
|
|
63
|
+
// API call format
|
|
64
|
+
// ==========================================================================
|
|
65
|
+
describe("API call format", () => {
|
|
66
|
+
it("builds correct URL with all expected query params", async () => {
|
|
67
|
+
const mockFetch = vi.fn().mockResolvedValue(makeLocResponse([]));
|
|
68
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
69
|
+
const source = new ChroniclingAmericaSource();
|
|
70
|
+
await source.lookup(subject, signal);
|
|
71
|
+
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
72
|
+
const [callUrl, callOptions] = mockFetch.mock.calls[0];
|
|
73
|
+
const parsed = new URL(callUrl);
|
|
74
|
+
expect(parsed.origin + parsed.pathname).toBe("https://www.loc.gov/collections/chronicling-america/");
|
|
75
|
+
expect(parsed.searchParams.get("q")).toBe('"John Wayne"');
|
|
76
|
+
expect(parsed.searchParams.get("fo")).toBe("json");
|
|
77
|
+
expect(parsed.searchParams.get("c")).toBe("5");
|
|
78
|
+
expect(callOptions.signal).toBeDefined();
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
// ==========================================================================
|
|
82
|
+
// Response parsing
|
|
83
|
+
// ==========================================================================
|
|
84
|
+
describe("response parsing", () => {
|
|
85
|
+
it("combines title and description text from results", async () => {
|
|
86
|
+
const mockFetch = vi.fn().mockResolvedValue(makeLocResponse([
|
|
87
|
+
{
|
|
88
|
+
title: "John Wayne obituary",
|
|
89
|
+
description: ["Famous actor known for westerns"],
|
|
90
|
+
url: "https://www.loc.gov/item/123",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
title: "Wayne interview 1960",
|
|
94
|
+
description: ["Rare interview from the archives"],
|
|
95
|
+
},
|
|
96
|
+
]));
|
|
97
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
98
|
+
mockSanitize.mockReturnValue("sanitized text about John Wayne");
|
|
99
|
+
const source = new ChroniclingAmericaSource();
|
|
100
|
+
const result = await source.lookup(subject, signal);
|
|
101
|
+
expect(result).not.toBeNull();
|
|
102
|
+
expect(result.text).toBe("sanitized text about John Wayne");
|
|
103
|
+
expect(result.confidence).toBe(-1);
|
|
104
|
+
expect(result.costUsd).toBe(0);
|
|
105
|
+
expect(result.url).toBe("https://www.loc.gov/item/123");
|
|
106
|
+
expect(result.publication).toBe("Chronicling America (Library of Congress)");
|
|
107
|
+
expect(result.metadata?.title).toBe("John Wayne obituary");
|
|
108
|
+
// sanitize was called with combined text
|
|
109
|
+
expect(mockSanitize).toHaveBeenCalledTimes(1);
|
|
110
|
+
const sanitizeArg = mockSanitize.mock.calls[0][0];
|
|
111
|
+
expect(sanitizeArg).toContain("John Wayne obituary");
|
|
112
|
+
expect(sanitizeArg).toContain("Famous actor known for westerns");
|
|
113
|
+
expect(sanitizeArg).toContain("Wayne interview 1960");
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
// ==========================================================================
|
|
117
|
+
// Empty results
|
|
118
|
+
// ==========================================================================
|
|
119
|
+
describe("empty results", () => {
|
|
120
|
+
it("returns null when API returns no results", async () => {
|
|
121
|
+
const mockFetch = vi.fn().mockResolvedValue(makeLocResponse([]));
|
|
122
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
123
|
+
const source = new ChroniclingAmericaSource();
|
|
124
|
+
const result = await source.lookup(subject, signal);
|
|
125
|
+
expect(result).toBeNull();
|
|
126
|
+
});
|
|
127
|
+
it("returns null on HTTP error (caught by base class)", async () => {
|
|
128
|
+
const mockFetch = vi.fn().mockResolvedValue({
|
|
129
|
+
ok: false,
|
|
130
|
+
status: 500,
|
|
131
|
+
statusText: "Internal Server Error",
|
|
132
|
+
json: async () => ({}),
|
|
133
|
+
});
|
|
134
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
135
|
+
const source = new ChroniclingAmericaSource();
|
|
136
|
+
const result = await source.lookup(subject, signal);
|
|
137
|
+
expect(result).toBeNull();
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
// ==========================================================================
|
|
141
|
+
// Factory
|
|
142
|
+
// ==========================================================================
|
|
143
|
+
describe("factory", () => {
|
|
144
|
+
it("returns a ChroniclingAmericaSource instance", () => {
|
|
145
|
+
const source = chroniclingAmerica();
|
|
146
|
+
expect(source).toBeInstanceOf(ChroniclingAmericaSource);
|
|
147
|
+
expect(source.name).toBe("Chronicling America");
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
//# sourceMappingURL=chronicling-america.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chronicling-america.test.js","sourceRoot":"","sources":["../../../src/__tests__/archives/chronicling-america.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AACxE,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAA;AAEjD,+EAA+E;AAC/E,kEAAkE;AAClE,+EAA+E;AAE/E,MAAM,YAAY,GAAG,EAAE,CAAC,EAAE,EAAE,CAAA;AAE5B,EAAE,CAAC,IAAI,CAAC,+BAA+B,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9C,kBAAkB,EAAE,CAAC,GAAG,IAAe,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC;CAClE,CAAC,CAAC,CAAA;AAEH,OAAO,EAAE,wBAAwB,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAA;AAEpG,+EAA+E;AAC/E,UAAU;AACV,+EAA+E;AAE/E,6BAA6B;AAC7B,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAA;AAE7C,uCAAuC;AACvC,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;AAExC,qCAAqC;AACrC,SAAS,eAAe,CACtB,OAKE;IAEF,OAAO;QACL,EAAE,EAAE,IAAI;QACR,MAAM,EAAE,GAAG;QACX,UAAU,EAAE,IAAI;QAChB,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;KAChC,CAAA;AACH,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,UAAU,CAAC,GAAG,EAAE;IACd,YAAY,CAAC,SAAS,EAAE,CAAA;IACxB,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,CAAA;AACjC,CAAC,CAAC,CAAA;AAEF,SAAS,CAAC,GAAG,EAAE;IACb,EAAE,CAAC,eAAe,EAAE,CAAA;IACpB,EAAE,CAAC,gBAAgB,EAAE,CAAA;AACvB,CAAC,CAAC,CAAA;AAEF,+EAA+E;AAC/E,QAAQ;AACR,+EAA+E;AAE/E,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,6EAA6E;IAC7E,WAAW;IACX,6EAA6E;IAE7E,QAAQ,CAAC,UAAU,EAAE,GAAG,EAAE;QACxB,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;YAChE,MAAM,MAAM,GAAG,IAAI,wBAAwB,EAAE,CAAA;YAE7C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;YAC/C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;YAC/C,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAA;YAC7D,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;YACzC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAChC,MAAM,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAC9C,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,6EAA6E;IAC7E,kBAAkB;IAClB,6EAA6E;IAE7E,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAA;YAChE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YAEjC,MAAM,MAAM,GAAG,IAAI,wBAAwB,EAAE,CAAA;YAC7C,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAEpC,MAAM,CAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;YAE1C,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAsC,CAAA;YAC3F,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAA;YAE/B,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC,IAAI,CAC1C,sDAAsD,CACvD,CAAA;YACD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;YACzD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YAClD,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC9C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;QAC1C,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,6EAA6E;IAC7E,mBAAmB;IACnB,6EAA6E;IAE7E,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;QAChC,EAAE,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;YAChE,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CACzC,eAAe,CAAC;gBACd;oBACE,KAAK,EAAE,qBAAqB;oBAC5B,WAAW,EAAE,CAAC,iCAAiC,CAAC;oBAChD,GAAG,EAAE,8BAA8B;iBACpC;gBACD;oBACE,KAAK,EAAE,sBAAsB;oBAC7B,WAAW,EAAE,CAAC,kCAAkC,CAAC;iBAClD;aACF,CAAC,CACH,CAAA;YACD,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YACjC,YAAY,CAAC,eAAe,CAAC,iCAAiC,CAAC,CAAA;YAE/D,MAAM,MAAM,GAAG,IAAI,wBAAwB,EAAE,CAAA;YAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAEnD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAA;YAC7B,MAAM,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAA;YAC5D,MAAM,CAAC,MAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;YACnC,MAAM,CAAC,MAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC/B,MAAM,CAAC,MAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,8BAA8B,CAAC,CAAA;YACxD,MAAM,CAAC,MAAO,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAA;YAC7E,MAAM,CAAC,MAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;YAE3D,yCAAyC;YACzC,MAAM,CAAC,YAAY,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAA;YAC7C,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAW,CAAA;YAC3D,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAA;YACpD,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,iCAAiC,CAAC,CAAA;YAChE,MAAM,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAA;QACvD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,6EAA6E;IAC7E,gBAAgB;IAChB,6EAA6E;IAE7E,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;YACxD,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAA;YAChE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YAEjC,MAAM,MAAM,GAAG,IAAI,wBAAwB,EAAE,CAAA;YAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAEnD,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC3B,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;YACjE,MAAM,SAAS,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC;gBAC1C,EAAE,EAAE,KAAK;gBACT,MAAM,EAAE,GAAG;gBACX,UAAU,EAAE,uBAAuB;gBACnC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;aACvB,CAAC,CAAA;YACF,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,SAAS,CAAC,CAAA;YAEjC,MAAM,MAAM,GAAG,IAAI,wBAAwB,EAAE,CAAA;YAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;YAEnD,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC3B,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,6EAA6E;IAC7E,UAAU;IACV,6EAA6E;IAE7E,QAAQ,CAAC,SAAS,EAAE,GAAG,EAAE;QACvB,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;YACrD,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAA;YACnC,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAA;YACvD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;QACjD,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"europeana.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/archives/europeana.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for EuropeanaSource.
|
|
3
|
+
*
|
|
4
|
+
* Mocks the global fetch API. sanitizeSourceText is mocked to isolate
|
|
5
|
+
* source-specific logic from shared sanitization behavior.
|
|
6
|
+
*/
|
|
7
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
8
|
+
import { ReliabilityTier } from "@debriefer/core";
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Mocks — must be declared before importing the module under test
|
|
11
|
+
// ============================================================================
|
|
12
|
+
const mockSanitize = vi.fn();
|
|
13
|
+
vi.mock("../../shared/sanitize-text.js", () => ({
|
|
14
|
+
sanitizeSourceText: (...args) => mockSanitize(...args),
|
|
15
|
+
}));
|
|
16
|
+
import { EuropeanaSource, europeana } from "../../archives/europeana.js";
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// Helpers
|
|
19
|
+
// ============================================================================
|
|
20
|
+
/** Standard test subject. */
|
|
21
|
+
const subject = { id: 1, name: "Leonardo da Vinci" };
|
|
22
|
+
/** Standard abort signal for tests. */
|
|
23
|
+
const signal = AbortSignal.timeout(5000);
|
|
24
|
+
/** Build a mock Europeana API response. */
|
|
25
|
+
function makeEuropeanaResponse(items) {
|
|
26
|
+
return {
|
|
27
|
+
ok: true,
|
|
28
|
+
status: 200,
|
|
29
|
+
statusText: "OK",
|
|
30
|
+
json: async () => ({ items }),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// ============================================================================
|
|
34
|
+
// Lifecycle
|
|
35
|
+
// ============================================================================
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
mockSanitize.mockReset();
|
|
38
|
+
vi.stubGlobal("fetch", vi.fn());
|
|
39
|
+
});
|
|
40
|
+
afterEach(() => {
|
|
41
|
+
vi.restoreAllMocks();
|
|
42
|
+
vi.unstubAllGlobals();
|
|
43
|
+
});
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// Tests
|
|
46
|
+
// ============================================================================
|
|
47
|
+
describe("EuropeanaSource", () => {
|
|
48
|
+
// ==========================================================================
|
|
49
|
+
// Metadata
|
|
50
|
+
// ==========================================================================
|
|
51
|
+
describe("metadata", () => {
|
|
52
|
+
it("has correct name, type, tier, domain, isFree, and cost", () => {
|
|
53
|
+
const source = new EuropeanaSource({ apiKey: "test-key" });
|
|
54
|
+
expect(source.name).toBe("Europeana");
|
|
55
|
+
expect(source.type).toBe("europeana");
|
|
56
|
+
expect(source.reliabilityTier).toBe(ReliabilityTier.ARCHIVAL);
|
|
57
|
+
expect(source.domain).toBe("api.europeana.eu");
|
|
58
|
+
expect(source.isFree).toBe(true);
|
|
59
|
+
expect(source.estimatedCostPerQuery).toBe(0);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
// ==========================================================================
|
|
63
|
+
// isAvailable
|
|
64
|
+
// ==========================================================================
|
|
65
|
+
describe("isAvailable", () => {
|
|
66
|
+
it("returns true when apiKey is provided", () => {
|
|
67
|
+
const source = new EuropeanaSource({ apiKey: "test-key" });
|
|
68
|
+
expect(source.isAvailable()).toBe(true);
|
|
69
|
+
});
|
|
70
|
+
it("returns false when no apiKey is provided and env var is unset", () => {
|
|
71
|
+
const original = process.env.EUROPEANA_API_KEY;
|
|
72
|
+
delete process.env.EUROPEANA_API_KEY;
|
|
73
|
+
const source = new EuropeanaSource();
|
|
74
|
+
expect(source.isAvailable()).toBe(false);
|
|
75
|
+
if (original !== undefined) {
|
|
76
|
+
process.env.EUROPEANA_API_KEY = original;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
// ==========================================================================
|
|
81
|
+
// API call format
|
|
82
|
+
// ==========================================================================
|
|
83
|
+
describe("API call format", () => {
|
|
84
|
+
it("builds correct URL with API key and query params", async () => {
|
|
85
|
+
const mockFetch = vi.fn().mockResolvedValue(makeEuropeanaResponse([]));
|
|
86
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
87
|
+
const source = new EuropeanaSource({ apiKey: "my-europeana-key" });
|
|
88
|
+
await source.lookup(subject, signal);
|
|
89
|
+
expect(mockFetch).toHaveBeenCalledTimes(1);
|
|
90
|
+
const [callUrl, callOptions] = mockFetch.mock.calls[0];
|
|
91
|
+
const parsed = new URL(callUrl);
|
|
92
|
+
expect(parsed.origin + parsed.pathname).toBe("https://api.europeana.eu/record/v2/search.json");
|
|
93
|
+
expect(parsed.searchParams.get("wskey")).toBe("my-europeana-key");
|
|
94
|
+
expect(parsed.searchParams.get("query")).toContain('"Leonardo da Vinci"');
|
|
95
|
+
expect(parsed.searchParams.get("query")).toContain("biography");
|
|
96
|
+
expect(parsed.searchParams.get("rows")).toBe("5");
|
|
97
|
+
expect(callOptions.signal).toBeDefined();
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
// ==========================================================================
|
|
101
|
+
// Response parsing
|
|
102
|
+
// ==========================================================================
|
|
103
|
+
describe("response parsing", () => {
|
|
104
|
+
it("combines title and description from items", async () => {
|
|
105
|
+
const mockFetch = vi.fn().mockResolvedValue(makeEuropeanaResponse([
|
|
106
|
+
{
|
|
107
|
+
title: ["Portrait of Leonardo da Vinci"],
|
|
108
|
+
dcDescription: ["A Renaissance polymath and painter."],
|
|
109
|
+
edmIsShownAt: ["https://www.example.eu/item/123"],
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
title: ["Da Vinci Codex"],
|
|
113
|
+
dcDescription: ["Collection of scientific writings."],
|
|
114
|
+
},
|
|
115
|
+
]));
|
|
116
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
117
|
+
mockSanitize.mockReturnValue("sanitized text about Leonardo da Vinci");
|
|
118
|
+
const source = new EuropeanaSource({ apiKey: "test-key" });
|
|
119
|
+
const result = await source.lookup(subject, signal);
|
|
120
|
+
expect(result).not.toBeNull();
|
|
121
|
+
expect(result.text).toBe("sanitized text about Leonardo da Vinci");
|
|
122
|
+
expect(result.confidence).toBe(-1);
|
|
123
|
+
expect(result.costUsd).toBe(0);
|
|
124
|
+
expect(result.url).toBe("https://www.example.eu/item/123");
|
|
125
|
+
expect(result.publication).toBe("Europeana");
|
|
126
|
+
expect(result.metadata?.title).toBe("Portrait of Leonardo da Vinci");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
// ==========================================================================
|
|
130
|
+
// URL fallback
|
|
131
|
+
// ==========================================================================
|
|
132
|
+
describe("URL fallback", () => {
|
|
133
|
+
it("falls back to guid when edmIsShownAt is missing", async () => {
|
|
134
|
+
const mockFetch = vi.fn().mockResolvedValue(makeEuropeanaResponse([
|
|
135
|
+
{
|
|
136
|
+
title: ["Da Vinci sketch"],
|
|
137
|
+
dcDescription: ["Anatomical study drawing."],
|
|
138
|
+
guid: "https://www.europeana.eu/portal/record/456.html",
|
|
139
|
+
},
|
|
140
|
+
]));
|
|
141
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
142
|
+
mockSanitize.mockReturnValue("sanitized text");
|
|
143
|
+
const source = new EuropeanaSource({ apiKey: "test-key" });
|
|
144
|
+
const result = await source.lookup(subject, signal);
|
|
145
|
+
expect(result).not.toBeNull();
|
|
146
|
+
expect(result.url).toBe("https://www.europeana.eu/portal/record/456.html");
|
|
147
|
+
});
|
|
148
|
+
it("uses edmIsShownAt over guid when both present", async () => {
|
|
149
|
+
const mockFetch = vi.fn().mockResolvedValue(makeEuropeanaResponse([
|
|
150
|
+
{
|
|
151
|
+
title: ["Da Vinci painting"],
|
|
152
|
+
dcDescription: ["The Mona Lisa."],
|
|
153
|
+
edmIsShownAt: ["https://museum.example.eu/mona-lisa"],
|
|
154
|
+
guid: "https://www.europeana.eu/portal/record/789.html",
|
|
155
|
+
},
|
|
156
|
+
]));
|
|
157
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
158
|
+
mockSanitize.mockReturnValue("sanitized text");
|
|
159
|
+
const source = new EuropeanaSource({ apiKey: "test-key" });
|
|
160
|
+
const result = await source.lookup(subject, signal);
|
|
161
|
+
expect(result).not.toBeNull();
|
|
162
|
+
expect(result.url).toBe("https://museum.example.eu/mona-lisa");
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
// ==========================================================================
|
|
166
|
+
// Empty / error results
|
|
167
|
+
// ==========================================================================
|
|
168
|
+
describe("empty results", () => {
|
|
169
|
+
it("returns null when no items in response", async () => {
|
|
170
|
+
const mockFetch = vi.fn().mockResolvedValue(makeEuropeanaResponse([]));
|
|
171
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
172
|
+
const source = new EuropeanaSource({ apiKey: "test-key" });
|
|
173
|
+
const result = await source.lookup(subject, signal);
|
|
174
|
+
expect(result).toBeNull();
|
|
175
|
+
});
|
|
176
|
+
it("returns null on HTTP error (caught by base class)", async () => {
|
|
177
|
+
const mockFetch = vi.fn().mockResolvedValue({
|
|
178
|
+
ok: false,
|
|
179
|
+
status: 429,
|
|
180
|
+
statusText: "Too Many Requests",
|
|
181
|
+
json: async () => ({}),
|
|
182
|
+
});
|
|
183
|
+
vi.stubGlobal("fetch", mockFetch);
|
|
184
|
+
const source = new EuropeanaSource({ apiKey: "test-key" });
|
|
185
|
+
const result = await source.lookup(subject, signal);
|
|
186
|
+
expect(result).toBeNull();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
// ==========================================================================
|
|
190
|
+
// Factory
|
|
191
|
+
// ==========================================================================
|
|
192
|
+
describe("factory", () => {
|
|
193
|
+
it("returns a EuropeanaSource instance", () => {
|
|
194
|
+
const source = europeana({ apiKey: "test-key" });
|
|
195
|
+
expect(source).toBeInstanceOf(EuropeanaSource);
|
|
196
|
+
expect(source.name).toBe("Europeana");
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
//# sourceMappingURL=europeana.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"europeana.test.js","sourceRoot":"","sources":["../../../src/__tests__/archives/europeana.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"internet-archive.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/archives/internet-archive.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|