Skip to content

Commit

Permalink
Fix(general): Fix FK error when deleting a session for which a messag…
Browse files Browse the repository at this point in the history
…e still exists Resolves #1480. (#1481)
  • Loading branch information
rnwood authored May 15, 2024
1 parent 91aa8df commit 5e577a8
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 3 deletions.
68 changes: 68 additions & 0 deletions Rnwood.Smtp4dev.Tests/Data/DataModelTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
using MimeKit;
using NSubstitute;
using Rnwood.Smtp4dev.Controllers;
using Rnwood.Smtp4dev.Data;
using Rnwood.Smtp4dev.Hubs;
using Rnwood.Smtp4dev.Server;
using Rnwood.Smtp4dev.Server.Settings;
using Rnwood.Smtp4dev.Tests.DBMigrations.Helpers;
using Rnwood.SmtpServer;
using System;
using System.Threading.Tasks;
using Xunit;

namespace Rnwood.Smtp4dev.Tests.Data
{
public class DataModelTests
{
[Fact]
public async Task CanDeleteSessionWhenMessageExist()
{
var sqlLiteForTesting = new SqliteInMemory();
var context = new Smtp4devDbContext(sqlLiteForTesting.ContextOptions);

DbModel.Session session = new DbModel.Session();
context.Add(session);
DbModel.Message testMessage1 = await GetTestMessage("Message subject1");
testMessage1.Session = session;

context.Add(testMessage1);
await context.SaveChangesAsync();

context.Remove(session);
await context.SaveChangesAsync();

Assert.Null(testMessage1.Session);
}

private static async Task<DbModel.Message> GetTestMessage(string subject, string from = "from@from.com", string to = "to@to.com")
{
MimeMessage mimeMessage = new MimeMessage();
mimeMessage.From.Add(InternetAddress.Parse(from));
mimeMessage.To.Add(InternetAddress.Parse(to));

mimeMessage.Subject = subject;
BodyBuilder bodyBuilder = new BodyBuilder();
bodyBuilder.HtmlBody = "<html>Hi</html>";
bodyBuilder.TextBody = "Hi";

mimeMessage.Body = bodyBuilder.ToMessageBody();

MemoryMessageBuilder memoryMessageBuilder = new MemoryMessageBuilder();
memoryMessageBuilder.Recipients.Add(to);
memoryMessageBuilder.From = from;
memoryMessageBuilder.ReceivedDate = DateTime.Now;
using (var messageData = await memoryMessageBuilder.WriteData())
{
mimeMessage.WriteTo(messageData);
}

IMessage message = await memoryMessageBuilder.ToMessage();

var dbMessage = await new MessageConverter().ConvertAsync(message, [to]);
dbMessage.Mailbox = new DbModel.Mailbox { Name = MailboxOptions.DEFAULTNAME };

return dbMessage;
}
}
}
2 changes: 1 addition & 1 deletion Rnwood.Smtp4dev/ClientApp/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ <h1 style="float: none;">Your browser is unsupported!</h1>
</div>
</div>
</div>
<script type="module" src="@/main.ts"></script>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
12 changes: 12 additions & 0 deletions Rnwood.Smtp4dev/Data/Smtp4devDbContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Globalization;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Namotion.Reflection;
using Rnwood.Smtp4dev.DbModel;

namespace Rnwood.Smtp4dev.Data
Expand All @@ -22,8 +23,19 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
.HasOne(r => r.Message)
.WithMany(x => x.Relays)
.HasForeignKey(x => x.MessageId)
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();

modelBuilder.Entity<Mailbox>()
.HasMany<Message>()
.WithOne(m => m.Mailbox)
.OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Message>()
.HasOne<Session>(x => x.Session)
.WithMany()
.OnDelete(DeleteBehavior.SetNull);

base.OnModelCreating(modelBuilder);
}

Expand Down
1 change: 1 addition & 0 deletions Rnwood.Smtp4dev/DbModel/Message.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity.Core.Objects.DataClasses;

namespace Rnwood.Smtp4dev.DbModel
{
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace Rnwood.Smtp4dev.Migrations
{
/// <inheritdoc />
public partial class FixSessionMessageCascasing : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Messages_Sessions_SessionId",
table: "Messages");

migrationBuilder.AddForeignKey(
name: "FK_Messages_Sessions_SessionId",
table: "Messages",
column: "SessionId",
principalTable: "Sessions",
principalColumn: "Id",
onDelete: ReferentialAction.SetNull);
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Messages_Sessions_SessionId",
table: "Messages");

migrationBuilder.AddForeignKey(
name: "FK_Messages_Sessions_SessionId",
table: "Messages",
column: "SessionId",
principalTable: "Sessions",
principalColumn: "Id");
}
}
}
4 changes: 3 additions & 1 deletion Rnwood.Smtp4dev/Migrations/Smtp4devDbContextModelSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,11 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.WithMany()
.HasForeignKey("MailboxId")
.OnDelete(DeleteBehavior.Cascade);

b.HasOne("Rnwood.Smtp4dev.DbModel.Session", "Session")
.WithMany()
.HasForeignKey("SessionId");
.HasForeignKey("SessionId")
.OnDelete(DeleteBehavior.SetNull);

b.Navigation("Mailbox");

Expand Down
2 changes: 1 addition & 1 deletion Rnwood.Smtp4dev/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development",
"SERVEROPTIONS__URLS": "http://*:1234"
"SERVEROPTIONS__URLS": "http://*:5000"
},
"applicationUrl": "http://localhost:5000/"
}
Expand Down

0 comments on commit 5e577a8

Please sign in to comment.