public async Task TestNetworkDown() { var throwingApiAccess = new ThrowingFeatureToggleApiAccess(); IoCManager.RegisterInstance(typeof(IFeatureToggleApiAccess), throwingApiAccess); IFeatureToggleRouter router = await FeatureToggleRouter.CreateAsync(); foreach (var defaultEnabledFeatureId in FeatureConfiguration.DefaultEnabledFeatureIds) { var observer = new CachingObserver <bool>(); router.IsFeatureEnabled(defaultEnabledFeatureId).Subscribe(observer); Assert.IsTrue(observer.Last); } // Now generate some random disabled features and check whether // the router tells us that they are disabled var random = new Random(); for (var i = 0; i < 10;) { var featureId = random.Next(); if (FeatureConfiguration.DefaultEnabledFeatureIds.Contains((FeatureId)featureId)) { continue; } var observer = new CachingObserver <bool>(); router.IsFeatureEnabled((FeatureId)featureId).Subscribe(observer); Assert.IsFalse(observer.Last); i++; } }
public async Task TestFailingUpdate() { var random = new Random(); var nonDefaultEnabledFeatureId = random.Next(); while (FeatureConfiguration.DefaultEnabledFeatureIds.Contains((FeatureId)nonDefaultEnabledFeatureId)) { nonDefaultEnabledFeatureId = random.Next(); } var dummyApiAccess = new DummyFeatureToggleApiAccess { ReturnValue = new List <FeatureDto> { new FeatureDto(nonDefaultEnabledFeatureId, "Test", null, new List <int>(), new List <int>()) } }; IoCManager.RegisterInstance(typeof(IFeatureToggleApiAccess), dummyApiAccess); IFeatureToggleRouter router = await FeatureToggleRouter.CreateAsync(); var feature0Observer = new CachingObserver <bool>(); router.IsFeatureEnabled((FeatureId)nonDefaultEnabledFeatureId).Subscribe(feature0Observer); Assert.IsTrue(feature0Observer.Last); // Make network fail, make sure no change is made and value doesn't revert to default // state (disabled) IoCManager.RegisterInstance(typeof(IFeatureToggleApiAccess), new ThrowingFeatureToggleApiAccess()); await router.RefreshEnabledFeaturesAsync(); Assert.IsTrue(feature0Observer.Last); }
public async Task TestSuccessfulUpdate() { var dummyApiAccess = new DummyFeatureToggleApiAccess { ReturnValue = new List <FeatureDto> { new FeatureDto(0, "Test", null, new List <int>(), new List <int>()) } }; IoCManager.RegisterInstance(typeof(IFeatureToggleApiAccess), dummyApiAccess); IFeatureToggleRouter router = await FeatureToggleRouter.CreateAsync(); var feature0Observer = new CachingObserver <bool>(); var feature1Observer = new CachingObserver <bool>(); router.IsFeatureEnabled(0).Subscribe(feature0Observer); router.IsFeatureEnabled((FeatureId)1).Subscribe(feature1Observer); Assert.IsTrue(feature0Observer.Last); Assert.IsFalse(feature1Observer.Last); // Swap feature states dummyApiAccess.ReturnValue = new List <FeatureDto> { new FeatureDto(1, "Test", null, new List <int>(), new List <int>()) }; await router.RefreshEnabledFeaturesAsync(); Assert.IsFalse(feature0Observer.Last); Assert.IsTrue(feature1Observer.Last); }
public void Test() { var observable = new Observable <bool>(false); var caching = new CachingObserver <bool>(); observable.Subscribe(caching); Assert.IsFalse(caching.Last); observable.Current = true; Assert.IsTrue(caching.Last); }
private void StartAutoCheckForAchievements() { if (Interlocked.Exchange(ref isAutoChecking, 1) == 1) { return; } var featureObserver = new CachingObserver <bool>(); achievementFeatureSubscription = IoCManager.Resolve <IFeatureToggleRouter>() .IsFeatureEnabled(FeatureId.Achievements) .Subscribe(featureObserver); async Task DequeueAndRepeatAsync() { try { if (featureObserver.Last /* feature is enabled */) { await BackupData.WaitForInitAsync(); var pending = await AchievementManager.DequeuePendingAchievementNotifications(); AchievementNotification.QueueAchievementNotifications(pending); } } catch (InvalidTransactionException) { // Safe to ignore in this case, just retry later. // This can happen because the auto-refresh can interleave // with other transactions that execute asynchronous code // inside them. } await Task.Delay(5000); if (isAutoChecking == 1) { Device.BeginInvokeOnMainThread(async() => await DequeueAndRepeatAsync()); } } Device.BeginInvokeOnMainThread(async() => await DequeueAndRepeatAsync()); }