package gig

import (

"bytes"

"encoding/json"

"errors"

"strings"

"testing"

"time"

"unsafe"

"github.com/matryer/is"

)

func TestLogger(t *testing.T) {

is := is.New(t)

// Note: Just for the test coverage, not a real test.

g := New()

c, _ := g.NewFakeContext("/", nil)

h := Logger()(func(c Context) error {

return c.Gemini("test")

})

// Status 2x

is.NoErr(h(c))

// Status 3x

c, _ = g.NewFakeContext("/", nil)

h = Logger()(func(c Context) error {

return c.NoContent(StatusRedirectTemporary, "test")

})

is.NoErr(h(c))

// Status 4x

c, _ = g.NewFakeContext("/", nil)

h = Logger()(func(c Context) error {

return c.NoContent(StatusSlowDown, "test")

})

is.NoErr(h(c))

// Status 5x with empty path

c, _ = g.NewFakeContext("/", nil)

h = Logger()(func(c Context) error {

return errors.New("error")

})

is.NoErr(h(c))

// Status 6x with empty path

c, _ = g.NewFakeContext("/", nil)

h = Logger()(func(c Context) error {

return c.NoContent(StatusClientCertificateRequired, "test")

})

is.NoErr(h(c))

}

func TestLoggerTemplate(t *testing.T) {

buf := new(bytes.Buffer)

oldWriter := DefaultWriter

DefaultWriter = buf

defer func() {

DefaultWriter = oldWriter

}()

g := New()

g.Use(LoggerWithConfig(LoggerConfig{

Format: `{"time":"${time_rfc3339_nano}","time_unix":"${time_unix}",` +

`"time_unix_nano":"${time_unix_nano}","time_rfc3339":"${time_rfc3339}",` +

`"id":"${id}","remote_ip":"${remote_ip}","host":"${host}",` +

`""uri":"${uri}","status":${status}, "latency":${latency},` +

`"latency_human":"${latency_human}","bytes_in":${bytes_in}, "path":"${path}", ` +

`"bytes_out":${bytes_out},"us":"${query}","meta":"${meta}"}` + "\n",

}))

g.Handle("/login", func(c Context) error {

return c.Gemini("Header Logged")

})

c, _ := g.NewFakeContext("/login?username=apagano-param&password=secret", nil)

g.ServeGemini(c)

cases := []string{

"apagano-param",

"\"path\":\"/login\"",

"\"uri\":\"/login?user",

"\"remote_ip\":\"192.0.2.1\"",

"\"status\":20",

"\"bytes_in\":45,",

"\"meta\":\"text/gemini",

}

for _, token := range cases {

is := is.New(t)

t.Run(token, func(t *testing.T) {

is.True(strings.Contains(buf.String(), token))

})

}

}

func TestLoggerCustomTimestamp(t *testing.T) {

is := is.New(t)

buf := new(bytes.Buffer)

oldWriter := DefaultWriter

DefaultWriter = buf

defer func() {

DefaultWriter = oldWriter

}()

customTimeFormat := "2006-01-02 15:04:05.00000"

g := New()

g.Use(LoggerWithConfig(LoggerConfig{

Format: `{"time":"${time_custom}","id":"${id}","remote_ip":"${remote_ip}","host":"${host}","user_agent":"${user_agent}",` +

`"method":"${method}","uri":"${uri}","status":${status}, "latency":${latency},` +

`"latency_human":"${latency_human}","bytes_in":${bytes_in}, "path":"${path}", "referer":"${referer}",` +

`"bytes_out":${bytes_out},"ch":"${header:X-Custom-Header}",` +

`"us":"${query:username}", "cf":"${form:username}", "session":"${cookie:session}"}` + "\n",

CustomTimeFormat: customTimeFormat,

}))

g.Handle("/", func(c Context) error {

return c.Gemini("custom time stamp test")

})

c, _ := g.NewFakeContext("/", nil)

g.ServeGemini(c)

var objs map[string]*json.RawMessage

if err := json.Unmarshal(buf.Bytes(), &objs); err != nil {

is.Fail()

}

loggedTime := *(*string)(unsafe.Pointer(objs["time"]))

_, err := time.Parse(customTimeFormat, loggedTime)

is.True(err != nil)

}


Source