Skip to content

Commit

Permalink
Merge branch 'master' into permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
daniel-lerch committed Feb 7, 2025
2 parents dd3de97 + 21d6fb0 commit 93eb31f
Show file tree
Hide file tree
Showing 25 changed files with 2,633 additions and 1,188 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
- name: Setup NodeJS
uses: actions/setup-node@v4
with:
node-version: '20'
node-version: '22'
- name: Restore NPM packages
run: npm install
working-directory: webapp
Expand Down Expand Up @@ -69,7 +69,7 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
push: true
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20 AS webapp
FROM node:22 AS webapp
WORKDIR /app

# Copy package definition and restore node modules as distinct layers
Expand Down
2 changes: 1 addition & 1 deletion Korga.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "_", "_", "{28945597-DB66-4C
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{2ED6D7FB-8B8A-4139-98C3-854E00A38490}"
ProjectSection(SolutionItems) = preProject
docs\docker-compose.yml = docs\docker-compose.yml
docs\compose.yaml = docs\compose.yaml
docs\email-processing-pipeline.md = docs\email-processing-pipeline.md
docs\frontend.md = docs\frontend.md
EndProjectSection
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ The following instructions are written for Windows but generally also apply to L
### Frontend
- Visual Studio Code
- Vue Language Features (Volar) Extension
- NodeJS 20 LTS
- NodeJS 22 LTS

During development the frontend running on the Vue CLI development server will use _http://localhost:10501_ as API endpoint.
That means the backend can be running in Visual Studio with Debugger attached.
Expand Down
8 changes: 5 additions & 3 deletions server/ChurchTools/Model/Service.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
namespace ChurchTools.Model;
using System.Collections.Generic;

namespace ChurchTools.Model;

