Passed
Pull Request — master (#31)
by Stefano
02:08
created

pkg/cmd/root_integration_test.go   A

Size/Duplication

Total Lines 204
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 130
dl 0
loc 204
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A cmd_test.TestScanCommand 0 20 2
A cmd_test.TestScanWithRemoteDictionary 0 32 3
A cmd_test.TestVersionCommand 0 13 1
A cmd_test.TestScanWithUserAgentFlag 0 38 3
A cmd_test.TestRootCommand 0 15 1
A cmd_test.executeCommand 0 10 1
A cmd_test.removeTestFile 0 6 2
A cmd_test.TestDictionaryGenerateCommand 0 18 1
A cmd_test.createCommand 0 16 3
1
package cmd_test
2
3
import (
4
	"bytes"
5
	"io/ioutil"
6
	"net/http"
7
	"net/http/httptest"
8
	"os"
9
	"strings"
10
	"sync/atomic"
11
	"testing"
12
13
	"github.com/pkg/errors"
14
	"github.com/sirupsen/logrus"
15
	"github.com/spf13/cobra"
16
	"github.com/stefanoj3/dirstalk/pkg/cmd"
17
	"github.com/stefanoj3/dirstalk/pkg/common/test"
18
	"github.com/stretchr/testify/assert"
19
)
20
21
func TestRootCommand(t *testing.T) {
22
	logger, _ := test.NewLogger()
23
24
	c, err := createCommand(logger)
25
	assert.NoError(t, err)
26
	assert.NotNil(t, c)
27
28
	_, out, err := executeCommand(c)
29
	assert.NoError(t, err)
30
31
	// ensure the summary is printed
32
	assert.Contains(t, out, "dirstalk is a tool that attempts")
33
	assert.Contains(t, out, "Usage")
34
	assert.Contains(t, out, "dictionary.generate")
35
	assert.Contains(t, out, "scan")
36
}
37
38
func TestScanCommand(t *testing.T) {
39
	logger, _ := test.NewLogger()
40
41
	c, err := createCommand(logger)
42
	assert.NoError(t, err)
43
	assert.NotNil(t, c)
44
45
	var calls int32
46
	srv := httptest.NewServer(
47
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
48
			atomic.AddInt32(&calls, 1)
49
			w.WriteHeader(http.StatusNotFound)
50
		}),
51
	)
52
	defer srv.Close()
53
54
	_, _, err = executeCommand(c, "scan", srv.URL, "--dictionary", "testdata/dict.txt")
55
	assert.NoError(t, err)
56
57
	assert.Equal(t, int32(3), calls)
58
}
59
60
func TestScanWithRemoteDictionary(t *testing.T) {
61
	logger, _ := test.NewLogger()
62
63
	c, err := createCommand(logger)
64
	assert.NoError(t, err)
65
	assert.NotNil(t, c)
66
67
	dictionaryServer := httptest.NewServer(
68
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
69
			dict := `home
70
home/index.php
71
blabla
72
`
73
			w.WriteHeader(http.StatusOK)
74
			_, _ = w.Write([]byte(dict))
75
		}),
76
	)
77
	defer dictionaryServer.Close()
78
79
	var calls int32
80
	srv := httptest.NewServer(
81
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
82
			atomic.AddInt32(&calls, 1)
83
			w.WriteHeader(http.StatusNotFound)
84
		}),
85
	)
86
	defer srv.Close()
87
88
	_, _, err = executeCommand(c, "scan", srv.URL, "--dictionary", dictionaryServer.URL)
89
	assert.NoError(t, err)
90
91
	assert.Equal(t, int32(3), calls)
92
}
93
94
func TestScanWithUserAgentFlag(t *testing.T) {
95
	const testUserAgent = "my_test_user_agent"
96
97
	logger, _ := test.NewLogger()
98
99
	c, err := createCommand(logger)
100
	assert.NoError(t, err)
101
	assert.NotNil(t, c)
102
103
	var callsWithMatchingUserAgent int32
104
	var callsWithNonMatchingUserAgent int32
105
106
	srv := httptest.NewServer(
107
		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
108
			if r.Header.Get("User-Agent") == testUserAgent {
109
				atomic.AddInt32(&callsWithMatchingUserAgent, 1)
110
			} else {
111
				atomic.AddInt32(&callsWithNonMatchingUserAgent, 1)
112
			}
113
114
			w.WriteHeader(http.StatusNotFound)
115
		}),
116
	)
117
	defer srv.Close()
118
119
	_, _, err = executeCommand(
120
		c,
121
		"scan",
122
		srv.URL,
123
		"--user-agent",
124
		testUserAgent,
125
		"--dictionary",
126
		"testdata/dict.txt",
127
	)
128
	assert.NoError(t, err)
129
130
	assert.Equal(t, int32(3), callsWithMatchingUserAgent)
131
	assert.Equal(t, int32(0), callsWithNonMatchingUserAgent)
132
}
133
134
func TestDictionaryGenerateCommand(t *testing.T) {
135
	logger, _ := test.NewLogger()
136
137
	c, err := createCommand(logger)
138
	assert.NoError(t, err)
139
	assert.NotNil(t, c)
140
141
	testFilePath := "testdata/" + test.RandStringRunes(10)
142
	defer removeTestFile(testFilePath)
143
	_, _, err = executeCommand(c, "dictionary.generate", ".", "-o", testFilePath)
144
	assert.NoError(t, err)
145
146
	content, err := ioutil.ReadFile(testFilePath)
147
	assert.NoError(t, err)
148
149
	// Ensure the command ran and produced some of the expected output
150
	// it is not in the scope of this test to ensure the correct output
151
	assert.Contains(t, string(content), "root_integration_test.go")
152
}
153
154
func TestVersionCommand(t *testing.T) {
155
	logger, buf := test.NewLogger()
156
157
	c, err := createCommand(logger)
158
	assert.NoError(t, err)
159
	assert.NotNil(t, c)
160
161
	_, _, err = executeCommand(c, "version")
162
	assert.NoError(t, err)
163
164
	// Ensure the command ran and produced some of the expected output
165
	// it is not in the scope of this test to ensure the correct output
166
	assert.Contains(t, buf.String(), "Version: ")
167
}
168
169
func executeCommand(root *cobra.Command, args ...string) (c *cobra.Command, output string, err error) {
170
	buf := new(bytes.Buffer)
171
	root.SetOutput(buf)
172
173
	a := []string{""}
174
	os.Args = append(a, args...)
175
176
	c, err = root.ExecuteC()
177
178
	return c, buf.String(), err
179
}
180
181
func removeTestFile(path string) {
182
	if !strings.Contains(path, "testdata") {
183
		return
184
	}
185
186
	_ = os.Remove(path)
187
}
188
189
func createCommand(logger *logrus.Logger) (*cobra.Command, error) {
190
	dirStalkCmd, err := cmd.NewRootCommand(logger)
191
	if err != nil {
192
		return nil, err
193
	}
194
195
	scanCmd, err := cmd.NewScanCommand(logger)
196
	if err != nil {
197
		return nil, errors.Wrap(err, "failed to create scan command")
198
	}
199
200
	dirStalkCmd.AddCommand(scanCmd)
201
	dirStalkCmd.AddCommand(cmd.NewGenerateDictionaryCommand())
202
	dirStalkCmd.AddCommand(cmd.NewVersionCommand(logger.Out))
203
204
	return dirStalkCmd, nil
205
}
206