Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
41 changes: 25 additions & 16 deletions src/Web/Features/BlogPosts/Edit/Edit.razor
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@
</div>
}

@if (_model is null && _error is null)
@if (_isLoading)
{
<p class="text-gray-600 dark:text-gray-400">Loading...</p>
<p class="text-gray-600 dark:text-gray-400" role="status">Loading...</p>
}
else if (_model is not null)
{
Expand Down Expand Up @@ -60,38 +60,47 @@ else if (_model is not null)
private PostFormModel? _model;
private string? _error;
private bool _concurrencyError;
private bool _isLoading = true;
private string _callerUserId = string.Empty;
private bool _callerIsAdmin;

protected override async Task OnParametersSetAsync()
{
var result = await Sender.Send(new GetBlogPostByIdQuery(Id));
if (result.Success)
try
{
if (result.Value is not null)
var result = await Sender.Send(new GetBlogPostByIdQuery(Id));
if (result.Success)
Comment on lines 67 to +72
{
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
_callerUserId = user.FindFirst("sub")?.Value ?? string.Empty;
_callerIsAdmin = user.IsInRole("Admin");
var isAuthor = result.Value.AuthorId == _callerUserId;
if (result.Value is not null)
{
var authState = await AuthStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
_callerUserId = user.FindFirst("sub")?.Value ?? string.Empty;
_callerIsAdmin = user.IsInRole("Admin");
var isAuthor = result.Value.AuthorId == _callerUserId;

if (!_callerIsAdmin && !isAuthor)
{
Navigation.NavigateTo("/blog");
return;
}

if (!_callerIsAdmin && !isAuthor)
_model = new PostFormModel { Title = result.Value.Title, Content = result.Value.Content };
}
else
{
Navigation.NavigateTo("/blog");
return;
}

_model = new PostFormModel { Title = result.Value.Title, Content = result.Value.Content };
}
else
{
_model = null;
_error = result.Error;
}
}
else
finally
{
_error = result.Error;
_isLoading = false;
}
}

Expand Down
24 changes: 24 additions & 0 deletions tests/Web.Tests.Bunit/Features/EditAclTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,30 @@ public EditAclTests()
Services.AddSingleton<AuthenticationStateProvider>(_authProvider);
}

[Fact]
public void EditRedirectsToBlogWhenPostNotFound()
{
// Arrange
var sender = Substitute.For<ISender>();
var postId = Guid.NewGuid();

sender.Send(Arg.Any<GetBlogPostByIdQuery>(), Arg.Any<CancellationToken>())
.Returns(Task.FromResult(Result.Ok<BlogPostDto?>(null)));

Services.AddSingleton(sender);

var navigation = Services.GetRequiredService<NavigationManager>();

// Act
var cut = RenderWithUser<Edit>(
CreatePrincipalWithSub("auth0|some-user", ["Author"]),
parameters => parameters.Add(p => p.Id, postId));

// Assert
navigation.Uri.Should().EndWith("/blog");
cut.Markup.Should().NotContain("Loading...");
}

[Fact]
public void EditRedirectsToBlogWhenAuthorIsNotPostOwner()
{
Expand Down
Loading