Skip to content
This repository has been archived by the owner on Mar 20, 2023. It is now read-only.

Commit

Permalink
actions: add index handler tests (gomods#1637)
Browse files Browse the repository at this point in the history
  • Loading branch information
marwan-at-work authored Jul 3, 2020
1 parent d6f06d0 commit 408fd74
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 26 deletions.
61 changes: 35 additions & 26 deletions cmd/proxy/actions/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,60 @@ package actions

import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"time"

"github.com/gomods/athens/pkg/errors"
"github.com/gomods/athens/pkg/index"
"github.com/gomods/athens/pkg/log"
"github.com/sirupsen/logrus"
)

// indexHandler implements GET baseURL/index
func indexHandler(index index.Indexer) http.HandlerFunc {
const op errors.Op = "actions.IndexHandler"
return func(w http.ResponseWriter, r *http.Request) {
var (
err error
limit int
since time.Time
)
if limitStr := r.FormValue("limit"); limitStr != "" {
limit, err = strconv.Atoi(limitStr)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
if sinceStr := r.FormValue("since"); sinceStr != "" {
since, err = time.Parse(time.RFC3339, sinceStr)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
}
if limit <= 0 {
limit = 2000
}
list, err := index.Lines(r.Context(), since, limit)
ctx := r.Context()
list, err := getIndexLines(r, index)
if err != nil {
http.Error(w, err.Error(), 500)
log.EntryFromContext(ctx).SystemErr(err)
http.Error(w, err.Error(), errors.Kind(err))
return
}
enc := json.NewEncoder(w)
for _, meta := range list {
if err = enc.Encode(meta); err != nil {
http.Error(w, err.Error(), 500)
log.EntryFromContext(ctx).SystemErr(err)
fmt.Fprintln(w, err)
return
}
}
}
}

func getIndexLines(r *http.Request, index index.Indexer) ([]*index.Line, error) {
const op errors.Op = "actions.IndexHandler"
var (
err error
limit = 2000
since time.Time
)
if limitStr := r.FormValue("limit"); limitStr != "" {
limit, err = strconv.Atoi(limitStr)
if err != nil || limit <= 0 {
return nil, errors.E(op, err, errors.KindBadRequest, logrus.InfoLevel)
}
}
if sinceStr := r.FormValue("since"); sinceStr != "" {
since, err = time.Parse(time.RFC3339, sinceStr)
if err != nil {
return nil, errors.E(op, err, errors.KindBadRequest, logrus.InfoLevel)
}
}
list, err := index.Lines(r.Context(), since, limit)
if err != nil {
return nil, errors.E(op, err)
}
return list, nil
}
124 changes: 124 additions & 0 deletions cmd/proxy/actions/index_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package actions

import (
"context"
"fmt"
"net/http/httptest"
"net/url"
"testing"
"time"

"github.com/gomods/athens/pkg/index"
)

var indexHandlerTests = []struct {
name string
desc string
lines []*index.Line
err error
limit string
since string
code int
}{
{
name: "happy path",
desc: "given no params and 1 line, the handler should return 200 along with the index line",
lines: []*index.Line{
{
Path: "github.com/pkg/errors",
Version: "v0.9.1",
Timestamp: time.Now(),
},
},
code: 200,
},
{
name: "valid limit",
desc: "given a valid limit number, the handler should return 200",
lines: []*index.Line{
{
Path: "github.com/pkg/errors",
Version: "v0.9.1",
Timestamp: time.Now(),
},
},
limit: "1",
code: 200,
},
{
name: "valid since",
desc: "given a valid since string, the handler should return 200",
lines: []*index.Line{
{
Path: "github.com/pkg/errors",
Version: "v0.9.1",
Timestamp: time.Now(),
},
},
limit: "1",
since: time.Now().Add(-time.Hour).Format(time.RFC3339),
code: 200,
},
{
name: "invalid limit",
desc: "a limit query param must be a valid integer",
limit: "im not an integer",
code: 400,
},
{
name: "limit too low",
desc: "a limit query cannot be a negative number",
limit: "-1",
code: 400,
},
{
name: "invalid zero limit",
desc: "a limit cannot be 0",
limit: "0",
code: 400,
},
{
name: "invalid since",
desc: "since must be a valid RFC3339 format",
since: time.Now().Format(time.RFC822),
code: 400,
},
{
name: "index error",
desc: "given an underlying index error, the handler must return 500",
err: fmt.Errorf("internal error"),
code: 500,
},
}

func TestIndexHandler(t *testing.T) {
for _, tc := range indexHandlerTests {
t.Run(tc.name, func(t *testing.T) {
t.Log(tc.desc)
req := httptest.NewRequest("GET", "/index", nil)
q := url.Values{}
q.Set("limit", tc.limit)
q.Set("since", tc.since)
req.URL.RawQuery = q.Encode()
w := httptest.NewRecorder()
mi := &mockIndexer{lines: tc.lines, err: tc.err}
handler := indexHandler(mi)
handler(w, req)
if w.Code != tc.code {
t.Fatalf("expected response code to be %d but got %d", tc.code, w.Code)
}

})
}
}

type mockIndexer struct {
index.Indexer

lines []*index.Line
err error
}

func (mi *mockIndexer) Lines(ctx context.Context, since time.Time, limit int) ([]*index.Line, error) {
return mi.lines, mi.err
}

0 comments on commit 408fd74

Please sign in to comment.