1
+ import { describe , it , expect , vi , beforeEach , afterEach } from 'vitest' ;
2
+ import { getArchivedUrl } from './retrieve.js' ;
3
+ import * as httpModule from '../utils/http.js' ;
4
+ import * as rateLimitModule from '../utils/rate-limit.js' ;
5
+
6
+ vi . mock ( '../utils/http.js' ) ;
7
+ vi . mock ( '../utils/rate-limit.js' ) ;
8
+
9
+ describe ( 'getArchivedUrl' , ( ) => {
10
+ beforeEach ( ( ) => {
11
+ vi . clearAllMocks ( ) ;
12
+ vi . spyOn ( rateLimitModule . waybackRateLimiter , 'waitForSlot' ) . mockResolvedValue ( ) ;
13
+ vi . spyOn ( rateLimitModule . waybackRateLimiter , 'recordRequest' ) . mockImplementation ( ) ;
14
+ } ) ;
15
+
16
+ afterEach ( ( ) => {
17
+ vi . restoreAllMocks ( ) ;
18
+ } ) ;
19
+
20
+ it ( 'should retrieve archived URL successfully' , async ( ) => {
21
+ const mockResponse = new Response ( JSON . stringify ( {
22
+ url : 'https://example.com' ,
23
+ archived_snapshots : {
24
+ closest : {
25
+ status : '200' ,
26
+ available : true ,
27
+ url : 'https://web.archive.org/web/20231225120000/https://example.com' ,
28
+ timestamp : '20231225120000'
29
+ }
30
+ }
31
+ } ) ) ;
32
+
33
+ vi . spyOn ( httpModule , 'fetchWithTimeout' ) . mockResolvedValueOnce ( mockResponse ) ;
34
+ vi . spyOn ( httpModule , 'parseJsonResponse' ) . mockResolvedValueOnce ( {
35
+ url : 'https://example.com' ,
36
+ archived_snapshots : {
37
+ closest : {
38
+ status : '200' ,
39
+ available : true ,
40
+ url : 'https://web.archive.org/web/20231225120000/https://example.com' ,
41
+ timestamp : '20231225120000'
42
+ }
43
+ }
44
+ } ) ;
45
+
46
+ const result = await getArchivedUrl ( { url : 'https://example.com' } ) ;
47
+
48
+ expect ( result . success ) . toBe ( true ) ;
49
+ expect ( result . available ) . toBe ( true ) ;
50
+ expect ( result . archivedUrl ) . toBe ( 'https://web.archive.org/web/20231225120000/https://example.com' ) ;
51
+ expect ( result . timestamp ) . toBe ( '20231225120000' ) ;
52
+ } ) ;
53
+
54
+ it ( 'should handle no snapshots found' , async ( ) => {
55
+ const mockResponse = new Response ( JSON . stringify ( {
56
+ url : 'https://example.com' ,
57
+ archived_snapshots : { }
58
+ } ) ) ;
59
+
60
+ vi . spyOn ( httpModule , 'fetchWithTimeout' ) . mockResolvedValueOnce ( mockResponse ) ;
61
+ vi . spyOn ( httpModule , 'parseJsonResponse' ) . mockResolvedValueOnce ( {
62
+ url : 'https://example.com' ,
63
+ archived_snapshots : { }
64
+ } ) ;
65
+
66
+ const result = await getArchivedUrl ( { url : 'https://example.com' } ) ;
67
+
68
+ expect ( result . success ) . toBe ( false ) ;
69
+ expect ( result . available ) . toBe ( false ) ;
70
+ expect ( result . message ) . toContain ( 'No archived versions found' ) ;
71
+ } ) ;
72
+
73
+ it ( 'should provide direct URL when timestamp is specified' , async ( ) => {
74
+ const mockResponse = new Response ( JSON . stringify ( {
75
+ url : 'https://example.com' ,
76
+ archived_snapshots : { }
77
+ } ) ) ;
78
+
79
+ vi . spyOn ( httpModule , 'fetchWithTimeout' ) . mockResolvedValueOnce ( mockResponse ) ;
80
+ vi . spyOn ( httpModule , 'parseJsonResponse' ) . mockResolvedValueOnce ( {
81
+ url : 'https://example.com' ,
82
+ archived_snapshots : { }
83
+ } ) ;
84
+
85
+ const result = await getArchivedUrl ( {
86
+ url : 'https://example.com' ,
87
+ timestamp : '20231225120000'
88
+ } ) ;
89
+
90
+ expect ( result . success ) . toBe ( true ) ;
91
+ expect ( result . available ) . toBe ( false ) ;
92
+ expect ( result . archivedUrl ) . toBe ( 'https://web.archive.org/web/20231225120000/https://example.com' ) ;
93
+ } ) ;
94
+
95
+ it ( 'should handle HTTP errors' , async ( ) => {
96
+ vi . spyOn ( httpModule , 'fetchWithTimeout' ) . mockRejectedValueOnce (
97
+ new httpModule . HttpError ( 'Not found' , 404 )
98
+ ) ;
99
+
100
+ const result = await getArchivedUrl ( { url : 'https://example.com' } ) ;
101
+
102
+ expect ( result . success ) . toBe ( false ) ;
103
+ expect ( result . message ) . toContain ( 'Failed to retrieve archived URL' ) ;
104
+ } ) ;
105
+
106
+ it ( 'should handle invalid URLs' , async ( ) => {
107
+ const result = await getArchivedUrl ( { url : 'not-a-url' } ) ;
108
+
109
+ expect ( result . success ) . toBe ( false ) ;
110
+ expect ( result . message ) . toContain ( 'Failed to retrieve archived URL' ) ;
111
+ } ) ;
112
+
113
+ it ( 'should handle latest timestamp' , async ( ) => {
114
+ const mockResponse = new Response ( JSON . stringify ( {
115
+ url : 'https://example.com' ,
116
+ archived_snapshots : {
117
+ closest : {
118
+ status : '200' ,
119
+ available : true ,
120
+ url : 'https://web.archive.org/web/20231225120000/https://example.com' ,
121
+ timestamp : '20231225120000'
122
+ }
123
+ }
124
+ } ) ) ;
125
+
126
+ vi . spyOn ( httpModule , 'fetchWithTimeout' ) . mockResolvedValueOnce ( mockResponse ) ;
127
+ vi . spyOn ( httpModule , 'parseJsonResponse' ) . mockResolvedValueOnce ( {
128
+ url : 'https://example.com' ,
129
+ archived_snapshots : {
130
+ closest : {
131
+ status : '200' ,
132
+ available : true ,
133
+ url : 'https://web.archive.org/web/20231225120000/https://example.com' ,
134
+ timestamp : '20231225120000'
135
+ }
136
+ }
137
+ } ) ;
138
+
139
+ const result = await getArchivedUrl ( {
140
+ url : 'https://example.com' ,
141
+ timestamp : 'latest'
142
+ } ) ;
143
+
144
+ expect ( result . success ) . toBe ( true ) ;
145
+ expect ( result . available ) . toBe ( true ) ;
146
+ } ) ;
147
+ } ) ;
0 commit comments