From d69d39c94cf10a8846b5d019b9b40c9dee72d18f Mon Sep 17 00:00:00 2001 From: Syed Omair Date: Tue, 18 Mar 2025 00:28:43 +0500 Subject: [PATCH] added integration test for user and dept --- docker-compose.yml | 2 +- integration_test/integration_test.go | 131 ++++++++++++++++++++++----- lib/container/connection.go | 2 - lib/container/connection_test.go | 81 +++++++++++++++++ lib/response/response.go | 57 ------------ 5 files changed, 188 insertions(+), 85 deletions(-) create mode 100644 lib/container/connection_test.go diff --git a/docker-compose.yml b/docker-compose.yml index 3c2b4a5..222053d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,7 +21,7 @@ services: - .:/app - /var/run/docker.sock:/var/run/docker.sock command: > - sh -c " go mod tidy && go test -v ./integration_test/... " + sh -c " go mod tidy && go test -v ./integration_test/... ./lib/... " user_service: env_file: .env_local diff --git a/integration_test/integration_test.go b/integration_test/integration_test.go index 63d8427..5523472 100644 --- a/integration_test/integration_test.go +++ b/integration_test/integration_test.go @@ -4,16 +4,25 @@ import ( "context" "crypto/rand" "database/sql" + "encoding/json" "fmt" "log" + "net/http" + "net/http/httptest" "os" "strings" "testing" _ "github.com/lib/pq" + "github.com/stretchr/testify/assert" "github.com/syedomair/backend-microservices/lib/container" + "github.com/syedomair/backend-microservices/lib/mockgrpc" + "github.com/syedomair/backend-microservices/service/department_service/department" + "github.com/syedomair/backend-microservices/service/user_service/user" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" + "go.uber.org/zap" + "google.golang.org/grpc" ) func TestMain(m *testing.M) { @@ -137,11 +146,55 @@ func randString(n int) string { return fmt.Sprintf("%x", b)[:n] } -/* -func TestUserRepo(t *testing.T) { +func TestDepartmentAPI(t *testing.T) { + c := setupTestDB(t) + departmentRepo := department.NewDBRepository(c.Db(), c.Logger()) + + limit := 10 + offset := 0 + orderby := "name" + sort := "asc" + + departmentDB, count, err := departmentRepo.GetAllDepartmentDB(limit, offset, orderby, sort) + + // Assertions + assert.NoError(t, err) + assert.Equal(t, 3, len(departmentDB)) + assert.Equal(t, "3", count) + + mockRepo := departmentRepo + mockLogger := zap.NewNop() + + controller := &department.Controller{ + Repo: mockRepo, + Logger: mockLogger, + } + + req, err := http.NewRequest("GET", "/departments", nil) + assert.NoError(t, err) + + rr := httptest.NewRecorder() + + // Act + controller.GetAllDepartments(rr, req) + + assert.Equal(t, http.StatusOK, rr.Code) + assert.NoError(t, err) + assert.Equal(t, "application/json;charset=utf-8", rr.Header().Get("Content-Type")) + + var response map[string]interface{} + err = json.NewDecoder(rr.Body).Decode(&response) + assert.NoError(t, err) + assert.Equal(t, "success", response["result"]) + data := response["data"].(map[string]interface{}) + departments := data["List"].([]interface{}) + department := departments[0].(map[string]interface{}) + assert.Equal(t, "Finance", department["name"]) + +} + +func TestUserAPI(t *testing.T) { c := setupTestDB(t) -*/ -/* userRepo := user.NewDBRepository(c.Db(), c.Logger()) limit := 10 @@ -149,37 +202,65 @@ func TestUserRepo(t *testing.T) { orderby := "name" sort := "asc" - users, count, err := userRepo.GetAllUserDB(limit, offset, orderby, sort) + usersDB, count, err := userRepo.GetAllUserDB(limit, offset, orderby, sort) // Assertions assert.NoError(t, err) - assert.Equal(t, 9, len(users)) + assert.Equal(t, 9, len(usersDB)) assert.Equal(t, "9", count) -*/ -/* mockRepo := userRepo mockLogger := zap.NewNop() + _, conn, _ := mockgrpc.SetupGRPCServer(t) + defer conn.Close() + + mockConnectionPool := &mockgrpc.MockConnectionPool{ + GetFunc: func() (*grpc.ClientConn, error) { + return conn, nil + }, + PutFunc: func(conn *grpc.ClientConn) { + }, + } + controller := &user.Controller{ - Repo: mockRepo, - Logger: mockLogger, + Repo: mockRepo, + Logger: mockLogger, + PointServiceConnectionPool: mockConnectionPool, } -*/ -/* - result, err := controller.GetAllUsersData(10, 0, "name", "asc") + req, err := http.NewRequest("GET", "/users", nil) + assert.NoError(t, err) + + rr := httptest.NewRecorder() + + // Act + controller.GetAllUsers(rr, req) + + assert.Equal(t, http.StatusOK, rr.Code) + assert.NoError(t, err) + assert.Equal(t, "application/json;charset=utf-8", rr.Header().Get("Content-Type")) + var response map[string]interface{} + err = json.NewDecoder(rr.Body).Decode(&response) assert.NoError(t, err) - assert.Equal(t, 8, len(result)) - - assert.Equal(t, "40", result["HighAge"].(string)) - assert.Equal(t, "22", result["LowAge"].(string)) - assert.Equal(t, "90000.00", result["HighSalary"].(string)) - assert.Equal(t, "48000.00", result["LowSalary"].(string)) - assert.Equal(t, "31.22", result["AvgAge"].(string)) - assert.Equal(t, "68333.33", result["AvgSalary"].(string)) - assert.Equal(t, "9", result["Count"].(string)) -*/ - -//} + assert.Equal(t, "success", response["result"]) + + data := response["data"].(map[string]interface{}) + assert.Equal(t, "40", data["HighAge"]) + assert.Equal(t, "22", data["LowAge"]) + assert.Equal(t, "31.22", data["AvgAge"]) + assert.Equal(t, "90000.00", data["HighSalary"]) + assert.Equal(t, "48000.00", data["LowSalary"]) + assert.Equal(t, "68333.33", data["AvgSalary"]) + assert.Equal(t, "9", data["Count"]) + + users := data["List"].([]interface{}) + assert.Equal(t, 9, len(users)) + + user := users[0].(map[string]interface{}) + assert.Equal(t, "Alice Johnson", user["name"]) + assert.Equal(t, float64(30), user["age"]) + assert.Equal(t, 60000.0, user["salary"]) + assert.Equal(t, float64(0), user["point"]) +} diff --git a/lib/container/connection.go b/lib/container/connection.go index be2788f..a8a00ef 100644 --- a/lib/container/connection.go +++ b/lib/container/connection.go @@ -6,7 +6,6 @@ import ( "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" - //pb "your_protobuf_package" // Replace with your protobuf package ) type ConnectionPoolInterface interface { @@ -44,7 +43,6 @@ func (p *ConnectionPool) Get() (*grpc.ClientConn, error) { p.mu.Lock() defer p.mu.Unlock() if p.active < p.maxSize { - //conn, err := grpc.Dial(p.target, grpc.WithTransportCredentials(insecure.NewCredentials())) conn, err := grpc.NewClient(p.target, grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { return nil, fmt.Errorf("failed to dial: %v", err) diff --git a/lib/container/connection_test.go b/lib/container/connection_test.go new file mode 100644 index 0000000..4acb8f7 --- /dev/null +++ b/lib/container/connection_test.go @@ -0,0 +1,81 @@ +package container + +import ( + "context" + "net" + "testing" + + "github.com/stretchr/testify/assert" + "google.golang.org/grpc" + "google.golang.org/grpc/test/bufconn" +) + +const bufSize = 1024 * 1024 + +var lis *bufconn.Listener + +func bufDialer(context.Context, string) (net.Conn, error) { + return lis.Dial() +} + +func startBufconnServer() { + lis = bufconn.Listen(bufSize) + s := grpc.NewServer() + go func() { + if err := s.Serve(lis); err != nil { + panic(err) + } + }() +} + +func TestNewConnectionPool(t *testing.T) { + pool, err := NewConnectionPool("bufnet", 2) + assert.NoError(t, err) + assert.NotNil(t, pool) +} + +func TestConnectionPool_GetAndPut(t *testing.T) { + startBufconnServer() + pool, _ := NewConnectionPool("bufnet", 2) + + conn1, err := pool.Get() + assert.NoError(t, err) + assert.NotNil(t, conn1) + + pool.Put(conn1) + conn2, err := pool.Get() + assert.NoError(t, err) + assert.Equal(t, conn1, conn2, "Expected the same connection to be reused") + pool.Put(conn2) +} + +func TestConnectionPool_MaxSize(t *testing.T) { + startBufconnServer() + pool, _ := NewConnectionPool("bufnet", 2) + + conn1, _ := pool.Get() + conn2, _ := pool.Get() + + done := make(chan bool) + go func() { + conn3, _ := pool.Get() + assert.NotNil(t, conn3) + done <- true + }() + + pool.Put(conn1) + <-done + + pool.Put(conn2) +} + +func TestConnectionPool_Close(t *testing.T) { + startBufconnServer() + pool, _ := NewConnectionPool("bufnet", 2) + conn1, _ := pool.Get() + conn2, _ := pool.Get() + pool.Put(conn1) + pool.Put(conn2) + pool.Close() + assert.Equal(t, 0, pool.active) +} diff --git a/lib/response/response.go b/lib/response/response.go index 32b79bf..a8518b7 100644 --- a/lib/response/response.go +++ b/lib/response/response.go @@ -1,62 +1,5 @@ package response -/* -import ( - "encoding/json" - "net/http" -) - -const ( - Success = "success" - Failure = "failure" -) - -// ErrorResponseHelper func -func ErrorResponseHelper(methodName string, w http.ResponseWriter, errorMessage string, httpStatus int) { - w.Header().Set("Content-Type", "application/json;charset=utf-8") - w.WriteHeader(httpStatus) - w.Write(errorResponse(errorMessage)) -} - -// SuccessResponseHelper func -func SuccessResponseHelper(w http.ResponseWriter, class interface{}, httpStatus int) { - w.Header().Set("Content-Type", "application/json;charset=utf-8") - w.Header().Set("Access-Control-Allow-Origin", "*") - w.WriteHeader(httpStatus) - w.Write(successResponse(class)) -} - -// SuccessResponseList func -func SuccessResponseList(w http.ResponseWriter, class interface{}, offset string, limit string, count string) { - tempResponse := make(map[string]interface{}) - tempResponse["count"] = count - tempResponse["offset"] = offset - tempResponse["limit"] = limit - tempResponse["list"] = class - - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(http.StatusOK) - w.Write(successResponse(tempResponse)) -} - -func errorResponse(message string) []byte { - class := map[string]string{"message": message} - return commonResponse(class, Failure) -} - -func successResponse(class interface{}) []byte { - return commonResponse(class, Success) -} - -func commonResponse(class interface{}, result string) []byte { - response := make(map[string]interface{}) - response["result"] = result - response["data"] = class - jsonByte, _ := json.Marshal(response) - return jsonByte -} - -*/ import ( "encoding/json" "net/http"