Passed
Push — master ( e87dc6...829c59 )
by Stefano
02:13
created

IfStatusCodeIsInvalid   B

Complexity

Conditions 4

Size

Total Lines 65
Code Lines 44

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 44
nop 1
dl 0
loc 65
rs 8.824
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
package scan_test
2
3
import (
4
	"net/http"
5
	"testing"
6
	"time"
7
8
	"github.com/stefanoj3/dirstalk/pkg/common/test"
9
	"github.com/stefanoj3/dirstalk/pkg/scan"
10
	"github.com/stefanoj3/dirstalk/pkg/scan/client"
11
	"github.com/stefanoj3/dirstalk/pkg/scan/producer"
12
	"github.com/stretchr/testify/assert"
13
)
14
15
func TestScanningWithEmptyProducerWillProduceNoResults(t *testing.T) {
16
	logger, _ := test.NewLogger()
17
18
	prod := producer.NewDictionaryProducer([]string{}, []string{}, 1)
19
	c := &http.Client{Timeout: time.Microsecond}
20
	sut := scan.NewScanner(
21
		c,
22
		prod,
23
		producer.NewReProducer(prod),
24
		logger,
25
	)
26
27
	results := sut.Scan(test.MustParseUrl(t, "http://localhost/"), 10)
28
29
	for r := range results {
30
		t.Fatalf("No results expected, got %s", r.Target.Path)
31
	}
32
}
33
34
func TestScannerWillLogAnErrorWithInvalidDictionary(t *testing.T) {
35
	logger, loggerBuffer := test.NewLogger()
36
37
	prod := producer.NewDictionaryProducer(
38
		[]string{"\n"},
39
		[]string{"/home"},
40
		1,
41
	)
42
43
	testServer, serverAssertion := test.NewServerWithAssertion(
44
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}),
45
	)
46
	defer testServer.Close()
47
48
	c, err := client.NewClientFromConfig(
49
		1000,
50
		nil,
51
		"",
52
		false,
53
		nil,
54
		nil,
55
		test.MustParseUrl(t, testServer.URL),
56
	)
57
	assert.NoError(t, err)
58
	sut := scan.NewScanner(
59
		c,
60
		prod,
61
		producer.NewReProducer(prod),
62
		logger,
63
	)
64
65
	results := sut.Scan(test.MustParseUrl(t, testServer.URL), 10)
66
67
	for r := range results {
68
		t.Fatalf("No results expected, got %s", r.Target.Path)
69
	}
70
71
	assert.Contains(t, loggerBuffer.String(), "failed to build request")
72
	assert.Contains(t, loggerBuffer.String(), "invalid method")
73
	assert.Equal(t, 0, serverAssertion.Len())
74
}
75
76
func TestScannerWillNotRedirectIfStatusCodeIsInvalid(t *testing.T) {
77
	logger, loggerBuffer := test.NewLogger()
78
79
	prod := producer.NewDictionaryProducer(
80
		[]string{http.MethodGet},
81
		[]string{"/home"},
82
		3,
83
	)
84
85
	testServer, serverAssertion := test.NewServerWithAssertion(
86
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
87
			w.Header().Add("location", "/potato")
88
			if r.URL.Path == "/home" {
89
				w.WriteHeader(http.StatusOK)
90
				return
91
			}
92
93
			w.WriteHeader(http.StatusNotFound)
94
		}),
95
	)
96
	defer testServer.Close()
97
98
	c, err := client.NewClientFromConfig(
99
		1000,
100
		nil,
101
		"",
102
		false,
103
		nil,
104
		nil,
105
		test.MustParseUrl(t, testServer.URL),
106
	)
107
	assert.NoError(t, err)
108
109
	sut := scan.NewScanner(
110
		c,
111
		prod,
112
		producer.NewReProducer(prod),
113
		logger,
114
	)
115
116
	results := make([]scan.Result, 0, 2)
117
	resultsChannel := sut.Scan(test.MustParseUrl(t, testServer.URL), 10)
118
119
	for r := range resultsChannel {
120
		results = append(results, r)
121
	}
