public void MakesSpaceAvailableForNextTransmission()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider())
                {
                    Capacity = 1
                };

                storage.Enqueue(() => new Transmission(new Uri("any://address"), new byte[1], "any/content", "any/encoding"));

                storage.Dequeue();

                Assert.True(storage.Enqueue(() => new StubTransmission()));
            }
            public void SavesTransmissionFileAfterPreviousUnsuccessfullAttempt()
            {
                var storage = new TransmissionStorage {
                    Capacity = 0
                };

                storage.Initialize(new StubApplicationFolderProvider());
                storage.Enqueue(() => new StubTransmission());

                storage.Capacity = 1;

                Assert.IsTrue(storage.Enqueue(() => new StubTransmission()));
            }
            public void DoesNotMakeMoreSpaceAvailableWhenTransmissionCouldNotBeDequeued()
            {
                var storage = new TransmissionStorage {
                    Capacity = 0
                };

                storage.Initialize(new StubApplicationFolderProvider());
                storage.Enqueue(() => new StubTransmission());

                storage.Dequeue();

                Assert.IsFalse(storage.Enqueue(() => new StubTransmission()));
            }
            public void SavesTransmissionToTheNewlyCreatedFile()
            {
                string     writtenContents = null;
                StubStream fileStream      = new StubStream();

                fileStream.OnDispose = disposing =>
                {
                    writtenContents = Encoding.UTF8.GetString(fileStream.ToArray());
                };

                var file = new StubPlatformFile {
                    OnOpen = () => fileStream
                };
                var folder = new StubPlatformFolder {
                    OnCreateFile = fileName => file
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage();

                storage.Initialize(provider);

                byte[] contents     = Encoding.UTF8.GetBytes(Path.GetRandomFileName());
                var    transmission = new StubTransmission(contents);

                storage.Enqueue(() => transmission);

                string encodedContent = writtenContents.Split(Environment.NewLine.ToCharArray()).Last();

                AssertEx.AreEqual(contents, Convert.FromBase64String(encodedContent));
            }
            // Uncomment this integration test only during investigations.
            // Create unit tests to test for specific error conditions it uncovers.
            // [TestMethod]
            public void IsThreadSafe()
            {
                const int NumberOfThreads = 16;
                const int NumberOfFilesPerThread = 64;
                var storage = new TransmissionStorage();
                storage.Initialize(new ApplicationFolderProvider());

                try
                {
                    string s = new string('c', 500);
                    byte[] content = Encoding.Unicode.GetBytes(s);

                    var tasks = new Task[NumberOfThreads];
                    for (int t = 0; t < tasks.Length; t++)
                    {
                        tasks[t] = TaskEx.Run(async () =>
                        {
                            await TaskEx.Delay(new Random(t).Next(50));
                            for (int f = 0; f < NumberOfFilesPerThread; f++)
                            {
                                storage.Enqueue(() => new Transmission(new Uri("http://address"), content, string.Empty, string.Empty));
                                storage.Dequeue();
                            }
                        });
                    }

                    TaskEx.WhenAll(tasks).GetAwaiter().GetResult();
                }
                finally
                {
                    while (storage.Dequeue() != null)
                    {
                    }
                }
            }
            public void ReturnsFalseAndDoesNotSaveTransmissionWhenStorageCapacityIsAlreadyExceeded()
            {
                StubPlatformFile existingFile = CreateTransmissionFile(default(Uri), new byte[42]);

                bool fileCreated          = false;
                StubPlatformFolder folder = CreateFolder(existingFile);

                folder.OnCreateFile = name =>
                {
                    fileCreated = true;
                    return(new StubPlatformFile());
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage {
                    Capacity = 10
                };

                storage.Initialize(provider);

                bool result = storage.Enqueue(() => new StubTransmission());

                Thread.Sleep(20);

                Assert.IsFalse(fileCreated, "file created");
                Assert.IsFalse(result);
            }
            // Uncomment this integration test only during investigations.
            // Create unit tests to test for specific error conditions it uncovers.
            // [TestMethod]
            public void IsThreadSafe()
            {
                const int NumberOfThreads        = 16;
                const int NumberOfFilesPerThread = 64;
                var       storage = new TransmissionStorage(new ApplicationFolderProvider());

                try
                {
                    string s       = new string('c', 500);
                    byte[] content = Encoding.Unicode.GetBytes(s);

                    var tasks = new Task[NumberOfThreads];
                    for (int t = 0; t < tasks.Length; t++)
                    {
                        tasks[t] = TaskEx.Run(async() =>
                        {
                            await TaskEx.Delay(new Random(t).Next(50));
                            for (int f = 0; f < NumberOfFilesPerThread; f++)
                            {
                                storage.Enqueue(() => new Transmission(new Uri("http://address"), content, string.Empty, string.Empty));
                                storage.Dequeue();
                            }
                        });
                    }

                    TaskEx.WhenAll(tasks).GetAwaiter().GetResult();
                }
                finally
                {
                    while (storage.Dequeue() != null)
                    {
                    }
                }
            }
            public void ReturnsFalseDoesNotEnqueueIfProcessHasNoRightToListFilesInApplicationFolder()
            {
                var folder = new StubPlatformFolder {
                    OnGetFiles = () => { throw new UnauthorizedAccessException(); }
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.False(result);
            }
            public void ReturnsFalseWhenTransmissionGetterReturnedNullIndicatingNoMoreTransmissionsInBuffer()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider());

                bool result = storage.Enqueue(() => null);

                Assert.False(result);
            }
            public void ReturnsFalseWhenPreviousTransmissionExceedsCapacity()
            {
                StubPlatformFolder folder = CreateFolder();
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider)
                {
                    Capacity = 10
                };

                bool firstTransmissionSaved  = storage.Enqueue(() => new Transmission(new Uri("any://address"), new byte[42], string.Empty, string.Empty));
                bool secondTransmissionSaved = storage.Enqueue(() => new Transmission(new Uri("any://address"), new byte[42], string.Empty, string.Empty));

                Assert.True(firstTransmissionSaved);
                Assert.False(secondTransmissionSaved);
            }
            public void ReturnsTrueWhenTransmissionIsSavedSuccessfully()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider());

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.True(result);
            }
            public void ReturnsFalseIfApplicationFolderIsNotAvailable()
            {
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => null
                };
                var storage = new TransmissionStorage(provider);

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.False(result);
            }
            public void CreatesFilesWithUniqueNamesToPreventConflictsWithOtherThreads()
            {
                var actualFileNames = new List <string>();
                var folder          = new StubPlatformFolder
                {
                    OnCreateFile = fileName =>
                    {
                        actualFileNames.Add(fileName);
                        return(new StubPlatformFile());
                    }
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());
                storage.Enqueue(() => new StubTransmission());

                Assert.NotEqual(actualFileNames[0], actualFileNames[1]);
            }
            public void DoesNotRemoveTransmissionFromBufferIfStorageCapacityIsExceededToAvoidDroppingData()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider())
                {
                    Capacity = 0
                };
                bool transmissionRemovedFromBuffer = false;

                storage.Enqueue(() =>
                {
                    transmissionRemovedFromBuffer = true;
                    return(new StubTransmission());
                });

                Assert.False(transmissionRemovedFromBuffer);
            }
            public void DoesNotRemoveTransmissionFromBufferIfApplicationFolderIsNotAvailableToAvoidDroppingData()
            {
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => null
                };
                var  storage = new TransmissionStorage(provider);
                bool transmissionRemovedFromBuffer = false;

                storage.Enqueue(() =>
                {
                    transmissionRemovedFromBuffer = true;
                    return(new StubTransmission());
                });

                Assert.False(transmissionRemovedFromBuffer);
            }
            public void HandlesFileNotFoundExceptionThrownWhenCalculatingSizeBecauseTransmissionHasAlreadyBeenDequeued()
            {
                var file = new StubPlatformFile();

                file.OnGetName   = () => "Dequeued" + TransmissionStorage.TransmissionFileExtension;
                file.OnGetLength = () => { throw new FileNotFoundException(); };
                StubPlatformFolder folder = CreateFolder(file);
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider);

                bool transmissionEnqueued = storage.Enqueue(() => new StubTransmission());

                Assert.True(transmissionEnqueued);
            }
            public void ReturnsFalseIfProcessHasNoRightToWriteToFilesInApplicationFolder()
            {
                var file = new StubPlatformFile {
                    OnOpen = () => { throw new UnauthorizedAccessException(); }
                };
                var folder = new StubPlatformFolder {
                    OnCreateFile = name => file
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider);

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.False(result);
            }
            public void ChangesTemporaryExtensionToPermanentToMakeFileAvailableForDequeueAsync()
            {
                string           permanentFileName = null;
                StubPlatformFile file = CreateFile("TemporaryFile");

                file.OnRename = desiredName => permanentFileName = desiredName;
                var folder = new StubPlatformFolder {
                    OnCreateFile = fileName => file
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());

                Assert.True(permanentFileName.EndsWith(TransmissionStorage.TransmissionFileExtension, StringComparison.OrdinalIgnoreCase));
            }
            public void CreatesNewFileWithTemporaryExtensionToPreventConflictsWithDequeueAsync()
            {
                string temporaryFileName = null;
                var    folder            = new StubPlatformFolder
                {
                    OnCreateFile = fileName =>
                    {
                        temporaryFileName = fileName;
                        return(new StubPlatformFile());
                    }
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());

                Assert.True(temporaryFileName.EndsWith(TransmissionStorage.TemporaryFileExtension, StringComparison.OrdinalIgnoreCase));
            }
            public void ClosesFileStreamToEnsureChangesAreCommittedToDisk()
            {
                bool fileStreamDisposed = false;
                var  fileStream         = new StubStream {
                    OnDispose = disposing => fileStreamDisposed = true
                };
                var file = new StubPlatformFile {
                    OnOpen = () => fileStream
                };
                var folder = new StubPlatformFolder {
                    OnCreateFile = fileName => file
                };
                var provider = new StubApplicationFolderProvider {
                    OnGetApplicationFolder = () => folder
                };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());

                Assert.True(fileStreamDisposed);
            }
            public void DoesNotMakeMoreSpaceAvailableWhenTransmissionCouldNotBeDequeued()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider()) { Capacity = 0 };
                storage.Enqueue(() => new StubTransmission());

                storage.Dequeue();

                Assert.False(storage.Enqueue(() => new StubTransmission()));
            }
            public void MakesSpaceAvailableForNextTransmission()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider()) { Capacity = 1 };
                storage.Enqueue(() => new Transmission(new Uri("any://address"), new byte[1], "any/content", "any/encoding"));

                storage.Dequeue();

                Assert.True(storage.Enqueue(() => new StubTransmission()));
            }
            public void DoesNotRemoveTransmissionFromBufferIfStorageCapacityIsExceededToAvoidDroppingData()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider()) { Capacity = 0 };
                bool transmissionRemovedFromBuffer = false;

                storage.Enqueue(() =>
                {
                    transmissionRemovedFromBuffer = true;
                    return new StubTransmission();
                });

                Assert.False(transmissionRemovedFromBuffer);
            }
            public void DoesNotRemoveTransmissionFromBufferIfApplicationFolderIsNotAvailableToAvoidDroppingData()
            {
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => null };
                var storage = new TransmissionStorage(provider);
                bool transmissionRemovedFromBuffer = false;

                storage.Enqueue(() =>
                {
                    transmissionRemovedFromBuffer = true;
                    return new StubTransmission();
                });

                Assert.False(transmissionRemovedFromBuffer);
            }
            public void ReturnsFalseWhenTransmissionGetterReturnedNullIndicatingNoMoreTransmissionsInBuffer()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider());

                bool result = storage.Enqueue(() => null);

                Assert.False(result);
            }
            public void ChangesTemporaryExtensionToPermanentToMakeFileAvailableForDequeueAsync()
            {
                string permanentFileName = null;
                StubPlatformFile file = CreateFile("TemporaryFile");
                file.OnRename = desiredName => permanentFileName = desiredName;
                var folder = new StubPlatformFolder { OnCreateFile = fileName => file };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());

                Assert.True(permanentFileName.EndsWith(TransmissionStorage.TransmissionFileExtension, StringComparison.OrdinalIgnoreCase));
            }
            public void ReturnsFalseIfApplicationFolderIsNotAvailable()
            {
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => null };
                var storage = new TransmissionStorage(provider);

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.False(result);
            }
            public void SavesTransmissionFileAfterPreviousUnsuccessfullAttempt()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider()) { Capacity = 0 };
                storage.Enqueue(() => new StubTransmission());

                storage.Capacity = 1;

                Assert.True(storage.Enqueue(() => new StubTransmission()));
            }
            public void HandlesFileNotFoundExceptionThrownWhenCalculatingSizeBecauseTransmissionHasAlreadyBeenDequeued()
            {
                var file = new StubPlatformFile();
                file.OnGetName = () => "Dequeued" + TransmissionStorage.TransmissionFileExtension;
                file.OnGetLength = () => { throw new FileNotFoundException(); };
                StubPlatformFolder folder = CreateFolder(file);
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                bool transmissionEnqueued = storage.Enqueue(() => new StubTransmission());

                Assert.True(transmissionEnqueued);
            }
            public void ReturnsFalseWhenPreviousTransmissionExceedsCapacity()
            {
                StubPlatformFolder folder = CreateFolder();
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider) { Capacity = 10 };

                bool firstTransmissionSaved = storage.Enqueue(() => new Transmission(new Uri("any://address"), new byte[42], string.Empty, string.Empty));
                bool secondTransmissionSaved = storage.Enqueue(() => new Transmission(new Uri("any://address"), new byte[42], string.Empty, string.Empty));

                Assert.True(firstTransmissionSaved);
                Assert.False(secondTransmissionSaved);
            }
            public void ReturnsFalseAndDoesNotSaveTransmissionWhenStorageCapacityIsAlreadyExceeded()
            {
                StubPlatformFile existingFile = CreateTransmissionFile(default(Uri), new byte[42]);

                bool fileCreated = false;
                StubPlatformFolder folder = CreateFolder(existingFile);
                folder.OnCreateFile = name =>
                {
                    fileCreated = true;
                    return new StubPlatformFile();
                };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider) { Capacity = 10 };

                bool result = storage.Enqueue(() => new StubTransmission());
                Thread.Sleep(20);

                Assert.False(fileCreated, "filecreated");
                Assert.False(result);
            }
            public void ReturnsTrueWhenTransmissionIsSavedSuccessfully()
            {
                var storage = new TransmissionStorage(new StubApplicationFolderProvider());

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.True(result);
            }
            public void CreatesFilesWithUniqueNamesToPreventConflictsWithOtherThreads()
            {
                var actualFileNames = new List<string>();
                var folder = new StubPlatformFolder
                {
                    OnCreateFile = fileName =>
                    {
                        actualFileNames.Add(fileName);
                        return new StubPlatformFile();
                    }
                };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());
                storage.Enqueue(() => new StubTransmission());

                Assert.NotEqual(actualFileNames[0], actualFileNames[1]);
            }
            public void ReturnsFalseDoesNotEnqueueIfProcessHasNoRightToListFilesInApplicationFolder()
            {
                var folder = new StubPlatformFolder { OnGetFiles = () => { throw new UnauthorizedAccessException(); } };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.False(result);
            }
            public void CreatesNewFileWithTemporaryExtensionToPreventConflictsWithDequeueAsync()
            {
                string temporaryFileName = null;
                var folder = new StubPlatformFolder
                {
                    OnCreateFile = fileName =>
                    {
                        temporaryFileName = fileName;
                        return new StubPlatformFile();
                    }
                };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());

                Assert.True(temporaryFileName.EndsWith(TransmissionStorage.TemporaryFileExtension, StringComparison.OrdinalIgnoreCase));
            }
            public void ReturnsFalseIfProcessHasNoRightToWriteToFilesInApplicationFolder()
            {
                var file = new StubPlatformFile { OnOpen = () => { throw new UnauthorizedAccessException(); } };
                var folder = new StubPlatformFolder { OnCreateFile = name => file };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                bool result = storage.Enqueue(() => new StubTransmission());

                Assert.False(result);
            }
            public void ClosesFileStreamToEnsureChangesAreCommittedToDisk()
            {
                bool fileStreamDisposed = false;
                var fileStream = new StubStream { OnDispose = disposing => fileStreamDisposed = true };
                var file = new StubPlatformFile { OnOpen = () => fileStream };
                var folder = new StubPlatformFolder { OnCreateFile = fileName => file };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                storage.Enqueue(() => new StubTransmission());
                
                Assert.True(fileStreamDisposed);
            }
            public void SavesTransmissionToTheNewlyCreatedFile()
            {
                string writtenContents = null;
                StubStream fileStream = new StubStream();
                fileStream.OnDispose = disposing =>
                {
                    writtenContents = Encoding.UTF8.GetString(fileStream.ToArray());
                };

                var file = new StubPlatformFile { OnOpen = () => fileStream };
                var folder = new StubPlatformFolder { OnCreateFile = fileName => file };
                var provider = new StubApplicationFolderProvider { OnGetApplicationFolder = () => folder };
                var storage = new TransmissionStorage(provider);

                byte[] contents = Encoding.UTF8.GetBytes(Path.GetRandomFileName());
                var transmission = new StubTransmission(contents);
                storage.Enqueue(() => transmission);
                
                string encodedContent = writtenContents.Split(Environment.NewLine.ToCharArray()).Last();
                Assert.Equal(contents, Convert.FromBase64String(encodedContent));
            }