diff options
-rw-r--r-- | Timeline.Tests/IntegratedTests/TimelineTest.cs | 56 | ||||
-rw-r--r-- | Timeline/Controllers/TimelineController.cs | 20 | ||||
-rw-r--r-- | Timeline/Services/TimelineService.cs | 25 |
3 files changed, 101 insertions, 0 deletions
diff --git a/Timeline.Tests/IntegratedTests/TimelineTest.cs b/Timeline.Tests/IntegratedTests/TimelineTest.cs index 51653b0a..14a0a59e 100644 --- a/Timeline.Tests/IntegratedTests/TimelineTest.cs +++ b/Timeline.Tests/IntegratedTests/TimelineTest.cs @@ -316,6 +316,62 @@ namespace Timeline.Tests.IntegratedTests }
[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()
{
using var client = await CreateClientAsAdministrator();
diff --git a/Timeline/Controllers/TimelineController.cs b/Timeline/Controllers/TimelineController.cs index 9ada16e0..85ccb5c1 100644 --- a/Timeline/Controllers/TimelineController.cs +++ b/Timeline/Controllers/TimelineController.cs @@ -206,5 +206,25 @@ namespace Timeline.Controllers return BadRequest(ErrorResponse.TimelineCommon.NameConflict());
}
}
+
+ [HttpDelete("timelines/{name}")]
+ [Authorize]
+ public async Task<ActionResult<TimelineInfo>> 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 76acc7d7..f12a7fcc 100644 --- a/Timeline/Services/TimelineService.cs +++ b/Timeline/Services/TimelineService.cs @@ -269,6 +269,15 @@ namespace Timeline.Services /// <exception cref="ConflictException">Thrown when the timeline already exists.</exception>
/// <exception cref="UserNotExistException">Thrown when the owner user does not exist.</exception>
Task<TimelineInfo> CreateTimeline(string name, long owner);
+
+ /// <summary>
+ /// Delete a timeline.
+ /// </summary>
+ /// <param name="name">The name of the timeline.</param>
+ /// <exception cref="ArgumentNullException">Thrown when <paramref name="name"/> is null.</exception>
+ /// <exception cref="ArgumentException">Thrown when timeline name is invalid.</exception>
+ /// <exception cref="TimelineNotExistException">Thrown when the timeline does not exist.</exception>
+ Task DeleteTimeline(string name);
}
public interface IPersonalTimelineService : IBaseTimelineService
@@ -733,6 +742,22 @@ namespace Timeline.Services Members = new List<UserInfo>()
};
}
+
+ 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
|