Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 87 additions & 0 deletions FluentAAS/FluentAAS.Builder.Tests/AasBuilderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,93 @@ public void AddSubmodelFragment_WithoutBaseSubmodel_ShouldThrowInvalidOperationE
ex.Message.ShouldContain("No base submodel");
}

[Fact]
public void Build_WithShellReferencingKnownSubmodelId_ShouldSucceed()
{
// Arrange
var builder = CreateSut();
var submodelId = _fixture.Create<string>()!;
builder.AddSubmodel(new Submodel(id: submodelId, idShort: "known-submodel"));

var shell = new AssetAdministrationShell(
id: _fixture.Create<string>()!,
assetInformation: new AssetInformation(AssetKind.Instance))
{
IdShort = "shell-with-known-ref",
Submodels =
[
new Reference(
ReferenceTypes.ModelReference,
[new Key(KeyTypes.Submodel, submodelId)])
]
};

builder.AddShellInternal(shell);

// Act
var environment = builder.Build();

// Assert
var builtShell = environment.AssetAdministrationShells!.OfType<AssetAdministrationShell>().Single();
builtShell.Submodels.ShouldNotBeNull();
builtShell.Submodels.Count.ShouldBe(1);
builtShell.Submodels.Single().Keys.Single().Value.ShouldBe(submodelId);
}

[Fact]
public void Build_WithShellReferencingUnknownSubmodelId_ShouldThrowInvalidOperationException()
{
// Arrange
var builder = CreateSut();
var unknownSubmodelId = _fixture.Create<string>()!;

var shell = new AssetAdministrationShell(
id: _fixture.Create<string>()!,
assetInformation: new AssetInformation(AssetKind.Instance))
{
IdShort = "shell-with-unknown-ref",
Submodels =
[
new Reference(
ReferenceTypes.ModelReference,
[new Key(KeyTypes.Submodel, unknownSubmodelId)])
]
};

builder.AddShellInternal(shell);

// Act
var act = () => builder.Build();

// Assert
var ex = Should.Throw<InvalidOperationException>(act);
ex.Message.ShouldContain($"references unknown submodel id '{unknownSubmodelId}'");
}

[Fact]
public void Build_WhenFragmentBatchFails_ShouldRollbackAppliedFragmentsBeforeRetry()
{
// Arrange
var builder = CreateSut();
var existingSubmodelId = _fixture.Create<string>();
var missingSubmodelId = _fixture.Create<string>();

builder.AddSubmodel(new Submodel(id: existingSubmodelId, idShort: "existing"));
builder.AddSubmodelFragment(existingSubmodelId, fragment => fragment.AddProperty("temperature", "21.5"));
builder.AddSubmodelFragment(missingSubmodelId, fragment => fragment.AddProperty("pressure", "1.0"));

// Act
Should.Throw<InvalidOperationException>(() => builder.Build());

builder.AddSubmodel(new Submodel(id: missingSubmodelId, idShort: "missing-now-added"));
var env = builder.Build();

// Assert
var existingSubmodel = env.Submodels!.OfType<Submodel>().Single(s => s.Id == existingSubmodelId);
existingSubmodel.SubmodelElements.ShouldNotBeNull();
existingSubmodel.SubmodelElements.Count(e => e.IdShort == "temperature").ShouldBe(1);
}

[Fact]
public void Build_WhenCalledMultipleTimes_ShouldReturnNewEnvironmentInstancesWithSameContent()
{
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ var environment = builder.Build();
- Fragment targets must exist.
- Shell submodel references must resolve to known submodels.

> Backward compatibility note: `AddExistingSubmodel(...)` still works and delegates to `AddSubmodel(...)`.
> Backward compatibility note: `AddExistingSubmodel(...)` still works, but it delegates to `AddSubmodelInternal(...)` (not `AddSubmodel(...)`) and therefore skips the additional public `IdShort` validation performed by `AddSubmodel(...)`.

---

Expand Down
Loading