storj/private/apigen/gogen_test.go
Ivan Fraixedes d34c1b6825 private/apigen: Generate docs & typescript for example
Generate the documentation and the typescript code for the example of
that we have to generate an API through the API generator.

The JSON Go struct field tags are needed because the typescript
generator require them, otherwise it panics.

The test had to be adjusted according to match the tags so Go consider
the structs the same type, otherwise, it doesn't compile.

Change-Id: I3e4ebff9174885c50ca2058b86b7ec60e025945c
2023-08-25 12:30:21 +00:00

137 lines
3.0 KiB
Go

// Copyright (C) 2022 Storj Labs, Inc.
// See LICENSE for copying information.
package apigen_test
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
"github.com/gorilla/mux"
"github.com/spacemonkeygo/monkit/v3"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zaptest"
"storj.io/common/testcontext"
"storj.io/common/uuid"
"storj.io/storj/private/api"
"storj.io/storj/private/apigen"
"storj.io/storj/private/apigen/example"
)
type (
auth struct{}
service struct{}
response = struct {
ID uuid.UUID `json:"id"`
Date time.Time `json:"date"`
PathParam string `json:"pathParam"`
Body string `json:"body"`
}
)
func (a auth) IsAuthenticated(ctx context.Context, r *http.Request, isCookieAuth, isKeyAuth bool) (context.Context, error) {
return ctx, nil
}
func (a auth) RemoveAuthCookie(w http.ResponseWriter) {}
func (s service) GenTestAPI(
ctx context.Context,
pathParam string,
id uuid.UUID,
date time.Time,
body struct {
Content string `json:"content"`
},
) (*response, api.HTTPError) {
return &response{
ID: id,
Date: date,
PathParam: pathParam,
Body: body.Content,
}, api.HTTPError{}
}
func send(ctx context.Context, method string, url string, body interface{}) ([]byte, error) {
var bodyReader io.Reader = http.NoBody
if body != nil {
bodyJSON, err := json.Marshal(body)
if err != nil {
return nil, err
}
bodyReader = bytes.NewBuffer(bodyJSON)
}
req, err := http.NewRequestWithContext(ctx, method, url, bodyReader)
if err != nil {
return nil, err
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}
if err := resp.Body.Close(); err != nil {
return nil, err
}
return respBody, nil
}
func TestAPIServer(t *testing.T) {
ctx := testcontext.NewWithTimeout(t, 5*time.Second)
defer ctx.Cleanup()
router := mux.NewRouter()
example.NewTestAPI(zaptest.NewLogger(t), monkit.Package(), service{}, router, auth{})
server := httptest.NewServer(router)
defer server.Close()
id, err := uuid.New()
require.NoError(t, err)
expected := response{
ID: id,
Date: time.Now(),
PathParam: "foo",
Body: "bar",
}
resp, err := send(ctx, http.MethodPost,
fmt.Sprintf("%s/api/v0/testapi/%s?id=%s&date=%s",
server.URL,
expected.PathParam,
url.QueryEscape(expected.ID.String()),
url.QueryEscape(expected.Date.Format(apigen.DateFormat)),
), struct{ Content string }{expected.Body},
)
require.NoError(t, err)
var actual map[string]string
require.NoError(t, json.Unmarshal(resp, &actual))
for _, key := range []string{"id", "date", "pathParam", "body"} {
require.Contains(t, actual, key)
}
require.Equal(t, expected.ID.String(), actual["id"])
require.Equal(t, expected.Date.Format(apigen.DateFormat), actual["date"])
require.Equal(t, expected.PathParam, actual["pathParam"])
require.Equal(t, expected.Body, actual["body"])
}