diff --git a/src/PostIt/PostIt.Tests/HomePageProviderFlowTests.cs b/src/PostIt/PostIt.Tests/HomePageProviderFlowTests.cs index 2428f8cb0..8fce7921e 100644 --- a/src/PostIt/PostIt.Tests/HomePageProviderFlowTests.cs +++ b/src/PostIt/PostIt.Tests/HomePageProviderFlowTests.cs @@ -143,4 +143,27 @@ public class HomePageProviderFlowTests Assert.Equal(string.Empty, payload.GoogleCalendarId); Assert.Equal(string.Empty, payload.BankInfoSummary); } + + [Fact] + public void PerformerConfigurationPage_preserves_current_user_id_in_save_payload() + { + var vm = new PerformerConfigurationPageViewModel + { + PerformerId = "user-42", + UserName = "alice", + ExerciseCountryCode = "fr", + SIREN = "123456789", + Website = "https://example.com", + Active = true, + AcceptNotifications = true, + AcceptPublicContact = true, + UseGeoLocalizationToReduceDistanceWithClients = true + }; + + var payload = vm.BuildPerformerProfileSettings(); + + Assert.Equal("user-42", payload.PerformerId); + Assert.Equal("alice", payload.UserName); + Assert.Equal("fr", payload.ExerciseCountryCode); + } } diff --git a/src/PostIt/PostIt/ViewModels/PerformerConfigurationPageViewModel.cs b/src/PostIt/PostIt/ViewModels/PerformerConfigurationPageViewModel.cs index bf8318ab5..91b6d0572 100644 --- a/src/PostIt/PostIt/ViewModels/PerformerConfigurationPageViewModel.cs +++ b/src/PostIt/PostIt/ViewModels/PerformerConfigurationPageViewModel.cs @@ -29,12 +29,15 @@ public partial class ActivitySelectionOption : ObservableObject public partial class PerformerConfigurationPageViewModel : ViewModelBase { - private readonly YavscApiClient _api; - private readonly ActivityApiClient _activityClient; + private readonly YavscApiClient? _api; + private readonly ActivityApiClient? _activityClient; [ObservableProperty] public partial bool IsBusy { get; set; } + [ObservableProperty] + public partial string PerformerId { get; set; } = string.Empty; + [ObservableProperty] public partial string UserName { get; set; } = "—"; @@ -68,25 +71,32 @@ public partial class PerformerConfigurationPageViewModel : ViewModelBase public override bool CanNavigateNext { get => false; protected set { _ = value; } } public override bool CanNavigatePrevious { get => true; protected set { _ = value; } } - public PerformerConfigurationPageViewModel(YavscApiClient api, ActivityApiClient activityClient) + public PerformerConfigurationPageViewModel(YavscApiClient? api, ActivityApiClient? activityClient) { - _api = api ?? throw new ArgumentNullException(nameof(api)); - _activityClient = activityClient ?? throw new ArgumentNullException(nameof(activityClient)); + _api = api; + _activityClient = activityClient; } - public PerformerConfigurationPageViewModel() : this(null!, null!) { } + public PerformerConfigurationPageViewModel() : this(null, null) { } public Task InitializeAsync() => RefreshAsync(); [RelayCommand] public async Task RefreshAsync() { + if (_api is null || _activityClient is null) + { + StatusMessage = "Client API de configuration indisponible."; + return; + } + IsBusy = true; try { var endpoint = new Uri(new Uri(_api.Settings.ApiUrl.TrimEnd('/') + "/", UriKind.Absolute), "account/performer-profile").ToString(); var dto = await _api.CallAsync(HttpMethod.Get, endpoint).ConfigureAwait(true); + PerformerId = dto?.PerformerId ?? string.Empty; UserName = dto?.UserName ?? "—"; ExerciseCountryCode = string.IsNullOrWhiteSpace(dto?.ExerciseCountryCode) ? "fr" : dto.ExerciseCountryCode; SIREN = dto?.SIREN ?? string.Empty; @@ -123,29 +133,40 @@ public partial class PerformerConfigurationPageViewModel : ViewModelBase } } + public PerformerProfileSettings BuildPerformerProfileSettings() + { + return new PerformerProfileSettings + { + PerformerId = string.IsNullOrWhiteSpace(PerformerId) ? string.Empty : PerformerId, + UserName = UserName, + ExerciseCountryCode = string.IsNullOrWhiteSpace(ExerciseCountryCode) ? "fr" : ExerciseCountryCode, + SIREN = SIREN, + WebSite = Website, + Active = Active, + AcceptNotifications = AcceptNotifications, + AcceptPublicContact = AcceptPublicContact, + UseGeoLocalizationToReduceDistanceWithClients = UseGeoLocalizationToReduceDistanceWithClients, + SelectedActivityCodes = AvailableActivities + .Where(a => a.IsSelected) + .Select(a => a.Code) + .Distinct(StringComparer.OrdinalIgnoreCase) + .ToList() + }; + } + [RelayCommand] public async Task SaveAsync() { + if (_api is null) + { + StatusMessage = "Client API de configuration indisponible."; + return; + } + IsBusy = true; try { - var dto = new PerformerProfileSettings - { - PerformerId = string.Empty, - UserName = UserName, - ExerciseCountryCode = string.IsNullOrWhiteSpace(ExerciseCountryCode) ? "fr" : ExerciseCountryCode, - SIREN = SIREN, - WebSite = Website, - Active = Active, - AcceptNotifications = AcceptNotifications, - AcceptPublicContact = AcceptPublicContact, - UseGeoLocalizationToReduceDistanceWithClients = UseGeoLocalizationToReduceDistanceWithClients, - SelectedActivityCodes = AvailableActivities - .Where(a => a.IsSelected) - .Select(a => a.Code) - .Distinct(StringComparer.OrdinalIgnoreCase) - .ToList() - }; + var dto = BuildPerformerProfileSettings(); var endpoint = new Uri(new Uri(_api.Settings.ApiUrl.TrimEnd('/') + "/", UriKind.Absolute), "account/performer-profile").ToString(); var response = await _api.CallAsync(HttpMethod.Put, endpoint, dto).ConfigureAwait(true); diff --git a/src/Yavsc.Api/Controllers/accounting/AccountController.cs b/src/Yavsc.Api/Controllers/accounting/AccountController.cs index a1713188a..a7b378e94 100644 --- a/src/Yavsc.Api/Controllers/accounting/AccountController.cs +++ b/src/Yavsc.Api/Controllers/accounting/AccountController.cs @@ -228,7 +228,17 @@ namespace Yavsc.WebApi.Controllers } var uid = User.GetUserId(); - if (string.IsNullOrWhiteSpace(uid) || !string.Equals(model.PerformerId, uid, StringComparison.Ordinal)) + if (string.IsNullOrWhiteSpace(uid)) + { + return Challenge(); + } + + if (string.IsNullOrWhiteSpace(model.PerformerId)) + { + model.PerformerId = uid; + } + + if (!string.Equals(model.PerformerId, uid, StringComparison.Ordinal)) { return Forbid(); }