public void GatherBuiltInAndUserConfigurations_ProjectOverrideReplacesShipped() { var configObjectName = "Dictionary"; var projectDictionaryConfigs = Path.Combine(FdoFileHelper.GetConfigSettingsDir(Cache.ProjectId.ProjectFolder), "Dictionary"); Directory.CreateDirectory(projectDictionaryConfigs); using (var tempConfigFile = TempFile.WithFilename(Path.Combine(projectDictionaryConfigs, "Override" + DictionaryConfigurationModel.FileExtension))) { string firstShippedConfigName; var shippedFileList = Directory.EnumerateFiles(Path.Combine(FwDirectoryFinder.DefaultConfigurations, "Dictionary"), "*" + DictionaryConfigurationModel.FileExtension); var fileList = shippedFileList.ToArray(); using (var stream = new FileStream(fileList.First(), FileMode.Open)) { var doc = new XmlDocument(); doc.Load(stream); var node = doc.SelectSingleNode("DictionaryConfiguration"); firstShippedConfigName = node.Attributes["name"].Value; } File.WriteAllText(tempConfigFile.Path, "<?xml version='1.0' encoding='utf-8'?><DictionaryConfiguration name='" + firstShippedConfigName + "'/>"); // SUT var fileListFromResults = DictionaryConfigurationUtils.GatherBuiltInAndUserConfigurations(Cache, configObjectName).Values; CollectionAssert.Contains(fileListFromResults, tempConfigFile.Path); Assert.AreEqual(fileListFromResults.Count, fileList.Count(), "Override was added instead of replacing a shipped config."); } }
public void MigrateIfNeeded(SimpleLogger logger, Mediator mediator, string appVersion) { m_logger = logger; Cache = (FdoCache)mediator.PropertyTable.GetValue("cache"); var foundOne = string.Format("{0}: Configuration was found in need of migration. - {1}", appVersion, DateTime.Now.ToString("yyyy MMM d h:mm:ss")); var configSettingsDir = FdoFileHelper.GetConfigSettingsDir(Cache.ProjectId.ProjectFolder); var dictionaryConfigLoc = Path.Combine(configSettingsDir, DictionaryConfigurationListener.DictionaryConfigurationDirectoryName); var stemPath = Path.Combine(dictionaryConfigLoc, "Stem" + DictionaryConfigurationModel.FileExtension); var lexemePath = Path.Combine(dictionaryConfigLoc, "Lexeme" + DictionaryConfigurationModel.FileExtension); if (File.Exists(stemPath) && !File.Exists(lexemePath)) { File.Move(stemPath, lexemePath); } foreach (var config in DCM.GetConfigsNeedingMigration(Cache, DCM.VersionCurrent)) { m_logger.WriteLine(foundOne); if (config.Label.StartsWith("Stem-")) { config.Label = config.Label.Replace("Stem-", "Lexeme-"); } m_logger.WriteLine(string.Format("Migrating {0} configuration '{1}' from version {2} to {3}.", config.Type, config.Label, config.Version, DCM.VersionCurrent)); m_logger.IncreaseIndent(); MigrateFrom83Alpha(logger, config, LoadBetaDefaultForAlphaConfig(config)); config.Save(); m_logger.DecreaseIndent(); } }
public void MigrateOldConfigurationsIfNeeded_MatchesLabelsWhenUIIsLocalized() { // Localize a Part's label to German (sufficient to cause a mismatched nodes crash if one config's labels are localized) var localizedPartLabels = new Dictionary <string, string>(); localizedPartLabels["Main Entry"] = "Haupteintrag"; var pathsToL10nStrings = (Dictionary <string, Dictionary <string, string> >)ReflectionHelper.GetField(m_mediator.StringTbl, "m_pathsToStrings"); pathsToL10nStrings["group[@id = 'LocalizedAttributes']/"] = localizedPartLabels; var configSettingsDir = FdoFileHelper.GetConfigSettingsDir(Path.GetDirectoryName(Cache.ProjectId.Path)); var newConfigFilePath = Path.Combine(configSettingsDir, DictionaryConfigurationListener.DictionaryConfigurationDirectoryName, "Lexeme" + DictionaryConfigurationModel.FileExtension); Assert.False(File.Exists(newConfigFilePath), "should not yet be migrated"); Directory.CreateDirectory(configSettingsDir); File.WriteAllLines(Path.Combine(configSettingsDir, "Test.fwlayout"), new[] { @"<layoutType label='Lexeme-based (complex forms as main entries)' layout='publishStem'><configure class='LexEntry' label='Main Entry' layout='publishStemEntry' />", @"<configure class='LexEntry' label='Minor Entry' layout='publishStemMinorEntry' hideConfig='true' /></layoutType>'" }); var migrator = new DictionaryConfigurationMigrator(m_mediator); Assert.DoesNotThrow(() => migrator.MigrateOldConfigurationsIfNeeded(), "ArgumentException indicates localized labels."); // SUT var updatedConfigModel = new DictionaryConfigurationModel(newConfigFilePath, Cache); Assert.AreEqual(2, updatedConfigModel.Parts.Count, "Should have 2 top-level nodes"); Assert.AreEqual("Main Entry", updatedConfigModel.Parts[0].Label); DirectoryUtilities.DeleteDirectoryRobust(configSettingsDir); }
internal static List <DictionaryConfigurationModel> GetConfigsNeedingMigration(FdoCache cache, int targetVersion) { var configSettingsDir = FdoFileHelper.GetConfigSettingsDir(Path.GetDirectoryName(cache.ProjectId.Path)); var dictionaryConfigLoc = Path.Combine(configSettingsDir, DictionaryConfigurationListener.DictionaryConfigurationDirectoryName); var reversalIndexConfigLoc = Path.Combine(configSettingsDir, DictionaryConfigurationListener.ReversalIndexConfigurationDirectoryName); var projectConfigPaths = new List <string>(ConfigFilesInDir(dictionaryConfigLoc)); projectConfigPaths.AddRange(ConfigFilesInDir(reversalIndexConfigLoc)); return(projectConfigPaths.Select(path => new DictionaryConfigurationModel(path, null)) .Where(model => model.Version < targetVersion).ToList()); }
public void GetValidConfigurationForPublication_PublicationThatMatchesNoConfigReturnsNull() { using (var helper = new UndoableUnitOfWorkHelper(Cache.ActionHandlerAccessor, "doit", "undoit")) { var testPubItem = Cache.ServiceLocator.GetInstance <ICmPossibilityFactory>().Create(); int enId = Cache.WritingSystemFactory.GetWsFromStr("en"); var testPubName = Cache.TsStrFactory.MakeString("NotTheTestPub", enId); Cache.LangProject.LexDbOA.PublicationTypesOA.PossibilitiesOS.Add(testPubItem); testPubItem.Name.set_String(enId, testPubName); var configSansTestPub = ConfigurationTemplate.Replace("</Publications>", "<Publication>NotTheTestPub</Publication></Publications>"); var overrideFiles = new List <TempFile>(); using (var docView = new TestXhtmlDocView()) { docView.SetConfigObjectName("Dictionary"); docView.SetMediator(m_mediator); var projConfigs = Path.Combine(FdoFileHelper.GetConfigSettingsDir(Cache.ProjectId.ProjectFolder), "Dictionary"); Directory.CreateDirectory(projConfigs); // override every shipped config with a config that does not have the TestPub publication var shippedFileList = Directory.EnumerateFiles(Path.Combine(FwDirectoryFinder.DefaultConfigurations, "Dictionary"), "*" + DictionaryConfigurationModel.FileExtension); var overrideCount = 0; foreach (var shippedFile in shippedFileList) { ++overrideCount; var tempFileName = Path.Combine(projConfigs, overrideCount + DictionaryConfigurationModel.FileExtension); var tempConfigFile = TempFile.WithFilename(tempFileName); overrideFiles.Add(tempConfigFile); using (var stream = new FileStream(shippedFile, FileMode.Open)) { var doc = new XmlDocument(); doc.Load(stream); var node = doc.SelectSingleNode("DictionaryConfiguration"); var shippedName = node.Attributes["name"].Value; File.WriteAllText(tempConfigFile.Path, configSansTestPub.Replace("name='AConfigPubtest'", "name='" + shippedName + "'")); } } // SUT var result = docView.GetValidConfigurationForPublication("TestPub"); // Delete all our temp files before asserting so they are sure to go away foreach (var tempFile in overrideFiles) { tempFile.Dispose(); } Assert.IsNull(result, "When no configurations have the publication null should be returned."); } } }
/// <summary> /// Stores the configuration name as the key, and the file path as the value /// User configuration files with the same name as a shipped configuration will trump the shipped /// </summary> /// <seealso cref="DictionaryConfigurationController.ListDictionaryConfigurationChoices()"/> public static SortedDictionary <string, string> GatherBuiltInAndUserConfigurations(FdoCache cache, string configObjectName) { var configurations = new SortedDictionary <string, string>(); var defaultConfigs = Directory.EnumerateFiles(Path.Combine(FwDirectoryFinder.DefaultConfigurations, configObjectName), "*" + DictionaryConfigurationModel.FileExtension); // for every configuration file in the DefaultConfigurations folder add an entry AddOrOverrideConfiguration(defaultConfigs, configurations); var projectConfigPath = Path.Combine(FdoFileHelper.GetConfigSettingsDir(cache.ProjectId.ProjectFolder), configObjectName); if (Directory.Exists(projectConfigPath)) { var projectConfigs = Directory.EnumerateFiles(projectConfigPath, "*" + DictionaryConfigurationModel.FileExtension); // for every configuration in the projects configurations folder either override a shipped configuration or add an entry AddOrOverrideConfiguration(projectConfigs, configurations); } return(configurations); }
public void GetProjectConfigurationDirectory_ReportsCorrectlyForDictionaryAndReversal() { var mediator = m_mediator; { string projectConfigDir; mediator.PropertyTable.SetProperty("currentContentControl", "lexiconEdit"); projectConfigDir = Path.Combine(FdoFileHelper.GetConfigSettingsDir(Cache.ProjectId.ProjectFolder), "Dictionary"); Assert.That(DictionaryConfigurationListener.GetProjectConfigurationDirectory(mediator), Is.EqualTo(projectConfigDir), "did not return expected directory"); mediator.PropertyTable.SetProperty("currentContentControl", "reversalToolEditComplete"); projectConfigDir = Path.Combine(FdoFileHelper.GetConfigSettingsDir(Cache.ProjectId.ProjectFolder), "ReversalIndex"); Assert.That(DictionaryConfigurationListener.GetProjectConfigurationDirectory(mediator), Is.EqualTo(projectConfigDir), "did not return expected directory"); mediator.PropertyTable.SetProperty("currentContentControl", "somethingElse"); Assert.IsNull(DictionaryConfigurationListener.GetProjectConfigurationDirectory(mediator), "Other areas should cause null return"); } }
public void MigrateOldConfigurationsIfNeeded_BringsPreHistoricFileToCurrentVersion() { var configSettingsDir = FdoFileHelper.GetConfigSettingsDir(Path.GetDirectoryName(Cache.ProjectId.Path)); var newConfigFilePath = Path.Combine(configSettingsDir, DictionaryConfigurationListener.DictionaryConfigurationDirectoryName, "Lexeme" + DictionaryConfigurationModel.FileExtension); Assert.False(File.Exists(newConfigFilePath), "should not yet be migrated"); Directory.CreateDirectory(configSettingsDir); File.WriteAllLines(Path.Combine(configSettingsDir, "Test.fwlayout"), new[] { @"<layoutType label='Lexeme-based (complex forms as main entries)' layout='publishStem'><configure class='LexEntry' label='Main Entry' layout='publishStemEntry' />", @"<configure class='LexEntry' label='Minor Entry' layout='publishStemMinorEntry' hideConfig='true' /></layoutType>'" }); var migrator = new DictionaryConfigurationMigrator(m_mediator); migrator.MigrateOldConfigurationsIfNeeded(); // SUT var updatedConfigModel = new DictionaryConfigurationModel(newConfigFilePath, Cache); Assert.AreEqual(DictionaryConfigurationMigrator.VersionCurrent, updatedConfigModel.Version); DirectoryUtilities.DeleteDirectoryRobust(configSettingsDir); }
public void GatherBuiltInAndUserConfigurations_ReturnsProjectAndShippedConfigs() { var configObjectName = "Dictionary"; var projectDictionaryConfigs = Path.Combine(FdoFileHelper.GetConfigSettingsDir(Cache.ProjectId.ProjectFolder), "Dictionary"); Directory.CreateDirectory(projectDictionaryConfigs); using (var tempConfigFile = TempFile.WithFilename(Path.Combine(projectDictionaryConfigs, "NotAShippingConfig" + DictionaryConfigurationModel.FileExtension))) { File.WriteAllText(tempConfigFile.Path, "<?xml version='1.0' encoding='utf-8'?><DictionaryConfiguration name='New User Config'/>"); // SUT var fileListFromResults = DictionaryConfigurationUtils.GatherBuiltInAndUserConfigurations(Cache, configObjectName).Values; var shippedFileList = Directory.EnumerateFiles(Path.Combine(FwDirectoryFinder.DefaultConfigurations, "Dictionary"), "*" + DictionaryConfigurationModel.FileExtension); // all the shipped configs are in the return list CollectionAssert.IsSubsetOf(shippedFileList, fileListFromResults); // new user configuration is present in results CollectionAssert.Contains(fileListFromResults, tempConfigFile.Path); } }
public void GetValidConfigurationForPublication_ConfigurationContainingPubIsPicked() { using (var helper = new UndoableUnitOfWorkHelper(Cache.ActionHandlerAccessor, "doit", "undoit")) { var testPubItem = Cache.ServiceLocator.GetInstance <ICmPossibilityFactory>().Create(); int enId = Cache.WritingSystemFactory.GetWsFromStr("en"); var testPubName = Cache.TsStrFactory.MakeString("TestPub", enId); Cache.LangProject.LexDbOA.PublicationTypesOA.PossibilitiesOS.Add(testPubItem); testPubItem.Name.set_String(enId, testPubName); var notTestPubItem = Cache.ServiceLocator.GetInstance <ICmPossibilityFactory>().Create(); var notTestPubName = Cache.TsStrFactory.MakeString("NotTestPub", enId); Cache.LangProject.LexDbOA.PublicationTypesOA.PossibilitiesOS.Add(notTestPubItem); notTestPubItem.Name.set_String(enId, notTestPubName); var nonMatchingConfig = ConfigurationTemplate.Replace("</Publications>", "<Publication>NotTestPub</Publication></Publications>"); //Change the name for the matching config so that our two user configs don't conflict with each other var matchingConfig = ConfigurationTemplate.Replace("</Publications>", "<Publication>TestPub</Publication></Publications>").Replace("AConfigPub", "AAConfigPub"); var dictionaryConfigPath = Path.Combine(FdoFileHelper.GetConfigSettingsDir(Cache.ProjectId.ProjectFolder), "Dictionary"); using (var docView = new TestXhtmlDocView()) using (var nonMatchedConfigFile = TempFile.WithFilename(Path.Combine(dictionaryConfigPath, "NoMatch" + DictionaryConfigurationModel.FileExtension))) using (var matchedConfigFile = TempFile.WithFilename(Path.Combine(dictionaryConfigPath, "Match" + DictionaryConfigurationModel.FileExtension))) { File.WriteAllText(nonMatchedConfigFile.Path, nonMatchingConfig); File.WriteAllText(matchedConfigFile.Path, matchingConfig); docView.SetConfigObjectName("Dictionary"); m_mediator.PropertyTable.SetProperty("currentContentControl", "lexiconDictionary", false); m_mediator.PropertyTable.SetProperty("DictionaryPublicationLayout", nonMatchedConfigFile.Path); docView.SetMediator(m_mediator); // SUT var validConfig = docView.GetValidConfigurationForPublication("TestPub"); Assert.That(validConfig, Is.Not.StringContaining(nonMatchedConfigFile.Path)); Assert.That(validConfig, Is.StringContaining(matchedConfigFile.Path)); } } }
public void MigrateOldConfigurationsIfNeeded_PreservesOrderOfBibliographies() { var configSettingsDir = FdoFileHelper.GetConfigSettingsDir(Path.GetDirectoryName(Cache.ProjectId.Path)); var newConfigFilePath = Path.Combine(configSettingsDir, DictionaryConfigurationListener.ReversalIndexConfigurationDirectoryName, "AllReversalIndexes" + DictionaryConfigurationModel.FileExtension); Assert.False(File.Exists(newConfigFilePath), "should not yet be migrated"); Directory.CreateDirectory(configSettingsDir); File.WriteAllLines(Path.Combine(configSettingsDir, "Test.fwlayout"), new[] { @"<layoutType label='All Reversal Indexes' layout='publishReversal'>", @"<configure class='ReversalIndexEntry' label='Reversal Entry' layout='publishReversalEntry' /></layoutType>'" }); var migrator = new DictionaryConfigurationMigrator(m_mediator); migrator.MigrateOldConfigurationsIfNeeded(); // SUT var updatedConfigModel = new DictionaryConfigurationModel(newConfigFilePath, Cache); var refdSenseChildren = updatedConfigModel.Parts[0].Children.Find(n => n.Label == "Referenced Senses").Children; var bibCount = 0; for (var i = 0; i < refdSenseChildren.Count; i++) { var bibNode = refdSenseChildren[i]; if (!bibNode.Label.StartsWith("Bibliography")) { continue; } StringAssert.StartsWith("Bibliography (", bibNode.Label, "Should specify (entry|sense), lest we never know"); Assert.False(bibNode.IsCustomField, bibNode.Label + " should not be custom."); // Rough test to ensure Bibliography nodes aren't bumped to the end of the list. In the defaults, the later Bibliography // node is a little more than five nodes from the end Assert.LessOrEqual(i, refdSenseChildren.Count - 5, "Bibliography nodes should not have been bumped to the end of the list"); ++bibCount; } Assert.AreEqual(2, bibCount, "Should be exactly two Bibliography nodes (sense and entry)"); DirectoryUtilities.DeleteDirectoryRobust(configSettingsDir); }
/// <remarks>Useful for querying about an area of FLEx that the user is not in.</remarks> internal static string GetProjectConfigurationDirectory(Mediator mediator, string area) { var cache = (FdoCache)mediator.PropertyTable.GetValue("cache"); return(area == null ? null : Path.Combine(FdoFileHelper.GetConfigSettingsDir(cache.ProjectId.ProjectFolder), area)); }