public async Task DownloadCalledOnceOnCacheUpdate() { var f = new dummyFile(); f.GetStream = () => { var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); Debug.WriteLine("Just called GetStream"); return(Observable.Return(new StreamReader(mr))); }; var dc = new dummyCache(); await f.SaveFileInCache(DateTime.Now.ToString(), new byte[] { 0, 1 }, dc); var vm = new FileDownloadController(f, dc); int isDownloadingCounter = 0; vm.WhenAny(x => x.IsDownloading, x => x.Value) .Subscribe(_ => isDownloadingCounter++); var dummy = vm.IsDownloaded; var dummy1 = vm.IsDownloading; vm.DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => f.GetStreamCalled == 1, 1000); Assert.AreEqual(1, f.GetStreamCalled); }
public async Task CheckTest2() { var data = await TestUtils.GetFileAsBytes("test2.pdf"); var f = new dummyFile(); f.GetStream = () => { throw new InvalidOperationException(); }; // Install original data in cache var dc = new dummyCache(); await f.SaveFileInCache(f.DateToReturn, data, dc); // Create VM's and hook them up. var vm = new FileDownloadController(f, dc); var pf = new PDFFile(vm); var dummy1 = pf.NumberOfPages; // Start it off vm.DownloadOrUpdate.Execute(null); await pf.WhenAny(x => x.NumberOfPages, y => y.Value) .Where(y => y != 0) .Take(1) .Timeout(TimeSpan.FromSeconds(1), Observable.Return(0)) .FirstAsync(); Assert.AreEqual(6, pf.NumberOfPages); // Now, make sure that we still get a "1" out of the update guy. }
/// <summary> /// Generate a number of MakeDownloaders. /// </summary> /// <param name="count"></param> /// <returns></returns> private static async Task <PDFFile[]> MakeDownloaders(int count) { // In this test we make sure not to access the # of pages. Func <Task <PDFFile> > creator = async() => { var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); f.GetStream = () => { return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); vm.DownloadOrUpdate.Execute(null); return(new PDFFile(vm)); }; List <PDFFile> r = new List <PDFFile>(); for (int i = 0; i < count; i++) { r.Add(await creator()); } return(r.ToArray()); }
public async Task CheckDateCalledOnceCacheFilled() { var f = new dummyFile(); f.GetStream = () => { var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); return(Observable.Return(new StreamReader(mr))); }; var dc = new dummyCache(); await f.SaveFileInCache(f.DateToReturn, new byte[] { 0, 1, 2 }, dc); var vm = new FileDownloadController(f, dc); int isDownloadingCounter = 0; vm.WhenAny(x => x.IsDownloading, x => x.Value) .Subscribe(_ => isDownloadingCounter++); var dummy = vm.IsDownloaded; var dummy1 = vm.IsDownloading; vm.DownloadOrUpdate.Execute(null); Assert.AreEqual(1, f.GetDateCalled); }
public async Task MonitorPageUpdateLateRenderRequest() { // In this test we make sure not to access the # of pages. var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); f.GetStream = () => { return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); var pf = new PDFFile(vm); // Setup the look before we setup the render. var pupdatetmp = pf.GetPageStreamAndCacheInfo(5).Timeout(TimeSpan.FromSeconds(5)).FirstAsync(); vm.DownloadOrUpdate.Execute(null); var pupdate = await pupdatetmp; // Make sure what came back looks ok! Assert.IsNotNull(pupdate); var page = await pupdate.Item2.FirstAsync(); Assert.AreEqual(5, (int)page.Index); }
public async Task TriggerSuccessfulFileDownloadCached() { var f = new dummyFile(); var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); f.GetStream = () => Observable.Return(new StreamReader(mr)); var dc = new dummyCache(); await f.SaveFileInCache(DateTime.Now.ToString(), new byte[] { 0, 1, 2 }, dc); var vm = new FileDownloadController(f, dc); var dummy = vm.IsDownloaded; int downloadUpdateCount = 0; vm.FileDownloadedAndCached.Subscribe(_ => downloadUpdateCount++); vm.DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => vm.IsDownloaded == true, 1000); Assert.IsTrue(vm.IsDownloaded); await TestUtils.SpinWait(() => downloadUpdateCount == 1, 1000); Assert.AreEqual(1, downloadUpdateCount); }
public async Task CheckDateCalledOnceCacheEmpty() { var f = new dummyFile(); f.GetStream = () => { var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); return(Observable.Return(new StreamReader(mr))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); int isDownloadingCounter = 0; vm.WhenAny(x => x.IsDownloading, x => x.Value) .Subscribe(_ => isDownloadingCounter++); var dummy = vm.IsDownloaded; var dummy1 = vm.IsDownloading; vm.DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => f.GetDateCalled == 0, 100); await Task.Delay(100); // Just in case. :-) Assert.AreEqual(0, f.GetDateCalled); }
public async Task DownloadOccursWhenAsked() { // The file - we can use dummy data b.c. we aren't feeding it to the PDF renderer. var f = new dummyFile(); var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); f.GetStream = () => Observable.Return(new StreamReader(mr)); var dc = new dummyCache(); var fucVM = new FileUserControlViewModel(f, dc); // Simulate the subscription setups var t = fucVM.IsDownloading; var fc = fucVM.FileNotCachedOrDownloading; fucVM.OnLoaded.Execute(null); // Nothing downloaded, nothing in cache. Assert.IsTrue(fucVM.FileNotCachedOrDownloading); Assert.IsFalse(fucVM.IsDownloading); // Trigger the download Debug.WriteLine("Triggering the download"); fucVM.ClickedUs.Execute(null); // This should be an immediate download in this test, so look for it. await TestUtils.SpinWait(() => fucVM.FileNotCachedOrDownloading == false, 1000); Assert.IsFalse(fucVM.FileNotCachedOrDownloading); Assert.IsFalse(fucVM.IsDownloading); }
public async Task MonitorPageUpdateEarlyRenderRequest() { // In this test we make sure not to access the # of pages. var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); f.GetStream = () => { return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); var pf = new PDFFile(vm); // Run the download (which will complete synchronously here), and then schedule the watch // for new items. vm.DownloadOrUpdate.Execute(null); var pupdate = await pf.GetPageStreamAndCacheInfo(5).Timeout(TimeSpan.FromSeconds(5)).FirstAsync(); // Make sure all that came back is ok. Assert.IsNotNull(pupdate); var page = await pupdate.Item2.FirstAsync(); Assert.AreEqual(5, (int)page.Index); }
public async Task DownloadFileFromCacheNotThereYet() { var f = new dummyFile(); f.GetStream = () => { throw new InvalidOperationException(); }; // Install original data in cache var dc = new dummyCache(); var data = await TestUtils.GetFileAsBytes("test.pdf"); await f.SaveFileInCache(f.DateToReturn, data, dc); // Create VM's and hook them up. var vm = new FileDownloadController(f, dc); var pf = new PDFFile(vm); var dummy1 = pf.NumberOfPages; // Start it off Debug.WriteLine("FIring the download or update"); vm.DownloadOrUpdate.Execute(null); await pf.WhenAny(x => x.NumberOfPages, x => x.Value) .Where(x => x != 0) .Timeout(TimeSpan.FromSeconds(1), Observable.Return <int>(0)) .FirstAsync(); Assert.AreEqual(10, pf.NumberOfPages); }
public async Task CheckCacheLookupHappensOnce() { // When we have an item that is cached, we shouldn't do the full load // too many times, (once) when looking at only the page number. var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); f.GetStream = () => { throw new InvalidOperationException(); }; // Install original data in cache var dc = new dummyCache(); await f.SaveFileInCache(f.DateToReturn, data, dc); // Create VM's and hook them up. var vm = new FileDownloadController(f, dc); var pf = new PDFFile(vm); var dummy1 = pf.NumberOfPages; // Start it off vm.DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => pf.NumberOfPages == 10, 1000); // Now, make sure we did it only once. // TODO: Currently this is 2 b.c. there is a second lookup for a date, which also includes // going after the file data. This should get fixed and split the database up. Assert.AreEqual(3, dc.NumberTimesGetCalled); }
public async Task SizePerpareCausesErrorsIfCalledEarly() { // Get the size stuff ready, and then call it to make sure // there are no issues with doing the size calculation. // Get the infrastructure setup var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); f.GetStream = () => { return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); var pf = new PDFFile(vm); vm.DownloadOrUpdate.Execute(null); // Now, build the VM var pdfVM = new PDFPageViewModel(pf.GetPageStreamAndCacheInfo(1), dc); // Next, fire off the size thing. var r = pdfVM.CalcRenderingSize(IWalker.ViewModels.PDFPageViewModel.RenderingDimension.Horizontal, (double)100, (double)100); Assert.IsNull(r); }
public async Task ButtonNotGoodTillDownload() { // Build a PDF file that will only download after we ask it to. var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); f.GetStream = () => { return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); var pdf = new PDFFile(vm); // Open a single talk and see if we can see it open. var now = new TimePeriod(DateTime.Now, DateTime.Now + TimeSpan.FromSeconds(1000)); var exp = new ExpandingSlideThumbViewModel(pdf, now); // Make sure there are no slides - also primes the pump for Rx. Assert.IsNull(exp.TalkAsThumbs); await TestUtils.SpinWait(() => exp.CanShowThumbs == false, 1000); // Now, make sure that things go "true" after we fire off the file. vm.DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => exp.CanShowThumbs == true, 1000); }
public async Task WaitForFirstSlideAfterReady() { // Get the dummy file and input real PDF data. // Hook it up to the download controller var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); f.GetStream = () => { return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var fdc = new FileDownloadController(f, dc); var pf = new PDFFile(fdc); var dummy1 = pf.NumberOfPages; // Run the download fdc.DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => pf.NumberOfPages != 0, 1000); // The first spin guy var hero = new FirstSlideHeroViewModel(pf, null); // Make sure the thing is ready now. await TestUtils.SpinWait(() => hero.HeroPageUC != null, 1000); }
public async Task LoadVMButNoImageLoad() { // WHen this VM isn't attached to a actual View, we should not // trigger any loading or similar. All should remain very quiet. // (e.g. lazy loading). // Get the infrastructure setup var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); int timesLoaded = 0; f.GetStream = () => { timesLoaded++; return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); vm.DownloadOrUpdate.Execute(null); var pf = new PDFFile(vm); // Now, build the VM var pdfVM = new PDFPageViewModel(pf.GetPageStreamAndCacheInfo(1), dc); await TestUtils.SpinWait(() => timesLoaded != 0, 1000); Assert.AreEqual(1, timesLoaded); Assert.AreEqual(0, dc.NumberTimesGetCalled); }
public async Task MakeSureNothingRenderedWhenImageCached() { // The exact image we need is in the cache. So we should never make a // request to load the PDF file or PdfDocument. // Get the infrastructure setup var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); int loaderCalled = 0; f.GetStream = () => { loaderCalled++; throw new InvalidOperationException(); }; // Create the cache, and add everything into it that the system should need. var dc = new dummyCache(); await f.SaveFileInCache(f.DateToReturn, data, dc); var dt = await f.GetCacheCreateTime(dc); var pageSize = new IWalkerSize() { Width = 1280, Height = 720 }; await dc.InsertObject(string.Format("{0}-{1}-p1-DefaultPageSize", f.UniqueKey, dt.Value.ToString()), pageSize); var imageData = new byte[] { 0, 1, 2, 3, 4 }; await dc.Insert(string.Format("{0}-{1}-p1-w100-h56", f.UniqueKey, dt.Value), imageData); Debug.WriteLine("Setup is done, and data has been inserted into the cache. Testing starting"); // Create the rest of the infrastructure. var vm = new FileDownloadController(f, dc); var pf = new PDFFile(vm); // Now, build the VM var pdfVM = new PDFPageViewModel(pf.GetPageStreamAndCacheInfo(1), dc); // Subscribe so we can "get" the image. MemoryStream lastImage = null; pdfVM.ImageStream.Subscribe(img => lastImage = img); Assert.IsNull(lastImage); // Render, and make sure things "worked" pdfVM.RenderImage.Execute(Tuple.Create(IWalker.ViewModels.PDFPageViewModel.RenderingDimension.Horizontal, (double)100, (double)100)); vm.DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => lastImage != null, 2000); Assert.AreEqual(0, loaderCalled); Assert.IsNotNull(lastImage); Assert.AreEqual(4, dc.NumberTimesInsertCalled); // Nothing new should have happened }
public async Task RenderNormalRenderEarlyTrigger() { // Normal sequence of things when there is no image cached. // WHen this VM isn't attached to a actual View, we should not // trigger any loading or similar. All should remain very quiet. // (e.g. lazy loading). // Get the infrastructure setup var f = new dummyFile(); var data = await TestUtils.GetFileAsBytes("test.pdf"); int timesLoaded = 0; f.GetStream = () => { timesLoaded++; return(Observable.Return(new StreamReader(new MemoryStream(data)))); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); // It shouldn't matter where the download is triggered from - let it happen early // here before other things are hooked up. vm.DownloadOrUpdate.Execute(null); var pf = new PDFFile(vm); // Now, build the VM var pdfVM = new PDFPageViewModel(pf.GetPageStreamAndCacheInfo(1), dc); // Subscribe so we can "get" the image. MemoryStream lastImage = null; Debug.WriteLine("Subscribing to ImageStream"); pdfVM.ImageStream.Subscribe(img => { lastImage = img; Debug.WriteLine("Just got an image."); }); Assert.IsNull(lastImage); // Render, and make sure things "worked" Debug.WriteLine("Going to fire off a render request"); pdfVM.RenderImage.Execute(Tuple.Create(IWalker.ViewModels.PDFPageViewModel.RenderingDimension.Horizontal, (double)100, (double)100)); await TestUtils.SpinWait(() => timesLoaded != 0, 1000); await TestUtils.SpinWait(() => dc.NumberTimesGetCalled == 3, 1000); await TestUtils.SpinWait(() => lastImage != null, 1000); Assert.AreEqual(1, timesLoaded); Assert.AreEqual(3, dc.NumberTimesGetCalled); // Once for data, once for size cache, and once again for data file. Assert.IsNotNull(lastImage); }
public void CtorHasNothingAccessedNoCache() { var f = new dummyFile(); var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); Assert.AreEqual(0, f.GetDateCalled); Assert.AreEqual(0, f.GetStreamCalled); }
public async Task GetBytesAlreadyCached() { var dc = new dummyCache(); await dc.Insert("hi", new byte[] { 0, 1, 2 }).ToArray(); var r = await dc.GetOrFetch("hi", () => Observable.Return(new byte[0])); Assert.AreEqual(3, r.Length); Assert.AreEqual((byte)1, r[1]); }
public async Task GetBytesNotThereFail() { var dc = new dummyCache(); var r = await dc.GetOrFetch("hi", () => Observable.Throw <byte[]>(new NotImplementedException())) .Materialize() .ToArray(); Assert.AreEqual(1, r.Length); Assert.IsTrue(r[0].Kind == NotificationKind.OnError); }
public async Task CtorHasNothingAccessedCache() { var f = new dummyFile(); var dc = new dummyCache(); await f.SaveFileInCache(f.DateToReturn, new byte[] { 0, 1, 2, 3 }, dc); var vm = new FileDownloadController(f, dc); Assert.AreEqual(0, f.GetDateCalled); Assert.AreEqual(0, f.GetStreamCalled); }
public async Task GetBytesNotThere() { var dc = new dummyCache(); var r = await dc.GetOrFetch("hi", () => Observable.Return(new byte[0])) .Materialize() .ToArray(); Assert.AreEqual(2, r.Length); Assert.IsTrue(r[0].Kind == NotificationKind.OnNext); Assert.IsTrue(r[1].Kind == NotificationKind.OnCompleted); }
public async Task IsDownloadingSetDuringDownload() { // http://stackoverflow.com/questions/21588945/structuring-tests-or-property-for-this-reactive-ui-scenario var f = new dummyFile(); var getStreamSubject = new Subject <StreamReader>(); f.GetStream = () => { return(getStreamSubject); }; var dc = new dummyCache(); var fucVM = new FileUserControlViewModel(f, dc); // Simulate the subscriptions var t = fucVM.IsDownloading; var fc = fucVM.FileNotCachedOrDownloading; fucVM.OnLoaded.Execute(null); // Nothing downloaded, nothing in cache. Assert.IsTrue(fucVM.FileNotCachedOrDownloading); Assert.IsFalse(fucVM.IsDownloading); // Trigger the download Debug.WriteLine("Triggering the download"); fucVM.ClickedUs.Execute(null); // Nothing downloaded, nothing in cache. Assert.IsTrue(fucVM.FileNotCachedOrDownloading); Assert.IsTrue(fucVM.IsDownloading); // After it should have been downloaded, check again. await Task.Delay(20); Debug.WriteLine("Sending the data"); var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); getStreamSubject.OnNext(new StreamReader(mr)); getStreamSubject.OnCompleted(); // Give a chance for anything queued up to run by advancing the scheduler. await TestUtils.SpinWait(() => fucVM.IsDownloading == false, 1000); await TestUtils.SpinWait(() => fucVM.FileNotCachedOrDownloading == false, 1000); // And do an final check. Assert.IsFalse(fucVM.IsDownloading); Assert.IsFalse(fucVM.FileNotCachedOrDownloading); }
public async Task GetBytesWhatGoesInComesOut() { var dc = new dummyCache(); var r = await dc.GetOrFetch("hi", () => Observable.Return(new byte[] { 0, 1, 2, 3, 4 })); var r1 = await dc.GetOrFetch("hi", () => Observable.Return(new byte[] { 0 })); Assert.AreEqual(5, r1.Length); Assert.AreEqual(0, r1[0]); Assert.AreEqual(1, r1[1]); Assert.AreEqual(2, r1[2]); Assert.AreEqual(3, r1[3]); Assert.AreEqual(4, r1[4]); }
public async Task IsDownloadingFlipsCorrectly() { // http://stackoverflow.com/questions/21588945/structuring-tests-or-property-for-this-reactive-ui-scenario var f = new dummyFile(); var newSR = new Subject <StreamReader>(); f.GetStream = () => { return(newSR); }; var dc = new dummyCache(); var vm = new FileDownloadController(f, dc); var dummy = vm.IsDownloaded; var dummy1 = vm.IsDownloading; Assert.IsFalse(vm.IsDownloading); Assert.IsFalse(vm.IsDownloaded); // Fire off the download Debug.WriteLine("Starting download/update"); vm.DownloadOrUpdate.Execute(null); // Since the download is synchronous, it should get here just fine. await TestUtils.SpinWait(() => vm.IsDownloading == true, 1000); await TestUtils.SpinWait(() => vm.IsDownloaded == false, 1000); Assert.IsTrue(vm.IsDownloading); Assert.IsFalse(vm.IsDownloaded); Debug.WriteLine("Going to wait a bit here"); await Task.Delay(1000); // And now stuff the data in. Debug.WriteLine("Going to send the data one"); var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); newSR.OnNext(new StreamReader(mr)); newSR.OnCompleted(); Debug.WriteLine("Done sending the data along"); // And make sure it finishes. await TestUtils.SpinWait(() => vm.IsDownloaded == true, 1000); Assert.IsTrue(vm.IsDownloaded); Assert.IsFalse(vm.IsDownloading); }
public async Task FetchOnce() { // When not in cache, make sure it is fetched and updated in the cache. var ds = new dummyScreen(); var ms = new myMeetingListRef(); var dc = new dummyCache(); var t = new CategoryPageViewModel(ds, ms, dc); await TestUtils.SpinWait(() => dc.NumberTimesInsertCalled >= 1, 1000); var item = await dc.GetObject <IMeetingRefExtended[]>(ms.UniqueString); Assert.IsNotNull(item); Assert.AreEqual(2, item.Length); Assert.AreEqual("meeting1", item[0].Title); Assert.AreEqual("meeting2", item[1].Title); }
public async Task GetNewValueFetchFalse() { // Value is not in cache first. Event though we say no, it should still do the fetch. var dc = new dummyCache(); var rtn = await dc.GetAndFetchLatest("key", () => Observable.Return("hi there"), dt => Observable.Return(false)) .ToList() .Timeout(TimeSpan.FromMilliseconds(1000)) .FirstAsync(); // We should have gotten it back Assert.IsNotNull(rtn); Assert.AreEqual(1, rtn.Count); Assert.AreEqual("hi there", rtn[0]); // It should be in the cache. Assert.AreEqual("hi there", await dc.GetObject <string>("key")); }
public async Task UnderstandHowDummyCacheCausesProblems() { var f = new dummyFile(); var dc = new dummyCache(); var DownloadOrUpdate = ReactiveCommand.CreateAsyncObservable(_ => dc.GetCreatedAt(f.UniqueKey) .Select(dt => dt.HasValue)); var value = false; DownloadOrUpdate.Subscribe(_ => value = true); Assert.IsFalse(value); DownloadOrUpdate.Execute(null); await TestUtils.SpinWait(() => value == true, 2000); Assert.IsTrue(value); }
public async Task FileDownlaodedIsCached() { var f = new dummyFile(); var dc = new dummyCache(); await f.SaveFileInCache(DateTime.Now.ToString(), new byte[] { 0, 1 }, dc); var vm = new FileDownloadController(f, dc); bool value = false; var dispose = vm.WhenAny(x => x.IsDownloaded, y => y.Value) .Subscribe(v => value = v); await TestUtils.SpinWait(() => vm.IsDownloaded == true, 1000); await TestUtils.SpinWait(() => value == true, 1000); dispose.Dispose(); }
public async Task IsDownloadingWithAutoDownload() { Settings.AutoDownloadNewMeeting = true; // http://stackoverflow.com/questions/21588945/structuring-tests-or-property-for-this-reactive-ui-scenario var f = new dummyFile(); var getStreamSubject = new Subject <StreamReader>(); f.GetStream = () => { return(getStreamSubject); }; var dc = new dummyCache(); var fucVM = new FileUserControlViewModel(f, dc); // Simulate the subscribing var t = fucVM.IsDownloading; var fc = fucVM.FileNotCachedOrDownloading; fucVM.OnLoaded.Execute(null); // Nothing downloaded, nothing in cache. Assert.IsTrue(fucVM.FileNotCachedOrDownloading); Assert.IsTrue(fucVM.IsDownloading); await Task.Delay(20); var data = new byte[] { 0, 1, 2, 3 }; var mr = new MemoryStream(data); getStreamSubject.OnNext(new StreamReader(mr)); getStreamSubject.OnCompleted(); // It is amazing that we have to wait this long. await TestUtils.SpinWait(() => fucVM.IsDownloading == false, 400); await TestUtils.SpinWait(() => fucVM.FileNotCachedOrDownloading == false, 1000); // And do an final check. Assert.IsFalse(fucVM.IsDownloading); Assert.IsFalse(fucVM.FileNotCachedOrDownloading); }