public void FileGen_AdditionalProperties()
        {
            // 0. Arrange
            string analysisRootDir = TestUtils.CreateTestSpecificFolder(this.TestContext);
            TestLogger logger = new TestLogger();

            CreateProjectWithFiles("project1", analysisRootDir);
            AnalysisConfig config = CreateValidConfig(analysisRootDir);

            // Add additional properties
            config.LocalSettings = new AnalysisProperties();
            config.LocalSettings.Add(new Property() { Id = "key1", Value = "value1" });
            config.LocalSettings.Add(new Property() { Id = "key.2", Value = "value two" });
            config.LocalSettings.Add(new Property() { Id = "key.3", Value = " " });

            // Sensitive data should not be written
            config.LocalSettings.Add(new Property() { Id = SonarProperties.DbPassword, Value ="secret db pwd" });
            config.LocalSettings.Add(new Property() { Id = SonarProperties.SonarPassword, Value = "secret pwd" });

            // Server properties should not be added
            config.ServerSettings = new AnalysisProperties();
            config.ServerSettings.Add(new Property() { Id = "server.key", Value = "should not be added" });

            // Act
            ProjectInfoAnalysisResult result = PropertiesFileGenerator.GenerateFile(config, logger);

            // Assert
            AssertExpectedProjectCount(1, result);

            // One valid project info file -> file created
            AssertPropertiesFilesCreated(result, logger);

            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists("key1", "value1");
            provider.AssertSettingExists("key.2", "value two");
            provider.AssertSettingExists("key.3", " ");

            provider.AssertSettingDoesNotExist("server.key");

            // SONARMSBRU-136: TODO - uncomment the following code:
            //provider.AssertSettingExists("server.key", "");
            //provider.AssertSettingDoesNotExist(SonarProperties.DbPassword);
            //provider.AssertSettingDoesNotExist(SonarProperties.SonarPassword);

            // SONARMSBRU-136: TODO - delete the following code:
            // v1.0.1 back-compat: check sensitive data is written to the properties file
            provider.AssertSettingExists(SonarProperties.DbPassword, "secret db pwd");
            provider.AssertSettingExists(SonarProperties.SonarPassword, "secret pwd");
        }
        public void PropertiesWriter_GlobalSettingsWritten()
        {
            // Tests that global settings in the ProjectInfo are written to the file
            
            // Arrange
            string projectBaseDir = TestUtils.CreateTestSpecificFolder(TestContext, "PropertiesWriterTest_GlobalSettingsWritten");

            AnalysisConfig config = new AnalysisConfig()
            {
                SonarOutputDir = @"C:\my_folder"
            };

            AnalysisProperties globalSettings = new AnalysisProperties();
            globalSettings.Add(new Property() { Id = "my.setting1", Value = "setting1" });
            globalSettings.Add(new Property() { Id = "my.setting2", Value = "setting 2 with spaces" });
            globalSettings.Add(new Property() { Id = "my.setting.3", Value = @"c:\dir1\dir2\foo.txt" }); // path that will be escaped

            // Act
            PropertiesWriter writer = new PropertiesWriter(config);
            writer.WriteGlobalSettings(globalSettings);
            string fullActualPath = SaveToResultFile(projectBaseDir, "Actual.txt", writer.Flush());

            // Assert
            SQPropertiesFileReader propertyReader = new SQPropertiesFileReader(fullActualPath);

            propertyReader.AssertSettingExists("my.setting1", "setting1");
            propertyReader.AssertSettingExists("my.setting2", "setting 2 with spaces");
            propertyReader.AssertSettingExists("my.setting.3", @"c:\\dir1\\dir2\\foo.txt");
        }
        public void PropertiesWriter_AnalysisSettingsWritten()
        {
            // Tests that analysis settings in the ProjectInfo are written to the file
            // Arrange
            string projectBaseDir = TestUtils.CreateTestSpecificFolder(TestContext, "PropertiesWriterTest_AnalysisSettingsWritten");
            string productProject = CreateEmptyFile(projectBaseDir, "MyProduct.csproj");
            
            string productFile = CreateEmptyFile(projectBaseDir, "File.cs");
            List<string> productFiles = new List<string>();
            productFiles.Add(productFile);
            string productFileListFilePath = Path.Combine(projectBaseDir, "productManagedFiles.txt");

            ProjectInfo product = CreateProjectInfo("AnalysisSettingsTest.proj", "7B3B7244-5031-4D74-9BBD-3316E6B5E7D5", productProject, false, productFiles, productFileListFilePath, null, null, "language");

            List<ProjectInfo> projects = new List<ProjectInfo>();
            projects.Add(product);

            AnalysisConfig config = new AnalysisConfig()
            {
                SonarOutputDir = @"C:\my_folder"
            };

            // These are the settings we are going to check. The other analysis values are not checked.
            product.AnalysisSettings = new AnalysisProperties();
            product.AnalysisSettings.Add(new Property() { Id = "my.setting1", Value = "setting1" });
            product.AnalysisSettings.Add(new Property() { Id = "my.setting2", Value = "setting 2 with spaces" });
            product.AnalysisSettings.Add(new Property() { Id = "my.setting.3", Value = @"c:\dir1\dir2\foo.txt" }); // path that will be escaped
            
            // Act
            PropertiesWriter writer = new PropertiesWriter(config);
            writer.WriteSettingsForProject(product, new string[] { productFile }, null, null);          
            string fullActualPath = SaveToResultFile(projectBaseDir, "Actual.txt", writer.Flush());

            // Assert
            SQPropertiesFileReader propertyReader = new SQPropertiesFileReader(fullActualPath);

            propertyReader.AssertSettingExists("7B3B7244-5031-4D74-9BBD-3316E6B5E7D5.my.setting1", "setting1");
            propertyReader.AssertSettingExists("7B3B7244-5031-4D74-9BBD-3316E6B5E7D5.my.setting2", "setting 2 with spaces");
            propertyReader.AssertSettingExists("7B3B7244-5031-4D74-9BBD-3316E6B5E7D5.my.setting.3", @"c:\\dir1\\dir2\\foo.txt");
        }
        public void FileGen_VSBootstrapperIsDisabled_OverrideUserSettings_SameValue()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            Property bootstrapperProperty = new Property() { Id = PropertiesFileGenerator.VSBootstrapperPropertyKey, Value = "false" };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("disableBootstrapperSame", logger, bootstrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists(PropertiesFileGenerator.VSBootstrapperPropertyKey, "false");
            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.VSBootstrapperPropertyKey);
            logger.AssertWarningsLogged(0); // not expecting a warning if the user has supplied the value we want
        }
        public void FileGen_VSBootstrapperIsDisabled_OverrideUserSettings_DifferentValue()
        {
            // 0. Arrange
            TestLogger logger = new TestLogger();

            // Try to explicitly enable the setting
            Property bootstrapperProperty = new Property() { Id = PropertiesFileGenerator.VSBootstrapperPropertyKey, Value = "true" };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("disableBootstrapperDiff", logger, bootstrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists(PropertiesFileGenerator.VSBootstrapperPropertyKey, "false");
            logger.AssertSingleWarningExists(PropertiesFileGenerator.VSBootstrapperPropertyKey);
        }
        public void FileGen_VSBootstrapperIsDisabled()
        {
            // 0. Arrange
            TestLogger logger = new TestLogger();

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("disableBootstrapper", logger);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists(PropertiesFileGenerator.VSBootstrapperPropertyKey, "false");
            logger.AssertWarningsLogged(0);
        }
        public void FileGen_BuildWrapperOutputDirContainsFiles_PropertyIsWritten()
        {
            // Arrange
            // Create directory and file in child directory
            string bwOutputPath = TestUtils.CreateTestSpecificFolder(this.TestContext, "bw_output_withFiles");
            string childDir = TestUtils.CreateTestSpecificFolder(this.TestContext, "bw_output_withFiles\\childDir");
            string contentFilePath = Path.Combine(childDir, "dummy.txt");
            File.WriteAllText(contentFilePath, "dummy bw output");

            TestLogger logger = new TestLogger();
            Property buildWrapperProperty = new Property() { Id = PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, Value = bwOutputPath };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("buildwrapper_dirwithfiles", logger, buildWrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            string expectedPropertyValue = PropertiesWriter.Escape(bwOutputPath); // property is a path so it will be escaped
            provider.AssertSettingExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, expectedPropertyValue);

            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, bwOutputPath);

            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void FileGen_ValidFiles_WithUnfixableSarif()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            // SARIF file path
            string testSarifPath = Path.Combine(testDir, "testSarif.json");
            string escapedSarifPath = testSarifPath.Replace(@"\", @"\\");

            // Create SARIF report path property and add it to the project info
            AnalysisProperties projectSettings = new AnalysisProperties();
            projectSettings.Add(new Property() { Id = RoslynV1SarifFixer.ReportFilePropertyKey, Value = testSarifPath });
            Guid projectGuid = Guid.NewGuid();
            CreateProjectWithFiles("withFiles1", testDir, projectGuid, true, projectSettings);

            TestLogger logger = new TestLogger();
            AnalysisConfig config = CreateValidConfig(testDir);

            // Mock SARIF fixer simulated unfixable/absent file
            MockRoslynV1SarifFixer mockSarifFixer = new MockRoslynV1SarifFixer(null);

            // Act
            ProjectInfoAnalysisResult result = PropertiesFileGenerator.GenerateFile(config, logger, mockSarifFixer);

            // Assert
            Assert.AreEqual(1, mockSarifFixer.CallCount);

            // One valid project info file -> file created
            AssertPropertiesFilesCreated(result, logger);

            // Unfixable SARIF -> cannot fix -> report file property removed
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingDoesNotExist(projectGuid.ToString().ToUpper() + "." + RoslynV1SarifFixer.ReportFilePropertyKey);
        }
        public void FileGen_ValidFiles_WithFixableSarif()
        {
            // Arrange
            string testDir = TestUtils.CreateTestSpecificFolder(this.TestContext);

            // SARIF file path
            string testSarifPath = Path.Combine(testDir, "testSarif.json");

            // Create SARIF report path property and add it to the project info
            AnalysisProperties projectSettings = new AnalysisProperties();
            projectSettings.Add(new Property() { Id = RoslynV1SarifFixer.ReportFilePropertyKey, Value = testSarifPath });
            Guid projectGuid = Guid.NewGuid();
            CreateProjectWithFiles("withFiles1", testDir, projectGuid, true, projectSettings);

            TestLogger logger = new TestLogger();
            AnalysisConfig config = CreateValidConfig(testDir);

            // Mock SARIF fixer simulates fixable SARIF with fixed name
            string returnPathDir = Path.GetDirectoryName(testSarifPath);
            string returnPathFileName = Path.GetFileNameWithoutExtension(testSarifPath) +
                RoslynV1SarifFixer.FixedFileSuffix + Path.GetExtension(testSarifPath);

            MockRoslynV1SarifFixer mockSarifFixer = new MockRoslynV1SarifFixer(returnPathFileName);
            string escapedMockReturnPath = mockSarifFixer.ReturnVal.Replace(@"\", @"\\");

            // Act
            ProjectInfoAnalysisResult result = PropertiesFileGenerator.GenerateFile(config, logger, mockSarifFixer);

            // Assert
            Assert.AreEqual(1, mockSarifFixer.CallCount);

            // Fixable SARIF -> new file saved -> changed property
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingExists(projectGuid.ToString().ToUpper() + "." + RoslynV1SarifFixer.ReportFilePropertyKey, escapedMockReturnPath);
        }
        public void FileGen_BuildWrapperOutputDirIsMissing_PropertyNotWritten()
        {
            // Arrange
            TestLogger logger = new TestLogger();
            Property buildWrapperProperty = new Property() { Id = PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, Value = "non-existent directory" };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("buildwrapper_missingdir", logger, buildWrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingDoesNotExist(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey);

            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, "non-existent directory");
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }
        public void FileGen_BuildWrapperOutputDirIsEmpty_PropertyNotWritten()
        {
            // Arrange
            // Create empty folder with empty child folder
            string emptyFolderPath = TestUtils.CreateTestSpecificFolder(this.TestContext, "empty_bw_output");
            TestUtils.CreateTestSpecificFolder(this.TestContext, "empty_bw_output\\childDir");

            TestLogger logger = new TestLogger();
            Property buildWrapperProperty = new Property() { Id = PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, Value = emptyFolderPath };

            // Act
            ProjectInfoAnalysisResult result = ExecuteAndCheckSucceeds("buildwrapper_emptydir", logger, buildWrapperProperty);

            // Assert
            SQPropertiesFileReader provider = new SQPropertiesFileReader(result.FullPropertiesFilePath);
            provider.AssertSettingDoesNotExist(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey);

            logger.AssertSingleDebugMessageExists(PropertiesFileGenerator.BuildWrapperOutputDirectoryKey, emptyFolderPath);
            logger.AssertWarningsLogged(0);
            logger.AssertErrorsLogged(0);
        }