122
123
	expectedsResults := []scan.Result{
124
		{
125
			Target:     scan.Target{Path: "/home", Method: http.MethodGet, Depth: 3},
126
			StatusCode: http.StatusOK,
127
			URL:        *test.MustParseUrl(t, testServer.URL+"/home"),
128
		},
129
		{
130
			Target:     scan.Target{Path: "/home/home", Method: http.MethodGet, Depth: 2},
131
			StatusCode: http.StatusNotFound,
132
			URL:        *test.MustParseUrl(t, testServer.URL+"/home/home"),
133
		},
134
	}
135
136
	assert.Equal(t, expectedsResults, results)
137
138
	assert.Contains(t, loggerBuffer.String(), "/home")
139
	assert.Contains(t, loggerBuffer.String(), "/home/home")
140
	assert.Equal(t, 2, serverAssertion.Len())
141
}
142
143
func TestScannerWillChangeMethodForRedirect(t *testing.T) {
144
	logger, loggerBuffer := test.NewLogger()
145
146
	prod := producer.NewDictionaryProducer(
147
		[]string{http.MethodPatch},
148
		[]string{"/home"},
149
		3,
150
	)
151
152
	testServer, serverAssertion := test.NewServerWithAssertion(
153
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
154
			if r.URL.Path == "/home" {
155
				http.Redirect(w, r, "/potato", http.StatusMovedPermanently)
156
				return
157
			}
158
159
			w.WriteHeader(http.StatusNotFound)
160
		}),
161
	)
162
	defer testServer.Close()
163
164
	c, err := client.NewClientFromConfig(
165
		1000,
166
		nil,
167
		"",
168
		false,
169
		nil,
170
		nil,
171
		test.MustParseUrl(t, testServer.URL),
172
	)
173
	assert.NoError(t, err)
174
175
	sut := scan.NewScanner(
176
		c,
177
		prod,
178
		producer.NewReProducer(prod),
179
		logger,
180
	)
181
182
	results := make([]scan.Result, 0, 4)
183
	resultsChannel := sut.Scan(test.MustParseUrl(t, testServer.URL), 1)
184
185
	for r := range resultsChannel {
186
		results = append(results, r)
187
	}
188
189
	expectedResults := []scan.Result{
190
		{
191
			Target:     scan.Target{Path: "/home", Method: http.MethodPatch, Depth: 3},
192
			StatusCode: http.StatusMovedPermanently,
193
			URL:        *test.MustParseUrl(t, testServer.URL+"/home"),
194
		},
195
		{
196
			Target:     scan.Target{Path: "/potato", Method: http.MethodGet, Depth: 2},
197
			StatusCode: http.StatusNotFound,
198
			URL:        *test.MustParseUrl(t, testServer.URL+"/potato"),
199
		},
200
		{
201
			Target:     scan.Target{Path: "/home/home", Method: http.MethodPatch, Depth: 2},
202
			StatusCode: http.StatusNotFound,
203
			URL:        *test.MustParseUrl(t, testServer.URL+"/home/home"),
204
		},
205
	}
206
207
	assert.Equal(t, expectedResults, results)
208
209
	loggerBufferAsString := loggerBuffer.String()
210
	assert.Contains(t, loggerBufferAsString, "/home")
211
	assert.Contains(t, loggerBufferAsString, "/potato")
212
	assert.Contains(t, loggerBufferAsString, "/home/home")
213
	assert.NotContains(t, loggerBufferAsString, "error")
214
	assert.Equal(t, 3, serverAssertion.Len())
215
}
216
217
func TestScannerWhenOutOfDepthWillNotFollowRedirect(t *testing.T) {
218
	logger, loggerBuffer := test.NewLogger()
219
220
	prod := producer.NewDictionaryProducer(
221
		[]string{http.MethodPatch},
222
		[]string{"/home"},
223
		0,
224
	)
225
226
	testServer, serverAssertion := test.NewServerWithAssertion(
227
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
228
			if r.URL.Path == "/home" {
229
				http.Redirect(w, r, "/potato", http.StatusMovedPermanently)
230
				return
231
			}
232
233
			w.WriteHeader(http.StatusNotFound)
234
		}),
