< Summary

Information
Class: UIBlazor.Services.Settings.ProfileService
Assembly: UIBlazor
File(s): /home/runner/work/InvAit/InvAit/UIBlazor/Services/Settings/ProfileService.cs
Tag: 14_22728831704
Line coverage
77%
Covered lines: 49
Uncovered lines: 14
Coverable lines: 63
Total lines: 147
Line coverage: 77.7%
Branch coverage
63%
Covered branches: 24
Total branches: 38
Branch coverage: 63.1%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
get_ActiveProfile()100%11100%
AfterInitAsync()100%88100%
OnAnyPropertyChanged(...)75%44100%
OnProfilePropertyChanged(...)100%66100%
NotifySkipSsl(...)100%11100%
DeleteProfileAsync()83.33%6690%
ActivateProfileAsync()75%4485.71%
ResetAsync()50%2292.3%
Dispose()0%620%
CopyProfileProperties(...)0%7280%

File(s)

/home/runner/work/InvAit/InvAit/UIBlazor/Services/Settings/ProfileService.cs

#LineLine coverage
 1using System.ComponentModel;
 2using System.Reflection;
 3using Microsoft.JSInterop;
 4
 5namespace UIBlazor.Services.Settings;
 6
 7public class ProfileService(ILocalStorageService localStorage, ILogger<ProfileService> logger, IJSRuntime jSRuntime)
 78    : BaseSettingsProvider<ProfileOptions>(localStorage, logger, "ProfileSettings"), IProfileManager
 9{
 2710    public ConnectionProfile ActiveProfile { get; private set; }
 11
 12    protected override async Task AfterInitAsync()
 13    {
 614        if (Current.Profiles.Count == 0)
 15        {
 116            await ResetAsync();
 17        }
 18
 1319        ActiveProfile = Current.Profiles.FirstOrDefault(p => p.Id == Current.ActiveProfileId) ?? Current.Profiles.First(
 20
 2621        foreach (var profile in Current.Profiles)
 22        {
 723            profile.PropertyChanged += OnProfilePropertyChanged;
 24        }
 25
 626        if (ActiveProfile.SkipSSL)
 27        {
 128            NotifySkipSsl(ActiveProfile.SkipSSL);
 29        }
 630    }
 31
 32    protected override void OnAnyPropertyChanged(string? propertyName)
 33    {
 134        if (propertyName == nameof(ProfileOptions.ActiveProfileId))
 35        {
 236            ActiveProfile = Current.Profiles.FirstOrDefault(p => p.Id == Current.ActiveProfileId) ?? Current.Profiles.Fi
 37        }
 138    }
 39
 40    private void OnProfilePropertyChanged(object? sender, PropertyChangedEventArgs e)
 41    {
 142        if (sender is ConnectionProfile profile && profile.Id == Current.ActiveProfileId)
 43        {
 144            if (e.PropertyName == nameof(ConnectionProfile.SkipSSL))
 45            {
 146                NotifySkipSsl(profile.SkipSSL);
 47            }
 48        }
 49
 150        Debouncer.Trigger();
 151    }
 52
 53    private void NotifySkipSsl(bool skipSsl)
 54    {
 355        jSRuntime.InvokeAsync<string>("postVsMessage", new VsRequest { Action = BasicEnum.SkipSSL, Payload = skipSsl.ToS
 356    }
 57
 58    public async Task DeleteProfileAsync(string profileId)
 59    {
 260        if (Current.Profiles.Count < 2)
 61        {
 162            return; // нельзя удалять единственный профиль.
 63        }
 64
 365        var profile = Current.Profiles.FirstOrDefault(p => p.Id == profileId);
 166        if (profile != null)
 67        {
 168            profile.PropertyChanged -= OnProfilePropertyChanged;
 169            Current.Profiles.Remove(profile);
 70
 71            // актуализация активного профиля
 172            if (profileId == Current.ActiveProfileId)
 73            {
 074                await ActivateProfileAsync(Current.Profiles.First().Id, saveImediatly: true);
 75            }
 76            else
 77            {
 178                Debouncer.Trigger();
 79            }
 80        }
 81
 182        return;
 283    }
 84
 85    public async Task ActivateProfileAsync(string profileId, bool saveImediatly = false)
 86    {
 287        var profile = Current.Profiles.FirstOrDefault(p => p.Id == profileId);
 188        if (profile != null)
 89        {
 190            Current.ActiveProfileId = profileId;
 91
 192            NotifySkipSsl(profile.SkipSSL);
 93
 194            if (!saveImediatly)
 95            {
 096                Debouncer.Trigger();
 97            }
 98            else
 99            {
 1100                await SaveAsync();
 101            }
 102        }
 1103    }
 104
 105    public override async Task ResetAsync()
 106    {
 4107        foreach (var p in Current.Profiles)
 108        {
 0109            p.PropertyChanged -= OnProfilePropertyChanged;
 110        }
 111
 2112        var defaultProfile = new ConnectionProfile
 2113        {
 2114            Name = "default",
 2115            Endpoint = "https://api.openai.com"
 2116        };
 117
 2118        defaultProfile.PropertyChanged += OnProfilePropertyChanged;
 2119        Current.Profiles = [defaultProfile];
 2120        Current.ActiveProfileId = defaultProfile.Id;
 2121        ActiveProfile = defaultProfile;
 122
 2123        await SaveAsync();
 2124    }
 125
 126    public override void Dispose()
 127    {
 0128        base.Dispose();
 0129        foreach (var p in Current.Profiles)
 130        {
 0131            p.PropertyChanged -= OnProfilePropertyChanged;
 132        }
 0133    }
 134
 135    private static void CopyProfileProperties(ConnectionProfile from, ConnectionProfile to)
 136    {
 0137        var properties = typeof(ConnectionProfile)
 0138            .GetProperties(BindingFlags.Public | BindingFlags.Instance)
 0139            .Where(p => p is { CanRead: true, CanWrite: true } && p.Name != nameof(ConnectionProfile.Id));
 140
 0141        foreach (var prop in properties)
 142        {
 0143            var value = prop.GetValue(from);
 0144            prop.SetValue(to, value);
 145        }
 0146    }
 147}