e67691d51c
I made several commits to add support to the API generator for anonymous types because the example was using them. Later, I was told that we don't need to support them, so the example should have never used anonymous types. Supporting anonymous types has added complexity to the API generator and we are finding bugs in corner cases whose fixes lead to adding more complexity and some fixes doesn't seem to have a neat solution without doing a big refactoring. We decided to reduce the side effects that supporting anonymous type has brought just removing it. This commit remove the support for anonymous types and reflect that in the example. Change-Id: I2f8c87a0db0e229971ab1bef46cca16fee924191
166 lines
3.6 KiB
Go
166 lines
3.6 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"
|
|
"storj.io/storj/private/apigen/example/myapi"
|
|
)
|
|
|
|
type (
|
|
auth struct{}
|
|
service struct{}
|
|
)
|
|
|
|
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) Get(
|
|
ctx context.Context,
|
|
) ([]myapi.Document, api.HTTPError) {
|
|
return []myapi.Document{}, api.HTTPError{}
|
|
}
|
|
|
|
func (s service) GetOne(
|
|
ctx context.Context,
|
|
pathParam string,
|
|
) (*myapi.Document, api.HTTPError) {
|
|
return &myapi.Document{}, api.HTTPError{}
|
|
}
|
|
|
|
func (s service) GetTag(
|
|
ctx context.Context,
|
|
pathParam string,
|
|
tagName string,
|
|
) (*[2]string, api.HTTPError) {
|
|
return &[2]string{}, api.HTTPError{}
|
|
}
|
|
|
|
func (s service) GetVersions(
|
|
ctx context.Context,
|
|
pathParam string,
|
|
) ([]myapi.Version, api.HTTPError) {
|
|
return []myapi.Version{}, api.HTTPError{}
|
|
}
|
|
|
|
func (s service) UpdateContent(
|
|
ctx context.Context,
|
|
pathParam string,
|
|
id uuid.UUID,
|
|
date time.Time,
|
|
body myapi.NewDocument,
|
|
) (*myapi.Document, api.HTTPError) {
|
|
return &myapi.Document{
|
|
ID: id,
|
|
Date: date,
|
|
PathParam: pathParam,
|
|
Body: body.Content,
|
|
}, api.HTTPError{}
|
|
}
|
|
|
|
func send(ctx context.Context, t *testing.T, method string, url string, body interface{}) ([]byte, error) {
|
|
t.Helper()
|
|
|
|
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
|
|
}
|
|
|
|
if c := resp.StatusCode; c != http.StatusOK {
|
|
t.Fatalf("unexpected status code. Want=%d, Got=%d", http.StatusOK, c)
|
|
}
|
|
|
|
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.NewDocuments(zaptest.NewLogger(t), monkit.Package(), service{}, router, auth{})
|
|
|
|
server := httptest.NewServer(router)
|
|
defer server.Close()
|
|
|
|
id, err := uuid.New()
|
|
require.NoError(t, err)
|
|
|
|
expected := myapi.Document{
|
|
ID: id,
|
|
Date: time.Now(),
|
|
PathParam: "foo",
|
|
Body: "bar",
|
|
}
|
|
|
|
resp, err := send(ctx, t, http.MethodPost,
|
|
fmt.Sprintf("%s/api/v0/docs/%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)
|
|
|
|
fmt.Println(string(resp))
|
|
|
|
var actual map[string]any
|
|
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"].(string))
|
|
require.Equal(t, expected.Date.Format(apigen.DateFormat), actual["date"].(string))
|
|
require.Equal(t, expected.PathParam, actual["pathParam"].(string))
|
|
require.Equal(t, expected.Body, actual["body"].(string))
|
|
}
|