Exemple #1
0
        public void TestTLKs()
        {
            GlobalTest.Init();

            Console.WriteLine(@"Testing TLK operations");
            var tlksDir = Path.Combine(GlobalTest.FindDirectoryInParentDirectories(GlobalTest.TESTDATA_FOLDER_NAME), "tlk", "me3");

            var tlksToTestOn = Directory.GetFiles(tlksDir, "*.tlk", SearchOption.AllDirectories);

            foreach (var tlk in tlksToTestOn)
            {
                TalkFile talkFileMe2 = new TalkFile();
                talkFileMe2.LoadTlkData(tlk);
                var tlkStream   = ME3ExplorerCore.TLK.ME2ME3.HuffmanCompression.SaveToTlkStream(talkFileMe2.StringRefs);
                var reloadedTlk = new TalkFile();
                tlkStream.Position = 0;
                reloadedTlk.LoadTlkDataFromStream(tlkStream);

                foreach (var v in talkFileMe2.StringRefs)
                {
                    var fd = reloadedTlk.findDataById(v.StringID);

                    if (fd == "\"Male\"")
                    {
                        continue;                   //Male/Female, we don't have way to distinguish these
                    }
                    Assert.AreEqual($"\"{v.Data}\"", fd);
                }
            }
        }
Exemple #2
0
        public void ValidateTargetsME3()
        {
            GlobalTest.Init();
            var root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME3);

            Console.WriteLine("TargetTesting: Game directories folder for ME3: " + root);

            var normal = Path.Combine(root, "normal");

            //correct game
            GameTarget gt            = new GameTarget(Mod.MEGame.ME3, normal, false);
            var        failureReason = gt.ValidateTarget();

            Assert.IsNull(failureReason, "GameTarget for ME3 Normal should not have returned a failure string when validating against the correct game. Failure reason returned: " + failureReason);
            Assert.IsTrue(gt.IsValid, "GameTarget for ME3 Normal should have been marked as valid when validating against the correct game, but it wasn't");

            //wrong game
            gt            = new GameTarget(Mod.MEGame.ME1, normal, false);
            failureReason = gt.ValidateTarget();
            Assert.IsNotNull(failureReason, "GameTarget for ME3 Normal should have returned a failure string when validating against the wrong game (ME1), but none was returned");
            Assert.IsFalse(gt.IsValid, "GameTarget for ME3 Normal should have been marked as invalid when validating against the wrong game (ME1), but wasn't");

            gt            = new GameTarget(Mod.MEGame.ME2, normal, false);
            failureReason = gt.ValidateTarget();
            Assert.IsNotNull(failureReason, "GameTarget for ME3 Normal should have returned a failure string when validating against the wrong game (ME2), but none was returned");
            Assert.IsFalse(gt.IsValid, "GameTarget for ME3 Normal should have been marked as invalid when validating against the wrong game (ME2), but wasn't");
        }
