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
28 changes: 3 additions & 25 deletions src/Setlistbot.Domain/CommentAggregate/Comment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ string reply
Ensure.String.IsNotNullOrWhiteSpace(permalink, nameof(permalink));
Ensure.String.IsNotNullOrWhiteSpace(author, nameof(author));
Ensure.String.IsNotEmptyOrWhiteSpace(artistId, nameof(artistId));
Ensure.String.IsNotNullOrWhiteSpace(reply, nameof(reply));

Id = id;
Author = author;
Expand All @@ -48,24 +47,7 @@ public static Comment NewComment(
string body,
string permalink,
string artistId
)
{
Ensure.String.IsNotNullOrWhiteSpace(id, nameof(id));
Ensure.String.IsNotNullOrEmpty(body, nameof(body));
Ensure.String.IsNotNullOrWhiteSpace(permalink, nameof(permalink));
Ensure.String.IsNotNullOrWhiteSpace(author, nameof(author));
Ensure.String.IsNotEmptyOrWhiteSpace(artistId, nameof(artistId));

return new Comment()
{
Id = id,
Author = author,
Body = body,
Permalink = permalink,
ArtistId = artistId,
Reply = string.Empty,
};
}
) => new(id, author, body, permalink, artistId, string.Empty);

/// <summary>
/// Returns true if text is mentioned in the comment
Expand All @@ -81,11 +63,7 @@ public bool HasMentionOf(string text)
/// Sets the reply value
/// </summary>
/// <param name="reply">The raw string value that was used in the reply</param>
public void SetReply(string reply)
{
Ensure.That(reply, nameof(reply)).IsNotNullOrWhiteSpace();

Reply = reply;
}
public void SetReply(string reply) =>
Reply = Ensure.String.IsNotNullOrWhiteSpace(reply, nameof(reply));
}
}
9 changes: 6 additions & 3 deletions src/Setlistbot.Domain/Extensions/DateParseExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@

