/// <summary>
        /// Copy a Note to another TaskList.
        /// </summary>
        /// <param name="note">Note to be copied</param>
        /// <param name="taskListDestination">TaskList where the Note will be copied</param>
        /// <returns>The Note's Copy new row key</returns>
        public string CopyNote(Note note, TaskList taskListDestination)
        {
            var noteCopy = new Note
                               {
                                   PartitionKey = note.PartitionKey,
                                   RowKey = ShortGuid.NewGuid(),
                                   IsClosed = note.IsClosed,
                                   OrderingIndex = note.OrderingIndex,
                                   Owner = note.Owner,
                                   Title = note.Title,
                                   Content = note.Content,
                                   Container = taskListDestination
                               };

            _repository.Create(noteCopy);

            // copy the original Note share list to the copied Note share list.
            foreach (var share in note.Share)
            {
                if (share.RowKey != note.Owner.RowKey)
                {
                    _repository.AddShare(noteCopy, share.RowKey);
                }
            }

            _unitOfWork.SubmitChanges();
            return noteCopy.RowKey;
        }
        /// <summary>
        /// Creates a new Note.
        /// </summary>
        /// <param name="entityToCreate">Note domain object with the properties to map to an Notes table entity</param>
        public void Create(Note entityToCreate)
        {
            // get the last inserted Note ordering index
            var maxOrderingIndex = -1;
            var result = _unitOfWork.Load<NoteEntity>("Notes", n => n.PartitionKey == entityToCreate.Owner.RowKey).ToList();

            if (result.Any())
            {
                maxOrderingIndex = result.Max(n => n.OrderingIndex);
            }

            entityToCreate.PartitionKey = entityToCreate.Owner.RowKey;
            entityToCreate.RowKey = ShortGuid.NewGuid();
            entityToCreate.OrderingIndex = maxOrderingIndex + 1;
            entityToCreate.ContainerKeys = string.Format("{0}+{1}", entityToCreate.Container.PartitionKey, entityToCreate.Container.RowKey);

            var noteEntity = entityToCreate.MapToNoteEntity();
            _unitOfWork.Create(noteEntity, "Notes");

            // the User that creates the new Note is automatically add in the Note Shares list.
            var noteSharePartitionKey = string.Format("{0}+{1}", entityToCreate.PartitionKey, entityToCreate.RowKey);
            var noteShare = new NoteShareEntity(noteSharePartitionKey, entityToCreate.Owner.RowKey);
            _unitOfWork.Create(noteShare, "NoteShares");

            // store in the TaskListNotes an entity to indicate that the Note is in the containing TaskList.
            var taskListNoteEntityPartitionKey = string.Format("{0}+{1}", entityToCreate.Container.PartitionKey, entityToCreate.Container.RowKey);
            var taskListNoteEntityRowKey = string.Format("{0}+{1}", entityToCreate.PartitionKey, entityToCreate.RowKey);
            var taskListNoteEntity = new TaskListNoteEntity(taskListNoteEntityPartitionKey, taskListNoteEntityRowKey);
            _unitOfWork.Create(taskListNoteEntity, "TaskListNotes");
        }
        public void Create(Note entityToCreate)
        {
            var note = entityToCreate.MapToNoteEntity();
            var maxIndex = _notes.Max(n => n.OrderingIndex);
            note.OrderingIndex = maxIndex + 1;
            var noteShare = new NoteShareEntity(entityToCreate.RowKey, entityToCreate.Owner.RowKey);

            _notes.Add(note);
            _noteShares.Add(noteShare);
        }
        public void ANoteWithAnEmptyContentIsInvalid()
        {
            // Arrange
            var user = new User() { PartitionKey = "windowsliveid", RowKey = "user.test-windowsliveid" };
            var taskList = new TaskList("Test title", user) { PartitionKey = "user.test-windowsliveid", RowKey = ShortGuid.NewGuid().ToString() };
            const string validTitle = "Test title";
            string invalidContent = string.Empty;
            var note = new Note(validTitle, invalidContent, user, taskList) { PartitionKey = taskList.RowKey, RowKey = ShortGuid.NewGuid().ToString() };

            // Act
            var validationResult = note.IsValid();

            // Assert
            Assert.IsFalse(validationResult);
        }
        public void ANoteWithAllValidPropertiesIsValid()
        {
            // Arrange
            var user = new User() { PartitionKey = "windowsliveid", RowKey = "user.test-windowsliveid" };
            var taskList = new TaskList("Test title", user) { PartitionKey = "user.test-windowsliveid", RowKey = ShortGuid.NewGuid().ToString() };
            const string validTitle = "Test title";
            const string validContent = "Test content";
            var note = new Note(validTitle, validContent, user, taskList) { PartitionKey = taskList.RowKey, RowKey = ShortGuid.NewGuid().ToString() };

            // Act
            var validationResult = note.IsValid();

            // Assert
            Assert.IsTrue(validationResult);
        }
        public void NotesRepositoryAddShareCallsCreateFromTheUnitOfWork()
        {
            // Arrange
            var user = new User { PartitionKey = User1PartitionKey, RowKey = User1RowKey };
            var taskList = new TaskList("Test title", user) { PartitionKey = TaskList1PartitionKey, RowKey = _taskList1RowKey };
            var note = new Note("Test title", "Test content", user, taskList);
            note.Share.Add(user);

            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var repository = new NotesRepository(unitOfWorkMock.Object);

            // Act
            repository.AddShare(note, string.Format("{0}+{1}", User1PartitionKey, User1RowKey));

            // Assert
            unitOfWorkMock.Verify(uow => uow.Create(It.IsAny<NoteShareEntity>(), "NoteShares"), Times.Once());
        }
        public void NotesServiceMethodAddShareShouldAddAUserToTheNoteShares()
        {
            // Arrange
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var taskListsRepositoryMock = new Mock<ITaskListsRepository>();
            var notesRepositoryMock = new Mock<INotesRepository>();
            var taskListsService = new TaskListsService(unitOfWorkMock.Object, taskListsRepositoryMock.Object, notesRepositoryMock.Object);
            var repository = new NotesMemoryRepository();
            var note = new Note { PartitionKey = NotesMemoryRepository.User1RowKey, RowKey = repository.Note1RowKey };
            var service = new NotesService(unitOfWorkMock.Object, repository, taskListsService);
            var noteSharesCount = repository._noteShares.Count;

            // Act
            service.AddShare(note, NotesMemoryRepository.User2RowKey);

            // Assert
            Assert.IsTrue(repository._noteShares.Count == noteSharesCount + 1);
        }
        public void NotesRepositoryCreateCallsCreateFromTheUnitOfWork()
        {
            // Arrange
            var user = new User { PartitionKey = User1PartitionKey, RowKey = User1RowKey };
            var taskList = new TaskList("Test title", user) { PartitionKey = TaskList1PartitionKey, RowKey = _taskList1RowKey };
            var note = new Note("Test title", "Test content", user, taskList);
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            unitOfWorkMock.Setup(u => u.Load("Notes", It.IsAny<Expression<Func<NoteEntity, bool>>>())).Returns(BuildNotesTable());
            var repository = new NotesRepository(unitOfWorkMock.Object);

            // Act
            repository.Create(note);

            // Assert
            Assert.IsTrue(note.PartitionKey != string.Empty);
            Assert.IsTrue(note.RowKey != string.Empty);
            unitOfWorkMock.Verify(uow => uow.Create(It.IsAny<NoteEntity>(), "Notes"), Times.Once());
            unitOfWorkMock.Verify(uow => uow.Create(It.IsAny<NoteShareEntity>(), "NoteShares"), Times.Once());
            unitOfWorkMock.Verify(uow => uow.Create(It.IsAny<TaskListNoteEntity>(), "TaskListNotes"), Times.Once());
        }
        public void NotesServiceMethodCreateShouldCreateANote()
        {
            // Arrange
            var user = new User { PartitionKey = NotesMemoryRepository.IdentityProvider, RowKey = NotesMemoryRepository.User1RowKey };
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var taskListsRepositoryMock = new Mock<ITaskListsRepository>();
            var notesRepositoryMock = new Mock<INotesRepository>();
            var taskListsService = new TaskListsService(unitOfWorkMock.Object, taskListsRepositoryMock.Object, notesRepositoryMock.Object);
            var repository = new NotesMemoryRepository();
            var note = new Note { PartitionKey = NotesMemoryRepository.User1RowKey, RowKey = repository.Note1RowKey, Owner = user };
            var service = new NotesService(unitOfWorkMock.Object, repository, taskListsService);

            // Act
            service.Create(note);
            var result = service.Get(note.PartitionKey, note.RowKey);

            // Assert
            Assert.IsInstanceOfType(result, typeof(Note));
            Assert.IsNotNull(result);
        }
        public static Note MapToNote(this NoteEntity entry)
        {
            Note note = null;

            if (entry != null)
            {
                note = new Note
                            {
                                PartitionKey = entry.PartitionKey,
                                RowKey = entry.RowKey,
                                Timestamp = entry.Timestamp,
                                Title = entry.Title,
                                Content = entry.Content,
                                IsClosed = entry.IsClosed,
                                OrderingIndex = entry.OrderingIndex,
                                ContainerKeys = entry.ContainerKeys
                            };
            }

            return note;
        }
        public void NotesServiceMethodCopyNoteShouldCopyANote()
        {
            // Arrange
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var taskListsRepositoryMock = new Mock<ITaskListsRepository>();
            var notesRepositoryMock = new Mock<INotesRepository>();
            var taskListsService = new TaskListsService(unitOfWorkMock.Object, taskListsRepositoryMock.Object, notesRepositoryMock.Object);
            var repository = new NotesMemoryRepository();
            var user = new User { PartitionKey = NotesMemoryRepository.IdentityProvider, RowKey = NotesMemoryRepository.User1RowKey };
            var note = new Note { PartitionKey = NotesMemoryRepository.User1RowKey, RowKey = repository.Note1RowKey, Owner = user };
            var taskList = new TaskList { PartitionKey = NotesMemoryRepository.TaskList2PartitionKey, RowKey = repository.TaskList2RowKey };
            var service = new NotesService(unitOfWorkMock.Object, repository, taskListsService);

            // Act
            service.CopyNote(note, taskList);
            service.LoadNotes(taskList);

            // Assert
            //Assert.IsInstanceOfType(result, typeof(IQueryable<Note>));
            //Assert.IsTrue(result.Count() == 2);
        }
        public void NotesServiceMethodHasPermissionToEditShouldReturnTrueForAUserInTheShare()
        {
            // Arrange
            var user = new User { PartitionKey = NotesMemoryRepository.IdentityProvider, RowKey = NotesMemoryRepository.User1RowKey };
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var taskListsRepositoryMock = new Mock<ITaskListsRepository>();
            var notesRepositoryMock = new Mock<INotesRepository>();
            var taskListsService = new TaskListsService(unitOfWorkMock.Object, taskListsRepositoryMock.Object, notesRepositoryMock.Object);
            var repository = new NotesMemoryRepository();
            var note = new Note { PartitionKey = NotesMemoryRepository.User1RowKey, RowKey = repository.Note1RowKey, Owner = user };
            var service = new NotesService(unitOfWorkMock.Object, repository, taskListsService);

            // Act
            var result = service.HasPermissionToEdit(user, note);

            // Assert
            Assert.IsTrue(result);
        }
        /// <summary>
        /// Fills the note share users list.
        /// </summary>
        /// <param name="note">Note to have the Share list filled</param>
        public void LoadShare(Note note)
        {
            var noteSharePartitionKey = string.Format("{0}+{1}", note.PartitionKey, note.RowKey);
            var noteShares = _unitOfWork.Load<NoteShareEntity>("NoteShares", n => n.PartitionKey == noteSharePartitionKey);

            foreach (var noteShare in noteShares)
            {
                var userKeys = noteShare.RowKey.Split('-');
                var identityProvider = userKeys[1];

                var share = Get(identityProvider, noteShare.RowKey);

                if (share != null)
                {
                    note.Share.Add(share);
                }
            }
        }
        /// <summary>
        /// Fills the Note Owner information with an User object.
        /// </summary>
        /// <param name="note">Note to have the Owner filled.</param>
        public void LoadOwner(Note note)
        {
            var ownerKeys = note.PartitionKey.Split('-');
            var ownerPartitionKey = ownerKeys[1];
            var owner = Get(ownerPartitionKey, note.PartitionKey);

            if (owner != null)
            {
                note.Owner = owner;
            }
        }
 /// <summary>
 /// Load all the Users that the Note was shared with.
 /// </summary>
 /// <param name="note">Note to fill the Share list</param>
 public void LoadShare(Note note)
 {
     _repository.LoadShare(note);
 }
 /// <summary>
 /// Load the User that created the Note.
 /// </summary>
 /// <param name="note">Note to fill the Owner data</param>
 public void LoadOwner(Note note)
 {
     _repository.LoadOwner(note);
 }
 /// <summary>
 /// Create a Note.
 /// </summary>
 /// <param name="entityToCreate">Note to create</param>
 public void Create(Note entityToCreate)
 {
     _repository.Create(entityToCreate);
     _unitOfWork.SubmitChanges();
 }
 /// <summary>
 /// Share the Note with a User.
 /// </summary>
 /// <param name="note">The Note to be shared</param>
 /// <param name="userId">RowKey from the User</param>
 public void AddShare(Note note, string userId)
 {
     var sharePartitionKey = string.Format("{0}+{1}", note.PartitionKey, note.RowKey);
     var share = new NoteShareEntity(sharePartitionKey, userId);
     _unitOfWork.Create(share, "NoteShares");
 }
 /// <summary>
 /// Update a Note.
 /// </summary>
 /// <param name="entityToUpdate">Note to update</param>
 public void Update(Note entityToUpdate)
 {
     _repository.Update(entityToUpdate);
     _unitOfWork.SubmitChanges();
 }
        public void UsersServiceMethodLoadNoteOwnerShouldLoadOwner()
        {
            // Arrange
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var repository = new UsersMemoryRepository();
            var note = new Note { PartitionKey = UsersMemoryRepository.Note1PartitionKey, RowKey = repository.Note1RowKey };
            var service = new UsersService(unitOfWorkMock.Object, repository);

            // Act
            service.LoadOwner(note);

            // Assert
            Assert.IsNotNull(note.Owner);
        }
 /// <summary>
 /// Checks if a User has permissions to edit a Note, if it is in the Note Share list.
 /// </summary>
 /// <param name="user">The User to check the permission</param>
 /// <param name="note">The Note the User wants to edit</param>
 /// <returns>True if the User is in the Note Share list, False otherwise</returns>
 public bool HasPermissionToEdit(User user, Note note)
 {
     var noteSharePartitionKey = string.Format("{0}+{1}", note.PartitionKey, note.RowKey);
     return _unitOfWork.Get<NoteShareEntity>("NoteShares", ns => ns.PartitionKey == noteSharePartitionKey && ns.RowKey == user.RowKey) != null;
 }
        public void LoadContainer(Note note)
        {
            var taskListNote = TaskListNotes.FirstOrDefault(tn => tn.RowKey == string.Format("{0}+{1}", note.PartitionKey, note.RowKey));

            if (taskListNote != null)
            {
                var taskListKeys = taskListNote.PartitionKey.Split('+');
                var taskListPartitionKey = taskListKeys[0];
                var taskListRowKey = taskListKeys[1];
                var taskList = TaskLists.FirstOrDefault(t => t.PartitionKey == taskListPartitionKey && t.RowKey == taskListRowKey);

                if (taskList != null)
                {
                    note.Container = taskList.MapToTaskList();
                }
            }
        }
 /// <summary>
 /// Delete a Note.
 /// </summary>
 /// <param name="entityToDelete">Note to delete</param>
 public void Delete(Note entityToDelete)
 {
     _repository.Delete(entityToDelete);
     _unitOfWork.SubmitChanges();
 }
 /// <summary>
 /// Move a Note to another TaskList.
 /// </summary>
 /// <param name="note">Note to be moved</param>
 /// <param name="taskListDestination">TaskList where the Note will be moved</param>
 /// <returns></returns>
 public string MoveNote(Note note, TaskList taskListDestination)
 {
     _repository.Delete(note);
     return CopyNote(note, taskListDestination);
 }
        public void TaskListsServiceMethodDeleteShouldDeleteATaskList()
        {
            // Arrange
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var repository = new TaskListsMemoryRepository();
            var notesRepository = new NotesMemoryRepository();
            var service = new TaskListsService(unitOfWorkMock.Object, repository, notesRepository);
            var result = service.Get(TaskListsMemoryRepository.User1RowKey, repository.TaskList1RowKey);
            var user = new User { PartitionKey = TaskListsMemoryRepository.IdentityProvider, RowKey = TaskListsMemoryRepository.User1RowKey };
            var note = new Note { PartitionKey = TaskListsMemoryRepository.User1RowKey, RowKey = repository.Note1RowKey, Owner = user };
            result.Notes.Add(note);

            // Act
            service.Delete(result);
            result = service.Get(TaskListsMemoryRepository.User1RowKey, repository.TaskList1RowKey);

            // Assert
            Assert.IsNull(result);
        }
        /// <summary>
        /// Deletes an entity from the Notes Azure Table and all the entities in the related Azure Tables.
        /// </summary>
        /// <param name="entityToDelete">TaskList domain object with the properties to delete an existing TaskLists table entity</param>
        public void Delete(Note entityToDelete)
        {
            _unitOfWork.Delete<NoteEntity>("Notes", entityToDelete.PartitionKey, entityToDelete.RowKey);

            // delete all the entities that relate a Containing TaskList and his Notes.
            var taskListNoteRowKey = string.Format("{0}+{1}", entityToDelete.PartitionKey, entityToDelete.RowKey);
            var taskListNote = _unitOfWork.Get<TaskListEntity>("TaskListNotes", tn => tn.RowKey == taskListNoteRowKey);
            _unitOfWork.Delete<TaskListEntity>("TaskListNotes", taskListNote.PartitionKey, taskListNote.RowKey);

            // delete all the entities related to the Note Shares list.
            var noteSharePartitionKey = string.Format("{0}+{1}", entityToDelete.PartitionKey, entityToDelete.RowKey);
            var shares = _unitOfWork.Load<NoteShareEntity>("NoteShares").Where(n => n.PartitionKey == noteSharePartitionKey);

            foreach (var share in shares)
            {
                _unitOfWork.Delete<NoteShareEntity>("NoteShares", share.PartitionKey, share.RowKey);
            }
        }
 /// <summary>
 /// Remove an existing Share from the Note.
 /// </summary>
 /// <param name="note">The Note with the Share to be removed</param>
 /// <param name="userId">RowKey from the User</param>
 public void RemoveShare(Note note, string userId)
 {
     var sharePartitionKey = string.Format("{0}+{1}", note.PartitionKey, note.RowKey);
     _unitOfWork.Delete<NoteShareEntity>("NoteShares", sharePartitionKey, userId);
 }
 /// <summary>
 /// Share the Note with a User.
 /// </summary>
 /// <param name="note">Note to be shared</param>
 /// <param name="userId">The User row key</param>
 public void AddShare(Note note, string userId)
 {
     _repository.AddShare(note, userId);
     _unitOfWork.SubmitChanges();
 }
        public void UsersServiceMethodLoadShareShouldLoadTheNoteShares()
        {
            // Arrange
            var unitOfWorkMock = new Mock<IUnitOfWork>();
            var repository = new UsersMemoryRepository();
            var note = new Note { PartitionKey = UsersMemoryRepository.Note1PartitionKey, RowKey = repository.Note1RowKey };
            var service = new UsersService(unitOfWorkMock.Object, repository);

            // Act
            service.LoadShare(note);

            // Assert
            Assert.IsTrue(note.Share.Count == 2);
        }
 /// <summary>
 /// Updates an entity in the Notes Azure Table.
 /// </summary>
 /// <param name="entityToUpdate">Note domain object with the properties to update an existing Notes table entity</param>
 public void Update(Note entityToUpdate)
 {
     _unitOfWork.Update("Notes", entityToUpdate.MapToNoteEntity());
 }