Files
SocialPub/PrivaPub.Tests/Infrastructure/IndexTests.cs
T
thepraandClaude Opus 5.5 00b2685cf4 T1: tests stop sharing state they don't own
- JobQueue takes an optional scope, so a test's worker leases and reaps only its own jobs.
- The dead-host delivery test runs alone (Exclusive), on its own jobs, and cleans up the
  breaker rows it trips; the breaker has tests of its own on unique hosts.
- Index and migration tests run alone: they drop indexes and rewrite every post.
- DomainBlocks.Load replaces reflection and a database-wide block in tests.
- Harness.Outgoing sees only deliveries queued since the harness started: Peer ports are
  reused within a run, which made the circle test flaky.
- Two pure-logic tests leave Mongo-gated classes, so CI runs them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ELjqpznMFMNrJoJUj6K5p2
2026-10-03 10:36:15 +02:00

65 lines
2.8 KiB
C#

using MongoDB.Driver;
using MongoDB.Entities;
using PrivaPub.Federation.Actors;
using PrivaPub.Infrastructure.Data;
using PrivaPub.Infrastructure.Data.Migrations;
using PrivaPub.Models;
using PrivaPub.Models.Federation;
using PrivaPub.Models.User;
using PrivaPub.StaticServices;
using PrivaPub.Tests.Support;
namespace PrivaPub.Tests.Infrastructure
{
[Xunit.Collection(nameof(Exclusive))]
[Trait("Category", "Integration")]
public class IndexTests
{
[Fact]
public async Task Duplicates_are_removed_and_the_unique_indexes_then_hold()
{
Assert.SkipUnless(MongoFixture.Enabled, MongoFixture.Skip);
var token = TestContext.Current.CancellationToken;
await DB.Default.Index<ForeignAvatar>().DropAllAsync(token);
await DB.Default.Index<Follower>().DropAllAsync(token);
var actorUri = $"https://r.example/users/{Guid.NewGuid():N}";
var localId = Guid.NewGuid().ToString("N")[..24];
await DB.Default.SaveAsync(new[]
{
new ForeignAvatar { ActorURI = actorUri, Name = "old", UpdatedAt = DateTime.UtcNow.AddDays(-2) },
new ForeignAvatar { ActorURI = actorUri, Name = "new", UpdatedAt = DateTime.UtcNow }
}, token);
await DB.Default.SaveAsync(new[]
{
new Follower { LocalActorId = localId, ActorURI = actorUri, IsAccepted = false },
new Follower { LocalActorId = localId, ActorURI = actorUri, IsAccepted = true }
}, token);
await new _001_deduplicate_before_unique_indexes().UpgradeAsync();
await Indexes.Create(token);
Assert.Equal("new", (await DB.Default.Find<ForeignAvatar>().Match(a => a.ActorURI == actorUri).ExecuteSingleAsync(token)).Name);
Assert.True((await DB.Default.Find<Follower>().Match(f => f.LocalActorId == localId).ExecuteSingleAsync(token)).IsAccepted);
var duplicate = await Assert.ThrowsAsync<MongoWriteException>(async () =>
await DB.Default.SaveAsync(new ForeignAvatar { ActorURI = actorUri }, token));
Assert.Equal(ServerErrorCategory.DuplicateKey, duplicate.WriteError.Category);
}
[Fact]
public async Task A_username_is_reserved_once_across_personas_and_groups()
{
Assert.SkipUnless(MongoFixture.Enabled, MongoFixture.Skip);
var token = TestContext.Current.CancellationToken;
var local = new LocalActorService(new DbEntities(), new StaticOptions<AppConfiguration>(new AppConfiguration { BackendBaseAddress = "https://privapub.test" }));
var name = $"n{Guid.NewGuid():N}"[..20];
Assert.True(await local.TryReserveUserName(name, LocalActorKind.Person, "a", token));
Assert.False(await local.TryReserveUserName(name.ToUpperInvariant(), LocalActorKind.Group, "b", token));
Assert.True(await local.IsUserNameTaken(name, token));
Assert.False(await local.TryReserveUserName("admin", LocalActorKind.Person, "c", token));
Assert.False(await local.TryReserveUserName(LocalActorService.InstanceUserName, LocalActorKind.Person, "c", token));
}
}
}