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
135 changes: 135 additions & 0 deletions src/NoteBookmark.Api.Tests/Domain/ContainsPlaceholderAttributeTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
using System.ComponentModel.DataAnnotations;
using FluentAssertions;
using NoteBookmark.Domain;
using Xunit;

namespace NoteBookmark.Api.Tests.Domain;

public class ContainsPlaceholderAttributeTests
{
[Fact]
public void IsValid_ShouldReturnSuccess_WhenValueContainsPlaceholder()
{
// Arrange
var attribute = new ContainsPlaceholderAttribute("topic");
var validationContext = new ValidationContext(new object());

// Act
var result = attribute.GetValidationResult("Find articles about {topic}", validationContext);

// Assert
result.Should().Be(ValidationResult.Success);
}

[Fact]
public void IsValid_ShouldReturnError_WhenValueDoesNotContainPlaceholder()
{
// Arrange
var attribute = new ContainsPlaceholderAttribute("topic");
var validationContext = new ValidationContext(new object());

// Act
var result = attribute.GetValidationResult("Find articles about something", validationContext);

// Assert
result.Should().NotBe(ValidationResult.Success);
result?.ErrorMessage.Should().Contain("topic");
}

[Fact]
public void IsValid_ShouldReturnSuccess_WhenValueIsNull()
{
// Arrange
var attribute = new ContainsPlaceholderAttribute("content");
var validationContext = new ValidationContext(new object());

// Act
var result = attribute.GetValidationResult(null, validationContext);

// Assert
result.Should().Be(ValidationResult.Success);
}

[Fact]
public void IsValid_ShouldReturnSuccess_WhenValueIsEmpty()
{
// Arrange
var attribute = new ContainsPlaceholderAttribute("content");
var validationContext = new ValidationContext(new object());

// Act
var result = attribute.GetValidationResult("", validationContext);

// Assert
result.Should().Be(ValidationResult.Success);
}

[Fact]
public void IsValid_ShouldReturnSuccess_WhenValueIsWhitespace()
{
// Arrange
var attribute = new ContainsPlaceholderAttribute("content");
var validationContext = new ValidationContext(new object());

// Act
var result = attribute.GetValidationResult(" ", validationContext);

// Assert
result.Should().Be(ValidationResult.Success);
}

[Fact]
public void Constructor_ShouldSetPlaceholder()
{
// Arrange & Act
var attribute = new ContainsPlaceholderAttribute("custom");
var validationContext = new ValidationContext(new object());

// Assert
var result = attribute.GetValidationResult("text with {custom} placeholder", validationContext);
result.Should().Be(ValidationResult.Success);
}

[Fact]
public void ErrorMessage_ShouldContainPlaceholderName()
{
// Arrange
var attribute = new ContainsPlaceholderAttribute("myplaceholder");
var validationContext = new ValidationContext(new object());

// Act
var result = attribute.GetValidationResult("text without placeholder", validationContext);

// Assert
result?.ErrorMessage.Should().Contain("myplaceholder");
result?.ErrorMessage.Should().Contain("must contain");
}

[Theory]
[InlineData("Summary of {content}", "content", true)]
[InlineData("Summary of content", "content", false)]
[InlineData("Use {topic} for search", "topic", true)]
[InlineData("Use topic for search", "topic", false)]
[InlineData("Multiple {var1} and {var2}", "var1", true)]
[InlineData("Multiple {var1} and {var2}", "var2", true)]
[InlineData("Multiple var1 and var2", "var1", false)]
public void IsValid_ShouldValidateCorrectly_ForVariousInputs(string value, string placeholder, bool shouldBeValid)
{
// Arrange
var attribute = new ContainsPlaceholderAttribute(placeholder);
var validationContext = new ValidationContext(new object());

// Act
var result = attribute.GetValidationResult(value, validationContext);

// Assert
if (shouldBeValid)
{
result.Should().Be(ValidationResult.Success);
}
else
{
result.Should().NotBe(ValidationResult.Success);
}
}
}
100 changes: 100 additions & 0 deletions src/NoteBookmark.Api.Tests/Domain/NoteCategoriesTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using FluentAssertions;
using NoteBookmark.Domain;
using Xunit;

namespace NoteBookmark.Api.Tests.Domain;

public class NoteCategoriesTests
{
[Theory]
[InlineData("ai", "AI")]
[InlineData("AI", "AI")]
[InlineData("cloud", "Cloud")]
[InlineData("CLOUD", "Cloud")]
[InlineData("data", "Data")]
[InlineData("database", "Databases")]
[InlineData("dev", "Programming")]
[InlineData("devops", "DevOps")]
[InlineData("lowcode", "LowCode")]
[InlineData("misc", "Miscellaneous")]
[InlineData("top", "Suggestion of the week")]
[InlineData("oss", "Open Source")]
[InlineData("del", "del")]
public void GetCategory_ShouldReturnCorrectCategory_ForValidInput(string input, string expected)
{
// Act
var result = NoteCategories.GetCategory(input);

// Assert
result.Should().Be(expected);
}

[Theory]
[InlineData("unknown")]
[InlineData("invalid")]
[InlineData("")]
public void GetCategory_ShouldReturnMiscellaneous_ForInvalidCategory(string input)
{
// Act
var result = NoteCategories.GetCategory(input);

// Assert
result.Should().Be("Miscellaneous");
}

[Fact]
public void GetCategory_ShouldReturnMiscellaneous_ForNullInput()
{
// Act
var result = NoteCategories.GetCategory(null);

// Assert
result.Should().Be("Miscellaneous");
}

[Fact]
public void GetCategory_ShouldBeCaseInsensitive()
{
// Arrange
var inputs = new[] { "AI", "ai", "Ai", "aI" };

// Act & Assert
foreach (var input in inputs)
{
var result = NoteCategories.GetCategory(input);
result.Should().Be("AI");
}
}

[Fact]
public void GetCategories_ShouldReturnAllCategories()
{
// Act
var result = NoteCategories.GetCategories();

// Assert
result.Should().NotBeNull();
result.Should().HaveCount(11);
result.Should().Contain("AI");
result.Should().Contain("Cloud");
result.Should().Contain("Data");
result.Should().Contain("Databases");
result.Should().Contain("DevOps");
result.Should().Contain("LowCode");
result.Should().Contain("Miscellaneous");
result.Should().Contain("Programming");
result.Should().Contain("Open Source");
result.Should().Contain("Suggestion of the week");
result.Should().Contain("del");
}

[Fact]
public void GetCategories_ShouldReturnListType()
{
// Act
var result = NoteCategories.GetCategories();

// Assert
result.Should().BeOfType<List<string>>();
}
}
87 changes: 87 additions & 0 deletions src/NoteBookmark.Api.Tests/Domain/NoteTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,41 @@ public void Note_WhenCreated_HasCorrectDefaultValues()
note.Category.Should().BeNull();
}

[Fact]
public void Note_Constructor_ShouldInitializePartitionKey_WithCurrentYearMonth()
{
// Act
var note = new Note();

// Assert
note.PartitionKey.Should().Be(DateTime.UtcNow.ToString("yyyy-MM"));
}

[Fact]
public void Note_Constructor_ShouldInitializeRowKey_WithValidGuid()
{
// Act
var note = new Note();

// Assert
note.RowKey.Should().NotBeNullOrEmpty();
Guid.TryParse(note.RowKey, out _).Should().BeTrue();
}

[Fact]
public void Note_Constructor_ShouldInitializeDateAdded_WithCurrentUtcTime()
{
// Arrange
var before = DateTime.UtcNow;

// Act
var note = new Note();
var after = DateTime.UtcNow;

// Assert
note.DateAdded.Should().BeOnOrAfter(before).And.BeOnOrBefore(after);
}

[Fact]
public void Note_WhenPropertiesSet_ReturnsCorrectValues()
{
Expand All @@ -41,4 +76,56 @@ public void Note_WhenPropertiesSet_ReturnsCorrectValues()
note.Tags.Should().Be("azure, functions, serverless");
note.Category.Should().Be("Technology");
}

[Fact]
public void Validate_ShouldReturnTrue_WhenCommentIsNotEmpty()
{
// Arrange
var note = new Note { Comment = "This is a valid comment" };

// Act
var result = note.Validate();

// Assert
result.Should().BeTrue();
}

[Fact]
public void Validate_ShouldReturnFalse_WhenCommentIsNull()
{
// Arrange
var note = new Note { Comment = null };

// Act
var result = note.Validate();

// Assert
result.Should().BeFalse();
}

[Fact]
public void Validate_ShouldReturnFalse_WhenCommentIsEmpty()
{
// Arrange
var note = new Note { Comment = "" };

// Act
var result = note.Validate();

// Assert
result.Should().BeFalse();
}

[Fact]
public void Validate_ShouldReturnFalse_WhenCommentIsWhitespace()
{
// Arrange
var note = new Note { Comment = " " };

// Act
var result = note.Validate();

// Assert
result.Should().BeFalse();
}
}
Loading
Loading