diff --git a/.forgejo/workflows/buildAndTest.yml b/.forgejo/workflows/buildAndTest.yml index 64e522bab..2f14e449e 100644 --- a/.forgejo/workflows/buildAndTest.yml +++ b/.forgejo/workflows/buildAndTest.yml @@ -31,7 +31,6 @@ jobs: steps: - name: Clone yavsc run: | - set -e cd /src git clone https://forgejo.pschneider.fr/notazof/yavsc.git _src cd _src @@ -41,14 +40,12 @@ jobs: fi git submodule update --init --recursive echo "✅ Checked out at $(git rev-parse HEAD) on $(git branch --show-current 2>/dev/null || echo detached HEAD)" - - name: Secret scan - run: | - echo "🔍 Scanning for secrets..." - cd /src/_src && dotnet tool restore && dotnet picket git --verbose --redact --exit-code 1 --log-opts -n1 \ + - name: Test run: | echo "🚀 Lancement des tests..." cd /src/_src && dotnet test \ --verbosity normal \ --filter="Category!=Platform-Android" \ - --logger "xunit;LogFileName=test-results.xml" + --logger "xunit;LogFileName=test-results.xml" \ + && echo "✅ Success !" || { echo "❌ Fail ($?)!"; exit 1; } diff --git a/.gitleaksignore b/.gitleaksignore deleted file mode 100644 index 056cf69d2..000000000 --- a/.gitleaksignore +++ /dev/null @@ -1,45 +0,0 @@ -# Exclure uniquement les dossiers de sortie de compilation -bin/ -obj/ -src/*/bin/ -src/*/obj/ -test/*/bin/ -test/*/obj/ - -# Toolchain front (Node / esbuild) -node_modules/ -build/ -package-lock.json - -# Exclure les caches lourds -.git/ -.vs/ - -.env - -.*.env - -*.csproj.lscache -data/ -appsettings.*.json -appsettings-*.*.json - -# Exception: the Testing-environment override for Yavsc.Org is a tracked -# configuration source, not a secrets file. TestWebApplicationFactory -# (Yavsc.Org.Tests) flips ASPNETCORE_ENVIRONMENT to "Testing" so -# AddConfiguration("org") in Program.Main loads this file as the -# last in the chain (it is optional). It overrides the connection -# string and SMTP section for the in-memory test host and contains -# no production secrets. -!src/Yavsc.Org/appsettings-org.Testing.json - -generated/ -*.tmp -tmp/ -DataDir/ - -*.tests.trx -*.tests.html - -*.log - diff --git a/.vscode/tasks.json b/.vscode/tasks.json index f5bcc21a2..a30c9c065 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -47,10 +47,7 @@ "group": "build", "isBuildCommand": true, "isTestCommand": false, - "isBackground": true, - "options": { - "cwd": "${workspaceFolder}" - } + "isBackground": true }, { "label": "test blogs backend", @@ -66,28 +63,6 @@ "isDefault": false } }, - { - "label": "test api backend (npgsql)", - "type": "process", - "problemMatcher": ["$msCompile"], - "command": "dotnet", - "args": [ - "test", - "Yavsc.Api.Test.csproj", - "-v", - "minimal" - ], - "options": { - "cwd": "src/Yavsc.Api.Test", - "env": { - "YAVSC_API_TEST_DB_PROVIDER": "npgsql", - } - }, - "group": { - "kind": "test", - "isDefault": false - } - }, { "label": "build-webapi", "type": "process", diff --git a/Makefile b/Makefile index d99fe5e5e..08f0461d2 100644 --- a/Makefile +++ b/Makefile @@ -48,4 +48,70 @@ docker-build: docker-run: docker run -d -p 5000:5000 --name yavsc yavsc -.PHONY: test install docker-image docker-build docker-run +# CrĂ©e une branche release/ depuis main, met Ă  jour les +# `` des .csproj via dotnet-gitversion, et la +# pousse sur origin. +# +# Usage : make release V=1.0.7-rc1 +# +# PrĂ©-requis : ĂȘtre sur main, working tree clean. La cible +# vĂ©rifie les deux et refuse sinon — elle ne fait JAMAIS +# de checkout automatique, c'est Ă  l'opĂ©rateur de s'ĂȘtre +# positionnĂ© sur la bonne branche au prĂ©alable (sinon le +# bump pourrait partir sur une branche tierce par accident). +# +# Notes : +# - Le nom de branche vient de l'argument V (ex: 1.0.7-rc1 +# donne release/1.0.7-rc1). C'est une Ă©tiquette d'intention, +# pas la version assembly. +# - La version dans les .csproj vient de GitVersion qui la +# calcule depuis l'historique git (tag le plus proche + +# nombre de commits). C'est la version assembly rĂ©elle. +# - L'ordre (fetch → branche → bump → push) garantit qu'on +# part d'un main synchro et qu'on ne pollue pas main avec +# le bump (qui vit sur la branche release). +# - Fail-fast si la branche existe dĂ©jĂ  en local ou sur origin. +release: + @if [ -z "$(V)" ]; then \ + echo "Usage: make release V="; \ + echo " V : version semver (ex. 1.0.7-rc1) — sert Ă  nommer la branche."; \ + exit 1; \ + fi + @if [ -n "$$(git status --porcelain)" ]; then \ + echo "Working tree sale, refus de crĂ©er une branche release."; \ + git status --short; \ + exit 1; \ + fi + @BRANCH="release/$(V)"; \ + if git show-ref --verify --quiet "refs/heads/$$BRANCH"; then \ + echo "La branche $$BRANCH existe dĂ©jĂ  en local."; \ + echo " Pour la supprimer : git branch -D $$BRANCH"; \ + exit 1; \ + fi; \ + if git ls-remote --exit-code --heads origin "$$BRANCH" >/dev/null 2>&1; then \ + echo "La branche $$BRANCH existe dĂ©jĂ  sur origin."; \ + exit 1; \ + fi; \ + echo "==> Fetch + vĂ©rification synchro main"; \ + git fetch origin main; \ + if ! git merge-base --is-ancestor origin/main HEAD; then \ + echo "main a avancĂ© plus loin que HEAD. Fais :"; \ + echo " git pull --ff-only origin main"; \ + exit 1; \ + fi; \ + echo "==> CrĂ©ation de $$BRANCH depuis main"; \ + git checkout -b "$$BRANCH"; \ + echo "==> dotnet-gitversion /updateprojectfiles"; \ + dotnet-gitversion /updateprojectfiles; \ + echo "==> Commit du bump"; \ + git add .; \ + if git diff --cached --quiet; then \ + echo "Pas de changements Ă  committer (gitversion n'a produit aucune diff)."; \ + else \ + git commit -m "chore(release): bump version via gitversion for $(V)"; \ + fi; \ + echo "==> Push de $$BRANCH sur origin"; \ + git push -u origin "$$BRANCH"; \ + echo "==> TerminĂ©. Branche $$BRANCH live sur origin." + +.PHONY: test release diff --git a/contrib/Makefile b/contrib/Makefile index 4e4ef4df6..79145668f 100644 --- a/contrib/Makefile +++ b/contrib/Makefile @@ -95,15 +95,6 @@ showConfig: @echo CONFIGURATION: $(CONFIGURATION) @echo BASEAPPDIR: $(BASEAPPDIR) -showApiLogs: - @sudo journalctl -u yavscApi.service -S "2 min ago" | tee yavscApi.log - -showOrgLogs: - @sudo journalctl -u yavscOrg.service -S "2 min ago" | tee yavscOrg.log - -showBlogsLogs: - @sudo journalctl -u yavscBlogs.service -S "2 min ago" | tee yavscBlogs.log - clean: @rm -rf generated diff --git a/dotnet-tools.json b/dotnet-tools.json index 1762a89de..b0e38abda 100644 --- a/dotnet-tools.json +++ b/dotnet-tools.json @@ -1,13 +1,5 @@ { "version": 1, "isRoot": true, - "tools": { - "picket": { - "version": "0.2.12", - "commands": [ - "picket" - ], - "rollForward": false - } - } + "tools": {} } \ No newline at end of file diff --git a/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs b/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs index 6cac39603..04cc0f314 100644 --- a/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs +++ b/src/PostIt/PostIt.Tests/ActivitiesPageViewModelTests.cs @@ -162,12 +162,6 @@ public class ActivitiesPageViewModelTests return Task.CompletedTask; } - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - public ValueTask DisposeAsync() => ValueTask.CompletedTask; } } diff --git a/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs b/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs index 34804b4cd..17fcc968c 100644 --- a/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs +++ b/src/PostIt/PostIt.Tests/BillingCommandPageViewModelTests.cs @@ -352,12 +352,6 @@ public class BillingCommandPageViewModelTests return Task.CompletedTask; } - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - public ValueTask DisposeAsync() => ValueTask.CompletedTask; } } diff --git a/src/PostIt/PostIt.Tests/BillingQueriesPageViewModelTests.cs b/src/PostIt/PostIt.Tests/BillingQueriesPageViewModelTests.cs index e53139351..d3d1d5694 100644 --- a/src/PostIt/PostIt.Tests/BillingQueriesPageViewModelTests.cs +++ b/src/PostIt/PostIt.Tests/BillingQueriesPageViewModelTests.cs @@ -127,12 +127,6 @@ public class BillingQueriesPageViewModelTests return Task.CompletedTask; } - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - public ValueTask DisposeAsync() => ValueTask.CompletedTask; } } diff --git a/src/PostIt/PostIt.Tests/EstimateEditionPageViewModelTests.cs b/src/PostIt/PostIt.Tests/EstimateEditionPageViewModelTests.cs deleted file mode 100644 index db70e25fa..000000000 --- a/src/PostIt/PostIt.Tests/EstimateEditionPageViewModelTests.cs +++ /dev/null @@ -1,270 +0,0 @@ -using System.Net.Http; -using PostIt.ViewModels; -using Yavsc; -using Yavsc.Api.Client; - -namespace PostIt.Tests; - -public class EstimateEditionPageViewModelTests -{ - private static BillingQuerySummaryDto SampleQuery() => new() - { - Id = 42, - BillingCode = "Brush", - ActivityCode = "hair", - PerformerId = "perf-1", - ClientId = "cli-1", - Status = QueryStatus.InProgress, - Description = "Coupe simple", - EventDate = new DateTime(2026, 9, 12, 10, 0, 0, DateTimeKind.Utc), - }; - - private static EstimateEditionPageViewModel CreateViewModel(StubEstimateApi api, BillingQuerySummaryDto? query = null) - { - var client = new EstimateApiClient(api, "https://business.example/api/v1/"); - return new EstimateEditionPageViewModel(query ?? SampleQuery(), client); - } - - [Fact] - public void Constructor_prefills_description_and_adds_a_first_line() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - - Assert.Equal("Coupe simple", vm.EstimateDescription); - Assert.Single(vm.Lines); - Assert.Same(vm.Lines[0], vm.SelectedLine); - Assert.Contains("#42", vm.ContextLabel); - Assert.Contains("cli-1", vm.ContextLabel); - } - - [Fact] - public void AddLine_appends_and_selects_the_new_line() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - - vm.AddLineCommand.Execute(null); - - Assert.Equal(2, vm.Lines.Count); - Assert.Same(vm.Lines[1], vm.SelectedLine); - } - - [Fact] - public void RemoveLine_removes_the_selected_line() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - var first = vm.Lines[0]; - - vm.RemoveLineCommand.Execute(null); - - Assert.Empty(vm.Lines); - Assert.Null(vm.SelectedLine); - Assert.False(vm.RemoveLineCommand.CanExecute(null)); - Assert.DoesNotContain(first, vm.Lines); - } - - [Fact] - public void Total_sums_line_totals_and_tracks_edits() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - - vm.Lines[0].Count = 2; - vm.Lines[0].UnitaryCost = 15.5m; - - Assert.Equal(31m, vm.Total); - Assert.Equal($"{31m:0.00} EUR", vm.TotalLabel); - - vm.AddLineCommand.Execute(null); - vm.Lines[1].Count = 1; - vm.Lines[1].UnitaryCost = 9m; - - Assert.Equal(40m, vm.Total); - } - - [Fact] - public async Task Send_without_title_warns_and_does_not_post() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - vm.Lines[0].Name = "Coupe"; - vm.Lines[0].Description = "Coupe simple"; - vm.Lines[0].UnitaryCost = 25m; - - await vm.SendCommand.ExecuteAsync(null); - - Assert.Null(api.LastBody); - Assert.Equal(StatusSeverity.Warning, vm.ActionStatus.Severity); - Assert.Contains("titre", vm.ActionStatus.Message); - } - - [Fact] - public async Task Send_without_any_line_warns_and_does_not_post() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - vm.EstimateTitle = "Devis coupe"; - vm.Lines.Clear(); - - await vm.SendCommand.ExecuteAsync(null); - - Assert.Null(api.LastBody); - Assert.Equal(StatusSeverity.Warning, vm.ActionStatus.Severity); - Assert.Contains("ligne", vm.ActionStatus.Message); - } - - [Fact] - public async Task Send_with_a_blank_line_name_warns_and_does_not_post() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - vm.EstimateTitle = "Devis coupe"; - vm.Lines[0].Description = "Oubli du nom"; - - await vm.SendCommand.ExecuteAsync(null); - - Assert.Null(api.LastBody); - Assert.Equal(StatusSeverity.Warning, vm.ActionStatus.Severity); - Assert.Contains("nom", vm.ActionStatus.Message); - } - - [Fact] - public async Task Send_posts_the_estimate_payload_to_the_estimate_route() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - vm.EstimateTitle = " Devis coupe "; - vm.Lines[0].Name = "Coupe"; - vm.Lines[0].Description = "Coupe simple"; - vm.Lines[0].Count = 2.4m; - vm.Lines[0].UnitaryCost = 25m; - - await vm.SendCommand.ExecuteAsync(null); - - Assert.Equal("https://business.example/api/v1/estimate", api.LastPath); - Assert.Equal(HttpMethod.Post, api.LastMethod); - - var payload = Assert.IsType(api.LastBody); - Assert.Equal(42, payload.CommandId); - Assert.Equal("cli-1", payload.ClientId); - Assert.Equal("Brush", payload.CommandType); - Assert.Equal("Devis coupe", payload.Title); - Assert.Equal("Coupe simple", payload.Description); - Assert.Empty(payload.AttachedFiles); - Assert.Empty(payload.AttachedGraphics); - - var line = Assert.Single(payload.Bill); - Assert.Equal("Coupe", line.Name); - Assert.Equal(2, line.Count); - Assert.Equal(25m, line.UnitaryCost); - Assert.Equal("EUR", line.Currency); - } - - [Fact] - public async Task Send_marks_the_page_as_sent_and_disables_resend() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - vm.EstimateTitle = "Devis coupe"; - vm.Lines[0].Name = "Coupe"; - vm.Lines[0].Description = "Coupe simple"; - vm.Lines[0].UnitaryCost = 25m; - - await vm.SendCommand.ExecuteAsync(null); - - Assert.True(vm.HasSent); - Assert.False(vm.SendCommand.CanExecute(null)); - Assert.Equal("Devis envoyĂ©", vm.SendLabel); - Assert.Equal(StatusSeverity.Info, vm.ActionStatus.Severity); - Assert.Contains("#7", vm.ActionStatus.Message); - } - - [Fact] - public async Task Send_surfaces_server_errors_as_error_status() - { - var api = new StubEstimateApi { Failure = new HttpRequestException("boom", null, System.Net.HttpStatusCode.InternalServerError) }; - var vm = CreateViewModel(api); - vm.EstimateTitle = "Devis coupe"; - vm.Lines[0].Name = "Coupe"; - vm.Lines[0].Description = "Coupe simple"; - - await vm.SendCommand.ExecuteAsync(null); - - Assert.False(vm.HasSent); - Assert.Equal(StatusSeverity.Error, vm.ActionStatus.Severity); - Assert.True(vm.SendCommand.CanExecute(null)); - } - - [Fact] - public async Task Send_accepts_negative_amounts_for_discount_lines() - { - var api = new StubEstimateApi(); - var vm = CreateViewModel(api); - vm.EstimateTitle = "Devis avec remise"; - vm.Lines[0].Name = "Coupe"; - vm.Lines[0].Description = "Coupe simple"; - vm.Lines[0].UnitaryCost = 25m; - - vm.AddLineCommand.Execute(null); - vm.Lines[1].Name = "Remise fidĂ©litĂ©"; - vm.Lines[1].Description = "Remise client rĂ©gulier"; - vm.Lines[1].UnitaryCost = -5m; - - Assert.Equal(20m, vm.Total); - - await vm.SendCommand.ExecuteAsync(null); - - var payload = Assert.IsType(api.LastBody); - Assert.Equal(2, payload.Bill.Count); - Assert.Equal(-5m, payload.Bill[1].UnitaryCost); - Assert.True(vm.HasSent); - } - - private sealed class StubEstimateApi : IYavscApiClient - { - public HttpClient Http { get; } = new(); - public string? LastPath { get; private set; } - public HttpMethod? LastMethod { get; private set; } - public object? LastBody { get; private set; } - public Exception? Failure { get; init; } - - public Task CallAsync(HttpMethod method, string path, object? body = null, CancellationToken ct = default) - { - LastMethod = method; - LastPath = path; - LastBody = body; - - if (Failure is not null) - { - throw Failure; - } - - if (typeof(T) == typeof(EstimateCreatedDto)) - { - var payload = (EstimateDto)body!; - var created = new EstimateCreatedDto { Id = 7, Bill = payload.Bill }; - return Task.FromResult((T)(object)created); - } - - return Task.FromResult(default(T)!); - } - - public Task CallAsync(HttpMethod method, string path, object? body = null, CancellationToken ct = default) - { - LastMethod = method; - LastPath = path; - LastBody = body; - return Task.CompletedTask; - } - - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - - public Task CallAsync(HttpMethod method, string path, Func contentFactory, CancellationToken ct = default) - => CallAsync(method, path, (object?)null, ct); - - public ValueTask DisposeAsync() => ValueTask.CompletedTask; - } -} diff --git a/src/PostIt/PostIt.Tests/HomePageProviderFlowTests.cs b/src/PostIt/PostIt.Tests/HomePageProviderFlowTests.cs deleted file mode 100644 index 16f01c5e9..000000000 --- a/src/PostIt/PostIt.Tests/HomePageProviderFlowTests.cs +++ /dev/null @@ -1,15 +0,0 @@ -using PostIt.ViewModels; - -namespace PostIt.Tests; - -public class HomePageProviderFlowTests -{ - [Fact] - public void HomePage_exposes_provider_requests_command() - { - var vm = new HomePageViewModel(); - - Assert.NotNull(vm.OpenProviderRequests); - Assert.True(vm.OpenProviderRequests.CanExecute(null)); - } -} diff --git a/src/PostIt/PostIt.Tests/MainPageButtonsTests.cs b/src/PostIt/PostIt.Tests/MainPageButtonsTests.cs index f72c8d4d5..d1d00532d 100644 --- a/src/PostIt/PostIt.Tests/MainPageButtonsTests.cs +++ b/src/PostIt/PostIt.Tests/MainPageButtonsTests.cs @@ -8,8 +8,6 @@ using Yavsc.Blogspot; using PostIt.Services; using PostIt.ViewModels; using PostIt.Views; -using PostIt.Views.Blogs; -using PostIt.Helpers; namespace PostIt.Tests; @@ -74,13 +72,13 @@ public class MainPageButtonsTests { } } - private static BlogsViewModel MakeViewModel(BlogPostDto? selectedPost = null) + private static MainViewModel MakeViewModel(BlogPostDto? selectedPost = null) { var api = new ThrowingApi(); var blog = new BlogApiClient(api, "http://localhost/"); var circle = new CircleApiClient(api, "http://localhost/"); var acl = new BlogAclApiClient(api, "http://localhost/"); - // Minimal DI graph: only what BlogsViewModel resolves + // Minimal DI graph: only what MainPageViewModel resolves // when the user clicks a navigation button. Today that's // SignaturePageViewModel / CirclesPageViewModel / ACL // dependencies. The graph intentionally stays local to this @@ -95,7 +93,7 @@ public class MainPageButtonsTests services.AddTransient(); services.AddTransient(); services.AddTransient(); - var vm = new BlogsViewModel(blog, services: services.BuildServiceProvider()); + var vm = new MainViewModel(blog, services: services.BuildServiceProvider()); if (selectedPost is not null) vm.SelectedPost = selectedPost; return vm; } @@ -103,7 +101,7 @@ public class MainPageButtonsTests /// /// Mount a real (as /// SessionStatusBannerTests does), push a - /// with the given VM onto + /// with the given VM onto /// NavRoot. PushAsync is awaited (via /// GetAwaiter().GetResult()) so the page is on the /// nav stack before the test tries to interact with its @@ -111,17 +109,13 @@ public class MainPageButtonsTests /// realised and KeyPressQwerty has a real /// to dispatch against. /// - private static (MainView window, BlogsPage page) MountMainPage(BlogsViewModel vm) + private static (MainView window, MainPage page) MountMainPage(MainViewModel vm) { var window = new MainView(); - var page = new BlogsPage { DataContext = vm }; + var page = new MainPage { DataContext = vm }; var app = (PostIt.App)Application.Current!; - app.AttachMainWindow(window); - window.NavRoot.PushAsync(page).GetAwaiter().GetResult(); - var mainWindow = new Window { Content = window }; - mainWindow.Show(); return (window, page); } @@ -151,7 +145,7 @@ public class MainPageButtonsTests } [AvaloniaFact] - public async Task Acl_button_click_pushes_a_page_onto_nav_stack() + public void Acl_button_click_pushes_a_page_onto_nav_stack() { // Arrange: a VM whose SelectedPost is non-null so // CanManageAcl evaluates to true and the button is @@ -184,7 +178,7 @@ public class MainPageButtonsTests } [AvaloniaFact] - public async Task Circles_button_click_pushes_a_page_onto_nav_stack() + public void Circles_button_click_pushes_a_page_onto_nav_stack() { // Arrange: OpenCircles has no CanExecute guard today — // any click should fire it and push the page. @@ -209,7 +203,7 @@ public class MainPageButtonsTests public void Signature_dev_button_click_pushes_a_page_onto_nav_stack() { // Arrange: the "[DEV] Signature" button is bound to the - // BlogsViewModel.OpenSignatureDevCommand [RelayCommand]. + // MainPageViewModel.OpenSignatureDevCommand [RelayCommand]. // The click must push SignaturePage on top of NavRoot. // The ServiceCollection registered in MakeViewModel provides // SignaturePageViewModel so the command can resolve it via diff --git a/src/PostIt/PostIt.Tests/MainPageSaveTests.cs b/src/PostIt/PostIt.Tests/MainPageSaveTests.cs index 519cd141d..0fd5627c8 100644 --- a/src/PostIt/PostIt.Tests/MainPageSaveTests.cs +++ b/src/PostIt/PostIt.Tests/MainPageSaveTests.cs @@ -5,11 +5,10 @@ using Yavsc.Blogspot; using Yavsc.Api.Client; using PostIt.ViewModels; using PostIt.Views; -using PostIt.Views.Blogs; namespace PostIt.Tests; /// -/// Headless UI tests for the "Save" flow in . +/// Headless UI tests for the "Save" flow in . /// The pattern is the one SessionStatusBannerTests /// established: [AvaloniaFact], a /// hosting the page (via a because @@ -41,9 +40,9 @@ public class MainPageSaveTests var recorder = new CallRecorder(); var api = new RecordingYavscApiClient(recorder); var blog = new BlogApiClient(api, "http://localhost/"); - var viewModel = new BlogsViewModel(blog); + var viewModel = new MainViewModel(blog); - var page = new BlogsPage { DataContext = viewModel }; + var page = new MainPage { DataContext = viewModel }; // MainPage is a ContentPage (a Page, not a Control), so it // must be hosted in a navigation surface. The production // MainWindow.axaml uses NavigationPage, and the API is the @@ -64,7 +63,9 @@ public class MainPageSaveTests const string typed = "Mon premier billet"; titleBox.Text = typed; - var saveButton = page.SaveButton; + var saveButton = window.GetVisualDescendants() + .OfType