aboutsummaryrefslogtreecommitdiffhomepage
path: root/cmd/mbf/internal/pkgsite/api_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/mbf/internal/pkgsite/api_test.go')
-rw-r--r--cmd/mbf/internal/pkgsite/api_test.go111
1 files changed, 111 insertions, 0 deletions
diff --git a/cmd/mbf/internal/pkgsite/api_test.go b/cmd/mbf/internal/pkgsite/api_test.go
new file mode 100644
index 00000000..d2c21d81
--- /dev/null
+++ b/cmd/mbf/internal/pkgsite/api_test.go
@@ -0,0 +1,111 @@
+package pkgsite
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "strconv"
+ "testing"
+
+ "hakurei.app/internal/info"
+ "hakurei.app/internal/rosa"
+)
+
+// prefix is prepended to every API path.
+const prefix = "/api/" + apiVersion + "/"
+
+func TestAPIInfo(t *testing.T) {
+ t.Parallel()
+
+ w := httptest.NewRecorder()
+ handleInfo(w, httptest.NewRequestWithContext(
+ t.Context(),
+ http.MethodGet,
+ prefix+"info",
+ nil,
+ ))
+
+ resp := w.Result()
+ checkStatus(t, resp, http.StatusOK)
+ checkAPIHeader(t, w.Header())
+
+ checkPayload(t, resp, struct {
+ Count int `json:"count"`
+ HakureiVersion string `json:"hakurei_version"`
+ }{len(rosa.Collect()), info.Version()})
+}
+
+func TestAPIGet(t *testing.T) {
+ t.Parallel()
+ const target = prefix + "get"
+
+ index := newIndex(t)
+ newRequest := func(suffix string) *httptest.ResponseRecorder {
+ w := httptest.NewRecorder()
+ index.handleGet(w, httptest.NewRequestWithContext(
+ t.Context(),
+ http.MethodGet,
+ target+suffix,
+ nil,
+ ))
+ return w
+ }
+
+ checkValidate := func(t *testing.T, suffix string, vmin, vmax int, wantErr string) {
+ t.Run("invalid", func(t *testing.T) {
+ t.Parallel()
+
+ w := newRequest("?" + suffix + "=invalid")
+ resp := w.Result()
+ checkError(t, resp, wantErr, http.StatusBadRequest)
+ })
+
+ t.Run("min", func(t *testing.T) {
+ t.Parallel()
+
+ w := newRequest("?" + suffix + "=" + strconv.Itoa(vmin-1))
+ resp := w.Result()
+ checkError(t, resp, wantErr, http.StatusBadRequest)
+
+ w = newRequest("?" + suffix + "=" + strconv.Itoa(vmin))
+ resp = w.Result()
+ checkStatus(t, resp, http.StatusOK)
+ })
+
+ t.Run("max", func(t *testing.T) {
+ t.Parallel()
+
+ w := newRequest("?" + suffix + "=" + strconv.Itoa(vmax+1))
+ resp := w.Result()
+ checkError(t, resp, wantErr, http.StatusBadRequest)
+
+ w = newRequest("?" + suffix + "=" + strconv.Itoa(vmax))
+ resp = w.Result()
+ checkStatus(t, resp, http.StatusOK)
+ })
+ }
+
+ t.Run("limit", func(t *testing.T) {
+ t.Parallel()
+ checkValidate(
+ t, "index=0&sort=0&limit", 1, 100,
+ "limit must be an integer between 1 and 100",
+ )
+ })
+
+ count := len(rosa.Collect())
+ t.Run("index", func(t *testing.T) {
+ t.Parallel()
+ checkValidate(
+ t, "limit=1&sort=0&index", 0, count-1,
+ "index must be an integer between 0 and "+strconv.Itoa(count-1),
+ )
+ })
+
+ t.Run("sort", func(t *testing.T) {
+ t.Parallel()
+ checkValidate(
+ t, "index=0&limit=1&sort", 0, int(sortOrderEnd),
+ "sort must be an integer between 0 and "+strconv.Itoa(int(sortOrderEnd)),
+ )
+ })
+}