Skip to content

Commit be6915f

Browse files
committed
fixed settings import bug...
1 parent be05c57 commit be6915f

3 files changed

Lines changed: 315 additions & 8 deletions

File tree

src/LogExpert.Configuration/ConfigManager.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ public ImportResult Import (FileInfo fileInfo, ExportImportFlags importFlags)
196196
// Handle any critical errors from loading
197197
if (loadResult.CriticalFailure)
198198
{
199-
return ImportResult.Failed("Import Failed", $"Import file is invalid or corrupted:\n\n{loadResult.CriticalMessage}\n\nImport cancelled.");
199+
return ImportResult.Failed("Import Failed", $"Import file is invalid or corrupted:\n\n{loadResult.CriticalMessage}\n\nImport canceled.");
200200
}
201201

202202
importedSettings = loadResult.Settings;
@@ -205,7 +205,7 @@ public ImportResult Import (FileInfo fileInfo, ExportImportFlags importFlags)
205205
JsonSerializationException)
206206
{
207207
_logger.Error($"Import file is invalid or corrupted: {ex}");
208-
return ImportResult.Failed("Import Failed", $"Import file is invalid or corrupted:\n\n{ex.Message}\n\nImport cancelled.");
208+
return ImportResult.Failed("Import Failed", $"Import file is invalid or corrupted:\n\n{ex.Message}\n\nImport canceled.");
209209
}
210210

211211
if (SettingsAreEmptyOrDefault(importedSettings))
@@ -228,8 +228,8 @@ public ImportResult Import (FileInfo fileInfo, ExportImportFlags importFlags)
228228
$"History={importedSettings.FileHistoryList?.Count ?? 0}, " +
229229
$"Highlights={importedSettings.Preferences?.HighlightGroupList?.Count ?? 0}");
230230

231-
// Proceed with import
232-
Instance._settings = Instance.Import(Instance._settings, fileInfo, importFlags);
231+
// Proceed with import - Use Settings property to ensure _settings is initialized
232+
_settings = Instance.Import(Instance.Settings, fileInfo, importFlags);
233233
Save(SettingsFlags.All);
234234

235235
_logger.Info("Import completed successfully");

src/LogExpert.Core/Classes/ObjectClone.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
using System.IO;
21
using System.Text.Json;
32

