public void SynchronizeAction_LFDataChangedLDOtherDataChanged_ModifiedDateUpdated()
        {
            //Setup
            TestEnvironment.CopyFwProjectTo(modifiedTestProjectCode, _lDSettings.WebWorkDirectory);
            Directory.Move(Path.Combine(_lDSettings.WebWorkDirectory, modifiedTestProjectCode), LanguageDepotMock.ProjectFolderPath);

            _lfProject.IsInitialClone = true;
            _transferFdoToMongo.Run(_lfProject);

            var lfEntry = _mongoConnection.GetLfLexEntries().First(e => e.Guid == _testEntryGuid);
            var originalLfDateModified           = lfEntry.DateModified;
            var originalLfAuthorInfoModifiedDate = lfEntry.AuthorInfo.ModifiedDate;

            lfEntry.Note = LfMultiText.FromSingleStringMapping("en", "A note from LF");
            lfEntry.AuthorInfo.ModifiedDate = DateTime.UtcNow;
            _mongoConnection.UpdateRecord(_lfProject, lfEntry);

            var fwChangedGloss = lfEntry.Senses[0].Gloss["en"].Value + " - changed in FW";

            _lDProject = new LanguageDepotMock(testProjectCode, _lDSettings);
            var lDcache    = _lDProject.FieldWorksProject.Cache;
            var lDFdoEntry = lDcache.ServiceLocator.GetObject(_testEntryGuid) as ILexEntry;

            Assert.That(lDFdoEntry.SensesOS[0].Gloss.AnalysisDefaultWritingSystem.Text, Is.EqualTo(fwChangedGloss));

            // Exercise
            var sutSynchronize = new SynchronizeAction(_env.Settings, _env.Logger);
            var timeBeforeRun  = DateTime.UtcNow;

            sutSynchronize.Run(_lfProject);

            // Verify
            Assert.That(GetGlossFromMongoDb(_testEntryGuid), Is.EqualTo(fwChangedGloss));
            var updatedLfEntry = _mongoConnection.GetLfLexEntries().First(e => e.Guid == _testEntryGuid);

            // LF and LD changed the same entry but different fields, so we want to see the
            // DateModified change so that LF will re-process the entry.
            Assert.That(updatedLfEntry.DateModified, Is.GreaterThan(originalLfDateModified));
            // The FDO modified date (AuthorInfo.ModifiedDate in LF) should be updated.
            Assert.That(updatedLfEntry.AuthorInfo.ModifiedDate, Is.GreaterThan(originalLfAuthorInfoModifiedDate));

            Assert.That(_mongoConnection.GetLastSyncedDate(_lfProject), Is.GreaterThanOrEqualTo(timeBeforeRun));
        }
        public void SynchronizeAction_LFDataDeletedLDDataChanged_LDWins()
        {
            //Setup
            TestEnvironment.CopyFwProjectTo(modifiedTestProjectCode, _lDSettings.WebWorkDirectory);
            Directory.Move(Path.Combine(_lDSettings.WebWorkDirectory, modifiedTestProjectCode), LanguageDepotMock.ProjectFolderPath);

            _lfProject.IsInitialClone = true;
            _transferFdoToMongo.Run(_lfProject);

            var lfEntry = _mongoConnection.GetLfLexEntries().First(e => e.Guid == _testEntryGuid);
            var originalLfDateModified           = lfEntry.DateModified;
            var originalLfAuthorInfoModifiedDate = lfEntry.AuthorInfo.ModifiedDate;

            lfEntry.Senses.Remove(lfEntry.Senses[0]);
            _mongoConnection.UpdateRecord(_lfProject, lfEntry);

            const string fwChangedGloss = "English gloss - changed in FW";

            _lDProject = new LanguageDepotMock(testProjectCode, _lDSettings);
            var lDcache    = _lDProject.FieldWorksProject.Cache;
            var lDFdoEntry = lDcache.ServiceLocator.GetObject(_testEntryGuid) as ILexEntry;

            Assert.That(lDFdoEntry.SensesOS[0].Gloss.AnalysisDefaultWritingSystem.Text, Is.EqualTo(fwChangedGloss));

            // Exercise
            var sutSynchronize = new SynchronizeAction(_env.Settings, _env.Logger);
            var timeBeforeRun  = DateTime.UtcNow;

            sutSynchronize.Run(_lfProject);

            // Verify
            Assert.That(GetGlossFromMongoDb(_testEntryGuid), Is.EqualTo(fwChangedGloss));
            Assert.That(GetGlossFromLanguageDepot(_testEntryGuid, 2), Is.EqualTo(fwChangedGloss));
            var updatedLfEntry = _mongoConnection.GetLfLexEntries().First(e => e.Guid == _testEntryGuid);

            Assert.That(updatedLfEntry.IsDeleted, Is.False);
            DateTime updatedLfDateModified = updatedLfEntry.DateModified;

            Assert.That(updatedLfDateModified, Is.GreaterThan(originalLfDateModified));
            Assert.That(updatedLfDateModified, Is.GreaterThan(timeBeforeRun));
            Assert.That(updatedLfEntry.AuthorInfo.ModifiedDate, Is.GreaterThan(originalLfAuthorInfoModifiedDate));
            Assert.That(_mongoConnection.GetLastSyncedDate(_lfProject), Is.GreaterThanOrEqualTo(timeBeforeRun));
        }
        public void Success_NoNewChangesFromOthersAndUs()
        {
            // Setup
            TestEnvironment.CopyFwProjectTo(TestLangProj, _lDSettings.WebWorkDirectory);
            TestEnvironment.CopyFwProjectTo(TestLangProj, _env.Settings.WebWorkDirectory);
            LanguageDepotMock.Server.Start();
            var ldDirectory = Path.Combine(_lDSettings.WebWorkDirectory, TestLangProj);
            var oldHashOfLd = MercurialTestHelper.GetRevisionOfTip(ldDirectory);

            // Execute
            _synchronizeAction.Run(_lfProject);

            // Verify
            Assert.That(MercurialTestHelper.GetRevisionOfTip(ldDirectory), Is.EqualTo(oldHashOfLd));
            Assert.That(MercurialTestHelper.GetRevisionOfWorkingSet(_lfProject.ProjectDir),
                        Is.EqualTo(oldHashOfLd));
            Assert.That(_env.Logger.GetErrors(), Is.Null.Or.Empty);
            Assert.That(_env.Logger.GetMessages(), Does.Contain("No changes from others"));
            Assert.That(_lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.SYNCING));
        }
        public void TransferMongoToFdoAction_NoChangedData_DateModifiedUnchanged()
        {
            // Setup
            TestEnvironment.CopyFwProjectTo(testProjectCode, _lDSettings.WebWorkDirectory);
            _lfProject.IsInitialClone = true;
            _transferFdoToMongo.Run(_lfProject);

            // Exercise
            var transferMongoToFdo = new TransferMongoToFdoAction(_env.Settings, _env.Logger,
                                                                  _mongoConnection, _recordFactory, _counts);

            transferMongoToFdo.Run(_lfProject);

            // Verify
            var lfcache    = _lfProject.FieldWorksProject.Cache;
            var lfFdoEntry = lfcache.ServiceLocator.GetObject(_testEntryGuid) as ILexEntry;

            Assert.That(lfFdoEntry.DateModified.ToUniversalTime(),
                        Is.EqualTo(DateTime.Parse("2016-02-25 03:51:29.404")));
        }
        public void Success_ChangesFromOthersNoChangesFromUs()
        {
            // Setup
            var ldDirectory = CopyModifiedProjectAsTestLangProj(_lDSettings.WebWorkDirectory);

            TestEnvironment.CopyFwProjectTo(TestLangProj, _env.Settings.WebWorkDirectory);
            LanguageDepotMock.Server.Start();
            var oldHashOfLd = MercurialTestHelper.GetRevisionOfTip(ldDirectory);

            // Execute
            _synchronizeAction.Run(_lfProject);

            // Verify
            Assert.That(MercurialTestHelper.GetRevisionOfWorkingSet(_lfProject.ProjectDir),
                        Is.EqualTo(MercurialTestHelper.GetRevisionOfTip(ldDirectory)),
                        "Our repo doesn't have the changes from LanguageDepot");
            Assert.That(MercurialTestHelper.GetRevisionOfTip(ldDirectory), Is.EqualTo(oldHashOfLd));
            Assert.That(_env.Logger.GetErrors(), Is.Null.Or.Empty);
            Assert.That(_env.Logger.GetMessages(), Does.Contain("Received changes from others"));
            Assert.That(_lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.SYNCING));
        }
        public void Success_NewBranchFormat_LfMerge68()
        {
            // Setup
            var ldDirectory = CopyModifiedProjectAsTestLangProj(_lDSettings.WebWorkDirectory);

            TestEnvironment.CopyFwProjectTo(TestLangProj, _env.Settings.WebWorkDirectory);
            TestEnvironment.WriteTextFile(Path.Combine(_env.Settings.WebWorkDirectory, TestLangProj, "FLExProject.ModelVersion"), "{\"modelversion\": 7000068}");
            LanguageDepotMock.Server.Start();
            var oldHashOfLd = MercurialTestHelper.GetRevisionOfTip(ldDirectory);

            // Execute
            _synchronizeAction.Run(_lfProject);

            // Verify
            Assert.That(MercurialTestHelper.GetRevisionOfWorkingSet(_lfProject.ProjectDir),
                        Is.EqualTo(MercurialTestHelper.GetRevisionOfTip(ldDirectory)),
                        "Our repo doesn't have the changes from LanguageDepot");
            Assert.That(MercurialTestHelper.GetRevisionOfTip(ldDirectory), Is.EqualTo(oldHashOfLd));
            Assert.That(_env.Logger.GetErrors(), Is.Null.Or.Empty);
            Assert.That(_env.Logger.GetMessages(), Does.Contain("Received changes from others"));
        }
