Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.0 Release #556

Merged
merged 59 commits into from
Apr 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
c6df7f7
started adding data for testing
Jackson-Williams-15 Apr 13, 2024
6b7d9ca
442: Assert valid date & time on post update
evan-scales Apr 13, 2024
cfca6ef
remove using statement
evan-scales Apr 13, 2024
8d53a1d
running correctly, but tags aren't working (didn't mess with them)
AaronKeys Apr 14, 2024
2d0521b
Merge branch 'main' into profileDescCharLimit
AaronKeys Apr 14, 2024
f2100a2
516: Show end date on day overflow
evan-scales Apr 16, 2024
19942b0
Merge pull request #537 from SCCapstone/prod
evan-scales Apr 17, 2024
896f3fa
Import screenshots
jbytes1027 Apr 17, 2024
be3a609
stores auth token to post game data
Jackson-Williams-15 Apr 18, 2024
2cc88e8
added tags, more games, and create post data/API call
Jackson-Williams-15 Apr 18, 2024
0943cbf
Merge pull request #539 from SCCapstone/FixImages
evan-scales Apr 18, 2024
831ea7a
Merge branch 'main' into 442
evan-scales Apr 18, 2024
412a5eb
442: Fix review points
evan-scales Apr 18, 2024
6ba67e1
remove bad comment
evan-scales Apr 18, 2024
30eeafe
Merge pull request #532 from SCCapstone/516
evan-scales Apr 18, 2024
7176086
Merge pull request #523 from SCCapstone/profileDescCharLimit
evan-scales Apr 18, 2024
3d730cf
Merge pull request #510 from SCCapstone/442
evan-scales Apr 18, 2024
0db6174
Merge remote-tracking branch 'origin' into DiscoverBehavioralTesting
Jackson-Williams-15 Apr 19, 2024
e7471ad
add more users
Jackson-Williams-15 Apr 19, 2024
62febfa
generates 48 test post templates
Jackson-Williams-15 Apr 19, 2024
77c24cc
added more variety to the posts dates and times for filtering test. A…
Jackson-Williams-15 Apr 19, 2024
d0a39d7
updated time and date, prevents from making dates in the past
Jackson-Williams-15 Apr 19, 2024
7b5622e
format
Jackson-Williams-15 Apr 19, 2024
f8db826
Added comments and update README.md
epadams Apr 20, 2024
4c9dc7e
Update README.md
epadams Apr 20, 2024
18e7cd0
added special character to password
Jackson-Williams-15 Apr 21, 2024
2de5442
Fixed silent errors and added email checking
epadams Apr 21, 2024
a004bea
limit tags to 6
Jackson-Williams-15 Apr 21, 2024
e528901
age validation for profile working
AaronKeys Apr 21, 2024
4154ec5
lint, format, comments, small changes
AaronKeys Apr 21, 2024
bc96a8d
fixed the problem with error showing on start
AaronKeys Apr 21, 2024
19e26a0
add some more comments
evan-scales Apr 21, 2024
e7bcab8
ran formatter
evan-scales Apr 21, 2024
337c310
383: Comment helpers
evan-scales Apr 21, 2024
c1d8863
Update README.md
evan-scales Apr 21, 2024
b0148a5
comment dtos
evan-scales Apr 21, 2024
83b2209
Merge branch '382' of https://github.com/SCCapstone/PalmettoProgramme…
evan-scales Apr 21, 2024
7c6fe9c
Merge pull request #547 from SCCapstone/SilentFail
epadams Apr 21, 2024
f2c8f2e
Merge pull request #552 from SCCapstone/383
epadams Apr 21, 2024
ff27509
Merge pull request #550 from SCCapstone/errorOnPostStart
epadams Apr 21, 2024
1168317
Fix for the tag helper text showing, when there are 6 or less tags.
AaronKeys Apr 21, 2024
8066e30
format and lint
AaronKeys Apr 21, 2024
9892e58
Merge branch 'main' into CommentSPA
evan-scales Apr 22, 2024
2bc88d0
Merge pull request #543 from SCCapstone/CommentSPA
evan-scales Apr 22, 2024
0cfa3a5
Merge pull request #540 from SCCapstone/DiscoverBehavioralTesting
epadams Apr 22, 2024
7a555a6
Merge pull request #553 from SCCapstone/382
epadams Apr 22, 2024
f054ad4
Cleanup, use native field error, allow clearing DOB
epadams Apr 22, 2024
ef1fa2e
Lint and format
epadams Apr 22, 2024
84c1e56
Remove unessecary values
epadams Apr 22, 2024
3d9d8f2
Merge pull request #549 from SCCapstone/ageValidation
epadams Apr 22, 2024
ade095d
Merge pull request #554 from SCCapstone/postTagText
epadams Apr 22, 2024
fe5a64c
Update demo
jbytes1027 Apr 22, 2024
ee57e36
limits tag characters to 10 and overall tag count to 4 and includes e…
Jackson-Williams-15 Apr 22, 2024
c3e6abd
format
Jackson-Williams-15 Apr 22, 2024
9a86ae2
Merge remote-tracking branch 'origin/main' into LimitTags
Jackson-Williams-15 Apr 22, 2024
e23d530
Merge pull request #548 from SCCapstone/LimitTags
Jackson-Williams-15 Apr 22, 2024
051214d
Merge pull request #555 from SCCapstone/DemoVideo
evan-scales Apr 22, 2024
dd95846
fix chat input
evan-scales Apr 22, 2024
33d16b2
Merge pull request #558 from SCCapstone/fixChatInput
evan-scales Apr 22, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/Chat/ChatResponseDTO.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
namespace FU.API.DTOs.Chat;

/// <summary>
/// The response DTO for chat.
/// Members is a collection of usernames.
/// </summary>
public class ChatResponseDTO
{
public int Id { get; set; }
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/Chat/MessageResponseDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

using FU.API.Models;

/// <summary>
/// The response DTO for message.
/// Sender is the user who sent the message, and contains the username and avatar.
/// </summary>
public class MessageResponseDTO
{
public int Id { get; set; }
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/Game/GameDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
using FU.API.Validation;
using System.ComponentModel.DataAnnotations;

/// <summary>
/// The DTO for creating/retrieving games.
/// Name is the name of the game.
/// </summary>
public class GameDTO
{
public int Id { get; set; }
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/Game/UpdateGameDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
using FU.API.Validation;
using System.ComponentModel.DataAnnotations;

/// <summary>
/// The DTO for updating games.
/// Only Name and ImageUrl can be updated.
/// </summary>
public class UpdateGameDTO
{
[NonEmptyString]
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/LoginRequestDTO.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
namespace FU.API.DTOs;

/// <summary>
/// The request DTO for login.
/// Used for logging in.
/// </summary>
public class LoginRequestDTO
{
public string Username { get; set; } = string.Empty;
Expand Down
5 changes: 5 additions & 0 deletions FU.API/FU.API/DTOs/Post/PostRequestDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
using FU.API.Validation;
using System.ComponentModel.DataAnnotations;

/// <summary>
/// The DTO for creating posts.
/// Needs a title and a gameId.
/// TagIds is a list of tag ids.
/// </summary>
public class PostRequestDTO
{
[NonEmptyString]
Expand Down
7 changes: 7 additions & 0 deletions FU.API/FU.API/DTOs/Post/PostResponseDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,13 @@
using FU.API.DTOs.Chat;
using FU.API.Models;

/// <summary>
/// The response DTO for post.
/// May contain reference to the last message in the chat.
/// Includes the creator of the post.
/// Include the game name, and list of tag names.
/// Indicates if the current user has joined the post.
/// </summary>
public class PostResponseDTO
{
public int Id { get; set; }
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/ResendConfirmationDTO.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
namespace FU.API.DTOs;

/// <summary>
/// The DTO for resending a confirmation email.
/// May be trying to find the user by email or username.
/// </summary>
public class ResendConfirmationDTO
{
public string? Email { get; set; }
Expand Down
5 changes: 5 additions & 0 deletions FU.API/FU.API/DTOs/Search/PostSearchRequestDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ namespace FU.API.DTOs.Search;

using Microsoft.AspNetCore.Mvc;

/// <summary>
/// Represents a request to search for posts.
/// All properties are optional.
/// Will be converted to a PostQuery.
/// </summary>
public record PostSearchRequestDTO
{
[FromQuery]
Expand Down
5 changes: 5 additions & 0 deletions FU.API/FU.API/DTOs/Search/UserSearchRequestDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ namespace FU.API.DTOs.Search;

using Microsoft.AspNetCore.Mvc;

/// <summary>
/// The request DTO for searching for users.
/// All properties are optional.
/// Will be converted to a UserQuery.
/// </summary>
public record UserSearchRequestDTO
{
[FromQuery]
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/Tag/TagRequestDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
using System.ComponentModel.DataAnnotations;
using FU.API.Validation;

/// <summary>
/// The DTO for creating tags.
/// Tag names can't be longer than 20 characters.
/// </summary>
public class TagRequestDTO
{
[NoSpaces]
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/DTOs/Tag/TagResponseDTO.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
namespace FU.API.DTOs.Tag;

/// <summary>
/// The response DTO for tags.
/// Includes the tag's id and name.
/// </summary>
public class TagResponseDTO
{
public int Id { get; set; }
Expand Down
3 changes: 3 additions & 0 deletions FU.API/FU.API/DTOs/UpdateCredentialDTO.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
using FU.API.Validation;
using System.ComponentModel.DataAnnotations;

/// <summary>
/// Used for updating credentials.
/// </summary>
public record UpdateCredentailsDTO
{
[NonEmptyString]
Expand Down
3 changes: 3 additions & 0 deletions FU.API/FU.API/DTOs/User/UserRelationDTO.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
namespace FU.API.DTOs.User;

/// <summary>
/// The response DTO for user relations.
/// </summary>
public class UserRelationDTO
{
public string Status { get; set; } = string.Empty;
Expand Down
4 changes: 4 additions & 0 deletions FU.API/FU.API/Helpers/AuthHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
using System.Security.Claims;
using System.Text;

/// <summary>
/// Helper class for creating authentication tokens.
/// Used when a user logs in or sending account verification emails.
/// </summary>
public static class AuthHelper
{
public static AuthenticationInfo CreateAuthInfo(IConfiguration configuration, DateTime expires, int userId)
Expand Down
5 changes: 5 additions & 0 deletions FU.API/FU.API/Helpers/Mapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ namespace FU.API.Helpers;
using FU.API.DTOs.User;
using FU.API.DTOs;

/// <summary>
/// A static class that contains extension methods for mapping between DTOs and models.
/// Used to keep the controllers clean.
/// Simple mapping, and no complex logic.
/// </summary>
public static class Mapper
{
public static UserProfile ToProfile(this ApplicationUser appUser, Message? lastChatMessage = null)
Expand Down
2 changes: 2 additions & 0 deletions FU.API/FU.API/Services/PostService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ public async Task<Post> UpdatePost(Post postChanges)
throw new PostException("The updated post's creator does not match the old post's creator", HttpStatusCode.UnprocessableEntity);
}

AssertValidDateAndTime(postChanges);

ogPost.Game = await _dbContext.Games.FindAsync(postChanges.GameId) ?? throw new NonexistentGameException();
ogPost.Description = postChanges.Description;
ogPost.MaxPlayers = postChanges.MaxPlayers;
Expand Down
180 changes: 128 additions & 52 deletions FU.API/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,76 @@
- Azure Communication Service is used to send emails
- Docker can be used for containerization

## Development

### External Requirements

In order to run the project you first have to install:

- [ASP.NET Core 7](https://learn.microsoft.com/en-us/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-7.0)
- [PostgreSQL](https://www.postgresql.org/download/)

### Postgres Setup

Install and start the database by installing Docker and running the following command.

```
docker run --name postgres-490 -e POSTGRES_DB=fu_dev -e POSTGRES_PASSWORD=dev -e POSTGRES_USER=dev -p 5432:5432 postgres:alpine
```

To run the container at a later time, run:

```
docker container start postgres-490
```

Alternatively, install and start a PostgreSQL database manually.

### Config Setup

Config settings are loaded from the environment variables. To automatically load the environment variable from a file, create a `.env` file in this folder.

#### Blob storage

An azure storage account is needed with a storage container. Public anonymous access must be enabled. The `STORAGE_CONNECTION_STRING` and `AVATAR_CONTAINER_NAME` environment variables must be set.

```
STORAGE_CONNECTION_STRING="XXXXXXXX"
AVATAR_CONTAINER_NAME="some-container-name"
```

#### Jwt Secret

A random string of 32+ characters is required in the `JWT_SECRET` environment variable as a Jwt Secret.

```
JWT_SECRET="my-32-character-ultra-secure-and-ultra-long-secret"
```

#### Email service

An azure communication service is needed to send emails.

```
EMAIL_CONNECTION_STRING="XXXXXXXX"
```

#### Connect to Postgres

Set the postgres `CONNECTION_STRING` environment variable.

```
CONNECTION_STRING="Host=localhost; Database=fu_dev; Username=dev; Password=dev"
```

### Coding Style

Follow Google's C# [style guide](https://google.github.io/styleguide/csharp-style.html)

## Testing

Run tests on the backend with `dotnet test`. Tests are located in `FU.API.Tests/`. They consist of service unit tests as behavioral testing is done by the SPA.

## Understanding Controllers

The controllers serve as wrappers around the Services. They take an http request, run a corresponding service calls, and return an http result. For example consider the following `GameController` class.
Expand Down Expand Up @@ -73,72 +143,78 @@ When users navigate to a pages with a chat, they will be connected the chat grou

First an avatar is uploaded to the server via `AvatarController.UploadAvatar`. Then it is validated to be an image, cropped to be square, resized, and converted to a JPEG using the `SkiaSharp` library. Then the image is uploaded to a public azure storage blob and its a url is returned to the user for previewing. If the user wants to use the image, they call `UsersController.UpdateProfile` to set it as their new avatar. After awhile, unused profile pictures are deleted by `PeriodicRemoteStorageCleanerHostedService`.

## Development
## Understanding DTOs

### External Requirements
DTOs, or Data Transfer Objects, serve as simple objects that carry data between processes, typically between a client and a server.

In order to run the project you first have to install:
Consider the following DTO as an example:

- [ASP.NET Core 7](https://learn.microsoft.com/en-us/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-7.0)
- [PostgreSQL](https://www.postgresql.org/download/)

### Postgres Setup

Install and start the database by installing Docker and running the following command.

```
docker run --name postgres-490 -e POSTGRES_DB=fu_dev -e POSTGRES_PASSWORD=dev -e POSTGRES_USER=dev -p 5432:5432 postgres:alpine
```
public record UserSearchRequestDTO
{
[FromQuery]
public string? Keywords { get; set; }

To run the container at a later time, run:
[FromQuery]
public string? Sort { get; set; }

```
docker container start postgres-490
```

Alternatively, install and start a PostgreSQL database manually.

### Config Setup

Config settings are loaded from the environment variables. To automatically load the environment variable from a file, create a `.env` file in this folder.

#### Blob storage

An azure storage account is needed with a storage container. Public anonymous access must be enabled. The `STORAGE_CONNECTION_STRING` and `AVATAR_CONTAINER_NAME` environment variables must be set.
[FromQuery]
public int? Limit { get; set; }

[FromQuery]
public int? Page { get; set; }
}
```
STORAGE_CONNECTION_STRING="XXXXXXXX"
AVATAR_CONTAINER_NAME="some-container-name"
```

In this example, UserSearchRequestDTO is a DTO used for handling user search requests. It contains properties for keywords, sorting criteria, pagination limits, and page numbers. The [FromQuery] attribute indicates that the properties should be bound from the query string when used in our ASP.NET Web API.

#### Jwt Secret

A random string of 32+ characters is required in the `JWT_SECRET` environment variable as a Jwt Secret.
To process the user search request, a static mapper class is utilized to convert the UserSearchRequestDTO to a UserQuery. Here's an example of how it's done:

```
JWT_SECRET="my-32-character-ultra-secure-and-ultra-long-secret"
```

#### Email service

An azure communication service is needed to send emails.
public static class Mapper
{
...
public static UserQuery ToUserQuery(this UserSearchRequestDTO dto)
{
var query = new UserQuery()
{
Limit = dto.Limit ?? 20,
Page = dto.Page ?? 1,
SortType = UserSortType.Username, // Default value
SortDirection = SortDirection.Ascending // Default value
};

// Splitting keywords if provided
if (dto.Keywords is not null)
{
query.Keywords = dto.Keywords.Split(" ").ToList();
}

```
EMAIL_CONNECTION_STRING="XXXXXXXX"
```
// Setting default sort if not provided
dto.Sort ??= "newest:desc";

#### Connect to Postgres
// Parsing and setting sort type and direction
var arr = dto.Sort.ToLower().Split(":");
query.SortType = arr[0] switch
{
"username" => UserSortType.Username,
"dob" => UserSortType.DOB,
"chatactivity" => UserSortType.ChatActivity,
_ => UserSortType.Username,
};

Set the postgres `CONNECTION_STRING` environment variable.
if (arr.Length > 1 && arr[1].StartsWith("desc"))
{
query.SortDirection = SortDirection.Descending;
}
else
{
query.SortDirection = SortDirection.Ascending;
}

return query;
}
}
```
CONNECTION_STRING="Host=localhost; Database=fu_dev; Username=dev; Password=dev"
```

### Coding Style

Follow Google's C# [style guide](https://google.github.io/styleguide/csharp-style.html)

## Testing

Run tests on the backend with `dotnet test`. Tests are located in `FU.API.Tests/`. They consist of service unit tests as behavioral testing is done by the SPA.
This static mapper class contains a method ToUserQuery which takes a UserSearchRequestDTO and converts it into a UserQuery object, which is then used in the search service to perform the actual search operation.
Loading
Loading