package services import ( "context" "testing" "github.com/google/uuid" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "gorm.io/driver/sqlite" "gorm.io/gorm" "veza-backend-api/internal/models" "veza-backend-api/internal/repositories" ) func setupLiveStreamTest(t *testing.T) (*LiveStreamService, *gorm.DB) { db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{}) require.NoError(t, err) require.NoError(t, db.AutoMigrate(&models.LiveStream{}, &models.Room{})) repo := repositories.NewLiveStreamRepository(db) roomRepo := repositories.NewRoomRepository(db) svc := NewLiveStreamService(repo, roomRepo) return svc, db } func TestCreate_GeneratesStreamKey(t *testing.T) { svc, _ := setupLiveStreamTest(t) stream := &models.LiveStream{Title: "Test Stream"} created, err := svc.Create(context.Background(), uuid.New(), stream) require.NoError(t, err) assert.NotEmpty(t, created.StreamKey) _, parseErr := uuid.Parse(created.StreamKey) assert.NoError(t, parseErr, "stream key should be valid UUID") } func TestCreate_RequiresTitle(t *testing.T) { svc, _ := setupLiveStreamTest(t) _, err := svc.Create(context.Background(), uuid.New(), &models.LiveStream{}) assert.Error(t, err) } func TestListByUser_ReturnsOnlyUserStreams(t *testing.T) { svc, _ := setupLiveStreamTest(t) user1 := uuid.New() user2 := uuid.New() _, err := svc.Create(context.Background(), user1, &models.LiveStream{Title: "User1 Stream 1"}) require.NoError(t, err) _, err = svc.Create(context.Background(), user1, &models.LiveStream{Title: "User1 Stream 2"}) require.NoError(t, err) _, err = svc.Create(context.Background(), user2, &models.LiveStream{Title: "User2 Stream 1"}) require.NoError(t, err) streams, err := svc.ListByUser(context.Background(), user1) require.NoError(t, err) assert.Len(t, streams, 2) for _, s := range streams { assert.Equal(t, user1, s.UserID) } } func TestRegenerateStreamKey_Success(t *testing.T) { svc, _ := setupLiveStreamTest(t) userID := uuid.New() created, err := svc.Create(context.Background(), userID, &models.LiveStream{Title: "Test Stream"}) require.NoError(t, err) oldKey := created.StreamKey newKey, err := svc.RegenerateStreamKey(context.Background(), created.ID, userID) require.NoError(t, err) assert.NotEqual(t, oldKey, newKey) assert.NotEmpty(t, newKey) } func TestRegenerateStreamKey_WrongUser(t *testing.T) { svc, _ := setupLiveStreamTest(t) user1 := uuid.New() user2 := uuid.New() created, err := svc.Create(context.Background(), user1, &models.LiveStream{Title: "Test Stream"}) require.NoError(t, err) _, err = svc.RegenerateStreamKey(context.Background(), created.ID, user2) assert.Error(t, err) } func TestSetIsLive_SetsStartedAt(t *testing.T) { svc, _ := setupLiveStreamTest(t) userID := uuid.New() created, err := svc.Create(context.Background(), userID, &models.LiveStream{Title: "Test Stream"}) require.NoError(t, err) err = svc.SetIsLive(context.Background(), created.ID, true) require.NoError(t, err) updated, err := svc.Get(context.Background(), created.ID) require.NoError(t, err) assert.True(t, updated.IsLive) assert.NotNil(t, updated.StartedAt) assert.Nil(t, updated.EndedAt) } func TestSetIsLive_SetsEndedAt(t *testing.T) { svc, _ := setupLiveStreamTest(t) userID := uuid.New() created, err := svc.Create(context.Background(), userID, &models.LiveStream{Title: "Test Stream"}) require.NoError(t, err) require.NoError(t, svc.SetIsLive(context.Background(), created.ID, true)) err = svc.SetIsLive(context.Background(), created.ID, false) require.NoError(t, err) updated, err := svc.Get(context.Background(), created.ID) require.NoError(t, err) assert.False(t, updated.IsLive) assert.NotNil(t, updated.EndedAt) } func TestUpdateViewerCount_Clamps(t *testing.T) { svc, _ := setupLiveStreamTest(t) userID := uuid.New() created, err := svc.Create(context.Background(), userID, &models.LiveStream{Title: "Test Stream"}) require.NoError(t, err) err = svc.UpdateViewerCount(context.Background(), created.ID, -100) require.NoError(t, err) updated, err := svc.Get(context.Background(), created.ID) require.NoError(t, err) assert.Equal(t, 0, updated.ViewerCount) } func TestUpdate_OwnershipCheck(t *testing.T) { svc, _ := setupLiveStreamTest(t) user1 := uuid.New() user2 := uuid.New() created, err := svc.Create(context.Background(), user1, &models.LiveStream{Title: "Test Stream"}) require.NoError(t, err) stream := &models.LiveStream{Title: "Hijacked"} _, err = svc.Update(context.Background(), created.ID, user2, stream) assert.Error(t, err) }