Skip to content

Commit bac3533

Browse files
rnwoodweb-flow
andauthored
fix: broken logo image and redirects for basepath (#1868)
* fix: Broken logo image and redirects for basepath * Add more tests * Fix test build errors --------- Co-authored-by: smtp4dev-automation <[email protected]>
1 parent ce55514 commit bac3533

6 files changed

Lines changed: 48 additions & 27 deletions

File tree

.vscode/launch.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// If you have changed target frameworks, make sure to update the program path.
1212
"program": "${workspaceFolder}/Rnwood.Smtp4dev/bin/Debug/net8.0/Rnwood.Smtp4dev.dll",
1313
"cwd": "${workspaceFolder}/Rnwood.Smtp4dev",
14-
"args": ["--recreatedb", "--urls", "http://localhost:5000"],
14+
"args": ["--recreatedb", "--urls", "http://localhost:5000", "--basepath=/smtp4dev"],
1515
"stopAtEntry": false,
1616
"internalConsoleOptions": "openOnSessionStart",
1717
"preLaunchTask": "build Rnwood.Smtp4dev",
@@ -30,7 +30,7 @@
3030
"name": "Chrome (Client Debug)",
3131
"type": "chrome",
3232
"request": "launch",
33-
"url": "http://localhost:5000",
33+
"url": "http://localhost:5000/smtp4dev",
3434
"webRoot": "${workspaceFolder}/Rnwood.Smtp4dev/ClientApp/src",
3535
"sourceMapPathOverrides": {
3636
"../../ClientApp/src/*": "${webRoot}/*",

.vscode/tasks.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
"type": "process",
88
"args": [
99
"build",
10-
"${workspaceFolder}/Rnwood.Smtp4dev",
1110
"/property:GenerateFullPaths=true"
1211
],
1312
"problemMatcher": "$msCompile",

Rnwood.Smtp4dev.Tests/E2E/E2ETests.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ public class E2ETestOptions
2626
{
2727
public bool InMemoryDB { get; set; }
2828
public string BasePath { get; set; }
29-
public IDictionary<string,string> EnvironmentVariables { get; set; } = new Dictionary<string,string>();
29+
30+
public string TestPath { get; set; }
31+
public IDictionary<string, string> EnvironmentVariables { get; set; } = new Dictionary<string, string>();
3032
}
3133

3234
public class E2ETestContext
@@ -156,7 +158,7 @@ protected void RunE2ETest(Action<E2ETestContext> test, E2ETestOptions options =
156158
if (newLine.StartsWith("Now listening on: http://"))
157159
{
158160
int portNumber = int.Parse(Regex.Replace(newLine, @".*http://[^\s]+:(\d+)", "$1"));
159-
baseUrl = new Uri($"http://localhost:{portNumber}{options.BasePath ?? ""}");
161+
baseUrl = new Uri($"http://localhost:{portNumber}{options.TestPath ?? options.BasePath ?? ""}");
160162
}
161163

162164
if (newLine.StartsWith("SMTP Server is listening on port"))

Rnwood.Smtp4dev.Tests/E2E/E2ETests_WebUI_CheckMessageIsReceivedAndDisplayed.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,14 @@ public E2ETests_WebUI_CheckMessageIsReceivedAndDisplayed(ITestOutputHelper outpu
1717
{
1818
}
1919

20-
[Theory]
21-
[InlineData("/", false)]
22-
[InlineData("/", true)]
23-
[InlineData("/smtp4dev", true)]
24-
public void CheckMessageIsReceivedAndDisplayed(string basePath, bool inMemoryDb)
20+
[Theory]
21+
[InlineData("", "", false)]
22+
[InlineData("", "/", true)]
23+
[InlineData("/smtp4dev", "/smtp4dev", true)]
24+
[InlineData("/smtp4dev", "/smtp4dev/", true)]
25+
[InlineData("/smtp4dev", "", true)]
26+
[InlineData("/smtp4dev", "/", true)]
27+
public void CheckMessageIsReceivedAndDisplayed(string basePath, string testPath, bool inMemoryDb)
2528
{
2629
RunUITestAsync($"{nameof(CheckMessageIsReceivedAndDisplayed)}-{basePath}-{inMemoryDb}", async (page, baseUrl, smtpPortNumber) =>
2730
{
@@ -59,13 +62,14 @@ public void CheckMessageIsReceivedAndDisplayed(string basePath, bool inMemoryDb)
5962
var rows = await grid.GetRowsAsync();
6063
return rows.FirstOrDefault();
6164
});
62-
65+
6366
Assert.NotNull(messageRow);
6467
Assert.True(await messageRow.ContainsTextAsync(messageSubject));
6568
}, new UITestOptions
6669
{
6770
InMemoryDB = inMemoryDb,
68-
BasePath = basePath
71+
BasePath = basePath,
72+
TestPath = testPath
6973
});
7074
}
7175
}

Rnwood.Smtp4dev/ClientApp/src/components/home/home.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
<div style="flex: 0 0 content">
55
<a href="https://github.com/rnwood/smtp4dev/" target="_blank">
66

7-
<UseDark v-slot="{ isDark, toggleDark }">
8-
<img height="35" :src="isDark ? '/logo-dark.png' : '/logo.png'" class="logo" alt="smtp4dev" />
7+
<UseDark v-slot="{ isDark }">
8+
<img height="35" :src="isDark ? './logo-dark.png' : './logo.png'" class="logo" alt="smtp4dev" />
99
</UseDark>
1010
</a>
1111
</div>

Rnwood.Smtp4dev/Startup.cs

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private static void ValidateDatabaseVersionCompatibility(Smtp4devDbContext conte
6060

6161
// Get all migrations that have been applied to the database
6262
var appliedMigrations = context.Database.GetAppliedMigrations().ToList();
63-
63+
6464
// Get all migrations available in the current application
6565
var availableMigrations = context.Database.GetMigrations().ToList();
6666

@@ -92,7 +92,7 @@ public void ConfigureServices(IServiceCollection services)
9292
//Remove the JSON content type from the actions where it is not supported.
9393
NSwag.OpenApiOperationDescription sendOp = d.Operations.FirstOrDefault(o => o.Path.EndsWith("/send") || o.Path.EndsWith("/reply"));
9494
sendOp.Operation.RequestBody.Content.Remove("application/json");
95-
95+
9696
};
9797
});
9898

