public void UnknownAccessTokenThrowsArgumentException() { var settings = new CoreSettings(); var accessControl = new AccessControl(settings); Assert.Throws<ArgumentException>(() => accessControl.VerifyAccess(new Guid())); }
public async Task DoesntAuthenticeWithoutPermission() { var coreSettings = new CoreSettings { EnableAutomaticReports = false }; var client = new AnalyticsClient(Substitute.For<IAnalyticsEndpoint>()); await client.InitializeAsync(coreSettings); Assert.False(client.IsAuthenticated); }
public void InitializesEndpoint() { var coreSettings = new CoreSettings { EnableAutomaticReports = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); client.Initialize(coreSettings); endpoint.Received().Initialize(); }
public async Task CreatesUserIfAnalyticsTokenIsNull() { var coreSettings = new CoreSettings { EnableAutomaticReports = true, AnalyticsToken = null }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); endpoint.Received().CreateUserAsync(); }
public void SendsReport() { var coreSettings = new CoreSettings { EnableAutomaticReports = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); client.Initialize(coreSettings); client.RecordNonFatalError(new Exception()); endpoint.ReceivedWithAnyArgs().ReportNonFatalException(null); }
public void UpdatesEmailIfSet() { var coreSettings = new CoreSettings { EnableAutomaticReports = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); client.Initialize(coreSettings); client.RecordBugReport("blabla", "*****@*****.**"); endpoint.Received().UpdateEmail("*****@*****.**"); }
public async Task DoesntCreateUserIfAnalyticsTokenIsSaved() { var coreSettings = new CoreSettings { EnableAutomaticReports = true, AnalyticsToken = "cooltoken", BuddyAnalyticsUpgraded = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); endpoint.DidNotReceive().CreateUserAsync(); }
public async Task RecreatesAnalyticsTokenIfNecessacry() { var coreSettings = new CoreSettings { EnableAutomaticReports = true, AnalyticsToken = "cooltoken", BuddyAnalyticsUpgraded = false }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); Assert.NotEqual("cooltoken", coreSettings.AnalyticsToken); }
public async Task RecordDeviceInformation() { var coreSettings = new CoreSettings { EnableAutomaticReports = true, AnalyticsToken = null }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); endpoint.Received().RecordDeviceInformationAsync(); }
public void RegisterVoteForSameEntryThrowsInvalidOperationException() { var settings = new CoreSettings { MaxVoteCount = 2 }; var accessControl = new AccessControl(settings); Guid token = accessControl.RegisterRemoteAccessToken(new Guid()); var entry = SetupVotedEntry(); accessControl.RegisterVote(token, entry); entry.Vote(); Assert.Throws<InvalidOperationException>(() => accessControl.RegisterVote(token, entry)); }
public async Task Authenticates() { var coreSettings = new CoreSettings { EnableAutomaticReports = true, AnalyticsToken = "cooltoken", BuddyAnalyticsUpgraded = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); Assert.True(client.IsAuthenticated); endpoint.Received().AuthenticateUserAsync(Arg.Any<string>()); }
public void Initialize(CoreSettings settings) { if (settings == null) throw new ArgumentNullException("settings"); this.coreSettings = settings; this.endpoint.Initialize(); this.Log().Info("Initialized the analytics and crash report provider"); this.Log().Info("Automatic analytics are {0}", this.EnableAutomaticReports ? "Enabled" : "Disabled"); }
public void UnlockedRemoteControlGivesAdminRightsByDefault() { var settings = new CoreSettings { LockRemoteControl = false }; var accessControl = new AccessControl(settings); Guid token = accessControl.RegisterRemoteAccessToken(new Guid()); accessControl.VerifyAccess(token); }
public async Task InitializeAsync(CoreSettings settings) { if (settings == null) throw new ArgumentNullException("settings"); this.coreSettings = settings; // If we don't have permission to send things, do nothing if (!this.coreSettings.EnableAutomaticReports) return; await this.AuthenticateAsync(); }
public void LockedRemoteControlGivesGuestRightsByDefault() { var settings = new CoreSettings { LockRemoteControl = true, RemoteControlPassword = "******" }; var accessControl = new AccessControl(settings); Guid token = accessControl.RegisterRemoteAccessToken(new Guid()); Assert.Throws<AccessException>(() => accessControl.VerifyAccess(token)); }
public void RegisteredVoteUnregistersAutomaticallyWhenEntryvoteCountIsReset() { var settings = new CoreSettings { MaxVoteCount = 2 }; var accessControl = new AccessControl(settings); Guid token = accessControl.RegisterRemoteAccessToken(new Guid()); var entry = new PlaylistEntry(0, Helpers.SetupSongMock()); entry.Vote(); var votes = accessControl.ObserveRemainingVotes(token).CreateCollection(); accessControl.RegisterVote(token, entry); entry.ResetVotes(); Assert.Equal(new int?[] { 2, 1, 2 }, votes); }
public Library(ILibraryReader libraryReader, ILibraryWriter libraryWriter, CoreSettings settings, IFileSystem fileSystem, Func<string, ILocalSongFinder> localSongFinderFunc = null) { if (libraryReader == null) throw new ArgumentNullException("libraryReader"); if (libraryWriter == null) throw new ArgumentNullException("libraryWriter"); if (settings == null) throw new ArgumentNullException("settings"); if (fileSystem == null) throw new ArgumentNullException("fileSystem"); this.libraryReader = libraryReader; this.libraryWriter = libraryWriter; this.settings = settings; this.fileSystem = fileSystem; this.localSongFinderFunc = localSongFinderFunc ?? (x => new LocalSongFinder(x)); this.globalSubscriptions = new CompositeDisposable(); this.accessControl = new AccessControl(settings); this.songLock = new ReaderWriterLockSlim(); this.songs = new HashSet<LocalSong>(); this.playlists = new ReactiveList<Playlist>(); this.songsUpdated = new Subject<Unit>(); this.audioPlayer = new AudioPlayer(); this.manualUpdateTrigger = new Subject<Unit>(); this.LoadedSong = this.audioPlayer.LoadedSong; this.TotalTime = this.audioPlayer.TotalTime; this.PlaybackState = this.audioPlayer.PlaybackState; this.WhenAnyValue(x => x.CurrentPlaylist.CanPlayNextSong).SampleAndCombineLatest(this.audioPlayer.PlaybackState .Where(p => p == AudioPlayerState.Finished), (canPlayNextSong, _) => canPlayNextSong) .SelectMany(x => this.HandleSongFinishAsync(x).ToObservable()) .Subscribe(); this.CurrentPlaybackTime = this.audioPlayer.CurrentTimeChanged; this.volume = this.settings.WhenAnyValue(x => x.Volume) .ToProperty(this, x => x.Volume); }
public void IgnoresEmailIfNullOrEmpty() { var coreSettings = new CoreSettings { EnableAutomaticReports = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); client.Initialize(coreSettings); client.RecordBugReport("blabla"); endpoint.DidNotReceiveWithAnyArgs().UpdateEmail(Arg.Any<string>()); client.RecordBugReport("blabla", String.Empty); endpoint.DidNotReceiveWithAnyArgs().UpdateEmail(Arg.Any<string>()); client.RecordBugReport("blabla", " "); endpoint.DidNotReceiveWithAnyArgs().UpdateEmail(null); }
public PlaylistViewModel(Playlist playlist, Library library, Guid accessToken, CoreSettings coreSettings) { if (playlist == null) throw new ArgumentNullException("playlist"); if (library == null) throw new ArgumentNullException("library"); if (coreSettings == null) throw new ArgumentNullException("coreSettings"); this.playlist = playlist; this.library = library; this.disposable = new CompositeDisposable(); this.entries = playlist .CreateDerivedCollection(entry => new PlaylistEntryViewModel(entry), x => x.Dispose()) .DisposeWith(this.disposable); this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit() .Merge(this.entries.Changed.ToUnit()) .Subscribe(_ => this.UpdateCurrentSong()) .DisposeWith(this.disposable); IObservable<List<PlaylistEntryViewModel>> remainingSongs = this.entries.Changed .Select(x => Unit.Default) .Merge(this.playlist.WhenAnyValue(x => x.CurrentSongIndex).ToUnit()) .Select(x => this.entries.Reverse().TakeWhile(entry => !entry.IsPlaying).ToList()); this.songsRemaining = remainingSongs .Select(x => x.Count) .ToProperty(this, x => x.SongsRemaining) .DisposeWith(this.disposable); this.timeRemaining = remainingSongs .Select(x => x.Any() ? x.Select(entry => entry.Duration).Aggregate((t1, t2) => t1 + t2) : (TimeSpan?)null) .ToProperty(this, x => x.TimeRemaining) .DisposeWith(this.disposable); this.CurrentPlayingEntry = this.Model.WhenAnyValue(x => x.CurrentSongIndex).Select(x => x == null ? null : this.entries[x.Value]); this.canAlterPlaylist = this.library.LocalAccessControl.HasAccess(coreSettings.WhenAnyValue(x => x.LockPlaylist), accessToken) .ToProperty(this, x => x.CanAlterPlaylist) .DisposeWith(disposable); // We re-evaluate the selected entries after each up or down move here, because WPF // doesn't send us proper updates about the selection var reEvaluateSelectedPlaylistEntry = new Subject<Unit>(); this.MovePlaylistSongUpCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1 && x.First().Index > 0) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveUp, canAlterPlaylist) => canMoveUp && canAlterPlaylist)); this.MovePlaylistSongUpCommand.Subscribe(_ => { int index = this.SelectedEntries.First().Index; this.library.MovePlaylistSong(index, index - 1, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.MovePlaylistSongDownCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1 && x.First().Index < this.Songs.Count - 1) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveDown, canAlterPlaylist) => canMoveDown && canAlterPlaylist)); this.MovePlaylistSongDownCommand.Subscribe(_ => { int index = this.SelectedEntries.First().Index; this.library.MovePlaylistSong(index, index + 1, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.MovePlaylistSongCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries) .Merge(reEvaluateSelectedPlaylistEntry.Select(_ => this.SelectedEntries)) .Select(x => x != null && x.Count() == 1) .CombineLatest(this.WhenAnyValue(x => x.CanAlterPlaylist), (canMoveUp, canAlterPlaylist) => canMoveUp && canAlterPlaylist)); this.MovePlaylistSongCommand.Subscribe(x => { int fromIndex = this.SelectedEntries.First().Index; int toIndex = (int?)x ?? this.Songs.Last().Index + 1; // If we move a song from the front of the playlist to the back, we want it move be // in front of the target song if (fromIndex < toIndex) { toIndex--; } this.library.MovePlaylistSong(fromIndex, toIndex, accessToken); reEvaluateSelectedPlaylistEntry.OnNext(Unit.Default); }); this.RemoveSelectedPlaylistEntriesCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.SelectedEntries, x => x.CanAlterPlaylist, (selectedPlaylistEntries, canAlterPlaylist) => selectedPlaylistEntries != null && selectedPlaylistEntries.Any() && canAlterPlaylist)); this.RemoveSelectedPlaylistEntriesCommand.Subscribe(x => this.library.RemoveFromPlaylist(this.SelectedEntries.Select(entry => entry.Index), accessToken)); }
public async Task SendsReport() { var coreSettings = new CoreSettings { EnableAutomaticReports = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); await client.RecordErrorAsync(new Exception()); endpoint.ReceivedWithAnyArgs().RecordErrorAsync(null); }
public async Task RespectsDisabledReports() { var coreSettings = new CoreSettings { EnableAutomaticReports = false }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); await client.RecordErrorAsync(new Exception()); Assert.False(client.IsAuthenticated); endpoint.DidNotReceiveWithAnyArgs().RecordErrorAsync(null, null); }
public async Task ForcesAuthentication() { var coreSettings = new CoreSettings { EnableAutomaticReports = false }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); // This won't authenticate because automatic reports are disabled await client.InitializeAsync(coreSettings); // This will force an authentication even if automatic reports are disabled await client.RecordCrashAsync(new Exception()); Assert.True(client.IsAuthenticated); endpoint.ReceivedWithAnyArgs().RecordErrorAsync(null, null); }
public async Task UpdatesEmailIfSet() { var coreSettings = new CoreSettings { EnableAutomaticReports = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); await client.RecordBugReportAsync("blabla", "*****@*****.**"); endpoint.Received().UpdateUserEmailAsync("*****@*****.**"); }
public async Task IgnoresEmailIfNullOrEmpty() { var coreSettings = new CoreSettings { EnableAutomaticReports = true }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); await client.InitializeAsync(coreSettings); await client.RecordBugReportAsync("blabla"); endpoint.DidNotReceiveWithAnyArgs().UpdateUserEmailAsync(null); await client.RecordBugReportAsync("blabla", String.Empty); endpoint.DidNotReceiveWithAnyArgs().UpdateUserEmailAsync(null); await client.RecordBugReportAsync("blabla", " "); endpoint.DidNotReceiveWithAnyArgs().UpdateUserEmailAsync(null); }
public async Task ForcesAuthentication() { var coreSettings = new CoreSettings { EnableAutomaticReports = false }; var endpoint = Substitute.For<IAnalyticsEndpoint>(); var client = new AnalyticsClient(endpoint); // This won't authenticate because automatic reports are disabled await client.InitializeAsync(coreSettings); // This will force an authentication even if automatic reports are disabled await client.RecordBugReportAsync("blabla"); Assert.True(client.IsAuthenticated); endpoint.Received().RecordErrorAsync(Arg.Is<Exception>(x => x.Message == "blabla"), null); }
public ShellViewModel(Library library, ViewSettings viewSettings, CoreSettings coreSettings, IWindowManager windowManager, MobileApiInfo mobileApiInfo) { this.library = library; this.ViewSettings = viewSettings; this.coreSettings = coreSettings; this.disposable = new CompositeDisposable(); this.UpdateViewModel = new UpdateViewModel(viewSettings); this.library.Initialize(); this.accessToken = this.library.LocalAccessControl.RegisterLocalAccessToken(); this.library.WhenAnyValue(x => x.CurrentPlaylist).Subscribe(x => this.RaisePropertyChanged("CurrentPlaylist")); this.canChangeTime = this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockTime), this.accessToken) .ToProperty(this, x => x.CanChangeTime); this.canChangeVolume = this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockVolume), this.accessToken) .ToProperty(this, x => x.CanChangeVolume); this.canAlterPlaylist = this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockPlaylist), this.accessToken) .ToProperty(this, x => x.CanAlterPlaylist); this.showVotes = this.library.RemoteAccessControl.WhenAnyValue(x => x.IsGuestSystemReallyEnabled) .CombineLatest(mobileApiInfo.ConnectedClientCount, (enableGuestSystem, connectedClients) => enableGuestSystem && connectedClients > 0) .ToProperty(this, x => x.ShowVotes); mobileApiInfo.VideoPlayerToggleRequest.Subscribe(_ => this.ShowVideoPlayer = !this.ShowVideoPlayer); this.isAdmin = this.library.LocalAccessControl.ObserveAccessPermission(this.accessToken) .Select(x => x == AccessPermission.Admin) .ToProperty(this, x => x.IsAdmin); this.NextSongCommand = ReactiveCommand.CreateAsyncTask(this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockPlayPause), this.accessToken) .CombineLatest(this.library.WhenAnyValue(x => x.CurrentPlaylist.CanPlayNextSong), (x1, x2) => x1 && x2) .ObserveOn(RxApp.MainThreadScheduler), _ => this.library.PlayNextSongAsync(this.accessToken)); this.PreviousSongCommand = ReactiveCommand.CreateAsyncTask(this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockPlayPause), this.accessToken) .CombineLatest(this.library.WhenAnyValue(x => x.CurrentPlaylist.CanPlayPreviousSong), (x1, x2) => x1 && x2) .ObserveOn(RxApp.MainThreadScheduler), _ => this.library.PlayPreviousSongAsync(this.accessToken)); if (!this.library.Playlists.Any()) { this.library.AddAndSwitchToPlaylist(this.GetNewPlaylistName(), this.accessToken); } else { this.library.SwitchToPlaylist(this.library.Playlists.First(), this.accessToken); } this.SettingsViewModel = new SettingsViewModel(this.library, this.ViewSettings, this.coreSettings, windowManager, this.accessToken, mobileApiInfo); this.LocalViewModel = new LocalViewModel(this.library, this.ViewSettings, this.coreSettings, accessToken); this.YoutubeViewModel = new YoutubeViewModel(this.library, this.ViewSettings, this.coreSettings, accessToken); this.SoundCloudViewModel = new SoundCloudViewModel(this.library, accessToken, this.coreSettings, this.ViewSettings); this.DirectYoutubeViewModel = new DirectYoutubeViewModel(this.library, this.coreSettings, accessToken); this.currentSongSource = this.WhenAnyValue(x => x.IsLocal, x => x.IsYoutube, x => x.IsSoundCloud, (local, youtube, soundcloud) => { if (local) { return (ISongSourceViewModel)this.LocalViewModel; } if (youtube) { return this.YoutubeViewModel; } if (soundcloud) { return this.SoundCloudViewModel; } return this.LocalViewModel; }) .ToProperty(this, x => x.CurrentSongSource, null, ImmediateScheduler.Instance); this.MuteCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.IsAdmin)); this.MuteCommand.Subscribe(x => this.Volume = 0); this.UnMuteCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.IsAdmin)); this.UnMuteCommand.Subscribe(x => this.Volume = 1); this.canModifyWindow = this.library.LocalAccessControl.HasAccess(this.ViewSettings.WhenAnyValue(x => x.LockWindow), this.accessToken) .ToProperty(this, x => x.CanModifyWindow); this.isPlaying = this.library.PlaybackState .Select(x => x == AudioPlayerState.Playing) .ObserveOn(RxApp.MainThreadScheduler) .ToProperty(this, x => x.IsPlaying); this.currentTime = this.library.CurrentPlaybackTime .StartWith(TimeSpan.Zero) .Select(x => x.FormatAdaptive()) .ToProperty(this, x => x.CurrentTime); this.currentSeconds = this.library.CurrentPlaybackTime .Select(x => (int)x.TotalSeconds) .ToProperty(this, x => x.CurrentSeconds); this.totalTime = this.library.TotalTime .Select(x => x.FormatAdaptive()) .ToProperty(this, x => x.TotalTime); this.totalSeconds = this.library.TotalTime .Select(x => (int)x.TotalSeconds) .ToProperty(this, x => x.TotalSeconds); this.volume = this.library.WhenAnyValue(x => x.Volume, x => (double)x) .ToProperty(this, x => x.Volume); this.AddPlaylistCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.CanAlterPlaylist)); this.AddPlaylistCommand.Subscribe(x => this.AddPlaylist()); this.Playlists = this.library.Playlists.CreateDerivedCollection(this.CreatePlaylistViewModel, x => x.Dispose()); this.ShowSettingsCommand = ReactiveCommand.Create(); this.ShowSettingsCommand.Subscribe(x => this.SettingsViewModel.HandleSettings()); this.ShufflePlaylistCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.CanAlterPlaylist)); this.ShufflePlaylistCommand.Subscribe(x => this.library.ShufflePlaylist(this.accessToken)); IObservable<bool> canPlay = this.WhenAnyValue(x => x.CurrentPlaylist.SelectedEntries) .CombineLatest(this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockPlayPause), this.accessToken), this.library.LoadedSong, this.library.PlaybackState, (selectedPlaylistEntries, hasPlayAccess, loadedSong, playBackState) => // The admin can always play, but if we are in party mode, we have to check // whether it is allowed to play hasPlayAccess && // If exactly one song is selected, the command can be executed (selectedPlaylistEntries != null && selectedPlaylistEntries.Count() == 1 || // If the current song is paused, the command can be executed (loadedSong != null || playBackState == AudioPlayerState.Paused))); this.PlayCommand = ReactiveCommand.CreateAsyncTask(canPlay, async _ => { if (await this.library.PlaybackState.FirstAsync() == AudioPlayerState.Paused || await this.library.LoadedSong.FirstAsync() != null) { await this.library.ContinueSongAsync(this.accessToken); } else { await this.library.PlaySongAsync(this.CurrentPlaylist.SelectedEntries.First().Index, this.accessToken); } }); this.PlayOverrideCommand = ReactiveCommand.CreateAsyncTask(this.WhenAnyValue(x => x.CurrentPlaylist.SelectedEntries) .CombineLatest(this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockPlayPause), this.accessToken), (selectedPlaylistEntries, hasAccess) => hasAccess && (selectedPlaylistEntries != null && selectedPlaylistEntries.Count() == 1)), _ => this.library.PlaySongAsync(this.CurrentPlaylist.SelectedEntries.First().Index, this.accessToken)); this.PauseCommand = ReactiveCommand.CreateAsyncTask(this.library.LocalAccessControl.HasAccess(this.coreSettings.WhenAnyValue(x => x.LockPlayPause), this.accessToken) .CombineLatest(this.WhenAnyValue(x => x.IsPlaying), (hasAccess, isPlaying) => hasAccess && isPlaying), _ => this.library.PauseSongAsync(this.accessToken)); var pauseOrContinueCommand = this.WhenAnyValue(x => x.IsPlaying) .Select(x => x ? this.PauseCommand : this.PlayCommand).Publish(null); pauseOrContinueCommand.Connect(); this.PauseContinueCommand = ReactiveCommand.CreateAsyncTask( pauseOrContinueCommand.Select(x => x.CanExecuteObservable).Switch().ObserveOn(RxApp.MainThreadScheduler), async _ => { IReactiveCommand<Unit> command = await pauseOrContinueCommand.FirstAsync(); await command.ExecuteAsync(); }); this.EditPlaylistNameCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.CanAlterPlaylist, x => x.CurrentPlaylist, (x1, x2) => x1 && !x2.Model.IsTemporary)); this.EditPlaylistNameCommand.Subscribe(x => this.CurrentPlaylist.EditName = true); this.RemovePlaylistCommand = ReactiveCommand.Create(this.WhenAnyValue(x => x.CurrentEditedPlaylist, x => x.CurrentPlaylist, x => x.CanAlterPlaylist, (currentEditedPlaylist, currentPlaylist, canAlterPlaylist) => (currentEditedPlaylist != null || currentPlaylist != null) && canAlterPlaylist)); this.RemovePlaylistCommand.Subscribe(x => this.RemoveCurrentPlaylist()); this.IsLocal = true; }
public void LocalSmokeTest() { var settings = new CoreSettings(); var accessControl = new AccessControl(settings); Guid token = accessControl.RegisterLocalAccessToken(); accessControl.VerifyAccess(token, false); accessControl.SetLocalPassword(token, "password123"); accessControl.DowngradeLocalAccess(token); Assert.Throws<AccessException>(() => accessControl.VerifyAccess(token)); }
public void UpdatesRemoteAccessWhenLockRemoteSettingChanges() { var settings = new CoreSettings { LockRemoteControl = false }; var accessControl = new AccessControl(settings); Guid remoteToken = accessControl.RegisterRemoteAccessToken(new Guid()); Guid adminToken = accessControl.RegisterLocalAccessToken(); var permissions = accessControl.ObserveAccessPermission(remoteToken).CreateCollection(); settings.LockRemoteControl = true; accessControl.SetRemotePassword(adminToken, "password"); settings.LockRemoteControl = false; settings.LockRemoteControl = true; Assert.Equal(new[] { AccessPermission.Admin, AccessPermission.Guest, AccessPermission.Admin, AccessPermission.Guest }, permissions); }
public async Task StoresAnalyticsToken() { var coreSettings = new CoreSettings { EnableAutomaticReports = true, AnalyticsToken = null }; var client = new AnalyticsClient(Substitute.For<IAnalyticsEndpoint>()); await client.InitializeAsync(coreSettings); Assert.NotNull(coreSettings.AnalyticsToken); }
public LibraryBuilder WithSettings(CoreSettings settings) { this.settings = settings; return this; }