Skip to content
Open
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
118 changes: 118 additions & 0 deletions backend/Platform.LabMetadata.Tests/LaboratoryTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@

using System;
using NUnit.Framework;
using Platform.LabMetadata;

namespace Platform.LabMetadata.Tests
{
[TestFixture]
public class LaboratoryMetadataTests
{
[Test]
public void Constructor_ShouldPreserveLaboratoryId()
{
var id = Guid.NewGuid();

var metadata = new LaboratoryMetadata(
id,
"Learn access control",
LaboratoryDifficulty.Easy,
LaboratoryType.AccessControl,
new[] { "security" }
);

Assert.That(metadata.LaboratoryId, Is.EqualTo(id));
}

[Test]
public void Constructor_ShouldRejectInvalidDifficulty()
{
var invalidDifficulty = (LaboratoryDifficulty)999;

Assert.Throws<ArgumentOutOfRangeException>(() =>
new LaboratoryMetadata(
Guid.NewGuid(),
"Test objective",
invalidDifficulty,
LaboratoryType.AccessControl,
new[] { "security" }
)
);
}

[Test]
public void Constructor_ShouldRejectInvalidType()
{
var invalidType = (LaboratoryType)999;

Assert.Throws<ArgumentOutOfRangeException>(() =>
new LaboratoryMetadata(
Guid.NewGuid(),
"Test objective",
LaboratoryDifficulty.Easy,
invalidType,
new[] { "security" }
)
);
}

[Test]
public void Constructor_ShouldNormalizeTags()
{
var metadata = new LaboratoryMetadata(
Guid.NewGuid(),
"Test objective",
LaboratoryDifficulty.Easy,
LaboratoryType.AccessControl,
new[] { " Security ", "MFA", "security", " " }
);

Assert.That(
metadata.Tags,
Is.EqualTo(new[] { "security", "mfa" })
);
}

[Test]
public void Constructor_ShouldRejectEmptyId()
{
Assert.Throws<ArgumentException>(() =>
new LaboratoryMetadata(
Guid.Empty,
"Test objective",
LaboratoryDifficulty.Easy,
LaboratoryType.AccessControl,
new[] { "security" }
)
);
}

[Test]
public void Constructor_ShouldRejectEmptyObjective()
{
Assert.Throws<ArgumentException>(() =>
new LaboratoryMetadata(
Guid.NewGuid(),
" ",
LaboratoryDifficulty.Easy,
LaboratoryType.AccessControl,
new[] { "security" }
)
);
}

[Test]
public void Constructor_ShouldRejectNullTags()
{
Assert.Throws<ArgumentNullException>(() =>
new LaboratoryMetadata(
Guid.NewGuid(),
"Test objective",
LaboratoryDifficulty.Easy,
LaboratoryType.AccessControl,
null!
)
);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.4" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.0" />
<PackageReference Include="NUnit" Version="4.3.2" />
<PackageReference Include="NUnit.Analyzers" Version="4.7.0" />
<PackageReference Include="NUnit3TestAdapter" Version="5.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Platform.LabMetadata\Platform.LabMetadata.csproj" />
</ItemGroup>

<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>

</Project>
10 changes: 10 additions & 0 deletions backend/Platform.LabMetadata/LaboratoryDifficulty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

namespace Platform.LabMetadata
{
public enum LaboratoryDifficulty
{
Easy,
Medium,
Hard
}
}
59 changes: 59 additions & 0 deletions backend/Platform.LabMetadata/LaboratoryMetadata.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

using System;
using System.Collections.Generic;
using System.Linq;

namespace Platform.LabMetadata
{
public class LaboratoryMetadata
{
// Referenca na postojecu laboratoriju iz LAB-01.
// LAB-02 ne generise novi identitet.
public Guid LaboratoryId { get; }

public string Objective { get; private set; }
public LaboratoryDifficulty Difficulty { get; private set; }
public LaboratoryType Type { get; private set; }
public IReadOnlyList<string> Tags { get; private set; }

public LaboratoryMetadata(
Guid laboratoryId,
string objective,
LaboratoryDifficulty difficulty,
LaboratoryType type,
IEnumerable<string> tags)
{
if (laboratoryId == Guid.Empty)
throw new ArgumentException(
"Laboratory ID cannot be empty.",
nameof(laboratoryId));

if (string.IsNullOrWhiteSpace(objective))
throw new ArgumentException(
"Laboratory objective is required.",
nameof(objective));

if (!Enum.IsDefined(difficulty))
throw new ArgumentOutOfRangeException(nameof(difficulty));

if (!Enum.IsDefined(type))
throw new ArgumentOutOfRangeException(nameof(type));

if (tags is null)
throw new ArgumentNullException(nameof(tags));

LaboratoryId = laboratoryId;
Objective = objective.Trim();
Difficulty = difficulty;
Type = type;

Tags = Array.AsReadOnly(
tags
.Where(tag => !string.IsNullOrWhiteSpace(tag))
.Select(tag => tag.Trim().ToLowerInvariant())
.Distinct()
.ToArray()
);
}
}
}
15 changes: 15 additions & 0 deletions backend/Platform.LabMetadata/LaboratoryType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

namespace Platform.LabMetadata
{
public enum LaboratoryType
{
AccessControl,
LogAnalysis,
SecurityConfiguration,
ThreatModeling,
MfaAndSessions,
ContextualAuthorization,
IncidentResponse,
IsolatedService
}
}
9 changes: 9 additions & 0 deletions backend/Platform.LabMetadata/Platform.LabMetadata.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

</Project>
2 changes: 2 additions & 0 deletions backend/SecurityLab.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<Project Path="Platform.Api/Platform.Api.csproj" />
<Project Path="Platform.Audit/Platform.Audit.csproj" />
<Project Path="Platform.Audit.Tests/Platform.Audit.Tests.csproj" />
<Project Path="Platform.LabMetadata.Tests/Platform.LabMetadata.Tests.csproj" Id="8ff98d14-96bd-4c62-b1ce-8e45e60fb816" />
<Project Path="Platform.LabMetadata/Platform.LabMetadata.csproj" Id="90892a49-5843-4415-a14a-1d89b684646f" />
<Project Path="Platform.Authoring.Tests/Platform.Authoring.Tests.csproj" />
<Project Path="Platform.Authoring/Platform.Authoring.csproj" />
<Project Path="Platform.RateLimiting.Tests/Platform.RateLimiting.Tests.csproj" />
Expand Down
Loading