package whatsapp_test import ( "context" "fmt" "testing" "time" "go-crm/internal/whatsapp" ) // TestFakeConnector_FirstConnectReturnsQR verifies that a fresh Connect() // emits a QR frame before the connected state. func TestFakeConnector_FirstConnectReturnsQR(t *testing.T) { fc := whatsapp.NewFakeConnector() ch, err := fc.Connect(context.Background(), 1) if err != nil { t.Fatalf("Connect failed: %v", err) } select { case frame := <-ch: if frame.QR == "" { t.Errorf("expected QR code in first frame, got empty QR with state=%s", frame.State) } if frame.State != whatsapp.StateWaitingQR { t.Errorf("expected StateWaitingQR, got %s", frame.State) } case <-time.After(500 * time.Millisecond): t.Fatal("timeout waiting for QR frame") } } // TestFakeConnector_IsConnectedFalseBeforeScan verifies IsConnected returns false // until MarkConnected is explicitly called — mirrors the IsLoggedIn() semantics. func TestFakeConnector_IsConnectedFalseBeforeScan(t *testing.T) { fc := whatsapp.NewFakeConnector() connected, err := fc.IsConnected(context.Background(), 1) if err != nil { t.Fatalf("IsConnected error: %v", err) } if connected { t.Errorf("expected not connected before any scan, got connected=true") } // Connect and drain QR frame — still not authenticated. ch, _ := fc.Connect(context.Background(), 1) <-ch // consume QR frame connected, err = fc.IsConnected(context.Background(), 1) if err != nil { t.Fatalf("IsConnected error after Connect: %v", err) } if connected { t.Errorf("expected not connected after QR issued but before scan, got connected=true") } } // TestFakeConnector_IsConnectedTrueAfterMarkConnected verifies MarkConnected flips IsConnected. func TestFakeConnector_IsConnectedTrueAfterMarkConnected(t *testing.T) { fc := whatsapp.NewFakeConnector() fc.MarkConnected(1) connected, err := fc.IsConnected(context.Background(), 1) if err != nil { t.Fatalf("IsConnected error: %v", err) } if !connected { t.Errorf("expected connected=true after MarkConnected, got false") } } // TestFakeConnector_ConnectErrorPropagates verifies SetConnectError is returned from Connect. func TestFakeConnector_ConnectErrorPropagates(t *testing.T) { fc := whatsapp.NewFakeConnector() fc.SetConnectError(fmt.Errorf("simulated failure")) _, err := fc.Connect(context.Background(), 1) if err == nil { t.Fatal("expected error from Connect, got nil") } } // TestFakeConnector_QueuedFramesDeliveredInOrder verifies custom QR frames via QueueQR. func TestFakeConnector_QueuedFramesDeliveredInOrder(t *testing.T) { fc := whatsapp.NewFakeConnector() fc.QueueQR(1, whatsapp.QRFrame{QR: "qr-frame-1", State: whatsapp.StateWaitingQR}, whatsapp.QRFrame{QR: "qr-frame-2", State: whatsapp.StateWaitingQR}, ) ch, err := fc.Connect(context.Background(), 1) if err != nil { t.Fatalf("Connect failed: %v", err) } first := <-ch if first.QR != "qr-frame-1" { t.Errorf("expected qr-frame-1, got %q", first.QR) } second := <-ch if second.QR != "qr-frame-2" { t.Errorf("expected qr-frame-2, got %q", second.QR) } } // TestFakeConnector_DisconnectClearsState verifies Disconnect removes connected state. func TestFakeConnector_DisconnectClearsState(t *testing.T) { fc := whatsapp.NewFakeConnector() fc.MarkConnected(1) if err := fc.Disconnect(context.Background(), 1); err != nil { t.Fatalf("Disconnect error: %v", err) } connected, _ := fc.IsConnected(context.Background(), 1) if connected { t.Errorf("expected connected=false after Disconnect") } } // TestFakeConnector_MultipleClientsIsolated verifies separate clients don't share state. func TestFakeConnector_MultipleClientsIsolated(t *testing.T) { fc := whatsapp.NewFakeConnector() fc.MarkConnected(1) connected1, _ := fc.IsConnected(context.Background(), 1) connected2, _ := fc.IsConnected(context.Background(), 2) if !connected1 { t.Errorf("client 1 should be connected") } if connected2 { t.Errorf("client 2 should not be connected") } }