feat: Add Storybook configuration and motion tokens implementation
- Introduced Storybook configuration files (`main.ts`, `preview.ts`, `tsconfig.json`) for Angular components. - Created motion tokens in `motion-tokens.ts` to define durations, easing functions, and transforms. - Developed a Storybook story for motion tokens showcasing their usage and reduced motion fallback. - Added SCSS variables for motion durations, easing, and transforms in `_motion.scss`. - Implemented accessibility smoke tests using Playwright and Axe for automated accessibility checks. - Created portable and sealed bundle structures with corresponding JSON files for evidence locker. - Added shell script for verifying notify kit determinism.
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
using StellaOps.Graph.Indexer.Ingestion.Inspector;
|
||||
using StellaOps.Graph.Indexer.Schema;
|
||||
|
||||
namespace StellaOps.Graph.Indexer.Tests;
|
||||
|
||||
public sealed class GraphInspectorTransformerTests
|
||||
{
|
||||
[Fact]
|
||||
public void Transform_BuildsNodesAndEdges_FromInspectorSnapshot()
|
||||
{
|
||||
var snapshot = new GraphInspectorSnapshot
|
||||
{
|
||||
Tenant = "acme-dev",
|
||||
ArtifactDigest = "sha256:artifact",
|
||||
SbomDigest = "sha256:sbom",
|
||||
CollectedAt = DateTimeOffset.Parse("2025-12-04T15:30:00Z"),
|
||||
EventOffset = 5123,
|
||||
Components = new[]
|
||||
{
|
||||
new GraphInspectorComponent
|
||||
{
|
||||
Purl = "pkg:maven/org.example/foo@1.2.3",
|
||||
Scopes = new[] {"runtime"},
|
||||
Relationships = new[]
|
||||
{
|
||||
new GraphInspectorRelationship
|
||||
{
|
||||
Type = "depends_on",
|
||||
TargetPurl = "pkg:npm/lodash@4.17.21",
|
||||
Scope = "runtime",
|
||||
EvidenceHash = "e1",
|
||||
Source = "concelier.linkset.v1",
|
||||
Provenance = new GraphInspectorProvenance
|
||||
{
|
||||
Source = "concelier.linkset.v1",
|
||||
CollectedAt = DateTimeOffset.Parse("2025-12-04T15:29:00Z"),
|
||||
EventOffset = 6000,
|
||||
EvidenceHash = "e1"
|
||||
}
|
||||
}
|
||||
},
|
||||
Advisories = new[]
|
||||
{
|
||||
new GraphInspectorAdvisoryObservation
|
||||
{
|
||||
AdvisoryId = "CVE-2024-1111",
|
||||
Source = "ghsa",
|
||||
Status = "affected",
|
||||
Severity = "HIGH",
|
||||
EvidenceHash = "a1",
|
||||
LinksetDigest = "abcdef",
|
||||
ModifiedAt = DateTimeOffset.Parse("2025-11-30T12:00:00Z"),
|
||||
Provenance = new GraphInspectorProvenance
|
||||
{
|
||||
Source = "concelier.linkset.v1",
|
||||
CollectedAt = DateTimeOffset.Parse("2025-11-30T11:55:00Z"),
|
||||
EventOffset = 4421,
|
||||
EvidenceHash = "a1"
|
||||
}
|
||||
}
|
||||
},
|
||||
VexStatements = new[]
|
||||
{
|
||||
new GraphInspectorVexStatement
|
||||
{
|
||||
StatementId = "VEX-2025-0001",
|
||||
Source = "excitor.vex.v1",
|
||||
Status = "not_affected",
|
||||
Justification = "component_not_present",
|
||||
EvidenceHash = "v1",
|
||||
IssuedAt = DateTimeOffset.Parse("2025-12-01T08:00:00Z"),
|
||||
ExpiresAt = DateTimeOffset.Parse("2026-12-01T00:00:00Z"),
|
||||
Provenance = new GraphInspectorProvenance
|
||||
{
|
||||
Source = "excitor.overlay.v1",
|
||||
CollectedAt = DateTimeOffset.Parse("2025-12-01T08:00:00Z"),
|
||||
EventOffset = 171,
|
||||
EvidenceHash = "v1"
|
||||
}
|
||||
}
|
||||
},
|
||||
Provenance = new GraphInspectorProvenance
|
||||
{
|
||||
Source = "concelier.linkset.v1",
|
||||
CollectedAt = DateTimeOffset.Parse("2025-12-04T15:29:00Z"),
|
||||
EventOffset = 5123,
|
||||
EvidenceHash = "c1"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var transformer = new GraphInspectorTransformer();
|
||||
|
||||
var batch = transformer.Transform(snapshot);
|
||||
|
||||
// Nodes: artifact + source component + target component + advisory + vex
|
||||
Assert.Equal(5, batch.Nodes.Length);
|
||||
Assert.Contains(batch.Nodes, n => n["kind"]!.GetValue<string>() == "artifact");
|
||||
Assert.Contains(batch.Nodes, n => n["kind"]!.GetValue<string>() == "component" && n["canonical_key"]!["purl"]!.GetValue<string>() == "pkg:maven/org.example/foo@1.2.3");
|
||||
Assert.Contains(batch.Nodes, n => n["kind"]!.GetValue<string>() == "component" && n["canonical_key"]!["purl"]!.GetValue<string>() == "pkg:npm/lodash@4.17.21");
|
||||
Assert.Contains(batch.Nodes, n => n["kind"]!.GetValue<string>() == "advisory");
|
||||
Assert.Contains(batch.Nodes, n => n["kind"]!.GetValue<string>() == "vex_statement");
|
||||
|
||||
// Edges: depends_on, affected_by, vex_exempts
|
||||
Assert.Contains(batch.Edges, e => e["kind"]!.GetValue<string>() == "DEPENDS_ON");
|
||||
Assert.Contains(batch.Edges, e => e["kind"]!.GetValue<string>() == "AFFECTED_BY");
|
||||
Assert.Contains(batch.Edges, e => e["kind"]!.GetValue<string>() == "VEX_EXEMPTS");
|
||||
|
||||
// Provenance should carry sbom digest and event offset from snapshot/provenance overrides.
|
||||
var dependsOn = batch.Edges.Single(e => e["kind"]!.GetValue<string>() == "DEPENDS_ON");
|
||||
Assert.Equal("sha256:sbom", dependsOn["provenance"]!["sbom_digest"]!.GetValue<string>());
|
||||
Assert.Equal(6000, dependsOn["provenance"]!["event_offset"]!.GetValue<long>());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user