File: handler_test.go

package info (click to toggle)
golang-github-igm-sockjs-go 3.0.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, sid, trixie
  • size: 512 kB
  • sloc: javascript: 39; makefile: 5
file content (156 lines) | stat: -rw-r--r-- 4,579 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package sockjs

import (
	"encoding/json"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

var testOptions = DefaultOptions

func init() {
	testOptions.RawWebsocket = true
}

func TestHandler_Create(t *testing.T) {
	handler := NewHandler("/echo", testOptions, nil)
	if handler.Prefix() != "/echo" {
		t.Errorf("Prefix not properly set, got '%s' expected '%s'", handler.Prefix(), "/echo")
	}
	if handler.sessions == nil {
		t.Errorf("Handler session map not made")
	}
	server := httptest.NewServer(handler)
	defer server.Close()

	resp, err := http.Get(server.URL + "/echo")
	if err != nil {
		t.Errorf("There should not be any error, got '%s'", err)
		t.FailNow()
	}
	if resp == nil {
		t.Errorf("Response should not be nil")
		t.FailNow()
	}
	if resp.StatusCode != http.StatusOK {
		t.Errorf("Unexpected status code receiver, got '%d' expected '%d'", resp.StatusCode, http.StatusOK)
	}
}

func TestHandler_RootPrefixInfoHandler(t *testing.T) {
	infoOptions := testOptions
	jSessionCalled := false
	infoOptions.JSessionID = func(writer http.ResponseWriter, request *http.Request) {
		jSessionCalled = true
	}
	handler := NewHandler("", infoOptions, nil)
	if handler.Prefix() != "" {
		t.Errorf("Prefix not properly set, got '%s' expected '%s'", handler.Prefix(), "")
	}
	server := httptest.NewServer(handler)
	defer server.Close()

	resp, err := http.Get(server.URL + "/info")
	if err != nil {
		t.Errorf("There should not be any error, got '%s'", err)
		t.FailNow()
	}
	if resp == nil {
		t.Errorf("Response should not be nil")
		t.FailNow()
	}

	if resp.StatusCode != http.StatusOK {
		t.Errorf("Unexpected status code receiver, got '%d' expected '%d'", resp.StatusCode, http.StatusOK)
		t.FailNow()
	}
	assert.True(t, jSessionCalled)
	infoData, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Errorf("Error reading body: '%v'", err)
	}
	var i info
	err = json.Unmarshal(infoData, &i)
	if err != nil {
		t.Fatalf("Error unmarshaling info: '%v', data was: '%s'", err, string(infoData))
	}
	if i.Websocket != true {
		t.Fatalf("Expected websocket to be true")
	}
}

func TestHandler_ParseSessionId(t *testing.T) {
	h := Handler{prefix: "/prefix"}
	url, _ := url.Parse("http://server:80/server/session/whatever")
	if session, err := h.parseSessionID(url); session != "session" || err != nil {
		t.Errorf("Wrong session parsed, got '%s' expected '%s' with error = '%v'", session, "session", err)
	}
}

func TestHandler_SessionByRequest(t *testing.T) {
	h := NewHandler("", testOptions, nil)
	h.options.DisconnectDelay = 10 * time.Millisecond
	var handlerFuncCalled = make(chan Session)
	h.handlerFunc = func(s Session) { handlerFuncCalled <- s }
	req, _ := http.NewRequest("POST", "/server/sessionid/whatever/follows", nil)
	sess, err := h.sessionByRequest(req)
	if sess == nil || err != nil {
		t.Errorf("session should be returned")
		// test handlerFunc was called
		select {
		case s := <-handlerFuncCalled: // ok
			if s.session != sess {
				t.Errorf("Handler was not passed correct session")
			}
		case <-time.After(100 * time.Millisecond):
			t.Errorf("HandlerFunc was not called")
		}
	}
	// test session is reused for multiple requests with same sessionID
	req2, _ := http.NewRequest("POST", "/server/sessionid/whatever", nil)
	if sess2, err := h.sessionByRequest(req2); sess2 != sess || err != nil {
		t.Errorf("Expected error, got session: '%v'", sess)
	}
	// test session expires after timeout
	time.Sleep(15 * time.Millisecond)
	h.sessionsMux.Lock()
	if _, exists := h.sessions["sessionid"]; exists {
		t.Errorf("session should not exist in handler after timeout")
	}
	h.sessionsMux.Unlock()
	// test proper behaviour in case URL is not correct
	req, _ = http.NewRequest("POST", "", nil)
	if _, err := h.sessionByRequest(req); err == nil {
		t.Errorf("Expected parser sessionID from URL error, got 'nil'")
	}
}

func TestHandler_StrictPathMatching(t *testing.T) {
	handler := NewHandler("/echo", testOptions, nil)
	server := httptest.NewServer(handler)
	defer server.Close()

	cases := []struct {
		url            string
		expectedStatus int
	}{
		{url: "/echo", expectedStatus: http.StatusOK},
		{url: "/test/echo", expectedStatus: http.StatusNotFound},
		{url: "/echo/test/test/echo", expectedStatus: http.StatusNotFound},
	}

	for _, urlCase := range cases {
		t.Run(urlCase.url, func(t *testing.T) {
			resp, err := http.Get(server.URL + urlCase.url)
			require.NoError(t, err)
			assert.Equal(t, urlCase.expectedStatus, resp.StatusCode)
		})
	}
}