namespace Setlistbot.Domain.Extensions
{
public static class DateParseExtensions
public static partial class DateParseExtensions
{
public static IEnumerable<DateOnly> ParseDates(this string input)
{
if (string.IsNullOrWhiteSpace(input))
{
return Enumerable.Empty<DateOnly>();
return [];
}

var dates = new List<DateOnly>();

var dateRegex = new Regex(@"\d{1,4}[- /.]\d{1,2}[- /.]\d{1,4}");
var dateRegex = DatesRegex();
foreach (Match match in dateRegex.Matches(input))
{
if (DateOnly.TryParse(match.Value, out var date))
Expand All @@ -27,5 +27,8 @@ public static IEnumerable<DateOnly> ParseDates(this string input)

return dates;
}

[GeneratedRegex(@"\d{1,4}[- /.]\d{1,2}[- /.]\d{1,4}")]
private static partial Regex DatesRegex();
}
}
81 changes: 19 additions & 62 deletions src/Setlistbot.Domain/PostAggregate/Post.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ namespace Setlistbot.Domain.PostAggregate
{
public sealed class Post
{
private List<DateOnly> _dates = null!;

public string Id { get; private set; } = string.Empty;
public string Author { get; private set; } = string.Empty;
public string Title { get; private set; } = string.Empty;
Expand All @@ -17,87 +15,46 @@ public sealed class Post

public string ParentId => $"t3_{Id}";

public IReadOnlyCollection<DateOnly> Dates
{
get
{
_dates ??= Title.ParseDates().Concat(SelfText.ParseDates()).ToList();
return _dates.AsReadOnly();
}
}
public IReadOnlyCollection<DateOnly> Dates =>
Title.ParseDates().Concat(SelfText.ParseDates()).ToList().AsReadOnly();

private Post() { }

public static Post NewPost(
public Post(
string id,
string author,
string title,
string selfText,
string permalink,
string artistId
string artistId,
string reply
)
{
Ensure.String.IsNotNullOrWhiteSpace(id, nameof(id));
Ensure.String.IsNotNullOrWhiteSpace(author, nameof(author));
Ensure.String.IsNotNullOrWhiteSpace(title, nameof(title));
Ensure.String.IsNotNullOrWhiteSpace(permalink, nameof(permalink));
Ensure.String.IsNotEmptyOrWhiteSpace(artistId, nameof(artistId));

return new Post()
{
Id = id,
Author = author,
Title = title,
SelfText = selfText,
Permalink = permalink,
ArtistId = artistId,
Reply = string.Empty,
};
Id = Ensure.String.IsNotNullOrWhiteSpace(id, nameof(id));
Author = Ensure.String.IsNotNullOrWhiteSpace(author, nameof(author));
Title = Ensure.String.IsNotNullOrWhiteSpace(title, nameof(title));
SelfText = selfText;
Permalink = Ensure.String.IsNotNullOrWhiteSpace(permalink, nameof(permalink));
ArtistId = Ensure.String.IsNotNullOrWhiteSpace(artistId, nameof(artistId));
Reply = reply;
}

public static Post Hydrate(
public static Post NewPost(
string id,
string author,
string title,
string selfText,
string permalink,
string artistId,
string reply
)
{
Ensure.String.IsNotNullOrWhiteSpace(id, nameof(id));
Ensure.String.IsNotNullOrWhiteSpace(author, nameof(author));
Ensure.String.IsNotNullOrWhiteSpace(title, nameof(title));
Ensure.String.IsNotNullOrWhiteSpace(permalink, nameof(permalink));
Ensure.String.IsNotNullOrWhiteSpace(artistId, nameof(artistId));
Ensure.String.IsNotNullOrWhiteSpace(reply, nameof(reply));

return new Post()
{
Id = id,
Author = author,
Title = title,
SelfText = selfText,
Permalink = permalink,
ArtistId = artistId,
Reply = reply,
};
}
string artistId
) => new(id, author, title, selfText, permalink, artistId, string.Empty);

public bool HasMentionOf(string text)
{
return text != null
&& (
Title.Contains(text, StringComparison.CurrentCultureIgnoreCase)
|| SelfText.Contains(text, StringComparison.CurrentCultureIgnoreCase)
);
return Title.Contains(text, StringComparison.CurrentCultureIgnoreCase)
|| SelfText.Contains(text, StringComparison.CurrentCultureIgnoreCase);
}

public void SetReply(string reply)
{
Ensure.That(reply, nameof(reply)).IsNotNullOrWhiteSpace();

Reply = reply;
}
public void SetReply(string reply) =>
Reply = Ensure.String.IsNotNullOrWhiteSpace(reply, nameof(reply));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public static PostEntity ToTableEntity(this Post post, string partitionKey)
{
return entity == null
? null
: Post.Hydrate(
: new Post(
entity.RowKey,
entity.Author,
entity.Title,
Expand Down
161 changes: 160 additions & 1 deletion test/Setlistbot.Domain.UnitTests/CommentAggregate/CommentTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,163 @@
using Setlistbot.Domain.CommentAggregate;

namespace Setlistbot.Domain.UnitTests.CommentAggregate
{
public sealed class CommentTests { }
public sealed class CommentTests
{
[Fact]
public void NewComment_ValidParameters_CreatesComment()
{
// Arrange
var id = "1";
var author = "Author";
var body = "This is a comment.";
var permalink = "http://example.com";
var artistId = "ArtistId";

// Act
var comment = Comment.NewComment(id, author, body, permalink, artistId);

// Assert
Assert.Equal(id, comment.Id);
Assert.Equal(author, comment.Author);
Assert.Equal(body, comment.Body);
Assert.Equal(permalink, comment.Permalink);
Assert.Equal(artistId, comment.ArtistId);
Assert.Equal(string.Empty, comment.Reply);
}

[Fact]
public void HasMentionOf_ContainsText_ReturnsTrue()
{
// Arrange
var comment = Comment.NewComment(
"1",
"Author",
"This is a comment mentioning something.",
"http://example.com",
"ArtistId"
);

// Act
var result = comment.HasMentionOf("mentioning");

// Assert
Assert.True(result);
}

[Fact]
public void HasMentionOf_DoesNotContainText_ReturnsFalse()
{
// Arrange
var comment = Comment.NewComment(
"1",
"Author",
"This is a comment.",
"http://example.com",
"ArtistId"
);

// Act
var result = comment.HasMentionOf("mentioning");

// Assert
Assert.False(result);
}

[Fact]
public void SetReply_ValidReply_SetsReply()
{
// Arrange
var comment = Comment.NewComment(
"1",
"Author",
"This is a comment.",
"http://example.com",
"ArtistId"
);
var reply = "This is a reply.";

// Act
comment.SetReply(reply);

// Assert
Assert.Equal(reply, comment.Reply);
}

[Fact]
public void SetReply_EmptyReply_ExpectException()
{
// Arrange
var comment = Comment.NewComment(
"1",
"Author",
"This is a comment.",
"http://example.com",
"ArtistId"
);
var reply = string.Empty;

// Act & Assert
Assert.Throws<ArgumentException>(() => comment.SetReply(reply));
}

[Fact]
public void Dates_ValidBody_ReturnsDates()
{
// Arrange
var comment = Comment.NewComment(
"1",
"Author",
"This is a comment mentioning 2023-10-01 and 2023-10-02.",
"http://example.com",
"ArtistId"
);

// Act
var result = comment.Dates;

// Assert
Assert.Equal(2, result.Count);
Assert.Contains(new DateOnly(2023, 10, 1), result);
Assert.Contains(new DateOnly(2023, 10, 2), result);
}

[Fact]
public void Dates_NoDatesInBody_ReturnsEmptyList()
{
// Arrange
var comment = Comment.NewComment(
"1",
"Author",
"This is a comment without dates.",
"http://example.com",
"ArtistId"
);

// Act
var result = comment.Dates;

// Assert
Assert.Empty(result);
}

[Fact]
public void ParentId_ValidId_ReturnsParentId()
{
// Arrange
var comment = Comment.NewComment(
"1",
"Author",
"This is a comment.",
"http://example.com",
"ArtistId"
);

// Act
var result = comment.ParentId;

// Assert
Assert.Equal("t1_1", result);
}
}
}
Loading