Skip to content

Commit d3a1d82

Browse files
authored
SF-3499 Fix crash from expired tokens when setting drafting sources (#3360)
1 parent 0803616 commit d3a1d82

File tree

2 files changed

+59
-0
lines changed

2 files changed

+59
-0
lines changed

src/SIL.XForge.Scripture/Services/SFProjectService.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2012,6 +2012,10 @@ private async Task<TranslateSource> GetTranslateSourceAsync(
20122012
{
20132013
// The user does not have Paratext access
20142014
}
2015+
catch (UnauthorizedAccessException)
2016+
{
2017+
// The user's refresh token is invalid
2018+
}
20152019
}
20162020

20172021
// If the project is created or the last sync was not successful, sync it unless explicitly skipped.

test/SIL.XForge.Scripture.Tests/Services/SFProjectServiceTests.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Microsoft.Extensions.Options;
1414
using Newtonsoft.Json;
1515
using NSubstitute;
16+
using NSubstitute.ExceptionExtensions;
1617
using NUnit.Framework;
1718
using SIL.XForge.Configuration;
1819
using SIL.XForge.DataAccess;
@@ -2556,6 +2557,60 @@ await env
25562557
await env.SyncService.DidNotReceive().SyncAsync(Arg.Any<SyncConfig>());
25572558
}
25582559

2560+
[Test]
2561+
public async Task UpdateSettingsAsync_ChangeAlternateTrainingSource_AnotherUserOnTheProjectCannotRefreshToken()
2562+
{
2563+
var env = new TestEnvironment();
2564+
const string newProjectParatextId = "changedId";
2565+
env.ParatextService.TryGetProjectRoleAsync(
2566+
Arg.Is<UserSecret>(u => u.Id == User02),
2567+
newProjectParatextId,
2568+
CancellationToken.None
2569+
)
2570+
.ThrowsAsync(new UnauthorizedAccessException());
2571+
2572+
// Ensure that the new project does not exist
2573+
Assert.That(
2574+
env.RealtimeService.GetRepository<SFProject>().Query().Any(p => p.ParatextId == newProjectParatextId),
2575+
Is.False
2576+
);
2577+
2578+
// SUT
2579+
await env.Service.UpdateSettingsAsync(
2580+
User01,
2581+
Project01,
2582+
new SFProjectSettings { AlternateTrainingSourceParatextId = newProjectParatextId }
2583+
);
2584+
2585+
// Verify the alternate training source property of the target project
2586+
SFProject project = env.GetProject(Project01);
2587+
Assert.That(project.TranslateConfig.DraftConfig.AlternateTrainingSource?.ProjectRef, Is.Not.Null);
2588+
Assert.That(
2589+
project.TranslateConfig.DraftConfig.AlternateTrainingSource?.ParatextId,
2590+
Is.EqualTo(newProjectParatextId)
2591+
);
2592+
Assert.That(project.TranslateConfig.DraftConfig.AlternateTrainingSource?.Name, Is.EqualTo("NewSource"));
2593+
Assert.That(project.UserRoles, Contains.Key(User02));
2594+
2595+
// Verify the project document that was created for the alternate training source
2596+
SFProject alternateTrainingSourceProject = env.GetProject(
2597+
project.TranslateConfig.DraftConfig.AlternateTrainingSource!.ProjectRef
2598+
);
2599+
Assert.That(alternateTrainingSourceProject.ParatextId, Is.EqualTo(newProjectParatextId));
2600+
Assert.That(alternateTrainingSourceProject.Name, Is.EqualTo("NewSource"));
2601+
Assert.That(alternateTrainingSourceProject.UserRoles, Does.Not.ContainKey(User02));
2602+
2603+
// Verify that a sync is scheduled
2604+
await env.SyncService.Received().SyncAsync(Arg.Any<SyncConfig>());
2605+
env.BackgroundJobClient.Received(1).Create(Arg.Any<Job>(), Arg.Any<IState>());
2606+
2607+
// Verify that the alternate training source project was created
2608+
Assert.That(
2609+
env.RealtimeService.GetRepository<SFProject>().Query().Any(p => p.ParatextId == newProjectParatextId),
2610+
Is.True
2611+
);
2612+
}
2613+
25592614
[Test]
25602615
public async Task UpdateSettingsAsync_ChangeAdditionalTrainingSource_CreatesProject()
25612616
{

0 commit comments

Comments
 (0)