Exemple #3
0
        public void InitialUILoadTest()
        {
            GlobalTest.Init();
            App app = new App(); //Pre boot
            //Thread thread = new Thread(() =>
            //{
            //    app.InitializeComponent();
            //    app.Run();
            //});
            //thread.SetApartmentState(ApartmentState.STA);
            //thread.Start();
            //thread.Join();
            //var shutdownTimer = new System.Timers.Timer();
            //shutdownTimer.Interval = 15000;
            //shutdownTimer.Elapsed += (o, e) =>
            //{
            //    app.Shutdown();
            //    app = null;

            //};

            //shutdownTimer.Start();
            //while (app != null)
            //{
            //    Thread.Sleep(1000);
            //}
        }
        public void ValidateArchiveModLoading()
        {
            GlobalTest.Init();

            Console.WriteLine("Fetching third party services");
            App.ThirdPartyImportingService      = OnlineContent.FetchThirdPartyImportingService();
            App.ThirdPartyIdentificationService = OnlineContent.FetchThirdPartyIdentificationManifest();

            var        compressedModsDirectory = Path.Combine(GlobalTest.FindDirectoryInParentDirectories(GlobalTest.TESTDATA_FOLDER_NAME), "compressedmods");
            List <Mod> modsFoundInArchive      = new List <Mod>();

            void addModCallback(Mod m)
            {
                Console.WriteLine($"Found mod in archive: {m.ModName}");
                modsFoundInArchive.Add(m);
            }

            void failedModCallback(Mod m)
            {
                Console.WriteLine($"A mod failed to load. This may be expected: {m.ModName}");
            }

            void logMessageCallback(string m)
            {
                Console.WriteLine(m);
            }

            foreach (var archive in Directory.GetFiles(compressedModsDirectory))
            {
                modsFoundInArchive.Clear();
                var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(archive);
                Console.WriteLine($"Inspecting archive: { archive}");
                ModArchiveImporter.InspectArchive(archive, addModCallback, failedModCallback, logMessageCallback, forcedMD5: realArchiveInfo.md5, forcedSize: realArchiveInfo.size);
                Assert.AreEqual(realArchiveInfo.nummodsexpected, modsFoundInArchive.Count(x => x.ValidMod), $"{archive} did not parse correct amount of mods.");

                foreach (var v in modsFoundInArchive)
                {
                    var cookedName = v.Game == MEGame.ME3 ? @"CookedPCConsole" : "CookedPC";
                    // Check nothing has FilesToInstall containing two 'CookedPCConsole' items in the string.
                    // This is fun edge case due to TESTPATCH having two names DLC_TestPatch and TESTPATCH

                    foreach (var mj in v.InstallationJobs)
                    {
                        foreach (var fti in mj.FilesToInstall)
                        {
                            var numAppearances = Regex.Matches(fti.Key, cookedName).Count;
                            if (numAppearances > 1)
                            {
                                Assert.Fail($@"Found more than 1 instance of {cookedName} in FilesToInstall targetpath item {fti.Key}! This indicates queue building was wrong. Mod: {v.ModName}, file {archive}");
                            }
                        }
                    }
                }
            }
        }
Exemple #5
0
        public void TestMixins()
        {
            GlobalTest.Init();

            var me3BackupPath = BackupService.GetGameBackupPath(MEGame.ME3);

            if (me3BackupPath != null)
            {
                GlobalTest.CreateScratchDir();
                MixinHandler.LoadME3TweaksPackage();
                // We can conduct this test
                var mixins = MixinHandler.ME3TweaksPackageMixins.Where(x => !x.IsFinalizer).ToList();
                MixinHandler.LoadPatchDataForMixins(mixins);

                List <string> failedMixins = new List <string>();
                void failedApplicationCallback(string str)
                {
                    failedMixins.Add(str);
                }

                var compilingListsPerModule = MixinHandler.GetMixinApplicationList(mixins, failedApplicationCallback);

                //Mixins are ready to be applied
                var outdir = Path.Combine(Path.Combine(GlobalTest.GetScratchDir(), "MixinTest"));
                Utilities.DeleteFilesAndFoldersRecursively(outdir);
                Directory.CreateDirectory(outdir);
                foreach (var mapping in compilingListsPerModule)
                {
                    MixinManager.ApplyMixinsToModule(mapping, outdir, null, failedApplicationCallback);
                }

                MixinHandler.FreeME3TweaksPatchData();
                GlobalTest.DeleteScratchDir();
                if (failedMixins.Any())
                {
                    Assert.Fail($"MixinTests failed. {failedMixins.Count} mixins failed to apply.");
                }
            }
            else
            {
                Console.WriteLine(@"No backup for ME3 is available. MixinTests will be skipped.");
            }
        }
