refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)
Solution + 23 src projects + 26 test projects renamed; folders, csproj, namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated. ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated. SQL roles/logins, LDAP domains, CLI command name, and CLI config dir (~/.scadalink → ~/.scadabridge) also renamed. Build green; 5 Host.Tests fail awaiting SQL login rename in next commit. Pre-existing StaleTagMonitor timing flakes unchanged. Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
**Goal:** Extract OPC UA endpoint configuration from free-form JSON strings into a strongly-typed `OpcUaEndpointConfig` POCO with a validator and serializer in Commons; consume the model from both the site-side runtime (`OpcUaDataConnection`) and the central UI (`/admin/connections` create/edit), rendering typed Bootstrap controls instead of a JSON textarea.
|
||||
|
||||
**Architecture:** New POCO/validator/serializer in `ScadaLink.Commons` are the single schema. Typed nested JSON (`System.Text.Json`, camelCase) is the storage shape; a legacy flat string-dict fallback in the serializer keeps existing rows readable. `IDataConnection.ConnectAsync` keeps its `IDictionary<string,string>` contract (protocol-agnostic), and `OpcUaDataConnection` uses `OpcUaEndpointConfigSerializer.FromFlatDict` internally to get the typed model. A shared `<OpcUaEndpointEditor>` Blazor component renders the form, used twice (primary + backup).
|
||||
**Architecture:** New POCO/validator/serializer in `ZB.MOM.WW.ScadaBridge.Commons` are the single schema. Typed nested JSON (`System.Text.Json`, camelCase) is the storage shape; a legacy flat string-dict fallback in the serializer keeps existing rows readable. `IDataConnection.ConnectAsync` keeps its `IDictionary<string,string>` contract (protocol-agnostic), and `OpcUaDataConnection` uses `OpcUaEndpointConfigSerializer.FromFlatDict` internally to get the typed model. A shared `<OpcUaEndpointEditor>` Blazor component renders the form, used twice (primary + backup).
|
||||
|
||||
**Tech Stack:** C# 12 / .NET 10, System.Text.Json, Blazor Server, Bootstrap 5, xUnit + bUnit + NSubstitute.
|
||||
|
||||
@@ -34,15 +34,15 @@
|
||||
## Task 1: Create POCOs and add ValidationCategory value
|
||||
|
||||
**Files:**
|
||||
- Create: `src/ScadaLink.Commons/Types/DataConnections/OpcUaSecurityMode.cs`
|
||||
- Create: `src/ScadaLink.Commons/Types/DataConnections/OpcUaHeartbeatConfig.cs`
|
||||
- Create: `src/ScadaLink.Commons/Types/DataConnections/OpcUaEndpointConfig.cs`
|
||||
- Modify: `src/ScadaLink.Commons/Types/Flattening/ValidationResult.cs` (add `ConnectionConfig` enum value)
|
||||
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/OpcUaSecurityMode.cs`
|
||||
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/OpcUaHeartbeatConfig.cs`
|
||||
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/OpcUaEndpointConfig.cs`
|
||||
- Modify: `src/ZB.MOM.WW.ScadaBridge.Commons/Types/Flattening/ValidationResult.cs` (add `ConnectionConfig` enum value)
|
||||
|
||||
**Step 1: Create `OpcUaSecurityMode.cs`**
|
||||
|
||||
```csharp
|
||||
namespace ScadaLink.Commons.Types.DataConnections;
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
|
||||
public enum OpcUaSecurityMode
|
||||
{
|
||||
@@ -55,7 +55,7 @@ public enum OpcUaSecurityMode
|
||||
**Step 2: Create `OpcUaHeartbeatConfig.cs`**
|
||||
|
||||
```csharp
|
||||
namespace ScadaLink.Commons.Types.DataConnections;
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
|
||||
public sealed class OpcUaHeartbeatConfig
|
||||
{
|
||||
@@ -67,7 +67,7 @@ public sealed class OpcUaHeartbeatConfig
|
||||
**Step 3: Create `OpcUaEndpointConfig.cs`**
|
||||
|
||||
```csharp
|
||||
namespace ScadaLink.Commons.Types.DataConnections;
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
|
||||
public sealed class OpcUaEndpointConfig
|
||||
{
|
||||
@@ -95,7 +95,7 @@ public sealed class OpcUaEndpointConfig
|
||||
|
||||
**Step 4: Add `ConnectionConfig` to `ValidationCategory`**
|
||||
|
||||
In `src/ScadaLink.Commons/Types/Flattening/ValidationResult.cs:50-65`, append `ConnectionConfig` to the enum:
|
||||
In `src/ZB.MOM.WW.ScadaBridge.Commons/Types/Flattening/ValidationResult.cs:50-65`, append `ConnectionConfig` to the enum:
|
||||
|
||||
```csharp
|
||||
public enum ValidationCategory
|
||||
@@ -119,13 +119,13 @@ public enum ValidationCategory
|
||||
|
||||
**Step 5: Build to confirm everything compiles**
|
||||
|
||||
Run: `dotnet build src/ScadaLink.Commons/ScadaLink.Commons.csproj`
|
||||
Run: `dotnet build src/ZB.MOM.WW.ScadaBridge.Commons/ZB.MOM.WW.ScadaBridge.Commons.csproj`
|
||||
Expected: build succeeded, 0 errors.
|
||||
|
||||
**Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ScadaLink.Commons/Types/DataConnections/ src/ScadaLink.Commons/Types/Flattening/ValidationResult.cs
|
||||
git add src/ZB.MOM.WW.ScadaBridge.Commons/Types/DataConnections/ src/ZB.MOM.WW.ScadaBridge.Commons/Types/Flattening/ValidationResult.cs
|
||||
git commit -m "feat(commons): OpcUaEndpointConfig POCOs + ConnectionConfig ValidationCategory"
|
||||
```
|
||||
|
||||
@@ -134,15 +134,15 @@ git commit -m "feat(commons): OpcUaEndpointConfig POCOs + ConnectionConfig Valid
|
||||
## Task 2: TDD — `OpcUaEndpointConfigSerializer` tests (failing)
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/ScadaLink.Commons.Tests/Types/DataConnections/OpcUaEndpointConfigSerializerTests.cs`
|
||||
- Create: `tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Types/DataConnections/OpcUaEndpointConfigSerializerTests.cs`
|
||||
|
||||
**Step 1: Write the failing test file**
|
||||
|
||||
```csharp
|
||||
using ScadaLink.Commons.Serialization;
|
||||
using ScadaLink.Commons.Types.DataConnections;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Serialization;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
|
||||
namespace ScadaLink.Commons.Tests.Types.DataConnections;
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Types.DataConnections;
|
||||
|
||||
public class OpcUaEndpointConfigSerializerTests
|
||||
{
|
||||
@@ -308,13 +308,13 @@ public class OpcUaEndpointConfigSerializerTests
|
||||
|
||||
**Step 2: Run the tests to verify failure**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
|
||||
Expected: build error — type `OpcUaEndpointConfigSerializer` does not exist.
|
||||
|
||||
**Step 3: Commit the failing tests**
|
||||
|
||||
```bash
|
||||
git add tests/ScadaLink.Commons.Tests/Types/DataConnections/
|
||||
git add tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Types/DataConnections/
|
||||
git commit -m "test(commons): failing tests for OpcUaEndpointConfigSerializer"
|
||||
```
|
||||
|
||||
@@ -323,16 +323,16 @@ git commit -m "test(commons): failing tests for OpcUaEndpointConfigSerializer"
|
||||
## Task 3: Implement `OpcUaEndpointConfigSerializer`
|
||||
|
||||
**Files:**
|
||||
- Create: `src/ScadaLink.Commons/Serialization/OpcUaEndpointConfigSerializer.cs`
|
||||
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Serialization/OpcUaEndpointConfigSerializer.cs`
|
||||
|
||||
**Step 1: Implement the serializer**
|
||||
|
||||
```csharp
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using ScadaLink.Commons.Types.DataConnections;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
|
||||
namespace ScadaLink.Commons.Serialization;
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Serialization;
|
||||
|
||||
/// <summary>
|
||||
/// Serializes <see cref="OpcUaEndpointConfig"/> to/from the typed nested JSON
|
||||
@@ -450,13 +450,13 @@ public static class OpcUaEndpointConfigSerializer
|
||||
|
||||
**Step 2: Run tests, verify they pass**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigSerializerTests`
|
||||
Expected: all 8 tests pass.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ScadaLink.Commons/Serialization/
|
||||
git add src/ZB.MOM.WW.ScadaBridge.Commons/Serialization/
|
||||
git commit -m "feat(commons): OpcUaEndpointConfigSerializer with legacy fallback + flat-dict interop"
|
||||
```
|
||||
|
||||
@@ -465,16 +465,16 @@ git commit -m "feat(commons): OpcUaEndpointConfigSerializer with legacy fallback
|
||||
## Task 4: TDD — `OpcUaEndpointConfigValidator` tests (failing)
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/ScadaLink.Commons.Tests/Validators/OpcUaEndpointConfigValidatorTests.cs`
|
||||
- Create: `tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Validators/OpcUaEndpointConfigValidatorTests.cs`
|
||||
|
||||
**Step 1: Write the failing test file**
|
||||
|
||||
```csharp
|
||||
using ScadaLink.Commons.Types.DataConnections;
|
||||
using ScadaLink.Commons.Types.Flattening;
|
||||
using ScadaLink.Commons.Validators;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Validators;
|
||||
|
||||
namespace ScadaLink.Commons.Tests.Validators;
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Tests.Validators;
|
||||
|
||||
public class OpcUaEndpointConfigValidatorTests
|
||||
{
|
||||
@@ -586,13 +586,13 @@ public class OpcUaEndpointConfigValidatorTests
|
||||
|
||||
**Step 2: Run, verify failure**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
|
||||
Expected: build error — `OpcUaEndpointConfigValidator` not defined.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add tests/ScadaLink.Commons.Tests/Validators/
|
||||
git add tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/Validators/
|
||||
git commit -m "test(commons): failing tests for OpcUaEndpointConfigValidator"
|
||||
```
|
||||
|
||||
@@ -601,15 +601,15 @@ git commit -m "test(commons): failing tests for OpcUaEndpointConfigValidator"
|
||||
## Task 5: Implement `OpcUaEndpointConfigValidator`
|
||||
|
||||
**Files:**
|
||||
- Create: `src/ScadaLink.Commons/Validators/OpcUaEndpointConfigValidator.cs`
|
||||
- Create: `src/ZB.MOM.WW.ScadaBridge.Commons/Validators/OpcUaEndpointConfigValidator.cs`
|
||||
|
||||
**Step 1: Implement**
|
||||
|
||||
```csharp
|
||||
using ScadaLink.Commons.Types.DataConnections;
|
||||
using ScadaLink.Commons.Types.Flattening;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
|
||||
|
||||
namespace ScadaLink.Commons.Validators;
|
||||
namespace ZB.MOM.WW.ScadaBridge.Commons.Validators;
|
||||
|
||||
/// <summary>
|
||||
/// Pure-function validator for <see cref="OpcUaEndpointConfig"/>. Errors carry
|
||||
@@ -672,13 +672,13 @@ public static class OpcUaEndpointConfigValidator
|
||||
|
||||
**Step 2: Run tests, verify pass**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.Commons.Tests/ScadaLink.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.Commons.Tests/ZB.MOM.WW.ScadaBridge.Commons.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointConfigValidatorTests`
|
||||
Expected: all 11 tests pass.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ScadaLink.Commons/Validators/
|
||||
git add src/ZB.MOM.WW.ScadaBridge.Commons/Validators/
|
||||
git commit -m "feat(commons): OpcUaEndpointConfigValidator"
|
||||
```
|
||||
|
||||
@@ -687,8 +687,8 @@ git commit -m "feat(commons): OpcUaEndpointConfigValidator"
|
||||
## Task 6: Refactor `OpcUaDataConnection.ConnectAsync`
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/ScadaLink.DataConnectionLayer/Adapters/OpcUaDataConnection.cs:44-115`
|
||||
- Verify: `tests/ScadaLink.DataConnectionLayer.Tests/` — any existing test that constructs a `Dictionary<string,string>` and passes it to `ConnectAsync` should keep working unchanged.
|
||||
- Modify: `src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/OpcUaDataConnection.cs:44-115`
|
||||
- Verify: `tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/` — any existing test that constructs a `Dictionary<string,string>` and passes it to `ConnectAsync` should keep working unchanged.
|
||||
|
||||
**Step 1: Replace `ConnectAsync`, `StartHeartbeatMonitorAsync`, and remove `ParseInt`/`ParseBool` helpers**
|
||||
|
||||
@@ -760,22 +760,22 @@ private async Task StartHeartbeatMonitorAsync(OpcUaHeartbeatConfig? heartbeat, C
|
||||
}
|
||||
```
|
||||
|
||||
Delete the two `internal static` helpers at lines 107-115 (`ParseInt`, `ParseBool`). Add `using ScadaLink.Commons.Serialization;` and `using ScadaLink.Commons.Types.DataConnections;` at the top.
|
||||
Delete the two `internal static` helpers at lines 107-115 (`ParseInt`, `ParseBool`). Add `using ZB.MOM.WW.ScadaBridge.Commons.Serialization;` and `using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;` at the top.
|
||||
|
||||
**Step 2: Run DCL test suite — confirm nothing broke**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.DataConnectionLayer.Tests/ScadaLink.DataConnectionLayer.Tests.csproj`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests.csproj`
|
||||
Expected: all green. Existing tests pass `Dictionary<string,string>` to `ConnectAsync`; `FromFlatDict` accepts the same keys (including `endpoint` and `EndpointUrl` casing variants).
|
||||
|
||||
**Step 3: If a test was directly verifying `ParseInt`/`ParseBool` behavior, delete it**
|
||||
|
||||
`grep -n "ParseInt\|ParseBool" tests/ScadaLink.DataConnectionLayer.Tests/ -r` — if it returns hits, delete those test cases. They were testing internals that no longer exist; the same behavior is now covered by `OpcUaEndpointConfigSerializerTests.FromFlatDict_*`.
|
||||
`grep -n "ParseInt\|ParseBool" tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/ -r` — if it returns hits, delete those test cases. They were testing internals that no longer exist; the same behavior is now covered by `OpcUaEndpointConfigSerializerTests.FromFlatDict_*`.
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ScadaLink.DataConnectionLayer/Adapters/OpcUaDataConnection.cs
|
||||
git add tests/ScadaLink.DataConnectionLayer.Tests/ # if any test edits
|
||||
git add src/ZB.MOM.WW.ScadaBridge.DataConnectionLayer/Adapters/OpcUaDataConnection.cs
|
||||
git add tests/ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests/ # if any test edits
|
||||
git commit -m "refactor(dcl): OpcUaDataConnection uses OpcUaEndpointConfig via FromFlatDict"
|
||||
```
|
||||
|
||||
@@ -784,8 +784,8 @@ git commit -m "refactor(dcl): OpcUaDataConnection uses OpcUaEndpointConfig via F
|
||||
## Task 7: Refactor `DeploymentManagerActor.EnsureDclConnections`
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/ScadaLink.SiteRuntime/Actors/DeploymentManagerActor.cs:411-468`
|
||||
- Verify: `tests/ScadaLink.SiteRuntime.Tests/` — particularly any test that hands a sample `FlattenedConfiguration` with a connection JSON.
|
||||
- Modify: `src/ZB.MOM.WW.ScadaBridge.SiteRuntime/Actors/DeploymentManagerActor.cs:411-468`
|
||||
- Verify: `tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/` — particularly any test that hands a sample `FlattenedConfiguration` with a connection JSON.
|
||||
|
||||
**Why this changes:** The current code does dumb `JsonDocument.EnumerateObject` + `prop.Value.ToString()` to flatten the connection JSON into a `Dictionary<string,string>`. With the new typed nested JSON shape (containing a nested `heartbeat` object), that flattener produces `"heartbeat" → "{\"tagPath\":\"...\"}"` — broken. The serializer's `Deserialize` + `ToFlatDict` does it correctly and also handles the legacy shape.
|
||||
|
||||
@@ -860,13 +860,13 @@ private static IDictionary<string, string> FlattenConnectionConfig(string protoc
|
||||
|
||||
**Step 2: Run SiteRuntime tests**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.SiteRuntime.Tests/ScadaLink.SiteRuntime.Tests.csproj`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests/ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests.csproj`
|
||||
Expected: green. Any existing test passing legacy-style JSON for an OPC UA connection still works because `Deserialize` handles both shapes.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ScadaLink.SiteRuntime/Actors/DeploymentManagerActor.cs
|
||||
git add src/ZB.MOM.WW.ScadaBridge.SiteRuntime/Actors/DeploymentManagerActor.cs
|
||||
git commit -m "refactor(site-runtime): route OPC UA connection JSON through serializer"
|
||||
```
|
||||
|
||||
@@ -875,18 +875,18 @@ git commit -m "refactor(site-runtime): route OPC UA connection JSON through seri
|
||||
## Task 8: TDD — `<OpcUaEndpointEditor>` Blazor component tests (failing)
|
||||
|
||||
**Files:**
|
||||
- Create: `tests/ScadaLink.CentralUI.Tests/Forms/OpcUaEndpointEditorTests.cs`
|
||||
- Create: `tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Forms/OpcUaEndpointEditorTests.cs`
|
||||
|
||||
**Step 1: Write the failing tests**
|
||||
|
||||
```csharp
|
||||
using Bunit;
|
||||
using ScadaLink.Commons.Types.DataConnections;
|
||||
using ScadaLink.Commons.Types.Flattening;
|
||||
using ScadaLink.Commons.Validators;
|
||||
using OpcUaEndpointEditor = ScadaLink.CentralUI.Components.Forms.OpcUaEndpointEditor;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Validators;
|
||||
using OpcUaEndpointEditor = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Forms.OpcUaEndpointEditor;
|
||||
|
||||
namespace ScadaLink.CentralUI.Tests.Forms;
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests.Forms;
|
||||
|
||||
public class OpcUaEndpointEditorTests : BunitContext
|
||||
{
|
||||
@@ -969,13 +969,13 @@ public class OpcUaEndpointEditorTests : BunitContext
|
||||
|
||||
**Step 2: Run, verify failure**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
|
||||
Expected: build error — `OpcUaEndpointEditor` does not exist.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add tests/ScadaLink.CentralUI.Tests/Forms/
|
||||
git add tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/Forms/
|
||||
git commit -m "test(ui): failing bUnit tests for OpcUaEndpointEditor"
|
||||
```
|
||||
|
||||
@@ -984,14 +984,14 @@ git commit -m "test(ui): failing bUnit tests for OpcUaEndpointEditor"
|
||||
## Task 9: Implement `<OpcUaEndpointEditor>` Blazor component
|
||||
|
||||
**Files:**
|
||||
- Create: `src/ScadaLink.CentralUI/Components/Forms/OpcUaEndpointEditor.razor`
|
||||
- Create: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Forms/OpcUaEndpointEditor.razor`
|
||||
|
||||
**Step 1: Implement the component**
|
||||
|
||||
```razor
|
||||
@namespace ScadaLink.CentralUI.Components.Forms
|
||||
@using ScadaLink.Commons.Types.DataConnections
|
||||
@using ScadaLink.Commons.Types.Flattening
|
||||
@namespace ZB.MOM.WW.ScadaBridge.CentralUI.Components.Forms
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening
|
||||
|
||||
<div class="opcua-endpoint-editor">
|
||||
<h6 class="text-muted border-bottom pb-1">@Title</h6>
|
||||
@@ -1143,13 +1143,13 @@ git commit -m "test(ui): failing bUnit tests for OpcUaEndpointEditor"
|
||||
|
||||
**Step 2: Run the editor tests, verify pass**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~OpcUaEndpointEditorTests`
|
||||
Expected: all 6 tests pass.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ScadaLink.CentralUI/Components/Forms/
|
||||
git add src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Forms/
|
||||
git commit -m "feat(ui): OpcUaEndpointEditor Blazor component"
|
||||
```
|
||||
|
||||
@@ -1158,9 +1158,9 @@ git commit -m "feat(ui): OpcUaEndpointEditor Blazor component"
|
||||
## Task 10: TDD — `DataConnectionForm` refactor tests (failing/updating)
|
||||
|
||||
**Files:**
|
||||
- Create or modify: `tests/ScadaLink.CentralUI.Tests/DataConnectionFormTests.cs`
|
||||
- Create or modify: `tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/DataConnectionFormTests.cs`
|
||||
|
||||
Before writing, run: `ls tests/ScadaLink.CentralUI.Tests/ | grep -i "DataConnection"`. If a test file already exists, **modify** it; otherwise create new.
|
||||
Before writing, run: `ls tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ | grep -i "DataConnection"`. If a test file already exists, **modify** it; otherwise create new.
|
||||
|
||||
**Step 1: Write the failing tests**
|
||||
|
||||
@@ -1171,11 +1171,11 @@ using Bunit;
|
||||
using Microsoft.AspNetCore.Components.Authorization;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NSubstitute;
|
||||
using ScadaLink.Commons.Entities.Sites;
|
||||
using ScadaLink.Commons.Interfaces.Repositories;
|
||||
using DataConnectionForm = ScadaLink.CentralUI.Components.Pages.Admin.DataConnectionForm;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites;
|
||||
using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories;
|
||||
using DataConnectionForm = ZB.MOM.WW.ScadaBridge.CentralUI.Components.Pages.Admin.DataConnectionForm;
|
||||
|
||||
namespace ScadaLink.CentralUI.Tests;
|
||||
namespace ZB.MOM.WW.ScadaBridge.CentralUI.Tests;
|
||||
|
||||
public class DataConnectionFormTests : BunitContext
|
||||
{
|
||||
@@ -1271,13 +1271,13 @@ public class DataConnectionFormTests : BunitContext
|
||||
|
||||
**Step 2: Run, verify failure**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
|
||||
Expected: at least one test fails — current form still has the Protocol dropdown and stores raw textarea JSON, not typed-camelCase JSON.
|
||||
|
||||
**Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add tests/ScadaLink.CentralUI.Tests/DataConnectionFormTests.cs
|
||||
git add tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/DataConnectionFormTests.cs
|
||||
git commit -m "test(ui): failing tests for DataConnectionForm refactor"
|
||||
```
|
||||
|
||||
@@ -1286,7 +1286,7 @@ git commit -m "test(ui): failing tests for DataConnectionForm refactor"
|
||||
## Task 11: Refactor `DataConnectionForm.razor`
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/ScadaLink.CentralUI/Components/Pages/Admin/DataConnectionForm.razor` (whole file)
|
||||
- Modify: `src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Admin/DataConnectionForm.razor` (whole file)
|
||||
|
||||
**Step 1: Rewrite the form**
|
||||
|
||||
@@ -1297,14 +1297,14 @@ Replace the entire file with:
|
||||
@page "/admin/connections/{Id:int}/edit"
|
||||
@page "/admin/data-connections/create"
|
||||
@page "/admin/data-connections/{Id:int}/edit"
|
||||
@using ScadaLink.Security
|
||||
@using ScadaLink.Commons.Entities.Sites
|
||||
@using ScadaLink.Commons.Interfaces.Repositories
|
||||
@using ScadaLink.Commons.Types.DataConnections
|
||||
@using ScadaLink.Commons.Types.Flattening
|
||||
@using ScadaLink.Commons.Serialization
|
||||
@using ScadaLink.Commons.Validators
|
||||
@using ScadaLink.CentralUI.Components.Forms
|
||||
@using ZB.MOM.WW.ScadaBridge.Security
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Entities.Sites
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Interfaces.Repositories
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Types.DataConnections
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Types.Flattening
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Serialization
|
||||
@using ZB.MOM.WW.ScadaBridge.Commons.Validators
|
||||
@using ZB.MOM.WW.ScadaBridge.CentralUI.Components.Forms
|
||||
@attribute [Authorize(Policy = AuthorizationPolicies.RequireAdmin)]
|
||||
@inject ISiteRepository SiteRepository
|
||||
@inject NavigationManager NavigationManager
|
||||
@@ -1525,18 +1525,18 @@ Replace the entire file with:
|
||||
|
||||
**Step 2: Run the form tests, verify pass**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj --filter FullyQualifiedName~DataConnectionFormTests`
|
||||
Expected: all tests pass.
|
||||
|
||||
**Step 3: Run the full CentralUI suite**
|
||||
|
||||
Run: `dotnet test tests/ScadaLink.CentralUI.Tests/ScadaLink.CentralUI.Tests.csproj`
|
||||
Run: `dotnet test tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests/ZB.MOM.WW.ScadaBridge.CentralUI.Tests.csproj`
|
||||
Expected: all tests pass (the pre-existing `DataConnectionsPageTests` is unaffected; it tests the list page, not the form).
|
||||
|
||||
**Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add src/ScadaLink.CentralUI/Components/Pages/Admin/DataConnectionForm.razor
|
||||
git add src/ZB.MOM.WW.ScadaBridge.CentralUI/Components/Pages/Admin/DataConnectionForm.razor
|
||||
git commit -m "refactor(ui/admin): DataConnectionForm uses OpcUaEndpointEditor and typed model"
|
||||
```
|
||||
|
||||
@@ -1553,10 +1553,10 @@ Expected: build succeeded, 0 errors. Warnings acceptable.
|
||||
|
||||
Run: `dotnet test`
|
||||
Expected: all test projects green. Likely-affected suites:
|
||||
- `ScadaLink.Commons.Tests` (+ new serializer & validator tests, ~19 new total)
|
||||
- `ScadaLink.DataConnectionLayer.Tests` (existing tests must still pass)
|
||||
- `ScadaLink.SiteRuntime.Tests` (existing tests must still pass)
|
||||
- `ScadaLink.CentralUI.Tests` (+ new editor tests, + new/updated form tests)
|
||||
- `ZB.MOM.WW.ScadaBridge.Commons.Tests` (+ new serializer & validator tests, ~19 new total)
|
||||
- `ZB.MOM.WW.ScadaBridge.DataConnectionLayer.Tests` (existing tests must still pass)
|
||||
- `ZB.MOM.WW.ScadaBridge.SiteRuntime.Tests` (existing tests must still pass)
|
||||
- `ZB.MOM.WW.ScadaBridge.CentralUI.Tests` (+ new editor tests, + new/updated form tests)
|
||||
|
||||
**Step 3: If anything fails**, do NOT proceed to Docker. Diagnose and fix in a new commit before moving on.
|
||||
|
||||
@@ -1569,7 +1569,7 @@ There is no commit in this task — it's a checkpoint.
|
||||
**Step 1: Rebuild and start the cluster**
|
||||
|
||||
Run: `bash docker/deploy.sh`
|
||||
Expected: `scadalink:latest` rebuilt, 5 cluster containers up (central-a, central-b, site-a, site-b, site-c per `docker/README.md`).
|
||||
Expected: `scadabridge:latest` rebuilt, 5 cluster containers up (central-a, central-b, site-a, site-b, site-c per `docker/README.md`).
|
||||
|
||||
**Step 2: Open the connections page**
|
||||
|
||||
@@ -1603,13 +1603,13 @@ From the list page, click a site row to select it, then click `+ Connection`.
|
||||
|
||||
**Step 6: Verify DB JSON shape**
|
||||
|
||||
Run: `docker exec scadalink-central-a sqlite3 /var/lib/scadalink/scadalink.db "SELECT PrimaryConfiguration FROM DataConnections ORDER BY Id DESC LIMIT 1;"`
|
||||
Run: `docker exec scadabridge-central-a sqlite3 /var/lib/scadabridge/scadabridge.db "SELECT PrimaryConfiguration FROM DataConnections ORDER BY Id DESC LIMIT 1;"`
|
||||
Expected: typed nested JSON containing `"endpointUrl"`, `"securityMode"`, `"heartbeat":{"tagPath":...}`.
|
||||
|
||||
**Step 7: Deploy a template that uses the connection**
|
||||
|
||||
Optional but a strong smoke. Use any pre-existing template that has a connection binding. Navigate to `/deployment/topology`, deploy to the site that owns the new connection.
|
||||
Expected: site logs (`docker logs scadalink-site-a`) show "OPC UA connected to opc.tcp://..." — the runtime parsed the new JSON shape correctly.
|
||||
Expected: site logs (`docker logs scadabridge-site-a`) show "OPC UA connected to opc.tcp://..." — the runtime parsed the new JSON shape correctly.
|
||||
|
||||
**Step 8: If anything's off**, capture screenshots / logs, fix, and re-deploy before committing.
|
||||
|
||||
@@ -1631,7 +1631,7 @@ Expected: branch advances on origin; existing PR #1 picks up the new commits.
|
||||
|
||||
**Step 3: Verify the PR**
|
||||
|
||||
Open `https://gitea.dohertylan.com/dohertj2/scadalink-design/pulls/1` and confirm the new commits are listed.
|
||||
Open `https://gitea.dohertylan.com/dohertj2/scadabridge-design/pulls/1` and confirm the new commits are listed.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user