Example #7
0
        public void Success_ChangesFromUsNoChangesFromOthers()
        {
            // Setup
            CopyModifiedProjectAsTestLangProj(_env.Settings.WebWorkDirectory);
            TestEnvironment.CopyFwProjectTo(TestLangProj, _lDSettings.WebWorkDirectory);
            LanguageDepotMock.Server.Start();
            var oldHashOfUs = MercurialTestHelper.GetRevisionOfWorkingSet(_lfProject.ProjectDir);

            // Execute
            _synchronizeAction.Run(_lfProject);

            // Verify
            Assert.That(MercurialTestHelper.GetRevisionOfWorkingSet(_lfProject.ProjectDir),
                        Is.EqualTo(oldHashOfUs));
            Assert.That(MercurialTestHelper.GetRevisionOfTip(
                            Path.Combine(_lDSettings.WebWorkDirectory, TestLangProj)),
                        Is.EqualTo(oldHashOfUs), "LanguageDepot doesn't have our changes");
            Assert.That(_env.Logger.GetErrors(), Is.Null.Or.Empty);
            Assert.That(_env.Logger.GetMessages(), Is.StringContaining("No changes from others"));
            Assert.That(_lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.SYNCING));
        }
        public void Error_InvalidUtf8InXml()
        {
            // Setup
            TestEnvironment.CopyFwProjectTo(TestLangProj, _lDSettings.WebWorkDirectory);
            TestEnvironment.CopyFwProjectTo(TestLangProj, _env.Settings.WebWorkDirectory);
            LanguageDepotMock.Server.Start();
            var ldDirectory = Path.Combine(_lDSettings.WebWorkDirectory, TestLangProj);
            var oldHashOfLd = MercurialTestHelper.GetRevisionOfTip(ldDirectory);
            var fwdataPath  = Path.Combine(_env.Settings.WebWorkDirectory, TestLangProj, TestLangProj + ".fwdata");

            TestEnvironment.OverwriteBytesInFile(fwdataPath, new byte[] { 0xc0, 0xc1 }, 25);            // 0xC0 and 0xC1 are always invalid byte values in UTF-8

            // Execute
            _synchronizeAction.Run(_lfProject);

            // Verify
            string errors = _env.Logger.GetErrors();

            Assert.That(errors, Does.Contain("System.Xml.XmlException"));
            // Stack trace should also have been logged
            Assert.That(errors, Does.Contain("\n  at Chorus.sync.Synchronizer.SyncNow (Chorus.sync.SyncOptions options)"));
            Assert.That(_lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.SYNCING));
        }
        public void SynchronizeAction_NoChangedData_GlossUnchanged()
        {
            // Setup
            TestEnvironment.CopyFwProjectTo(testProjectCode, _lDSettings.WebWorkDirectory);
            _lfProject.IsInitialClone = true;
            _transferFdoToMongo.Run(_lfProject);

            // Exercise
            var sutSynchronize = new SynchronizeAction(_env.Settings, _env.Logger);

            sutSynchronize.Run(_lfProject);

            // Verify
            IEnumerable <LfLexEntry> receivedMongoData = _mongoConnection.GetLfLexEntries();

            Assert.That(receivedMongoData, Is.Not.Null);
            Assert.That(receivedMongoData, Is.Not.Empty);
            Assert.That(receivedMongoData.Count(), Is.EqualTo(originalNumOfFdoEntries));

            LfLexEntry lfEntry = receivedMongoData.First(e => e.Guid == _testEntryGuid);

            Assert.That(lfEntry.Senses[0].Gloss["en"].Value, Is.EqualTo("English gloss"));
        }
        public void Error_WrongXmlEncoding()
        {
            // Setup
            TestEnvironment.CopyFwProjectTo(TestLangProj, _lDSettings.WebWorkDirectory);
            TestEnvironment.CopyFwProjectTo(TestLangProj, _env.Settings.WebWorkDirectory);
            LanguageDepotMock.Server.Start();
            var ldDirectory = Path.Combine(_lDSettings.WebWorkDirectory, TestLangProj);
            var oldHashOfLd = MercurialTestHelper.GetRevisionOfTip(ldDirectory);
            var fwdataPath  = Path.Combine(_env.Settings.WebWorkDirectory, TestLangProj, TestLangProj + ".fwdata");

            TestEnvironment.ChangeFileEncoding(fwdataPath, System.Text.Encoding.UTF8, System.Text.Encoding.UTF32);
            // Note that the XML file will still claim the encoding is UTF-8!

            // Execute
            _synchronizeAction.Run(_lfProject);

            // Verify
            string errors = _env.Logger.GetErrors();

            Assert.That(errors, Does.Contain("System.Xml.XmlException: '.', hexadecimal value 0x00, is an invalid character."));
            // Stack trace should also have been logged
            Assert.That(errors, Does.Contain("\n  at Chorus.sync.Synchronizer.SyncNow (Chorus.sync.SyncOptions options)"));
            Assert.That(_lfProject.State.SRState, Is.EqualTo(ProcessingState.SendReceiveStates.SYNCING));
        }
