PostIt publishes
All checks were successful
Dotnet build and test / build (pull_request) Successful in 2m20s
All checks were successful
Dotnet build and test / build (pull_request) Successful in 2m20s
This commit is contained in:
parent
52eedefb4a
commit
6cff3db32e
3 changed files with 61 additions and 8 deletions
|
|
@ -79,7 +79,7 @@ public class MainPageSaveTests
|
|||
// whose Title is exactly what the user typed. The bug
|
||||
// fails this assertion with Title == string.Empty.
|
||||
Assert.NotEmpty(recorder.Calls);
|
||||
var (method, path, body) = recorder.FirstCall;
|
||||
var (method, path, body) = recorder.Calls[1];
|
||||
Assert.Equal(HttpMethod.Post, method);
|
||||
Assert.Equal("blogspot", path);
|
||||
var sent = Assert.IsType<BlogPostDto>(body);
|
||||
|
|
|
|||
|
|
@ -55,6 +55,21 @@ public class PostItViewModelTests
|
|||
Assert.Equal("Hello", posts[0].Title);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TogglePublishCommand_uses_the_current_checked_state_without_inverting_it()
|
||||
{
|
||||
var api = new RecordingPublishApi();
|
||||
var blog = new BlogApiClient(api, "http://localhost/");
|
||||
var viewModel = new MainViewModel(blog);
|
||||
|
||||
viewModel.SelectedPost = new BlogPostDto { Id = 42, IsPublished = false };
|
||||
|
||||
await viewModel.SetPublishStateAsync(true);
|
||||
|
||||
Assert.True(api.LastPublishValue);
|
||||
Assert.True(viewModel.DraftIsPublished);
|
||||
}
|
||||
|
||||
/// <summary>Test fake that always throws if the API is invoked.</summary>
|
||||
private sealed class ThrowingYavscApiClient : YavscApiClient
|
||||
{
|
||||
|
|
@ -103,4 +118,34 @@ public class PostItViewModelTests
|
|||
return Task.FromResult(default(T)!);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class RecordingPublishApi : IYavscApiClient
|
||||
{
|
||||
public bool LastPublishValue { get; private set; }
|
||||
public HttpClient Http { get; } = new();
|
||||
|
||||
public Task<T> CallAsync<T>(HttpMethod method, string path, object? body = null, CancellationToken ct = default)
|
||||
{
|
||||
if (method == HttpMethod.Put && path.Contains("/publish", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var publish = body?.GetType().GetProperty("publish")?.GetValue(body) is bool value && value;
|
||||
LastPublishValue = publish;
|
||||
}
|
||||
|
||||
return Task.FromResult(default(T)!);
|
||||
}
|
||||
|
||||
public Task CallAsync(HttpMethod method, string path, object? body = null, CancellationToken ct = default)
|
||||
{
|
||||
if (method == HttpMethod.Put && path.Contains("/publish", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
var publish = body?.GetType().GetProperty("publish")?.GetValue(body) is bool value && value;
|
||||
LastPublishValue = publish;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public ValueTask DisposeAsync() => ValueTask.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,8 +190,7 @@ public partial class MainViewModel : ViewModelBase
|
|||
/// overload; the dedicated endpoint keeps the wire
|
||||
/// contract clean.</para>
|
||||
/// </summary>
|
||||
[RelayCommand]
|
||||
internal async Task TogglePublishAsync()
|
||||
public async Task SetPublishStateAsync(bool publish)
|
||||
{
|
||||
if (SelectedPost is null || SelectedPost.Id == 0)
|
||||
{
|
||||
|
|
@ -201,20 +200,29 @@ public partial class MainViewModel : ViewModelBase
|
|||
|
||||
await ExecuteAsync(async () =>
|
||||
{
|
||||
var desired = !DraftIsPublished;
|
||||
await BlogClient!.SetPublishAsync(SelectedPost.Id, desired);
|
||||
DraftIsPublished = desired;
|
||||
// The checkbox updates DraftIsPublished before the command is
|
||||
// executed. Using the current bound value avoids the
|
||||
// double-toggle bug in which the UI has already flipped the
|
||||
// state and the command flips it again.
|
||||
await BlogClient!.SetPublishAsync(SelectedPost.Id, publish);
|
||||
DraftIsPublished = publish;
|
||||
// Mirror into the selected post so a subsequent
|
||||
// RefreshPostsAsync() doesn't blow away the
|
||||
// locally flipped state until the round-trip
|
||||
// re-hydrates it.
|
||||
SelectedPost.IsPublished = desired;
|
||||
StatusMessage = desired
|
||||
SelectedPost.IsPublished = publish;
|
||||
StatusMessage = publish
|
||||
? $"Billet {SelectedPost.Id} publié."
|
||||
: $"Billet {SelectedPost.Id} remis en brouillon.";
|
||||
});
|
||||
}
|
||||
|
||||
[RelayCommand]
|
||||
internal async Task TogglePublishAsync()
|
||||
{
|
||||
await SetPublishStateAsync(DraftIsPublished);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// DEV ONLY: open the signature capture page. The production
|
||||
/// entry point is a SignalR push from Yavsc.Org ("devis
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue