From bd3c365d1e685cea78be4fdf424d904fa722375d Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Fri, 25 Sep 2026 13:56:32 +0800 Subject: [PATCH] Update SaveSettings method to handle legacy collection documents and add corresponding tests --- .../Editing/NotificationsDataStore.cs | 12 +++--- ...ficationsDataStoreLegacyCollectionTests.cs | 42 +++++++++++++++++++ 2 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/ServiceControl.Persistence.Tests.RavenDB/Editing/NotificationsDataStoreLegacyCollectionTests.cs diff --git a/src/ServiceControl.Persistence.RavenDB/Editing/NotificationsDataStore.cs b/src/ServiceControl.Persistence.RavenDB/Editing/NotificationsDataStore.cs index f374c980a8..c801d834fa 100644 --- a/src/ServiceControl.Persistence.RavenDB/Editing/NotificationsDataStore.cs +++ b/src/ServiceControl.Persistence.RavenDB/Editing/NotificationsDataStore.cs @@ -22,13 +22,15 @@ public async Task LoadSettings(CancellationToken cancella public async Task SaveSettings(NotificationsSettings settings, CancellationToken cancellationToken = default) { using var session = await sessionProvider.OpenSession(cancellationToken: cancellationToken); - var document = new NotificationsSettingsDocument + // Changed in place because RavenDB will not move a document to another collection, and older databases hold this one in the NotificationsSettings collection. + var document = await session.LoadAsync(SingleDocumentId, cancellationToken); + if (document == null) { - Id = SingleDocumentId, - Email = Copy(settings.Email) - }; + document = new NotificationsSettingsDocument { Id = SingleDocumentId }; + await session.StoreAsync(document, SingleDocumentId, cancellationToken); + } - await session.StoreAsync(document, SingleDocumentId, cancellationToken); + document.Email = Copy(settings.Email); await session.SaveChangesAsync(cancellationToken); } diff --git a/src/ServiceControl.Persistence.Tests.RavenDB/Editing/NotificationsDataStoreLegacyCollectionTests.cs b/src/ServiceControl.Persistence.Tests.RavenDB/Editing/NotificationsDataStoreLegacyCollectionTests.cs new file mode 100644 index 0000000000..65fb400523 --- /dev/null +++ b/src/ServiceControl.Persistence.Tests.RavenDB/Editing/NotificationsDataStoreLegacyCollectionTests.cs @@ -0,0 +1,42 @@ +namespace ServiceControl.Persistence.Tests.RavenDB.Editing; + +using System.Threading.Tasks; +using NUnit.Framework; +using Raven.Client; +using ServiceControl.Notifications; +using ServiceControl.Persistence.RavenDB.Editing; + +class NotificationsDataStoreLegacyCollectionTests : PersistenceTestBase +{ + [Test, CancelAfter(30_000)] + public async Task SaveSettings_updates_a_document_held_in_the_legacy_collection() + { + var cancellationToken = TestContext.CurrentContext.CancellationToken; + + using (var session = PersistenceTestsContext.DocumentStore.OpenAsyncSession()) + { + var legacy = new NotificationsSettingsDocument { Email = new EmailNotifications { SmtpServer = "legacy.smtp" } }; + await session.StoreAsync(legacy, "NotificationsSettings/All", cancellationToken); + // Databases written by ServiceControl 6.19 and earlier hold the document in this collection, under the old class name. + var metadata = session.Advanced.GetMetadataFor(legacy); + metadata[Constants.Documents.Metadata.Collection] = "NotificationsSettings"; + metadata[Constants.Documents.Metadata.RavenClrType] = "ServiceControl.Notifications.NotificationsSettings, ServiceControl.Persistence"; + await session.SaveChangesAsync(cancellationToken); + } + + using (var session = PersistenceTestsContext.DocumentStore.OpenAsyncSession()) + { + var seeded = await session.LoadAsync("NotificationsSettings/All", cancellationToken); + Assert.That(session.Advanced.GetMetadataFor(seeded)[Constants.Documents.Metadata.Collection], Is.EqualTo("NotificationsSettings")); + } + + var settings = await NotificationsStore.LoadSettings(cancellationToken); + Assert.That(settings.Email.SmtpServer, Is.EqualTo("legacy.smtp")); + settings.Email.SmtpServer = "updated.smtp"; + await NotificationsStore.SaveSettings(settings, cancellationToken); + + await CompleteDatabaseOperation(); + var loaded = await NotificationsStore.LoadSettings(cancellationToken); + Assert.That(loaded.Email.SmtpServer, Is.EqualTo("updated.smtp")); + } +}