aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-08-28 00:01:04 +0800
committercrupest <crupest@outlook.com>2020-08-28 00:01:04 +0800
commit12410a51fb2e5f55e8d83415bc3c4053a146ce3b (patch)
tree920ef556df34e0d69d990f8bf3ef2fdce13f9f46
parentc10dc9e221317ea39f9ce0f172670ffbe94e6f8a (diff)
downloadtimeline-12410a51fb2e5f55e8d83415bc3c4053a146ce3b.tar.gz
timeline-12410a51fb2e5f55e8d83415bc3c4053a146ce3b.tar.bz2
timeline-12410a51fb2e5f55e8d83415bc3c4053a146ce3b.zip
Add change timeline name api to timeline controller.
-rw-r--r--Timeline.Tests/IntegratedTests/TimelineTest.cs61
-rw-r--r--Timeline.Tests/Services/TimelineServiceTest.cs8
-rw-r--r--Timeline/Controllers/TimelineController.cs26
-rw-r--r--Timeline/Filters/Timeline.cs13
-rw-r--r--Timeline/Models/Http/TimelineController.cs19
-rw-r--r--Timeline/Services/TimelineService.cs3
6 files changed, 120 insertions, 10 deletions
diff --git a/Timeline.Tests/IntegratedTests/TimelineTest.cs b/Timeline.Tests/IntegratedTests/TimelineTest.cs
index 302b2195..ac4f41a2 100644
--- a/Timeline.Tests/IntegratedTests/TimelineTest.cs
+++ b/Timeline.Tests/IntegratedTests/TimelineTest.cs
@@ -488,7 +488,7 @@ namespace Timeline.Tests.IntegratedTests
{
var res = await client.DeleteAsync("timelines/t1");
- res.Should().HaveStatusCode(HttpStatusCode.NotFound);
+ res.Should().HaveStatusCode(400);
}
}
}
@@ -545,15 +545,15 @@ namespace Timeline.Tests.IntegratedTests
}
{
var res = await client.PatchAsJsonAsync(generator("notexist", null), new TimelinePatchRequest { });
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
+ res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
}
{
var res = await client.PutAsync(generator("notexist", "members/user1"), null);
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
+ res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
}
{
var res = await client.DeleteAsync(generator("notexist", "members/user1"));
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
+ res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
}
{
var res = await client.GetAsync(generator("notexist", "posts"));
@@ -561,11 +561,11 @@ namespace Timeline.Tests.IntegratedTests
}
{
var res = await client.PostAsJsonAsync(generator("notexist", "posts"), TimelineHelper.TextPostCreateRequest("aaa"));
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
+ res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
}
{
var res = await client.DeleteAsync(generator("notexist", "posts/123"));
- res.Should().HaveStatusCode(404).And.HaveCommonBody(errorCode);
+ res.Should().HaveStatusCode(400).And.HaveCommonBody(errorCode);
}
{
var res = await client.GetAsync(generator("notexist", "posts/123/data"));
@@ -1436,5 +1436,54 @@ namespace Timeline.Tests.IntegratedTests
.Which.Title.Should().Be("atitle");
}
}
+
+ [Fact]
+ public async Task ChangeName()
+ {
+ {
+ using var client = await CreateDefaultClient();
+ var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "t1", NewName = "tttttttt" });
+ res.Should().HaveStatusCode(401);
+ }
+
+ {
+ using var client = await CreateClientAs(2);
+ var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "t1", NewName = "tttttttt" });
+ res.Should().HaveStatusCode(403);
+ }
+
+ using (var client = await CreateClientAsUser())
+ {
+ {
+ var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "!!!", NewName = "tttttttt" });
+ res.Should().BeInvalidModel();
+ }
+
+ {
+ var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "ttt", NewName = "!!!!" });
+ res.Should().BeInvalidModel();
+ }
+
+ {
+ var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "ttttt", NewName = "tttttttt" });
+ res.Should().HaveStatusCode(400).And.HaveCommonBody().Which.Code.Should().Be(ErrorCodes.TimelineController.NotExist);
+ }
+
+ {
+ var res = await client.PostAsJsonAsync("timelineop/changename", new TimelineChangeNameRequest { OldName = "t1", NewName = "newt" });
+ res.Should().HaveStatusCode(200).And.HaveJsonBody<TimelineInfo>().Which.Name.Should().Be("newt");
+ }
+
+ {
+ var res = await client.GetAsync("timelines/t1");
+ res.Should().HaveStatusCode(404);
+ }
+
+ {
+ var res = await client.GetAsync("timelines/newt");
+ res.Should().HaveStatusCode(200).And.HaveJsonBody<TimelineInfo>().Which.Name.Should().Be("newt");
+ }
+ }
+ }
}
}
diff --git a/Timeline.Tests/Services/TimelineServiceTest.cs b/Timeline.Tests/Services/TimelineServiceTest.cs
index 3883cda9..5a774b78 100644
--- a/Timeline.Tests/Services/TimelineServiceTest.cs
+++ b/Timeline.Tests/Services/TimelineServiceTest.cs
@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Timeline.Entities;
using Timeline.Models;
using Timeline.Services;
+using Timeline.Services.Exceptions;
using Timeline.Tests.Helpers;
using Xunit;
@@ -304,7 +305,14 @@ namespace Timeline.Tests.Services
{
_clock.ForwardCurrentTime();
+ await _timelineService.Awaiting(s => s.ChangeTimelineName("!!!", "newtl")).Should().ThrowAsync<ArgumentException>();
+ await _timelineService.Awaiting(s => s.ChangeTimelineName("tl", "!!!")).Should().ThrowAsync<ArgumentException>();
+ await _timelineService.Awaiting(s => s.ChangeTimelineName("tl", "newtl")).Should().ThrowAsync<TimelineNotExistException>();
+
await _timelineService.CreateTimeline("tl", await _userService.GetUserIdByUsername("user"));
+ await _timelineService.CreateTimeline("tl2", await _userService.GetUserIdByUsername("user"));
+
+ await _timelineService.Awaiting(s => s.ChangeTimelineName("tl", "tl2")).Should().ThrowAsync<EntityAlreadyExistException>();
var time = _clock.ForwardCurrentTime();
diff --git a/Timeline/Controllers/TimelineController.cs b/Timeline/Controllers/TimelineController.cs
index 90b50bbb..9a3147ea 100644
--- a/Timeline/Controllers/TimelineController.cs
+++ b/Timeline/Controllers/TimelineController.cs
@@ -308,6 +308,7 @@ namespace Timeline.Controllers
[HttpDelete("timelines/{name}/posts/{id}")]
[Authorize]
[ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<CommonDeleteResponse>> PostDelete([FromRoute][GeneralTimelineName] string name, [FromRoute] long id)
@@ -336,6 +337,7 @@ namespace Timeline.Controllers
[HttpPatch("timelines/{name}")]
[Authorize]
[ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
public async Task<ActionResult<TimelineInfo>> TimelinePatch([FromRoute][GeneralTimelineName] string name, [FromBody] TimelinePatchRequest body)
@@ -461,5 +463,29 @@ namespace Timeline.Controllers
return CommonDeleteResponse.NotExist();
}
}
+
+ [HttpPost("timelineop/changename")]
+ [Authorize]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(StatusCodes.Status400BadRequest)]
+ [ProducesResponseType(StatusCodes.Status401Unauthorized)]
+ [ProducesResponseType(StatusCodes.Status403Forbidden)]
+ public async Task<ActionResult<TimelineInfo>> TimelineOpChangeName([FromBody] TimelineChangeNameRequest body)
+ {
+ if (!this.IsAdministrator() && !(await _service.HasManagePermission(body.OldName, this.GetUserId())))
+ {
+ return StatusCode(StatusCodes.Status403Forbidden, ErrorResponse.Common.Forbid());
+ }
+
+ try
+ {
+ var timeline = await _service.ChangeTimelineName(body.OldName, body.NewName);
+ return Ok(_mapper.Map<TimelineInfo>(timeline));
+ }
+ catch (EntityAlreadyExistException)
+ {
+ return BadRequest(ErrorResponse.TimelineController.NameConflict());
+ }
+ }
}
}
diff --git a/Timeline/Filters/Timeline.cs b/Timeline/Filters/Timeline.cs
index 90b87223..6a730ee7 100644
--- a/Timeline/Filters/Timeline.cs
+++ b/Timeline/Filters/Timeline.cs
@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Timeline.Models.Http;
using Timeline.Services.Exceptions;
@@ -13,11 +14,17 @@ namespace Timeline.Filters
{
if (e.InnerException is UserNotExistException)
{
- context.Result = new NotFoundObjectResult(ErrorResponse.UserCommon.NotExist());
+ if (HttpMethods.IsGet(context.HttpContext.Request.Method))
+ context.Result = new NotFoundObjectResult(ErrorResponse.UserCommon.NotExist());
+ else
+ context.Result = new BadRequestObjectResult(ErrorResponse.UserCommon.NotExist());
}
else
{
- context.Result = new NotFoundObjectResult(ErrorResponse.TimelineController.NotExist());
+ if (HttpMethods.IsGet(context.HttpContext.Request.Method))
+ context.Result = new NotFoundObjectResult(ErrorResponse.TimelineController.NotExist());
+ else
+ context.Result = new BadRequestObjectResult(ErrorResponse.TimelineController.NotExist());
}
}
}
diff --git a/Timeline/Models/Http/TimelineController.cs b/Timeline/Models/Http/TimelineController.cs
index 95bae3e6..7bd141ed 100644
--- a/Timeline/Models/Http/TimelineController.cs
+++ b/Timeline/Models/Http/TimelineController.cs
@@ -71,4 +71,23 @@ namespace Timeline.Models.Http
/// </summary>
public TimelineVisibility? Visibility { get; set; }
}
+
+ /// <summary>
+ /// Change timeline name request model.
+ /// </summary>
+ public class TimelineChangeNameRequest
+ {
+ /// <summary>
+ /// Old name of timeline.
+ /// </summary>
+ [Required]
+ [TimelineName]
+ public string OldName { get; set; } = default!;
+ /// <summary>
+ /// New name of timeline.
+ /// </summary>
+ [Required]
+ [TimelineName]
+ public string NewName { get; set; } = default!;
+ }
}
diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs
index 0a3a2076..4bcae596 100644
--- a/Timeline/Services/TimelineService.cs
+++ b/Timeline/Services/TimelineService.cs
@@ -411,6 +411,7 @@ namespace Timeline.Services
}
}
+ /// Remember to include Members when query.
private async Task<Models.Timeline> MapTimelineFromEntity(TimelineEntity entity)
{
var owner = await _userService.GetUserById(entity.OwnerId);
@@ -1138,7 +1139,7 @@ namespace Timeline.Services
ValidateTimelineName(oldTimelineName, nameof(oldTimelineName));
ValidateTimelineName(newTimelineName, nameof(newTimelineName));
- var entity = await _database.Timelines.Where(t => t.Name == oldTimelineName).SingleOrDefaultAsync();
+ var entity = await _database.Timelines.Include(t => t.Members).Where(t => t.Name == oldTimelineName).SingleOrDefaultAsync();
if (entity == null)
throw new TimelineNotExistException(oldTimelineName);