From 8ee0decd2f9e4d73e28a6a6fa1da33940313b582 Mon Sep 17 00:00:00 2001 From: Martin Tirion Date: Tue, 27 Aug 2024 16:52:58 +0200 Subject: [PATCH] Added validation of root-reference with ~ --- .../DocLinkChecker.Test/HyperlinkTests.cs | 46 +++++++++++++++++++ .../DocLinkChecker/Models/Hyperlink.cs | 1 - .../Services/LinkValidatorService.cs | 42 ++++++++++++----- 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/src/DocLinkChecker/DocLinkChecker.Test/HyperlinkTests.cs b/src/DocLinkChecker/DocLinkChecker.Test/HyperlinkTests.cs index 6a22fc1..5a76892 100644 --- a/src/DocLinkChecker/DocLinkChecker.Test/HyperlinkTests.cs +++ b/src/DocLinkChecker/DocLinkChecker.Test/HyperlinkTests.cs @@ -303,6 +303,52 @@ public async void ValidateLocalLinkNonExistingHeadingShouldHaveErrors() headingError.Severity.Should().Be(Enums.MarkdownErrorSeverity.Warning); } + [Theory] + [InlineData("~/general/images/nature.jpeg")] + [InlineData("~\\general\\images\\nature.jpeg")] + public async void ValidateRootLinkShouldHaveNoErrors(string path) + { + // Arrange + _config.DocumentationFiles.SourceFolder = _fileServiceMock.Root; + string sourceDoc = $"{_fileServiceMock.Root}\\general\\another-sample.md"; + + LinkValidatorService service = new LinkValidatorService(_serviceProvider, _config, _fileService, _console); + + //Act + int line = 499; + int column = 75; + Hyperlink link = new Hyperlink(sourceDoc, line, column, path); + await service.VerifyHyperlink(link); + + // Assert + service.Errors.Should().BeEmpty(); + } + + [Theory] + [InlineData("~/general/images/NON_EXISTING.jpeg")] + [InlineData("~\\NON_EXISTING\\images\\nature.jpeg")] + public async void ValidateInvalidRootLinkShouldHaveErrors(string path) + { + // Arrange + _config.DocumentationFiles.SourceFolder = _fileServiceMock.Root; + string sourceDoc = $"{_fileServiceMock.Root}\\general\\another-sample.md"; + + LinkValidatorService service = new LinkValidatorService(_serviceProvider, _config, _fileService, _console); + + //Act + int line = 499; + int column = 75; + Hyperlink link = new Hyperlink(sourceDoc, line, column, path); + await service.VerifyHyperlink(link); + + // Assert + service.Errors.Should().NotBeEmpty(); + var linkError = service.Errors.FirstOrDefault(x => x.Message.Contains("Not found")); + linkError.Line.Should().Be(line); + linkError.Column.Should().Be(column); + linkError.Severity.Should().Be(MarkdownErrorSeverity.Error); + } + [Fact] public async void ValidateLocalLinkWithFullPathShouldHaveErrors() { diff --git a/src/DocLinkChecker/DocLinkChecker/Models/Hyperlink.cs b/src/DocLinkChecker/DocLinkChecker/Models/Hyperlink.cs index 7ab906d..53d2381 100644 --- a/src/DocLinkChecker/DocLinkChecker/Models/Hyperlink.cs +++ b/src/DocLinkChecker/DocLinkChecker/Models/Hyperlink.cs @@ -1,6 +1,5 @@ namespace DocLinkChecker.Models { - using System.Diagnostics; using System.IO; using DocLinkChecker.Enums; diff --git a/src/DocLinkChecker/DocLinkChecker/Services/LinkValidatorService.cs b/src/DocLinkChecker/DocLinkChecker/Services/LinkValidatorService.cs index 1233c7c..f60ae1a 100644 --- a/src/DocLinkChecker/DocLinkChecker/Services/LinkValidatorService.cs +++ b/src/DocLinkChecker/DocLinkChecker/Services/LinkValidatorService.cs @@ -272,18 +272,38 @@ private Task VerifyLocalHyperlink(Hyperlink hyperlink) return Task.CompletedTask; } - // compute link of the url relative to the path of the file. - if (!_fileService.ExistsFileOrDirectory(hyperlink.UrlFullPath)) + if (hyperlink.Url.StartsWith("~")) { - // referenced file doesn't exist - _errors.Enqueue( - new MarkdownError( - hyperlink.FilePath, - hyperlink.Line, - hyperlink.Column, - MarkdownErrorSeverity.Error, - $"Not found: {hyperlink.Url}")); - return Task.CompletedTask; + // special case for a reference to the root of the docs. Calculate full path differently. + string url = hyperlink.Url.Replace("~", _config.DocumentationFiles.SourceFolder); + if (!_fileService.ExistsFileOrDirectory(url)) + { + // referenced file doesn't exist + _errors.Enqueue( + new MarkdownError( + hyperlink.FilePath, + hyperlink.Line, + hyperlink.Column, + MarkdownErrorSeverity.Error, + $"Not found: {hyperlink.Url}")); + return Task.CompletedTask; + } + } + else + { + // compute link of the url relative to the path of the file. + if (!_fileService.ExistsFileOrDirectory(hyperlink.UrlFullPath)) + { + // referenced file doesn't exist + _errors.Enqueue( + new MarkdownError( + hyperlink.FilePath, + hyperlink.Line, + hyperlink.Column, + MarkdownErrorSeverity.Error, + $"Not found: {hyperlink.Url}")); + return Task.CompletedTask; + } } switch (_config.DocLinkChecker.RelativeLinkStrategy)