From 5689335712af1ff06379a3ad210251de5f895bc9 Mon Sep 17 00:00:00 2001 From: Robin Munn Date: Mon, 19 Aug 2024 10:42:24 +0700 Subject: [PATCH] Working end-to-end Send/Receive test Our first test from SynchronizeActionTests fully converted to do end-to-end testing with a real LexBox instance, and working. --- src/LfMerge.Core.Tests/E2E/TryOutE2ETests.cs | 103 +++++++------------ src/LfMerge.Core.Tests/LcmTestHelper.cs | 10 ++ src/LfMerge.Core.Tests/SRTestEnvironment.cs | 1 + src/LfMerge.Core.Tests/TestDoubles.cs | 2 + 4 files changed, 50 insertions(+), 66 deletions(-) diff --git a/src/LfMerge.Core.Tests/E2E/TryOutE2ETests.cs b/src/LfMerge.Core.Tests/E2E/TryOutE2ETests.cs index a147e984..e4de5548 100644 --- a/src/LfMerge.Core.Tests/E2E/TryOutE2ETests.cs +++ b/src/LfMerge.Core.Tests/E2E/TryOutE2ETests.cs @@ -20,9 +20,6 @@ namespace LfMerge.Core.Tests.E2E [Category("IntegrationTests")] public class TryOutE2ETests : E2ETestBase { - - // TODO: Duplicate the test below using LexBox instead of a mock LanguageDepot server - [Test] public async Task E2E_LFDataChangedLDDataChanged_LFWins() { @@ -32,86 +29,60 @@ public async Task E2E_LFDataChangedLDDataChanged_LFWins() var fwProjectCode = Regex.Replace(lfProject.ProjectCode, "^sr-", "fw-"); var fwProject = CloneFromLexbox(lfProject.ProjectCode, fwProjectCode); - // Do some initial checks to make sure we got the right data + // Modify FW data first, then push to Lexbox Guid entryId = Guid.Parse("0006f482-a078-4cef-9c5a-8bd35b53cf72"); - var lcmObject = lfProject.FieldWorksProject?.ServiceLocator?.ObjectRepository?.GetObject(entryId); - Assert.That(lcmObject, Is.Not.Null); - var lcmEntry = lcmObject as ILexEntry; - Assert.That(lcmEntry, Is.Not.Null); - Assert.That(lcmEntry.CitationForm.BestVernacularAlternative.Text, Is.EqualTo("cibubu")); - - IEnumerable originalMongoData = _mongoConnection.GetLfLexEntries(); - LfLexEntry lfEntry = originalMongoData.First(e => e.Guid == entryId); - - Assert.That(lfEntry.CitationForm.BestString(["seh"]), Is.EqualTo("cibubu")); - // Check that FW project cloned correctly too - - var fwObject = fwProject?.ServiceLocator?.ObjectRepository?.GetObject(entryId); - Assert.That(fwObject, Is.Not.Null); - var fwEntry = fwObject as ILexEntry; + var fwEntryRepo = fwProject.Cache.ServiceLocator.GetInstance(); + var fwEntry = fwEntryRepo.GetObject(entryId); Assert.That(fwEntry, Is.Not.Null); - Assert.That(fwEntry.CitationForm.BestVernacularAlternative.Text, Is.EqualTo("cibubu")); - - // TODO: Finish implementing the rest of the original test (below) from SynchronizeActionTests, then create helper methods for reusable parts - - // Capture original modified dates from the particular entry we're interested in + string unchangedGloss = LcmTestHelper.GetAnalysisText(fwEntry.SensesOS[0].Gloss); + LcmTestHelper.UpdateAnalysisText(fwProject, fwEntry.SensesOS[0].Gloss, text => text + " - changed in FW"); + DateTime fwDateModified = fwEntry.DateModified; + CommitAndPush(fwProject, lfProject.ProjectCode, fwProjectCode, "Modified gloss in FW"); - // IEnumerable originalMongoData = _mongoConnection.GetLfLexEntries(); - // LfLexEntry lfEntry = originalMongoData.First(e => e.Guid == _testEntryGuid); - // DateTime originalLfDateModified = lfEntry.DateModified; - // DateTime originalLfAuthorInfoModifiedDate = lfEntry.AuthorInfo.ModifiedDate; + // Modify LF data second, then launch Send/Receive - // Modify the entry in LF, but not yet in LD + var lfEntry = _mongoConnection.GetLfLexEntryByGuid(entryId); + // Verify LF entry not yet affected by FW change because Send/Receive has not happened yet + Assert.That(lfEntry.Senses[0].Gloss["pt"].Value, Is.EqualTo(unchangedGloss)); + // Capture original modified dates so we can check later that they've been updated + DateTime originalLfDateModified = lfEntry.DateModified; + DateTime originalLfAuthorInfoModifiedDate = lfEntry.AuthorInfo.ModifiedDate; - // string unchangedGloss = lfEntry.Senses[0].Gloss["en"].Value; - // string fwChangedGloss = unchangedGloss + " - changed in FW"; - // string lfChangedGloss = unchangedGloss + " - changed in LF"; - // lfEntry.Senses[0].Gloss["en"].Value = lfChangedGloss; - // lfEntry.AuthorInfo.ModifiedDate = DateTime.UtcNow; - // _mongoConnection.UpdateRecord(_lfProject, lfEntry); + lfEntry.Senses[0].Gloss["pt"].Value = unchangedGloss + " - changed in LF"; + lfEntry.AuthorInfo.ModifiedDate = lfEntry.DateModified = DateTime.UtcNow; + _mongoConnection.UpdateRecord(lfProject, lfEntry); - // Verify that the LD project has the FW value for the gloss + // Ensure LF project will S/R to local LexBox - // _lDProject = new LanguageDepotMock(testProjectCode, _lDSettings); - // var lDcache = _lDProject.FieldWorksProject.Cache; - // var lDLcmEntry = lDcache.ServiceLocator.GetObject(_testEntryGuid) as ILexEntry; - // Assert.That(lDLcmEntry.SensesOS[0].Gloss.AnalysisDefaultWritingSystem.Text, Is.EqualTo(fwChangedGloss)); - - // Capture the original modified date from the entry in the FW/LCM project - - // DateTime originalLdDateModified = lDLcmEntry.DateModified; + var saveEnv = Environment.GetEnvironmentVariable(MagicStrings.SettingsEnvVar_LanguageDepotRepoUri); + Environment.SetEnvironmentVariable(MagicStrings.SettingsEnvVar_LanguageDepotRepoUri, SRTestEnvironment.LexboxUrlForProjectWithAuth(lfProject.ProjectCode).AbsoluteUri); + Console.WriteLine(SRTestEnvironment.LexboxUrlForProjectWithAuth(lfProject.ProjectCode).AbsoluteUri); // Exercise - // Capture date/time immediately before running, to make sure that SyncAction updates it - - // var sutSynchronize = new SynchronizeAction(_env.Settings, _env.Logger); - // var timeBeforeRun = DateTime.UtcNow; + // Do LfMerge Send/Receive of LF project] + var lfEntryBeforeSR = _mongoConnection.GetLfLexEntryByGuid(entryId); + Assert.That(lfEntryBeforeSR?.Senses?[0]?.Gloss?["pt"]?.Value, Is.EqualTo(unchangedGloss + " - changed in LF")); - // Actually do the LfMerge Send/Receive with mock LD - - // sutSynchronize.Run(_lfProject); + try { + var syncAction = new SynchronizeAction(TestEnv.Settings, TestEnv.Logger); + var timeBeforeRun = DateTime.UtcNow; + Assert.That(timeBeforeRun, Is.GreaterThan(lfEntry.AuthorInfo.ModifiedDate)); // TODO: Since this is trivially true, we might be able to get rid of timeBeforeRun. + syncAction.Run(lfProject); + } finally { + Environment.SetEnvironmentVariable(MagicStrings.SettingsEnvVar_LanguageDepotRepoUri, saveEnv); + } // Verify - // Verify that the result of the conflict was LF winning - - // Assert.That(GetGlossFromMongoDb(_testEntryGuid), Is.EqualTo(lfChangedGloss)); - - // Verify that the modified dates got updated when LF won the merge conflict, even though LF's view of the data didn't change + // Verify that the result of the conflict was LF winning, and LF's modified dates got updated by the sync action - // LfLexEntry updatedLfEntry = _mongoConnection.GetLfLexEntries().First(e => e.Guid == _testEntryGuid); - // DateTime updatedLfDateModified = updatedLfEntry.DateModified; - // DateTime updatedLfAuthorInfoModifiedDate = updatedLfEntry.AuthorInfo.ModifiedDate; - // // LF had the same data previously; however it's a merge conflict so DateModified - // // got updated - // Assert.That(updatedLfDateModified, Is.GreaterThan(originalLfDateModified)); - // // But the LCM modified date (AuthorInfo.ModifiedDate in LF) should be updated. - // Assert.That(updatedLfAuthorInfoModifiedDate, Is.GreaterThan(originalLfAuthorInfoModifiedDate)); - // Assert.That(updatedLfDateModified, Is.GreaterThan(originalLdDateModified)); - // Assert.That(_mongoConnection.GetLastSyncedDate(_lfProject), Is.GreaterThanOrEqualTo(timeBeforeRun)); + var lfEntryAfterSR = _mongoConnection.GetLfLexEntryByGuid(entryId); + Assert.That(lfEntryAfterSR?.Senses?[0]?.Gloss?["pt"]?.Value, Is.EqualTo(unchangedGloss + " - changed in LF")); + Assert.That(lfEntryAfterSR.DateModified, Is.GreaterThan(originalLfDateModified)); + Assert.That(lfEntryAfterSR.AuthorInfo.ModifiedDate, Is.GreaterThan(originalLfAuthorInfoModifiedDate)); } } } diff --git a/src/LfMerge.Core.Tests/LcmTestHelper.cs b/src/LfMerge.Core.Tests/LcmTestHelper.cs index 82f7e0f0..e21b0590 100644 --- a/src/LfMerge.Core.Tests/LcmTestHelper.cs +++ b/src/LfMerge.Core.Tests/LcmTestHelper.cs @@ -32,6 +32,16 @@ public static ILexEntry GetEntry(FwProject project, Guid guid) return repo.GetObject(guid); } + public static string? GetVernacularText(IMultiUnicode field) + { + return field.BestVernacularAlternative?.Text; + } + + public static string? GetAnalysisText(IMultiUnicode field) + { + return field.BestAnalysisAlternative?.Text; + } + public static void SetVernacularText(FwProject project, IMultiUnicode field, string newText) { var accessor = project.Cache.ActionHandlerAccessor; diff --git a/src/LfMerge.Core.Tests/SRTestEnvironment.cs b/src/LfMerge.Core.Tests/SRTestEnvironment.cs index 8c2fcaf8..12a3e024 100644 --- a/src/LfMerge.Core.Tests/SRTestEnvironment.cs +++ b/src/LfMerge.Core.Tests/SRTestEnvironment.cs @@ -47,6 +47,7 @@ public SRTestEnvironment(TemporaryFolder? tempFolder = null) : base(true, true, true, tempFolder ?? new TemporaryFolder(TestName + Path.GetRandomFileName())) { TempFolder = _languageForgeServerFolder; // Better name for what E2E tests use it for + Settings.CommitWhenDone = true; // For SR tests specifically, we *do* want changes to .fwdata files to be persisted } public static Task Login() diff --git a/src/LfMerge.Core.Tests/TestDoubles.cs b/src/LfMerge.Core.Tests/TestDoubles.cs index 01a9a079..827209dd 100644 --- a/src/LfMerge.Core.Tests/TestDoubles.cs +++ b/src/LfMerge.Core.Tests/TestDoubles.cs @@ -417,6 +417,8 @@ class ChorusHelperDouble: ChorusHelper { public override string GetSyncUri(ILfProject project) { + var envOverride = Environment.GetEnvironmentVariable(MagicStrings.SettingsEnvVar_LanguageDepotRepoUri); + if (envOverride != null) return envOverride; var server = LanguageDepotMock.Server; return server != null && server.IsStarted ? server.Url : LanguageDepotMock.ProjectFolderPath; }