Exemple #6
0
        public void InitialUILoadTest()
        {
            GlobalTest.Init();
            App app = new App(); //Pre boot

            var xamlPaths = Path.Combine(GlobalTest.FindDirectoryInParentDirectories("MassEffectModManagerCore"), "modmanager", "localizations");
            var files     = Directory.GetFiles(xamlPaths, "*.xaml");

            foreach (var filepath in files)
            {
                // Will throw exception if there's an error loading the file
                Console.WriteLine($@"Loading localization file {filepath}");
                XamlReader.Load(new XmlTextReader(filepath));
            }

            //Thread thread = new Thread(() =>
            //{
            //    app.InitializeComponent();
            //    app.Run();
            //});
            //thread.SetApartmentState(ApartmentState.STA);
            //thread.Start();
            //thread.Join();
            //var shutdownTimer = new System.Timers.Timer();
            //shutdownTimer.Interval = 15000;
            //shutdownTimer.Elapsed += (o, e) =>
            //{
            //    app.Shutdown();
            //    app = null;

            //};

            //shutdownTimer.Start();
            //while (app != null)
            //{
            //    Thread.Sleep(1000);
            //}
        }
Exemple #7
0
        public void ValidateArchiveModLoading()
        {
            GlobalTest.Init();

            Console.WriteLine("Fetching third party services");
            App.ThirdPartyImportingService      = OnlineContent.FetchThirdPartyImportingService();
            App.ThirdPartyIdentificationService = OnlineContent.FetchThirdPartyIdentificationManifest();

            var        compressedModsDirectory = Path.Combine(GlobalTest.GetTestDataDirectory(), "compressedmods");
            List <Mod> modsFoundInArchive      = new List <Mod>();

            void addModCallback(Mod m)
            {
                Console.WriteLine($"Found mod in archive: {m.ModName}");
                modsFoundInArchive.Add(m);
            }

            void failedModCallback(Mod m)
            {
                Console.WriteLine($"A mod failed to load. This may be expected: {m.ModName}");
            }

            void logMessageCallback(string m)
            {
                Console.WriteLine(m);
            }

            foreach (var archive in Directory.GetFiles(compressedModsDirectory))
            {
                modsFoundInArchive.Clear();
                var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(archive);
                Console.WriteLine($"Inspecting archive: { archive}");
                ModArchiveImporter.InspectArchive(archive, addModCallback, failedModCallback, logMessageCallback, forcedMD5: realArchiveInfo.md5, forcedSize: realArchiveInfo.size);
                Assert.AreEqual(realArchiveInfo.nummodsexpected, modsFoundInArchive.Count, $"{archive} did not parse correct amount of mods.");
            }
        }
        public void ValidateOnlineFetches()
        {
            GlobalTest.Init();
            var helpItems = OnlineContent.FetchLatestHelp("int", false, true);

            Assert.AreNotEqual(0, helpItems.Count, "FetchLatestHelp failed: No items were parsed, the list is empty!");
            helpItems.Sort();

            var tips = OnlineContent.FetchTipsService(true);

            Assert.AreNotEqual(0, tips.Count, "FetchTipsService failed: No items were parsed, the list is empty!");

            var tpmiService = OnlineContent.FetchThirdPartyImportingService(true);

            Assert.AreNotEqual(0, tpmiService.Count, "FetchThirdPartyImportingService failed: No items were parsed, the list is empty!");

            var bgfis = OnlineContent.FetchBasegameFileIdentificationServiceManifest(true);

            Assert.AreNotEqual(0, bgfis.Count, "FetchBasegameIdentificationServiceManifest failed: No items were parsed, the list is empty!");

            var startupManifest = OnlineContent.FetchOnlineStartupManifest(true);

            Assert.AreNotEqual(0, startupManifest.Count, "FetchOnlineStartupManifest failed: No items were parsed, the list is empty!");
        }
