", article.Html);
@@ -280,7 +282,7 @@ public class ArticleMarkdownTests
{
foreach (var signedIn in new[] { false, true })
{
- var html = ArticleMarkdown.Render(body, "de", "switches", signedIn, Titles).Html;
+ var html = ArticleMarkdown.Render(body, "de", "switches", signedIn, Titles, NoRedirects).Html;
Assert.DoesNotContain("href=\"javascript", html, StringComparison.OrdinalIgnoreCase);
Assert.DoesNotContain("href=\"java", html, StringComparison.OrdinalIgnoreCase);
@@ -365,7 +367,7 @@ public class ArticleMarkdownTests
{
foreach (var signedIn in new[] { false, true })
{
- var html = ArticleMarkdown.Render(body, "de", "switches", signedIn, Titles).Html;
+ var html = ArticleMarkdown.Render(body, "de", "switches", signedIn, Titles, NoRedirects).Html;
Assert.DoesNotContain("network", html);
Assert.DoesNotContain("href=\"https://e.com", html);
@@ -446,12 +448,12 @@ public class ArticleMarkdownTests
var body = "Öffentlich.\n\n\\[\\[network-internals]]";
var logger = new ListLogger();
- var anonymous = ArticleMarkdown.RenderVisible(body, "de", "switches", signedIn: false, Titles, logger: logger);
+ var anonymous = ArticleMarkdown.RenderVisible(body, "de", "switches", signedIn: false, Titles, NoRedirects, logger: logger);
Assert.DoesNotContain("network", anonymous.Html);
Assert.Contains("
", anonymous.Html);
Assert.Contains(logger.Entries, e => e.Level == LogLevel.Warning);
- var signedIn = ArticleMarkdown.RenderVisible(body, "de", "switches", signedIn: true, Titles);
+ var signedIn = ArticleMarkdown.RenderVisible(body, "de", "switches", signedIn: true, Titles, NoRedirects);
Assert.DoesNotContain("network", signedIn.Html);
Assert.Contains("Öffentlich.", signedIn.Html);
}
diff --git a/test/Wiki.Host.Tests/Fakes.cs b/test/Wiki.Host.Tests/Fakes.cs
index f961085..ea607b4 100644
--- a/test/Wiki.Host.Tests/Fakes.cs
+++ b/test/Wiki.Host.Tests/Fakes.cs
@@ -69,8 +69,22 @@ public sealed class FakeStore : INoteStore
return (await GetHeadAsync(ct)).Commit;
}
- public Task ReadTextAsync(string path, string commit, CancellationToken ct) =>
- Task.FromResult(Files.TryGetValue(path, out var text) ? new StoredText(text, BlobSha(text)) : null);
+ /// Paths whose text read throws, as an unreachable remote does.
+ public HashSet FailReads { get; } = [];
+
+ private readonly Dictionary _textReads = new();
+
+ public int TextReads(string path)
+ {
+ lock (_textReads) return _textReads.GetValueOrDefault(path);
+ }
+
+ public Task ReadTextAsync(string path, string commit, CancellationToken ct)
+ {
+ lock (_textReads) _textReads[path] = _textReads.GetValueOrDefault(path) + 1;
+ if (FailReads.Contains(path)) throw new IOException($"store unavailable: {path}");
+ return Task.FromResult(Files.TryGetValue(path, out var text) ? new StoredText(text, BlobSha(text)) : null);
+ }
/// Every path was asked for, in order.
public List ByteReads { get; } = [];
diff --git a/test/Wiki.Host.Tests/HouseTests.cs b/test/Wiki.Host.Tests/HouseTests.cs
index b20bdda..12996b4 100644
--- a/test/Wiki.Host.Tests/HouseTests.cs
+++ b/test/Wiki.Host.Tests/HouseTests.cs
@@ -48,8 +48,10 @@ public class HouseTests(WikiHostFactory factory) : IClassFixture { });
+ var sync = new HttpRequestMessage(HttpMethod.Post, "/api/v1/sync?force=true");
+ sync.Headers.Add("X-Api-Key", WikiHostFactory.ApiKey);
+ Assert.Equal(HttpStatusCode.OK, (await failing.CreateClient().SendAsync(sync)).StatusCode);
+ factory.Store.FailReads.Add("articles/_plan.json");
+ try
+ {
+ var before = factory.Store.TextReads("articles/_plan.json");
+ var client = failing.CreateClient(new WebApplicationFactoryClientOptions { AllowAutoRedirect = false });
+
+ Assert.Equal(HttpStatusCode.OK, (await client.GetAsync("/house/de/schalter")).StatusCode);
+ Assert.Equal(HttpStatusCode.OK, (await client.GetAsync("/house/de/schalter")).StatusCode);
+ Assert.Equal(HttpStatusCode.NotFound, (await client.GetAsync("/house/de/old-switch")).StatusCode);
+
+ Assert.Equal(before + 1, factory.Store.TextReads("articles/_plan.json"));
+ }
+ finally
+ {
+ factory.Store.FailReads.Clear();
+ }
}
[Fact]