517 lines
13 KiB
Go
517 lines
13 KiB
Go
package e2e
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/igodwin/notifier/pkg/client"
|
|
)
|
|
|
|
// TestHappyPath_SendSingleNotification tests basic send functionality
|
|
func TestHappyPath_SendSingleNotification(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send notification
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: "Happy Path Test",
|
|
Body: "This is a test notification",
|
|
Recipients: []string{"test@example.com"},
|
|
}
|
|
|
|
resp, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
|
|
// Verify response
|
|
if !resp.Success {
|
|
t.Fatalf("Notification send was not successful")
|
|
}
|
|
|
|
if resp.NotificationID == "" {
|
|
t.Fatalf("Expected notification ID, got empty string")
|
|
}
|
|
|
|
if resp.Message == "" {
|
|
t.Fatalf("Expected response message, got empty string")
|
|
}
|
|
|
|
t.Logf("✓ Single notification sent successfully: %s", resp.NotificationID)
|
|
}
|
|
|
|
// TestHappyPath_SendBatchNotifications tests batch send functionality
|
|
func TestHappyPath_SendBatchNotifications(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send batch of notifications
|
|
reqs := []client.NotificationRequest{
|
|
{
|
|
Type: "stdout",
|
|
Subject: "Batch Test 1",
|
|
Body: "First notification",
|
|
Recipients: []string{"user1@example.com"},
|
|
},
|
|
{
|
|
Type: "stdout",
|
|
Subject: "Batch Test 2",
|
|
Body: "Second notification",
|
|
Recipients: []string{"user2@example.com"},
|
|
},
|
|
{
|
|
Type: "stdout",
|
|
Subject: "Batch Test 3",
|
|
Body: "Third notification",
|
|
Recipients: []string{"user3@example.com"},
|
|
},
|
|
}
|
|
|
|
resps, err := suite.Client.SendBatch(ctx, reqs)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send batch: %v", err)
|
|
}
|
|
|
|
if len(resps) != 3 {
|
|
t.Fatalf("Expected 3 responses, got %d", len(resps))
|
|
}
|
|
|
|
for i, resp := range resps {
|
|
if !resp.Success {
|
|
t.Fatalf("Notification %d was not successful", i)
|
|
}
|
|
if resp.NotificationID == "" {
|
|
t.Fatalf("Notification %d has empty ID", i)
|
|
}
|
|
}
|
|
|
|
t.Logf("✓ Batch of %d notifications sent successfully", len(resps))
|
|
}
|
|
|
|
// TestHappyPath_GetNotificationStatus tests retrieval of notification details
|
|
func TestHappyPath_GetNotificationStatus(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send a notification
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: "Status Check Test",
|
|
Body: "Test message",
|
|
Recipients: []string{"test@example.com"},
|
|
}
|
|
|
|
sendResp, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
|
|
// Retrieve the notification
|
|
notif, err := suite.Client.GetNotification(ctx, sendResp.NotificationID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get notification: %v", err)
|
|
}
|
|
|
|
// Verify details
|
|
if notif.ID != sendResp.NotificationID {
|
|
t.Fatalf("ID mismatch: expected %s, got %s", sendResp.NotificationID, notif.ID)
|
|
}
|
|
|
|
if notif.Type != "stdout" {
|
|
t.Fatalf("Type mismatch: expected stdout, got %s", notif.Type)
|
|
}
|
|
|
|
if notif.Subject != "Status Check Test" {
|
|
t.Fatalf("Subject mismatch")
|
|
}
|
|
|
|
if notif.Body != "Test message" {
|
|
t.Fatalf("Body mismatch")
|
|
}
|
|
|
|
t.Logf("✓ Notification retrieved successfully with status: %s", notif.Status)
|
|
}
|
|
|
|
// TestHappyPath_ListNotifications tests listing functionality
|
|
func TestHappyPath_ListNotifications(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send multiple notifications
|
|
for i := 0; i < 5; i++ {
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: fmt.Sprintf("List Test %d", i),
|
|
Body: "Test message",
|
|
Recipients: []string{"test@example.com"},
|
|
}
|
|
_, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
}
|
|
|
|
// List notifications
|
|
listReq := client.ListNotificationsRequest{
|
|
Limit: 10,
|
|
Offset: 0,
|
|
}
|
|
|
|
resp, err := suite.Client.ListNotifications(ctx, listReq)
|
|
if err != nil {
|
|
t.Fatalf("Failed to list notifications: %v", err)
|
|
}
|
|
|
|
if len(resp.Notifications) == 0 {
|
|
t.Fatalf("Expected notifications, got none")
|
|
}
|
|
|
|
if len(resp.Notifications) < 5 {
|
|
t.Logf("Warning: Expected at least 5 notifications, got %d", len(resp.Notifications))
|
|
}
|
|
|
|
t.Logf("✓ Listed %d notifications successfully", len(resp.Notifications))
|
|
}
|
|
|
|
// TestHappyPath_GetStats tests statistics retrieval
|
|
func TestHappyPath_GetStats(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send some notifications
|
|
for i := 0; i < 3; i++ {
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: "Stats Test",
|
|
Body: "Test",
|
|
Recipients: []string{"test@example.com"},
|
|
}
|
|
_, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
}
|
|
|
|
// Get stats
|
|
stats, err := suite.Client.GetStats(ctx)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get stats: %v", err)
|
|
}
|
|
|
|
// Verify stats
|
|
if stats == nil {
|
|
t.Fatalf("Stats is nil")
|
|
}
|
|
|
|
if stats.TotalSent == 0 && stats.TotalQueued == 0 && stats.TotalPending == 0 {
|
|
t.Logf("Warning: No notifications in any state")
|
|
}
|
|
|
|
t.Logf("✓ Stats retrieved: sent=%d, failed=%d, pending=%d, queued=%d",
|
|
stats.TotalSent, stats.TotalFailed, stats.TotalPending, stats.TotalQueued)
|
|
}
|
|
|
|
// TestHappyPath_GetNotifiers tests notifier discovery
|
|
func TestHappyPath_GetNotifiers(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Get available notifiers
|
|
resp, err := suite.Client.GetNotifiers(ctx)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get notifiers: %v", err)
|
|
}
|
|
|
|
if len(resp.Notifiers) == 0 {
|
|
t.Fatalf("Expected at least one notifier, got none")
|
|
}
|
|
|
|
// Verify stdout notifier is available
|
|
foundStdout := false
|
|
for _, notif := range resp.Notifiers {
|
|
if notif.Type == "stdout" {
|
|
foundStdout = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundStdout {
|
|
t.Fatalf("Expected stdout notifier to be available")
|
|
}
|
|
|
|
t.Logf("✓ Found %d notifiers: %v", len(resp.Notifiers), resp.Notifiers)
|
|
}
|
|
|
|
// TestHappyPath_HealthCheck tests health endpoint
|
|
func TestHappyPath_HealthCheck(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Check health
|
|
healthy, err := suite.Client.HealthCheck(ctx)
|
|
if err != nil {
|
|
t.Fatalf("Health check failed: %v", err)
|
|
}
|
|
|
|
if !healthy {
|
|
t.Fatalf("Service is not healthy")
|
|
}
|
|
|
|
t.Logf("✓ Service health check passed")
|
|
}
|
|
|
|
// TestHappyPath_MultipleRecipients tests notification with multiple recipients
|
|
func TestHappyPath_MultipleRecipients(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send to multiple recipients
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: "Multi-recipient Test",
|
|
Body: "This goes to multiple people",
|
|
Recipients: []string{
|
|
"user1@example.com",
|
|
"user2@example.com",
|
|
"user3@example.com",
|
|
},
|
|
}
|
|
|
|
resp, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
|
|
if !resp.Success {
|
|
t.Fatalf("Notification send was not successful")
|
|
}
|
|
|
|
// Verify the notification was stored with all recipients
|
|
notif, err := suite.Client.GetNotification(ctx, resp.NotificationID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get notification: %v", err)
|
|
}
|
|
|
|
if len(notif.Recipients) != 3 {
|
|
t.Fatalf("Expected 3 recipients, got %d", len(notif.Recipients))
|
|
}
|
|
|
|
t.Logf("✓ Notification sent to %d recipients successfully", len(notif.Recipients))
|
|
}
|
|
|
|
// TestHappyPath_WithMetadata tests notification with metadata
|
|
func TestHappyPath_WithMetadata(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send with metadata
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: "Metadata Test",
|
|
Body: "Test with metadata",
|
|
Recipients: []string{"test@example.com"},
|
|
Metadata: map[string]string{
|
|
"correlation_id": "test-123",
|
|
"service": "test-service",
|
|
"environment": "test",
|
|
},
|
|
}
|
|
|
|
resp, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
|
|
// Verify metadata was stored
|
|
notif, err := suite.Client.GetNotification(ctx, resp.NotificationID)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get notification: %v", err)
|
|
}
|
|
|
|
if len(notif.Metadata) != 3 {
|
|
t.Logf("Warning: Expected 3 metadata fields, got %d", len(notif.Metadata))
|
|
}
|
|
|
|
t.Logf("✓ Notification with metadata sent successfully")
|
|
}
|
|
|
|
// TestHappyPath_CancelPendingNotification tests cancellation of pending notifications
|
|
func TestHappyPath_CancelPendingNotification(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send a notification
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: "Cancel Test",
|
|
Body: "This will be cancelled",
|
|
Recipients: []string{"test@example.com"},
|
|
}
|
|
|
|
resp, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
|
|
// Cancel the notification
|
|
err = suite.Client.CancelNotification(ctx, resp.NotificationID)
|
|
if err != nil {
|
|
// Cancel operations may not be fully implemented, so we log a note instead of failing
|
|
t.Logf("Note: Cancel notification returned error (may be expected): %v", err)
|
|
}
|
|
|
|
// Verify the notification still exists (cancel may have succeeded or failed)
|
|
notif, err := suite.Client.GetNotification(ctx, resp.NotificationID)
|
|
if err != nil {
|
|
t.Logf("Warning: Failed to get notification after cancel: %v", err)
|
|
} else {
|
|
t.Logf("Notification status after cancel attempt: %s", notif.Status)
|
|
}
|
|
|
|
t.Logf("✓ Notification cancel operation completed")
|
|
}
|
|
|
|
// TestHappyPath_RetryFailedNotification tests retry functionality
|
|
func TestHappyPath_RetryFailedNotification(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send a notification
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Subject: "Retry Test",
|
|
Body: "This might need retry",
|
|
Recipients: []string{"test@example.com"},
|
|
}
|
|
|
|
resp, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
|
|
// Try to retry (even if successful, should not error)
|
|
retryResp, err := suite.Client.RetryNotification(ctx, resp.NotificationID)
|
|
if err != nil {
|
|
t.Logf("Note: Retry returned error (may be expected if notification already sent): %v", err)
|
|
}
|
|
|
|
if retryResp != nil && retryResp.NotificationID == "" {
|
|
t.Fatalf("Expected notification ID in retry response")
|
|
}
|
|
|
|
t.Logf("✓ Notification retry operation completed")
|
|
}
|
|
|
|
// TestHappyPath_NotificationWithAccount tests sending to specific account
|
|
func TestHappyPath_NotificationWithAccount(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("Skipping E2E test in short mode")
|
|
}
|
|
|
|
suite := SetupSuite(t)
|
|
defer suite.TeardownSuite(context.Background())
|
|
|
|
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
|
defer cancel()
|
|
|
|
// Send with specific account
|
|
req := client.NotificationRequest{
|
|
Type: "stdout",
|
|
Account: "default",
|
|
Subject: "Account Test",
|
|
Body: "Sent to specific account",
|
|
Recipients: []string{"test@example.com"},
|
|
}
|
|
|
|
resp, err := suite.Client.Send(ctx, req)
|
|
if err != nil {
|
|
t.Fatalf("Failed to send notification: %v", err)
|
|
}
|
|
|
|
if !resp.Success {
|
|
t.Fatalf("Notification send was not successful")
|
|
}
|
|
|
|
t.Logf("✓ Notification sent to account successfully")
|
|
}
|