235
	)
236
	defer testServer.Close()
237
238
	c, err := client.NewClientFromConfig(
239
		1000,
240
		nil,
241
		"",
242
		false,
243
		nil,
244
		nil,
245
		test.MustParseUrl(t, testServer.URL),
246
	)
247
	assert.NoError(t, err)
248
249
	sut := scan.NewScanner(
250
		c,
251
		prod,
252
		producer.NewReProducer(prod),
253
		logger,
254
	)
255
256
	results := make([]scan.Result, 0, 1)
257
	resultsChannel := sut.Scan(test.MustParseUrl(t, testServer.URL), 1)
258
259
	for r := range resultsChannel {
260
		results = append(results, r)
261
	}
262
263
	expectedResults := []scan.Result{
264
		{
265
			Target:     scan.Target{Path: "/home", Method: http.MethodPatch, Depth: 0},
266
			StatusCode: http.StatusMovedPermanently,
267
			URL:        *test.MustParseUrl(t, testServer.URL+"/home"),
268
		},
269
	}
270
271
	assert.Equal(t, expectedResults, results)
272
273
	loggerBufferAsString := loggerBuffer.String()
274
	assert.Contains(t, loggerBufferAsString, "/home")
275
	assert.Contains(t, loggerBufferAsString, "depth is 0, not following any redirect")
276
	assert.NotContains(t, loggerBufferAsString, "error")
277
	assert.Equal(t, 1, serverAssertion.Len())
278
}
279
280
func TestScannerWillSkipRedirectWhenLocationHostIsDifferent(t *testing.T) {
281
	logger, loggerBuffer := test.NewLogger()
282
283
	prod := producer.NewDictionaryProducer(
284
		[]string{http.MethodPatch},
285
		[]string{"/home"},
286
		3,
287
	)
288
289
	testServer, serverAssertion := test.NewServerWithAssertion(
290
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
291
			if r.URL.Path == "/home" {
292
				http.Redirect(w, r, "http://gibberish/potato", http.StatusMovedPermanently)
293
				return
294
			}
295
296
			w.WriteHeader(http.StatusNotFound)
297
		}),
298
	)
299
	defer testServer.Close()
300
301
	c, err := client.NewClientFromConfig(
302
		1000,
303
		nil,
304
		"",
305
		false,
306
		nil,
307
		nil,
308
		test.MustParseUrl(t, testServer.URL),
309
	)
310
	assert.NoError(t, err)
311
312
	sut := scan.NewScanner(
313
		c,
314
		prod,
315
		producer.NewReProducer(prod),
316
		logger,
317
	)
318
319
	results := make([]scan.Result, 0, 4)
320
	resultsChannel := sut.Scan(test.MustParseUrl(t, testServer.URL), 1)
321
322
	for r := range resultsChannel {
323
		results = append(results, r)
324
	}
325
326
	expectedResults := []scan.Result{
327
		{
328
			Target:     scan.Target{Path: "/home", Method: http.MethodPatch, Depth: 3},
329
			StatusCode: http.StatusMovedPermanently,
330
			URL:        *test.MustParseUrl(t, testServer.URL+"/home"),
331
		},
332
		{
333
			Target:     scan.Target{Path: "/home/home", Method: http.MethodPatch, Depth: 2},
334
			StatusCode: http.StatusNotFound,
335
			URL:        *test.MustParseUrl(t, testServer.URL+"/home/home"),
336
		},
337
	}
338
339
	assert.Equal(t, expectedResults, results)
340
341
	loggerBufferAsString := loggerBuffer.String()
342
	assert.Contains(t, loggerBufferAsString, "/home")
343
	assert.Contains(t, loggerBufferAsString, "/home/home")
344
	assert.Contains(t, loggerBufferAsString, "skipping redirect, pointing to a different host")
345
	assert.NotContains(t, loggerBufferAsString, "error")
346
	assert.Equal(t, 2, serverAssertion.Len())
347
}
348