public class Service
{
public Service(int id, string name, int serviceGroupId, int sortKey, string groupIds, string tagIds)
public Service(int id, string name, int serviceGroupId, int sortKey, List<int>? groupIds, string tagIds)
{
Id = id;
Name = name;
Expand All @@ -19,7 +21,7 @@ public Service(int id, string name, int serviceGroupId, int sortKey, string grou
/// <summary>
/// Comma separated list of standard groups IDs
/// </summary>
public string? GroupIds { get; }
public List<int>? GroupIds { get; }
/// <summary>
/// Comma separated list of person tag IDs
/// </summary>
Expand Down
6 changes: 3 additions & 3 deletions server/Korga.Tests/Korga.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="8.0.7" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="coverlet.collector" Version="6.0.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="xunit" Version="2.9.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2">
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }

public DbSet<InboxEmail> InboxEmails => Set<InboxEmail>();
public DbSet<DistributionList> DistributionLists => Set<DistributionList>();
public DbSet<PersonFilterList> PersonFilterLists => Set<PersonFilterList>();
public DbSet<PersonFilter> PersonFilters => Set<PersonFilter>();
Expand Down
23 changes: 23 additions & 0 deletions server/Korga.Tests/Migrations/09_PersonFilterList/InboxEmail.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;

namespace Korga.Tests.Migrations.PersonFilterList;

public class InboxEmail
{
public long Id { get; set; }

public long? DistributionListId { get; set; }
public DistributionList? DistributionList { get; set; }

public uint? UniqueId { get; set; }
public required string Subject { get; set; }
public required string From { get; set; }
public string? Sender { get; set; }
public string? ReplyTo { get; set; }
public required string To { get; set; }
public string? Receiver { get; set; }
public byte[]? Header { get; set; }
public byte[]? Body { get; set; }
public DateTime DownloadTime { get; set; }
public DateTime ProcessingCompletedTime { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Microsoft.EntityFrameworkCore;

namespace Korga.Tests.Migrations.NullableEmailHeaders;

public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options) { }

public DbSet<InboxEmail> InboxEmails => Set<InboxEmail>();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;

namespace Korga.Tests.Migrations.NullableEmailHeaders;

public class InboxEmail
{
public long Id { get; set; }

public long? DistributionListId { get; set; }

public uint? UniqueId { get; set; }
public string? Subject { get; set; }
public string? From { get; set; }
public string? Sender { get; set; }
public string? ReplyTo { get; set; }
public string? To { get; set; }
public string? Receiver { get; set; }
public byte[]? Header { get; set; }
public byte[]? Body { get; set; }
public DateTime DownloadTime { get; set; }
public DateTime ProcessingCompletedTime { get; set; }
}
122 changes: 122 additions & 0 deletions server/Korga.Tests/Migrations/10_NullableEmailHeadersMigrationTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.Extensions.DependencyInjection;
using System.Collections.Generic;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace Korga.Tests.Migrations;

public class NullableEmailHeadersMigrationTests : MigrationTestBase<PersonFilterList.DatabaseContext, NullableEmailHeaders.DatabaseContext>
{
public NullableEmailHeadersMigrationTests(ITestOutputHelper testOutput) : base(testOutput) { }

[Fact]
public async Task TestUpgrade()
{
PersonFilterList.InboxEmail reference = new()
{
Id = 1,
Subject = "Test",
From = "[email protected]",
To = "[email protected]",
};
PersonFilterList.InboxEmail emptyFields = new()
{
Id = 2,
Subject = string.Empty,
From = string.Empty,
To = string.Empty,
};
IMigrator migrator = databaseContext.GetInfrastructure().GetRequiredService<IMigrator>();

// Create database schema of last migration before the one to test
await migrator.MigrateAsync("PersonFilterList");

// Add test data
before.InboxEmails.Add(reference);
before.InboxEmails.Add(emptyFields);
await before.SaveChangesAsync();

// Run migration at test
await migrator.MigrateAsync("NullableEmailHeaders");

// Verify that data has been migrated as expected
List<NullableEmailHeaders.InboxEmail> inboxEmails = await after.InboxEmails.ToListAsync();
Assert.Contains(inboxEmails, email => email.Id == reference.Id);
Assert.Contains(inboxEmails, email => email.Id == emptyFields.Id);
Assert.Equal(2, inboxEmails.Count);
}

[Fact]
public async Task TestDowngrade()
{
NullableEmailHeaders.InboxEmail reference = new()
{
Id = 1,
Subject = "Test",
From = "[email protected]",
To = "[email protected]",
};
NullableEmailHeaders.InboxEmail emptyFields = new()
{
Id = 2,
Subject = string.Empty,
From = string.Empty,
To = string.Empty,
};
NullableEmailHeaders.InboxEmail nullSubject = new()
{
Id = 3,
Subject = null,
From = "[email protected]",
To = "[email protected]",
};
NullableEmailHeaders.InboxEmail nullFrom = new()
{
Id = 4,
Subject = "Test",
From = null,
To = "[email protected]",
};
NullableEmailHeaders.InboxEmail nullTo = new()
{
Id = 5,
Subject = "Test",
From = "[email protected]",
To = null,
};
IMigrator migrator = databaseContext.GetInfrastructure().GetRequiredService<IMigrator>();

// Create database schema of the migration to test
await migrator.MigrateAsync("NullableEmailHeaders");

// Add test data
after.InboxEmails.Add(reference);
after.InboxEmails.Add(emptyFields);
after.InboxEmails.Add(nullSubject);
after.InboxEmails.Add(nullFrom);
after.InboxEmails.Add(nullTo);
await after.SaveChangesAsync();

// Reset change tracker before upgrading the schema again to avoid caching
after.ChangeTracker.Clear();

// Migrate to migration before the one to test and thereby revert it
await migrator.MigrateAsync("PersonFilterList");

// Verify that data has been migrated as expected
List<PersonFilterList.InboxEmail> inboxEmails = await before.InboxEmails.ToListAsync();
Assert.Contains(inboxEmails, email => email.Id == reference.Id);
Assert.Contains(inboxEmails, email => email.Id == emptyFields.Id);
Assert.DoesNotContain(inboxEmails, email => email.Id == nullSubject.Id);
Assert.DoesNotContain(inboxEmails, email => email.Id == nullFrom.Id);
Assert.DoesNotContain(inboxEmails, email => email.Id == nullTo.Id);
Assert.Equal(2, inboxEmails.Count);

// Upgrade database again to verify rollback worked
await migrator.MigrateAsync("NullableEmailHeaders");
}
}
4 changes: 2 additions & 2 deletions server/Korga.Tests/Migrations/10_PermissionMigrationTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class PermissionMigrationTests : MigrationTestBase<PersonFilterList.Datab
{
public PermissionMigrationTests(ITestOutputHelper testOutput) : base(testOutput) { }

[Fact]
//[Fact]
public async Task TestUpgrade()
{
IMigrator migrator = databaseContext.GetInfrastructure().GetRequiredService<IMigrator>();
Expand Down Expand Up @@ -52,7 +52,7 @@ public async Task TestUpgrade()
Assert.True(await after.PersonFilterLists.AnyAsync(fl => fl.Id == permittedRecipientId));
}

[Fact]
//[Fact]
public async Task TestDowngrade()
{
IMigrator migrator = databaseContext.GetInfrastructure().GetRequiredService<IMigrator>();
Expand Down
2 changes: 1 addition & 1 deletion server/Korga/Controllers/ServiceController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ private async ValueTask<IEnumerable<int>> GetServiceGroups(IEnumerable<int> serv
foreach (Service service in services)
{
if (service.GroupIds == null) continue;
groupIds.UnionWith(service.GroupIds.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse));
groupIds.UnionWith(service.GroupIds);
}
return groupIds;
}
Expand Down
Loading

0 comments on commit 93eb31f

Please sign in to comment.