Exemple #9
0
        public void TestBuildingExtractionQueues()
        {
            GlobalTest.Init();

            Console.WriteLine("Fetching third party services");
            App.ThirdPartyImportingService      = OnlineContent.FetchThirdPartyImportingService();
            App.ThirdPartyIdentificationService = OnlineContent.FetchThirdPartyIdentificationManifest();

            var        compressedModsDirectory = Path.Combine(GlobalTest.GetTestDataDirectory(), "compressedmods");
            List <Mod> modsFoundInArchive      = new List <Mod>();

            void addModCallback(Mod m)
            {
                Console.WriteLine($"Found mod in archive: {m.ModName}");
                modsFoundInArchive.Add(m);
            }

            void failedModCallback(Mod m)
            {
                //Console.WriteLine($"A mod failed to load. This may be expected: {m.ModName}");
            }

            void logMessageCallback(string m)
            {
                Console.WriteLine(m);
            }

            #region Get Targets
            List <GameTarget> targets = new List <GameTarget>();
            var root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME1);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(Mod.MEGame.ME1, d, false, false);
                gt.ValidateTarget();
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME2);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(Mod.MEGame.ME2, d, false, false);
                gt.ValidateTarget();
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME3);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(Mod.MEGame.ME3, d, false, false);
                gt.ValidateTarget();
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            #endregion

            //Compressed Mods

            foreach (var archive in Directory.GetFiles(compressedModsDirectory))
            {
                modsFoundInArchive.Clear();
                var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(archive);
                Console.WriteLine($@"Inspecting archive: { archive}");
                ModArchiveImporter.InspectArchive(archive, addModCallback, failedModCallback, logMessageCallback, forcedMD5: realArchiveInfo.md5, forcedSize: realArchiveInfo.size);
                var archiveZ = new SevenZipExtractor(archive);
                foreach (var mod in modsFoundInArchive)
                {
                    bool altsOn = false;
                    while (true)
                    {
                        if (altsOn)
                        {
                            foreach (var job in mod.InstallationJobs)
                            {
                                List <string> selectedGroups = new List <string>();
                                foreach (var altfile in job.AlternateFiles)
                                {
                                    if (altfile.GroupName != null)
                                    {
                                        if (selectedGroups.Contains(altfile.GroupName))
                                        {
                                            continue; //we already did first time of this. I know that's a weak test case...
                                        }
                                        selectedGroups.Add(altfile.GroupName);
                                    }

                                    altfile.IsSelected = true;
                                }
                            }
                        }

                        var refs = mod.GetAllRelativeReferences(!mod.IsVirtualized, archiveZ); //test
                        //validate references are actually in this archive
                        foreach (var fileREf in refs)
                        {
                            var expectedPath = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, fileREf);
                            //var expectedPath = fileREf;
                            var inArchiveFile = archiveZ.ArchiveFileData.FirstOrDefault(x => x.FileName == expectedPath);
                            Assert.IsNotNull(inArchiveFile.FileName, "Relative referenced file was not found in archive: " + fileREf);
                        }

                        //size test
                        Assert.AreNotEqual(0, mod.SizeRequiredtoExtract, "Archive extraction size is zero! For file " + archive);

                        var targetsForMod = targets.Where(x => x.Game == mod.Game).ToList();
                        foreach (var target in targetsForMod)
                        {
                            var queue = mod.GetInstallationQueues(target);
                            foreach (var jobMapping in queue.Item1)
                            {
                                foreach (var unpackedItem in jobMapping.Value.unpackedJobMapping)
                                {
                                    string sourceFile;
                                    if (jobMapping.Key.JobDirectory == null || unpackedItem.Value.IsFullRelativeFilePath)
                                    {
                                        sourceFile = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, unpackedItem.Value.FilePath);
                                    }
                                    else
                                    {
                                        sourceFile = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, jobMapping.Key.JobDirectory, unpackedItem.Value.FilePath);
                                    }
                                    Assert.IsTrue(archiveZ.ArchiveFileNames.Contains(sourceFile), "Archive should contain a file specified by mod (mod is valid) but does not appear to. File: " + sourceFile);
                                }
                            }
                        }

                        if (!altsOn)
                        {
                            altsOn = true;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
            }

            //EXE mods
            var exeModsDirectory = Path.Combine(GlobalTest.GetTestDataDirectory(), "exemods");

            if (Directory.Exists(exeModsDirectory))
            {
                foreach (var exe in Directory.GetFiles(exeModsDirectory))
                {
                    modsFoundInArchive.Clear();
                    //var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(exe);
                    Console.WriteLine($@"Inspecting exe: { exe}");
                    ModArchiveImporter.InspectArchive(exe, addModCallback, failedModCallback, logMessageCallback);
                    var archiveZ = new SevenZipExtractor(exe, InArchiveFormat.Nsis);
                    foreach (var mod in modsFoundInArchive)
                    {
                        foreach (var job in mod.InstallationJobs)
                        {
                            List <string> selectedGroups = new List <string>();
                            foreach (var altfile in job.AlternateFiles)
                            {
                                if (altfile.GroupName != null)
                                {
                                    if (selectedGroups.Contains(altfile.GroupName))
                                    {
                                        continue; //we already did first time of this. I know that's a weak test case...
                                    }
                                    selectedGroups.Add(altfile.GroupName);
                                }

                                altfile.IsSelected = true;
                            }
                        }


                        var refs = mod.GetAllRelativeReferences(false, archiveZ); //test and get refs. exe mods will always be virtualized as they won't have a moddesc.ini file.
                                                                                  //exe mods remap to subconetns
                                                                                  //same code as Mod-Extraction.cs
                        foreach (var fileREf in refs)
                        {
                            var expectedPath = FilesystemInterposer.PathCombine(mod.IsInArchive, mod.ModPath, fileREf);
                            //var expectedPath = fileREf;
                            var inArchiveFile = archiveZ.ArchiveFileData.FirstOrDefault(x => x.FileName == expectedPath);
                            Assert.IsNotNull(inArchiveFile.FileName, "Relative referenced file was not found in archive: " + fileREf);
                        }

                        mod.ExtractFromArchive(exe, "", false, testRun: true);
                    }
                }
            }
            else
            {
                Console.WriteLine("No exemods directory found. This section of testing will be skipped");
            }
        }
