From c2b107eda8a14f836d663638641a3e3f17373b5d Mon Sep 17 00:00:00 2001 From: crupest Date: Sun, 17 Nov 2019 18:56:27 +0800 Subject: Complete personal timeline service without tests. --- Timeline/Services/TimelineService.cs | 126 +++++++++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 5 deletions(-) diff --git a/Timeline/Services/TimelineService.cs b/Timeline/Services/TimelineService.cs index eff0c3fc..494beb11 100644 --- a/Timeline/Services/TimelineService.cs +++ b/Timeline/Services/TimelineService.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; @@ -214,6 +215,7 @@ namespace Timeline.Services /// /// Username or the timeline name. See remarks of . /// The user to check on. + /// True if it is a member, false if not. /// Thrown when or is null. /// /// Thrown when timeline name is of bad format. @@ -231,8 +233,11 @@ namespace Timeline.Services /// Thrown when is not a valid username. /// /// - /// Thrown when user does not exist. - /// True if it is a member, false if not. + /// Thrown when user does not exist. + /// + /// + /// Timeline owner is also considered as a member. + /// Task IsMemberOf(string name, string username); } @@ -296,7 +301,7 @@ namespace Timeline.Services public abstract class BaseTimelineService : IBaseTimelineService { - protected BaseTimelineService(DatabaseContext database, IClock clock) + protected BaseTimelineService(ILoggerFactory loggerFactory, DatabaseContext database, IClock clock) { Clock = clock; Database = database; @@ -600,13 +605,124 @@ namespace Timeline.Services var timelineEntity = await Database.Timelines.Where(t => t.Id == timelineId).Select(t => new { t.OwnerId }).SingleAsync(); - var postEntitu = await Database.Timelines. // TODO! + var postEntity = await Database.Timelines.Where(p => p.Id == id).Select(p => new { p.OwnerId }).SingleOrDefaultAsync(); + + if (postEntity == null) + throw new TimelinePostNotExistException(id); + + return timelineEntity.OwnerId == userId || postEntity.OwnerId == userId; + } + + public async Task IsMemberOf(string name, string username) + { + if (name == null) + throw new ArgumentNullException(nameof(name)); + if (username == null) + throw new ArgumentNullException(nameof(username)); - if (timelineEntity.OwnerId == userId) { + var (result, message) = UsernameValidator.Validate(username); + if (!result) + { + throw new UsernameBadFormatException(username); + } + } + + var user = await Database.Users.Where(u => u.Name == username).Select(u => new { u.Id }).SingleOrDefaultAsync(); + + if (user == null) + { + throw new UserNotExistException(username); + } + + var userId = user.Id; + + var timelineId = await FindTimelineId(name); + + var timelineEntity = await Database.Timelines.Where(t => t.Id == timelineId).Select(t => new { t.OwnerId }).SingleAsync(); + + if (userId == timelineEntity.OwnerId) return true; + + var timelineMemberEntity = await Database.TimelineMembers.Where(m => m.TimelineId == timelineId && m.UserId == userId).SingleOrDefaultAsync(); + + return timelineMemberEntity != null; + } + } + + public class PersonalTimelineService : BaseTimelineService, IPersonalTimelineService + { + public PersonalTimelineService(ILoggerFactory loggerFactory, DatabaseContext database, IClock clock) + : base(loggerFactory, database, clock) + { + + } + + protected override async Task FindTimelineId(string name) + { + { + var (result, message) = UsernameValidator.Validate(name); + if (!result) + { + throw new TimelineNameBadFormatException(name, new UsernameBadFormatException(name, message)); + } + } + + var userEntity = await Database.Users.Where(u => u.Name == name).Select(u => new { u.Id }).SingleOrDefaultAsync(); + + if (userEntity == null) + { + throw new TimelineNotExistException(name, new UserNotExistException(name)); + } + + var userId = userEntity.Id; + + var timelineEntity = await Database.Timelines.Where(t => t.OwnerId == userId && t.Name == null).Select(t => new { t.Id }).SingleOrDefaultAsync(); + + if (timelineEntity != null) + { + return timelineEntity.Id; + } + else + { + var newTimelineEntity = new TimelineEntity + { + Name = null, + Description = null, + OwnerId = userId, + Visibility = TimelineVisibility.Register, + CreateTime = Clock.GetCurrentTime(), + }; + Database.Timelines.Add(newTimelineEntity); + await Database.SaveChangesAsync(); + + return newTimelineEntity.Id; } } + public async Task GetTimeline(string username) + { + if (username == null) + throw new ArgumentNullException(nameof(username)); + + var timelineId = await FindTimelineId(username); + + var timelineEntity = await Database.Timelines.Where(t => t.Id == timelineId).SingleAsync(); + + var timelineMemberEntities = await Database.TimelineMembers.Where(m => m.TimelineId == timelineId).Select(m => new { m.UserId }).ToListAsync(); + + var memberUsernameTasks = timelineMemberEntities.Select(m => Database.Users.Where(u => u.Id == m.UserId).Select(u => u.Name).SingleAsync()).ToArray(); + + var memberUsernames = await Task.WhenAll(memberUsernameTasks); + + return new BaseTimelineInfo + { + Description = timelineEntity.Description, + Owner = username, + Visibility = timelineEntity.Visibility, + Members = memberUsernames.ToList() + }; + } + } } -- cgit v1.2.3