From a2cfc3d51b7be1943208901d810e3148e89ec2b3 Mon Sep 17 00:00:00 2001 From: crupest Date: Wed, 5 Feb 2020 18:24:10 +0800 Subject: Improve relate filter. --- Timeline.Tests/IntegratedTests/TimelineTest.cs | 59 ++++++++++++++++++++------ Timeline/Controllers/TimelineController.cs | 16 +++++-- Timeline/Services/TimelineService.cs | 40 ++++++++++++++--- 3 files changed, 92 insertions(+), 23 deletions(-) diff --git a/Timeline.Tests/IntegratedTests/TimelineTest.cs b/Timeline.Tests/IntegratedTests/TimelineTest.cs index 253554df..2500a0c3 100644 --- a/Timeline.Tests/IntegratedTests/TimelineTest.cs +++ b/Timeline.Tests/IntegratedTests/TimelineTest.cs @@ -67,7 +67,9 @@ namespace Timeline.Tests.IntegratedTests { await CreateTestTimelines(); - var testResult = new List(); + var testResultOwn = new List(); + var testResultJoin = new List(); + var testResultAll = new List(); { var client = await CreateClientAsUser(); @@ -84,31 +86,62 @@ namespace Timeline.Tests.IntegratedTests { var res = await client.GetAsync("/users/user1/timeline"); - testResult.Add(res.Should().HaveStatusCode(200) - .And.HaveJsonBody().Which); + var timeline = res.Should().HaveStatusCode(200) + .And.HaveJsonBody().Which; + testResultAll.Add(timeline); + testResultJoin.Add(timeline); } { var res = await client.GetAsync("/timelines/t1"); - testResult.Add(res.Should().HaveStatusCode(200) - .And.HaveJsonBody().Which); - } - - { - var res = await client.GetAsync("/users/user2/timeline"); - testResult.Add(res.Should().HaveStatusCode(200) - .And.HaveJsonBody().Which); + var timeline = res.Should().HaveStatusCode(200) + .And.HaveJsonBody().Which; + testResultAll.Add(timeline); + testResultJoin.Add(timeline); } } - testResult.Add(_testTimelines[2]); + testResultAll.Add(_testTimelines[2]); + testResultOwn.Add(_testTimelines[2]); { var client = await CreateClientAs(2); var res = await client.GetAsync("/timelines?relate=user2"); res.Should().HaveStatusCode(200) .And.HaveJsonBody>() - .Which.Should().BeEquivalentTo(testResult); + .Which.Should().BeEquivalentTo(testResultAll); + } + + { + var client = await CreateClientAs(2); + var res = await client.GetAsync("/timelines?relate=user2&relateType=own"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody>() + .Which.Should().BeEquivalentTo(testResultOwn); + } + + { + var client = await CreateClientAs(2); + var res = await client.GetAsync("/timelines?relate=user2&relateType=join"); + res.Should().HaveStatusCode(200) + .And.HaveJsonBody>() + .Which.Should().BeEquivalentTo(testResultJoin); + } + } + + [Fact] + public async Task TimelineList_InvalidModel() + { + var client = await CreateClientAsUser(); + + { + var res = await client.GetAsync("/timelines?relate=us!!"); + res.Should().BeInvalidModel(); + } + + { + var res = await client.GetAsync("/timelines?relateType=aaa"); + res.Should().BeInvalidModel(); } } diff --git a/Timeline/Controllers/TimelineController.cs b/Timeline/Controllers/TimelineController.cs index 811b0426..47b3696c 100644 --- a/Timeline/Controllers/TimelineController.cs +++ b/Timeline/Controllers/TimelineController.cs @@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Timeline.Filters; using Timeline.Models.Http; @@ -28,14 +29,21 @@ namespace Timeline.Controllers } [HttpGet("timelines")] - public async Task>> TimelineList([FromQuery][Username] string? relate) + public async Task>> TimelineList([FromQuery][Username] string? relate, [FromQuery][RegularExpression("(own)|(join)")] string? relateType) { - long? relatedUserId = null; + TimelineUserRelationship? relationship = null; if (relate != null) { try { - relatedUserId = await _userService.GetUserIdByUsername(relate); + var relatedUserId = await _userService.GetUserIdByUsername(relate); + + relationship = new TimelineUserRelationship(relateType switch + { + "own" => TimelineUserRelationshipType.Own, + "join" => TimelineUserRelationshipType.Join, + _ => TimelineUserRelationshipType.Default + }, relatedUserId); } catch (UserNotExistException) { @@ -43,7 +51,7 @@ namespace Timeline.Controllers } } - var result = await _service.GetTimelines(relatedUserId); + var result = await _service.GetTimelines(relationship); result.ForEach(t => t.FillLinks(Url)); return Ok(result); } diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs index 67a57deb..7afc0512 100644 --- a/Timeline/Services/TimelineService.cs +++ b/Timeline/Services/TimelineService.cs @@ -13,6 +13,25 @@ using static Timeline.Resources.Services.TimelineService; namespace Timeline.Services { + public enum TimelineUserRelationshipType + { + Own = 0b1, + Join = 0b10, + Default = Own | Join + } + + public class TimelineUserRelationship + { + public TimelineUserRelationship(TimelineUserRelationshipType type, long userId) + { + Type = type; + UserId = userId; + } + + public TimelineUserRelationshipType Type { get; set; } + public long UserId { get; set; } + } + /// /// This define the common interface of both personal timeline /// and normal timeline. @@ -231,12 +250,12 @@ namespace Timeline.Services /// /// Get all timelines including personal timelines. /// - /// Filter timelines related (own or is a member) to specific user. + /// Filter timelines related (own or is a member) to specific user. /// The list of timelines. /// /// If user with related user id does not exist, empty list will be returned. /// - Task> GetTimelines(long? relatedUserId = null); + Task> GetTimelines(TimelineUserRelationship? relate = null); /// /// Create a timeline. @@ -628,18 +647,27 @@ namespace Timeline.Services } } - public async Task> GetTimelines(long? relatedUserId = null) + public async Task> GetTimelines(TimelineUserRelationship? relate = null) { List entities; - if (relatedUserId == null) + if (relate == null) { entities = await Database.Timelines.Include(t => t.Members).ToListAsync(); } else { - var timelineAsMemberIds = await Database.TimelineMembers.Where(m => m.UserId == relatedUserId).Select(m => m.TimelineId).ToListAsync(); - entities = await Database.Timelines.Where(t => t.OwnerId == relatedUserId || timelineAsMemberIds.Contains(t.Id)).Include(t => t.Members).ToListAsync(); + entities = new List(); + + if ((relate.Type & TimelineUserRelationshipType.Own) != 0) + { + entities.AddRange(await Database.Timelines.Where(t => t.OwnerId == relate.UserId && t.Name != null).Include(t => t.Members).ToListAsync()); + } + + if ((relate.Type & TimelineUserRelationshipType.Join) != 0) + { + entities.AddRange(await Database.TimelineMembers.Where(m => m.UserId == relate.UserId).Include(m => m.Timeline).ThenInclude(t => t.Members).Select(m => m.Timeline).ToListAsync()); + } } var result = new List(); -- cgit v1.2.3