From 4538aa0be40316a967d6fbcbc08bc9670b9bbcf0 Mon Sep 17 00:00:00 2001 From: crupest Date: Sat, 13 Feb 2021 15:46:02 +0800 Subject: feat: Add timeline manageable. --- .../Timeline.Tests/IntegratedTests/TimelineTest.cs | 73 +++++++++++++--------- .../Controllers/BookmarkTimelineController.cs | 8 ++- .../Controllers/HighlightTimelineController.cs | 8 ++- BackEnd/Timeline/Controllers/SearchController.cs | 8 ++- BackEnd/Timeline/Controllers/TimelineController.cs | 19 ++++-- .../Timeline/Controllers/TimelinePostController.cs | 4 +- BackEnd/Timeline/Models/Http/HttpTimeline.cs | 4 +- BackEnd/Timeline/Models/Mapper/TimelineMapper.cs | 22 ++++++- 8 files changed, 105 insertions(+), 41 deletions(-) diff --git a/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs b/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs index ec9a6d83..be00b595 100644 --- a/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs +++ b/BackEnd/Timeline.Tests/IntegratedTests/TimelineTest.cs @@ -75,15 +75,6 @@ namespace Timeline.Tests.IntegratedTests await client.TestGetAssertInvalidModelAsync("timelines?visibility=aaa"); } - var testResultRelate = new List(); - var testResultOwn = new List(); - var testResultJoin = new List(); - var testResultOwnPrivate = new List(); - var testResultRelatePublic = new List(); - var testResultRelateRegister = new List(); - var testResultJoinPrivate = new List(); - var testResultPublic = new List(); - { using var client = await CreateClientAsUser(); @@ -91,6 +82,34 @@ namespace Timeline.Tests.IntegratedTests await client.PutTimelineMemberAsync("t1", "user3"); await client.PatchTimelineAsync("@user1", new() { Visibility = TimelineVisibility.Public }); await client.PatchTimelineAsync("t1", new() { Visibility = TimelineVisibility.Register }); + } + + { + using var client = await CreateClientAs(2); + + await client.PutTimelineMemberAsync("@user2", "user3"); + await client.PutTimelineMemberAsync("t2", "user3"); + await client.PatchTimelineAsync("@user2", new() { Visibility = TimelineVisibility.Register }); + await client.PatchTimelineAsync("t2", new() { Visibility = TimelineVisibility.Private }); + } + + { + using var client = await CreateClientAs(3); + await client.PatchTimelineAsync("@user3", new HttpTimelinePatchRequest { Visibility = TimelineVisibility.Private }); + await client.PatchTimelineAsync("t3", new HttpTimelinePatchRequest { Visibility = TimelineVisibility.Register }); + } + + { + var testResultRelate = new List(); + var testResultOwn = new List(); + var testResultJoin = new List(); + var testResultOwnPrivate = new List(); + var testResultRelatePublic = new List(); + var testResultRelateRegister = new List(); + var testResultJoinPrivate = new List(); + var testResultPublic = new List(); + + using var client = await CreateDefaultClient(); { var timeline = await client.GetTimelineAsync("@user1"); @@ -106,15 +125,6 @@ namespace Timeline.Tests.IntegratedTests testResultJoin.Add(timeline); testResultRelateRegister.Add(timeline); } - } - - { - using var client = await CreateClientAs(2); - - await client.PutTimelineMemberAsync("@user2", "user3"); - await client.PutTimelineMemberAsync("t2", "user3"); - await client.PatchTimelineAsync("@user2", new() { Visibility = TimelineVisibility.Register }); - await client.PatchTimelineAsync("t2", new() { Visibility = TimelineVisibility.Private }); { var timeline = await client.GetTimelineAsync("@user2"); @@ -129,12 +139,6 @@ namespace Timeline.Tests.IntegratedTests testResultJoin.Add(timeline); testResultJoinPrivate.Add(timeline); } - } - - { - using var client = await CreateClientAs(3); - await client.PatchTimelineAsync("@user3", new HttpTimelinePatchRequest { Visibility = TimelineVisibility.Private }); - await client.PatchTimelineAsync("t3", new HttpTimelinePatchRequest { Visibility = TimelineVisibility.Register }); { var timeline = await client.GetTimelineAsync("@user3"); @@ -149,10 +153,6 @@ namespace Timeline.Tests.IntegratedTests testResultOwn.Add(timeline); testResultRelateRegister.Add(timeline); } - } - - { - using var client = await CreateDefaultClient(); async Task TestAgainst(string url, List against) { @@ -413,5 +413,22 @@ namespace Timeline.Tests.IntegratedTests timeline.Color.Should().Be("#112233"); } } + + [Theory] + [MemberData(nameof(TimelineNameGeneratorTestData))] + public async Task Get_Manageable(TimelineNameGenerator generator) + { + { + using var client = await CreateClientAsUser(); + var timeline = await client.TestGetAsync($"timelines/{generator(1)}"); + timeline.Manageable.Should().Be(true); + } + + { + using var client = await CreateClientAs(2); + var timeline = await client.TestGetAsync($"timelines/{generator(1)}"); + timeline.Manageable.Should().Be(false); + } + } } } diff --git a/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs b/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs index 16793de6..e2a08dcb 100644 --- a/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs +++ b/BackEnd/Timeline/Controllers/BookmarkTimelineController.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using System.Collections.Generic; using System.Threading.Tasks; +using Timeline.Entities; using Timeline.Models.Http; using Timeline.Models.Mapper; using Timeline.Models.Validation; @@ -28,6 +29,11 @@ namespace Timeline.Controllers _timelineMapper = timelineMapper; } + private Task> Map(List timelines) + { + return _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId(), this.UserHasPermission(UserPermission.AllTimelineManagement)); + } + /// /// Get bookmark list in order. /// @@ -40,7 +46,7 @@ namespace Timeline.Controllers { var ids = await _service.GetBookmarks(this.GetUserId()); var timelines = await _timelineService.GetTimelineList(ids); - return await _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId()); + return await Map(timelines); } /// diff --git a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs index ea012f76..f582e74b 100644 --- a/BackEnd/Timeline/Controllers/HighlightTimelineController.cs +++ b/BackEnd/Timeline/Controllers/HighlightTimelineController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Timeline.Auth; +using Timeline.Entities; using Timeline.Models.Http; using Timeline.Models.Mapper; using Timeline.Models.Validation; @@ -28,6 +29,11 @@ namespace Timeline.Controllers _timelineMapper = timelineMapper; } + private Task> Map(List timelines) + { + return _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId(), this.UserHasPermission(UserPermission.AllTimelineManagement)); + } + /// /// Get all highlight timelines. /// @@ -38,7 +44,7 @@ namespace Timeline.Controllers { var ids = await _service.GetHighlightTimelines(); var timelines = await _timelineService.GetTimelineList(ids); - return await _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId()); + return await Map(timelines); } /// diff --git a/BackEnd/Timeline/Controllers/SearchController.cs b/BackEnd/Timeline/Controllers/SearchController.cs index dec876b6..b2266c18 100644 --- a/BackEnd/Timeline/Controllers/SearchController.cs +++ b/BackEnd/Timeline/Controllers/SearchController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Threading.Tasks; +using Timeline.Entities; using Timeline.Models.Http; using Timeline.Models.Mapper; using Timeline.Services; @@ -28,6 +29,11 @@ namespace Timeline.Controllers _userMapper = userMapper; } + private Task> Map(List timelines) + { + return _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId(), this.UserHasPermission(UserPermission.AllTimelineManagement)); + } + /// /// Search timelines whose name or title contains query string case-insensitively. /// @@ -40,7 +46,7 @@ namespace Timeline.Controllers { var searchResult = await _service.SearchTimeline(query); var timelines = searchResult.Items.Select(i => i.Item).ToList(); - return await _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId()); + return await Map(timelines); } /// diff --git a/BackEnd/Timeline/Controllers/TimelineController.cs b/BackEnd/Timeline/Controllers/TimelineController.cs index 8479ca83..b20ab227 100644 --- a/BackEnd/Timeline/Controllers/TimelineController.cs +++ b/BackEnd/Timeline/Controllers/TimelineController.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Threading.Tasks; +using Timeline.Entities; using Timeline.Filters; using Timeline.Models; using Timeline.Models.Http; @@ -43,6 +44,16 @@ namespace Timeline.Controllers private bool UserHasAllTimelineManagementPermission => this.UserHasPermission(UserPermission.AllTimelineManagement); + private Task Map(TimelineEntity timeline) + { + return _timelineMapper.MapToHttp(timeline, Url, this.GetOptionalUserId(), UserHasAllTimelineManagementPermission); + } + + private Task> Map(List timelines) + { + return _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId(), UserHasAllTimelineManagementPermission); + } + /// /// List all timelines. /// @@ -102,7 +113,7 @@ namespace Timeline.Controllers } var timelines = await _service.GetTimelines(relationship, visibilityFilter); - var result = await _timelineMapper.MapToHttp(timelines, Url, this.GetOptionalUserId()); + var result = await Map(timelines); return result; } @@ -118,7 +129,7 @@ namespace Timeline.Controllers { var timelineId = await _service.GetTimelineIdByName(timeline); var t = await _service.GetTimeline(timelineId); - var result = await _timelineMapper.MapToHttp(t, Url, this.GetOptionalUserId()); + var result = await Map(t); return result; } @@ -147,7 +158,7 @@ namespace Timeline.Controllers { await _service.ChangeProperty(timelineId, _mapper.Map(body)); var t = await _service.GetTimeline(timelineId); - var result = await _timelineMapper.MapToHttp(t, Url, this.GetOptionalUserId()); + var result = await Map(t); return result; } catch (EntityAlreadyExistException) @@ -237,7 +248,7 @@ namespace Timeline.Controllers try { var timeline = await _service.CreateTimeline(body.Name, userId); - var result = await _timelineMapper.MapToHttp(timeline, Url, this.GetOptionalUserId()); + var result = await Map(timeline); return result; } catch (EntityAlreadyExistException e) when (e.EntityName == EntityNames.Timeline) diff --git a/BackEnd/Timeline/Controllers/TimelinePostController.cs b/BackEnd/Timeline/Controllers/TimelinePostController.cs index 7e3d6900..4026d551 100644 --- a/BackEnd/Timeline/Controllers/TimelinePostController.cs +++ b/BackEnd/Timeline/Controllers/TimelinePostController.cs @@ -49,9 +49,9 @@ namespace Timeline.Controllers return _timelineMapper.MapToHttp(post, timelineName, Url, this.GetOptionalUserId(), UserHasAllTimelineManagementPermission); } - private Task> Map(List post, string timelineName) + private Task> Map(List posts, string timelineName) { - return _timelineMapper.MapToHttp(post, timelineName, Url, this.GetOptionalUserId(), UserHasAllTimelineManagementPermission); + return _timelineMapper.MapToHttp(posts, timelineName, Url, this.GetOptionalUserId(), UserHasAllTimelineManagementPermission); } /// diff --git a/BackEnd/Timeline/Models/Http/HttpTimeline.cs b/BackEnd/Timeline/Models/Http/HttpTimeline.cs index 87ebf0bb..8a865f96 100644 --- a/BackEnd/Timeline/Models/Http/HttpTimeline.cs +++ b/BackEnd/Timeline/Models/Http/HttpTimeline.cs @@ -10,7 +10,7 @@ namespace Timeline.Models.Http { public HttpTimeline() { } - public HttpTimeline(string uniqueId, string title, string name, DateTime nameLastModifed, string description, HttpUser owner, TimelineVisibility visibility, List members, string? color, DateTime createTime, DateTime lastModified, bool isHighlight, bool isBookmark, HttpTimelineLinks links) + public HttpTimeline(string uniqueId, string title, string name, DateTime nameLastModifed, string description, HttpUser owner, TimelineVisibility visibility, List members, string? color, DateTime createTime, DateTime lastModified, bool isHighlight, bool isBookmark, bool manageable, HttpTimelineLinks links) { UniqueId = uniqueId; Title = title; @@ -25,6 +25,7 @@ namespace Timeline.Models.Http LastModified = lastModified; IsHighlight = isHighlight; IsBookmark = isBookmark; + Manageable = manageable; _links = links; } @@ -78,6 +79,7 @@ namespace Timeline.Models.Http public bool IsHighlight { get; set; } public bool IsBookmark { get; set; } + public bool Manageable { get; set; } #pragma warning disable CA1707 // Identifiers should not contain underscores /// diff --git a/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs b/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs index 191e2f70..8dfd7b8d 100644 --- a/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs +++ b/BackEnd/Timeline/Models/Mapper/TimelineMapper.cs @@ -29,13 +29,28 @@ namespace Timeline.Models.Mapper _timelinePostService = timelinePostService; } - public async Task MapToHttp(TimelineEntity entity, IUrlHelper urlHelper, long? userId) + public async Task MapToHttp(TimelineEntity entity, IUrlHelper urlHelper, long? userId, bool isAdministrator) { await _database.Entry(entity).Reference(e => e.Owner).LoadAsync(); await _database.Entry(entity).Collection(e => e.Members).Query().Include(m => m.User).LoadAsync(); var timelineName = entity.Name is null ? "@" + entity.Owner.Username : entity.Name; + bool manageable; + + if (userId is null) + { + manageable = false; + } + else if (isAdministrator) + { + manageable = true; + } + else + { + manageable = await _timelineService.HasManagePermission(entity.Id, userId.Value); + } + return new HttpTimeline( uniqueId: entity.UniqueId, title: string.IsNullOrEmpty(entity.Title) ? timelineName : entity.Title, @@ -50,6 +65,7 @@ namespace Timeline.Models.Mapper lastModified: entity.LastModified, isHighlight: await _highlightTimelineService.IsHighlightTimeline(entity.Id), isBookmark: userId is not null && await _bookmarkTimelineService.IsBookmark(userId.Value, entity.Id, false, false), + manageable: manageable, links: new HttpTimelineLinks( self: urlHelper.ActionLink(nameof(TimelineController.TimelineGet), nameof(TimelineController)[0..^nameof(Controller).Length], new { timeline = timelineName }), posts: urlHelper.ActionLink(nameof(TimelinePostController.List), nameof(TimelinePostController)[0..^nameof(Controller).Length], new { timeline = timelineName }) @@ -57,12 +73,12 @@ namespace Timeline.Models.Mapper ); } - public async Task> MapToHttp(List entities, IUrlHelper urlHelper, long? userId) + public async Task> MapToHttp(List entities, IUrlHelper urlHelper, long? userId, bool isAdministrator) { var result = new List(); foreach (var entity in entities) { - result.Add(await MapToHttp(entity, urlHelper, userId)); + result.Add(await MapToHttp(entity, urlHelper, userId, isAdministrator)); } return result; } -- cgit v1.2.3