using Xunit;
namespace ZB.MOM.WW.ScadaBridge.CentralUI.PlaywrightTests.Cluster;
///
/// TDD coverage for the typed fixture helpers used by
/// state-changing Central UI Playwright E2E tests to provision and tear down
/// templates, attributes, areas, and instances against the running dev cluster.
/// When the cluster / MSSQL is unreachable the facts report as Skipped (not
/// Failed), matching the established suite idiom.
///
[Collection("Playwright")]
public class CliRunnerHelpersTests
{
///
/// A freshly created template is discoverable by name prefix and can be
/// deleted, exercising ,
/// , and
/// as a round-trip.
///
[SkippableFact]
public async Task CreateThenDeleteTemplate_RoundTrips()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var name = CliRunner.UniqueName("tmpl");
int id = await CliRunner.CreateTemplateAsync(name);
try
{
var ids = await CliRunner.ListTemplateIdsByNamePrefixAsync(name);
Assert.Contains(id, ids);
}
finally { await CliRunner.DeleteTemplateAsync(id); }
}
///
/// finds the well-known
/// site-a seed site by its siteIdentifier and returns a
/// positive id.
///
[SkippableFact]
public async Task ResolveSiteA_ReturnsId()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
Assert.True(await CliRunner.ResolveSiteIdAsync("site-a") > 0);
}
///
/// A freshly created data connection returns a positive id and is cleanly
/// deleted in teardown, exercising
/// and as a round-trip.
///
[SkippableFact]
public async Task CreateThenDeleteDataConnection_RoundTrips()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var siteId = await CliRunner.ResolveSiteIdAsync("site-a");
var id = await CliRunner.CreateDataConnectionAsync(siteId, CliRunner.UniqueName("conn"));
try
{
Assert.True(id > 0);
}
finally
{
await CliRunner.DeleteDataConnectionAsync(id);
}
}
///
/// A freshly created API method returns a positive id and is cleanly deleted in
/// teardown, exercising and
/// as a round-trip.
///
[SkippableFact]
public async Task CreateThenDeleteApiMethod_RoundTrips()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var id = await CliRunner.CreateApiMethodAsync(CliRunner.UniqueName("method"));
try
{
Assert.True(id > 0);
}
finally
{
await CliRunner.DeleteApiMethodAsync(id);
}
}
///
/// A freshly created area is discoverable by name prefix via
/// , confirming the round-trip
/// used by UI tests that need to tear down areas whose ids are never surfaced.
/// Exercises ,
/// , and
/// .
///
[SkippableFact]
public async Task ListAreaIdsByNamePrefix_FindsCreatedArea()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var siteId = await CliRunner.ResolveSiteIdAsync("site-a");
var name = CliRunner.UniqueName("listarea");
var areaId = await CliRunner.CreateAreaAsync(siteId, name);
try
{
var ids = await CliRunner.ListAreaIdsByNamePrefixAsync(siteId, name);
Assert.Contains(areaId, ids);
}
finally
{
await CliRunner.DeleteAreaAsync(areaId);
}
}
///
/// A freshly created external system is discoverable by name prefix and is cleanly
/// deleted in teardown, exercising ,
/// , and
/// as a round-trip.
///
[SkippableFact]
public async Task CreateThenDeleteExternalSystem_RoundTrips()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var name = CliRunner.UniqueName("extsys");
var id = await CliRunner.CreateExternalSystemAsync(name);
try
{
Assert.True(id > 0);
Assert.Contains(id, await CliRunner.ListExternalSystemIdsByNamePrefixAsync(name));
}
finally { await CliRunner.DeleteExternalSystemAsync(id); }
}
///
/// A freshly created notification list is discoverable by name prefix and is cleanly
/// deleted in teardown, exercising ,
/// , and
/// as a round-trip.
///
[SkippableFact]
public async Task CreateThenDeleteNotificationList_RoundTrips()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var name = CliRunner.UniqueName("notiflist");
var id = await CliRunner.CreateNotificationListAsync(name);
try
{
Assert.True(id > 0);
Assert.Contains(id, await CliRunner.ListNotificationListIdsByNamePrefixAsync(name));
}
finally { await CliRunner.DeleteNotificationListAsync(id); }
}
///
/// A freshly created shared script returns a positive id and is cleanly deleted in
/// teardown, exercising and
/// as a round-trip.
///
[SkippableFact]
public async Task CreateThenDeleteSharedScript_RoundTrips()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var id = await CliRunner.CreateSharedScriptAsync(CliRunner.UniqueName("script"));
try { Assert.True(id > 0); }
finally { await CliRunner.DeleteSharedScriptAsync(id); }
}
///
/// A freshly created LDAP→role mapping returns a positive id, is discoverable by its
/// ldapGroupName in security role-mapping list, and is cleanly deleted in
/// teardown, exercising and
/// as a round-trip.
///
[SkippableFact]
public async Task CreateThenDeleteRoleMapping_RoundTrips()
{
Skip.IfNot(await ClusterAvailability.IsAvailableAsync(), ClusterAvailability.SkipReason);
var group = CliRunner.UniqueName("grp");
var id = await CliRunner.CreateRoleMappingAsync(group, "Designer");
try
{
Assert.True(id > 0);
using var list = await CliRunner.RunJsonAsync("security", "role-mapping", "list");
Assert.Contains(
list.RootElement.EnumerateArray(),
e => e.TryGetProperty("ldapGroupName", out var n) && n.GetString() == group);
}
finally { await CliRunner.DeleteRoleMappingAsync(id); }
}
}