public async void Truncate_from_and_to_times_to_preceding_minute() { // Set up var req = new TimeLogDeleteRequest { Deletions = new[] { new TimeLogDeletedRange { FromTime = TestFromTime + TimeSpan.FromSeconds(5), ToTime = TestFromTime + TimeSpan.FromHours(1) + TimeSpan.FromSeconds(59) }, } }; // Act await _service.Delete(Db, _poll.Id, req); // Assert Db.WasSaveChangesCalled.Should().BeTrue(); var addedEntries = Db.Mock.TimeLogEntries.Added; // First entry var entry0 = addedEntries[0]; entry0.FromTime.Should().Be(TestFromTime); entry0.ToTime.Should().Be(TestFromTime + TimeSpan.FromHours(1)); }
public async void Should_combine_ajacent_deleted_ranges_into_a_single_entry() { // Set up var req = new TimeLogDeleteRequest { Deletions = new[] { new TimeLogDeletedRange { FromTime = TestFromTime + TimeSpan.FromHours(1), ToTime = TestFromTime + TimeSpan.FromHours(2) }, new TimeLogDeletedRange { FromTime = TestFromTime, ToTime = TestFromTime + TimeSpan.FromHours(1) }, } }; // Act await _service.Delete(Db, _poll.Id, req); // Assert Db.WasSaveChangesCalled.Should().BeTrue(); var addedEntries = Db.Mock.TimeLogEntries.Added; addedEntries.Should().HaveCount(1); // First entry var entry0 = addedEntries[0]; entry0.FromTime.Should().Be(TestFromTime); entry0.ToTime.Should().Be(TestFromTime + TimeSpan.FromHours(2)); }
public void If_from_time_is_on_or_before_to_time_should_throw_and_not_save_any_deletions(int hoursLength) { // Set up var req = new TimeLogDeleteRequest { Deletions = new[] { new TimeLogDeletedRange { FromTime = TestFromTime, ToTime = TestFromTime + TimeSpan.FromHours(1) }, new TimeLogDeletedRange { FromTime = TestFromTime + TimeSpan.FromHours(3), ToTime = TestFromTime + TimeSpan.FromHours(3 + hoursLength) }, } }; // Act Func <Task> action = async() => await _service.Delete(Db, _poll.Id, req); // Assert action.Should().Throw <BadRequestException>() .WithMessage("*fromTime*") .WithMessage("*toTime*"); Db.WasSaveChangesCalled.Should().BeFalse(); }
public async Task <IActionResult> Delete([FromBody] TimeLogDeleteRequest msg) { var poll = await GetDefaultPollAsync(); await _timeLogService.Delete(Db, poll.Id, msg); return(NoContent()); }
public void If_Deletions_is_null_should_throw() { // Set up var req = new TimeLogDeleteRequest(); // Act Func <Task> action = async() => await _service.Delete(Db, _poll.Id, req); // Assert action.Should().Throw <BadRequestException>().WithMessage("*deletions*"); }
public async void Should_insert_deletion_entry_for_every_range() { // Set up var req = new TimeLogDeleteRequest { Deletions = new[] { new TimeLogDeletedRange { FromTime = TestFromTime, ToTime = TestFromTime + TimeSpan.FromHours(1) }, new TimeLogDeletedRange { FromTime = TestFromTime + TimeSpan.FromHours(2), ToTime = TestFromTime + TimeSpan.FromHours(3) }, } }; // Act await _service.Delete(Db, _poll.Id, req); // Assert Db.WasSaveChangesCalled.Should().BeTrue(); var addedEntries = Db.Mock.TimeLogEntries.Added; addedEntries.Should().HaveCount(2); // First entry var entry0 = addedEntries[0]; entry0.IsDeletion.Should().Be(true); entry0.FromTime.Should().Be(TestFromTime + TimeSpan.FromHours(2)); entry0.ToTime.Should().Be(TestFromTime + TimeSpan.FromHours(3)); entry0.EntryText.Should().Be("[deletion]"); entry0.CreatedTimeUtc.Should().Be(TestUtcNow); // Second entry var entry1 = addedEntries[1]; entry1.IsDeletion.Should().Be(true); entry1.FromTime.Should().Be(TestFromTime); entry1.ToTime.Should().Be(TestFromTime + TimeSpan.FromHours(1)); entry1.EntryText.Should().Be("[deletion]"); entry1.CreatedTimeUtc.Should().Be(TestUtcNow); }
public async Task Delete(MainDbContext db, Guid pollId, TimeLogDeleteRequest req) { if (req.Deletions == null) { throw new BadRequestException("'deletions' field is not optional."); } var sortedDeletions = req.Deletions.OrderByDescending(d => d.ToTime).ToList(); var deletionEntries = new List <TimeLogEntry>(sortedDeletions.Count); TimeLogEntry currentEntry = null; var createdTimeUtc = _timeService.UtcNow; for (var i = 0; i < sortedDeletions.Count; i++) { var deletion = sortedDeletions[i]; // Adjust and validate time ranges. var fromTime = ToStartOfMinute(deletion.FromTime); var toTime = ToStartOfMinute(deletion.ToTime); if (fromTime >= toTime) { throw new BadRequestException( $"'fromTime' must be before 'toTime' after truncating to the start of minute. " + $"In deletion at position {i + 1} found 'fromTime': '{fromTime}', " + $"'toTime': {toTime}."); } // See if we need to extend the range or start a new one. // We don't need to compare fromTime or currentEntry.ToTime because // the entries are sorted by toTime desc. if (currentEntry != null && toTime >= currentEntry.FromTime) { // The entries overlap. Combine them into a single entry. currentEntry.FromTime = fromTime; } else { // Need to start a new entry. if (currentEntry != null) { db.TimeLogEntries.Add(currentEntry); } currentEntry = new TimeLogEntry { Id = Guid.NewGuid(), FromTime = fromTime, ToTime = toTime, EntryText = "[deletion]", TimeZone = deletion.TimeZone, TimeZoneOffset = deletion.TimeZoneOffset, CreatedTimeUtc = createdTimeUtc, IsDeletion = true, PollId = pollId, }; } } // Save the last entry. if (currentEntry != null) { db.TimeLogEntries.Add(currentEntry); } await db.SaveChangesAsync(); return; }
public Task Delete(MainDbContext db, Guid pollId, TimeLogDeleteRequest req) { throw new NotImplementedException(); }