mirror of
https://github.com/anyproto/anytype-heart.git
synced 2025-06-08 05:47:07 +09:00
GO-4459: Refactor auth tests
This commit is contained in:
parent
d05cc8a257
commit
239a606eb3
5 changed files with 148 additions and 399 deletions
|
@ -52,7 +52,7 @@ func AuthTokenHandler(s *AuthService) gin.HandlerFunc {
|
|||
sessionToken, appKey, err := s.SolveChallengeForToken(c.Request.Context(), challengeID, code)
|
||||
errCode := util.MapErrorCode(err,
|
||||
util.ErrToCode(ErrInvalidInput, http.StatusBadRequest),
|
||||
util.ErrToCode(ErrorFailedAuthenticate, http.StatusInternalServerError),
|
||||
util.ErrToCode(ErrFailedAuthenticate, http.StatusInternalServerError),
|
||||
)
|
||||
|
||||
if errCode != http.StatusOK {
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
var (
|
||||
ErrFailedGenerateChallenge = errors.New("failed to generate a new challenge")
|
||||
ErrInvalidInput = errors.New("invalid input")
|
||||
ErrorFailedAuthenticate = errors.New("failed to authenticate user")
|
||||
ErrFailedAuthenticate = errors.New("failed to authenticate user")
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
|
@ -53,7 +53,7 @@ func (s *AuthService) SolveChallengeForToken(ctx context.Context, challengeID, c
|
|||
})
|
||||
|
||||
if resp.Error.Code != pb.RpcAccountLocalLinkSolveChallengeResponseError_NULL {
|
||||
return "", "", ErrorFailedAuthenticate
|
||||
return "", "", ErrFailedAuthenticate
|
||||
}
|
||||
|
||||
return resp.SessionToken, resp.AppKey, nil
|
||||
|
|
140
cmd/api/auth/service_test.go
Normal file
140
cmd/api/auth/service_test.go
Normal file
|
@ -0,0 +1,140 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anyproto/anytype-heart/pb"
|
||||
"github.com/anyproto/anytype-heart/pb/service/mock_service"
|
||||
)
|
||||
|
||||
const (
|
||||
mockedAppName = "api-test"
|
||||
mockedChallengeId = "mocked-challenge-id"
|
||||
mockedCode = "mocked-mockedCode"
|
||||
mockedSessionToken = "mocked-session-token"
|
||||
mockedAppKey = "mocked-app-key"
|
||||
)
|
||||
|
||||
type fixture struct {
|
||||
*AuthService
|
||||
mwMock *mock_service.MockClientCommandsServer
|
||||
}
|
||||
|
||||
func newFixture(t *testing.T) *fixture {
|
||||
mw := mock_service.NewMockClientCommandsServer(t)
|
||||
authService := NewService(mw)
|
||||
|
||||
return &fixture{
|
||||
AuthService: authService,
|
||||
mwMock: mw,
|
||||
}
|
||||
}
|
||||
|
||||
func TestAuthService_GenerateNewChallenge(t *testing.T) {
|
||||
t.Run("successful challenge creation", func(t *testing.T) {
|
||||
// given
|
||||
ctx := context.Background()
|
||||
fx := newFixture(t)
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkNewChallenge", mock.Anything, &pb.RpcAccountLocalLinkNewChallengeRequest{AppName: mockedAppName}).
|
||||
Return(&pb.RpcAccountLocalLinkNewChallengeResponse{
|
||||
ChallengeId: mockedChallengeId,
|
||||
Error: &pb.RpcAccountLocalLinkNewChallengeResponseError{Code: pb.RpcAccountLocalLinkNewChallengeResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
challengeId, err := fx.GenerateNewChallenge(ctx, mockedAppName)
|
||||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, mockedChallengeId, challengeId)
|
||||
})
|
||||
|
||||
t.Run("failed challenge creation", func(t *testing.T) {
|
||||
// given
|
||||
ctx := context.Background()
|
||||
fx := newFixture(t)
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkNewChallenge", mock.Anything, &pb.RpcAccountLocalLinkNewChallengeRequest{AppName: mockedAppName}).
|
||||
Return(&pb.RpcAccountLocalLinkNewChallengeResponse{
|
||||
Error: &pb.RpcAccountLocalLinkNewChallengeResponseError{Code: pb.RpcAccountLocalLinkNewChallengeResponseError_UNKNOWN_ERROR},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
challengeId, err := fx.GenerateNewChallenge(ctx, mockedAppName)
|
||||
|
||||
// then
|
||||
require.Error(t, err)
|
||||
require.Equal(t, ErrFailedGenerateChallenge, err)
|
||||
require.Empty(t, challengeId)
|
||||
})
|
||||
}
|
||||
|
||||
func TestAuthService_SolveChallengeForToken(t *testing.T) {
|
||||
t.Run("successful token retrieval", func(t *testing.T) {
|
||||
// given
|
||||
ctx := context.Background()
|
||||
fx := newFixture(t)
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkSolveChallenge", mock.Anything, &pb.RpcAccountLocalLinkSolveChallengeRequest{
|
||||
ChallengeId: mockedChallengeId,
|
||||
Answer: mockedCode,
|
||||
}).
|
||||
Return(&pb.RpcAccountLocalLinkSolveChallengeResponse{
|
||||
SessionToken: mockedSessionToken,
|
||||
AppKey: mockedAppKey,
|
||||
Error: &pb.RpcAccountLocalLinkSolveChallengeResponseError{Code: pb.RpcAccountLocalLinkSolveChallengeResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
sessionToken, appKey, err := fx.SolveChallengeForToken(ctx, mockedChallengeId, mockedCode)
|
||||
|
||||
// then
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, mockedSessionToken, sessionToken)
|
||||
require.Equal(t, mockedAppKey, appKey)
|
||||
|
||||
})
|
||||
|
||||
t.Run("bad request", func(t *testing.T) {
|
||||
// given
|
||||
ctx := context.Background()
|
||||
fx := newFixture(t)
|
||||
|
||||
// when
|
||||
sessionToken, appKey, err := fx.SolveChallengeForToken(ctx, "", "")
|
||||
|
||||
// then
|
||||
require.Error(t, err)
|
||||
require.Equal(t, ErrInvalidInput, err)
|
||||
require.Empty(t, sessionToken)
|
||||
require.Empty(t, appKey)
|
||||
})
|
||||
|
||||
t.Run("failed token retrieval", func(t *testing.T) {
|
||||
// given
|
||||
ctx := context.Background()
|
||||
fx := newFixture(t)
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkSolveChallenge", mock.Anything, &pb.RpcAccountLocalLinkSolveChallengeRequest{
|
||||
ChallengeId: mockedChallengeId,
|
||||
Answer: mockedCode,
|
||||
}).
|
||||
Return(&pb.RpcAccountLocalLinkSolveChallengeResponse{
|
||||
Error: &pb.RpcAccountLocalLinkSolveChallengeResponseError{Code: pb.RpcAccountLocalLinkSolveChallengeResponseError_UNKNOWN_ERROR},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
sessionToken, appKey, err := fx.SolveChallengeForToken(ctx, mockedChallengeId, mockedCode)
|
||||
|
||||
// then
|
||||
require.Error(t, err)
|
||||
require.Equal(t, ErrFailedAuthenticate, err)
|
||||
require.Empty(t, sessionToken)
|
||||
require.Empty(t, appKey)
|
||||
})
|
||||
}
|
|
@ -85,401 +85,6 @@ func newFixture(t *testing.T) *fixture {
|
|||
}
|
||||
}
|
||||
|
||||
func TestApiServer_AuthDisplayCodeHandler(t *testing.T) {
|
||||
t.Run("successful challenge creation", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkNewChallenge", mock.Anything, &pb.RpcAccountLocalLinkNewChallengeRequest{AppName: "api-test"}).
|
||||
Return(&pb.RpcAccountLocalLinkNewChallengeResponse{
|
||||
ChallengeId: "mocked-challenge-id",
|
||||
Error: &pb.RpcAccountLocalLinkNewChallengeResponseError{Code: pb.RpcAccountLocalLinkNewChallengeResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("POST", "/v1/auth/displayCode", nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
var response AuthDisplayCodeResponse
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "mocked-challenge-id", response.ChallengeId)
|
||||
})
|
||||
|
||||
t.Run("failed challenge creation", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkNewChallenge", mock.Anything, &pb.RpcAccountLocalLinkNewChallengeRequest{AppName: "api-test"}).
|
||||
Return(&pb.RpcAccountLocalLinkNewChallengeResponse{
|
||||
Error: &pb.RpcAccountLocalLinkNewChallengeResponseError{Code: pb.RpcAccountLocalLinkNewChallengeResponseError_UNKNOWN_ERROR},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("POST", "/v1/auth/displayCode", nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestApiServer_AuthTokenHandler(t *testing.T) {
|
||||
t.Run("successful token retrieval", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
|
||||
challengeId := "mocked-challenge-id"
|
||||
code := "mocked-code"
|
||||
sessionToken := "mocked-session-token"
|
||||
appKey := "mocked-app-key"
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkSolveChallenge", mock.Anything, &pb.RpcAccountLocalLinkSolveChallengeRequest{
|
||||
ChallengeId: challengeId,
|
||||
Answer: code,
|
||||
}).
|
||||
Return(&pb.RpcAccountLocalLinkSolveChallengeResponse{
|
||||
SessionToken: sessionToken,
|
||||
AppKey: appKey,
|
||||
Error: &pb.RpcAccountLocalLinkSolveChallengeResponseError{Code: pb.RpcAccountLocalLinkSolveChallengeResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", "/v1/auth/token?challenge_id="+challengeId+"&code="+code, nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
var response AuthTokenResponse
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, sessionToken, response.SessionToken)
|
||||
require.Equal(t, appKey, response.AppKey)
|
||||
})
|
||||
|
||||
t.Run("bad request", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", "/v1/auth/token", nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusBadRequest, w.Code)
|
||||
})
|
||||
|
||||
t.Run("failed token retrieval", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
challengeId := "mocked-challenge-id"
|
||||
code := "mocked-code"
|
||||
|
||||
fx.mwMock.On("AccountLocalLinkSolveChallenge", mock.Anything, &pb.RpcAccountLocalLinkSolveChallengeRequest{
|
||||
ChallengeId: challengeId,
|
||||
Answer: code,
|
||||
}).
|
||||
Return(&pb.RpcAccountLocalLinkSolveChallengeResponse{
|
||||
Error: &pb.RpcAccountLocalLinkSolveChallengeResponseError{Code: pb.RpcAccountLocalLinkSolveChallengeResponseError_UNKNOWN_ERROR},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", "/v1/auth/token?challenge_id="+challengeId+"&code="+code, nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestApiServer_GetSpacesHandler(t *testing.T) {
|
||||
t.Run("successful retrieval of spaces", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
fx.accountInfo = &model.AccountInfo{TechSpaceId: techSpaceId, GatewayUrl: gatewayUrl}
|
||||
|
||||
fx.mwMock.On("ObjectSearch", mock.Anything, &pb.RpcObjectSearchRequest{
|
||||
SpaceId: techSpaceId,
|
||||
Filters: []*model.BlockContentDataviewFilter{
|
||||
{
|
||||
RelationKey: bundle.RelationKeyLayout.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Int64(int64(model.ObjectType_spaceView)),
|
||||
},
|
||||
{
|
||||
RelationKey: bundle.RelationKeySpaceLocalStatus.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Int64(int64(model.SpaceStatus_Ok)),
|
||||
},
|
||||
{
|
||||
RelationKey: bundle.RelationKeySpaceRemoteStatus.String(),
|
||||
Condition: model.BlockContentDataviewFilter_Equal,
|
||||
Value: pbtypes.Int64(int64(model.SpaceStatus_Ok)),
|
||||
},
|
||||
},
|
||||
Sorts: []*model.BlockContentDataviewSort{
|
||||
{
|
||||
RelationKey: "spaceOrder",
|
||||
Type: model.BlockContentDataviewSort_Asc,
|
||||
NoCollate: true,
|
||||
EmptyPlacement: model.BlockContentDataviewSort_End,
|
||||
},
|
||||
},
|
||||
Keys: []string{"targetSpaceId", "name", "iconEmoji", "iconImage"},
|
||||
}).Return(&pb.RpcObjectSearchResponse{
|
||||
Records: []*types.Struct{
|
||||
{
|
||||
Fields: map[string]*types.Value{
|
||||
"name": pbtypes.String("Another Workspace"),
|
||||
"targetSpaceId": pbtypes.String("another-space-id"),
|
||||
"iconEmoji": pbtypes.String(""),
|
||||
"iconImage": pbtypes.String(iconImage),
|
||||
},
|
||||
},
|
||||
{
|
||||
Fields: map[string]*types.Value{
|
||||
"name": pbtypes.String("My Workspace"),
|
||||
"targetSpaceId": pbtypes.String("my-space-id"),
|
||||
"iconEmoji": pbtypes.String("🚀"),
|
||||
"iconImage": pbtypes.String(""),
|
||||
},
|
||||
},
|
||||
},
|
||||
Error: &pb.RpcObjectSearchResponseError{Code: pb.RpcObjectSearchResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
fx.mwMock.On("WorkspaceOpen", mock.Anything, mock.Anything).Return(&pb.RpcWorkspaceOpenResponse{
|
||||
Error: &pb.RpcWorkspaceOpenResponseError{Code: pb.RpcWorkspaceOpenResponseError_NULL},
|
||||
Info: &model.AccountInfo{
|
||||
HomeObjectId: "home-object-id",
|
||||
ArchiveObjectId: "archive-object-id",
|
||||
ProfileObjectId: "profile-object-id",
|
||||
MarketplaceWorkspaceId: "marketplace-workspace-id",
|
||||
WorkspaceObjectId: "workspace-object-id",
|
||||
DeviceId: "device-id",
|
||||
AccountSpaceId: "account-space-id",
|
||||
WidgetsId: "widgets-id",
|
||||
SpaceViewId: "space-view-id",
|
||||
TechSpaceId: "tech-space-id",
|
||||
GatewayUrl: "gateway-url",
|
||||
LocalStoragePath: "local-storage-path",
|
||||
TimeZone: "time-zone",
|
||||
AnalyticsId: "analytics-id",
|
||||
NetworkId: "network-id",
|
||||
},
|
||||
}, nil).Twice()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("/v1/spaces?offset=%d&limit=%d", offset, limit), nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
var response PaginatedResponse[Space]
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, response.Data, 2)
|
||||
require.Equal(t, "Another Workspace", response.Data[0].Name)
|
||||
require.Equal(t, "another-space-id", response.Data[0].Id)
|
||||
require.Regexpf(t, regexp.MustCompile(gatewayUrl+`/image/`+iconImage), response.Data[0].Icon, "Icon URL does not match")
|
||||
require.Equal(t, "My Workspace", response.Data[1].Name)
|
||||
require.Equal(t, "my-space-id", response.Data[1].Id)
|
||||
require.Equal(t, "🚀", response.Data[1].Icon)
|
||||
})
|
||||
|
||||
t.Run("no spaces found", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
fx.accountInfo = &model.AccountInfo{TechSpaceId: techSpaceId}
|
||||
|
||||
fx.mwMock.On("ObjectSearch", mock.Anything, mock.Anything).
|
||||
Return(&pb.RpcObjectSearchResponse{
|
||||
Records: []*types.Struct{},
|
||||
Error: &pb.RpcObjectSearchResponseError{Code: pb.RpcObjectSearchResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("/v1/spaces?offset=%d&limit=%d", offset, limit), nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusNotFound, w.Code)
|
||||
})
|
||||
|
||||
t.Run("failed workspace open", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
fx.accountInfo = &model.AccountInfo{TechSpaceId: techSpaceId}
|
||||
|
||||
fx.mwMock.On("ObjectSearch", mock.Anything, mock.Anything).
|
||||
Return(&pb.RpcObjectSearchResponse{
|
||||
Records: []*types.Struct{
|
||||
{
|
||||
Fields: map[string]*types.Value{
|
||||
"name": pbtypes.String("My Workspace"),
|
||||
"targetSpaceId": pbtypes.String("my-space-id"),
|
||||
"iconEmoji": pbtypes.String("🚀"),
|
||||
"iconImage": pbtypes.String(""),
|
||||
},
|
||||
},
|
||||
},
|
||||
Error: &pb.RpcObjectSearchResponseError{Code: pb.RpcObjectSearchResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
fx.mwMock.On("WorkspaceOpen", mock.Anything, mock.Anything).
|
||||
Return(&pb.RpcWorkspaceOpenResponse{
|
||||
Error: &pb.RpcWorkspaceOpenResponseError{Code: pb.RpcWorkspaceOpenResponseError_UNKNOWN_ERROR},
|
||||
}, nil).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("/v1/spaces?offset=%d&limit=%d", offset, limit), nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestApiServer_CreateSpaceHandler(t *testing.T) {
|
||||
t.Run("successful create space", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
fx.mwMock.On("WorkspaceCreate", mock.Anything, mock.Anything).
|
||||
Return(&pb.RpcWorkspaceCreateResponse{
|
||||
Error: &pb.RpcWorkspaceCreateResponseError{Code: pb.RpcWorkspaceCreateResponseError_NULL},
|
||||
SpaceId: "new-space-id",
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
body := strings.NewReader(`{"name":"New Space"}`)
|
||||
req, _ := http.NewRequest("POST", "/v1/spaces", body)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
require.Contains(t, w.Body.String(), "new-space-id")
|
||||
})
|
||||
|
||||
t.Run("invalid JSON", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
|
||||
// when
|
||||
body := strings.NewReader(`{invalid json}`)
|
||||
req, _ := http.NewRequest("POST", "/v1/spaces", body)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusBadRequest, w.Code)
|
||||
})
|
||||
|
||||
t.Run("failed workspace creation", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
fx.mwMock.On("WorkspaceCreate", mock.Anything, mock.Anything).
|
||||
Return(&pb.RpcWorkspaceCreateResponse{
|
||||
Error: &pb.RpcWorkspaceCreateResponseError{Code: pb.RpcWorkspaceCreateResponseError_UNKNOWN_ERROR},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
body := strings.NewReader(`{"name":"Fail Space"}`)
|
||||
req, _ := http.NewRequest("POST", "/v1/spaces", body)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusInternalServerError, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestApiServer_GetMembersHandler(t *testing.T) {
|
||||
t.Run("successfully get members", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
fx.accountInfo = &model.AccountInfo{TechSpaceId: techSpaceId, GatewayUrl: gatewayUrl}
|
||||
|
||||
fx.mwMock.On("ObjectSearch", mock.Anything, mock.Anything).
|
||||
Return(&pb.RpcObjectSearchResponse{
|
||||
Records: []*types.Struct{
|
||||
{
|
||||
Fields: map[string]*types.Value{
|
||||
"id": pbtypes.String("member-1"),
|
||||
"name": pbtypes.String("John Doe"),
|
||||
"iconEmoji": pbtypes.String("👤"),
|
||||
"identity": pbtypes.String("AAjEaEwPF4nkEh7AWkqEnzcQ8HziGB4ETjiTpvRCQvWnSMDZ"),
|
||||
"globalName": pbtypes.String("john.any"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Fields: map[string]*types.Value{
|
||||
"id": pbtypes.String("member-2"),
|
||||
"name": pbtypes.String("Jane Doe"),
|
||||
"iconImage": pbtypes.String(iconImage),
|
||||
"identity": pbtypes.String("AAjLbEwPF4nkEh7AWkqEnzcQ8HziGB4ETjiTpvRCQvWnSMD4"),
|
||||
"globalName": pbtypes.String("jane.any"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Error: &pb.RpcObjectSearchResponseError{Code: pb.RpcObjectSearchResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("/v1/spaces/my-space/members?offset=%d&limit=%d", offset, limit), nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusOK, w.Code)
|
||||
|
||||
var response PaginatedResponse[Member]
|
||||
err := json.Unmarshal(w.Body.Bytes(), &response)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, response.Data, 2)
|
||||
require.Equal(t, "member-1", response.Data[0].Id)
|
||||
require.Equal(t, "John Doe", response.Data[0].Name)
|
||||
require.Equal(t, "👤", response.Data[0].Icon)
|
||||
require.Equal(t, "john.any", response.Data[0].GlobalName)
|
||||
require.Equal(t, "member-2", response.Data[1].Id)
|
||||
require.Equal(t, "Jane Doe", response.Data[1].Name)
|
||||
require.Regexpf(t, regexp.MustCompile(gatewayUrl+`/image/`+iconImage), response.Data[1].Icon, "Icon URL does not match")
|
||||
require.Equal(t, "jane.any", response.Data[1].GlobalName)
|
||||
})
|
||||
|
||||
t.Run("no members found", func(t *testing.T) {
|
||||
// given
|
||||
fx := newFixture(t)
|
||||
|
||||
fx.mwMock.On("ObjectSearch", mock.Anything, mock.Anything).
|
||||
Return(&pb.RpcObjectSearchResponse{
|
||||
Records: []*types.Struct{},
|
||||
Error: &pb.RpcObjectSearchResponseError{Code: pb.RpcObjectSearchResponseError_NULL},
|
||||
}).Once()
|
||||
|
||||
// when
|
||||
req, _ := http.NewRequest("GET", fmt.Sprintf("/v1/spaces/empty-space/members?offset=%d&limit=%d", offset, limit), nil)
|
||||
w := httptest.NewRecorder()
|
||||
fx.router.ServeHTTP(w, req)
|
||||
|
||||
// then
|
||||
require.Equal(t, http.StatusNotFound, w.Code)
|
||||
})
|
||||
}
|
||||
|
||||
func TestApiServer_GetObjectsForSpaceHandler(t *testing.T) {
|
||||
t.Run("successfully get objects for a space", func(t *testing.T) {
|
||||
// given
|
||||
|
|
|
@ -31,7 +31,11 @@ type fixture struct {
|
|||
|
||||
func newFixture(t *testing.T) *fixture {
|
||||
mw := mock_service.NewMockClientCommandsServer(t)
|
||||
spaceService := &SpaceService{mw: mw, AccountInfo: &model.AccountInfo{TechSpaceId: techSpaceId, GatewayUrl: gatewayUrl}}
|
||||
spaceService := NewService(mw)
|
||||
spaceService.AccountInfo = &model.AccountInfo{
|
||||
TechSpaceId: techSpaceId,
|
||||
GatewayUrl: gatewayUrl,
|
||||
}
|
||||
|
||||
return &fixture{
|
||||
SpaceService: spaceService,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue