Skip to content

Commit

Permalink
Merge pull request #341 from ITU-BDSA2024-GROUP10/comment-implementation
Browse files Browse the repository at this point in the history
Comment implementation
  • Loading branch information
math045b authored Nov 28, 2024
2 parents 33a6a12 + e1f9503 commit 14c1531
Show file tree
Hide file tree
Showing 26 changed files with 1,120 additions and 87 deletions.
8 changes: 4 additions & 4 deletions Chirp/src/Chirp.Core/AuthorService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

namespace Chirp.Core;


public interface IAuthorService
{
public List<AuthorDTO> GetFollows(string username);
Expand All @@ -11,13 +10,14 @@ public interface IAuthorService
public bool Unfollow(string currentUser, string userToUnFollow);
public bool MakeFollowersUnfollow(string username);
}

public class AuthorService(IAuthorRepository db) : IAuthorService
{
public List<AuthorDTO> GetFollows(string username)
{
return db.GetAuthorFollows(username).Result;
}

public List<AuthorDTO> GetFollowers(string username)
{
return db.GetAuthorFollowers(username).Result;
Expand All @@ -27,12 +27,12 @@ public bool MakeFollowersUnfollow(string username)
{
return db.MakeFollowersUnfollow(username).Result;
}

public bool Follow(string currentUser, string userToFollow)
{
return db.Follow(currentUser, userToFollow).Result;
}

public bool Unfollow(string currentUser, string userToUnFollow)
{
return db.UnFollow(currentUser, userToUnFollow).Result;
Expand Down
31 changes: 28 additions & 3 deletions Chirp/src/Chirp.Core/CheepService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ public interface ICheepService
public int GetAmountOfCheepPages(int pageSize);
public int GetAmountOfCheepPagesFromAuthors(IEnumerable<String> authors, int pageSize);
public bool CreateCheep(CheepDTO cheep);
public bool AddCommentToCheep(CommentDTO comment);
public int GetCommentAmountOnCheep(int? cheepId);
public CheepDTO GetCheepFromId(int cheepId);
public List<CommentDTO> GetCommentsFromCheep(int cheepId);
}

public class CheepService(ICheepRepository db) : ICheepService
Expand All @@ -19,8 +23,9 @@ public List<CheepDTO> GetCheepsByPage(int page, int pageSize)
{
ArgumentOutOfRangeException.ThrowIfNegative(pageSize);

var result = db.GetCheepsByPage(page, pageSize).Result ?? throw new ArgumentNullException(nameof(db.GetCheepsByPage));

var result = db.GetCheepsByPage(page, pageSize).Result ??
throw new ArgumentNullException(nameof(db.GetCheepsByPage));

return result.ToList();
}

Expand All @@ -33,7 +38,7 @@ public List<CheepDTO> GetCheepsFromAuthorByPage(string author, int page, int pag
{
return db.GetCheepsFromAuthorByPage(author, page, pageSize).Result.ToList();
}

public List<CheepDTO> GetCheepsFromAuthorsByPage(IEnumerable<string> authors, int page, int pageSize)
{
return db.GetCheepsFromAuthorsByPage(authors, page, pageSize).Result.ToList();
Expand All @@ -53,4 +58,24 @@ public bool CreateCheep(CheepDTO cheep)
{
return db.CreateCheep(cheep).Result;
}

public bool AddCommentToCheep(CommentDTO comment)
{
return db.AddCommentToCheep(comment).Result;
}

public int GetCommentAmountOnCheep(int? cheepId)
{
return db.GetCommentAmountOnCheep(cheepId).Result;
}

public CheepDTO GetCheepFromId(int cheepId)
{
return db.GetCheepById(cheepId).Result;
}

public List<CommentDTO> GetCommentsFromCheep(int cheepId)
{
return db.GetCommentsForCheep(cheepId).Result.ToList();
}
}
3 changes: 2 additions & 1 deletion Chirp/src/Chirp.Core/DTO/CheepDTO.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
namespace Chirp.Core.DTO;

public class CheepDTO(string author, string message, long unixTimestamp)
public class CheepDTO(int? id, string author, string message, long unixTimestamp)
{
public int? Id { get; set; } = id;
public string Author { get; set; } = author;
public string Message { get; set; } = message;
public long UnixTimestamp { get; set; } = unixTimestamp;
Expand Down
9 changes: 9 additions & 0 deletions Chirp/src/Chirp.Core/DTO/CommentDTO.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Chirp.Core.DTO;

public class CommentDTO(string author, int cheepId, string message, long unixTimestamp)
{
public string Author { get; set; } = author;
public int CheepId { get; set; } = cheepId;
public string Message { get; set; } = message;
public long UnixTimestamp { get; set; } = unixTimestamp;
}
4 changes: 2 additions & 2 deletions Chirp/src/Chirp.Core/IAuthorRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ public interface IAuthorRepository
public Task<bool> AddAuthor(AuthorDTO author);
public Task<List<AuthorDTO>> GetAuthorFollows(string username);
public Task<List<AuthorDTO>> GetAuthorFollowers(string username);
public Task<bool> Follow (string currentUser, string userToFollow);
public Task<bool> UnFollow (string currentUser, string userToUnFollow);
public Task<bool> Follow(string currentUser, string userToFollow);
public Task<bool> UnFollow(string currentUser, string userToUnFollow);
public Task<bool> MakeFollowersUnfollow(string user);
}
7 changes: 6 additions & 1 deletion Chirp/src/Chirp.Core/ICheepRepository.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Chirp.Core.DTO;
using System.Collections;
using Chirp.Core.DTO;

namespace Chirp.Core;

Expand All @@ -11,4 +12,8 @@ public interface ICheepRepository
public Task<bool> CreateCheep(CheepDTO cheep);
public Task<int> GetAmountOfCheeps();
public Task<int> GetAmountOfCheepsFromAuthors(IEnumerable<String> authors);
public Task<bool> AddCommentToCheep(CommentDTO comment);
public Task<int> GetCommentAmountOnCheep(int? cheepId);
public Task<CheepDTO> GetCheepById(int cheepId);
public Task<IEnumerable<CommentDTO>> GetCommentsForCheep(int cheepId);
}
24 changes: 12 additions & 12 deletions Chirp/src/Chirp.Infrastructure/AuthorRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public async Task<List<AuthorDTO>> GetAuthorFollowers(string username)
.Where(a => a.NormalizedUserName == username.ToUpper())
.Select(a => a.Followers)
.FirstOrDefaultAsync() ?? new List<Author>();

return followers.Select(a => new AuthorDTO(a.UserName!, a.Email!)).ToList();
}

Expand All @@ -53,10 +53,10 @@ public async Task<bool> Follow(string currentUser, string userToFollow)
if (!await UserExists(currentUser)) throw new UserDoesNotExist();
if (!await UserExists(userToFollow)) throw new UserDoesNotExist("User to follow does not exist");
if (await DoesFollow(currentUser, userToFollow)) return false;

var authorToFollow = await GetAuthor(userToFollow);
GetAuthor(currentUser).Result.Following.Add(authorToFollow);

await context.SaveChangesAsync();
return true;
}
Expand All @@ -69,17 +69,17 @@ public async Task<bool> UnFollow(string currentUser, string userToUnfollow)
if (!await UserExists(currentUser)) throw new UserDoesNotExist();
if (!await UserExists(userToUnfollow)) throw new UserDoesNotExist("User to unfollow does not exist");
if (!await DoesFollow(currentUser, userToUnfollow)) return false;

var authorToUnfollow = await GetAuthor(userToUnfollow);
context.Authors
.Where(a => a.NormalizedUserName == currentUser)
.Include(a => a.Following)
.FirstOrDefault()!.Following.Remove(authorToUnfollow);

await context.SaveChangesAsync();
return true;
}

private async Task<Author> GetAuthor(string username)
{
username = username.ToUpper();
Expand All @@ -98,14 +98,14 @@ private async Task<bool> DoesFollow(string currentUser, string userToFollow)
{
currentUser = currentUser.ToUpper();
userToFollow = userToFollow.ToUpper();
var list = await context.Authors
.Where(a => a.NormalizedUserName == currentUser)
.Select(a => a.Following).FirstOrDefaultAsync();
return list != null && list.Any(a => a.NormalizedUserName == userToFollow);
var list = await context.Authors
.Where(a => a.NormalizedUserName == currentUser)
.Select(a => a.Following).FirstOrDefaultAsync();

return list != null && list.Any(a => a.NormalizedUserName == userToFollow);
}

private async Task<List<Author>> GetFollowing(string currentUser)
private async Task<IEnumerable<Author>> GetFollowing(string currentUser)
{
currentUser = currentUser.ToUpper();
return await context.Authors
Expand Down
85 changes: 75 additions & 10 deletions Chirp/src/Chirp.Infrastructure/CheepRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,17 +12,18 @@ public class CheepRepository(ChirpDBContext context) : ICheepRepository
public async Task<IEnumerable<CheepDTO>?> GetCheepsByPage(int page, int pageSize)
{
if (pageSize < 0) return null;

var query = context.Cheeps
.Select(cheep => new { cheep.Author.UserName, cheep.Message, cheep.TimeStamp })
.Select(cheep => new { cheep.Id, cheep.Author.UserName, cheep.Message, cheep.TimeStamp })
.OrderByDescending(cheep => cheep.TimeStamp)
.Skip((page - 1) * pageSize)
.Take(pageSize);

var cheeps = await query.ToListAsync();

return cheeps.Select(cheep =>
new CheepDTO(cheep.UserName!, cheep.Message, new DateTimeOffset(cheep.TimeStamp).ToUnixTimeSeconds()));
new CheepDTO(cheep.Id, cheep.UserName!, cheep.Message,
new DateTimeOffset(cheep.TimeStamp).ToUnixTimeSeconds()));
}

public async Task<IEnumerable<CheepDTO>> GetCheepsFromAuthorByPage(string author, int page, int pageSize)
Expand All @@ -35,28 +36,31 @@ public async Task<IEnumerable<CheepDTO>> GetCheepsFromAuthor(string author)
author = author.ToUpper();
var query = context.Cheeps
.Where(cheep => cheep.Author.NormalizedUserName == author)
.Select(cheep => new { cheep.Author.UserName, cheep.Message, cheep.TimeStamp })
.Select(cheep => new { cheep.Id, cheep.Author.UserName, cheep.Message, cheep.TimeStamp })
.OrderByDescending(cheep => cheep.TimeStamp);
var cheeps = await query.ToListAsync();

return cheeps.Select(cheep =>
new CheepDTO(cheep.UserName!, cheep.Message, new DateTimeOffset(cheep.TimeStamp).ToUnixTimeSeconds()));
new CheepDTO(cheep.Id, cheep.UserName!, cheep.Message,
new DateTimeOffset(cheep.TimeStamp).ToUnixTimeSeconds()));
}

public async Task<IEnumerable<CheepDTO>> GetCheepsFromAuthorsByPage(IEnumerable<string> authors, int page, int pageSize)

public async Task<IEnumerable<CheepDTO>> GetCheepsFromAuthorsByPage(IEnumerable<string> authors, int page,
int pageSize)
{
authors = authors.Select(author => author.ToUpper());
var query = context.Cheeps
.Where(cheep => authors.Contains(cheep.Author.NormalizedUserName!))
.Select(cheep => new { cheep.Author.UserName, cheep.Message, cheep.TimeStamp })
.Select(cheep => new { cheep.Id, cheep.Author.UserName, cheep.Message, cheep.TimeStamp })
.OrderByDescending(cheep => cheep.TimeStamp)
.Skip((page - 1) * pageSize)
.Take(pageSize);

var cheeps = await query.ToListAsync();

return cheeps.Select(cheep =>
new CheepDTO(cheep.UserName!, cheep.Message, new DateTimeOffset(cheep.TimeStamp).ToUnixTimeSeconds()));
new CheepDTO(cheep.Id, cheep.UserName!, cheep.Message,
new DateTimeOffset(cheep.TimeStamp).ToUnixTimeSeconds()));
}

public Task<int> GetAmountOfCheeps()
Expand All @@ -77,9 +81,70 @@ public async Task<bool> CreateCheep(CheepDTO cheep)
.Where(a => a.UserName == cheep.Author)
.FirstOrDefaultAsync();
if (author == null) return false;
var cheep2 = new Cheep {Author = author, Message = cheep.Message, TimeStamp = DateTimeOffset.FromUnixTimeSeconds(cheep.UnixTimestamp).DateTime};
var cheep2 = new Cheep
{
Author = author, Message = cheep.Message,
TimeStamp = DateTimeOffset.FromUnixTimeSeconds(cheep.UnixTimestamp).DateTime
};
context.Cheeps.Add(cheep2);
await context.SaveChangesAsync();
return true;
}

public async Task<bool> AddCommentToCheep(CommentDTO comment)
{
var author = await context.Authors
.Where(a => a.UserName == comment.Author)
.FirstOrDefaultAsync();
if (author == null) return false;
var cheep = await context.Cheeps
.Where(c => c.Id == comment.CheepId)
.Include(c => c.Comments)
.FirstOrDefaultAsync();
if (cheep == null) return false;
var newComment = new Comment
{
Author = author, Cheep = cheep, Message = comment.Message,
TimeStamp = DateTimeOffset.FromUnixTimeSeconds(comment.UnixTimestamp).DateTime
};
cheep.Comments.Add(newComment);
await context.SaveChangesAsync();
return true;
}

public async Task<int> GetCommentAmountOnCheep(int? cheepId)
{
if (cheepId == null) return 0;
var query = await context.Cheeps
.Include(c => c.Comments)
.Where(c => c.Id == cheepId)
.FirstOrDefaultAsync();
var commentCount = query!.Comments.Count;
return commentCount;
}

public async Task<CheepDTO> GetCheepById(int cheepId)
{
var cheep = await context.Cheeps
.Where(c => c.Id == cheepId)
.Select(cheep => new { cheep.Id, cheep.Author.UserName, cheep.Message, cheep.TimeStamp })
.FirstOrDefaultAsync();

return new CheepDTO(cheep!.Id, cheep.UserName!, cheep.Message,
new DateTimeOffset(cheep.TimeStamp).ToUnixTimeSeconds());
;
}

public async Task<IEnumerable<CommentDTO>> GetCommentsForCheep(int cheepId)
{
var query = await context.Cheeps
.Where(c => c.Id == cheepId)
.Include(c => c.Comments)
.ThenInclude(comment => comment.Author)
.FirstOrDefaultAsync();
var comments = query!.Comments.OrderByDescending(c => c.TimeStamp);
return comments.Select(comment =>
new CommentDTO(comment.Author.UserName!, comment.Id, comment.Message,
new DateTimeOffset(comment.TimeStamp).ToUnixTimeSeconds()));
}
}
6 changes: 3 additions & 3 deletions Chirp/src/Chirp.Infrastructure/Chirp.Infrastructure.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\Chirp.Core\Chirp.Core.csproj" />
<ProjectReference Include="..\Chirp.Core\Chirp.Core.csproj"/>
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentValidation" Version="11.10.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.10" />
<PackageReference Include="FluentValidation" Version="11.10.0"/>
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.10"/>
</ItemGroup>

</Project>
24 changes: 23 additions & 1 deletion Chirp/src/Chirp.Infrastructure/ChirpDbContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class ChirpDBContext(DbContextOptions<ChirpDBContext> options) : Identity
{
public DbSet<Cheep> Cheeps { get; set; }
public DbSet<Author> Authors { get; set; }
public DbSet<Comment> Comments { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
Expand Down Expand Up @@ -51,6 +52,27 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
.WithMany(a => a.Followers);
});


//define comment entity constraints
modelBuilder.Entity<Comment>(entity =>
{
entity.HasKey((c => c.Id));
entity.Property(c => c.Id)
.ValueGeneratedOnAdd();

entity.Property(c => c.Message)
.IsRequired()
.HasMaxLength(160);
entity.Property(c => c.TimeStamp)
.IsRequired();
entity.HasOne(c => c.Author)
.WithMany(a => a.Comments)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);

entity.HasOne(c => c.Cheep)
.WithMany(c => c.Comments)
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
});
}
}
Loading

0 comments on commit 14c1531

Please sign in to comment.