public async Task UpdateAsync_EntryDoesNotExists_ReturnsNull()
        {
            // Arrange
            using var dbContext = CreateDbContext();
            var user = await CreateTestUserAsync(dbContext);

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(false);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entryToUpdate = new WorkEntry
            {
                Id         = Guid.NewGuid(),
                Date       = new DateTime(2021, 1, 1),
                HoursSpent = 6,
                UserId     = user.Id + "1",
                Notes      = "Some notes..."
            };

            var entry = await workEntriesService.UpdateAsync(entryToUpdate);

            Assert.Null(entry);
        }
        public async Task CreateAsync_ExplicitUserId(bool isAdmin, string currentUserId, string createdByUserId, string expectedEntryUserId)
        {
            // Arrange
            using var dbContext = CreateDbContext();

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(currentUserId);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(isAdmin);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entry = new WorkEntry
            {
                HoursSpent = 5,
                Date       = DateTime.Now.Date,
                Notes      = "Notes",
                UserId     = createdByUserId
            };

            entry = await workEntriesService.CreateAsync(entry);

            // Assert
            Assert.Equal(expectedEntryUserId, entry.UserId);
        }
        public async Task UpdateAsync_AnotherUser_ReturnsNull(bool isAdmin, bool isNullResult)
        {
            // Arrange
            using var dbContext = CreateDbContext();
            var user = await CreateTestUserAsync(dbContext);

            var anotherUser = await CreateTestUserAsync(dbContext);

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(isAdmin);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);
            var entry = await CreateWorkEntry(dbContext, anotherUser.Id);

            // Act
            var entryToUpdate = new WorkEntry
            {
                Id         = entry.Id,
                Date       = new DateTime(2021, 1, 1),
                HoursSpent = 6,
                Notes      = "Some notes..."
            };

            entry = await workEntriesService.UpdateAsync(entryToUpdate);

            Assert.Equal(isNullResult, entry == null);
        }
        public async Task CreateAsync_InitsEmptyFields()
        {
            // Arrange
            string testUserId = Guid.NewGuid().ToString();

            using var dbContext = CreateDbContext();

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(testUserId);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entry = new WorkEntry
            {
                HoursSpent = 5,
                Date       = DateTime.Now.Date,
                Notes      = "Notes"
            };

            var createdEntry = await workEntriesService.CreateAsync(entry);

            // Assert
            Assert.NotEqual(Guid.Empty, createdEntry.Id);
            Assert.Equal(testUserId, createdEntry.UserId);
            Assert.Equal(entry.Date, createdEntry.Date);
            Assert.Equal(entry.Notes, createdEntry.Notes);
            Assert.Equal(entry.HoursSpent, createdEntry.HoursSpent);
        }
        public async Task FindAsync_FilterTests(bool isAdmin, DateTime?minDate, DateTime?maxDate, bool sameUser, int expectedResultsCount)
        {
            // Arrange
            using var dbContext = CreateDbContext();
            var user = await CreateTestUserAsync(dbContext);

            var anotherUser = await CreateTestUserAsync(dbContext);

            await CreateWorkEntry(dbContext, user.Id, entry => entry.Date        = new DateTime(2020, 3, 5));
            await CreateWorkEntry(dbContext, user.Id, entry => entry.Date        = new DateTime(2020, 3, 10));
            await CreateWorkEntry(dbContext, user.Id, entry => entry.Date        = new DateTime(2020, 3, 17));
            await CreateWorkEntry(dbContext, anotherUser.Id, entry => entry.Date = new DateTime(2020, 3, 15));

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(isAdmin);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entries = await workEntriesService.FindAsync(sameUser?user.Id : anotherUser.Id, minDate, maxDate);

            // Assert
            Assert.Equal(expectedResultsCount, entries.Count);
        }
        public async Task FindAsync_EntriesExist_ReturnsWorkEntry()
        {
            // Arrange
            using var dbContext = CreateDbContext();
            var user = await CreateTestUserAsync(dbContext);

            var entry = await CreateWorkEntry(dbContext, user.Id);

            var entry1 = await CreateWorkEntry(dbContext, user.Id, entry => entry.Date = DateTime.Now.AddDays(-1));

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(false);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entries = await workEntriesService.FindAsync(user.Id);

            // Assert
            Assert.Collection(entries,
                              resultEntry => AssertEqual(entry1, resultEntry),
                              resultEntry => AssertEqual(entry, resultEntry)
                              );
        }
        public async Task UpdateAsync_EntryExists_UpdatesEntry()
        {
            // Arrange
            using var dbContext = CreateDbContext();
            var user = await CreateTestUserAsync(dbContext);

            var entry = await CreateWorkEntry(dbContext, user.Id);

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(false);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entryToUpdate = new WorkEntry
            {
                Id         = entry.Id,
                Date       = new DateTime(2021, 1, 1),
                HoursSpent = 6,
                UserId     = user.Id + "1",
                Notes      = "Some notes..."
            };

            entry = await workEntriesService.UpdateAsync(entryToUpdate);

            Assert.NotEqual(entryToUpdate.UserId, entry.UserId);

            // Line above tests that a user can't update the UserId field.
            // Now assign the same user id to compare all properties of both objects,
            // otherwise assert will fail
            entryToUpdate.UserId = entry.UserId;
            AssertEqual(entryToUpdate, entry);

            // assert entry state directly in the database
            entry = await dbContext.WorkEntries.FindAsync(entry.Id);

            AssertEqual(entryToUpdate, entry);
        }
        public async Task GetByIdAsync_EntryExists_ReturnsEntry()
        {
            // Arrange
            using var dbContext = CreateDbContext();

            var user = await CreateTestUserAsync(dbContext);

            var entry = await CreateWorkEntry(dbContext, user.Id);

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(false);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entryResult = await workEntriesService.GetByIdAsync(entry.Id);

            // Assert
            AssertEqual(entry, entryResult);
        }
        public async Task DeleteAsync_EntryExists_RemovesEntry(bool isAdmin, bool sameUser, bool isNullResult)
        {
            // Arrange
            using var dbContext = CreateDbContext();
            var user = await CreateTestUserAsync(dbContext);

            var anotherUser = await CreateTestUserAsync(dbContext);

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(isAdmin);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);
            var entry = await CreateWorkEntry(dbContext, sameUser?user.Id : anotherUser.Id);

            // Act
            await workEntriesService.DeleteAsync(entry.Id);

            // Assert
            Assert.Equal(isNullResult, await dbContext.WorkEntries.FindAsync(entry.Id) == null);
        }
        public async Task GetByIdAsync_FilterByUserIdTest(bool isAdmin, bool resultShouldBeNull)
        {
            // Arrange
            using var dbContext = CreateDbContext();

            var user = await CreateTestUserAsync(dbContext);

            var anotherUser = await CreateTestUserAsync(dbContext);

            var entry = await CreateWorkEntry(dbContext, anotherUser.Id);

            var userContextAccessorMock = new Mock <IUserContextAccessor>();

            userContextAccessorMock.Setup(m => m.GetUserId()).Returns(user.Id);
            userContextAccessorMock.Setup(m => m.IsAdminUser()).Returns(isAdmin);

            var workEntriesService = new WorkEntriesService(dbContext, Mock.Of <IDbErrorHandler>(), userContextAccessorMock.Object);

            // Act
            var entryResult = await workEntriesService.GetByIdAsync(entry.Id);

            // Assert
            Assert.Equal(resultShouldBeNull, entryResult == null);
        }