package services_test import ( "context" "regexp" "testing" "time" "github.com/DATA-DOG/go-sqlmock" "github.com/rede5/gohorsejobs/backend/internal/services" "github.com/stretchr/testify/assert" ) func TestCreateTicket(t *testing.T) { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() service := services.NewTicketService(db) tests := []struct { name string userID string subject string priority string mockRun func() wantErr bool }{ { name: "Success", userID: "user-1", subject: "Help me", priority: "high", mockRun: func() { mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO tickets`)). WithArgs("user-1", "Help me", "high"). WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "subject", "status", "priority", "created_at", "updated_at"}). AddRow("ticket-1", "user-1", "Help me", "open", "high", time.Now(), time.Now())) }, wantErr: false, }, { name: "Default Priority", userID: "user-1", subject: "Help me", priority: "", mockRun: func() { mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO tickets`)). WithArgs("user-1", "Help me", "medium"). WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "subject", "status", "priority", "created_at", "updated_at"}). AddRow("ticket-1", "user-1", "Help me", "open", "medium", time.Now(), time.Now())) }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.mockRun() got, err := service.CreateTicket(context.Background(), tt.userID, tt.subject, tt.priority) if (err != nil) != tt.wantErr { t.Errorf("TicketService.CreateTicket() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr { assert.Equal(t, "ticket-1", got.ID) } }) } } func TestListTickets(t *testing.T) { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() service := services.NewTicketService(db) tests := []struct { name string userID string mockRun func() wantErr bool }{ { name: "Success", userID: "user-1", mockRun: func() { mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, user_id, subject, status, priority, created_at, updated_at FROM tickets WHERE user_id = $1`)). WithArgs("user-1"). WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "subject", "status", "priority", "created_at", "updated_at"}). AddRow("ticket-1", "user-1", "Help", "open", "medium", time.Now(), time.Now()). AddRow("ticket-2", "user-1", "Bug", "closed", "high", time.Now(), time.Now())) }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.mockRun() tickets, err := service.ListTickets(context.Background(), tt.userID) if (err != nil) != tt.wantErr { t.Errorf("TicketService.ListTickets() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr { assert.Len(t, tickets, 2) } }) } } func TestGetTicket(t *testing.T) { db, mock, err := sqlmock.New() if err != nil { t.Fatalf("an error '%s' was not expected when opening a stub database connection", err) } defer db.Close() service := services.NewTicketService(db) tests := []struct { name string ticketID string userID string mockRun func() wantErr bool }{ { name: "Success", ticketID: "ticket-1", userID: "user-1", mockRun: func() { mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, user_id, subject, status, priority, created_at, updated_at FROM tickets WHERE id = $1 AND user_id = $2`)). WithArgs("ticket-1", "user-1"). WillReturnRows(sqlmock.NewRows([]string{"id", "user_id", "subject", "status", "priority", "created_at", "updated_at"}). AddRow("ticket-1", "user-1", "Help", "open", "medium", time.Now(), time.Now())) mock.ExpectQuery(regexp.QuoteMeta(`SELECT id, ticket_id, user_id, message, created_at FROM ticket_messages WHERE ticket_id = $1`)). WithArgs("ticket-1"). WillReturnRows(sqlmock.NewRows([]string{"id", "ticket_id", "user_id", "message", "created_at"}). AddRow("msg-1", "ticket-1", "user-1", "Hello", time.Now())) }, wantErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tt.mockRun() ticket, msgs, err := service.GetTicket(context.Background(), tt.ticketID, tt.userID) if (err != nil) != tt.wantErr { t.Errorf("TicketService.GetTicket() error = %v, wantErr %v", err, tt.wantErr) return } if !tt.wantErr { assert.Equal(t, "ticket-1", ticket.ID) assert.Len(t, msgs, 1) } }) } }