package handlers import ( "database/sql" "net/http" "net/http/httptest" "os" "strconv" "strings" "testing" "time" "go-crm/internal/db" "go-crm/internal/whatsapp" "golang.org/x/crypto/bcrypt" ) func TestListClientsWhatsAppDisplay(t *testing.T) { tmpfile, err := os.CreateTemp("", "test_*.db") if err != nil { t.Fatal(err) } defer os.Remove(tmpfile.Name()) tmpfile.Close() testDB, err := db.Init(tmpfile.Name()) if err != nil { t.Fatalf("failed to init db: %v", err) } defer testDB.Close() DB = testDB WAConnector = whatsapp.NewFakeConnector() hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost) _, err = testDB.Exec( "INSERT INTO accounts (email, name, password, created_at) VALUES (?, ?, ?, ?)", "test@example.com", "Test Account", string(hashedPassword), time.Now().Unix(), ) if err != nil { t.Fatalf("failed to create account: %v", err) } var accountID int64 err = testDB.QueryRow("SELECT account_id FROM accounts WHERE email = ?", "test@example.com").Scan(&accountID) if err != nil { t.Fatalf("failed to get account id: %v", err) } sessionID := "test-session" expires := time.Now().Add(time.Hour).Unix() _, err = testDB.Exec( "INSERT INTO sessions (session_id, account_id, expires) VALUES (?, ?, ?)", sessionID, accountID, expires, ) if err != nil { t.Fatalf("failed to create session: %v", err) } _, err = testDB.Exec( "INSERT INTO clients (account_id, name, phone, created_at) VALUES (?, ?, ?, ?)", accountID, "Client Without WhatsApp", "+5521987654321", time.Now().Unix(), ) if err != nil { t.Fatalf("failed to create client without wa: %v", err) } _, err = testDB.Exec( "INSERT INTO clients (account_id, name, phone, whatsapp_number, whatsapp_connected, created_at) VALUES (?, ?, ?, ?, ?, ?)", accountID, "Client With WhatsApp", "+5521987654322", "+5521987654322", 1, time.Now().Unix(), ) if err != nil { t.Fatalf("failed to create client with wa: %v", err) } req := httptest.NewRequest(http.MethodGet, "/clients", nil) req.AddCookie(&http.Cookie{Name: "session", Value: sessionID}) w := httptest.NewRecorder() ListClients(w, req) if w.Code != http.StatusOK { t.Fatalf("expected status 200, got %d", w.Code) } body := w.Body.String() if !strings.Contains(body, "Client Without WhatsApp") { t.Error("expected to find client without wa in response") } if !strings.Contains(body, "Connect") { t.Error("expected Connect button for client without WhatsApp") } if !strings.Contains(body, "Client With WhatsApp") { t.Error("expected to find client with wa in response") } if !strings.Contains(body, "+5521987654322") { t.Error("expected WhatsApp number displayed for connected client") } } func SetupTestDB(t *testing.T) (*sql.DB, func()) { tmpfile, err := os.CreateTemp("", "test_*.db") if err != nil { t.Fatal(err) } tmpfile.Close() testDB, err := db.Init(tmpfile.Name()) if err != nil { os.Remove(tmpfile.Name()) t.Fatalf("failed to init db: %v", err) } cleanup := func() { testDB.Close() os.Remove(tmpfile.Name()) } return testDB, cleanup } func TestLeadsConnectPage(t *testing.T) { testDB, cleanup := SetupTestDB(t) defer cleanup() DB = testDB WAConnector = whatsapp.NewFakeConnector() hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost) testDB.Exec( "INSERT INTO accounts (email, name, password, created_at) VALUES (?, ?, ?, ?)", "test@example.com", "Test Account", string(hashedPassword), time.Now().Unix(), ) var accountID int64 testDB.QueryRow("SELECT account_id FROM accounts WHERE email = ?", "test@example.com").Scan(&accountID) sessionID := "test-session" testDB.Exec( "INSERT INTO sessions (session_id, account_id, expires) VALUES (?, ?, ?)", sessionID, accountID, time.Now().Add(time.Hour).Unix(), ) var clientID int64 testDB.QueryRow( "INSERT INTO clients (account_id, name, phone, created_at) VALUES (?, ?, ?, ?) RETURNING client_id", accountID, "Test Client", "+5521987654321", time.Now().Unix(), ).Scan(&clientID) req := httptest.NewRequest(http.MethodGet, "/leads/connect?client_id="+strconv.FormatInt(clientID, 10), nil) req.AddCookie(&http.Cookie{Name: "session", Value: sessionID}) w := httptest.NewRecorder() LeadsConnectPage(w, req) if w.Code != http.StatusOK { t.Fatalf("expected status 200, got %d", w.Code) } body := w.Body.String() if !strings.Contains(body, "Scan to Connect") && !strings.Contains(body, "WhatsApp") { t.Error("expected QR connection page with WhatsApp messaging") } if !strings.Contains(strconv.FormatInt(clientID, 10), "") { t.Log("client_id passed to page") } } func TestLeadsQRPolling(t *testing.T) { testDB, cleanup := SetupTestDB(t) defer cleanup() DB = testDB WAConnector = whatsapp.NewFakeConnector() hashedPassword, _ := bcrypt.GenerateFromPassword([]byte("password"), bcrypt.DefaultCost) testDB.Exec( "INSERT INTO accounts (email, name, password, created_at) VALUES (?, ?, ?, ?)", "test@example.com", "Test Account", string(hashedPassword), time.Now().Unix(), ) var accountID int64 testDB.QueryRow("SELECT account_id FROM accounts WHERE email = ?", "test@example.com").Scan(&accountID) sessionID := "test-session" testDB.Exec( "INSERT INTO sessions (session_id, account_id, expires) VALUES (?, ?, ?)", sessionID, accountID, time.Now().Add(time.Hour).Unix(), ) var clientID int64 testDB.QueryRow( "INSERT INTO clients (account_id, name, phone, created_at) VALUES (?, ?, ?, ?) RETURNING client_id", accountID, "Test Client", "+5521987654321", time.Now().Unix(), ).Scan(&clientID) req := httptest.NewRequest(http.MethodGet, "/leads/qr?client_id="+strconv.FormatInt(clientID, 10), nil) req.AddCookie(&http.Cookie{Name: "session", Value: sessionID}) w := httptest.NewRecorder() LeadsQR(w, req) if w.Code != http.StatusOK { t.Fatalf("expected status 200, got %d", w.Code) } }