Skip to content

Commit aae1e03

Browse files
committed
SF-3759 Add backend endpoint
1 parent c392887 commit aae1e03

5 files changed

Lines changed: 249 additions & 0 deletions

File tree

src/SIL.XForge.Scripture/Controllers/SFProjectsRpcController.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -946,6 +946,45 @@ public async Task<IRpcMethodResult> SetServalConfig(string projectId, string? se
946946
}
947947
}
948948

949+
public async Task<IRpcMethodResult> SetQualityEstimationConfig(
950+
string projectId,
951+
QualityEstimationConfig? qualityEstimationConfig
952+
)
953+
{
954+
try
955+
{
956+
await projectService.SetQualityEstimationConfigAsync(
957+
UserId,
958+
SystemRoles,
959+
projectId,
960+
qualityEstimationConfig
961+
);
962+
return Ok();
963+
}
964+
catch (ForbiddenException)
965+
{
966+
return ForbiddenError();
967+
}
968+
catch (DataNotFoundException dnfe)
969+
{
970+
return NotFoundError(dnfe.Message);
971+
}
972+
catch (Exception)
973+
{
974+
_exceptionHandler.RecordEndpointInfoForException(
975+
new Dictionary<string, string>
976+
{
977+
{ "method", "SetQualityEstimationConfig" },
978+
{ "projectId", projectId },
979+
{ "version", qualityEstimationConfig?.Version.ToString(CultureInfo.InvariantCulture) },
980+
{ "slope", qualityEstimationConfig?.Slope.ToString(CultureInfo.InvariantCulture) },
981+
{ "intercept", qualityEstimationConfig?.Intercept.ToString(CultureInfo.InvariantCulture) },
982+
}
983+
);
984+
throw;
985+
}
986+
}
987+
949988
public async Task<IRpcMethodResult> SetUsfmConfig(string projectId, DraftUsfmConfig config)
950989
{
951990
try

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,14 @@ string audioUrl
8787
[LogEventMetric(EventScope.Drafting, nameof(curUserId))]
8888
Task SetServalConfigAsync(string curUserId, string[] systemRoles, string projectId, string? servalConfig);
8989

90+
[LogEventMetric(EventScope.Drafting, nameof(curUserId))]
91+
Task SetQualityEstimationConfigAsync(
92+
string curUserId,
93+
string[] systemRoles,
94+
string projectId,
95+
QualityEstimationConfig? qualityEstimationConfig
96+
);
97+
9098
Task<string> GetProjectIdFromParatextIdAsync(string[] systemRoles, string paratextId);
9199

92100
Task SetUsfmConfigAsync(string curUserId, string projectId, DraftUsfmConfig config);

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

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,32 @@ await projectDoc.SubmitJson0OpAsync(op =>
12331233
);
12341234
}
12351235

1236+
public async Task SetQualityEstimationConfigAsync(
1237+
string curUserId,
1238+
string[] systemRoles,
1239+
string projectId,
1240+
QualityEstimationConfig? qualityEstimationConfig
1241+
)
1242+
{
1243+
if (!systemRoles.Contains(SystemRole.ServalAdmin))
1244+
throw new ForbiddenException();
1245+
1246+
await using IConnection conn = await RealtimeService.ConnectAsync(curUserId);
1247+
IDocument<SFProject> projectDoc = await GetProjectDocAsync(projectId, conn);
1248+
if (qualityEstimationConfig is null)
1249+
{
1250+
await projectDoc.SubmitJson0OpAsync(op =>
1251+
op.Unset(p => p.TranslateConfig.DraftConfig.QualityEstimationConfig)
1252+
);
1253+
}
1254+
else
1255+
{
1256+
await projectDoc.SubmitJson0OpAsync(op =>
1257+
op.Set(p => p.TranslateConfig.DraftConfig.QualityEstimationConfig, qualityEstimationConfig)
1258+
);
1259+
}
1260+
}
1261+
12361262
public Task<string> GetProjectIdFromParatextIdAsync(string[] systemRoles, string paratextId)
12371263
{
12381264
if (!(systemRoles.Contains(SystemRole.ServalAdmin) || systemRoles.Contains(SystemRole.SystemAdmin)))

test/SIL.XForge.Scripture.Tests/Controllers/SFProjectsRpcControllerTests.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,6 +1012,88 @@ public void SetServalConfig_UnknownError()
10121012
env.ExceptionHandler.Received().RecordEndpointInfoForException(Arg.Any<Dictionary<string, string>>());
10131013
}
10141014