@@ -131,10 +131,10 @@ public void ConfigureServices(IServiceCollection services)
131131

132132

133133
using var context = new Smtp4devDbContext((DbContextOptions<Smtp4devDbContext>)opt.Options);
134-
134+
135135
// Validate database version compatibility before attempting any operations
136136
ValidateDatabaseVersionCompatibility(context);
137-
137+
138138
if (string.IsNullOrEmpty(serverOptions.Database))
139139
{
140140
context.Database.Migrate();
@@ -178,7 +178,7 @@ public void ConfigureServices(IServiceCollection services)
178178
{
179179
Log.Logger.Information("Populating MIME metadata for {count} existing messages during startup", messagesWithoutMetadata.Count);
180180
var mimeProcessingService = new MimeProcessingService();
181-
181+
182182
int processed = 0;
183183
int batchSize = 50; // Process in batches to avoid memory issues
184184

@@ -335,14 +335,30 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
335335

336336
if (!string.IsNullOrEmpty(serverOptions.BasePath) && serverOptions.BasePath != "/")
337337
{
338-
RewriteOptions rewrites = new RewriteOptions();
339-
rewrites.AddRedirect("^" + serverOptions.BasePath.TrimEnd('/') + "$", serverOptions.BasePath.TrimEnd('/') + "/");
340-
;
341-
rewrites.AddRedirect("^(/)?$", serverOptions.BasePath.TrimEnd('/') + "/");
342-
;
343-
app.UseRewriter(rewrites);
344-
345-
app.Map(serverOptions.BasePath, configure);
338+
string basePathNoSlash = serverOptions.BasePath.TrimEnd('/');
339+
string redirectTarget = basePathNoSlash + "/";
340+
341+
// Global middleware to redirect /smtp4dev to /smtp4dev/
342+
app.Use(async (context, next) =>
343+
{
344+
if (context.Request.Path.Equals(basePathNoSlash, StringComparison.OrdinalIgnoreCase)
345+
&& !context.Request.Path.Value.EndsWith("/"))
346+
{
347+
var queryString = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : "";
348+
context.Response.Redirect(redirectTarget + queryString, true);
349+
return;
350+
}
351+
else if (context.Request.Path.Value.Equals("/")
352+
|| context.Request.Path.Value == String.Empty)
353+
{
354+
var queryString = context.Request.QueryString.HasValue ? context.Request.QueryString.Value : "";
355+
context.Response.Redirect(redirectTarget + queryString, true);
356+
return;
357+
}
358+
await next();
359+
});
360+
361+
app.Map(serverOptions.BasePath.TrimEnd('/'), configure);
346362
}
347363
else
348364
{

0 commit comments

Comments
 (0)