From c4131a9122c9cb08f02f2138baeb3065bd4f4209 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Dec 2025 12:36:24 +0000 Subject: [PATCH 1/4] Initial plan From 3c80ddd349b1a9339c5c438a408f46f3cdbed3ba Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Dec 2025 12:44:46 +0000 Subject: [PATCH 2/4] Implement language management routes with GET and PATCH endpoints Co-authored-by: HermanPlay <78978614+HermanPlay@users.noreply.github.com> --- .../api/http/routes/languages_management.go | 120 ++++++++++ .../http/routes/languages_management_test.go | 208 ++++++++++++++++++ internal/api/http/server/server.go | 5 + internal/initialization/initialization.go | 43 ++-- package/domain/schemas/language_config.go | 1 + package/service/language_service.go | 49 +++++ package/service/mocks/mockgen.go | 14 ++ 7 files changed, 420 insertions(+), 20 deletions(-) create mode 100644 internal/api/http/routes/languages_management.go create mode 100644 internal/api/http/routes/languages_management_test.go diff --git a/internal/api/http/routes/languages_management.go b/internal/api/http/routes/languages_management.go new file mode 100644 index 00000000..1288bd8b --- /dev/null +++ b/internal/api/http/routes/languages_management.go @@ -0,0 +1,120 @@ +package routes + +import ( + "net/http" + "strconv" + + "github.com/gorilla/mux" + "github.com/mini-maxit/backend/internal/api/http/httputils" + "github.com/mini-maxit/backend/package/service" + "github.com/mini-maxit/backend/package/utils" + "go.uber.org/zap" +) + +type LanguagesManagementRoute interface { + GetAllLanguages(w http.ResponseWriter, r *http.Request) + ToggleLanguageVisibility(w http.ResponseWriter, r *http.Request) +} + +type languagesManagementRoute struct { + languageService service.LanguageService + logger *zap.SugaredLogger +} + +// GetAllLanguages godoc +// +// @Tags languages-management +// @Summary Get all languages +// @Description Get all language configurations +// @Produce json +// @Failure 500 {object} httputils.APIError +// @Success 200 {object} httputils.APIResponse[[]schemas.LanguageConfig] +// @Router /languages-management/languages [get] +func (lr *languagesManagementRoute) GetAllLanguages(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + httputils.ReturnError(w, http.StatusMethodNotAllowed, "Method not allowed") + return + } + + db := httputils.GetDatabase(r) + + languages, err := lr.languageService.GetAll(db) + if err != nil { + httputils.HandleServiceError(w, err, db, lr.logger) + return + } + + httputils.ReturnSuccess(w, http.StatusOK, languages) +} + +// ToggleLanguageVisibility godoc +// +// @Tags languages-management +// @Summary Toggle language visibility +// @Description Toggle the visibility (enabled/disabled) state of a language +// @Produce json +// @Param id path int true "Language ID" +// @Failure 400 {object} httputils.APIError +// @Failure 404 {object} httputils.APIError +// @Failure 500 {object} httputils.APIError +// @Success 200 {object} httputils.APIResponse[httputils.MessageResponse] +// @Router /languages-management/languages/{id} [patch] +func (lr *languagesManagementRoute) ToggleLanguageVisibility(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPatch { + httputils.ReturnError(w, http.StatusMethodNotAllowed, "Method not allowed") + return + } + + languageIDStr := httputils.GetPathValue(r, "id") + if languageIDStr == "" { + httputils.ReturnError(w, http.StatusBadRequest, "Language ID is required.") + return + } + + languageID, err := strconv.ParseInt(languageIDStr, 10, 64) + if err != nil { + httputils.ReturnError(w, http.StatusBadRequest, "Invalid language ID.") + return + } + + db := httputils.GetDatabase(r) + + err = lr.languageService.ToggleLanguageVisibility(db, languageID) + if err != nil { + httputils.HandleServiceError(w, err, db, lr.logger) + return + } + + httputils.ReturnSuccess(w, http.StatusOK, httputils.NewMessageResponse("Language visibility toggled successfully")) +} + +func NewLanguagesManagementRoute(languageService service.LanguageService) LanguagesManagementRoute { + route := &languagesManagementRoute{ + languageService: languageService, + logger: utils.NewNamedLogger("languages-management-route"), + } + + if err := utils.ValidateStruct(*route); err != nil { + panic(err) + } + return route +} + +func RegisterLanguagesManagementRoutes(mux *mux.Router, route LanguagesManagementRoute) { + mux.HandleFunc("/languages", func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodGet: + route.GetAllLanguages(w, r) + default: + httputils.ReturnError(w, http.StatusMethodNotAllowed, "Method not allowed") + } + }) + mux.HandleFunc("/languages/{id}", func(w http.ResponseWriter, r *http.Request) { + switch r.Method { + case http.MethodPatch: + route.ToggleLanguageVisibility(w, r) + default: + httputils.ReturnError(w, http.StatusMethodNotAllowed, "Method not allowed") + } + }) +} diff --git a/internal/api/http/routes/languages_management_test.go b/internal/api/http/routes/languages_management_test.go new file mode 100644 index 00000000..a1e2651f --- /dev/null +++ b/internal/api/http/routes/languages_management_test.go @@ -0,0 +1,208 @@ +package routes_test + +import ( + "context" + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/gorilla/mux" + "github.com/mini-maxit/backend/internal/api/http/httputils" + "github.com/mini-maxit/backend/internal/api/http/routes" + "github.com/mini-maxit/backend/internal/testutils" + "github.com/mini-maxit/backend/package/domain/schemas" + "github.com/mini-maxit/backend/package/errors" + mock_service "github.com/mini-maxit/backend/package/service/mocks" + "github.com/stretchr/testify/assert" + "go.uber.org/mock/gomock" +) + +func TestGetAllLanguages(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ls := mock_service.NewMockLanguageService(ctrl) + route := routes.NewLanguagesManagementRoute(ls) + db := &testutils.MockDatabase{} + + router := mux.NewRouter() + router.HandleFunc("/languages", func(w http.ResponseWriter, r *http.Request) { + route.GetAllLanguages(w, r) + }) + + handler := httputils.MockDatabaseMiddleware(router, db) + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mockUser := schemas.User{ + ID: 1, + Role: "admin", + Email: "test@example.com", + } + ctx := context.WithValue(r.Context(), httputils.UserKey, mockUser) + handler.ServeHTTP(w, r.WithContext(ctx)) + })) + defer server.Close() + + t.Run("Accept only GET", func(t *testing.T) { + methods := []string{http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete} + + for _, method := range methods { + req, err := http.NewRequest(method, server.URL+"/languages", nil) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + defer resp.Body.Close() + + assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode) + } + }) + + t.Run("Success", func(t *testing.T) { + expectedLanguages := []schemas.LanguageConfig{ + {ID: 1, Type: "C", Version: "11", FileExtension: ".c", IsDisabled: false}, + {ID: 2, Type: "C++", Version: "17", FileExtension: ".cpp", IsDisabled: false}, + } + + ls.EXPECT().GetAll(gomock.Any()).Return(expectedLanguages, nil) + + req, err := http.NewRequest(http.MethodGet, server.URL+"/languages", nil) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + defer resp.Body.Close() + + assert.Equal(t, http.StatusOK, resp.StatusCode) + + var apiResponse httputils.APIResponse[[]schemas.LanguageConfig] + err = json.NewDecoder(resp.Body).Decode(&apiResponse) + if err != nil { + t.Fatalf("Failed to decode response: %v", err) + } + + assert.Equal(t, expectedLanguages, apiResponse.Data) + }) + + t.Run("Service error", func(t *testing.T) { + ls.EXPECT().GetAll(gomock.Any()).Return(nil, assert.AnError) + + req, err := http.NewRequest(http.MethodGet, server.URL+"/languages", nil) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + defer resp.Body.Close() + + assert.Equal(t, http.StatusInternalServerError, resp.StatusCode) + }) +} + +func TestToggleLanguageVisibility(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + ls := mock_service.NewMockLanguageService(ctrl) + route := routes.NewLanguagesManagementRoute(ls) + db := &testutils.MockDatabase{} + + router := mux.NewRouter() + router.HandleFunc("/languages/{id}", func(w http.ResponseWriter, r *http.Request) { + route.ToggleLanguageVisibility(w, r) + }) + + handler := httputils.MockDatabaseMiddleware(router, db) + + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + mockUser := schemas.User{ + ID: 1, + Role: "admin", + Email: "test@example.com", + } + ctx := context.WithValue(r.Context(), httputils.UserKey, mockUser) + handler.ServeHTTP(w, r.WithContext(ctx)) + })) + defer server.Close() + + t.Run("Accept only PATCH", func(t *testing.T) { + methods := []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete} + + for _, method := range methods { + req, err := http.NewRequest(method, server.URL+"/languages/1", nil) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + defer resp.Body.Close() + + assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode) + } + }) + + t.Run("Invalid language ID", func(t *testing.T) { + req, err := http.NewRequest(http.MethodPatch, server.URL+"/languages/invalid", nil) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + defer resp.Body.Close() + + assert.Equal(t, http.StatusBadRequest, resp.StatusCode) + }) + + t.Run("Language not found", func(t *testing.T) { + ls.EXPECT().ToggleLanguageVisibility(gomock.Any(), int64(999)).Return(errors.ErrNotFound) + + req, err := http.NewRequest(http.MethodPatch, server.URL+"/languages/999", nil) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + defer resp.Body.Close() + + assert.Equal(t, http.StatusNotFound, resp.StatusCode) + }) + + t.Run("Success", func(t *testing.T) { + ls.EXPECT().ToggleLanguageVisibility(gomock.Any(), int64(1)).Return(nil) + + req, err := http.NewRequest(http.MethodPatch, server.URL+"/languages/1", nil) + if err != nil { + t.Fatalf("Failed to create request: %v", err) + } + resp, err := http.DefaultClient.Do(req) + if err != nil { + t.Fatalf("Failed to make request: %v", err) + } + defer resp.Body.Close() + + assert.Equal(t, http.StatusOK, resp.StatusCode) + + var apiResponse httputils.APIResponse[httputils.MessageResponse] + err = json.NewDecoder(resp.Body).Decode(&apiResponse) + if err != nil { + t.Fatalf("Failed to decode response: %v", err) + } + + assert.Equal(t, "Language visibility toggled successfully", apiResponse.Data.Message) + }) +} diff --git a/internal/api/http/server/server.go b/internal/api/http/server/server.go index 75deeaa9..cb180e1e 100644 --- a/internal/api/http/server/server.go +++ b/internal/api/http/server/server.go @@ -93,6 +93,10 @@ func NewServer(init *initialization.Initialization, log *zap.SugaredLogger) *Ser contestManagementMux := mux.NewRouter() routes.RegisterContestsManagementRoute(contestManagementMux, init.ContestManagementRoute) + // Languages management routes + languagesManagementMux := mux.NewRouter() + routes.RegisterLanguagesManagementRoutes(languagesManagementMux, init.LanguagesManagementRoute) + // Worker routes workerMux := mux.NewRouter() routes.RegisterWorkerRoutes(workerMux, init.WorkerRoute) @@ -107,6 +111,7 @@ func NewServer(init *initialization.Initialization, log *zap.SugaredLogger) *Ser secureMux.PathPrefix("/groups-management/").Handler(http.StripPrefix("/groups-management", groupMux)) secureMux.PathPrefix("/contests-management/").Handler(http.StripPrefix("/contests-management", contestManagementMux)) secureMux.PathPrefix("/contests").Handler(contestMux) + secureMux.PathPrefix("/languages-management/").Handler(http.StripPrefix("/languages-management", languagesManagementMux)) secureMux.PathPrefix("/workers/").Handler(http.StripPrefix("/workers", workerMux)) // API routes diff --git a/internal/initialization/initialization.go b/internal/initialization/initialization.go index 0a055501..d491511f 100644 --- a/internal/initialization/initialization.go +++ b/internal/initialization/initialization.go @@ -24,16 +24,17 @@ type Initialization struct { JWTService service.JWTService QueueService service.QueueService - AuthRoute routes.AuthRoute - ContestRoute routes.ContestRoute - ContestManagementRoute routes.ContestsManagementRoute - GroupRoute routes.GroupRoute - SubmissionRoute routes.SubmissionRoutes - TaskRoute routes.TaskRoute - TaskManagementRoute routes.TasksManagementRoute - AccessControlRoute routes.AccessControlRoute - UserRoute routes.UserRoute - WorkerRoute routes.WorkerRoute + AuthRoute routes.AuthRoute + ContestRoute routes.ContestRoute + ContestManagementRoute routes.ContestsManagementRoute + GroupRoute routes.GroupRoute + SubmissionRoute routes.SubmissionRoutes + TaskRoute routes.TaskRoute + TaskManagementRoute routes.TasksManagementRoute + AccessControlRoute routes.AccessControlRoute + UserRoute routes.UserRoute + WorkerRoute routes.WorkerRoute + LanguagesManagementRoute routes.LanguagesManagementRoute QueueListener queue.Listener @@ -147,6 +148,7 @@ func NewInitialization(cfg *config.Config) *Initialization { accessControlRoute := routes.NewAccessControlRoute(accessControlService) userRoute := routes.NewUserRoute(userService) workerRoute := routes.NewWorkerRoute(workerService) + languagesManagementRoute := routes.NewLanguagesManagementRoute(langService) // Queue listener - uses the same queue client as queue service queueListener := queue.NewListener( @@ -171,16 +173,17 @@ func NewInitialization(cfg *config.Config) *Initialization { JWTService: jwtService, QueueService: queueService, - AuthRoute: authRoute, - ContestRoute: contestRoute, - ContestManagementRoute: contestManagementRoute, - GroupRoute: groupRoute, - SubmissionRoute: submissionRoute, - TaskRoute: taskRoute, - TaskManagementRoute: tasksManagementRoute, - AccessControlRoute: accessControlRoute, - UserRoute: userRoute, - WorkerRoute: workerRoute, + AuthRoute: authRoute, + ContestRoute: contestRoute, + ContestManagementRoute: contestManagementRoute, + GroupRoute: groupRoute, + SubmissionRoute: submissionRoute, + TaskRoute: taskRoute, + TaskManagementRoute: tasksManagementRoute, + AccessControlRoute: accessControlRoute, + UserRoute: userRoute, + WorkerRoute: workerRoute, + LanguagesManagementRoute: languagesManagementRoute, QueueListener: queueListener, } diff --git a/package/domain/schemas/language_config.go b/package/domain/schemas/language_config.go index 6dc9349b..8e56a248 100644 --- a/package/domain/schemas/language_config.go +++ b/package/domain/schemas/language_config.go @@ -5,4 +5,5 @@ type LanguageConfig struct { Type string `json:"language"` Version string `json:"version"` FileExtension string `json:"fileExtension"` + IsDisabled bool `json:"isDisabled"` } diff --git a/package/service/language_service.go b/package/service/language_service.go index 48a57fa3..65846ae9 100644 --- a/package/service/language_service.go +++ b/package/service/language_service.go @@ -4,6 +4,7 @@ import ( "github.com/mini-maxit/backend/internal/database" "github.com/mini-maxit/backend/package/domain/models" "github.com/mini-maxit/backend/package/domain/schemas" + "github.com/mini-maxit/backend/package/errors" "github.com/mini-maxit/backend/package/repository" "github.com/mini-maxit/backend/package/utils" "go.uber.org/zap" @@ -15,6 +16,8 @@ type LanguageService interface { GetAll(db database.Database) ([]schemas.LanguageConfig, error) // GetAllEnabled retrieves all enabled language configurations from the database. GetAllEnabled(db database.Database) ([]schemas.LanguageConfig, error) + // ToggleLanguageVisibility toggles the visibility (enabled/disabled) state of a language. + ToggleLanguageVisibility(db database.Database, languageID int64) error // Init initializes languages in the database // // It should be called during application initialization. @@ -102,12 +105,58 @@ func (l *languageService) GetAllEnabled(db database.Database) ([]schemas.Languag return result, nil } +func (l *languageService) ToggleLanguageVisibility(db database.Database, languageID int64) error { + // Get the language to check its current state + languages, err := l.languageRepository.GetAll(db) + if err != nil { + l.logger.Errorf("Error getting languages: %v", err.Error()) + return err + } + + var found bool + var currentlyDisabled bool + for _, lang := range languages { + if lang.ID == languageID { + found = true + if lang.IsDisabled != nil { + currentlyDisabled = *lang.IsDisabled + } + break + } + } + + if !found { + l.logger.Errorf("Language with ID %d not found", languageID) + return errors.ErrNotFound + } + + // Toggle the state + if currentlyDisabled { + err = l.languageRepository.MarkEnabled(db, languageID) + } else { + err = l.languageRepository.MarkDisabled(db, languageID) + } + + if err != nil { + l.logger.Errorf("Error toggling language visibility: %v", err.Error()) + return err + } + + l.logger.Infof("Language %d visibility toggled successfully", languageID) + return nil +} + func LanguageToSchema(language *models.LanguageConfig) *schemas.LanguageConfig { + isDisabled := false + if language.IsDisabled != nil { + isDisabled = *language.IsDisabled + } return &schemas.LanguageConfig{ ID: language.ID, Type: language.Type, Version: language.Version, FileExtension: language.FileExtension, + IsDisabled: isDisabled, } } diff --git a/package/service/mocks/mockgen.go b/package/service/mocks/mockgen.go index ace9165e..6e021b20 100644 --- a/package/service/mocks/mockgen.go +++ b/package/service/mocks/mockgen.go @@ -1546,6 +1546,20 @@ func (mr *MockLanguageServiceMockRecorder) Init(db, enabledLanguages any) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Init", reflect.TypeOf((*MockLanguageService)(nil).Init), db, enabledLanguages) } +// ToggleLanguageVisibility mocks base method. +func (m *MockLanguageService) ToggleLanguageVisibility(db database.Database, languageID int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ToggleLanguageVisibility", db, languageID) + ret0, _ := ret[0].(error) + return ret0 +} + +// ToggleLanguageVisibility indicates an expected call of ToggleLanguageVisibility. +func (mr *MockLanguageServiceMockRecorder) ToggleLanguageVisibility(db, languageID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToggleLanguageVisibility", reflect.TypeOf((*MockLanguageService)(nil).ToggleLanguageVisibility), db, languageID) +} + // MockJWTService is a mock of JWTService interface. type MockJWTService struct { ctrl *gomock.Controller From dbb9c337b52b03f01b14443e0b7809b550755478 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Dec 2025 12:46:42 +0000 Subject: [PATCH 3/4] Fix formatting issues in initialization file Co-authored-by: HermanPlay <78978614+HermanPlay@users.noreply.github.com> --- internal/initialization/initialization.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/internal/initialization/initialization.go b/internal/initialization/initialization.go index d491511f..a6efad11 100644 --- a/internal/initialization/initialization.go +++ b/internal/initialization/initialization.go @@ -24,17 +24,17 @@ type Initialization struct { JWTService service.JWTService QueueService service.QueueService - AuthRoute routes.AuthRoute - ContestRoute routes.ContestRoute - ContestManagementRoute routes.ContestsManagementRoute - GroupRoute routes.GroupRoute - SubmissionRoute routes.SubmissionRoutes - TaskRoute routes.TaskRoute - TaskManagementRoute routes.TasksManagementRoute - AccessControlRoute routes.AccessControlRoute - UserRoute routes.UserRoute - WorkerRoute routes.WorkerRoute - LanguagesManagementRoute routes.LanguagesManagementRoute + AuthRoute routes.AuthRoute + ContestRoute routes.ContestRoute + ContestManagementRoute routes.ContestsManagementRoute + GroupRoute routes.GroupRoute + SubmissionRoute routes.SubmissionRoutes + TaskRoute routes.TaskRoute + TaskManagementRoute routes.TasksManagementRoute + AccessControlRoute routes.AccessControlRoute + UserRoute routes.UserRoute + WorkerRoute routes.WorkerRoute + LanguagesManagementRoute routes.LanguagesManagementRoute QueueListener queue.Listener From d2c93f8397d2377123ec2c6e9d816e6b6fef8349 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 21 Dec 2025 12:49:16 +0000 Subject: [PATCH 4/4] Remove redundant method checks from route handlers per code review Co-authored-by: HermanPlay <78978614+HermanPlay@users.noreply.github.com> --- .../api/http/routes/languages_management.go | 10 ----- .../http/routes/languages_management_test.go | 40 +------------------ 2 files changed, 2 insertions(+), 48 deletions(-) diff --git a/internal/api/http/routes/languages_management.go b/internal/api/http/routes/languages_management.go index 1288bd8b..106fae83 100644 --- a/internal/api/http/routes/languages_management.go +++ b/internal/api/http/routes/languages_management.go @@ -31,11 +31,6 @@ type languagesManagementRoute struct { // @Success 200 {object} httputils.APIResponse[[]schemas.LanguageConfig] // @Router /languages-management/languages [get] func (lr *languagesManagementRoute) GetAllLanguages(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodGet { - httputils.ReturnError(w, http.StatusMethodNotAllowed, "Method not allowed") - return - } - db := httputils.GetDatabase(r) languages, err := lr.languageService.GetAll(db) @@ -60,11 +55,6 @@ func (lr *languagesManagementRoute) GetAllLanguages(w http.ResponseWriter, r *ht // @Success 200 {object} httputils.APIResponse[httputils.MessageResponse] // @Router /languages-management/languages/{id} [patch] func (lr *languagesManagementRoute) ToggleLanguageVisibility(w http.ResponseWriter, r *http.Request) { - if r.Method != http.MethodPatch { - httputils.ReturnError(w, http.StatusMethodNotAllowed, "Method not allowed") - return - } - languageIDStr := httputils.GetPathValue(r, "id") if languageIDStr == "" { httputils.ReturnError(w, http.StatusBadRequest, "Language ID is required.") diff --git a/internal/api/http/routes/languages_management_test.go b/internal/api/http/routes/languages_management_test.go index a1e2651f..e4b627b3 100644 --- a/internal/api/http/routes/languages_management_test.go +++ b/internal/api/http/routes/languages_management_test.go @@ -29,7 +29,7 @@ func TestGetAllLanguages(t *testing.T) { router := mux.NewRouter() router.HandleFunc("/languages", func(w http.ResponseWriter, r *http.Request) { route.GetAllLanguages(w, r) - }) + }).Methods(http.MethodGet) handler := httputils.MockDatabaseMiddleware(router, db) @@ -44,24 +44,6 @@ func TestGetAllLanguages(t *testing.T) { })) defer server.Close() - t.Run("Accept only GET", func(t *testing.T) { - methods := []string{http.MethodPost, http.MethodPut, http.MethodPatch, http.MethodDelete} - - for _, method := range methods { - req, err := http.NewRequest(method, server.URL+"/languages", nil) - if err != nil { - t.Fatalf("Failed to create request: %v", err) - } - resp, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatalf("Failed to make request: %v", err) - } - defer resp.Body.Close() - - assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode) - } - }) - t.Run("Success", func(t *testing.T) { expectedLanguages := []schemas.LanguageConfig{ {ID: 1, Type: "C", Version: "11", FileExtension: ".c", IsDisabled: false}, @@ -119,7 +101,7 @@ func TestToggleLanguageVisibility(t *testing.T) { router := mux.NewRouter() router.HandleFunc("/languages/{id}", func(w http.ResponseWriter, r *http.Request) { route.ToggleLanguageVisibility(w, r) - }) + }).Methods(http.MethodPatch) handler := httputils.MockDatabaseMiddleware(router, db) @@ -134,24 +116,6 @@ func TestToggleLanguageVisibility(t *testing.T) { })) defer server.Close() - t.Run("Accept only PATCH", func(t *testing.T) { - methods := []string{http.MethodGet, http.MethodPost, http.MethodPut, http.MethodDelete} - - for _, method := range methods { - req, err := http.NewRequest(method, server.URL+"/languages/1", nil) - if err != nil { - t.Fatalf("Failed to create request: %v", err) - } - resp, err := http.DefaultClient.Do(req) - if err != nil { - t.Fatalf("Failed to make request: %v", err) - } - defer resp.Body.Close() - - assert.Equal(t, http.StatusMethodNotAllowed, resp.StatusCode) - } - }) - t.Run("Invalid language ID", func(t *testing.T) { req, err := http.NewRequest(http.MethodPatch, server.URL+"/languages/invalid", nil) if err != nil {