Skip to content

Commit

Permalink
test(service): test get header via in-memory service
Browse files Browse the repository at this point in the history
When a new nonce is generated it persists in memory for a giving
duration, currently 2 seconds.

Refs: #2
  • Loading branch information
piraz committed May 31, 2024
1 parent a043122 commit fa02ca6
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 17 deletions.
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright 2023 Flavio Garcia
Copyright 2024 Flavio Garcia

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ initiatives. Available under the
This site and all documentation are licensed under
[Creative Commons 3.0](http://creativecommons.org/licenses/by/3.0/).

Copyright © 2023 Flavio Gonçalves Garcia
Copyright © 2024 Flavio Garcia
84 changes: 69 additions & 15 deletions service_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
package peasant

import (
"log"
"math/rand"
"net/http"
"testing"
"time"

"github.com/candango/gopeasant/testrunner"
"github.com/stretchr/testify/assert"
)

func randomString(s int) string {
asciiLower := "abcdefghijklmnopqrstuvwxyz"
asciiUpper := "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
digits := "012345679"
chars := []rune(asciiLower + asciiUpper + digits)
r := make([]rune, s)
for i := range r {
r[i] = chars[rand.Intn(len(chars))]
}
return string(r)
}

type InMemoryNonceService struct {
nonceMap map[string]*interface{}
}
Expand All @@ -17,62 +30,103 @@ func (s *InMemoryNonceService) Block(resp http.ResponseWriter,
req *http.Request) error {
return nil
}

func (s *InMemoryNonceService) Clear(nonce string) error {
_, ok := s.nonceMap[nonce]
if !ok {
return nil
}
delete(s.nonceMap, nonce)
return nil
}

func (s *InMemoryNonceService) Consume(resp http.ResponseWriter,
req *http.Request, nonce string) (bool, error) {
return false, nil
_, ok := s.nonceMap[nonce]
if !ok {
return false, nil
}
err := s.Clear(nonce)
if err != nil {
return false, err
}
return true, nil
}

func (s *InMemoryNonceService) GetNonce(req *http.Request) (string, error) {
return "", nil
nonce := randomString(32)
s.nonceMap[nonce] = nil
ticker := time.NewTicker(2000 * time.Millisecond)
done := make(chan bool)

go func(nonce string) {
for {
select {
case <-done:
return
case <-ticker.C:
s.Clear(nonce)
done <- true
}
}
}(nonce)

return nonce, nil
}
func (s *InMemoryNonceService) provided(req http.ResponseWriter,
res *http.Request) (bool, error) {

func (s *InMemoryNonceService) Provided(_ http.ResponseWriter,
_ *http.Request) (bool, error) {
return false, nil
}

type NoncedHandler struct {
http.Handler
log.Logger
service NonceService
}

func NewNoncedHandler() *NoncedHandler {
h := http.NewServeMux()
h.Handle("/new-nonce", &NonceHandler{})
h.Handle("/new-nonce", &NoncedHandler{})
s := &InMemoryNonceService{
nonceMap: make(map[string]*interface{}),
}
return &NoncedHandler{
Handler: h,
service: s,
}

}

type NonceHandler struct {
service NonceService
}

func (h *NonceHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
func (h *NoncedHandler) ServeHTTP(res http.ResponseWriter, req *http.Request) {
method := req.Method
if method != http.MethodHead {
res.WriteHeader(http.StatusMethodNotAllowed)
return
}
res.Header().Add("return", "OK")
nonce, err := h.service.GetNonce(req)
if err != nil {
res.WriteHeader(http.StatusInternalServerError)
return
}
res.Header().Add("nonce", nonce)
}

func TestServer(t *testing.T) {
runner := testrunner.NewHttpTestRunner(t).WithHandler(NewNoncedHandler())

t.Run("Head Request tests", func(t *testing.T) {

t.Run("Request OK", func(t *testing.T) {
res, err := runner.WithPath("/new-nonce").Head()
if err != nil {
t.Error(err)
}

assert.Equal(t, "200 OK", res.Status)
assert.Equal(t, http.NoBody, res.Body)
assert.Equal(t, "OK", res.Header.Get("return"))
assert.Equal(t, 32, len(res.Header.Get("nonce")))
res, err = runner.WithPath("/new-nonce").Get()
assert.Equal(t, "405 Method Not Allowed", res.Status)
assert.Equal(t, http.NoBody, res.Body)
})
})
}

0 comments on commit fa02ca6

Please sign in to comment.