1package slack
2
3import (
4	"fmt"
5	"net/http"
6	"net/url"
7	"reflect"
8	"strings"
9	"testing"
10)
11
12func TestSlash_ServeHTTP(t *testing.T) {
13	once.Do(startServer)
14	serverURL := fmt.Sprintf("http://%s/slash", serverAddr)
15
16	tests := []struct {
17		body           url.Values
18		wantParams     SlashCommand
19		wantStatusCode int
20	}{
21		{
22			body: url.Values{
23				"command":         []string{"/command"},
24				"team_domain":     []string{"team"},
25				"enterprise_id":   []string{"E0001"},
26				"enterprise_name": []string{"Globular%20Construct%20Inc"},
27				"channel_id":      []string{"C1234ABCD"},
28				"text":            []string{"text"},
29				"team_id":         []string{"T1234ABCD"},
30				"user_id":         []string{"U1234ABCD"},
31				"user_name":       []string{"username"},
32				"response_url":    []string{"https://hooks.slack.com/commands/XXXXXXXX/00000000000/YYYYYYYYYYYYYY"},
33				"token":           []string{"valid"},
34				"channel_name":    []string{"channel"},
35				"trigger_id":      []string{"0000000000.1111111111.222222222222aaaaaaaaaaaaaa"},
36			},
37			wantParams: SlashCommand{
38				Command:        "/command",
39				TeamDomain:     "team",
40				EnterpriseID:   "E0001",
41				EnterpriseName: "Globular%20Construct%20Inc",
42				ChannelID:      "C1234ABCD",
43				Text:           "text",
44				TeamID:         "T1234ABCD",
45				UserID:         "U1234ABCD",
46				UserName:       "username",
47				ResponseURL:    "https://hooks.slack.com/commands/XXXXXXXX/00000000000/YYYYYYYYYYYYYY",
48				Token:          "valid",
49				ChannelName:    "channel",
50				TriggerID:      "0000000000.1111111111.222222222222aaaaaaaaaaaaaa",
51			},
52			wantStatusCode: http.StatusOK,
53		},
54		{
55			body: url.Values{
56				"token": []string{"invalid"},
57			},
58			wantParams: SlashCommand{
59				Token: "invalid",
60			},
61			wantStatusCode: http.StatusUnauthorized,
62		},
63	}
64
65	var slashCommand SlashCommand
66	client := &http.Client{}
67	http.HandleFunc("/slash", func(w http.ResponseWriter, r *http.Request) {
68		var err error
69		slashCommand, err = SlashCommandParse(r)
70		if err != nil {
71			w.WriteHeader(http.StatusInternalServerError)
72		}
73		acceptableTokens := []string{"valid", "valid2"}
74		if !slashCommand.ValidateToken(acceptableTokens...) {
75			w.WriteHeader(http.StatusUnauthorized)
76		}
77	})
78
79	for i, test := range tests {
80		req, err := http.NewRequest(http.MethodPost, serverURL, strings.NewReader(test.body.Encode()))
81		if err != nil {
82			t.Fatalf("%d: Unexpected error: %s", i, err)
83		}
84		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
85
86		resp, err := client.Do(req)
87		if err != nil {
88			t.Fatalf("%d: Unexpected error: %s", i, err)
89		}
90
91		if resp.StatusCode != test.wantStatusCode {
92			t.Errorf("%d: Got status code %d, want %d", i, resp.StatusCode, test.wantStatusCode)
93		}
94		if !reflect.DeepEqual(slashCommand, test.wantParams) {
95			t.Errorf("%d: Got params %#v, want %#v", i, slashCommand, test.wantParams)
96		}
97		resp.Body.Close()
98	}
99}
100