Files
owncast/persistence/notificationsrepository/integration_test.go
T
fea4339e94 Notifications repository + service (#4565)
* Notifications repository

* feat: notifications repo + service

* fix: remove use of notifications/notifications.go

* Update persistence/notificationsrepository/notificationsrepository.go

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix: remove unused method

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-11-21 15:34:01 -08:00

232 lines
6.4 KiB
Go

package notificationsrepository
import (
"testing"
"github.com/owncast/owncast/core/data"
"github.com/owncast/owncast/models"
"github.com/owncast/owncast/persistence/configrepository"
)
var (
integrationTestDatastore *data.Datastore
integrationRepo NotificationsRepository
)
func init() {
// Use the shared test datastore from the main test file
// This ensures we're using the same database setup
integrationTestDatastore = testDatastore
if integrationTestDatastore != nil {
integrationRepo = New(integrationTestDatastore)
}
}
func TestIntegrationSetup(t *testing.T) {
// This test ensures integration setup works properly
// The actual setup is done in the init function below
if integrationTestDatastore == nil {
integrationTestDatastore = data.GetDatastore()
Setup(integrationTestDatastore)
integrationRepo = New(integrationTestDatastore)
}
if integrationRepo == nil {
t.Error("Integration repository should be initialized")
}
}
func TestBrowserPushSetupIntegration(t *testing.T) {
// Test that browser push keys are generated during setup
configRepo := configrepository.Get()
pubKey, err := configRepo.GetBrowserPushPublicKey()
if err != nil {
t.Errorf("Should be able to get browser push public key: %v", err)
}
privKey, err := configRepo.GetBrowserPushPrivateKey()
if err != nil {
t.Errorf("Should be able to get browser push private key: %v", err)
}
// Keys should be generated during setup
if pubKey == "" || privKey == "" {
t.Error("Browser push keys should be generated during setup")
}
}
func TestBrowserPushConfigurationIntegration(t *testing.T) {
configRepo := configrepository.Get()
// Test that browser push is enabled by default
browserConfig := configRepo.GetBrowserPushConfig()
if !browserConfig.Enabled {
t.Error("Browser push should be enabled by default")
}
// Test that initial notification configuration flag is set
hasConfigured := configRepo.GetHasPerformedInitialNotificationsConfig()
if !hasConfigured {
t.Error("Should have performed initial notifications configuration")
}
}
func TestDiscordConfigurationIntegration(t *testing.T) {
configRepo := configrepository.Get()
// Test Discord configuration setup
discordConfig := models.DiscordConfiguration{
Enabled: true,
Webhook: "https://discord.com/api/webhooks/test",
GoLiveMessage: "Test stream is live!",
}
err := configRepo.SetDiscordConfig(discordConfig)
if err != nil {
t.Errorf("Failed to set Discord configuration: %v", err)
}
// Test with disabled Discord
disabledConfig := models.DiscordConfiguration{
Enabled: false,
Webhook: "",
}
err = configRepo.SetDiscordConfig(disabledConfig)
if err != nil {
t.Errorf("Failed to disable Discord configuration: %v", err)
}
}
func TestNotificationWorkflowIntegration(t *testing.T) {
channel := BrowserPushNotification
destination := "integration-test-endpoint"
// Add a notification
err := integrationRepo.AddNotification(channel, destination)
if err != nil {
t.Errorf("Failed to add notification: %v", err)
}
// Verify it was added
destinations, err := integrationRepo.GetNotificationDestinationsForChannel(channel)
if err != nil {
t.Errorf("Failed to get notification destinations: %v", err)
}
found := false
for _, dest := range destinations {
if dest == destination {
found = true
break
}
}
if !found {
t.Error("Notification destination should be found after adding")
}
// Clean up
err = integrationRepo.RemoveNotificationForChannel(channel, destination)
if err != nil {
t.Errorf("Failed to remove notification: %v", err)
}
// Verify removal
destinationsAfter, err := integrationRepo.GetNotificationDestinationsForChannel(channel)
if err != nil {
t.Errorf("Failed to get notification destinations after removal: %v", err)
}
for _, dest := range destinationsAfter {
if dest == destination {
t.Error("Notification destination should be removed")
}
}
}
func TestRepositoryGetSingleton(t *testing.T) {
// Test that Get() returns the same instance
repo1 := Get()
repo2 := Get()
if repo1 != repo2 {
t.Error("Get() should return the same singleton instance")
}
// Test that it implements the interface
var _ NotificationsRepository = repo1
}
func TestDatabaseTransactionIntegrity(t *testing.T) {
channel := "TRANSACTION_TEST_CHANNEL"
destinations := []string{"dest1", "dest2", "dest3"}
// Add multiple notifications
for _, dest := range destinations {
err := integrationRepo.AddNotification(channel, dest)
if err != nil {
t.Errorf("Failed to add notification %s: %v", dest, err)
}
}
// Verify all were added
retrievedDests, err := integrationRepo.GetNotificationDestinationsForChannel(channel)
if err != nil {
t.Errorf("Failed to retrieve destinations: %v", err)
}
if len(retrievedDests) != len(destinations) {
t.Errorf("Expected %d destinations, got %d", len(destinations), len(retrievedDests))
}
// Remove them one by one and verify state consistency
for i, dest := range destinations {
err := integrationRepo.RemoveNotificationForChannel(channel, dest)
if err != nil {
t.Errorf("Failed to remove notification %s: %v", dest, err)
}
remaining, err := integrationRepo.GetNotificationDestinationsForChannel(channel)
if err != nil {
t.Errorf("Failed to get remaining destinations: %v", err)
}
expectedRemaining := len(destinations) - (i + 1)
if len(remaining) != expectedRemaining {
t.Errorf("Expected %d remaining destinations, got %d", expectedRemaining, len(remaining))
}
}
}
func TestErrorHandling(t *testing.T) {
// Test with empty channel
err := integrationRepo.AddNotification("", "test-destination")
if err != nil {
// Empty channel might be allowed - this documents the behavior
t.Logf("Empty channel behavior: %v", err)
}
// Test with empty destination
err = integrationRepo.AddNotification("TEST_CHANNEL", "")
if err != nil {
// Empty destination might be allowed - this documents the behavior
t.Logf("Empty destination behavior: %v", err)
}
// Test removing from empty channel
err = integrationRepo.RemoveNotificationForChannel("", "test-destination")
if err != nil {
t.Logf("Remove from empty channel behavior: %v", err)
}
// Test getting destinations for empty channel
destinations, err := integrationRepo.GetNotificationDestinationsForChannel("")
if err != nil {
t.Errorf("Getting destinations for empty channel should not error: %v", err)
}
if len(destinations) > 0 {
t.Logf("Empty channel returned %d destinations", len(destinations))
}
}