1015+
[Test]
1016+
public async Task SetQualityEstimationConfig_Success()
1017+
{
1018+
var env = new TestEnvironment();
1019+
var qualityEstimationConfig = new QualityEstimationConfig
1020+
{
1021+
Version = 0.1M,
1022+
Slope = 109.6145,
1023+
Intercept = -14.0633,
1024+
};
1025+
1026+
// SUT
1027+
var result = await env.Controller.SetQualityEstimationConfig(Project01, qualityEstimationConfig);
1028+
Assert.That(result, Is.InstanceOf<RpcMethodSuccessResult>());
1029+
await env
1030+
.SFProjectService.Received()
1031+
.SetQualityEstimationConfigAsync(User01, Roles, Project01, qualityEstimationConfig);
1032+
}
1033+
1034+
[Test]
1035+
public async Task SetQualityEstimationConfig_Forbidden()
1036+
{
1037+
var env = new TestEnvironment();
1038+
var qualityEstimationConfig = new QualityEstimationConfig
1039+
{
1040+
Version = 0.1M,
1041+
Slope = 109.6145,
1042+
Intercept = -14.0633,
1043+
};
1044+
env.SFProjectService.SetQualityEstimationConfigAsync(User01, Roles, Project01, qualityEstimationConfig)
1045+
.Throws(new ForbiddenException());
1046+
1047+
// SUT
1048+
var result = await env.Controller.SetQualityEstimationConfig(Project01, qualityEstimationConfig);
1049+
Assert.That(result, Is.InstanceOf<RpcMethodErrorResult>());
1050+
Assert.That((result as RpcMethodErrorResult)?.ErrorCode, Is.EqualTo(RpcControllerBase.ForbiddenErrorCode));
1051+
await env
1052+
.SFProjectService.Received()
1053+
.SetQualityEstimationConfigAsync(User01, Roles, Project01, qualityEstimationConfig);
1054+
}
1055+
1056+
[Test]
1057+
public async Task SetQualityEstimationConfig_NotFound()
1058+
{
1059+
var env = new TestEnvironment();
1060+
var qualityEstimationConfig = new QualityEstimationConfig
1061+
{
1062+
Version = 0.1M,
1063+
Slope = 109.6145,
1064+
Intercept = -14.0633,
1065+
};
1066+
const string errorMessage = "Not Found";
1067+
env.SFProjectService.SetQualityEstimationConfigAsync(User01, Roles, Project01, qualityEstimationConfig)
1068+
.Throws(new DataNotFoundException(errorMessage));
1069+
1070+
// SUT
1071+
var result = await env.Controller.SetQualityEstimationConfig(Project01, qualityEstimationConfig);
1072+
Assert.That(result, Is.InstanceOf<RpcMethodErrorResult>());
1073+
Assert.That((result as RpcMethodErrorResult)?.Message, Is.EqualTo(errorMessage));
1074+
Assert.That((result as RpcMethodErrorResult)?.ErrorCode, Is.EqualTo(RpcControllerBase.NotFoundErrorCode));
1075+
}
1076+
1077+
[Test]
1078+
public void SetQualityEstimationConfig_UnknownError()
1079+
{
1080+
var env = new TestEnvironment();
1081+
var qualityEstimationConfig = new QualityEstimationConfig
1082+
{
1083+
Version = 0.1M,
1084+
Slope = 109.6145,
1085+
Intercept = -14.0633,
1086+
};
1087+
env.SFProjectService.SetQualityEstimationConfigAsync(User01, Roles, Project01, qualityEstimationConfig)
1088+
.Throws(new ArgumentNullException());
1089+
1090+
// SUT
1091+
Assert.ThrowsAsync<ArgumentNullException>(() =>
1092+
env.Controller.SetQualityEstimationConfig(Project01, qualityEstimationConfig)
1093+
);
1094+
env.ExceptionHandler.Received().RecordEndpointInfoForException(Arg.Any<Dictionary<string, string>>());
1095+
}
1096+
10151097
[Test]
10161098
public async Task SetUsfmConfig_Success()
10171099
{

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

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3900,6 +3900,94 @@ public void SetServalConfigAsync_UserMustBeServalAdmin()
39003900
);
39013901
}
39023902