Example #11
0
        public void SynchronizeAction_CustomReferenceAtomicField_DoesNotThrowExceptionDuringSync()
        {
            // Setup
            // Buggy code path needs us to change the field writing system to a "magic" ws (it's 0 in the original data/testlangproj project)
            var lcmMetaData  = _lfProject.FieldWorksProject.Cache.MetaDataCacheAccessor as SIL.LCModel.Infrastructure.IFwMetaDataCacheManaged;
            int listRef_flid = lcmMetaData.GetFieldIds().FirstOrDefault(flid => lcmMetaData.GetFieldLabel(flid) == "Cust Single ListRef");

            Assert.AreNotEqual(0, listRef_flid, "Cust Single ListRef field not found in test data");
            string fieldLabel = lcmMetaData.GetFieldLabel(listRef_flid);
            string fieldHelp  = lcmMetaData.GetFieldHelp(listRef_flid);
            int    wsid       = SIL.LCModel.DomainServices.WritingSystemServices.kwsAnal;

            lcmMetaData.UpdateCustomField(listRef_flid, fieldHelp, wsid, fieldLabel);

            TestEnvironment.CopyFwProjectTo(testProjectCode, _lDSettings.WebWorkDirectory);

            _lfProject.IsInitialClone = true;
            _transferLcmToMongo.Run(_lfProject);

            // To look at Mongo optionlist before test runs, uncomment this block
            // var x = _mongoConnection.GetLfOptionLists().FirstOrDefault(l => l.Code == "domain-type");
            // if (x != null) {
            //  foreach (LfOptionListItem item in x.Items) {
            //      Console.WriteLine($"{item.Guid} ({item.Key}) => {item.Value}");
            //  }
            // }

            // Buggy code path requires that there not be a GUID in the Mongo data
            IEnumerable <LfLexEntry> originalMongoData = _mongoConnection.GetLfLexEntries();
            LfLexEntry lfEntry = originalMongoData.First(e => e.Guid == _testEntryGuid);

            lfEntry.CustomFieldGuids.Remove("customField_entry_Cust_Single_ListRef");

            DateTime originalLfDateModified           = lfEntry.DateModified;
            DateTime originalLfAuthorInfoModifiedDate = lfEntry.AuthorInfo.ModifiedDate;

            lfEntry.AuthorInfo.ModifiedDate = DateTime.UtcNow;
            _mongoConnection.UpdateRecord(_lfProject, lfEntry);

            _lDProject = new LanguageDepotMock(testProjectCode, _lDSettings);
            var lDcache    = _lDProject.FieldWorksProject.Cache;
            var lDLcmEntry = lDcache.ServiceLocator.GetObject(_testEntryGuid) as ILexEntry;
            var data       = (SIL.LCModel.Application.ISilDataAccessManaged)lDcache.DomainDataByFlid;
            int ownedHvo   = data.get_ObjectProp(lDLcmEntry.Hvo, listRef_flid);

            Assert.AreNotEqual(0, ownedHvo, "Custom field value in test data was invalid during setup");
            Assert.IsTrue(data.get_IsValidObject(ownedHvo), "Custom field value in test data was invalid during setup");
            ICmObject referencedObject = lDcache.GetAtomicPropObject(ownedHvo);

            Assert.IsNotNull(referencedObject, "Custom field in test data referenced invalid CmObject during setup");
            DateTime originalLdDateModified = lDLcmEntry.DateModified;

            // Exercise
            var sutSynchronize = new SynchronizeAction(_env.Settings, _env.Logger);
            var timeBeforeRun  = DateTime.UtcNow;

            sutSynchronize.Run(_lfProject);

            // Verify
            LfLexEntry updatedLfEntry  = _mongoConnection.GetLfLexEntries().First(e => e.Guid == _testEntryGuid);
            var        updatedLcmEntry = lDcache.ServiceLocator.GetObject(_testEntryGuid) as ILexEntry;

            ownedHvo = data.get_ObjectProp(updatedLcmEntry.Hvo, listRef_flid);
            Assert.AreNotEqual(0, ownedHvo, "Custom field value in test data was invalid after running sync");
            Assert.IsTrue(data.get_IsValidObject(ownedHvo), "Custom field value in test data was invalid after running sync");
            referencedObject = lDcache.GetAtomicPropObject(ownedHvo);
            Assert.IsNotNull(referencedObject, "Custom field in test data referenced invalid CmObject after running sync");
            var poss = referencedObject as ICmPossibility;

            // TODO: Write another test to check on the abbrev hierarchy, because we may have a bug here (LfMerge not doing correct optionlist keys for hierarchical items)
            // Console.WriteLine($"Abbrev hierarchy: {poss.AbbrevHierarchyString}");
            Assert.IsNotNull(poss, "Custom field value in test data did not reference a CmPossibility object after running sync");
        }