public void StoreMergedRepositoryWhenDifferent()
        {
            const string transferCode = "abcdefgh";
            SerializeableCloudStorageCredentials credentialsFromSession = new SerializeableCloudStorageCredentials();
            var settingsModel = CreateSettingsModel(transferCode);
            NoteRepositoryModel repositoryModelLocal = new NoteRepositoryModel();

            repositoryModelLocal.Notes.Add(new NoteModel());
            NoteRepositoryModel repositoryModelCloud = new NoteRepositoryModel();

            repositoryModelCloud.Notes.Add(new NoteModel());

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <SerializeableCloudStorageCredentials>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudStorageCredentials.ToInt()))).
            Returns(credentialsFromSession);
            storyBoard.
            Setup(m => m.LoadFromSession <NoteRepositoryModel>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudRepository.ToInt()))).
            Returns(repositoryModelCloud);     // same as from repositoryStorageService
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(settingsModel);
            Mock <IRepositoryStorageService> repositoryStorageService = new Mock <IRepositoryStorageService>();

            repositoryStorageService.
            Setup(m => m.LoadRepositoryOrDefault(out repositoryModelLocal));     // same as from storyBoard
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            // Run step
            var step = new StoreMergedRepositoryAndQuitStep(
                SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit.ToInt(),
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CryptoRandomService(),
                repositoryStorageService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // repository is stored to the local device
            repositoryStorageService.Verify(m => m.TrySaveRepository(It.IsAny <NoteRepositoryModel>()), Times.Once);

            // repository is stored to the cloud
            cloudStorageClient.Verify(m => m.UploadFileAsync(It.IsAny <string>(), It.IsAny <byte[]>(), It.IsAny <CloudStorageCredentials>()), Times.Once);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <int>(x => x == SynchronizationStoryStepId.StopAndShowRepository.ToInt())), Times.Once);
        }
        public void RejectWhenNotesAreEqual()
        {
            NoteModel           noteModel       = new NoteModel();
            NoteRepositoryModel repositoryModel = new NoteRepositoryModel();

            repositoryModel.Notes.Add(noteModel);

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <NoteRepositoryModel>(It.Is <PullPushStorySessionKey>(p => p == PullPushStorySessionKey.CloudRepository))).
            Returns(repositoryModel);     // same as from repositoryStorageService
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(new SettingsModel());
            Mock <IRepositoryStorageService> repositoryStorageService = new Mock <IRepositoryStorageService>();

            repositoryStorageService.
            Setup(m => m.LoadRepositoryOrDefault(out repositoryModel));     // same as from storyBoard
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            // Run step
            var step = new StoreMergedRepositoryAndQuitStep(
                PullPushStoryStepId.StoreMergedRepositoryAndQuit,
                storyBoard.Object,
                noteModel.Id,
                PullPushDirection.PullFromServer,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CryptoRandomService(),
                repositoryStorageService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));;

            Assert.DoesNotThrowAsync(step.Run);

            // repository is not stored to the local device, nor to the cloud
            repositoryStorageService.Verify(m => m.TrySaveRepository(It.IsAny <NoteRepositoryModel>()), Times.Never);
            cloudStorageClient.Verify(m => m.UploadFileAsync(It.IsAny <string>(), It.IsAny <byte[]>(), It.IsAny <CloudStorageCredentials>()), Times.Never);
        }
        public void DoNotStoreAnythingWhenRepositoriesAreSame()
        {
            NoteRepositoryModel repositoryModel = new NoteRepositoryModel();

            repositoryModel.Revision = NoteRepositoryModel.NewestSupportedRevision;

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <NoteRepositoryModel>(It.Is <int>(p => p == SynchronizationStorySessionKey.CloudRepository.ToInt()))).
            Returns(repositoryModel);     // same as from repositoryStorageService
            Mock <ISettingsService>          settingsService          = new Mock <ISettingsService>();
            Mock <IRepositoryStorageService> repositoryStorageService = new Mock <IRepositoryStorageService>();

            repositoryStorageService.
            Setup(m => m.LoadRepositoryOrDefault(out repositoryModel));     // same as from storyBoard
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            // Run step
            var step = new StoreMergedRepositoryAndQuitStep(
                SynchronizationStoryStepId.StoreLocalRepositoryToCloudAndQuit.ToInt(),
                storyBoard.Object,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CryptoRandomService(),
                repositoryStorageService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));

            Assert.DoesNotThrowAsync(step.Run);

            // repository is not stored to the local device
            repositoryStorageService.Verify(m => m.TrySaveRepository(It.IsAny <NoteRepositoryModel>()), Times.Never);

            // repository is not stored to the cloud
            cloudStorageClient.Verify(m => m.UploadFileAsync(It.IsAny <string>(), It.IsAny <byte[]>(), It.IsAny <CloudStorageCredentials>()), Times.Never);

            // Next step is called
            storyBoard.Verify(m => m.ContinueWith(It.Is <int>(x => x == SynchronizationStoryStepId.StopAndShowRepository.ToInt())), Times.Once);
        }
        public void PushStoresCorrectData()
        {
            NoteModel cloudNoteModel = new NoteModel
            {
                HtmlContent    = "cloudContent",
                InRecyclingBin = true,
                ModifiedAt     = new DateTime(2000, 10, 22)
            };
            NoteRepositoryModel cloudRepositoryModel = new NoteRepositoryModel();

            cloudRepositoryModel.Notes.Add(cloudNoteModel);

            NoteModel localNoteModel = new NoteModel
            {
                Id             = cloudNoteModel.Id,
                HtmlContent    = "localContent",
                InRecyclingBin = false,
                ModifiedAt     = new DateTime(1900, 10, 22)
            };
            NoteRepositoryModel localRepositoryModel = new NoteRepositoryModel {
                Id = cloudNoteModel.Id
            };

            localRepositoryModel.Notes.Add(localNoteModel);

            Mock <IStoryBoard> storyBoard = new Mock <IStoryBoard>();

            storyBoard.
            Setup(m => m.LoadFromSession <NoteRepositoryModel>(It.Is <PullPushStorySessionKey>(p => p == PullPushStorySessionKey.CloudRepository))).
            Returns(cloudRepositoryModel);
            Mock <ISettingsService> settingsService = new Mock <ISettingsService>();

            settingsService.
            Setup(m => m.LoadSettingsOrDefault()).Returns(new SettingsModel {
                TransferCode = "AAAAAAAAAAAA", Credentials = new SerializeableCloudStorageCredentials()
            });
            Mock <IRepositoryStorageService> repositoryStorageService = new Mock <IRepositoryStorageService>();

            repositoryStorageService.
            Setup(m => m.LoadRepositoryOrDefault(out localRepositoryModel));
            Mock <ICloudStorageClient> cloudStorageClient = new Mock <ICloudStorageClient>();

            // Run step
            var step = new StoreMergedRepositoryAndQuitStep(
                PullPushStoryStepId.StoreMergedRepositoryAndQuit,
                storyBoard.Object,
                cloudNoteModel.Id,
                PullPushDirection.PushToServer,
                CommonMocksAndStubs.LanguageService(),
                CommonMocksAndStubs.FeedbackService(),
                settingsService.Object,
                CommonMocksAndStubs.CryptoRandomService(),
                repositoryStorageService.Object,
                CommonMocksAndStubs.CloudStorageClientFactory(cloudStorageClient.Object));;

            Assert.DoesNotThrowAsync(step.Run);

            // Cloud note object still exists and contains the content of the cloud plus a new modification date
            NoteModel newCloudNote = cloudRepositoryModel.Notes.FindById(localNoteModel.Id);

            Assert.AreSame(cloudNoteModel, newCloudNote);
            Assert.AreEqual("localContent", newCloudNote.HtmlContent);
            Assert.AreEqual(false, newCloudNote.InRecyclingBin);
            Assert.AreEqual(DateTime.UtcNow.Day, newCloudNote.ModifiedAt.Day);

            // Local note object still exists and has new modification date
            NoteModel newLocalNote = localRepositoryModel.Notes.FindById(cloudNoteModel.Id);

            Assert.AreEqual(DateTime.UtcNow.Day, newLocalNote.ModifiedAt.Day);

            // repository was stored to the local device and to the cloud
            repositoryStorageService.Verify(m => m.TrySaveRepository(It.IsAny <NoteRepositoryModel>()), Times.Once);
            cloudStorageClient.Verify(m => m.UploadFileAsync(It.IsAny <string>(), It.IsAny <byte[]>(), It.IsAny <CloudStorageCredentials>()), Times.Once);
        }