Skip to content

Commit 8ed4fba

Browse files
committed
feat: migrate GetProjectResource API to Connect RPC
1 parent 232c72d commit 8ed4fba

File tree

2 files changed

+123
-0
lines changed

2 files changed

+123
-0
lines changed

internal/api/v1beta1connect/resource.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,29 @@ func (h *ConnectHandler) CreateProjectResource(ctx context.Context, request *con
124124
}), nil
125125
}
126126

127+
func (h *ConnectHandler) GetProjectResource(ctx context.Context, request *connect.Request[frontierv1beta1.GetProjectResourceRequest]) (*connect.Response[frontierv1beta1.GetProjectResourceResponse], error) {
128+
fetchedResource, err := h.resourceService.Get(ctx, request.Msg.GetId())
129+
if err != nil {
130+
switch {
131+
case errors.Is(err, resource.ErrNotExist),
132+
errors.Is(err, resource.ErrInvalidUUID),
133+
errors.Is(err, resource.ErrInvalidID):
134+
return nil, connect.NewError(connect.CodeNotFound, ErrNotFound)
135+
default:
136+
return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError)
137+
}
138+
}
139+
140+
resourcePB, err := transformResourceToPB(fetchedResource)
141+
if err != nil {
142+
return nil, connect.NewError(connect.CodeInternal, ErrInternalServerError)
143+
}
144+
145+
return connect.NewResponse(&frontierv1beta1.GetProjectResourceResponse{
146+
Resource: resourcePB,
147+
}), nil
148+
}
149+
127150
func transformResourceToPB(from resource.Resource) (*frontierv1beta1.Resource, error) {
128151
var metadata *structpb.Struct
129152
var err error

internal/api/v1beta1connect/resource_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,3 +368,103 @@ func TestConnectHandler_CreateProjectResource(t *testing.T) {
368368
})
369369
}
370370
}
371+
372+
func TestConnectHandler_GetProjectResource(t *testing.T) {
373+
tests := []struct {
374+
name string
375+
setup func(rs *mocks.ResourceService)
376+
request *connect.Request[frontierv1beta1.GetProjectResourceRequest]
377+
want *connect.Response[frontierv1beta1.GetProjectResourceResponse]
378+
wantErr error
379+
}{
380+
{
381+
name: "should return internal error if resource service returns error",
382+
setup: func(rs *mocks.ResourceService) {
383+
rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), testResource.ID).Return(resource.Resource{}, errors.New("test error"))
384+
},
385+
request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{
386+
Id: testResource.ID,
387+
}),
388+
want: nil,
389+
wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError),
390+
},
391+
{
392+
name: "should return not found error if id is empty",
393+
setup: func(rs *mocks.ResourceService) {
394+
rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), "").Return(resource.Resource{}, resource.ErrInvalidID)
395+
},
396+
request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{}),
397+
want: nil,
398+
wantErr: connect.NewError(connect.CodeNotFound, ErrNotFound),
399+
},
400+
{
401+
name: "should return not found error if id is not uuid",
402+
setup: func(rs *mocks.ResourceService) {
403+
rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), "some-id").Return(resource.Resource{}, resource.ErrInvalidUUID)
404+
},
405+
request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{
406+
Id: "some-id",
407+
}),
408+
want: nil,
409+
wantErr: connect.NewError(connect.CodeNotFound, ErrNotFound),
410+
},
411+
{
412+
name: "should return not found error if resource not exist",
413+
setup: func(rs *mocks.ResourceService) {
414+
rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), testResource.ID).Return(resource.Resource{}, resource.ErrNotExist)
415+
},
416+
request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{
417+
Id: testResource.ID,
418+
}),
419+
want: nil,
420+
wantErr: connect.NewError(connect.CodeNotFound, ErrNotFound),
421+
},
422+
{
423+
name: "should return success if resource service returns resource",
424+
setup: func(rs *mocks.ResourceService) {
425+
rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), testResource.ID).Return(testResource, nil)
426+
},
427+
request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{
428+
Id: testResource.ID,
429+
}),
430+
want: connect.NewResponse(&frontierv1beta1.GetProjectResourceResponse{
431+
Resource: testResourcePB,
432+
}),
433+
wantErr: nil,
434+
},
435+
{
436+
name: "should return internal error if transform fails",
437+
setup: func(rs *mocks.ResourceService) {
438+
invalidResource := testResource
439+
invalidResource.Metadata = map[string]interface{}{
440+
"invalid": func() {}, // functions can't be marshaled
441+
}
442+
rs.EXPECT().Get(mock.AnythingOfType("context.backgroundCtx"), testResource.ID).Return(invalidResource, nil)
443+
},
444+
request: connect.NewRequest(&frontierv1beta1.GetProjectResourceRequest{
445+
Id: testResource.ID,
446+
}),
447+
want: nil,
448+
wantErr: connect.NewError(connect.CodeInternal, ErrInternalServerError),
449+
},
450+
}
451+
452+
for _, tt := range tests {
453+
t.Run(tt.name, func(t *testing.T) {
454+
mockResourceSrv := new(mocks.ResourceService)
455+
if tt.setup != nil {
456+
tt.setup(mockResourceSrv)
457+
}
458+
h := ConnectHandler{resourceService: mockResourceSrv}
459+
resp, err := h.GetProjectResource(context.Background(), tt.request)
460+
if tt.wantErr != nil {
461+
assert.Error(t, err)
462+
assert.Equal(t, tt.wantErr.(*connect.Error).Code(), err.(*connect.Error).Code())
463+
assert.Equal(t, tt.wantErr.(*connect.Error).Message(), err.(*connect.Error).Message())
464+
} else {
465+
assert.NoError(t, err)
466+
assert.EqualValues(t, tt.want, resp)
467+
}
468+
})
469+
}
470+
}

0 commit comments

Comments
 (0)