feat: complete legacy parity and modernize operator UI
This commit is contained in:
@@ -68,6 +68,75 @@ public sealed class OracleManualFinancialMutationExecutorTests
|
||||
Assert.True(plan.TransactionDisposed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Raw_update_accepts_Core_opaque_ROWID_command_and_binds_legacy_controls()
|
||||
{
|
||||
var plan = new Plan
|
||||
{
|
||||
ExecuteAsync = (index, _) => Task.FromResult(index == 0 ? -1 : 1)
|
||||
};
|
||||
var factory = new Factory(plan, 17);
|
||||
var service = new LegacyManualFinancialScreenService(
|
||||
new StaticRawQueryExecutor(),
|
||||
Executor(factory));
|
||||
var listed = Assert.Single((await service.SearchAsync(
|
||||
ManualFinancialScreenKind.Sales)).RawItems);
|
||||
var values = listed.Record.StorageValues.ToArray();
|
||||
values[0] = " raw_\u0000value ";
|
||||
|
||||
var receipt = await service.UpdateRawAsync(
|
||||
listed,
|
||||
new ManualFinancialRawRecord(listed.Record.Identity, values));
|
||||
|
||||
Assert.Equal(ManualFinancialMutationKind.Update, receipt.Kind);
|
||||
Assert.Equal(2, plan.Commands.Count);
|
||||
var command = plan.Commands[1];
|
||||
Assert.Contains(
|
||||
"ROWID = CHARTOROWID(:row_handle)",
|
||||
command.CommandText,
|
||||
StringComparison.Ordinal);
|
||||
Assert.Equal(" raw_\u0000value ", command.ParametersSnapshot
|
||||
.Single(parameter => parameter.ParameterName == "field_1").Value);
|
||||
Assert.Equal("AAAAAAAAAAAAAAAAAA", command.ParametersSnapshot
|
||||
.Single(parameter => parameter.ParameterName == "row_handle").Value);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Raw_update_row_version_mismatch_rolls_back_once_without_retry()
|
||||
{
|
||||
var plan = new Plan
|
||||
{
|
||||
ExecuteAsync = (index, _) => Task.FromResult(index == 0 ? -1 : 0)
|
||||
};
|
||||
var factory = new Factory(plan, 17);
|
||||
var service = new LegacyManualFinancialScreenService(
|
||||
new StaticRawQueryExecutor(),
|
||||
Executor(factory));
|
||||
var listed = Assert.Single((await service.SearchAsync(
|
||||
ManualFinancialScreenKind.Sales)).RawItems);
|
||||
var values = listed.Record.StorageValues.ToArray();
|
||||
values[0] = "A\u001fB";
|
||||
values[1] = "C\0";
|
||||
|
||||
var exception = await Assert.ThrowsAsync<ManualFinancialMutationRejectedException>(() =>
|
||||
service.UpdateRawAsync(
|
||||
listed,
|
||||
new ManualFinancialRawRecord(listed.Record.Identity, values)));
|
||||
|
||||
Assert.Equal(
|
||||
ManualFinancialMutationRejectionReason.NotFoundOrChanged,
|
||||
exception.Reason);
|
||||
Assert.False(exception.OutcomeUnknown);
|
||||
Assert.Equal(1, factory.CreateCount);
|
||||
Assert.Equal(1, plan.RollbackCount);
|
||||
Assert.Equal(0, plan.CommitCount);
|
||||
Assert.Equal(2, plan.Commands.Count);
|
||||
Assert.Equal([1, 1], plan.Commands.Select(command => command.ExecuteCount));
|
||||
Assert.Contains("CASE WHEN STOCK_NAME IS NULL THEN 'N'", plan.Commands[1].CommandText,
|
||||
StringComparison.Ordinal);
|
||||
Assert.DoesNotContain("CHR(31)", plan.Commands[1].CommandText, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task DeniedAuthorizationCreatesNoConnectionOrTransaction()
|
||||
{
|
||||
@@ -205,6 +274,46 @@ public sealed class OracleManualFinancialMutationExecutorTests
|
||||
throw new InvalidOperationException("A mutation test must not read.");
|
||||
}
|
||||
|
||||
private sealed class StaticRawQueryExecutor : IDataQueryExecutor
|
||||
{
|
||||
public DataTable Execute(DataSourceKind source, string tableName, string query) =>
|
||||
throw new NotSupportedException();
|
||||
|
||||
public Task<DataTable> ExecuteAsync(
|
||||
DataSourceKind source,
|
||||
string tableName,
|
||||
string query,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
throw new NotSupportedException();
|
||||
|
||||
public Task<DataTable> ExecuteAsync(
|
||||
DataSourceKind source,
|
||||
string tableName,
|
||||
DataQuerySpec query,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
var table = new DataTable();
|
||||
foreach (var column in ManualFinancialCutContracts.Get(
|
||||
ManualFinancialScreenKind.Sales).StorageColumns)
|
||||
{
|
||||
table.Columns.Add(column, typeof(string));
|
||||
}
|
||||
table.Columns.Add("ROW_VERSION", typeof(string));
|
||||
table.Columns.Add("ROW_HANDLE", typeof(string));
|
||||
table.Rows.Add(
|
||||
"Alpha",
|
||||
"_10",
|
||||
"2Q_20",
|
||||
"3Q_30",
|
||||
"4Q_40",
|
||||
"5Q_50",
|
||||
"6Q_60",
|
||||
Version,
|
||||
"AAAAAAAAAAAAAAAAAA");
|
||||
return Task.FromResult(table);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class Factory(Plan plan, int commandTimeoutSeconds = 15)
|
||||
: IDatabaseConnectionFactory
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user