Index: Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/Exporters/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter.cs =================================================================== diff -u -ra04b22a8d3bc9bf09d5572a99d40e36d70ae9928 -rc6bb356ca9ac02009e91e7e50dbcff56efcd7a52 --- Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/Exporters/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter.cs (.../GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter.cs) (revision a04b22a8d3bc9bf09d5572a99d40e36d70ae9928) +++ Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/Exporters/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter.cs (.../GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter.cs) (revision c6bb356ca9ac02009e91e7e50dbcff56efcd7a52) @@ -21,9 +21,13 @@ using System; using Core.Common.Base.IO; +using Core.Common.IO.Exceptions; using Core.Common.Util; +using log4net; using Ringtoets.Common.Data.AssessmentSection; using Ringtoets.GrassCoverErosionOutwards.Data; +using Ringtoets.GrassCoverErosionOutwards.Util; +using RingtoetsCommonIOResources = Ringtoets.Common.IO.Properties.Resources; namespace Ringtoets.GrassCoverErosionOutwards.IO.Exporters { @@ -32,6 +36,9 @@ /// public class GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter : IFileExporter { + private static readonly ILog log = LogManager.GetLogger(typeof(GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter)); + private readonly GrassCoverErosionOutwardsFailureMechanism failureMechanism; + private readonly IAssessmentSection assessmentSection; private readonly string filePath; /// @@ -59,12 +66,27 @@ IOUtils.ValidateFilePath(filePath); + this.failureMechanism = failureMechanism; + this.assessmentSection = assessmentSection; this.filePath = filePath; } public bool Export() { - throw new NotImplementedException(); + try + { + GrassCoverErosionOutwardsHydraulicBoundaryLocationsWriter.WriteHydraulicBoundaryLocations( + GrassCoverErosionOutwardsAggregatedHydraulicBoundaryLocationFactory.CreateAggregatedHydraulicBoundaryLocations( + assessmentSection, failureMechanism), + filePath); + } + catch (CriticalFileWriteException e) + { + log.ErrorFormat(RingtoetsCommonIOResources.HydraulicBoundaryLocationsExporter_Error_Exception_0_no_HydraulicBoundaryLocations_exported, e.Message); + return false; + } + + return true; } } } \ No newline at end of file Index: Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/Ringtoets.GrassCoverErosionOutwards.IO.csproj =================================================================== diff -u -r9134b288215ec6dd8b2d1eb5f5f0c9603baa734d -rc6bb356ca9ac02009e91e7e50dbcff56efcd7a52 --- Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/Ringtoets.GrassCoverErosionOutwards.IO.csproj (.../Ringtoets.GrassCoverErosionOutwards.IO.csproj) (revision 9134b288215ec6dd8b2d1eb5f5f0c9603baa734d) +++ Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/Ringtoets.GrassCoverErosionOutwards.IO.csproj (.../Ringtoets.GrassCoverErosionOutwards.IO.csproj) (revision c6bb356ca9ac02009e91e7e50dbcff56efcd7a52) @@ -7,6 +7,10 @@ + + ..\..\..\..\packages\log4net.2.0.4\lib\net40-full\log4net.dll + True + @@ -27,6 +31,7 @@ Copying.licenseheader + Index: Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/packages.config =================================================================== diff -u --- Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/packages.config (revision 0) +++ Ringtoets/GrassCoverErosionOutwards/src/Ringtoets.GrassCoverErosionOutwards.IO/packages.config (revision c6bb356ca9ac02009e91e7e50dbcff56efcd7a52) @@ -0,0 +1,26 @@ + + + + + \ No newline at end of file Index: Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.IO.Test/Exporters/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporterTest.cs =================================================================== diff -u -ra04b22a8d3bc9bf09d5572a99d40e36d70ae9928 -rc6bb356ca9ac02009e91e7e50dbcff56efcd7a52 --- Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.IO.Test/Exporters/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporterTest.cs (.../GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporterTest.cs) (revision a04b22a8d3bc9bf09d5572a99d40e36d70ae9928) +++ Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.IO.Test/Exporters/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporterTest.cs (.../GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporterTest.cs) (revision c6bb356ca9ac02009e91e7e50dbcff56efcd7a52) @@ -21,13 +21,18 @@ using System; using System.IO; +using System.Linq; +using System.Security.AccessControl; using Core.Common.Base.IO; using Core.Common.TestUtil; using NUnit.Framework; using Rhino.Mocks; using Ringtoets.Common.Data.AssessmentSection; +using Ringtoets.Common.Data.Hydraulics; +using Ringtoets.Common.Data.TestUtil; using Ringtoets.GrassCoverErosionOutwards.Data; using Ringtoets.GrassCoverErosionOutwards.IO.Exporters; +using Ringtoets.GrassCoverErosionOutwards.Util.TestUtil; namespace Ringtoets.GrassCoverErosionOutwards.IO.Test.Exporters { @@ -103,5 +108,108 @@ Assert.IsInstanceOf(exporter); mocks.VerifyAll(); } + + [Test] + public void Export_ValidData_ReturnsTrueAndWritesCorrectData() + { + // Setup + var assessmentSection = new ObservableTestAssessmentSectionStub(); + var failureMechanism = new GrassCoverErosionOutwardsFailureMechanism(); + GrassCoverErosionOutwardsHydraulicBoundaryLocationsTestHelper.AddHydraulicBoundaryLocations(failureMechanism, assessmentSection, new[] + { + new HydraulicBoundaryLocation(123, "aName", 1.1, 2.2) + }); + + string directoryPath = TestHelper.GetScratchPadPath("Export_ValidData_ReturnTrue"); + Directory.CreateDirectory(directoryPath); + string filePath = Path.Combine(directoryPath, "test.shp"); + const string baseName = "test"; + + var exporter = new GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter(failureMechanism, assessmentSection, filePath); + + // Precondition + AssertEssentialShapefileExists(directoryPath, baseName, false); + + try + { + // Call + bool isExported = exporter.Export(); + + // Assert + AssertEssentialShapefileExists(directoryPath, baseName, true); + AssertEssentialShapefileMd5Hashes(directoryPath, baseName); + Assert.IsTrue(isExported); + } + finally + { + Directory.Delete(directoryPath, true); + } + } + + [Test] + public void Export_InvalidDirectoryRights_LogErrorAndReturnFalse() + { + // Setup + var assessmentSection = new ObservableTestAssessmentSectionStub(); + var failureMechanism = new GrassCoverErosionOutwardsFailureMechanism(); + GrassCoverErosionOutwardsHydraulicBoundaryLocationsTestHelper.AddHydraulicBoundaryLocations(failureMechanism, assessmentSection, new[] + { + new HydraulicBoundaryLocation(123, "aName", 1.1, 2.2) + }); + + string directoryPath = TestHelper.GetScratchPadPath("Export_InvalidDirectoryRights_LogErrorAndReturnFalse"); + Directory.CreateDirectory(directoryPath); + string filePath = Path.Combine(directoryPath, "test.shp"); + + var exporter = new GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter(failureMechanism, assessmentSection, filePath); + + try + { + using (new DirectoryPermissionsRevoker(directoryPath, FileSystemRights.Write)) + { + // Call + var isExported = true; + Action call = () => isExported = exporter.Export(); + + // Assert + string expectedMessage = $"Er is een onverwachte fout opgetreden tijdens het schrijven van het bestand '{filePath}'. " + + "Er zijn geen hydraulische randvoorwaarden locaties geëxporteerd."; + TestHelper.AssertLogMessageIsGenerated(call, expectedMessage); + Assert.IsFalse(isExported); + } + } + finally + { + Directory.Delete(directoryPath, true); + } + } + + private static void AssertEssentialShapefileExists(string directoryPath, string baseName, bool shouldExist) + { + string pathName = Path.Combine(directoryPath, baseName); + Assert.AreEqual(shouldExist, File.Exists(pathName + ".shp")); + Assert.AreEqual(shouldExist, File.Exists(pathName + ".shx")); + Assert.AreEqual(shouldExist, File.Exists(pathName + ".dbf")); + } + + private static void AssertEssentialShapefileMd5Hashes(string directoryPath, string baseName) + { + string refPathName = Path.Combine(TestHelper.GetTestDataPath(TestDataPath.Ringtoets.GrassCoverErosionOutwards.IO), + nameof(GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter), "ExpectedExport"); + string pathName = Path.Combine(directoryPath, baseName); + + AssertBinaryFileContent(refPathName, pathName, ".shp", 100, 28); + AssertBinaryFileContent(refPathName, pathName, ".shx", 100, 8); + AssertBinaryFileContent(refPathName, pathName, ".dbf", 32, 841); + } + + private static void AssertBinaryFileContent(string refPathName, string pathName, string extension, int headerLength, int bodyLength) + { + byte[] refContent = File.ReadAllBytes(refPathName + extension); + byte[] content = File.ReadAllBytes(pathName + extension); + Assert.AreEqual(headerLength + bodyLength, content.Length); + Assert.AreEqual(refContent.Skip(headerLength).Take(bodyLength), + content.Skip(headerLength).Take(bodyLength)); + } } } \ No newline at end of file Index: Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.IO.Test/test-data/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter/ExpectedExport.dbf =================================================================== diff -u Binary files differ Index: Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.IO.Test/test-data/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter/ExpectedExport.dbf.bak =================================================================== diff -u Binary files differ Index: Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.IO.Test/test-data/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter/ExpectedExport.shp =================================================================== diff -u Binary files differ Index: Ringtoets/GrassCoverErosionOutwards/test/Ringtoets.GrassCoverErosionOutwards.IO.Test/test-data/GrassCoverErosionOutwardsHydraulicBoundaryLocationsExporter/ExpectedExport.shx =================================================================== diff -u Binary files differ