package http import ( "bytes" "database/sql" "encoding/json" db "infra-dashboard/Database" "net/http" "net/http/httptest" "reflect" "regexp" "testing" "github.com/DATA-DOG/go-sqlmock" "github.com/gorilla/mux" "gopkg.in/guregu/null.v4" ) func TestGetServerList(t *testing.T) { // Créer une connexion à la base de données simulée dbConn, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer dbConn.Close() // Simuler la réponse de la base de données mockServerList := []db.Server{ {ID: 1, Hostname: null.StringFrom("testsla"), OsId: null.StringFrom("8")}, {ID: 2, Hostname: null.StringFrom("Rabbit"), OsId: null.StringFrom("7")}, } rows := sqlmock.NewRows([]string{"id", "name", "active"}). AddRow(1, "testsla", "8"). AddRow(2, "Rabbit", "7") mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM dashboard_server")).WillReturnRows(rows) // Remplacer la fonction GetDatabaseConnection par une version mockée originalGetDatabaseConnection := db.GetDatabaseConnection db.GetDatabaseConnection = func() *sql.DB { return dbConn } defer func() { db.GetDatabaseConnection = originalGetDatabaseConnection }() // Créer une requête HTTP req, err := http.NewRequest("GET", "/servers", nil) if err != nil { t.Fatal(err) } // Créer un ResponseRecorder pour enregistrer la réponse rr := httptest.NewRecorder() handler := http.HandlerFunc(GetServersList) // Appeler la fonction GetServer handler.ServeHTTP(rr, req) // Vérifier le statut de la réponse if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // Vérifier le type de contenu de la réponse expectedContentType := "application/json" if ct := rr.Header().Get("Content-Type"); ct != expectedContentType { t.Errorf("handler returned wrong content type: got %v want %v", ct, expectedContentType) } // Vérifier le corps de la réponse var responseServerList []db.Server err = json.NewDecoder(rr.Body).Decode(&responseServerList) if err != nil { t.Fatal(err) } if !reflect.DeepEqual(responseServerList, mockServerList) { t.Errorf("handler returned unexpected body: got %v want %v", responseServerList, mockServerList) } // Vérifier que toutes les attentes ont été satisfaites if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } func TestGetServerbyID(t *testing.T) { // Créer une connexion à la base de données simulée dbConn, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer dbConn.Close() // Simuler la réponse de la base de données mockServer := db.Server{ ID: 1, Hostname: null.StringFrom("testsla"), OsId: null.StringFrom("8"), } rows := sqlmock.NewRows([]string{"id", "hostname", "os_id"}). AddRow(1, "testsla", "8") mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM dashboard_server WHERE id = ?")).WithArgs(sqlmock.AnyArg()).WillReturnRows(rows) // Remplacer la fonction GetDatabaseConnection par une version mockée originalGetDatabaseConnection := db.GetDatabaseConnection db.GetDatabaseConnection = func() *sql.DB { return dbConn } defer func() { db.GetDatabaseConnection = originalGetDatabaseConnection }() // Créer une requête HTTP req, err := http.NewRequest("GET", "/server/1", nil) if err != nil { t.Fatal(err) } // Ajouter les paramètres de la route req = mux.SetURLVars(req, map[string]string{"id": "1"}) // Créer un ResponseRecorder pour enregistrer la réponse rr := httptest.NewRecorder() handler := http.HandlerFunc(GetServersbyID) // Appeler la fonction GetServer handler.ServeHTTP(rr, req) // Vérifier le statut de la réponse if status := rr.Code; status != http.StatusOK { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) } // Vérifier le type de contenu de la réponse expectedContentType := "application/json" if ct := rr.Header().Get("Content-Type"); ct != expectedContentType { t.Errorf("handler returned wrong content type: got %v want %v", ct, expectedContentType) } // Vérifier le corps de la réponse var responseServer db.Server err = json.NewDecoder(rr.Body).Decode(&responseServer) if err != nil { t.Fatal("Error decoding json request", err) } if !reflect.DeepEqual(responseServer, mockServer) { t.Errorf("handler returned unexpected body: got %v want %v", responseServer, mockServer) } // Vérifier que toutes les attentes ont été satisfaites if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } } func TestGetServerbyOS(t *testing.T) { mockDB, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer mockDB.Close() db.GetDatabaseConnection = func() *sql.DB { return mockDB } mockServer := []db.Server{ {ID: 1, Hostname: null.StringFrom("testsla"), OsId: null.StringFrom("8")}, } tests := []struct { name string requestParam string mockBehavior func() expectedStatus int expectedContentType string }{ { name: "Successfully get Server by OS ID", requestParam: "8", mockBehavior: func() { rows := sqlmock.NewRows([]string{"id", "hostname", "os_id"}).AddRow(1, "testsla", "8") mock.ExpectQuery("SELECT * FROM dashboard_server WHERE os_id = ?").WithArgs(sqlmock.AnyArg()).WillReturnRows(rows) }, expectedStatus: http.StatusOK, expectedContentType: "application/json", }, { name: "Error getting Server by OS ID", requestParam: "test", mockBehavior: func() {}, expectedStatus: http.StatusInternalServerError, expectedContentType: "", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.mockBehavior() req, err := http.NewRequest("GET", "/server/os/", nil) if err != nil { t.Fatal(err) } req = mux.SetURLVars(req, map[string]string{"os_id": tt.requestParam}) rr := httptest.NewRecorder() handler := http.HandlerFunc(GetServersbyOS) handler.ServeHTTP(rr, req) if status := rr.Code; status != tt.expectedStatus { t.Errorf("handler returned wrong status code: got %v want %v", status, tt.expectedStatus) } if ct := rr.Header().Get("Content-Type"); ct != tt.expectedContentType { t.Errorf("handler returned wrong content type: got %v want %v", ct, tt.expectedContentType) } var responseServer []db.Server if len(responseServer) > 0 { err = json.NewDecoder(rr.Body).Decode(&responseServer) if err != nil { t.Fatal("Error decoding json request", err) } if !reflect.DeepEqual(responseServer, mockServer) { t.Errorf("handler returned unexpected body: got %v want %v", responseServer, mockServer) } } if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unfulfilled expectations: %s", err) } }) } } func TestCreateServer(t *testing.T) { mockDB, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer mockDB.Close() db.GetDatabaseConnection = func() *sql.DB { return mockDB } // Define the test cases tests := []struct { name string requestBody string mockBehavior func() expectedStatus int }{ { name: "Successful server creation", requestBody: `{"hostname": "test-host", "os_id": "1"}`, mockBehavior: func() { mock.ExpectPrepare("INSERT INTO dashboard_server (hostname, os_id) VALUES ( ?, ?)").ExpectExec().WithArgs("test-host", "1").WillReturnResult(sqlmock.NewResult(1, 1)) }, expectedStatus: http.StatusNoContent, }, { name: "Error creating server", requestBody: `{"hostname": "test-host", "os_id": "1"}`, mockBehavior: func() {}, expectedStatus: http.StatusInternalServerError, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Set up the mock behavior tt.mockBehavior() // Create a request with the test body req, err := http.NewRequest("POST", "/server/create", bytes.NewBuffer([]byte(tt.requestBody))) if err != nil { t.Fatalf("could not create request: %v", err) } req.Header.Set("Content-Type", "application/json") // Create a ResponseRecorder to record the response rr := httptest.NewRecorder() handler := http.HandlerFunc(CreateServer) // Call the handler handler.ServeHTTP(rr, req) // Check the status code if status := rr.Code; status != tt.expectedStatus { t.Errorf("handler returned wrong status code: got %v want %v", status, tt.expectedStatus) } // Verify that all expectations were met if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unmet expectations: %s", err) } }) } } func TestDeleteServer(t *testing.T) { // Create a mock database connection mockDB, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual)) if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer mockDB.Close() // Mock the GetDatabaseConnection function db.GetDatabaseConnection = func() *sql.DB { return mockDB } // Define the test cases tests := []struct { name string requestBody string mockBehavior func() expectedStatus int }{ { name: "Successful server deletion", requestBody: `{"hostname": "test-host", "os_id": "1"}`, mockBehavior: func() { mock.ExpectPrepare("DELETE FROM dashboard_server WHERE hostname = ? AND os_id = ?").ExpectExec().WithArgs("test-host", "1").WillReturnResult(sqlmock.NewResult(1, 1)) }, expectedStatus: http.StatusOK, }, { name: "Error deleting server", requestBody: `{"hostname": "test-host", "os_id": "1"}`, mockBehavior: func() { }, expectedStatus: http.StatusInternalServerError, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Set up the mock behavior tt.mockBehavior() // Create a request with the test body req, err := http.NewRequest("POST", "/server/delete", bytes.NewBuffer([]byte(tt.requestBody))) if err != nil { t.Fatalf("could not create request: %v", err) } req.Header.Set("Content-Type", "application/json") // Create a ResponseRecorder to record the response rr := httptest.NewRecorder() handler := http.HandlerFunc(DeleteServer) // Call the handler handler.ServeHTTP(rr, req) // Check the status code if status := rr.Code; status != tt.expectedStatus { t.Errorf("handler returned wrong status code: got %v want %v", status, tt.expectedStatus) } // Verify that all expectations were met if err := mock.ExpectationsWereMet(); err != nil { t.Errorf("there were unmet expectations: %s", err) } }) } }