Exemple #10
0
        public void ValidateModLoading()
        {
            GlobalTest.Init();
            Console.WriteLine("Executing path: " + GlobalTest.GetTestModsDirectory());
            var testingDataPath = GlobalTest.GetTestModsDirectory();

            Assert.IsTrue(Directory.Exists(testingDataPath), "Directory for testing doesn't exist: " + testingDataPath);

            //Force log startup on.


            //Test cases
            Mod aceSlammer = new Mod(Path.Combine(testingDataPath, "Ace Slammer", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsTrue(aceSlammer.ValidMod, "Ace slammer didn't parse into a valid mod! Reason: " + aceSlammer.LoadFailedReason);

            Mod diamondDifficulty = new Mod(Path.Combine(testingDataPath, "Diamond Difficulty", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsTrue(diamondDifficulty.ValidMod, "Diamond Difficulty didn't parse into a valid mod! Reason: " + diamondDifficulty.LoadFailedReason);

            Mod egm = new Mod(Path.Combine(testingDataPath, "Expanded Galaxy Mod", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsTrue(egm.ValidMod, "EGM didn't parse into a valid mod! Reason: " + egm.LoadFailedReason);
            var egmCustDLCJob = egm.GetJob(ModJob.JobHeader.CUSTOMDLC);

            Assert.IsNotNull(egmCustDLCJob, "Could not find EGM Custom DLC job!");
            Assert.AreEqual(2, egm.InstallationJobs.Count, $"EGM: Wrong number of installation jobs for custom dlc! Should be 2, got: {egm.InstallationJobs.Count}");
            Assert.AreEqual(6, egmCustDLCJob.AlternateDLCs.Count, $"EGM: Wrong number of alternate DLC on CustomDLC job! Should be 6, got: {egmCustDLCJob.AlternateDLCs.Count}");
            Assert.AreEqual(1, egmCustDLCJob.AlternateFiles.Count, $"EGM: Wrong number of alternate files on CustomDLC job! Should be 1, got: {egmCustDLCJob.AlternateFiles.Count}");
            var egmBasegameJob = egm.GetJob(ModJob.JobHeader.BASEGAME);

            Assert.IsNotNull(egmBasegameJob, "EGM Basegame job is null when it should exist!");
            Assert.AreEqual(23, egmBasegameJob.FilesToInstall.Count, $"EGM basegame job should install 23 files, but we see {egmBasegameJob.FilesToInstall.Count}");

            Assert.IsNull(egm.GetJob(ModJob.JobHeader.CITADEL), "EGM somehow returned a job for non-existent header!");

            Mod firefight = new Mod(Path.Combine(testingDataPath, "Firefight mod", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsTrue(firefight.ValidMod, "Firefight mod didn't parse into a valid mod! Reason: " + firefight.LoadFailedReason);

            //SP Controller Support 2.31 - invalid cause missing ) on moddesc.ini altfiles in customdlc.
            Mod spcontroller = new Mod(Path.Combine(testingDataPath, "SP Controller Support", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsFalse(spcontroller.ValidMod, "SP Controller support (wrong parenthesis on customdlc alts!) loaded as a valid mod when it shouldn't!");

            Mod zombiesupercoal = new Mod(Path.Combine(testingDataPath, "Zombie [SuperCoal]", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsTrue(zombiesupercoal.ValidMod, "zombie mod supercoal failed to load as a valid mod! Reason: " + zombiesupercoal.LoadFailedReason);

            // Can't find moddesc.ini
            Mod badPath = new Mod(Path.Combine(testingDataPath, "Not A Path", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsFalse(badPath.ValidMod, "An invalid/non-existing moddesc.ini somehow loaded as a valid mod!");

            //Same Gender Romances
            Mod sameGender = new Mod(Path.Combine(testingDataPath, "Same-Gender Romances for ME3", "moddesc.ini"), Mod.MEGame.Unknown);

            Assert.IsTrue(sameGender.ValidMod, "Same-Gender Romances failed to load as a valid mod!  Reason: " + sameGender.LoadFailedReason);
            var sgCustDLCJob = sameGender.InstallationJobs.FirstOrDefault(x => x.Header == ModJob.JobHeader.CUSTOMDLC);

            Assert.IsNotNull(sgCustDLCJob, "Could not find Same-Gender Romances Custom DLC job!");
            Assert.AreEqual(1, sameGender.InstallationJobs.Count, $"Same-gender romances: Wrong number of installation jobs! Should be 1, got: {sameGender.InstallationJobs.Count}");
        }
Exemple #11
0
        public void TestM3DirectoryResults()
        {
            GlobalTest.Init();
            List <GameTarget> targets = new List <GameTarget>();
            var root = GlobalTest.GetTestGameFoldersDirectory(MEGame.ME1);

            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(MEGame.ME1, d, false, false);
                gt.ValidateTarget();
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            root = GlobalTest.GetTestGameFoldersDirectory(MEGame.ME2);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(MEGame.ME2, d, false, false);
                gt.ValidateTarget();
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            root = GlobalTest.GetTestGameFoldersDirectory(MEGame.ME3);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(MEGame.ME3, d, false, false);
                gt.ValidateTarget();
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }

            foreach (var target in targets)
            {
                string expectedDLCPath;
                string expectedASIPath;
                string expectedBioGamePath;
                string expectedCookedPath;
                string expectedExecutableDir;
                if (target.Game == MEGame.ME1)
                {
                    expectedDLCPath       = Path.Combine(target.TargetPath, @"DLC");
                    expectedASIPath       = Path.Combine(target.TargetPath, @"Binaries", @"asi");
                    expectedBioGamePath   = Path.Combine(target.TargetPath, @"BioGame");
                    expectedCookedPath    = Path.Combine(target.TargetPath, @"BioGame", @"CookedPC");
                    expectedExecutableDir = Path.Combine(target.TargetPath, @"Binaries");
                }
                else if (target.Game == MEGame.ME2)
                {
                    expectedDLCPath       = Path.Combine(target.TargetPath, @"BioGame", @"DLC");
                    expectedASIPath       = Path.Combine(target.TargetPath, @"Binaries", @"asi");
                    expectedBioGamePath   = Path.Combine(target.TargetPath, @"BioGame");
                    expectedCookedPath    = Path.Combine(target.TargetPath, @"BioGame", @"CookedPC");
                    expectedExecutableDir = Path.Combine(target.TargetPath, @"Binaries");
                }
                else
                {
                    expectedDLCPath       = Path.Combine(target.TargetPath, @"BIOGame", @"DLC");
                    expectedASIPath       = Path.Combine(target.TargetPath, @"Binaries", @"Win32", @"asi");
                    expectedBioGamePath   = Path.Combine(target.TargetPath, @"BIOGame");
                    expectedCookedPath    = Path.Combine(target.TargetPath, @"BIOGame", @"CookedPCConsole");
                    expectedExecutableDir = Path.Combine(target.TargetPath, @"Binaries", @"Win32");
                }

                Assert.AreEqual(expectedDLCPath, M3Directories.GetDLCPath(target));
                Assert.AreEqual(expectedASIPath, M3Directories.GetASIPath(target));
                Assert.AreEqual(expectedBioGamePath, M3Directories.GetBioGamePath(target));
                Assert.AreEqual(expectedCookedPath, M3Directories.GetCookedPath(target));
                Assert.AreEqual(expectedExecutableDir, M3Directories.GetExecutableDirectory(target));
            }
        }
        public void TestASIManager()
        {
            GlobalTest.Init();
            Random random = new Random();

            Console.WriteLine(@"Loading ASI Manager Manifest");
            ASIManager.LoadManifest();

            var games = new[] { Mod.MEGame.ME1, Mod.MEGame.ME2, Mod.MEGame.ME3 };

            foreach (var game in games)
            {
                var        root   = GlobalTest.GetTestGameFoldersDirectory(game);
                var        normal = Path.Combine(root, "normal");
                GameTarget gt     = new GameTarget(game, normal, true, false);

                var asiDir = MEDirectories.ASIPath(gt);
                if (Directory.Exists(asiDir))
                {
                    // Clean slate
                    Utilities.DeleteFilesAndFoldersRecursively(asiDir);
                }

                var asisForGame = ASIManager.GetASIModsByGame(game);

                // 1: Test Installs of upgrades of versions
                foreach (var asi in asisForGame)
                {
                    // Install every version of an ASI and then ensure only one ASI of that type exists in the directory.
                    foreach (var v in asi.Versions)
                    {
                        var sourceBools = new bool?[] { true, false, null }; //online, local, let app decide
                        foreach (var sourceBool in sourceBools)
                        {
                            // INSTALL FROM SOURCE
                            Console.WriteLine($@"Install source variable: {sourceBool}");
                            Assert.IsTrue(ASIManager.InstallASIToTarget(v, gt, sourceBool),
                                          $"Installation of ASI failed: {v.Name}");
                            Assert.AreEqual(1, Directory.GetFiles(asiDir).Length,
                                            "The count of files in the ASI directory is not 1 after install of an ASI!");

                            // Check is installed
                            var installedASIs = gt.GetInstalledASIs().OfType <KnownInstalledASIMod>().ToList();
                            Assert.AreEqual(1, installedASIs.Count,
                                            "The amount of installed ASIs as fetched by GameTarget GetInstalledASIs() is not equal to 1!");

                            // Check it maps to the correct one.
                            var instASI = installedASIs.First();
                            Assert.AreEqual(v, instASI.AssociatedManifestItem, "The parsed installed ASI does not match the one we fed to ASIManager.InstallASIToTarget()!");

                            // Rename it to something random so the next version has to find it by the hash and not the filename.
                            var newPath = Path.Combine(asiDir, Guid.NewGuid() + ".asi");
                            File.Move(instASI.InstalledPath, newPath, false);

                            // Ensure it still can be found.
                            installedASIs = gt.GetInstalledASIs().OfType <KnownInstalledASIMod>().ToList();
                            Assert.AreEqual(1, installedASIs.Count, "The amount of installed ASIs as fetched by GameTarget GetInstalledASIs() is not equal to 1 after renaming the file!");

                            // Make multiple clones, to ensure all old ones get deleted on upgrades.
                            for (int i = 0; i < 5; i++)
                            {
                                var clonePath = Path.Combine(asiDir, instASI.AssociatedManifestItem.InstalledPrefix + i + ".asi");
                                File.Copy(newPath, clonePath, true);
                            }

                            installedASIs = gt.GetInstalledASIs().OfType <KnownInstalledASIMod>().ToList();
                            Assert.AreEqual(6, installedASIs.Count, "The amount of installed ASIs as fetched by GameTarget GetInstalledASIs() is not equal to 6 after cloning the file 5 times!");
                        }
                    }

                    var finalASIsPreRandomization = gt.GetInstalledASIs();
                    int randomCount = 0;
                    foreach (var iam in finalASIsPreRandomization)
                    {
                        // Test randomly editing it.
                        byte[] randomData = new byte[256];
                        random.NextBytes(randomData);
                        File.WriteAllBytes(iam.InstalledPath, randomData);
                        randomCount++;

                        var unknownInstalledASIs = gt.GetInstalledASIs().OfType <UnknownInstalledASIMod>().ToList();
                        Assert.AreEqual(randomCount, unknownInstalledASIs.Count, "Writing random bytes to installed ASI made amount of installed ASIs not correct!");
                    }

                    foreach (var v in finalASIsPreRandomization)
                    {
                        // Test uninstall and remove
                        Assert.IsTrue(v.Uninstall(), $"ASI failed to uninstall: {v.InstalledPath}");
                    }
                    Assert.AreEqual(0, Directory.GetFiles(asiDir).Length, "Leftover files remain after uninstalling all ASIs from target");
                }
            }
        }
        public void TestBuildingExtractionQueues()
        {
            GlobalTest.Init();

            Console.WriteLine("Fetching third party services");
            App.ThirdPartyImportingService      = OnlineContent.FetchThirdPartyImportingService();
            App.ThirdPartyIdentificationService = OnlineContent.FetchThirdPartyIdentificationManifest();

            var        compressedModsDirectory = Path.Combine(GlobalTest.GetTestDataDirectory(), "compressedmods");
            List <Mod> modsFoundInArchive      = new List <Mod>();

            void addModCallback(Mod m)
            {
                Console.WriteLine($"Found mod in archive: {m.ModName}");
                modsFoundInArchive.Add(m);
            }

            void failedModCallback(Mod m)
            {
                //Console.WriteLine($"A mod failed to load. This may be expected: {m.ModName}");
            }

            void logMessageCallback(string m)
            {
                Console.WriteLine(m);
            }

            #region Get Targets
            List <GameTarget> targets = new List <GameTarget>();
            var root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME1);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(Mod.MEGame.ME1, d, false, false);
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME2);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(Mod.MEGame.ME2, d, false, false);
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            root = GlobalTest.GetTestGameFoldersDirectory(Mod.MEGame.ME3);
            foreach (var d in Directory.GetDirectories(root))
            {
                GameTarget gt = new GameTarget(Mod.MEGame.ME3, d, false, false);
                if (gt.IsValid)
                {
                    targets.Add(gt);
                }
            }
            #endregion


            foreach (var archive in Directory.GetFiles(compressedModsDirectory))
            {
                modsFoundInArchive.Clear();
                var realArchiveInfo = GlobalTest.ParseRealArchiveAttributes(archive);
                Console.WriteLine($"Inspecting archive: { archive}");
                ModArchiveImporter.InspectArchive(archive, addModCallback, failedModCallback, logMessageCallback, forcedMD5: realArchiveInfo.md5, forcedSize: realArchiveInfo.size);
                var archiveZ = new SevenZipExtractor(archive);
                foreach (var mod in modsFoundInArchive)
                {
                    mod.GetAllRelativeReferences(archiveZ);
                    var targetsForMod = targets.Where(x => x.Game == mod.Game).ToList();
                    foreach (var target in targetsForMod)
                    {
                        mod.GetInstallationQueues(target);
                    }
                }
            }
        }