Skip to content

Commit

Permalink
add ts parsing helper for requests
Browse files Browse the repository at this point in the history
  • Loading branch information
umputun committed Apr 6, 2022
1 parent 97f70a5 commit 7e5e4ba
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ a request does not satisfy the maybeFn logic.
- `rest.NewErrorLogger` - creates a struct providing shorter form of logger call
- `rest.FileServer` - creates a file server for static assets with directory listing disabled
- `realip.Get` - returns client's IP address
- `rest.ParseFromTo` - parses "from" and "to" request's query params with various formats

## Profiler

Expand Down
31 changes: 31 additions & 0 deletions rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"bytes"
"encoding/json"
"net/http"
"time"

"github.com/pkg/errors"
)
Expand Down Expand Up @@ -67,3 +68,33 @@ func renderJSONWithStatus(w http.ResponseWriter, data interface{}, code int) {
w.WriteHeader(code)
_, _ = w.Write(buf.Bytes())
}

// ParseFromTo parses from and to query params of the request
func ParseFromTo(r *http.Request) (from, to time.Time, err error) {
parseTimeStamp := func(ts string) (time.Time, error) {
formats := []string{
"2006-01-02T15:04:05.000000000",
"2006-01-02T15:04:05",
"2006-01-02T15:04",
"20060102",
time.RFC3339,
time.RFC3339Nano,
}

for _, f := range formats {
if t, e := time.Parse(f, ts); e == nil {
return t, nil
}
}
return time.Time{}, errors.Errorf("can't parse date %q", ts)
}

if from, err = parseTimeStamp(r.URL.Query().Get("from")); err != nil {
return from, to, errors.Wrap(err, "incorrect from time")
}

if to, err = parseTimeStamp(r.URL.Query().Get("to")); err != nil {
return from, to, errors.Wrap(err, "incorrect to time")
}
return from, to, nil
}
50 changes: 50 additions & 0 deletions rest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ import (
"io"
"net/http"
"net/http/httptest"
"strconv"
"testing"
"time"

"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -73,6 +76,53 @@ func TestRest_RenderJSONWithHTML(t *testing.T) {
assert.Equal(t, "application/json; charset=utf-8", resp.Header.Get("Content-Type"))
}

func TestParseFromTo(t *testing.T) {

tbl := []struct {
query string
from, to time.Time
err error
}{
{
query: "from=20220406&to=20220501",
from: time.Date(2022, time.April, 6, 0, 0, 0, 0, time.UTC),
to: time.Date(2022, time.May, 1, 0, 0, 0, 0, time.UTC),
err: nil,
},
{
query: "from=2022-04-06T18:30:25&to=2022-05-01T17:50",
from: time.Date(2022, time.April, 6, 18, 30, 25, 0, time.UTC),
to: time.Date(2022, time.May, 1, 17, 50, 0, 0, time.UTC),
err: nil,
},
{
query: "from=2022-04-06T18:30:25&to=xyzbad",
err: errors.New(`incorrect to time: can't parse date "xyzbad"`),
},
{
query: "from=123455&to=2022-05-01T17:50",
err: errors.New(`incorrect from time: can't parse date "123455"`),
},
{"", time.Time{}, time.Time{}, errors.New("incorrect from time: can't parse date \"\"")},
}

for i, tt := range tbl {
t.Run(strconv.Itoa(i), func(t *testing.T) {
req, err := http.NewRequest("GET", "http://localhost?"+tt.query, http.NoBody)
require.NoError(t, err)
from, to, err := ParseFromTo(req)
if tt.err != nil {
assert.EqualError(t, err, tt.err.Error())
return
}
require.NoError(t, err)
assert.Equal(t, tt.from, from)
assert.Equal(t, tt.to, to)
})
}

}

func getTestHandlerBlah() http.HandlerFunc {
fn := func(rw http.ResponseWriter, req *http.Request) {
_, _ = rw.Write([]byte("blah"))
Expand Down

0 comments on commit 7e5e4ba

Please sign in to comment.