Fix language server events to emit 'Updated' instead of 'Created' for updates (#19941)

* Initial plan

* Fix language server events to emit 'Updated' instead of 'Created' for updates

Co-authored-by: AndyButland <1993459+AndyButland@users.noreply.github.com>

* Removed the added test and instead added the assertion of the added behaviour to an existing test.

* Applied the same test and fix to the dictionary item service.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AndyButland <1993459+AndyButland@users.noreply.github.com>
Co-authored-by: Andy Butland <abutland73@gmail.com>
This commit is contained in:
Copilot
2025-08-22 13:55:03 +02:00
committed by GitHub
parent fee6722ecc
commit 1085eebb84
4 changed files with 35 additions and 2 deletions

View File

@@ -168,7 +168,9 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
// So ensure we set something that can be distinguished here. // So ensure we set something that can be distinguished here.
if (dictionaryItem.CreateDate == default) if (dictionaryItem.CreateDate == default)
{ {
dictionaryItem.CreateDate = DateTime.MinValue; // Set such that it's prior to the update date, but not the default date which will be considered
// uninitialized and get reset to the current date at the repository.
dictionaryItem.CreateDate = DateTime.MinValue.AddHours(1);
} }
if (dictionaryItem.UpdateDate == default) if (dictionaryItem.UpdateDate == default)

View File

@@ -80,7 +80,27 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
/// <inheritdoc /> /// <inheritdoc />
public async Task<Attempt<ILanguage, LanguageOperationStatus>> UpdateAsync(ILanguage language, Guid userKey) public async Task<Attempt<ILanguage, LanguageOperationStatus>> UpdateAsync(ILanguage language, Guid userKey)
=> await SaveAsync( {
// Create and update dates aren't tracked for languages. They exist on ILanguage due to the
// inheritance from IEntity, but we don't store them.
// However we have logic in ServerEventSender that will provide SignalR events for created and update operations,
// where these dates are used to distinguish between the two (whether or not the entity has an identity cannot
// be used here, as these events fire after persistence when the identity is known for both creates and updates).
// So ensure we set something that can be distinguished here.
if (language.CreateDate == default)
{
// Set such that it's prior to the update date, but not the default date which will be considered
// uninitialized and get reset to the current date at the repository.
language.CreateDate = DateTime.MinValue.AddHours(1);
}
if (language.UpdateDate == default)
{
// TODO (V17): To align with updates of system dates, this needs to change to DateTime.UtcNow.
language.UpdateDate = DateTime.Now;
}
return await SaveAsync(
language, language,
() => () =>
{ {
@@ -101,6 +121,7 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
AuditType.Save, AuditType.Save,
"Update Language", "Update Language",
userKey); userKey);
}
/// <inheritdoc /> /// <inheritdoc />
public async Task<Attempt<ILanguage, LanguageOperationStatus>> CreateAsync(ILanguage language, Guid userKey) public async Task<Attempt<ILanguage, LanguageOperationStatus>> CreateAsync(ILanguage language, Guid userKey)

View File

@@ -362,6 +362,11 @@ internal sealed class DictionaryItemServiceTests : UmbracoIntegrationTest
var result = await DictionaryItemService.UpdateAsync(item, Constants.Security.SuperUserKey); var result = await DictionaryItemService.UpdateAsync(item, Constants.Security.SuperUserKey);
Assert.True(result.Success); Assert.True(result.Success);
// Verify that the create and update dates can be used to distinguish between creates
// and updates (as these fields are used in ServerEventSender to emit a "Created" or "Updated"
// event.
Assert.Greater(result.Result.UpdateDate, result.Result.CreateDate);
var updatedItem = await DictionaryItemService.GetAsync("Child"); var updatedItem = await DictionaryItemService.GetAsync("Child");
Assert.NotNull(updatedItem); Assert.NotNull(updatedItem);

View File

@@ -191,6 +191,11 @@ internal sealed class LanguageServiceTests : UmbracoIntegrationTest
Assert.IsTrue(result.Success); Assert.IsTrue(result.Success);
Assert.AreEqual(LanguageOperationStatus.Success, result.Status); Assert.AreEqual(LanguageOperationStatus.Success, result.Status);
// Verify that the create and update dates can be used to distinguish between creates
// and updates (as these fields are used in ServerEventSender to emit a "Created" or "Updated"
// event.
Assert.Greater(result.Result.UpdateDate, result.Result.CreateDate);
// re-get // re-get
languageDaDk = await LanguageService.GetAsync(languageDaDk.IsoCode); languageDaDk = await LanguageService.GetAsync(languageDaDk.IsoCode);
Assert.NotNull(languageDaDk); Assert.NotNull(languageDaDk);