From fe44cef65055f9ca2fa8d46f79f27f0c335d7564 Mon Sep 17 00:00:00 2001 From: crupest Date: Mon, 24 Feb 2020 16:52:19 +0800 Subject: [PATCH] Add delete timeline. --- .../IntegratedTests/TimelineTest.cs | 56 +++++++++++++++++++ Timeline/Controllers/TimelineController.cs | 20 +++++++ Timeline/Services/TimelineService.cs | 25 +++++++++ 3 files changed, 101 insertions(+) diff --git a/Timeline.Tests/IntegratedTests/TimelineTest.cs b/Timeline.Tests/IntegratedTests/TimelineTest.cs index 51653b0a5..14a0a59e1 100644 --- a/Timeline.Tests/IntegratedTests/TimelineTest.cs +++ b/Timeline.Tests/IntegratedTests/TimelineTest.cs @@ -315,6 +315,62 @@ public async Task TimelineCreate_Should_Work() } } + [Fact] + public async Task TimelineDelete_Should_Work() + { + await CreateTestTimelines(); + + { + using var client = await CreateDefaultClient(); + var res = await client.DeleteAsync("timelines/t1"); + res.Should().HaveStatusCode(HttpStatusCode.Unauthorized); + } + + { + using var client = await CreateClientAs(2); + var res = await client.DeleteAsync("timelines/t1"); + res.Should().HaveStatusCode(HttpStatusCode.Forbidden); + } + + { + using var client = await CreateClientAsAdministrator(); + + { + var res = await client.DeleteAsync("timelines/!!!"); + res.Should().BeInvalidModel(); + } + + { + var res = await client.DeleteAsync("timelines/t2"); + res.Should().BeDelete(true); + } + + { + var res = await client.DeleteAsync("timelines/t2"); + res.Should().BeDelete(false); + } + } + + { + using var client = await CreateClientAs(1); + + { + var res = await client.DeleteAsync("timelines/!!!"); + res.Should().BeInvalidModel(); + } + + { + var res = await client.DeleteAsync("timelines/t1"); + res.Should().BeDelete(true); + } + + { + var res = await client.DeleteAsync("timelines/t1"); + res.Should().HaveStatusCode(HttpStatusCode.NotFound); + } + } + } + [Fact] public async Task InvalidModel_BadName() { diff --git a/Timeline/Controllers/TimelineController.cs b/Timeline/Controllers/TimelineController.cs index 9ada16e08..85ccb5c16 100644 --- a/Timeline/Controllers/TimelineController.cs +++ b/Timeline/Controllers/TimelineController.cs @@ -206,5 +206,25 @@ public async Task> TimelineCreate([FromBody] Timeline return BadRequest(ErrorResponse.TimelineCommon.NameConflict()); } } + + [HttpDelete("timelines/{name}")] + [Authorize] + public async Task> TimelineDelete([FromRoute][TimelineName] string name) + { + if (!this.IsAdministrator() && !(await _service.HasManagePermission(name, this.GetUserId()))) + { + return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid()); + } + + try + { + await _service.DeleteTimeline(name); + return Ok(CommonDeleteResponse.Delete()); + } + catch (TimelineNotExistException) + { + return Ok(CommonDeleteResponse.NotExist()); + } + } } } diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs index 76acc7d7c..f12a7fcc0 100644 --- a/Timeline/Services/TimelineService.cs +++ b/Timeline/Services/TimelineService.cs @@ -269,6 +269,15 @@ public interface ITimelineService : IBaseTimelineService /// Thrown when the timeline already exists. /// Thrown when the owner user does not exist. Task CreateTimeline(string name, long owner); + + /// + /// Delete a timeline. + /// + /// The name of the timeline. + /// Thrown when is null. + /// Thrown when timeline name is invalid. + /// Thrown when the timeline does not exist. + Task DeleteTimeline(string name); } public interface IPersonalTimelineService : IBaseTimelineService @@ -733,6 +742,22 @@ public async Task CreateTimeline(string name, long owner) Members = new List() }; } + + public async Task DeleteTimeline(string name) + { + if (name == null) + throw new ArgumentNullException(nameof(name)); + + ValidateTimelineName(name, nameof(name)); + + var entity = await Database.Timelines.Where(t => t.Name == name).SingleOrDefaultAsync(); + + if (entity == null) + throw new TimelineNotExistException(name); + + Database.Timelines.Remove(entity); + await Database.SaveChangesAsync(); + } } public class PersonalTimelineService : BaseTimelineService, IPersonalTimelineService