Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cla-backend-go/v2/company/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/linuxfoundation/easycla/cla-backend-go/gen/v2/restapi/operations/company"
"github.com/linuxfoundation/easycla/cla-backend-go/utils"
"github.com/linuxfoundation/easycla/cla-backend-go/v2/organization-service/client/organizations"
v2ProjectServiceClient "github.com/linuxfoundation/easycla/cla-backend-go/v2/project-service/client/project"
)

// Configure sets up the middleware handlers
Expand Down Expand Up @@ -181,6 +182,13 @@ func Configure(api *operations.EasyclaAPI, service Service, projectClaGroupRepo

result, err := service.GetCompanyProjectCLAManagers(ctx, v2CompanyModel, params.ProjectSFID)
if err != nil {
var projectNotFound *v2ProjectServiceClient.GetProjectNotFound
if errors.As(err, &projectNotFound) {
msg := fmt.Sprintf("project not found in the project service: %s", params.ProjectSFID)
log.WithFields(f).WithError(err).Warn(msg)
return company.NewGetCompanyProjectClaManagersNotFound().WithXRequestID(reqID).WithPayload(utils.ErrorResponseNotFound(reqID, msg))
}

msg := "unable to load company project CLA managers"
log.WithFields(f).WithError(err).Warn(msg)
return company.NewGetCompanyProjectClaManagersBadRequest().WithXRequestID(reqID).WithPayload(
Expand Down
104 changes: 103 additions & 1 deletion cla-backend-go/v2/company/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/http/httptest"
"testing"
Expand All @@ -16,15 +17,37 @@ import (
"github.com/linuxfoundation/easycla/cla-backend-go/gen/v2/models"
"github.com/linuxfoundation/easycla/cla-backend-go/gen/v2/restapi/operations"
v2CompanyOps "github.com/linuxfoundation/easycla/cla-backend-go/gen/v2/restapi/operations/company"
v2ProjectServiceClient "github.com/linuxfoundation/easycla/cla-backend-go/v2/project-service/client/project"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const (
testCompanySFID = "0014100000Te0000AAE"
testOtherCompanySFID = "0014100000Te0000AAB"
)

type fakeCompanyService struct {
Service
result *models.CompanyClaGroups
err error
calls int

company *models.Company
claManagersErr error
claManagerCalls int
}

func (f *fakeCompanyService) GetCompanyByID(_ context.Context, _ string) (*models.Company, error) {
return f.company, nil
}

func (f *fakeCompanyService) GetCompanyProjectCLAManagers(_ context.Context, _ *models.Company, _ string) (*models.CompanyClaManagers, error) {
f.claManagerCalls++
if f.claManagersErr != nil {
return nil, f.claManagersErr
}
return &models.CompanyClaManagers{List: make([]*models.CompanyClaManager, 0)}, nil
}

func (f *fakeCompanyService) GetCompanyClaGroups(_ context.Context, companySFID string, _, _ *int64) (*models.CompanyClaGroups, error) {
Expand All @@ -51,7 +74,7 @@ func respond(t *testing.T, api *operations.EasyclaAPI, companySFID string, authU
}

func TestGetCompanyClaGroupsHandler(t *testing.T) {
companySFID := "0014100000Te0000AAE"
companySFID := testCompanySFID

testCases := []struct {
name string
Expand Down Expand Up @@ -118,3 +141,82 @@ func TestGetCompanyClaGroupsHandler(t *testing.T) {
})
}
}

func respondProjectClaManagers(t *testing.T, api *operations.EasyclaAPI, companyID, projectSFID string, authUser *auth.User) int {
t.Helper()
require.NotNil(t, api.CompanyGetCompanyProjectClaManagersHandler)
responder := api.CompanyGetCompanyProjectClaManagersHandler.Handle(v2CompanyOps.GetCompanyProjectClaManagersParams{
HTTPRequest: httptest.NewRequest(http.MethodGet, "/v4/company/"+companyID+"/project/"+projectSFID+"/cla-managers", nil),
CompanyID: companyID,
ProjectSFID: projectSFID,
}, authUser)
recorder := httptest.NewRecorder()
responder.WriteResponse(recorder, runtime.JSONProducer())
return recorder.Code
}

func TestGetCompanyProjectClaManagersHandler(t *testing.T) {
companyID := "company-uuid-1"
companySFID := testCompanySFID
projectSFID := "project-sfid-1"
orgUser := &auth.User{UserName: "org-user", ACL: auth.ACL{Allowed: true, Scopes: []auth.Scope{{Type: auth.Organization, ID: companySFID}}}}

testCases := []struct {
name string
authUser *auth.User
serviceErr error
expectedStatus int
expectedCalls int
}{
{
name: "success",
authUser: orgUser,
expectedStatus: http.StatusOK,
expectedCalls: 1,
},
{
name: "project missing from the project service",
authUser: orgUser,
serviceErr: v2ProjectServiceClient.NewGetProjectNotFound(),
expectedStatus: http.StatusNotFound,
expectedCalls: 1,
},
{
name: "wrapped project not found",
authUser: orgUser,
serviceErr: fmt.Errorf("loading CLA groups: %w", v2ProjectServiceClient.NewGetProjectNotFound()),
expectedStatus: http.StatusNotFound,
expectedCalls: 1,
},
{
name: "any other service failure",
authUser: orgUser,
serviceErr: errors.New("dynamodb failure"),
expectedStatus: http.StatusBadRequest,
expectedCalls: 1,
},
{
name: "permission check runs before the project lookup",
authUser: &auth.User{UserName: "other-user", ACL: auth.ACL{Allowed: true, Scopes: []auth.Scope{{Type: auth.Organization, ID: testOtherCompanySFID}}}},
serviceErr: v2ProjectServiceClient.NewGetProjectNotFound(),
expectedStatus: http.StatusForbidden,
expectedCalls: 0,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
api := operations.NewEasyclaAPI(nil)
service := &fakeCompanyService{
company: &models.Company{CompanyID: companyID, CompanyExternalID: companySFID},
claManagersErr: tc.serviceErr,
}
Configure(api, service, nil, "")

status := respondProjectClaManagers(t, api, companyID, projectSFID, tc.authUser)

assert.Equal(t, tc.expectedStatus, status)
assert.Equal(t, tc.expectedCalls, service.claManagerCalls)
})
}
}
Loading