package tests // Package tests -- // 1) StartSession ----- // 2) DestroySessioon ----- // 3) Set session variable--| // 4) Get session variable--| // 5) Update -- // -- // 6) Delete -- // -- // 7) GC session after lifetime import ( "fmt" "io" "net/http" "net/http/cookiejar" "net/http/httptest" "net/url" "testing" "time" "git.mtux.eu/darkgopher/session" "golang.org/x/net/publicsuffix" //all impls imports here ... _ "git.mtux.eu/darkgopher/session/storage/memory" ) const sid = "sid" const lifet = 180 var sm *session.Manager //current session impl. var testserver *httptest.Server //httptest server h2 var testclient *http.Client //httptest client h2 //var cursid string type TestServer struct{} func (ts *TestServer) Serve() { mux := http.NewServeMux() mux.HandleFunc("/startsession", ts.startSession) //ck mux.HandleFunc("/destroysession", ts.destroySession) //ck mux.HandleFunc("/setsessionvar", ts.setSessionVar) mux.HandleFunc("/getsessionvar", ts.getSessionVar) mux.HandleFunc("/updatesessionvar", ts.updateSessionVar) mux.HandleFunc("/validateupdatedvar", ts.validateUpdatedValue) mux.HandleFunc("/deletesessionvar", ts.deleteSessionValue) mux.HandleFunc("/validatedeletedvar", ts.validateDeletedValue) mux.HandleFunc("/sessionGC", ts.sessionGC) //ck mux.HandleFunc("/", ts.root) testserver = httptest.NewUnstartedServer(mux) testserver.EnableHTTP2 = true testserver.StartTLS() testclient = testserver.Client() } func (ts *TestServer) startSession(w http.ResponseWriter, r *http.Request) { var err error if _, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } io.WriteString(w, "OK") } func (ts *TestServer) destroySession(w http.ResponseWriter, r *http.Request) { var err error if _, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } if err = sm.SessionDestroy(w, r); err != nil { io.WriteString(w, err.Error()) } io.WriteString(w, "OK") } func (ts *TestServer) setSessionVar(w http.ResponseWriter, r *http.Request) { var err error var sess session.Session if sess, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } if err = sess.Set("Pes", "Minule"); err != nil { io.WriteString(w, err.Error()) } if err = sess.Set("Vek", 16); err != nil { io.WriteString(w, err.Error()) } io.WriteString(w, "OK") } func (ts *TestServer) getSessionVar(w http.ResponseWriter, r *http.Request) { var err error var sess session.Session if sess, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } var ( v any n any ) if v, err = sess.Get("Pes"); err != nil { io.WriteString(w, err.Error()) return } if n, err = sess.Get("Vek"); err != nil { io.WriteString(w, err.Error()) return } if v.(string) != "Minule" { fmt.Fprintf(w, "Value of session key: 'Pes' must be 'Minule', not: %s", v) return } if n.(int) != 16 { fmt.Fprintf(w, "Value of session key: 'Vek' must be '16', not: %d", n) return } io.WriteString(w, "OK") } func (ts *TestServer) updateSessionVar(w http.ResponseWriter, r *http.Request) { var err error var sess session.Session if sess, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } if err = sess.Set("Vek", 3); err != nil { io.WriteString(w, err.Error()) } io.WriteString(w, "OK") } func (ts *TestServer) validateUpdatedValue(w http.ResponseWriter, r *http.Request) { var err error var sess session.Session if sess, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } var n any if n, err = sess.Get("Vek"); err != nil { io.WriteString(w, err.Error()) } if n.(int) != 3 { io.WriteString(w, fmt.Sprintf("Value vek ater update must be: '3', not: '%d'", n.(int))) } io.WriteString(w, "OK") } func (ts *TestServer) deleteSessionValue(w http.ResponseWriter, r *http.Request) { var err error var sess session.Session if sess, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } if sess.Delete("Vek"); err != nil { io.WriteString(w, err.Error()) } io.WriteString(w, "OK") } func (ts *TestServer) validateDeletedValue(w http.ResponseWriter, r *http.Request) { var err error var sess session.Session if sess, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } var v any if v, err = sess.Get("Vek"); err != nil { io.WriteString(w, err.Error()) } if v != nil { io.WriteString(w, fmt.Sprintf("Session value 'Vek' must be nil after delete, not: %v", v)) } io.WriteString(w, "OK") } func (ts *TestServer) sessionGC(w http.ResponseWriter, r *http.Request) { var err error if _, err = sm.SessionStart(w, r); err != nil { io.WriteString(w, err.Error()) } time.Sleep(200 * time.Millisecond) io.WriteString(w, "OK") } func (ts *TestServer) root(w http.ResponseWriter, r *http.Request) { } func MkRequest(method, path string) (body []byte, err error) { var req *http.Request uri := fmt.Sprintf("%s%s", testserver.URL, path) if req, err = http.NewRequest(method, uri, nil); err != nil { return nil, fmt.Errorf("Create request to: %s failed: %v", uri, err) } var res *http.Response if res, err = testclient.Do(req); err != nil { return nil, fmt.Errorf("Request to: %s failed: %v", uri, err) } return io.ReadAll(res.Body) } func CheckRequestOK(path string) (err error) { var res []byte if res, err = MkRequest("GET", path); err != nil { return fmt.Errorf("Make request: %s failed: %v", path, err) } if string(res) != "OK" { return fmt.Errorf("Response from test request not OK, but: %s", res) } return } func t1(t *testing.T) { if err := CheckRequestOK("/startsession"); err != nil { t.Error(err) } uri, _ := url.Parse(testserver.URL + "/startsession") cks := testclient.Jar.Cookies(uri) if len(cks) != 1 && cks[0].Name != sid { t.Errorf("After session start must be set 1 cookie named: '%s'", sid) } } func t2(t *testing.T) { if err := CheckRequestOK("/destroysession"); err != nil { t.Error(err) } uri, _ := url.Parse(testserver.URL + "/destroysession") cks := testclient.Jar.Cookies(uri) if len(cks) != 0 { t.Errorf("After session destroy musoyt be 0 cookies in jar") } } func t3(t *testing.T) { if err := CheckRequestOK("/setsessionvar"); err != nil { t.Error(err) } } func t4(t *testing.T) { if err := CheckRequestOK("/getsessionvar"); err != nil { t.Error(err) } } func t5(t *testing.T) { if err := CheckRequestOK("/updatesessionvar"); err != nil { t.Error(err) } } func t6(t *testing.T) { if err := CheckRequestOK("/validateupdatedvar"); err != nil { t.Error(err) } } func t7(t *testing.T) { if err := CheckRequestOK("/deletesessionvar"); err != nil { t.Error(err) } } func t8(t *testing.T) { if err := CheckRequestOK("/validatedeletedvar"); err != nil { t.Error(err) } } func t9(t *testing.T) { if err := CheckRequestOK("/sessionGC"); err != nil { t.Error(err) } //TODO check ck invalidation } // iterate all session storage impls. and run t1 - t7 func TestRunAll(t *testing.T) { ts := &TestServer{} ts.Serve() //all impls. subtests for _, pn := range session.ProviderNames() { var err error jar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List}) testclient.Jar = jar if sm, err = session.NewManager(pn, sid, lifet, true); err != nil { t.Errorf("Session provider %s failed initialize err: %v", pn, err) } fns := []func(t *testing.T){t1, t2, t3, t4, t5, t6, t7, t8, t9} for idx, fn := range fns { t.Run(fmt.Sprintf("Test%d", idx+1), fn) } } }