1
- import { describe , expect , it } from 'vitest'
2
- import { createAnnotatedFileUrl , isImageFile } from './code-interpreter'
1
+ import { afterEach , beforeEach , describe , expect , it } from 'vitest'
2
+ import {
3
+ createAnnotatedFileUrl ,
4
+ isImageFile ,
5
+ replaceSandboxUrls ,
6
+ } from './code-interpreter'
3
7
import type { AnnotatedFile } from './code-interpreter'
4
8
9
+ const originalLocation = global . location
10
+ beforeEach ( ( ) => {
11
+ Object . defineProperty ( global , 'location' , {
12
+ value : { origin : 'http://localhost:3000' } ,
13
+ writable : true ,
14
+ } )
15
+ } )
16
+
17
+ afterEach ( ( ) => {
18
+ Object . defineProperty ( global , 'location' , {
19
+ value : originalLocation ,
20
+ writable : true ,
21
+ } )
22
+ } )
23
+
5
24
describe ( 'isImageFile' , ( ) => {
6
25
it ( 'returns true for supported image extensions' , ( ) => {
7
26
expect ( isImageFile ( 'photo.jpg' ) ) . toBe ( true )
@@ -28,15 +47,143 @@ describe('createAnnotatedFileUrl', () => {
28
47
filename : 'test.png' ,
29
48
}
30
49
31
- it ( 'returns absolute URL with correct params (browser)' , ( ) => {
32
- Object . defineProperty ( globalThis , 'location' , {
33
- value : { origin : 'https://example.com' } ,
34
- writable : true ,
35
- } )
36
-
50
+ it ( 'returns absolute URL with correct params including filename (browser)' , ( ) => {
37
51
const url = createAnnotatedFileUrl ( file )
38
52
expect ( url ) . toBe (
39
- 'https://example.com/api/container-file?containerId=c1&fileId=f1' ,
53
+ 'http://localhost:3000/api/container-file?containerId=c1&fileId=f1&filename=test.png' ,
54
+ )
55
+ } )
56
+
57
+ it ( 'handles filenames with special characters' , ( ) => {
58
+ const fileWithSpecialChars : AnnotatedFile = {
59
+ type : 'container_file_citation' ,
60
+ container_id : 'c2' ,
61
+ file_id : 'f2' ,
62
+ filename : 'my file with spaces.py' ,
63
+ }
64
+ const url = createAnnotatedFileUrl ( fileWithSpecialChars )
65
+ expect ( url ) . toBe (
66
+ 'http://localhost:3000/api/container-file?containerId=c2&fileId=f2&filename=my+file+with+spaces.py' ,
40
67
)
41
68
} )
69
+
70
+ it ( 'handles filenames with special URL characters' , ( ) => {
71
+ const fileWithUrlChars : AnnotatedFile = {
72
+ type : 'container_file_citation' ,
73
+ container_id : 'c3' ,
74
+ file_id : 'f3' ,
75
+ filename : 'file&with=special?chars.txt' ,
76
+ }
77
+ const url = createAnnotatedFileUrl ( fileWithUrlChars )
78
+ expect ( url ) . toBe (
79
+ 'http://localhost:3000/api/container-file?containerId=c3&fileId=f3&filename=file%26with%3Dspecial%3Fchars.txt' ,
80
+ )
81
+ } )
82
+ } )
83
+
84
+ describe ( 'replaceSandboxUrls' , ( ) => {
85
+ const mockAnnotations : Array < AnnotatedFile > = [
86
+ {
87
+ type : 'container_file_citation' ,
88
+ container_id : 'container-123' ,
89
+ file_id : 'file-456' ,
90
+ filename : 'example.py' ,
91
+ } ,
92
+ {
93
+ type : 'container_file_citation' ,
94
+ container_id : 'container-789' ,
95
+ file_id : 'file-101' ,
96
+ filename : 'data.csv' ,
97
+ } ,
98
+ {
99
+ type : 'other_type' ,
100
+ container_id : 'container-999' ,
101
+ file_id : 'file-999' ,
102
+ filename : 'ignored.txt' ,
103
+ } ,
104
+ ]
105
+
106
+ it ( 'should return original content when no file annotations are provided' , ( ) => {
107
+ const content = 'Check out sandbox:/mnt/data/example.py for details'
108
+ const result = replaceSandboxUrls ( content , [ ] )
109
+ expect ( result ) . toBe ( content )
110
+ } )
111
+
112
+ it ( 'should replace sandbox URLs with container-file URLs' , ( ) => {
113
+ const content = 'Check out sandbox:/mnt/data/example.py for details'
114
+ const result = replaceSandboxUrls ( content , mockAnnotations )
115
+
116
+ const expectedUrl = createAnnotatedFileUrl ( mockAnnotations [ 0 ] )
117
+ expect ( result ) . toBe ( `Check out ${ expectedUrl } for details` )
118
+ } )
119
+
120
+ it ( 'should handle multiple sandbox URLs in the same content' , ( ) => {
121
+ const content =
122
+ 'Files: sandbox:/mnt/data/example.py and sandbox:/mnt/data/data.csv'
123
+ const result = replaceSandboxUrls ( content , mockAnnotations )
124
+
125
+ const expectedUrl1 = createAnnotatedFileUrl ( mockAnnotations [ 0 ] )
126
+ const expectedUrl2 = createAnnotatedFileUrl ( mockAnnotations [ 1 ] )
127
+ expect ( result ) . toBe ( `Files: ${ expectedUrl1 } and ${ expectedUrl2 } ` )
128
+ } )
129
+
130
+ it ( 'should preserve sandbox URLs that do not have matching annotations' , ( ) => {
131
+ const content = 'Check out sandbox:/mnt/data/unknown.py'
132
+ const result = replaceSandboxUrls ( content , mockAnnotations )
133
+ expect ( result ) . toBe ( content )
134
+ } )
135
+
136
+ it ( 'should handle mixed content with some matching and some non-matching URLs' , ( ) => {
137
+ const content =
138
+ 'Files: sandbox:/mnt/data/example.py and sandbox:/mnt/data/unknown.py'
139
+ const result = replaceSandboxUrls ( content , mockAnnotations )
140
+
141
+ const expectedUrl = createAnnotatedFileUrl ( mockAnnotations [ 0 ] )
142
+ expect ( result ) . toBe (
143
+ `Files: ${ expectedUrl } and sandbox:/mnt/data/unknown.py` ,
144
+ )
145
+ } )
146
+
147
+ it ( 'should ignore annotations that are not container_file_citation type' , ( ) => {
148
+ const content = 'Check out sandbox:/mnt/data/ignored.txt'
149
+ const result = replaceSandboxUrls ( content , mockAnnotations )
150
+ expect ( result ) . toBe ( content )
151
+ } )
152
+
153
+ it ( 'should handle URLs with different formats (parentheses, brackets)' , ( ) => {
154
+ const content =
155
+ 'See (sandbox:/mnt/data/example.py) and [sandbox:/mnt/data/data.csv]'
156
+ const result = replaceSandboxUrls ( content , mockAnnotations )
157
+
158
+ const expectedUrl1 = createAnnotatedFileUrl ( mockAnnotations [ 0 ] )
159
+ const expectedUrl2 = createAnnotatedFileUrl ( mockAnnotations [ 1 ] )
160
+ expect ( result ) . toBe ( `See (${ expectedUrl1 } ) and [${ expectedUrl2 } ]` )
161
+ } )
162
+
163
+ it ( 'should handle URLs with whitespace after them' , ( ) => {
164
+ const content =
165
+ 'Check sandbox:/mnt/data/example.py and sandbox:/mnt/data/data.csv '
166
+ const result = replaceSandboxUrls ( content , mockAnnotations )
167
+
168
+ const expectedUrl1 = createAnnotatedFileUrl ( mockAnnotations [ 0 ] )
169
+ const expectedUrl2 = createAnnotatedFileUrl ( mockAnnotations [ 1 ] )
170
+ expect ( result ) . toBe ( `Check ${ expectedUrl1 } and ${ expectedUrl2 } ` )
171
+ } )
172
+
173
+ it ( 'should handle empty content' , ( ) => {
174
+ const result = replaceSandboxUrls ( '' , mockAnnotations )
175
+ expect ( result ) . toBe ( '' )
176
+ } )
177
+
178
+ it ( 'should handle content with no sandbox URLs' , ( ) => {
179
+ const content = 'This is just regular text with no URLs'
180
+ const result = replaceSandboxUrls ( content , mockAnnotations )
181
+ expect ( result ) . toBe ( content )
182
+ } )
183
+
184
+ it ( 'should handle malformed sandbox URLs gracefully' , ( ) => {
185
+ const content = 'Check sandbox:/mnt/data/ and sandbox:/invalid'
186
+ const result = replaceSandboxUrls ( content , mockAnnotations )
187
+ expect ( result ) . toBe ( content )
188
+ } )
42
189
} )
0 commit comments