1
1
package openai //nolint:testpackage // testing private field
2
2
3
3
import (
4
+ "strings"
5
+
4
6
"github.com/sashabaranov/go-openai/internal/test/checks"
5
7
6
8
"bytes"
@@ -9,6 +11,47 @@ import (
9
11
"testing"
10
12
)
11
13
14
+ type mockFormBuilder struct {
15
+ mockCreateFormFile func (string , * os.File ) error
16
+ mockWriteField func (string , string ) error
17
+ mockClose func () error
18
+ }
19
+
20
+ func (m * mockFormBuilder ) CreateFormFile (fieldname string , file * os.File ) error {
21
+ return m .mockCreateFormFile (fieldname , file )
22
+ }
23
+
24
+ func (m * mockFormBuilder ) WriteField (fieldname , value string ) error {
25
+ return m .mockWriteField (fieldname , value )
26
+ }
27
+
28
+ func (m * mockFormBuilder ) Close () error {
29
+ return m .mockClose ()
30
+ }
31
+
32
+ func (m * mockFormBuilder ) FormDataContentType () string {
33
+ return ""
34
+ }
35
+
36
+ func TestCloseMethod (t * testing.T ) {
37
+ t .Run ("NormalClose" , func (t * testing.T ) {
38
+ body := & bytes.Buffer {}
39
+ builder := NewFormBuilder (body )
40
+ checks .NoError (t , builder .Close (), "正常关闭应成功" )
41
+ })
42
+
43
+ t .Run ("ErrorPropagation" , func (t * testing.T ) {
44
+ errorMock := errors .New ("mock close error" )
45
+ mockBuilder := & mockFormBuilder {
46
+ mockClose : func () error {
47
+ return errorMock
48
+ },
49
+ }
50
+ err := mockBuilder .Close ()
51
+ checks .ErrorIs (t , err , errorMock , "应传递关闭错误" )
52
+ })
53
+ }
54
+
12
55
type failingWriter struct {
13
56
}
14
57
@@ -43,3 +86,95 @@ func TestFormBuilderWithClosedFile(t *testing.T) {
43
86
checks .HasError (t , err , "formbuilder should return error if file is closed" )
44
87
checks .ErrorIs (t , err , os .ErrClosed , "formbuilder should return error if file is closed" )
45
88
}
89
+
90
+ func TestMultiPartFormUploads (t * testing.T ) {
91
+ body := & bytes.Buffer {}
92
+ builder := NewFormBuilder (body )
93
+
94
+ t .Run ("MultipleFiles" , func (t * testing.T ) {
95
+ file1 , _ := os .CreateTemp (t .TempDir (), "*.png" )
96
+ file2 , _ := os .CreateTemp (t .TempDir (), "*.jpg" )
97
+ defer file1 .Close ()
98
+ defer file2 .Close ()
99
+
100
+ checks .NoError (t , builder .CreateFormFile ("image1" , file1 ), "PNG file upload failed" )
101
+ checks .NoError (t , builder .CreateFormFile ("image2" , file2 ), "JPG file upload failed" )
102
+ checks .NoError (t , builder .WriteField ("description" , "test images" ), "Field write failed" )
103
+ })
104
+
105
+ t .Run ("LargeFileConcurrent" , func (t * testing.T ) {
106
+ bigFile , _ := os .CreateTemp (t .TempDir (), "*.bin" )
107
+ defer bigFile .Close ()
108
+ bigFile .Write (make ([]byte , 1024 * 1024 * 5 )) // 5MB test file
109
+
110
+ checks .NoError (t , builder .CreateFormFile ("bigfile" , bigFile ), "Large file upload failed" )
111
+ checks .NoError (t , builder .WriteField ("note" , "large file test" ), "Field write failed" )
112
+ })
113
+
114
+ t .Run ("MixedContentTypes" , func (t * testing.T ) {
115
+ csvFile , _ := os .CreateTemp (t .TempDir (), "*.csv" )
116
+ textFile , _ := os .CreateTemp (t .TempDir (), "*.txt" )
117
+ defer csvFile .Close ()
118
+ defer textFile .Close ()
119
+
120
+ checks .NoError (t , builder .CreateFormFile ("data" , csvFile ), "CSV file upload failed" )
121
+ checks .NoError (t , builder .CreateFormFile ("text" , textFile ), "Text file upload failed" )
122
+ checks .NoError (t , builder .WriteField ("format" , "mixed" ), "Field write failed" )
123
+ })
124
+ }
125
+
126
+ func TestFormDataContentType (t * testing.T ) {
127
+ body := & bytes.Buffer {}
128
+ builder := NewFormBuilder (body )
129
+ contentType := builder .FormDataContentType ()
130
+ if ! strings .HasPrefix (contentType , "multipart/form-data" ) {
131
+ t .Fatalf ("Content-Type格式错误,期望multipart/form-data开头,实际得到:%s" , contentType )
132
+ }
133
+ }
134
+
135
+ func TestCreateFormFileReader (t * testing.T ) {
136
+ body := & bytes.Buffer {}
137
+ builder := NewFormBuilder (body )
138
+
139
+ t .Run ("SpecialCharacters" , func (t * testing.T ) {
140
+ checks .NoError (t , builder .CreateFormFileReader ("field" , strings .NewReader ("content" ), "测 试@file.txt" ), "特殊字符文件名应处理成功" )
141
+ })
142
+
143
+ t .Run ("InvalidReader" , func (t * testing.T ) {
144
+ err := builder .CreateFormFileReader ("field" , & failingReader {}, "valid.txt" )
145
+ checks .HasError (t , err , "无效reader应返回错误" )
146
+ })
147
+ }
148
+
149
+ type failingReader struct {}
150
+
151
+ func (r * failingReader ) Read (p []byte ) (int , error ) {
152
+ return 0 , errors .New ("mock read error" )
153
+ }
154
+
155
+ func TestWriteFieldEdgeCases (t * testing.T ) {
156
+ mockErr := errors .New ("mock write error" )
157
+ t .Run ("EmptyFieldName" , func (t * testing.T ) {
158
+ body := & bytes.Buffer {}
159
+ builder := NewFormBuilder (body )
160
+ err := builder .WriteField ("" , "valid-value" )
161
+ checks .HasError (t , err , "should return error for empty field name" )
162
+ })
163
+
164
+ t .Run ("EmptyValue" , func (t * testing.T ) {
165
+ body := & bytes.Buffer {}
166
+ builder := NewFormBuilder (body )
167
+ err := builder .WriteField ("valid-field" , "" )
168
+ checks .NoError (t , err , "should allow empty value" )
169
+ })
170
+
171
+ t .Run ("MockWriterFailure" , func (t * testing.T ) {
172
+ mockBuilder := & mockFormBuilder {
173
+ mockWriteField : func (_ , _ string ) error {
174
+ return mockErr
175
+ },
176
+ }
177
+ err := mockBuilder .WriteField ("field" , "value" )
178
+ checks .ErrorIs (t , err , mockErr , "should propagate write error" )
179
+ })
180
+ }
0 commit comments