43
namespace LogExpert.Core.Classes;
@@ -7,12 +6,12 @@ public static class ObjectClone
76
{
87
#region Public methods
98

10-
public static T Clone<T>(T RealObject)
9+
public static T Clone<T> (T realObject)
1110
{
1211
using MemoryStream objectStream = new();
1312

14-
JsonSerializer.Serialize(objectStream, RealObject);
15-
objectStream.Seek(0, SeekOrigin.Begin);
13+
JsonSerializer.Serialize(objectStream, realObject);
14+
_ = objectStream.Seek(0, SeekOrigin.Begin);
1615
return JsonSerializer.Deserialize<T>(objectStream);
1716
}
1817

src/LogExpert.Tests/ConfigManagerTest.cs

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public class ConfigManagerTest
2323
private ConfigManager _configManager;
2424

2525
[SetUp]
26+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
2627
public void SetUp ()
2728
{
2829
// Create isolated test directory for each test
@@ -547,6 +548,313 @@ public void LoadOrCreateNew_InvalidJSON_HandlesGracefully ()
547548

548549
#endregion
549550

551+
#region Import Method Tests
552+
553+
[Test]
554+
[Category("Import")]
555+
[Description("Import should handle null _settings field by using Settings property")]
556+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
557+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters", Justification = "Unit Test")]
558+
public void Import_WithUninitializedSettings_ShouldNotThrowNullReference ()
559+
{
560+
// Arrange
561+
// Create a valid import file
562+
Settings importSettings = CreatePopulatedSettings();
563+
importSettings.FilterList.Clear();
564+
importSettings.FilterList.Add(new FilterParams { SearchText = "IMPORTED_FILTER" });
565+
566+
string importFilePath = Path.Join(_testDir, "import_test.json");
567+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
568+
FileInfo importFile = new(importFilePath);
569+
570+
// Act & Assert - This should not throw NullReferenceException
571+
ImportResult result = null;
572+
Assert.DoesNotThrow(() => result = _configManager.Import(importFile, ExportImportFlags.All), "Import should not throw NullReferenceException when _settings is uninitialized");
573+
574+
Assert.That(result, Is.Not.Null);
575+
Assert.That(result.Success, Is.True, "Import should succeed");
576+
}
577+
578+
[Test]
579+
[Category("Import")]
580+
[Description("Import should validate that import file exists")]
581+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
582+
public void Import_WithNonExistentFile_ShouldReturnFailure ()
583+
{
584+
// Arrange
585+
FileInfo nonExistentFile = new(Path.Join(_testDir, "does_not_exist.json"));
586+
587+
// Act
588+
ImportResult result = _configManager.Import(nonExistentFile, ExportImportFlags.All);
589+
590+
// Assert
591+
Assert.That(result, Is.Not.Null);
592+
Assert.That(result.Success, Is.False, "Import should fail for non-existent file");
593+
Assert.That(result.ErrorMessage, Does.Contain("not found").IgnoreCase);
594+
}
595+
596+
[Test]
597+
[Category("Import")]
598+
[Description("Import should validate that import file is not null")]
599+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
600+
public void Import_WithNullFileInfo_ShouldReturnFailure ()
601+
{
602+
// Act
603+
ImportResult result = _configManager.Import(null, ExportImportFlags.All);
604+
605+
// Assert
606+
Assert.That(result, Is.Not.Null);
607+
Assert.That(result.Success, Is.False, "Import should fail for null file");
608+
Assert.That(result.ErrorMessage, Does.Contain("not found").IgnoreCase);
609+
}
610+
611+
[Test]
612+
[Category("Import")]
613+
[Description("Import should detect corrupted import files")]
614+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
615+
public void Import_WithCorruptedFile_ShouldReturnFailure ()
616+
{
617+
// Arrange
618+
string importFilePath = Path.Join(_testDir, "corrupt_import.json");
619+
File.WriteAllText(importFilePath, "{invalid json}");
620+
FileInfo importFile = new(importFilePath);
621+
622+
// Act
623+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.All);
624+
625+
// Assert
626+
Assert.That(result, Is.Not.Null);
627+
Assert.That(result.Success, Is.False, "Import should fail for corrupted file");
628+
Assert.That(result.ErrorMessage, Does.Contain("invalid").Or.Contain("corrupted").IgnoreCase);
629+
}
630+
631+
[Test]
632+
[Category("Import")]
633+
[Description("Import should detect empty/default settings and require confirmation")]
634+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
635+
public void Import_WithEmptySettings_ShouldRequireConfirmation ()
636+
{
637+
// Arrange
638+
Settings emptySettings = CreateTestSettings();
639+
string importFilePath = Path.Join(_testDir, "empty_import.json");
640+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(emptySettings));
641+
FileInfo importFile = new(importFilePath);
642+
643+
// Act
644+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.All);
645+
646+
// Assert
647+
Assert.That(result, Is.Not.Null);
648+
Assert.That(result.RequiresUserConfirmation, Is.True, "Empty settings should require confirmation");
649+
Assert.That(result.ConfirmationMessage, Does.Contain("empty").Or.Contain("default").IgnoreCase);
650+
}
651+
652+
[Test]
653+
[Category("Import")]
654+
[Description("Import should successfully import valid populated settings")]
655+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
656+
public void Import_WithValidPopulatedSettings_ShouldSucceed ()
657+
{
658+
// Arrange
659+
Settings importSettings = CreatePopulatedSettings();
660+
importSettings.FilterList.Clear();
661+
importSettings.FilterList.Add(new FilterParams { SearchText = "IMPORT_TEST_FILTER" });
662+
importSettings.SearchHistoryList.Clear();
663+
importSettings.SearchHistoryList.Add("IMPORT_TEST_SEARCH");
664+
665+
string importFilePath = Path.Join(_testDir, "valid_import.json");
666+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
667+
FileInfo importFile = new(importFilePath);
668+
669+
// Act
670+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.All);
671+
672+
// Assert
673+
Assert.That(result, Is.Not.Null);
674+
Assert.That(result.Success, Is.True, "Import should succeed with valid settings");
675+
676+
// Verify settings were actually imported
677+
Settings currentSettings = _configManager.Settings;
678+
Assert.That(currentSettings.FilterList.Any(f => f.SearchText == "IMPORT_TEST_FILTER"), Is.True,
679+
"Imported filter should be present");
680+
}
681+
682+
[Test]
683+
[Category("Import")]
684+
[Description("Import with Other flag should merge preferences correctly")]
685+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
686+
public void Import_WithOtherFlag_ShouldMergePreferences ()
687+
{
688+
// Arrange
689+
// Set up current settings
690+
Settings currentSettings = _configManager.Settings;
691+
currentSettings.Preferences.FontSize = 10;
692+
currentSettings.Preferences.ColumnizerMaskList.Clear();
693+
694+
// Create import settings with different preferences
695+
Settings importSettings = CreateTestSettings();
696+
importSettings.Preferences.FontSize = 12;
697+
importSettings.Preferences.ShowBubbles = true;
698+
699+
string importFilePath = Path.Join(_testDir, "import_other.json");
700+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
701+
FileInfo importFile = new(importFilePath);
702+
703+
// Act
704+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.Other);
705+
706+
// Assert
707+
Assert.That(result, Is.Not.Null);
708+
Assert.That(result.Success, Is.True);
709+
710+
Settings updatedSettings = _configManager.Settings;
711+
Assert.That(updatedSettings.Preferences.FontSize, Is.EqualTo(12),
712+
"Preferences should be merged from import file");
713+
}
714+
715+
[Test]
716+
[Category("Import")]
717+
[Description("Import with ColumnizerMasks flag should import columnizer masks")]
718+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
719+
public void Import_WithColumnizerMasksFlag_ShouldImportMasks ()
720+
{
721+
// Arrange
722+
Settings importSettings = CreateTestSettings();
723+
importSettings.Preferences.ColumnizerMaskList.Add(new ColumnizerMaskEntry { Mask = "*.log", ColumnizerName = "TestColumnizer" });
724+
725+
string importFilePath = Path.Join(_testDir, "import_columnizer.json");
726+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
727+
FileInfo importFile = new(importFilePath);
728+
729+
// Act
730+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.ColumnizerMasks);
731+
732+
// Assert
733+
Assert.That(result, Is.Not.Null);
734+
Assert.That(result.Success, Is.True);
735+
736+
Settings updatedSettings = _configManager.Settings;
737+
Assert.That(updatedSettings.Preferences.ColumnizerMaskList.Count, Is.GreaterThan(0),
738+
"Columnizer masks should be imported");
739+
}
740+
741+
[Test]
742+
[Category("Import")]
743+
[Description("Import with KeepExisting flag should merge rather than replace")]
744+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
745+
public void Import_WithKeepExistingFlag_ShouldMergeSettings ()
746+
{
747+
// Arrange
748+
// Set up current settings with existing data
749+
Settings currentSettings = _configManager.Settings;
750+
currentSettings.FilterList.Clear();
751+
currentSettings.FilterList.Add(new FilterParams { SearchText = "EXISTING_FILTER" });
752+
753+
// Create import settings with different data
754+
Settings importSettings = CreateTestSettings();
755+
importSettings.FilterList.Clear();
756+
importSettings.FilterList.Add(new FilterParams { SearchText = "NEW_FILTER" });
757+
758+
string importFilePath = Path.Join(_testDir, "import_keep_existing.json");
759+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
760+
FileInfo importFile = new(importFilePath);
761+
762+
// Act
763+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.ColumnizerMasks | ExportImportFlags.KeepExisting);
764+
765+
// Assert
766+
Assert.That(result, Is.Not.Null);
767+
Assert.That(result.Success, Is.True);
768+
769+
// Both should be present when using KeepExisting
770+
// Note: This test may need adjustment based on actual merge behavior
771+
}
772+
773+
[Test]
774+
[Category("Import")]
775+
[Description("Import should handle null Preferences in import file gracefully")]
776+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
777+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters", Justification = "Unit Test")]
778+
public void Import_WithNullPreferences_ShouldHandleGracefully ()
779+
{
780+
// Arrange
781+
var importSettings = new Settings
782+
{
783+
Preferences = null, // Deliberately null
784+
FilterList = [new() { SearchText = "TEST" }]
785+
};
786+
787+
string importFilePath = Path.Join(_testDir, "import_null_prefs.json");
788+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
789+
FileInfo importFile = new(importFilePath);
790+
791+
// Act & Assert
792+
ImportResult result = null;
793+
Assert.DoesNotThrow(() => result = _configManager.Import(importFile, ExportImportFlags.All), "Import should handle null Preferences gracefully");
794+
795+
Assert.That(result, Is.Not.Null);
796+
// May fail validation or require confirmation due to null Preferences
797+
}
798+
799+
[Test]
800+
[Category("Import")]
801+
[Description("Multiple imports should maintain consistency")]
802+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
803+
public void Import_MultipleImports_ShouldMaintainConsistency ()
804+
{
805+
// Arrange & Act - Multiple imports
806+
for (int i = 0; i < 3; i++)
807+
{
808+
Settings importSettings = CreateTestSettings();
809+
importSettings.FilterList.Add(new FilterParams { SearchText = $"IMPORT_{i}" });
810+
811+
string importFilePath = Path.Join(_testDir, $"import_{i}.json");
812+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
813+
FileInfo importFile = new(importFilePath);
814+
815+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.All);
816+
Assert.That(result.Success, Is.True, $"Import {i} should succeed");
817+
}
818+
819+
// Assert - Final state should be consistent
820+
Settings finalSettings = _configManager.Settings;
821+
Assert.That(finalSettings, Is.Not.Null);
822+
Assert.That(finalSettings.Preferences, Is.Not.Null);
823+
}
824+
825+
[Test]
826+
[Category("Import")]
827+
[Description("Import should save settings after successful import")]
828+
[System.Diagnostics.CodeAnalysis.SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Unit Test")]
829+
public void Import_SuccessfulImport_ShouldSaveSettings ()
830+
{
831+
// Arrange
832+
Settings importSettings = CreatePopulatedSettings();
833+
importSettings.FilterList.Clear();
834+
importSettings.FilterList.Add(new FilterParams { SearchText = "SAVE_TEST_FILTER" });
835+
836+
string importFilePath = Path.Join(_testDir, "import_save_test.json");
837+
File.WriteAllText(importFilePath, JsonConvert.SerializeObject(importSettings));
838+
FileInfo importFile = new(importFilePath);
839+
840+
// Act
841+
ImportResult result = _configManager.Import(importFile, ExportImportFlags.All);
842+
843+
// Assert
844+
Assert.That(result.Success, Is.True);
845+
846+
// Verify settings were saved by loading them
847+
string settingsFile = Path.Join(_testDir, "settings.json");
848+
if (File.Exists(settingsFile))
849+
{
850+
string content = File.ReadAllText(settingsFile);
851+
Assert.That(content, Does.Contain("SAVE_TEST_FILTER"),
852+
"Imported settings should be saved to disk");
853+
}
854+
}
855+
856+
#endregion
857+
550858
#region Integration Tests
551859

552860
[Test]

0 commit comments

Comments
 (0)