feat: add feedback backend foundation
This commit is contained in:
115
backend/tests/Socialize.Tests/Feedback/FeedbackRulesTests.cs
Normal file
115
backend/tests/Socialize.Tests/Feedback/FeedbackRulesTests.cs
Normal file
@@ -0,0 +1,115 @@
|
||||
using Socialize.Api.Modules.Feedback.Data;
|
||||
using Socialize.Api.Modules.Feedback.Services;
|
||||
|
||||
namespace Socialize.Tests.Feedback;
|
||||
|
||||
public class FeedbackRulesTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("Bug", FeedbackType.Bug)]
|
||||
[InlineData("suggestion", FeedbackType.Suggestion)]
|
||||
[InlineData("Request", FeedbackType.Request)]
|
||||
public void TryParseType_accepts_supported_types(string value, FeedbackType expected)
|
||||
{
|
||||
bool parsed = FeedbackRules.TryParseType(value, out FeedbackType type);
|
||||
|
||||
Assert.True(parsed);
|
||||
Assert.Equal(expected, type);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("")]
|
||||
[InlineData("Question")]
|
||||
[InlineData("Incident")]
|
||||
public void TryParseType_rejects_unsupported_types(string value)
|
||||
{
|
||||
bool parsed = FeedbackRules.TryParseType(value, out _);
|
||||
|
||||
Assert.False(parsed);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData("New", FeedbackStatus.New)]
|
||||
[InlineData("Planned", FeedbackStatus.Planned)]
|
||||
[InlineData("Resolved", FeedbackStatus.Resolved)]
|
||||
[InlineData("Won't Do", FeedbackStatus.WontDo)]
|
||||
[InlineData("WontDo", FeedbackStatus.WontDo)]
|
||||
[InlineData("Cancelled", FeedbackStatus.Cancelled)]
|
||||
public void TryParseStatus_accepts_supported_statuses(string value, FeedbackStatus expected)
|
||||
{
|
||||
bool parsed = FeedbackRules.TryParseStatus(value, out FeedbackStatus status);
|
||||
|
||||
Assert.True(parsed);
|
||||
Assert.Equal(expected, status);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanDeveloperSetStatus_rejects_cancelled_destination()
|
||||
{
|
||||
bool allowed = FeedbackRules.CanDeveloperSetStatus(FeedbackStatus.New, FeedbackStatus.Cancelled);
|
||||
|
||||
Assert.False(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanDeveloperSetStatus_rejects_changes_after_cancelled()
|
||||
{
|
||||
bool allowed = FeedbackRules.CanDeveloperSetStatus(FeedbackStatus.Cancelled, FeedbackStatus.Planned);
|
||||
|
||||
Assert.False(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanReporterCancel_rejects_cancelled_report()
|
||||
{
|
||||
bool allowed = FeedbackRules.CanReporterCancel(FeedbackStatus.Cancelled);
|
||||
|
||||
Assert.False(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanReporterAccess_allows_report_owner()
|
||||
{
|
||||
Guid reporterUserId = Guid.NewGuid();
|
||||
FeedbackReport report = new() { ReporterUserId = reporterUserId };
|
||||
|
||||
bool allowed = FeedbackAccessRules.CanReporterAccess(report, reporterUserId);
|
||||
|
||||
Assert.True(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanReporterAccess_rejects_other_users()
|
||||
{
|
||||
FeedbackReport report = new() { ReporterUserId = Guid.NewGuid() };
|
||||
|
||||
bool allowed = FeedbackAccessRules.CanReporterAccess(report, Guid.NewGuid());
|
||||
|
||||
Assert.False(allowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanReporterCancel_requires_owner_and_non_final_status()
|
||||
{
|
||||
Guid reporterUserId = Guid.NewGuid();
|
||||
FeedbackReport report = new()
|
||||
{
|
||||
ReporterUserId = reporterUserId,
|
||||
Status = FeedbackStatus.New,
|
||||
};
|
||||
|
||||
bool ownerAllowed = FeedbackAccessRules.CanReporterCancel(report, reporterUserId);
|
||||
bool otherUserAllowed = FeedbackAccessRules.CanReporterCancel(report, Guid.NewGuid());
|
||||
|
||||
Assert.True(ownerAllowed);
|
||||
Assert.False(otherUserAllowed);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void NormalizeTags_trims_deduplicates_and_orders()
|
||||
{
|
||||
IReadOnlyCollection<string> tags = FeedbackRules.NormalizeTags([" mobile ", "bug", "Mobile", ""]);
|
||||
|
||||
Assert.Equal(["bug", "mobile"], tags);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user