Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2bf83d0
Add transactions to the MongoDbContext
imnasnainaec Mar 3, 2026
8641a67
Move multi-DB operations from WordService into WordRepository (#4190)
Copilot Mar 4, 2026
095594a
Add MongoDB transactions to WordRepository multi-collection operation…
Copilot Mar 4, 2026
fc038b5
Move more things into WordRepo
imnasnainaec Mar 4, 2026
54fdea6
Isolate atomic repo transactions
imnasnainaec Mar 5, 2026
2a8e99d
Add new public repo methods to interface
imnasnainaec Mar 5, 2026
f6702b3
Move methods from WordRepo to WordService
imnasnainaec Mar 5, 2026
c0f7029
Refactor Merge
imnasnainaec Mar 5, 2026
7f6a6d0
Refactor UndoMerge
imnasnainaec Mar 5, 2026
9c4173b
Consolidate word actions
imnasnainaec Mar 6, 2026
10b6d8d
Update reverting
imnasnainaec Mar 6, 2026
7e269dd
Tidy
imnasnainaec Mar 6, 2026
7e1dfbf
Fix old id removal
imnasnainaec Mar 6, 2026
e8d0553
Move transaction scaffolding into MongoDbContext
imnasnainaec Mar 9, 2026
0405976
Consolidate WithSession methods
imnasnainaec Mar 9, 2026
adb947d
Update return type of revert/restore functions
imnasnainaec Mar 9, 2026
129c4b5
Fix tests
imnasnainaec Mar 9, 2026
d1679de
Fix RestoreFrontierWithSettion
imnasnainaec Mar 9, 2026
25fd2c0
Rename ExecuteWithTransaction to ExecuteInTransaction
imnasnainaec Mar 9, 2026
7f42af2
Fix up WordRepository public method order
imnasnainaec Mar 9, 2026
6ddf15e
Fix up WordService public method order
imnasnainaec Mar 9, 2026
4758d19
[WordService] Add XML docs and tests
imnasnainaec Mar 9, 2026
cd3b75d
Follow bunny advice
imnasnainaec Mar 9, 2026
9af416e
Resolve bunny advice
imnasnainaec Mar 11, 2026
d59c830
Restore [revert-]merge checking; Reorder with-session methods
imnasnainaec Mar 11, 2026
721c46a
Check id before restoring
imnasnainaec Mar 11, 2026
78917ae
Add UndoMerge bool asserts
imnasnainaec Mar 11, 2026
d8e0f59
Match namespace-class style of codebase
imnasnainaec Mar 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 7 additions & 8 deletions Backend.Tests/Controllers/AudioControllerTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using Backend.Tests.Mocks;
using BackendFramework.Controllers;
Expand All @@ -14,7 +14,7 @@ namespace Backend.Tests.Controllers
internal sealed class AudioControllerTests : IDisposable
{
private IProjectRepository _projRepo = null!;
private IWordRepository _wordRepo = null!;
private WordRepositoryMock _wordRepo = null!;
private PermissionServiceMock _permissionService = null!;
private WordService _wordService = null!;
private AudioController _audioController = null!;
Expand Down Expand Up @@ -163,20 +163,19 @@ public void TestDeleteAudioFileInvalidArguments()
[Test]
public void TestDeleteAudioFileNoWordWithAudio()
{
var result = _audioController.DeleteAudioFile(_projId, "not-a-word", _file.FileName).Result;
Assert.That(result, Is.InstanceOf<NotFoundObjectResult>());
var result1 = _audioController.DeleteAudioFile(_projId, "not-a-word", _file.FileName).Result;
Assert.That(result1, Is.InstanceOf<NotFoundObjectResult>());

var wordId = _wordRepo.Create(Util.RandomWord(_projId)).Result.Id;
result = _audioController.DeleteAudioFile(_projId, wordId, _file.FileName).Result;
Assert.That(result, Is.InstanceOf<NotFoundObjectResult>());
var result2 = _audioController.DeleteAudioFile(_projId, wordId, _file.FileName).Result;
Assert.That(result2, Is.InstanceOf<NotFoundObjectResult>());
}

[Test]
public void TestDeleteAudioFile()
{
// Refill test database
_wordRepo.DeleteAllWords(_projId).Wait();
_wordRepo.DeleteAllFrontierWords(_projId).Wait();
_wordRepo.DeleteAllWords(_projId);
var origWord = Util.RandomWord(_projId);
const string fileName = "a.wav";
origWord.Audio.Add(new Pronunciation(fileName));
Expand Down
8 changes: 4 additions & 4 deletions Backend.Tests/Controllers/LiftControllerTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
Expand All @@ -21,7 +21,7 @@ internal sealed class LiftControllerTests : IDisposable
{
private IProjectRepository _projRepo = null!;
private ISpeakerRepository _speakerRepo = null!;
private IWordRepository _wordRepo = null!;
private WordRepositoryMock _wordRepo = null!;
private ILiftService _liftService = null!;
private IWordService _wordService = null!;
private LiftController _liftController = null!;
Expand Down Expand Up @@ -54,8 +54,8 @@ public void Setup()
var permissionService = new PermissionServiceMock();
_wordService = new WordService(_wordRepo);
var logger = new LoggerMock<LiftController>();
_liftController = new LiftController(_projRepo, semDomRepo, _speakerRepo, _wordRepo, ackService,
_liftService, notifyService, permissionService, logger);
_liftController = new LiftController(_projRepo, semDomRepo, _speakerRepo, _wordRepo, _wordService,
ackService, _liftService, notifyService, permissionService, logger);

_projId = _projRepo.Create(new Project { Name = ProjName }).Result!.Id;
_file = new FormFile(_stream, 0, _stream.Length, "Name", FileName);
Expand Down
14 changes: 5 additions & 9 deletions Backend.Tests/Controllers/WordControllerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace Backend.Tests.Controllers
{
internal sealed class WordControllerTests : IDisposable
{
private IWordRepository _wordRepo = null!;
private WordRepositoryMock _wordRepo = null!;
private IPermissionService _permissionService = null!;
private IWordService _wordService = null!;
private WordController _wordController = null!;
Expand Down Expand Up @@ -411,15 +411,13 @@ public async Task TestUpdateWordMissingWord()
[Test]
public async Task TestRestoreWord()
{
var word = await _wordRepo.Create(Util.RandomWord(ProjId));
await _wordRepo.DeleteFrontier(ProjId, word.Id);
var word = await _wordRepo.Add(Util.RandomWord(ProjId));

Assert.That(await _wordRepo.GetAllWords(ProjId), Does.Contain(word).UsingPropertiesComparer());
Assert.That(await _wordRepo.GetAllFrontier(ProjId), Is.Empty);

var result = await _wordController.RestoreWord(ProjId, word.Id) as OkObjectResult;
Assert.That(result, Is.Not.Null);
Assert.That(result.Value, Is.True);
var result = await _wordController.RestoreWord(ProjId, word.Id);
Assert.That(result, Is.InstanceOf<OkResult>());
Assert.That(await _wordRepo.GetAllWords(ProjId), Does.Contain(word).UsingPropertiesComparer());
Assert.That(await _wordRepo.GetAllFrontier(ProjId), Does.Contain(word).UsingPropertiesComparer());
}
Expand All @@ -433,9 +431,7 @@ public async Task TestRestoreWordAlreadyInFrontier()
Assert.That(await _wordRepo.GetAllFrontier(ProjId), Does.Contain(word).UsingPropertiesComparer());
var frontierCount = await _wordRepo.GetFrontierCount(ProjId);

var result = await _wordController.RestoreWord(ProjId, word.Id) as OkObjectResult;
Assert.That(result, Is.Not.Null);
Assert.That(result.Value, Is.False);
Assert.ThrowsAsync<ArgumentException>(async () => await _wordController.RestoreWord(ProjId, word.Id));
Assert.That(await _wordRepo.GetFrontierCount(ProjId), Is.EqualTo(frontierCount));
}

Expand Down
36 changes: 36 additions & 0 deletions Backend.Tests/Mocks/MongoDbContextMock.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System;
using System.Threading.Tasks;
using BackendFramework.Interfaces;
using MongoDB.Driver;

namespace Backend.Tests.Mocks
{
public class MongoDbContextMock : IMongoDbContext
{
public IMongoDatabase Db => throw new NotSupportedException();

public Task<IMongoTransaction> BeginTransaction()
=> Task.FromResult<IMongoTransaction>(new MongoTransactionMock());

public Task<T> ExecuteInTransaction<T>(Func<IClientSessionHandle, Task<T>> operation)
{
throw new NotImplementedException();
}

public Task<T?> ExecuteInTransactionAllowNull<T>(Func<IClientSessionHandle, Task<T?>> operation)
{
throw new NotImplementedException();
}

private sealed class MongoTransactionMock : IMongoTransaction
{
public IClientSessionHandle Session => null!;

public Task CommitTransactionAsync() => Task.CompletedTask;

public Task AbortTransactionAsync() => Task.CompletedTask;

public void Dispose() { }
}
}
}
Loading
Loading