AtomiCloud.Diene.ApiEngine.TestHelper
1.0.0
dotnet add package AtomiCloud.Diene.ApiEngine.TestHelper --version 1.0.0
NuGet\Install-Package AtomiCloud.Diene.ApiEngine.TestHelper -Version 1.0.0
<PackageReference Include="AtomiCloud.Diene.ApiEngine.TestHelper" Version="1.0.0" />
<PackageVersion Include="AtomiCloud.Diene.ApiEngine.TestHelper" Version="1.0.0" />
<PackageReference Include="AtomiCloud.Diene.ApiEngine.TestHelper" />
paket add AtomiCloud.Diene.ApiEngine.TestHelper --version 1.0.0
#r "nuget: AtomiCloud.Diene.ApiEngine.TestHelper, 1.0.0"
#:package AtomiCloud.Diene.ApiEngine.TestHelper@1.0.0
#addin nuget:?package=AtomiCloud.Diene.ApiEngine.TestHelper&version=1.0.0
#tool nuget:?package=AtomiCloud.Diene.ApiEngine.TestHelper&version=1.0.0
Diene .NET API Engine
Diene's reproducible development environment is managed by Nix. Run direnv allow once, then use pls tasks from the loaded shell.
This branch is the workspace baseline inherited by every downstream sample: split CI/CD, secrets, release configuration, validators, standards, and vendored agent-skill synchronization.
Commands
pls setup— synchronize installed diene package skills.pls lint— run every pre-commit gate.pls secret:scan— scan tracked content for secrets.pls skills:sync— rebuild.claude/skills/vendor/from installed packages.
Standards
- CI/CD workflows
- conventional commits
- Infisical and secrets
- linting and pre-commit
- Nix flakes and development shells
- release automation
- service-tree identity
- shell scripts
- Taskfile conventions
Shared standards
- Authorization
- Contributor documentation
- Date and time
- Domain-driven design
- Functional practices
- Software design philosophy
- SOLID principles
- Stateless OOP and dependency injection
- Testing
- Three-layer architecture
- Utility libraries
- Data validation
Domain-specific documentation belongs under docs/domain/.
The docs/standards/contracts/ location is reserved for the separately owned C0
contracts standard.
.NET 10 foundation
This branch adds the .NET 10 toolchain, the App/Lib/UnitTest/IntTest
sample, merged multi-project coverage, strict and LLM dead-code modes. See the .NET baseline.
Common commands:
pls build,pls dev,pls run, andpls previewpls test,pls test:unit,pls test:int, and the coverage variantspls deadcodefor the non-blocking review; CI owns strict dn-inspect
The client contract is documented in docs/domain/api-engine.md. Production observability is intentionally absent until the observability add-back.
API engine packages
AtomiCloud.Diene.ApiEngine is the typed backend-client layer: an LPSM client
tree over generated SDKs, per-backend token attachment, a
retry-once-on-network-error transport profile, and full classification of every
response into Result<T, Problem>. It is a client only — the MVC controller base
and the exception-to-problem filter live in AtomiCloud.Diene.ServerEngine.
AtomiCloud.Diene.ApiEngine.TestHelper provides the fake upstreams, response
fixtures, and outcome assertions consumers would otherwise write per project.
dotnet add package AtomiCloud.Diene.ApiEngine
dotnet add package AtomiCloud.Diene.ApiEngine.TestHelper
Register a backend
Each upstream is declared once, addressed by the service tree, with its base
address and timeout read from the engine-owned HttpClient configuration block:
using AtomiCloud.Diene.ApiEngine.Client;
using AtomiCloud.Diene.ApiEngine.Config;
using AtomiCloud.Diene.ApiEngine.Module;
var address = ServiceAddress.Create("lithium", "notes", "note").Get();
var config = ApiEngineConfig.Create(options).Get();
builder.Services.AddAtomiClientTree(config, tree => tree
.Register(address, http => new NotesClient(http)));
Each registration produces a named HttpClient carrying the engine's handler
pipeline plus a keyed typed client over it, so a call site may resolve through
IClientTree or inject [FromKeyedServices("lithium.notes.note")] directly. An
upstream with an authResource gets its own auth handler bound to that resource,
so a backend can only ever carry its own credential.
Call through the wrapper
var outcome = await caller.Call(address, ct => client.GetNoteAsync(id, ct));
return outcome.Match(
note => Results.Ok(note),
problem => Results.Problem(problem.Detail, statusCode: problem.Status));
No exception escapes. A successful call yields its value; an upstream problem
envelope is passed through verbatim; a JSON failure that is not a problem becomes
UpstreamRejected (502); anything unreadable — a non-JSON body, a bare status, a
dropped connection, a timeout — becomes UpstreamTransportFailure (504). Only
the last is recoverable, and the two are separate types precisely so a caller can
tell "the service said no" from "there was no answer".
Test against a fake upstream
var upstream = new FakeUpstream("notes");
upstream.RespondNetworkFailure();
upstream.RespondOk(UpstreamResponses.Payload(new { id = "n-1" }));
services.AddHttpClient("lithium.notes.note")
.ConfigurePrimaryHttpMessageHandler(() => upstream);
outcome.ShouldBeOk();
upstream.Attempts.Should().Be(2); // exactly one retry, as a number
Run nix develop .#ci -c ./scripts/ci/pkg-validate.sh to pack both packages,
validate metadata and symbols, and exercise them through a scratch consumer. See
the library baseline for release and
promotion guidance.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- AtomiCloud.Diene.ApiEngine (>= 1.0.0)
- AtomiCloud.Diene.AuthEngine.TestHelper (>= 1.0.0)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on AtomiCloud.Diene.ApiEngine.TestHelper:
| Package | Downloads |
|---|---|
|
AtomiCloud.Diene.E2e.TestHelper
Diene family TestHelper bundle plus black-box response assertions. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0 | 244 | 7/29/2026 |