Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
projectdiscovery
GitHub Repository: projectdiscovery/nuclei
Path: blob/dev/pkg/input/formats/swagger/downloader_test.go
2851 views
1
package swagger
2
3
import (
4
"encoding/json"
5
"net/http"
6
"net/http/httptest"
7
"os"
8
"strings"
9
"testing"
10
"time"
11
12
"gopkg.in/yaml.v3"
13
)
14
15
func TestSwaggerDownloader_SupportedExtensions(t *testing.T) {
16
downloader := &SwaggerDownloader{}
17
extensions := downloader.SupportedExtensions()
18
19
expected := []string{".json", ".yaml", ".yml"}
20
if len(extensions) != len(expected) {
21
t.Errorf("Expected %d extensions, got %d", len(expected), len(extensions))
22
}
23
24
for i, ext := range extensions {
25
if ext != expected[i] {
26
t.Errorf("Expected extension %s, got %s", expected[i], ext)
27
}
28
}
29
}
30
31
func TestSwaggerDownloader_Download_JSON_Success(t *testing.T) {
32
// Create a mock Swagger spec (JSON)
33
mockSpec := map[string]interface{}{
34
"swagger": "2.0",
35
"info": map[string]interface{}{
36
"title": "Test API",
37
"version": "1.0.0",
38
},
39
"paths": map[string]interface{}{
40
"/test": map[string]interface{}{
41
"get": map[string]interface{}{
42
"summary": "Test endpoint",
43
},
44
},
45
},
46
}
47
48
// Create mock server
49
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
50
w.Header().Set("Content-Type", "application/json")
51
if err := json.NewEncoder(w).Encode(mockSpec); err != nil {
52
http.Error(w, "failed to encode response", http.StatusInternalServerError)
53
}
54
}))
55
defer server.Close()
56
57
// Create temp directory
58
tmpDir, err := os.MkdirTemp("", "swagger_test")
59
if err != nil {
60
t.Fatalf("Failed to create temp dir: %v", err)
61
}
62
63
defer func() {
64
if err := os.RemoveAll(tmpDir); err != nil {
65
t.Fatalf("Failed to remove temp dir: %v", err)
66
}
67
}()
68
69
// Test download
70
downloader := &SwaggerDownloader{}
71
filePath, err := downloader.Download(server.URL+"/swagger.json", tmpDir, nil)
72
if err != nil {
73
t.Fatalf("Download failed: %v", err)
74
}
75
76
// Verify file exists
77
if !fileExists(filePath) {
78
t.Errorf("Downloaded file does not exist: %s", filePath)
79
}
80
81
// Verify file content
82
content, err := os.ReadFile(filePath)
83
if err != nil {
84
t.Fatalf("Failed to read downloaded file: %v", err)
85
}
86
87
var downloadedSpec map[string]interface{}
88
if err := json.Unmarshal(content, &downloadedSpec); err != nil {
89
t.Fatalf("Failed to parse downloaded JSON: %v", err)
90
}
91
92
// Verify host field was added
93
_, exists := downloadedSpec["host"]
94
if !exists {
95
t.Error("Host field was not added to the spec")
96
}
97
}
98
99
func TestSwaggerDownloader_Download_YAML_Success(t *testing.T) {
100
// Create a mock Swagger spec (YAML)
101
mockSpecYAML := `
102
swagger: "2.0"
103
info:
104
title: "Test API"
105
version: "1.0.0"
106
paths:
107
/test:
108
get:
109
summary: "Test endpoint"
110
`
111
112
// Create mock server
113
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
114
w.Header().Set("Content-Type", "application/yaml")
115
if _, err := w.Write([]byte(mockSpecYAML)); err != nil {
116
http.Error(w, "failed to write response", http.StatusInternalServerError)
117
}
118
}))
119
120
defer server.Close()
121
122
// Create temp directory
123
tmpDir, err := os.MkdirTemp("", "swagger_test")
124
if err != nil {
125
t.Fatalf("Failed to create temp dir: %v", err)
126
}
127
128
defer func() {
129
if err := os.RemoveAll(tmpDir); err != nil {
130
t.Fatalf("Failed to remove temp dir: %v", err)
131
}
132
}()
133
134
// Test download
135
downloader := &SwaggerDownloader{}
136
filePath, err := downloader.Download(server.URL+"/swagger.yaml", tmpDir, nil)
137
if err != nil {
138
t.Fatalf("Download failed: %v", err)
139
}
140
141
// Verify file exists
142
if !fileExists(filePath) {
143
t.Errorf("Downloaded file does not exist: %s", filePath)
144
}
145
146
// Verify file content
147
content, err := os.ReadFile(filePath)
148
if err != nil {
149
t.Fatalf("Failed to read downloaded file: %v", err)
150
}
151
152
var downloadedSpec map[string]interface{}
153
if err := yaml.Unmarshal(content, &downloadedSpec); err != nil {
154
t.Fatalf("Failed to parse downloaded YAML: %v", err)
155
}
156
157
// Verify host field was added
158
_, exists := downloadedSpec["host"]
159
if !exists {
160
t.Error("Host field was not added to the spec")
161
}
162
}
163
164
func TestSwaggerDownloader_Download_UnsupportedExtension(t *testing.T) {
165
tmpDir, err := os.MkdirTemp("", "swagger_test")
166
if err != nil {
167
t.Fatalf("Failed to create temp dir: %v", err)
168
}
169
170
defer func() {
171
if err := os.RemoveAll(tmpDir); err != nil {
172
t.Fatalf("Failed to remove temp dir: %v", err)
173
}
174
}()
175
176
downloader := &SwaggerDownloader{}
177
_, err = downloader.Download("http://example.com/spec.xml", tmpDir, nil)
178
if err == nil {
179
t.Error("Expected error for unsupported extension, but got none")
180
}
181
182
if !strings.Contains(err.Error(), "URL does not appear to be a Swagger spec") {
183
t.Errorf("Unexpected error message: %v", err)
184
}
185
}
186
187
func TestSwaggerDownloader_Download_HTTPError(t *testing.T) {
188
// Create mock server that returns 404
189
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
190
w.WriteHeader(http.StatusNotFound)
191
}))
192
defer server.Close()
193
194
tmpDir, err := os.MkdirTemp("", "swagger_test")
195
if err != nil {
196
t.Fatalf("Failed to create temp dir: %v", err)
197
}
198
199
defer func() {
200
if err := os.RemoveAll(tmpDir); err != nil {
201
t.Fatalf("Failed to remove temp dir: %v", err)
202
}
203
}()
204
205
downloader := &SwaggerDownloader{}
206
_, err = downloader.Download(server.URL+"/swagger.json", tmpDir, nil)
207
if err == nil {
208
t.Error("Expected error for HTTP 404, but got none")
209
}
210
}
211
212
func TestSwaggerDownloader_Download_InvalidJSON(t *testing.T) {
213
// Create mock server that returns invalid JSON
214
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
215
w.Header().Set("Content-Type", "application/json")
216
if _, err := w.Write([]byte("invalid json")); err != nil {
217
http.Error(w, "failed to write response", http.StatusInternalServerError)
218
}
219
}))
220
defer server.Close()
221
222
tmpDir, err := os.MkdirTemp("", "swagger_test")
223
if err != nil {
224
t.Fatalf("Failed to create temp dir: %v", err)
225
}
226
227
defer func() {
228
if err := os.RemoveAll(tmpDir); err != nil {
229
t.Fatalf("Failed to remove temp dir: %v", err)
230
}
231
}()
232
233
downloader := &SwaggerDownloader{}
234
_, err = downloader.Download(server.URL+"/swagger.json", tmpDir, nil)
235
if err == nil {
236
t.Error("Expected error for invalid JSON, but got none")
237
}
238
}
239
240
func TestSwaggerDownloader_Download_InvalidYAML(t *testing.T) {
241
// Create mock server that returns invalid YAML
242
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
243
w.Header().Set("Content-Type", "application/yaml")
244
if _, err := w.Write([]byte("invalid: yaml: content: [")); err != nil {
245
http.Error(w, "failed to write response", http.StatusInternalServerError)
246
}
247
}))
248
defer server.Close()
249
250
tmpDir, err := os.MkdirTemp("", "swagger_test")
251
if err != nil {
252
t.Fatalf("Failed to create temp dir: %v", err)
253
}
254
255
defer func() {
256
if err := os.RemoveAll(tmpDir); err != nil {
257
t.Fatalf("Failed to remove temp dir: %v", err)
258
}
259
}()
260
261
downloader := &SwaggerDownloader{}
262
_, err = downloader.Download(server.URL+"/swagger.yaml", tmpDir, nil)
263
if err == nil {
264
t.Error("Expected error for invalid YAML, but got none")
265
}
266
}
267
268
func TestSwaggerDownloader_Download_Timeout(t *testing.T) {
269
// Create mock server with delay
270
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
271
time.Sleep(35 * time.Second) // Longer than 30 second timeout
272
if err := json.NewEncoder(w).Encode(map[string]interface{}{"test": "data"}); err != nil {
273
http.Error(w, "failed to encode response", http.StatusInternalServerError)
274
}
275
}))
276
defer server.Close()
277
278
tmpDir, err := os.MkdirTemp("", "swagger_test")
279
if err != nil {
280
t.Fatalf("Failed to create temp dir: %v", err)
281
}
282
283
defer func() {
284
if err := os.RemoveAll(tmpDir); err != nil {
285
t.Fatalf("Failed to remove temp dir: %v", err)
286
}
287
}()
288
289
downloader := &SwaggerDownloader{}
290
_, err = downloader.Download(server.URL+"/swagger.json", tmpDir, nil)
291
if err == nil {
292
t.Error("Expected timeout error, but got none")
293
}
294
}
295
296
func TestSwaggerDownloader_Download_WithExistingHost(t *testing.T) {
297
// Create a mock Swagger spec with existing host
298
mockSpec := map[string]interface{}{
299
"swagger": "2.0",
300
"info": map[string]interface{}{
301
"title": "Test API",
302
"version": "1.0.0",
303
},
304
"host": "existing-host.com",
305
"paths": map[string]interface{}{},
306
}
307
308
// Create mock server
309
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
310
w.Header().Set("Content-Type", "application/json")
311
if err := json.NewEncoder(w).Encode(mockSpec); err != nil {
312
http.Error(w, "failed to encode response", http.StatusInternalServerError)
313
}
314
}))
315
defer server.Close()
316
317
tmpDir, err := os.MkdirTemp("", "swagger_test")
318
if err != nil {
319
t.Fatalf("Failed to create temp dir: %v", err)
320
}
321
322
defer func() {
323
if err := os.RemoveAll(tmpDir); err != nil {
324
t.Fatalf("Failed to remove temp dir: %v", err)
325
}
326
}()
327
328
downloader := &SwaggerDownloader{}
329
filePath, err := downloader.Download(server.URL+"/swagger.json", tmpDir, nil)
330
if err != nil {
331
t.Fatalf("Download failed: %v", err)
332
}
333
334
// Verify existing host is preserved
335
content, err := os.ReadFile(filePath)
336
if err != nil {
337
t.Fatalf("Failed to read downloaded file: %v", err)
338
}
339
340
var downloadedSpec map[string]interface{}
341
if err := json.Unmarshal(content, &downloadedSpec); err != nil {
342
t.Fatalf("Failed to parse downloaded JSON: %v", err)
343
}
344
345
host, exists := downloadedSpec["host"]
346
if !exists {
347
t.Error("Host field was removed from the spec")
348
}
349
350
if hostStr, ok := host.(string); !ok || hostStr != "existing-host.com" {
351
t.Errorf("Expected host 'existing-host.com', got '%v'", host)
352
}
353
}
354
355
// Helper function to check if file exists
356
func fileExists(filename string) bool {
357
_, err := os.Stat(filename)
358
return !os.IsNotExist(err)
359
}
360
361