| package admin |
|
|
| import ( |
| "bytes" |
| "context" |
| "encoding/json" |
| "errors" |
| "net/http" |
| "net/http/httptest" |
| "testing" |
|
|
| infraerrors "github.com/Wei-Shaw/sub2api/internal/pkg/errors" |
| "github.com/Wei-Shaw/sub2api/internal/service" |
| "github.com/gin-gonic/gin" |
| "github.com/stretchr/testify/require" |
| ) |
|
|
| func setupAPIKeyHandler(adminSvc service.AdminService) *gin.Engine { |
| gin.SetMode(gin.TestMode) |
| router := gin.New() |
| h := NewAdminAPIKeyHandler(adminSvc) |
| router.PUT("/api/v1/admin/api-keys/:id", h.UpdateGroup) |
| return router |
| } |
|
|
| func TestAdminAPIKeyHandler_UpdateGroup_InvalidID(t *testing.T) { |
| router := setupAPIKeyHandler(newStubAdminService()) |
| body := `{"group_id": 2}` |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/abc", bytes.NewBufferString(body)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusBadRequest, rec.Code) |
| require.Contains(t, rec.Body.String(), "Invalid API key ID") |
| } |
|
|
| func TestAdminAPIKeyHandler_UpdateGroup_InvalidJSON(t *testing.T) { |
| router := setupAPIKeyHandler(newStubAdminService()) |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/10", bytes.NewBufferString(`{bad json`)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusBadRequest, rec.Code) |
| require.Contains(t, rec.Body.String(), "Invalid request") |
| } |
|
|
| func TestAdminAPIKeyHandler_UpdateGroup_KeyNotFound(t *testing.T) { |
| router := setupAPIKeyHandler(newStubAdminService()) |
| body := `{"group_id": 2}` |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/999", bytes.NewBufferString(body)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| |
| require.Equal(t, http.StatusNotFound, rec.Code) |
| } |
|
|
| func TestAdminAPIKeyHandler_UpdateGroup_BindGroup(t *testing.T) { |
| router := setupAPIKeyHandler(newStubAdminService()) |
| body := `{"group_id": 2}` |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/10", bytes.NewBufferString(body)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusOK, rec.Code) |
|
|
| var resp struct { |
| Code int `json:"code"` |
| Data json.RawMessage `json:"data"` |
| } |
| require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp)) |
| require.Equal(t, 0, resp.Code) |
|
|
| var data struct { |
| APIKey struct { |
| ID int64 `json:"id"` |
| GroupID *int64 `json:"group_id"` |
| } `json:"api_key"` |
| AutoGrantedGroupAccess bool `json:"auto_granted_group_access"` |
| } |
| require.NoError(t, json.Unmarshal(resp.Data, &data)) |
| require.Equal(t, int64(10), data.APIKey.ID) |
| require.NotNil(t, data.APIKey.GroupID) |
| require.Equal(t, int64(2), *data.APIKey.GroupID) |
| } |
|
|
| func TestAdminAPIKeyHandler_UpdateGroup_Unbind(t *testing.T) { |
| svc := newStubAdminService() |
| gid := int64(2) |
| svc.apiKeys[0].GroupID = &gid |
| router := setupAPIKeyHandler(svc) |
| body := `{"group_id": 0}` |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/10", bytes.NewBufferString(body)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusOK, rec.Code) |
|
|
| var resp struct { |
| Data struct { |
| APIKey struct { |
| GroupID *int64 `json:"group_id"` |
| } `json:"api_key"` |
| } `json:"data"` |
| } |
| require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp)) |
| require.Nil(t, resp.Data.APIKey.GroupID) |
| } |
|
|
| func TestAdminAPIKeyHandler_UpdateGroup_ServiceError(t *testing.T) { |
| svc := &failingUpdateGroupService{ |
| stubAdminService: newStubAdminService(), |
| err: errors.New("internal failure"), |
| } |
| router := setupAPIKeyHandler(svc) |
| body := `{"group_id": 2}` |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/10", bytes.NewBufferString(body)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusInternalServerError, rec.Code) |
| } |
|
|
| |
| func TestAdminAPIKeyHandler_UpdateGroup_EmptyBody_NoChange(t *testing.T) { |
| router := setupAPIKeyHandler(newStubAdminService()) |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/10", bytes.NewBufferString(`{}`)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusOK, rec.Code) |
|
|
| var resp struct { |
| Code int `json:"code"` |
| Data struct { |
| APIKey struct { |
| ID int64 `json:"id"` |
| } `json:"api_key"` |
| } `json:"data"` |
| } |
| require.NoError(t, json.Unmarshal(rec.Body.Bytes(), &resp)) |
| require.Equal(t, 0, resp.Code) |
| require.Equal(t, int64(10), resp.Data.APIKey.ID) |
| } |
|
|
| |
| func TestAdminAPIKeyHandler_UpdateGroup_GroupNotActive(t *testing.T) { |
| svc := &failingUpdateGroupService{ |
| stubAdminService: newStubAdminService(), |
| err: infraerrors.BadRequest("GROUP_NOT_ACTIVE", "target group is not active"), |
| } |
| router := setupAPIKeyHandler(svc) |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/10", bytes.NewBufferString(`{"group_id": 5}`)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusBadRequest, rec.Code) |
| require.Contains(t, rec.Body.String(), "GROUP_NOT_ACTIVE") |
| } |
|
|
| |
| func TestAdminAPIKeyHandler_UpdateGroup_NegativeGroupID(t *testing.T) { |
| svc := &failingUpdateGroupService{ |
| stubAdminService: newStubAdminService(), |
| err: infraerrors.BadRequest("INVALID_GROUP_ID", "group_id must be non-negative"), |
| } |
| router := setupAPIKeyHandler(svc) |
|
|
| rec := httptest.NewRecorder() |
| req := httptest.NewRequest(http.MethodPut, "/api/v1/admin/api-keys/10", bytes.NewBufferString(`{"group_id": -5}`)) |
| req.Header.Set("Content-Type", "application/json") |
| router.ServeHTTP(rec, req) |
|
|
| require.Equal(t, http.StatusBadRequest, rec.Code) |
| require.Contains(t, rec.Body.String(), "INVALID_GROUP_ID") |
| } |
|
|
| |
| type failingUpdateGroupService struct { |
| *stubAdminService |
| err error |
| } |
|
|
| func (f *failingUpdateGroupService) AdminUpdateAPIKeyGroupID(_ context.Context, _ int64, _ *int64) (*service.AdminUpdateAPIKeyGroupIDResult, error) { |
| return nil, f.err |
| } |
|
|