3903+
[Test]
3904+
public async Task SetQualityEstimationConfigAsync_AllowsNull()
3905+
{
3906+
var env = new TestEnvironment();
3907+
3908+
// SUT
3909+
await env.Service.SetQualityEstimationConfigAsync(
3910+
User01,
3911+
[SystemRole.ServalAdmin],
3912+
Project01,
3913+
qualityEstimationConfig: null
3914+
);
3915+
3916+
// Verify project document
3917+
SFProject project = env.GetProject(Project01);
3918+
Assert.That(project.TranslateConfig.DraftConfig!.QualityEstimationConfig, Is.Null);
3919+
}
3920+
3921+
[Test]
3922+
public void SetQualityEstimationConfigAsync_ProjectMustExist()
3923+
{
3924+
var env = new TestEnvironment();
3925+
var qualityEstimationConfig = new QualityEstimationConfig
3926+
{
3927+
Version = 0.1M,
3928+
Slope = 109.6145,
3929+
Intercept = -14.0633,
3930+
};
3931+
3932+
// SUT
3933+
Assert.ThrowsAsync<DataNotFoundException>(() =>
3934+
env.Service.SetQualityEstimationConfigAsync(
3935+
User01,
3936+
[SystemRole.ServalAdmin],
3937+
"invalid_project",
3938+
qualityEstimationConfig
3939+
)
3940+
);
3941+
}
3942+
3943+
[Test]
3944+
public async Task SetQualityEstimationConfigAsync_UpdatesProjectDocument()
3945+
{
3946+
var env = new TestEnvironment();
3947+
var qualityEstimationConfig = new QualityEstimationConfig
3948+
{
3949+
Version = 0.1M,
3950+
Slope = 109.6145,
3951+
Intercept = -14.0633,
3952+
};
3953+
3954+
// Verify project document
3955+
SFProject project = env.GetProject(Project01);
3956+
Assert.IsNotNull(project.TranslateConfig.DraftConfig.QualityEstimationConfig);
3957+
3958+
// SUT
3959+
await env.Service.SetQualityEstimationConfigAsync(
3960+
User01,
3961+
[SystemRole.ServalAdmin],
3962+
Project01,
3963+
qualityEstimationConfig
3964+
);
3965+
3966+
// Verify project document
3967+
project = env.GetProject(Project01);
3968+
Assert.That(
3969+
project.TranslateConfig.DraftConfig.QualityEstimationConfig,
3970+
Is.EqualTo(qualityEstimationConfig).UsingPropertiesComparer()
3971+
);
3972+
}
3973+
3974+
[Test]
3975+
public void SetQualityEstimationConfigAsync_UserMustBeServalAdmin()
3976+
{
3977+
var env = new TestEnvironment();
3978+
var qualityEstimationConfig = new QualityEstimationConfig
3979+
{
3980+
Version = 0.1M,
3981+
Slope = 109.6145,
3982+
Intercept = -14.0633,
3983+
};
3984+
3985+
// SUT
3986+
Assert.ThrowsAsync<ForbiddenException>(() =>
3987+
env.Service.SetQualityEstimationConfigAsync(User01, [SystemRole.User], Project01, qualityEstimationConfig)
3988+
);
3989+
}
3990+
39033991
[Test]
39043992
public async Task SetUsfmConfigAsync_UpdatesUsfmConfig()
39053993
{
@@ -4803,6 +4891,12 @@ public TestEnvironment()
48034891
{
48044892
UsfmConfig = new DraftUsfmConfig(),
48054893
ServalConfig = "{ existingConfig: true }",
4894+
QualityEstimationConfig = new QualityEstimationConfig
4895+
{
4896+
Version = 0M,
4897+
Slope = 0.0,
4898+
Intercept = 0.0,
4899+
},
48064900
},
48074901
},
48084902
CheckingConfig = new CheckingConfig { CheckingEnabled = true },

0 commit comments

Comments
 (0)