diff options
| author | transtrike <transtrike@gmail.com> | 2021-01-21 22:13:16 +0200 |
|---|---|---|
| committer | transtrike <transtrike@gmail.com> | 2021-01-21 22:13:16 +0200 |
| commit | 13a2ceda912f961a232c87236f1b29aa29bb6160 (patch) | |
| tree | 59f8d2bf63b03bacc76f98114d2aed78e420ddcd /src | |
| parent | a47ea20ab91017da53437f750ed8e0f939f5cdba (diff) | |
| parent | bda98b96433d7a9952524fab4ec65f96998b55de (diff) | |
| download | DevHive-13a2ceda912f961a232c87236f1b29aa29bb6160.tar DevHive-13a2ceda912f961a232c87236f1b29aa29bb6160.tar.gz DevHive-13a2ceda912f961a232c87236f1b29aa29bb6160.zip | |
Merge branch 'refactor_user_updating' into dev
Diffstat (limited to 'src')
126 files changed, 2404 insertions, 2359 deletions
diff --git a/src/DevHive.Angular/src/app/app-constants.module.ts b/src/DevHive.Angular/src/app/app-constants.module.ts index df676da..9ce8896 100644 --- a/src/DevHive.Angular/src/app/app-constants.module.ts +++ b/src/DevHive.Angular/src/app/app-constants.module.ts @@ -5,4 +5,6 @@ export class AppConstants { public static API_USER_REGISTER_URL = AppConstants.API_USER_URL + '/register'; public static FETCH_TIMEOUT = 500; + + public static FALLBACK_PROFILE_ICON = 'assets/images/feed/profile-pic.png'; } diff --git a/src/DevHive.Angular/src/app/app-routing.module.ts b/src/DevHive.Angular/src/app/app-routing.module.ts index 7817dcb..c511fe2 100644 --- a/src/DevHive.Angular/src/app/app-routing.module.ts +++ b/src/DevHive.Angular/src/app/app-routing.module.ts @@ -5,13 +5,15 @@ import { LoginComponent } from './components/login/login.component'; import { RegisterComponent } from './components/register/register.component'; import { ProfileComponent } from './components/profile/profile.component'; import {ProfileSettingsComponent} from './components/profile-settings/profile-settings.component'; +import {ErrorComponent} from './components/error/error.component'; const routes: Routes = [ { path: '', component: FeedComponent }, { path: 'login', component: LoginComponent }, { path: 'register', component: RegisterComponent }, { path: 'profile/:username', component: ProfileComponent }, - { path: 'profile/:username/settings', component: ProfileSettingsComponent } + { path: 'profile/:username/settings', component: ProfileSettingsComponent }, + { path: '**', component: ErrorComponent } ]; @NgModule({ diff --git a/src/DevHive.Angular/src/app/app.module.ts b/src/DevHive.Angular/src/app/app.module.ts index 7158941..8591724 100644 --- a/src/DevHive.Angular/src/app/app.module.ts +++ b/src/DevHive.Angular/src/app/app.module.ts @@ -14,6 +14,8 @@ import { FeedComponent } from './components/feed/feed.component'; import { PostComponent } from './components/post/post.component'; import { ProfileComponent } from './components/profile/profile.component'; import { ProfileSettingsComponent } from './components/profile-settings/profile-settings.component'; +import { ErrorComponent } from './components/error/error.component'; +import { LoadingComponent } from './components/loading/loading.component'; @NgModule({ declarations: [ @@ -23,7 +25,9 @@ import { ProfileSettingsComponent } from './components/profile-settings/profile- FeedComponent, PostComponent, ProfileComponent, - ProfileSettingsComponent + ProfileSettingsComponent, + ErrorComponent, + LoadingComponent ], imports: [ BrowserModule, diff --git a/src/DevHive.Angular/src/app/components/error/error.component.css b/src/DevHive.Angular/src/app/components/error/error.component.css new file mode 100644 index 0000000..ef6231d --- /dev/null +++ b/src/DevHive.Angular/src/app/components/error/error.component.css @@ -0,0 +1,23 @@ +#content { + font-size: 1.3em; +} + +#content hr { + width: 100%; + border: 1px solid black; + box-sizing: border-box; +} + +#back-btns { + width: 100%; + display: flex; +} + +#back-btns > * { + flex: 1; + margin-right: .2em; +} + +#back-btns > *:nth-last-child(1) { + margin-right: 0; +} diff --git a/src/DevHive.Angular/src/app/components/error/error.component.html b/src/DevHive.Angular/src/app/components/error/error.component.html new file mode 100644 index 0000000..8394810 --- /dev/null +++ b/src/DevHive.Angular/src/app/components/error/error.component.html @@ -0,0 +1,10 @@ +<div id="content"> + <div class="title"> + Page not found! + </div> + <hr> + <div id="back-btns"> + <button class="submit-btn" type="submit" (click)="backToFeed()">Back to feed</button> + <button class="submit-btn" type="submit" (click)="backToLogin()">Back to login</button> + </div> +</div> diff --git a/src/DevHive.Angular/src/app/components/error/error.component.ts b/src/DevHive.Angular/src/app/components/error/error.component.ts new file mode 100644 index 0000000..7069dc0 --- /dev/null +++ b/src/DevHive.Angular/src/app/components/error/error.component.ts @@ -0,0 +1,24 @@ +import { Component, OnInit } from '@angular/core'; +import {Router} from '@angular/router'; + +@Component({ + selector: 'app-error', + templateUrl: './error.component.html', + styleUrls: ['./error.component.css'] +}) +export class ErrorComponent implements OnInit { + + constructor(private _router: Router) + { } + + ngOnInit(): void { + } + + backToFeed(): void { + this._router.navigate(['/']); + } + + backToLogin(): void { + this._router.navigate(['/login']); + } +} diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.css b/src/DevHive.Angular/src/app/components/feed/feed.component.css index aa3c392..fe3f4a1 100644 --- a/src/DevHive.Angular/src/app/components/feed/feed.component.css +++ b/src/DevHive.Angular/src/app/components/feed/feed.component.css @@ -65,14 +65,24 @@ } #profile-bar-profile-pic { - width: 100%; + width: 7em; + height: 7em; box-sizing: border-box; padding: .5em; } #profile-bar-name { text-align: center; - margin-bottom: .5em; +} + +#profile-bar-username { + margin: .5em 0; +} + +#profile-bar > #profile-info { + display: flex; + flex-direction: column; + align-items: center; } /* Top bar */ @@ -120,7 +130,7 @@ /* Elements, that act as buttons */ -#profile-bar:hover, +#profile-bar > #profile-info:hover, #top-bar-profile-pic:hover { cursor: pointer; } diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.html b/src/DevHive.Angular/src/app/components/feed/feed.component.html index 5d7c86a..22213bc 100644 --- a/src/DevHive.Angular/src/app/components/feed/feed.component.html +++ b/src/DevHive.Angular/src/app/components/feed/feed.component.html @@ -1,21 +1,22 @@ -<!-- TODO: replace with loading component --> -<div id="content" *ngIf="!dataArrived"> - Loading... -</div> +<app-loading *ngIf="!dataArrived"></app-loading> <div id="feed-page" *ngIf="dataArrived"> - <nav id="profile-bar" (click)="goToProfile()"> - <img id="profile-bar-profile-pic" class="round-image" src="assets/images/feed/profile-pic.png" alt=""/> - <div id="profile-bar-name"> - {{ user.firstName }} {{ user.lastName }} - </div> - <div id="profile-bar-username"> - @{{ user.userName }} + <nav id="profile-bar"> + <div id="profile-info" (click)="goToProfile()"> + <img id="profile-bar-profile-pic" class="round-image" [src]="user.imageUrl" alt=""/> + <div id="profile-bar-name"> + {{ user.firstName }} {{ user.lastName }} + </div> + <div id="profile-bar-username"> + @{{ user.userName }} + </div> </div> + <button class="submit-btn" (click)="goToSettings()">Settings</button> + <button class="submit-btn" (click)="logout()">Logout</button> </nav> - <div id="feed-content"> + <div id="feed-content"> <nav id="top-bar"> - <img id="top-bar-profile-pic" class="round-image" src="assets/images/feed/profile-pic.png" alt="" (click)="goToProfile()"> + <img id="top-bar-profile-pic" class="round-image" [src]="user.imageUrl" alt="" (click)="goToProfile()"> <input id="top-bar-create-post" type="text" placeholder="What's on your mind?"/> <a id="top-bar-open-chat" href=""> <img src="assets/images/feed/chat-pic.png" alt=""/> diff --git a/src/DevHive.Angular/src/app/components/feed/feed.component.ts b/src/DevHive.Angular/src/app/components/feed/feed.component.ts index 7d37c9a..aa8599d 100644 --- a/src/DevHive.Angular/src/app/components/feed/feed.component.ts +++ b/src/DevHive.Angular/src/app/components/feed/feed.component.ts @@ -33,7 +33,12 @@ export class FeedComponent implements OnInit { // Workaround for waiting the fetch response // TODO: properly wait for it, before loading the page contents setTimeout(() => { this.user = this._userService.fetchUserFromSessionStorage(); }, AppConstants.FETCH_TIMEOUT); - setTimeout(() => { this.dataArrived = true; }, AppConstants.FETCH_TIMEOUT + 100); + setTimeout(() => { + this.dataArrived = true; + if (this.user.imageUrl === '') { + this.user.imageUrl = AppConstants.FALLBACK_PROFILE_ICON; + } + }, AppConstants.FETCH_TIMEOUT + 100); } else { this._router.navigate(['/login']); } @@ -42,4 +47,13 @@ export class FeedComponent implements OnInit { goToProfile(): void { this._router.navigate(['/profile/' + this.user.userName]); } + + goToSettings(): void { + this._router.navigate(['/profile/' + this.user.userName + '/settings']); + } + + logout(): void { + this._userService.logoutUserFromSessionStorage(); + this._router.navigate(['/login']); + } } diff --git a/src/DevHive.Angular/src/app/components/loading/loading.component.css b/src/DevHive.Angular/src/app/components/loading/loading.component.css new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/DevHive.Angular/src/app/components/loading/loading.component.css diff --git a/src/DevHive.Angular/src/app/components/loading/loading.component.html b/src/DevHive.Angular/src/app/components/loading/loading.component.html new file mode 100644 index 0000000..8440f4e --- /dev/null +++ b/src/DevHive.Angular/src/app/components/loading/loading.component.html @@ -0,0 +1,3 @@ +<div id="content"> + Loading... +</div> diff --git a/src/DevHive.Angular/src/app/components/loading/loading.component.ts b/src/DevHive.Angular/src/app/components/loading/loading.component.ts new file mode 100644 index 0000000..4dff0cd --- /dev/null +++ b/src/DevHive.Angular/src/app/components/loading/loading.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-loading', + templateUrl: './loading.component.html', + styleUrls: ['./loading.component.css'] +}) +export class LoadingComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/DevHive.Angular/src/app/components/login/login.component.ts b/src/DevHive.Angular/src/app/components/login/login.component.ts index a9206f2..bde7a09 100644 --- a/src/DevHive.Angular/src/app/components/login/login.component.ts +++ b/src/DevHive.Angular/src/app/components/login/login.component.ts @@ -3,6 +3,7 @@ import { FormGroup, FormBuilder, Validators, FormControl, AbstractControl } from import { Router } from '@angular/router'; import { Title } from '@angular/platform-browser'; import { UserService } from 'src/app/services/user.service'; +import {AppConstants} from 'src/app/app-constants.module'; @Component({ selector: 'app-login', @@ -28,9 +29,9 @@ export class LoginComponent implements OnInit { }); } - async onSubmit(): Promise<void> { - this._userService.loginUser(this.loginUserFormGroup); - this._router.navigate(['/']); + onSubmit(): void { + setTimeout(() => { this._userService.loginUser(this.loginUserFormGroup); }, AppConstants.FETCH_TIMEOUT); + setTimeout(() => { this._router.navigate(['/']); }, AppConstants.FETCH_TIMEOUT + 100); } onRedirectRegister(): void { diff --git a/src/DevHive.Angular/src/app/components/post/post.component.html b/src/DevHive.Angular/src/app/components/post/post.component.html index 041158f..a7acb0e 100644 --- a/src/DevHive.Angular/src/app/components/post/post.component.html +++ b/src/DevHive.Angular/src/app/components/post/post.component.html @@ -1,7 +1,7 @@ <div class="post"> <div class="content"> <div class="author"> - <img class="round-image" src="assets/images/feed/profile-pic.png"> + <img class="round-image" [src]="user.imageUrl"> <div class="author-info"> <div class="name"> {{ user.firstName }} {{ user.lastName }} diff --git a/src/DevHive.Angular/src/app/components/post/post.component.ts b/src/DevHive.Angular/src/app/components/post/post.component.ts index b4bb2f0..f615262 100644 --- a/src/DevHive.Angular/src/app/components/post/post.component.ts +++ b/src/DevHive.Angular/src/app/components/post/post.component.ts @@ -1,5 +1,6 @@ import { Component, OnInit } from '@angular/core'; import { Guid } from 'guid-typescript'; +import {AppConstants} from 'src/app/app-constants.module'; import { User } from 'src/models/identity/user'; @Component({ @@ -20,7 +21,7 @@ export class PostComponent implements OnInit { 'gosho_trapov', 'Gosho', 'Trapov', - 'assets/images/feed/profile-pic.png' + AppConstants.FALLBACK_PROFILE_ICON ); this.votesNumber = 23; diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css index e69de29..becae6d 100644 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css +++ b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.css @@ -0,0 +1,39 @@ +* { + box-sizing: border-box; +} + +#content { + max-width: 22em; + justify-content: start; +} + +hr { + width: calc(100% - 1em); + color: black; + border: 1px solid black; +} + +/* Navigation bar (for loggedin user) */ + +#navigation { + display: flex; + width: 100%; +} + +#navigation > .submit-btn { + flex: 1; + margin-top: 0; + margin-left: .5em; + font-size: inherit; +} + +#navigation > .submit-btn:nth-of-type(1) { + margin-left: 0; +} + +/* Buttons */ + +#delete-account:hover { + color: indianred; + border-color: indianred !important; +} diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html index 0cc443e..24c3eef 100644 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html +++ b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.html @@ -1 +1,10 @@ -<p>profile-settings works!</p> +<app-loading *ngIf="!dataArrived"></app-loading> + +<div id="content" *ngIf="dataArrived"> + <nav id="navigation"> + <button class="submit-btn" (click)="goBack()">ᐊ Back</button> + <button class="submit-btn" (click)="logout()">Logout</button> + </nav> + <hr> + <button id="delete-account" class="submit-btn" (click)="deleteAccount()">Delete account</button> +</div> diff --git a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts index 9226aae..3d7305f 100644 --- a/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts +++ b/src/DevHive.Angular/src/app/components/profile-settings/profile-settings.component.ts @@ -1,4 +1,8 @@ import { Component, OnInit } from '@angular/core'; +import {Router} from '@angular/router'; +import {AppConstants} from 'src/app/app-constants.module'; +import {UserService} from 'src/app/services/user.service'; +import {User} from 'src/models/identity/user'; @Component({ selector: 'app-profile-settings', @@ -6,10 +10,59 @@ import { Component, OnInit } from '@angular/core'; styleUrls: ['./profile-settings.component.css'] }) export class ProfileSettingsComponent implements OnInit { + public dataArrived = false; + public user: User; - constructor() { } + constructor(private _router: Router, private _userService: UserService) + { } ngOnInit(): void { + let username = this._router.url.substring(9); + username = username.substring(0, username.length - 9); + + if (sessionStorage.getItem('UserCred')) { + // Workaround for waiting the fetch response + // TODO: properly wait for it, before loading the page contents + setTimeout(() => { + this.user = this._userService.fetchUserFromSessionStorage(); + }, AppConstants.FETCH_TIMEOUT); + + // After getting the user, check if we're on the profile page of the logged in user + setTimeout(() => { + if (this.user.userName !== username) { + this.goToProfile(); + } else if (this.user.imageUrl === '') { + this.user.imageUrl = AppConstants.FALLBACK_PROFILE_ICON; + } + }, AppConstants.FETCH_TIMEOUT + 50); + + setTimeout(() => { + this.dataArrived = true; + }, AppConstants.FETCH_TIMEOUT + 100); + } + else { + this.goToProfile(); + } + } + + goToProfile(): void { + this._router.navigate([this._router.url.substring(0, this._router.url.length - 9)]); } + goBack(): void { + this._router.navigate(['/']); + } + + logout(): void { + this._userService.logoutUserFromSessionStorage(); + this.goToProfile(); + } + + deleteAccount(): void { + setTimeout(() => { this._userService.deleteUserRequest(this._userService.getUserIdFromSessionStroageToken()); }, AppConstants.FETCH_TIMEOUT); + setTimeout(() => { + this._userService.logoutUserFromSessionStorage(); + this._router.navigate(['/login']); + }, AppConstants.FETCH_TIMEOUT + 100); + } } diff --git a/src/DevHive.Angular/src/app/components/profile/profile.component.html b/src/DevHive.Angular/src/app/components/profile/profile.component.html index 5303db3..442cb8b 100644 --- a/src/DevHive.Angular/src/app/components/profile/profile.component.html +++ b/src/DevHive.Angular/src/app/components/profile/profile.component.html @@ -1,16 +1,14 @@ -<!-- TODO: replace with loading component --> -<div id="content" style="justify-content: center;" *ngIf="!dataArrived"> - Loading... -</div> +<app-loading *ngIf="!dataArrived"></app-loading> <div id="content" *ngIf="dataArrived"> <nav id="navigation"> - <button class="submit-btn" type="submit" (click)="goBack()">ᐊ Back</button> - <button class="submit-btn" type="submit" (click)="navigateToSettings()" *ngIf="loggedInUser">Settings</button> + <button class="submit-btn" (click)="goBack()">ᐊ Back</button> + <button class="submit-btn" (click)="navigateToSettings()" *ngIf="loggedInUser">Settings</button> + <button class="submit-btn" (click)="logout()" *ngIf="loggedInUser">Logout</button> </nav> <hr> <div id="main-info" class="rounded-border"> - <img class="round-image" src="assets/images/feed/profile-pic.png" alt=""/> + <img class="round-image" [src]="user.imageUrl" alt=""/> <div id="other-main-info"> <div id="name"> {{ user.firstName }} {{ user.lastName }} diff --git a/src/DevHive.Angular/src/app/components/profile/profile.component.ts b/src/DevHive.Angular/src/app/components/profile/profile.component.ts index 16bb053..9eb6e91 100644 --- a/src/DevHive.Angular/src/app/components/profile/profile.component.ts +++ b/src/DevHive.Angular/src/app/components/profile/profile.component.ts @@ -23,7 +23,6 @@ export class ProfileComponent implements OnInit { ngOnInit(): void { const username = this._router.url.substring(9); - console.log(username); if (sessionStorage.getItem('UserCred')) { // Workaround for waiting the fetch response @@ -37,6 +36,9 @@ export class ProfileComponent implements OnInit { if (this.user.userName !== username) { this.setDefaultUser(); } else { + if (this.user.imageUrl === '') { + this.user.imageUrl = AppConstants.FALLBACK_PROFILE_ICON; + } this.loggedInUser = true; } }, AppConstants.FETCH_TIMEOUT + 50); @@ -57,4 +59,13 @@ export class ProfileComponent implements OnInit { navigateToSettings(): void { this._router.navigate([this._router.url + '/settings']); } + + logout(): void { + this._userService.logoutUserFromSessionStorage(); + + // Reload the page + this._router.routeReuseStrategy.shouldReuseRoute = () => false; + this._router.onSameUrlNavigation = 'reload'; + this._router.navigate([this._router.url]); + } } diff --git a/src/DevHive.Angular/src/app/services/user.service.ts b/src/DevHive.Angular/src/app/services/user.service.ts index 8c679d7..7cf574b 100644 --- a/src/DevHive.Angular/src/app/services/user.service.ts +++ b/src/DevHive.Angular/src/app/services/user.service.ts @@ -14,7 +14,13 @@ export class UserService { constructor() { } getDefaultUser(): User { - return new User(Guid.createEmpty(), 'gosho_trapov', 'Gosho', 'Trapov', ''); + return new User(Guid.createEmpty(), 'gosho_trapov', 'Gosho', 'Trapov', AppConstants.FALLBACK_PROFILE_ICON); + } + + getUserIdFromSessionStroageToken(): Guid { + const jwt: IJWTPayload = JSON.parse(sessionStorage.getItem('UserCred') ?? ''); + const userCred = jwt_decode<IUserCredentials>(jwt.token); + return userCred.ID; } fetchUserFromSessionStorage(): User { @@ -77,4 +83,19 @@ export class UserService { }).then(response => response.json()) .then(data => sessionStorage.setItem('UserCred', JSON.stringify(data))); } + + logoutUserFromSessionStorage(): void { + sessionStorage.removeItem('UserCred'); + } + + deleteUserRequest(id: Guid): void { + const jwt = JSON.parse(sessionStorage.getItem('UserCred') ?? ''); + fetch(AppConstants.API_USER_URL + '?Id=' + id, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + Authorization: 'Bearer ' + jwt.token + } + }); + } } diff --git a/src/DevHive.Common/Models/Data/RepositoryMethods.cs b/src/DevHive.Common/Models/Data/RepositoryMethods.cs deleted file mode 100644 index bfd057f..0000000 --- a/src/DevHive.Common/Models/Data/RepositoryMethods.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; - -namespace DevHive.Common.Models.Misc -{ - public static class RepositoryMethods - { - public static async Task<bool> SaveChangesAsync(DbContext context) - { - int result = await context.SaveChangesAsync(); - - return result >= 1; - } - } -}
\ No newline at end of file diff --git a/src/DevHive.Common/Models/Misc/PasswordModifications.cs b/src/DevHive.Common/Models/Misc/PasswordModifications.cs new file mode 100644 index 0000000..f10a334 --- /dev/null +++ b/src/DevHive.Common/Models/Misc/PasswordModifications.cs @@ -0,0 +1,13 @@ +using System.Security.Cryptography; +using System.Text; + +namespace DevHive.Common.Models.Misc +{ + public static class PasswordModifications + { + public static string GeneratePasswordHash(string password) + { + return string.Join(string.Empty, SHA512.HashData(Encoding.ASCII.GetBytes(password))); + } + } +} diff --git a/src/DevHive.Common/Models/Misc/Patch.cs b/src/DevHive.Common/Models/Misc/Patch.cs new file mode 100644 index 0000000..ea5a4f1 --- /dev/null +++ b/src/DevHive.Common/Models/Misc/Patch.cs @@ -0,0 +1,9 @@ +namespace DevHive.Common.Models.Misc +{ + public class Patch + { + public string Name { get; set; } + public object Value { get; set; } + public string Action { get; set; } + } +} diff --git a/src/DevHive.Data/DevHiveContext.cs b/src/DevHive.Data/DevHiveContext.cs index 10fd004..c1bda49 100644 --- a/src/DevHive.Data/DevHiveContext.cs +++ b/src/DevHive.Data/DevHiveContext.cs @@ -12,6 +12,7 @@ namespace DevHive.Data public DbSet<Technology> Technologies { get; set; } public DbSet<Language> Languages { get; set; } + public DbSet<Post> Posts { get; set; } public DbSet<Comment> Comments { get; set; } protected override void OnModelCreating(ModelBuilder builder) diff --git a/src/DevHive.Data/Interfaces/Models/ILanguage.cs b/src/DevHive.Data/Interfaces/Models/ILanguage.cs index f757a3f..b77d5ae 100644 --- a/src/DevHive.Data/Interfaces/Models/ILanguage.cs +++ b/src/DevHive.Data/Interfaces/Models/ILanguage.cs @@ -1,7 +1,12 @@ +using System.Collections.Generic; +using DevHive.Data.Models; + namespace DevHive.Data.Interfaces.Models { public interface ILanguage : IModel { string Name { get; set; } + HashSet<User> Users { get; set; } + } } diff --git a/src/DevHive.Data/Interfaces/Models/IRole.cs b/src/DevHive.Data/Interfaces/Models/IRole.cs index 0623f07..c8b7068 100644 --- a/src/DevHive.Data/Interfaces/Models/IRole.cs +++ b/src/DevHive.Data/Interfaces/Models/IRole.cs @@ -5,6 +5,6 @@ namespace DevHive.Data.Interfaces.Models { public interface IRole { - List<User> Users { get; set; } + HashSet<User> Users { get; set; } } } diff --git a/src/DevHive.Data/Interfaces/Models/ITechnology.cs b/src/DevHive.Data/Interfaces/Models/ITechnology.cs index 9bd97f9..153f75f 100644 --- a/src/DevHive.Data/Interfaces/Models/ITechnology.cs +++ b/src/DevHive.Data/Interfaces/Models/ITechnology.cs @@ -1,7 +1,11 @@ +using System.Collections.Generic; +using DevHive.Data.Models; + namespace DevHive.Data.Interfaces.Models { public interface ITechnology : IModel { string Name { get; set; } + HashSet<User> Users { get; set; } } } diff --git a/src/DevHive.Data/Interfaces/Models/IUser.cs b/src/DevHive.Data/Interfaces/Models/IUser.cs index ef8c927..08ce385 100644 --- a/src/DevHive.Data/Interfaces/Models/IUser.cs +++ b/src/DevHive.Data/Interfaces/Models/IUser.cs @@ -8,9 +8,9 @@ namespace DevHive.Data.Interfaces.Models string FirstName { get; set; } string LastName { get; set; } string ProfilePictureUrl { get; set; } - IList<Language> Languages { get; set; } - IList<Technology> Technologies { get; set; } - IList<Role> Roles { get; set; } - IList<User> Friends { get; set; } + HashSet<Language> Languages { get; set; } + HashSet<Technology> Technologies { get; set; } + HashSet<Role> Roles { get; set; } + HashSet<User> Friends { get; set; } } } diff --git a/src/DevHive.Data/Interfaces/Repositories/IPostRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IPostRepository.cs index 913d8c4..7a9c02e 100644 --- a/src/DevHive.Data/Interfaces/Repositories/IPostRepository.cs +++ b/src/DevHive.Data/Interfaces/Repositories/IPostRepository.cs @@ -9,12 +9,16 @@ namespace DevHive.Data.Interfaces.Repositories { Task<bool> AddCommentAsync(Comment entity); + Task<Post> GetPostByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated); + Task<Comment> GetCommentByIdAsync(Guid id); + Task<Comment> GetCommentByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated); Task<bool> EditCommentAsync(Comment newEntity); Task<bool> DeleteCommentAsync(Comment entity); Task<bool> DoesCommentExist(Guid id); + Task<bool> DoesPostExist(Guid postId); } } diff --git a/src/DevHive.Data/Interfaces/Repositories/IRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IRepository.cs index 40a78de..d9f7c7a 100644 --- a/src/DevHive.Data/Interfaces/Repositories/IRepository.cs +++ b/src/DevHive.Data/Interfaces/Repositories/IRepository.cs @@ -18,4 +18,4 @@ namespace DevHive.Data.Repositories.Interfaces //Delete Entity from database Task<bool> DeleteAsync(TEntity entity); } -}
\ No newline at end of file +} diff --git a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs index eca6adb..c29669d 100644 --- a/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs +++ b/src/DevHive.Data/Interfaces/Repositories/IUserRepository.cs @@ -8,24 +8,15 @@ namespace DevHive.Data.Interfaces.Repositories { public interface IUserRepository : IRepository<User> { - Task<bool> AddFriendToUserAsync(User user, User friend); - Task<bool> AddLanguageToUserAsync(User user, Language language); - Task<bool> AddTechnologyToUserAsync(User user, Technology technology); - + //Read Task<User> GetByUsernameAsync(string username); Language GetUserLanguage(User user, Language language); - IList<Language> GetUserLanguages(User user); - IList<Technology> GetUserTechnologies(User user); + HashSet<Language> GetUserLanguages(User user); + HashSet<Technology> GetUserTechnologies(User user); Technology GetUserTechnology(User user, Technology technology); IEnumerable<User> QueryAll(); - Task<bool> EditUserLanguageAsync(User user, Language oldLang, Language newLang); - Task<bool> EditUserTechnologyAsync(User user, Technology oldTech, Technology newTech); - - Task<bool> RemoveFriendAsync(User user, User friend); - Task<bool> RemoveLanguageFromUserAsync(User user, Language language); - Task<bool> RemoveTechnologyFromUserAsync(User user, Technology technology); - + //Validations Task<bool> DoesEmailExistAsync(string email); Task<bool> DoesUserExistAsync(Guid id); Task<bool> DoesUserHaveThisFriendAsync(Guid userId, Guid friendId); diff --git a/src/DevHive.Data/Migrations/20201219141035_DbContext_Moved.Designer.cs b/src/DevHive.Data/Migrations/20201219141035_DbContext_Moved.Designer.cs deleted file mode 100644 index dd0e8c7..0000000 --- a/src/DevHive.Data/Migrations/20201219141035_DbContext_Moved.Designer.cs +++ /dev/null @@ -1,357 +0,0 @@ -// <auto-generated /> -using System; -using DevHive.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace DevHive.Data.Migrations -{ - [DbContext(typeof(DevHiveContext))] - [Migration("20201219141035_DbContext_Moved")] - partial class DbContext_Moved - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .UseIdentityByDefaultColumns() - .HasAnnotation("Relational:MaxIdentifierLength", 63) - .HasAnnotation("ProductVersion", "5.0.1"); - - modelBuilder.Entity("DevHive.Data.Models.Language", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<string>("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Languages"); - }); - - modelBuilder.Entity("DevHive.Data.Models.Role", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<string>("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property<string>("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<string>("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles"); - }); - - modelBuilder.Entity("DevHive.Data.Models.Technology", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<string>("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Technologies"); - }); - - modelBuilder.Entity("DevHive.Data.Models.User", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<int>("AccessFailedCount") - .HasColumnType("integer"); - - b.Property<string>("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property<string>("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<bool>("EmailConfirmed") - .HasColumnType("boolean"); - - b.Property<string>("FirstName") - .HasColumnType("text"); - - b.Property<string>("LastName") - .HasColumnType("text"); - - b.Property<bool>("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property<DateTimeOffset?>("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property<string>("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<string>("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<string>("PasswordHash") - .HasColumnType("text"); - - b.Property<string>("PhoneNumber") - .HasColumnType("text"); - - b.Property<bool>("PhoneNumberConfirmed") - .HasColumnType("boolean"); - - b.Property<string>("ProfilePicture") - .HasColumnType("text"); - - b.Property<string>("SecurityStamp") - .HasColumnType("text"); - - b.Property<bool>("TwoFactorEnabled") - .HasColumnType("boolean"); - - b.Property<Guid?>("UserId") - .HasColumnType("uuid"); - - b.Property<string>("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.HasIndex("UserId"); - - b.HasIndex("UserName") - .IsUnique(); - - b.ToTable("AspNetUsers"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property<string>("ClaimType") - .HasColumnType("text"); - - b.Property<string>("ClaimValue") - .HasColumnType("text"); - - b.Property<Guid>("RoleId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property<string>("ClaimType") - .HasColumnType("text"); - - b.Property<string>("ClaimValue") - .HasColumnType("text"); - - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => - { - b.Property<string>("LoginProvider") - .HasColumnType("text"); - - b.Property<string>("ProviderKey") - .HasColumnType("text"); - - b.Property<string>("ProviderDisplayName") - .HasColumnType("text"); - - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b => - { - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.Property<Guid>("RoleId") - .HasColumnType("uuid"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b => - { - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.Property<string>("LoginProvider") - .HasColumnType("text"); - - b.Property<string>("Name") - .HasColumnType("text"); - - b.Property<string>("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens"); - }); - - modelBuilder.Entity("RoleUser", b => - { - b.Property<Guid>("RolesId") - .HasColumnType("uuid"); - - b.Property<Guid>("UsersId") - .HasColumnType("uuid"); - - b.HasKey("RolesId", "UsersId"); - - b.HasIndex("UsersId"); - - b.ToTable("RoleUser"); - }); - - modelBuilder.Entity("DevHive.Data.Models.User", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Friends") - .HasForeignKey("UserId"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.Role", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.Role", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("RoleUser", b => - { - b.HasOne("DevHive.Data.Models.Role", null) - .WithMany() - .HasForeignKey("RolesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UsersId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("DevHive.Data.Models.User", b => - { - b.Navigation("Friends"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/DevHive.Data/Migrations/20201219141035_DbContext_Moved.cs b/src/DevHive.Data/Migrations/20201219141035_DbContext_Moved.cs deleted file mode 100644 index ccc5e91..0000000 --- a/src/DevHive.Data/Migrations/20201219141035_DbContext_Moved.cs +++ /dev/null @@ -1,301 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace DevHive.Data.Migrations -{ - public partial class DbContext_Moved : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "AspNetRoles", - columns: table => new - { - Id = table.Column<Guid>(type: "uuid", nullable: false), - Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), - NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), - ConcurrencyStamp = table.Column<string>(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoles", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetUsers", - columns: table => new - { - Id = table.Column<Guid>(type: "uuid", nullable: false), - FirstName = table.Column<string>(type: "text", nullable: true), - LastName = table.Column<string>(type: "text", nullable: true), - ProfilePicture = table.Column<string>(type: "text", nullable: true), - UserId = table.Column<Guid>(type: "uuid", nullable: true), - UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), - NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), - Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), - NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), - EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false), - PasswordHash = table.Column<string>(type: "text", nullable: true), - SecurityStamp = table.Column<string>(type: "text", nullable: true), - ConcurrencyStamp = table.Column<string>(type: "text", nullable: true), - PhoneNumber = table.Column<string>(type: "text", nullable: true), - PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false), - TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false), - LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true), - LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false), - AccessFailedCount = table.Column<int>(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUsers", x => x.Id); - table.ForeignKey( - name: "FK_AspNetUsers_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - }); - - migrationBuilder.CreateTable( - name: "Languages", - columns: table => new - { - Id = table.Column<Guid>(type: "uuid", nullable: false), - Name = table.Column<string>(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Languages", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "Technologies", - columns: table => new - { - Id = table.Column<Guid>(type: "uuid", nullable: false), - Name = table.Column<string>(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_Technologies", x => x.Id); - }); - - migrationBuilder.CreateTable( - name: "AspNetRoleClaims", - columns: table => new - { - Id = table.Column<int>(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - RoleId = table.Column<Guid>(type: "uuid", nullable: false), - ClaimType = table.Column<string>(type: "text", nullable: true), - ClaimValue = table.Column<string>(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserClaims", - columns: table => new - { - Id = table.Column<int>(type: "integer", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - UserId = table.Column<Guid>(type: "uuid", nullable: false), - ClaimType = table.Column<string>(type: "text", nullable: true), - ClaimValue = table.Column<string>(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); - table.ForeignKey( - name: "FK_AspNetUserClaims_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserLogins", - columns: table => new - { - LoginProvider = table.Column<string>(type: "text", nullable: false), - ProviderKey = table.Column<string>(type: "text", nullable: false), - ProviderDisplayName = table.Column<string>(type: "text", nullable: true), - UserId = table.Column<Guid>(type: "uuid", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); - table.ForeignKey( - name: "FK_AspNetUserLogins_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserRoles", - columns: table => new - { - UserId = table.Column<Guid>(type: "uuid", nullable: false), - RoleId = table.Column<Guid>(type: "uuid", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetRoles_RoleId", - column: x => x.RoleId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_AspNetUserRoles_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "AspNetUserTokens", - columns: table => new - { - UserId = table.Column<Guid>(type: "uuid", nullable: false), - LoginProvider = table.Column<string>(type: "text", nullable: false), - Name = table.Column<string>(type: "text", nullable: false), - Value = table.Column<string>(type: "text", nullable: true) - }, - constraints: table => - { - table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); - table.ForeignKey( - name: "FK_AspNetUserTokens_AspNetUsers_UserId", - column: x => x.UserId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateTable( - name: "RoleUser", - columns: table => new - { - RolesId = table.Column<Guid>(type: "uuid", nullable: false), - UsersId = table.Column<Guid>(type: "uuid", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_RoleUser", x => new { x.RolesId, x.UsersId }); - table.ForeignKey( - name: "FK_RoleUser_AspNetRoles_RolesId", - column: x => x.RolesId, - principalTable: "AspNetRoles", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - table.ForeignKey( - name: "FK_RoleUser_AspNetUsers_UsersId", - column: x => x.UsersId, - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Cascade); - }); - - migrationBuilder.CreateIndex( - name: "IX_AspNetRoleClaims_RoleId", - table: "AspNetRoleClaims", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "RoleNameIndex", - table: "AspNetRoles", - column: "NormalizedName", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserClaims_UserId", - table: "AspNetUserClaims", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserLogins_UserId", - table: "AspNetUserLogins", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUserRoles_RoleId", - table: "AspNetUserRoles", - column: "RoleId"); - - migrationBuilder.CreateIndex( - name: "EmailIndex", - table: "AspNetUsers", - column: "NormalizedEmail"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUsers_UserId", - table: "AspNetUsers", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_AspNetUsers_UserName", - table: "AspNetUsers", - column: "UserName", - unique: true); - - migrationBuilder.CreateIndex( - name: "UserNameIndex", - table: "AspNetUsers", - column: "NormalizedUserName", - unique: true); - - migrationBuilder.CreateIndex( - name: "IX_RoleUser_UsersId", - table: "RoleUser", - column: "UsersId"); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "AspNetRoleClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserClaims"); - - migrationBuilder.DropTable( - name: "AspNetUserLogins"); - - migrationBuilder.DropTable( - name: "AspNetUserRoles"); - - migrationBuilder.DropTable( - name: "AspNetUserTokens"); - - migrationBuilder.DropTable( - name: "Languages"); - - migrationBuilder.DropTable( - name: "RoleUser"); - - migrationBuilder.DropTable( - name: "Technologies"); - - migrationBuilder.DropTable( - name: "AspNetRoles"); - - migrationBuilder.DropTable( - name: "AspNetUsers"); - } - } -} diff --git a/src/DevHive.Data/Migrations/20201230154737_CommentMigration.Designer.cs b/src/DevHive.Data/Migrations/20201230154737_CommentMigration.Designer.cs deleted file mode 100644 index 0df3199..0000000 --- a/src/DevHive.Data/Migrations/20201230154737_CommentMigration.Designer.cs +++ /dev/null @@ -1,377 +0,0 @@ -// <auto-generated /> -using System; -using DevHive.Data; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; - -namespace DevHive.Data.Migrations -{ - [DbContext(typeof(DevHiveContext))] - [Migration("20201230154737_CommentMigration")] - partial class CommentMigration - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .UseIdentityByDefaultColumns() - .HasAnnotation("Relational:MaxIdentifierLength", 63) - .HasAnnotation("ProductVersion", "5.0.1"); - - modelBuilder.Entity("DevHive.Data.Models.Comment", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<DateTime>("Date") - .HasColumnType("timestamp without time zone"); - - b.Property<string>("Message") - .HasColumnType("text"); - - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.ToTable("Comments"); - }); - - modelBuilder.Entity("DevHive.Data.Models.Language", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<string>("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Languages"); - }); - - modelBuilder.Entity("DevHive.Data.Models.Role", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<string>("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property<string>("Name") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<string>("NormalizedName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedName") - .IsUnique() - .HasDatabaseName("RoleNameIndex"); - - b.ToTable("AspNetRoles"); - }); - - modelBuilder.Entity("DevHive.Data.Models.Technology", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<string>("Name") - .HasColumnType("text"); - - b.HasKey("Id"); - - b.ToTable("Technologies"); - }); - - modelBuilder.Entity("DevHive.Data.Models.User", b => - { - b.Property<Guid>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("uuid"); - - b.Property<int>("AccessFailedCount") - .HasColumnType("integer"); - - b.Property<string>("ConcurrencyStamp") - .IsConcurrencyToken() - .HasColumnType("text"); - - b.Property<string>("Email") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<bool>("EmailConfirmed") - .HasColumnType("boolean"); - - b.Property<string>("FirstName") - .HasColumnType("text"); - - b.Property<string>("LastName") - .HasColumnType("text"); - - b.Property<bool>("LockoutEnabled") - .HasColumnType("boolean"); - - b.Property<DateTimeOffset?>("LockoutEnd") - .HasColumnType("timestamp with time zone"); - - b.Property<string>("NormalizedEmail") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<string>("NormalizedUserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.Property<string>("PasswordHash") - .HasColumnType("text"); - - b.Property<string>("PhoneNumber") - .HasColumnType("text"); - - b.Property<bool>("PhoneNumberConfirmed") - .HasColumnType("boolean"); - - b.Property<string>("ProfilePicture") - .HasColumnType("text"); - - b.Property<string>("SecurityStamp") - .HasColumnType("text"); - - b.Property<bool>("TwoFactorEnabled") - .HasColumnType("boolean"); - - b.Property<Guid?>("UserId") - .HasColumnType("uuid"); - - b.Property<string>("UserName") - .HasMaxLength(256) - .HasColumnType("character varying(256)"); - - b.HasKey("Id"); - - b.HasIndex("NormalizedEmail") - .HasDatabaseName("EmailIndex"); - - b.HasIndex("NormalizedUserName") - .IsUnique() - .HasDatabaseName("UserNameIndex"); - - b.HasIndex("UserId"); - - b.HasIndex("UserName") - .IsUnique(); - - b.ToTable("AspNetUsers"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property<string>("ClaimType") - .HasColumnType("text"); - - b.Property<string>("ClaimValue") - .HasColumnType("text"); - - b.Property<Guid>("RoleId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetRoleClaims"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => - { - b.Property<int>("Id") - .ValueGeneratedOnAdd() - .HasColumnType("integer") - .UseIdentityByDefaultColumn(); - - b.Property<string>("ClaimType") - .HasColumnType("text"); - - b.Property<string>("ClaimValue") - .HasColumnType("text"); - - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserClaims"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => - { - b.Property<string>("LoginProvider") - .HasColumnType("text"); - - b.Property<string>("ProviderKey") - .HasColumnType("text"); - - b.Property<string>("ProviderDisplayName") - .HasColumnType("text"); - - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.HasKey("LoginProvider", "ProviderKey"); - - b.HasIndex("UserId"); - - b.ToTable("AspNetUserLogins"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b => - { - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.Property<Guid>("RoleId") - .HasColumnType("uuid"); - - b.HasKey("UserId", "RoleId"); - - b.HasIndex("RoleId"); - - b.ToTable("AspNetUserRoles"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b => - { - b.Property<Guid>("UserId") - .HasColumnType("uuid"); - - b.Property<string>("LoginProvider") - .HasColumnType("text"); - - b.Property<string>("Name") - .HasColumnType("text"); - - b.Property<string>("Value") - .HasColumnType("text"); - - b.HasKey("UserId", "LoginProvider", "Name"); - - b.ToTable("AspNetUserTokens"); - }); - - modelBuilder.Entity("RoleUser", b => - { - b.Property<Guid>("RolesId") - .HasColumnType("uuid"); - - b.Property<Guid>("UsersId") - .HasColumnType("uuid"); - - b.HasKey("RolesId", "UsersId"); - - b.HasIndex("UsersId"); - - b.ToTable("RoleUser"); - }); - - modelBuilder.Entity("DevHive.Data.Models.User", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Friends") - .HasForeignKey("UserId"); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.Role", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.Role", null) - .WithMany() - .HasForeignKey("RoleId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<System.Guid>", b => - { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UserId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("RoleUser", b => - { - b.HasOne("DevHive.Data.Models.Role", null) - .WithMany() - .HasForeignKey("RolesId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("DevHive.Data.Models.User", null) - .WithMany() - .HasForeignKey("UsersId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("DevHive.Data.Models.User", b => - { - b.Navigation("Friends"); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/DevHive.Data/Migrations/20201230154737_CommentMigration.cs b/src/DevHive.Data/Migrations/20201230154737_CommentMigration.cs deleted file mode 100644 index a442bfa..0000000 --- a/src/DevHive.Data/Migrations/20201230154737_CommentMigration.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace DevHive.Data.Migrations -{ - public partial class CommentMigration : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.CreateTable( - name: "Comments", - columns: table => new - { - Id = table.Column<Guid>(type: "uuid", nullable: false), - UserId = table.Column<Guid>(type: "uuid", nullable: false), - Message = table.Column<string>(type: "text", nullable: true), - Date = table.Column<DateTime>(type: "timestamp without time zone", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_Comments", x => x.Id); - }); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropTable( - name: "Comments"); - } - } -} diff --git a/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.cs b/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.cs deleted file mode 100644 index d698f10..0000000 --- a/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using Microsoft.EntityFrameworkCore.Migrations; - -namespace DevHive.Data.Migrations -{ - public partial class User_Implements_Languages : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.RenameColumn( - name: "UserId", - table: "Comments", - newName: "IssuerId"); - - migrationBuilder.RenameColumn( - name: "Date", - table: "Comments", - newName: "TimeCreated"); - - migrationBuilder.RenameColumn( - name: "ProfilePicture", - table: "AspNetUsers", - newName: "ProfilePictureUrl"); - - migrationBuilder.AddColumn<Guid>( - name: "UserId", - table: "Technologies", - type: "uuid", - nullable: true); - - migrationBuilder.AddColumn<Guid>( - name: "UserId", - table: "Languages", - type: "uuid", - nullable: true); - - migrationBuilder.CreateIndex( - name: "IX_Technologies_UserId", - table: "Technologies", - column: "UserId"); - - migrationBuilder.CreateIndex( - name: "IX_Languages_UserId", - table: "Languages", - column: "UserId"); - - migrationBuilder.AddForeignKey( - name: "FK_Languages_AspNetUsers_UserId", - table: "Languages", - column: "UserId", - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - - migrationBuilder.AddForeignKey( - name: "FK_Technologies_AspNetUsers_UserId", - table: "Technologies", - column: "UserId", - principalTable: "AspNetUsers", - principalColumn: "Id", - onDelete: ReferentialAction.Restrict); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.DropForeignKey( - name: "FK_Languages_AspNetUsers_UserId", - table: "Languages"); - - migrationBuilder.DropForeignKey( - name: "FK_Technologies_AspNetUsers_UserId", - table: "Technologies"); - - migrationBuilder.DropIndex( - name: "IX_Technologies_UserId", - table: "Technologies"); - - migrationBuilder.DropIndex( - name: "IX_Languages_UserId", - table: "Languages"); - - migrationBuilder.DropColumn( - name: "UserId", - table: "Technologies"); - - migrationBuilder.DropColumn( - name: "UserId", - table: "Languages"); - - migrationBuilder.RenameColumn( - name: "TimeCreated", - table: "Comments", - newName: "Date"); - - migrationBuilder.RenameColumn( - name: "IssuerId", - table: "Comments", - newName: "UserId"); - - migrationBuilder.RenameColumn( - name: "ProfilePictureUrl", - table: "AspNetUsers", - newName: "ProfilePicture"); - } - } -} diff --git a/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.Designer.cs b/src/DevHive.Data/Migrations/20210121083441_UserRefactor.Designer.cs index 1605b5b..7c7a092 100644 --- a/src/DevHive.Data/Migrations/20210112111416_User_Implements_Languages.Designer.cs +++ b/src/DevHive.Data/Migrations/20210121083441_UserRefactor.Designer.cs @@ -10,8 +10,8 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace DevHive.Data.Migrations { [DbContext(typeof(DevHiveContext))] - [Migration("20210112111416_User_Implements_Languages")] - partial class User_Implements_Languages + [Migration("20210121083441_UserRefactor")] + partial class UserRefactor { protected override void BuildTargetModel(ModelBuilder modelBuilder) { @@ -33,11 +33,16 @@ namespace DevHive.Data.Migrations b.Property<string>("Message") .HasColumnType("text"); + b.Property<Guid?>("PostId") + .HasColumnType("uuid"); + b.Property<DateTime>("TimeCreated") .HasColumnType("timestamp without time zone"); b.HasKey("Id"); + b.HasIndex("PostId"); + b.ToTable("Comments"); }); @@ -50,14 +55,29 @@ namespace DevHive.Data.Migrations b.Property<string>("Name") .HasColumnType("text"); - b.Property<Guid?>("UserId") + b.HasKey("Id"); + + b.ToTable("Languages"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() .HasColumnType("uuid"); - b.HasKey("Id"); + b.Property<Guid>("IssuerId") + .HasColumnType("uuid"); - b.HasIndex("UserId"); + b.Property<string>("Message") + .HasColumnType("text"); - b.ToTable("Languages"); + b.Property<DateTime>("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.ToTable("Posts"); }); modelBuilder.Entity("DevHive.Data.Models.Role", b => @@ -96,13 +116,8 @@ namespace DevHive.Data.Migrations b.Property<string>("Name") .HasColumnType("text"); - b.Property<Guid?>("UserId") - .HasColumnType("uuid"); - b.HasKey("Id"); - b.HasIndex("UserId"); - b.ToTable("Technologies"); }); @@ -188,6 +203,21 @@ namespace DevHive.Data.Migrations b.ToTable("AspNetUsers"); }); + modelBuilder.Entity("LanguageUser", b => + { + b.Property<Guid>("LanguagesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("LanguagesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("LanguageUser"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => { b.Property<int>("Id") @@ -304,18 +334,26 @@ namespace DevHive.Data.Migrations b.ToTable("RoleUser"); }); - modelBuilder.Entity("DevHive.Data.Models.Language", b => + modelBuilder.Entity("TechnologyUser", b => { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Languages") - .HasForeignKey("UserId"); + b.Property<Guid>("TechnologiesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("TechnologiesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("TechnologyUser"); }); - modelBuilder.Entity("DevHive.Data.Models.Technology", b => + modelBuilder.Entity("DevHive.Data.Models.Comment", b => { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Technologies") - .HasForeignKey("UserId"); + b.HasOne("DevHive.Data.Models.Post", null) + .WithMany("Comments") + .HasForeignKey("PostId"); }); modelBuilder.Entity("DevHive.Data.Models.User", b => @@ -325,6 +363,21 @@ namespace DevHive.Data.Migrations .HasForeignKey("UserId"); }); + modelBuilder.Entity("LanguageUser", b => + { + b.HasOne("DevHive.Data.Models.Language", null) + .WithMany() + .HasForeignKey("LanguagesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => { b.HasOne("DevHive.Data.Models.Role", null) @@ -391,13 +444,29 @@ namespace DevHive.Data.Migrations .IsRequired(); }); - modelBuilder.Entity("DevHive.Data.Models.User", b => + modelBuilder.Entity("TechnologyUser", b => { - b.Navigation("Friends"); + b.HasOne("DevHive.Data.Models.Technology", null) + .WithMany() + .HasForeignKey("TechnologiesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); - b.Navigation("Languages"); + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Navigation("Comments"); + }); - b.Navigation("Technologies"); + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Navigation("Friends"); }); #pragma warning restore 612, 618 } diff --git a/src/DevHive.Data/Migrations/20210121083441_UserRefactor.cs b/src/DevHive.Data/Migrations/20210121083441_UserRefactor.cs new file mode 100644 index 0000000..ea1af2e --- /dev/null +++ b/src/DevHive.Data/Migrations/20210121083441_UserRefactor.cs @@ -0,0 +1,411 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace DevHive.Data.Migrations +{ + public partial class UserRefactor : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column<Guid>(type: "uuid", nullable: false), + Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column<string>(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column<Guid>(type: "uuid", nullable: false), + FirstName = table.Column<string>(type: "text", nullable: true), + LastName = table.Column<string>(type: "text", nullable: true), + ProfilePictureUrl = table.Column<string>(type: "text", nullable: true), + UserId = table.Column<Guid>(type: "uuid", nullable: true), + UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), + Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), + NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true), + EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false), + PasswordHash = table.Column<string>(type: "text", nullable: true), + SecurityStamp = table.Column<string>(type: "text", nullable: true), + ConcurrencyStamp = table.Column<string>(type: "text", nullable: true), + PhoneNumber = table.Column<string>(type: "text", nullable: true), + PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false), + TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false), + LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true), + LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false), + AccessFailedCount = table.Column<int>(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUsers_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Languages", + columns: table => new + { + Id = table.Column<Guid>(type: "uuid", nullable: false), + Name = table.Column<string>(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Languages", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Posts", + columns: table => new + { + Id = table.Column<Guid>(type: "uuid", nullable: false), + IssuerId = table.Column<Guid>(type: "uuid", nullable: false), + TimeCreated = table.Column<DateTime>(type: "timestamp without time zone", nullable: false), + Message = table.Column<string>(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Posts", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Technologies", + columns: table => new + { + Id = table.Column<Guid>(type: "uuid", nullable: false), + Name = table.Column<string>(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Technologies", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column<int>(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoleId = table.Column<Guid>(type: "uuid", nullable: false), + ClaimType = table.Column<string>(type: "text", nullable: true), + ClaimValue = table.Column<string>(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column<int>(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + UserId = table.Column<Guid>(type: "uuid", nullable: false), + ClaimType = table.Column<string>(type: "text", nullable: true), + ClaimValue = table.Column<string>(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column<string>(type: "text", nullable: false), + ProviderKey = table.Column<string>(type: "text", nullable: false), + ProviderDisplayName = table.Column<string>(type: "text", nullable: true), + UserId = table.Column<Guid>(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column<Guid>(type: "uuid", nullable: false), + RoleId = table.Column<Guid>(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column<Guid>(type: "uuid", nullable: false), + LoginProvider = table.Column<string>(type: "text", nullable: false), + Name = table.Column<string>(type: "text", nullable: false), + Value = table.Column<string>(type: "text", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "RoleUser", + columns: table => new + { + RolesId = table.Column<Guid>(type: "uuid", nullable: false), + UsersId = table.Column<Guid>(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_RoleUser", x => new { x.RolesId, x.UsersId }); + table.ForeignKey( + name: "FK_RoleUser_AspNetRoles_RolesId", + column: x => x.RolesId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_RoleUser_AspNetUsers_UsersId", + column: x => x.UsersId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "LanguageUser", + columns: table => new + { + LanguagesId = table.Column<Guid>(type: "uuid", nullable: false), + UsersId = table.Column<Guid>(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_LanguageUser", x => new { x.LanguagesId, x.UsersId }); + table.ForeignKey( + name: "FK_LanguageUser_AspNetUsers_UsersId", + column: x => x.UsersId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_LanguageUser_Languages_LanguagesId", + column: x => x.LanguagesId, + principalTable: "Languages", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Comments", + columns: table => new + { + Id = table.Column<Guid>(type: "uuid", nullable: false), + IssuerId = table.Column<Guid>(type: "uuid", nullable: false), + Message = table.Column<string>(type: "text", nullable: true), + TimeCreated = table.Column<DateTime>(type: "timestamp without time zone", nullable: false), + PostId = table.Column<Guid>(type: "uuid", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Comments", x => x.Id); + table.ForeignKey( + name: "FK_Comments_Posts_PostId", + column: x => x.PostId, + principalTable: "Posts", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "TechnologyUser", + columns: table => new + { + TechnologiesId = table.Column<Guid>(type: "uuid", nullable: false), + UsersId = table.Column<Guid>(type: "uuid", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_TechnologyUser", x => new { x.TechnologiesId, x.UsersId }); + table.ForeignKey( + name: "FK_TechnologyUser_AspNetUsers_UsersId", + column: x => x.UsersId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_TechnologyUser_Technologies_TechnologiesId", + column: x => x.TechnologiesId, + principalTable: "Technologies", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUsers_UserId", + table: "AspNetUsers", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUsers_UserName", + table: "AspNetUsers", + column: "UserName", + unique: true); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Comments_PostId", + table: "Comments", + column: "PostId"); + + migrationBuilder.CreateIndex( + name: "IX_LanguageUser_UsersId", + table: "LanguageUser", + column: "UsersId"); + + migrationBuilder.CreateIndex( + name: "IX_RoleUser_UsersId", + table: "RoleUser", + column: "UsersId"); + + migrationBuilder.CreateIndex( + name: "IX_TechnologyUser_UsersId", + table: "TechnologyUser", + column: "UsersId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "Comments"); + + migrationBuilder.DropTable( + name: "LanguageUser"); + + migrationBuilder.DropTable( + name: "RoleUser"); + + migrationBuilder.DropTable( + name: "TechnologyUser"); + + migrationBuilder.DropTable( + name: "Posts"); + + migrationBuilder.DropTable( + name: "Languages"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + + migrationBuilder.DropTable( + name: "Technologies"); + } + } +} diff --git a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs index 7197c81..0727d33 100644 --- a/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs +++ b/src/DevHive.Data/Migrations/DevHiveContextModelSnapshot.cs @@ -31,11 +31,16 @@ namespace DevHive.Data.Migrations b.Property<string>("Message") .HasColumnType("text"); + b.Property<Guid?>("PostId") + .HasColumnType("uuid"); + b.Property<DateTime>("TimeCreated") .HasColumnType("timestamp without time zone"); b.HasKey("Id"); + b.HasIndex("PostId"); + b.ToTable("Comments"); }); @@ -48,14 +53,29 @@ namespace DevHive.Data.Migrations b.Property<string>("Name") .HasColumnType("text"); - b.Property<Guid?>("UserId") + b.HasKey("Id"); + + b.ToTable("Languages"); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Property<Guid>("Id") + .ValueGeneratedOnAdd() .HasColumnType("uuid"); - b.HasKey("Id"); + b.Property<Guid>("IssuerId") + .HasColumnType("uuid"); - b.HasIndex("UserId"); + b.Property<string>("Message") + .HasColumnType("text"); - b.ToTable("Languages"); + b.Property<DateTime>("TimeCreated") + .HasColumnType("timestamp without time zone"); + + b.HasKey("Id"); + + b.ToTable("Posts"); }); modelBuilder.Entity("DevHive.Data.Models.Role", b => @@ -94,13 +114,8 @@ namespace DevHive.Data.Migrations b.Property<string>("Name") .HasColumnType("text"); - b.Property<Guid?>("UserId") - .HasColumnType("uuid"); - b.HasKey("Id"); - b.HasIndex("UserId"); - b.ToTable("Technologies"); }); @@ -186,6 +201,21 @@ namespace DevHive.Data.Migrations b.ToTable("AspNetUsers"); }); + modelBuilder.Entity("LanguageUser", b => + { + b.Property<Guid>("LanguagesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("LanguagesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("LanguageUser"); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => { b.Property<int>("Id") @@ -302,18 +332,26 @@ namespace DevHive.Data.Migrations b.ToTable("RoleUser"); }); - modelBuilder.Entity("DevHive.Data.Models.Language", b => + modelBuilder.Entity("TechnologyUser", b => { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Languages") - .HasForeignKey("UserId"); + b.Property<Guid>("TechnologiesId") + .HasColumnType("uuid"); + + b.Property<Guid>("UsersId") + .HasColumnType("uuid"); + + b.HasKey("TechnologiesId", "UsersId"); + + b.HasIndex("UsersId"); + + b.ToTable("TechnologyUser"); }); - modelBuilder.Entity("DevHive.Data.Models.Technology", b => + modelBuilder.Entity("DevHive.Data.Models.Comment", b => { - b.HasOne("DevHive.Data.Models.User", null) - .WithMany("Technologies") - .HasForeignKey("UserId"); + b.HasOne("DevHive.Data.Models.Post", null) + .WithMany("Comments") + .HasForeignKey("PostId"); }); modelBuilder.Entity("DevHive.Data.Models.User", b => @@ -323,6 +361,21 @@ namespace DevHive.Data.Migrations .HasForeignKey("UserId"); }); + modelBuilder.Entity("LanguageUser", b => + { + b.HasOne("DevHive.Data.Models.Language", null) + .WithMany() + .HasForeignKey("LanguagesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<System.Guid>", b => { b.HasOne("DevHive.Data.Models.Role", null) @@ -389,13 +442,29 @@ namespace DevHive.Data.Migrations .IsRequired(); }); - modelBuilder.Entity("DevHive.Data.Models.User", b => + modelBuilder.Entity("TechnologyUser", b => { - b.Navigation("Friends"); + b.HasOne("DevHive.Data.Models.Technology", null) + .WithMany() + .HasForeignKey("TechnologiesId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); - b.Navigation("Languages"); + b.HasOne("DevHive.Data.Models.User", null) + .WithMany() + .HasForeignKey("UsersId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("DevHive.Data.Models.Post", b => + { + b.Navigation("Comments"); + }); - b.Navigation("Technologies"); + modelBuilder.Entity("DevHive.Data.Models.User", b => + { + b.Navigation("Friends"); }); #pragma warning restore 612, 618 } diff --git a/src/DevHive.Data/Models/Language.cs b/src/DevHive.Data/Models/Language.cs index 2983107..f2b2786 100644 --- a/src/DevHive.Data/Models/Language.cs +++ b/src/DevHive.Data/Models/Language.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using DevHive.Data.Interfaces.Models; namespace DevHive.Data.Models @@ -7,5 +8,6 @@ namespace DevHive.Data.Models { public Guid Id { get; set; } public string Name { get; set; } + public HashSet<User> Users { get; set; } } } diff --git a/src/DevHive.Data/Models/Role.cs b/src/DevHive.Data/Models/Role.cs index e63f007..e0855aa 100644 --- a/src/DevHive.Data/Models/Role.cs +++ b/src/DevHive.Data/Models/Role.cs @@ -12,6 +12,6 @@ namespace DevHive.Data.Models public const string DefaultRole = "User"; public const string AdminRole = "Admin"; - public List<User> Users { get; set; } + public HashSet<User> Users { get; set; } } } diff --git a/src/DevHive.Data/Models/Technology.cs b/src/DevHive.Data/Models/Technology.cs index 36cec32..a0728d5 100644 --- a/src/DevHive.Data/Models/Technology.cs +++ b/src/DevHive.Data/Models/Technology.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using DevHive.Data.Interfaces.Models; namespace DevHive.Data.Models @@ -7,5 +8,6 @@ namespace DevHive.Data.Models { public Guid Id { get; set; } public string Name { get; set; } + public HashSet<User> Users { get; set; } } } diff --git a/src/DevHive.Data/Models/User.cs b/src/DevHive.Data/Models/User.cs index 64e138f..2ac7adf 100644 --- a/src/DevHive.Data/Models/User.cs +++ b/src/DevHive.Data/Models/User.cs @@ -18,15 +18,16 @@ namespace DevHive.Data.Models /// <summary> /// Languages that the user uses or is familiar with /// </summary> - public IList<Language> Languages { get; set; } + // [Unique] + public HashSet<Language> Languages { get; set; } /// <summary> /// Technologies that the user uses or is familiar with /// </summary> - public IList<Technology> Technologies { get; set; } + public HashSet<Technology> Technologies { get; set; } = new HashSet<Technology>(); - public IList<Role> Roles { get; set; } = new List<Role>(); + public HashSet<Role> Roles { get; set; } = new HashSet<Role>(); - public IList<User> Friends { get; set; } = new List<User>(); + public HashSet<User> Friends { get; set; } = new HashSet<User>(); } } diff --git a/src/DevHive.Data/Repositories/BaseRepository.cs b/src/DevHive.Data/Repositories/BaseRepository.cs new file mode 100644 index 0000000..dabb35b --- /dev/null +++ b/src/DevHive.Data/Repositories/BaseRepository.cs @@ -0,0 +1,65 @@ +using System; +using System.Threading.Tasks; +using DevHive.Data.Repositories.Interfaces; +using Microsoft.EntityFrameworkCore; + +namespace DevHive.Data.Repositories +{ + public class BaseRepository<TEntity> : IRepository<TEntity> + where TEntity : class + { + private readonly DbContext _context; + + public BaseRepository(DbContext context) + { + this._context = context; + this._context.ChangeTracker.AutoDetectChangesEnabled = false; + } + + public virtual async Task<bool> AddAsync(TEntity entity) + { + await this._context + .Set<TEntity>() + .AddAsync(entity); + + return await this.SaveChangesAsync(_context); + } + + public virtual async Task<TEntity> GetByIdAsync(Guid id) + { + return await this._context + .Set<TEntity>() + .FindAsync(id); + } + + public virtual async Task<bool> EditAsync(TEntity newEntity) + { + // Old way(backup) + // User user = await this._context.Users + // .FirstOrDefaultAsync(x => x.Id == entity.Id); + + // this._context.Update(user); + // this._context.Entry(entity).CurrentValues.SetValues(entity); + + this._context + .Set<TEntity>() + .Update(newEntity); + + return await this.SaveChangesAsync(_context); + } + + public virtual async Task<bool> DeleteAsync(TEntity entity) + { + this._context.Remove(entity); + + return await this.SaveChangesAsync(_context); + } + + public virtual async Task<bool> SaveChangesAsync(DbContext context) + { + int result = await context.SaveChangesAsync(); + + return result >= 1; + } + } +} diff --git a/src/DevHive.Data/Repositories/LanguageRepository.cs b/src/DevHive.Data/Repositories/LanguageRepository.cs index e644fc4..d7ee609 100644 --- a/src/DevHive.Data/Repositories/LanguageRepository.cs +++ b/src/DevHive.Data/Repositories/LanguageRepository.cs @@ -1,75 +1,31 @@ using System; using System.Threading.Tasks; -using DevHive.Common.Models.Misc; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using Microsoft.EntityFrameworkCore; namespace DevHive.Data.Repositories { - public class LanguageRepository : ILanguageRepository + public class LanguageRepository : BaseRepository<Language>, ILanguageRepository { private readonly DevHiveContext _context; public LanguageRepository(DevHiveContext context) + :base(context) { this._context = context; } - #region Create - - public async Task<bool> AddAsync(Language entity) - { - await this._context - .Set<Language>() - .AddAsync(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - #region Read - - public async Task<Language> GetByIdAsync(Guid id) - { - return await this._context - .Set<Language>() - .FindAsync(id); - } - public async Task<Language> GetByNameAsync(string languageName) { return await this._context.Languages + .AsNoTracking() .FirstOrDefaultAsync(x => x.Name == languageName); } #endregion - #region Update - - public async Task<bool> EditAsync(Language newEntity) - { - this._context - .Set<Language>() - .Update(newEntity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - - #region Delete - - public async Task<bool> DeleteAsync(Language entity) - { - this._context - .Set<Language>() - .Remove(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - #region Validations - public async Task<bool> DoesLanguageNameExistAsync(string languageName) { return await this._context.Languages diff --git a/src/DevHive.Data/Repositories/PostRepository.cs b/src/DevHive.Data/Repositories/PostRepository.cs index 3be14e3..9230a2e 100644 --- a/src/DevHive.Data/Repositories/PostRepository.cs +++ b/src/DevHive.Data/Repositories/PostRepository.cs @@ -1,107 +1,84 @@ using System; using System.Threading.Tasks; -using DevHive.Common.Models.Misc; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using Microsoft.EntityFrameworkCore; namespace DevHive.Data.Repositories { - public class PostRepository : IPostRepository + public class PostRepository : BaseRepository<Post>, IPostRepository { private readonly DevHiveContext _context; public PostRepository(DevHiveContext context) + : base(context) { this._context = context; } - //Create - public async Task<bool> AddAsync(Post post) - { - await this._context - .Set<Post>() - .AddAsync(post); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - + #region Create public async Task<bool> AddCommentAsync(Comment entity) { - await this._context - .Set<Comment>() + await this._context.Comments .AddAsync(entity); - return await RepositoryMethods.SaveChangesAsync(this._context); + return await this.SaveChangesAsync(this._context); } + #endregion - //Read - public async Task<Post> GetByIdAsync(Guid id) + #region Read + public async Task<Post> GetPostByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated) { - return await this._context - .Set<Post>() - .FindAsync(id); + return await this._context.Posts + .FirstOrDefaultAsync(p => p.IssuerId == issuerId && + p.TimeCreated == timeCreated); } public async Task<Comment> GetCommentByIdAsync(Guid id) { - return await this._context - .Set<Comment>() + return await this._context.Comments .FindAsync(id); } - //Update - public async Task<bool> EditAsync(Post newPost) + public async Task<Comment> GetCommentByIssuerAndTimeCreatedAsync(Guid issuerId, DateTime timeCreated) { - this._context - .Set<Post>() - .Update(newPost); - - return await RepositoryMethods.SaveChangesAsync(this._context); + return await this._context.Comments + .FirstOrDefaultAsync(p => p.IssuerId == issuerId && + p.TimeCreated == timeCreated); } + #endregion + #region Update public async Task<bool> EditCommentAsync(Comment newEntity) { - this._context - .Set<Comment>() + this._context.Comments .Update(newEntity); - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - //Delete - public async Task<bool> DeleteAsync(Post post) - { - this._context - .Set<Post>() - .Remove(post); - - return await RepositoryMethods.SaveChangesAsync(this._context); + return await this.SaveChangesAsync(this._context); } + #endregion + #region Delete public async Task<bool> DeleteCommentAsync(Comment entity) { - this._context - .Set<Comment>() + this._context.Comments .Remove(entity); - return await RepositoryMethods.SaveChangesAsync(this._context); + return await this.SaveChangesAsync(this._context); } + #endregion #region Validations - public async Task<bool> DoesPostExist(Guid postId) { - return await this._context - .Set<Post>() + return await this._context.Posts .AsNoTracking() .AnyAsync(r => r.Id == postId); } public async Task<bool> DoesCommentExist(Guid id) { - return await this._context - .Set<Comment>() + return await this._context.Comments .AsNoTracking() .AnyAsync(r => r.Id == id); } diff --git a/src/DevHive.Data/Repositories/RoleRepository.cs b/src/DevHive.Data/Repositories/RoleRepository.cs index ca3fb8b..156792d 100644 --- a/src/DevHive.Data/Repositories/RoleRepository.cs +++ b/src/DevHive.Data/Repositories/RoleRepository.cs @@ -1,83 +1,43 @@ using System; using System.Threading.Tasks; -using DevHive.Common.Models.Misc; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using Microsoft.EntityFrameworkCore; namespace DevHive.Data.Repositories { - public class RoleRepository : IRoleRepository + public class RoleRepository : BaseRepository<Role>, IRoleRepository { private readonly DevHiveContext _context; public RoleRepository(DevHiveContext context) + :base(context) { this._context = context; } - //Create - public async Task<bool> AddAsync(Role entity) - { - await this._context - .Set<Role>() - .AddAsync(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - //Read - public async Task<Role> GetByIdAsync(Guid id) - { - return await this._context - .Set<Role>() - .FindAsync(id); - } - + #region Read public async Task<Role> GetByNameAsync(string name) { - return await this._context - .Set<Role>() + return await this._context.Roles .FirstOrDefaultAsync(x => x.Name == name); } + #endregion - //Update - public async Task<bool> EditAsync(Role newEntity) - { - Role role = await this.GetByIdAsync(newEntity.Id); - - this._context - .Entry(role) - .CurrentValues - .SetValues(newEntity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - //Delete - public async Task<bool> DeleteAsync(Role entity) - { - this._context - .Set<Role>() - .Remove(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - + #region Validations public async Task<bool> DoesNameExist(string name) { - return await this._context - .Set<Role>() + return await this._context.Roles .AsNoTracking() .AnyAsync(r => r.Name == name); } public async Task<bool> DoesRoleExist(Guid id) { - return await this._context - .Set<Role>() + return await this._context.Roles .AsNoTracking() .AnyAsync(r => r.Id == id); } + #endregion } } diff --git a/src/DevHive.Data/Repositories/TechnologyRepository.cs b/src/DevHive.Data/Repositories/TechnologyRepository.cs index 73827a7..83cc7aa 100644 --- a/src/DevHive.Data/Repositories/TechnologyRepository.cs +++ b/src/DevHive.Data/Repositories/TechnologyRepository.cs @@ -1,79 +1,34 @@ using System; using System.Threading.Tasks; -using DevHive.Common.Models.Misc; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using Microsoft.EntityFrameworkCore; - namespace DevHive.Data.Repositories { - public class TechnologyRepository : ITechnologyRepository + public class TechnologyRepository : BaseRepository<Technology>, ITechnologyRepository { private readonly DevHiveContext _context; public TechnologyRepository(DevHiveContext context) + :base(context) { this._context = context; } - #region Create - - public async Task<bool> AddAsync(Technology entity) - { - await this._context - .Set<Technology>() - .AddAsync(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - #region Read - - public async Task<Technology> GetByIdAsync(Guid id) - { - return await this._context - .Set<Technology>() - .FindAsync(id); - } public async Task<Technology> GetByNameAsync(string technologyName) { return await this._context.Technologies + .AsNoTracking() .FirstOrDefaultAsync(x => x.Name == technologyName); } #endregion - #region Edit - - public async Task<bool> EditAsync(Technology newEntity) - { - this._context - .Set<Technology>() - .Update(newEntity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - - #region Delete - - public async Task<bool> DeleteAsync(Technology entity) - { - this._context - .Set<Technology>() - .Remove(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - #region Validations - public async Task<bool> DoesTechnologyNameExistAsync(string technologyName) { - return await this._context - .Set<Technology>() + return await this._context.Technologies .AsNoTracking() .AnyAsync(r => r.Name == technologyName); } diff --git a/src/DevHive.Data/Repositories/UserRepository.cs b/src/DevHive.Data/Repositories/UserRepository.cs index 6d4a0bf..1511c63 100644 --- a/src/DevHive.Data/Repositories/UserRepository.cs +++ b/src/DevHive.Data/Repositories/UserRepository.cs @@ -2,59 +2,22 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using DevHive.Common.Models.Misc; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using Microsoft.EntityFrameworkCore; namespace DevHive.Data.Repositories { - public class UserRepository : IUserRepository + public class UserRepository : BaseRepository<User>, IUserRepository { private readonly DevHiveContext _context; public UserRepository(DevHiveContext context) + :base(context) { this._context = context; } - #region Create - - public async Task<bool> AddAsync(User entity) - { - await this._context.Users - .AddAsync(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> AddFriendToUserAsync(User user, User friend) - { - this._context.Update(user); - user.Friends.Add(friend); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> AddLanguageToUserAsync(User user, Language language) - { - this._context.Update(user); - - user.Languages.Add(language); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> AddTechnologyToUserAsync(User user, Technology technology) - { - this._context.Update(user); - - user.Technologies.Add(technology); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - #region Read public IEnumerable<User> QueryAll() @@ -65,7 +28,7 @@ namespace DevHive.Data.Repositories .AsEnumerable(); } - public async Task<User> GetByIdAsync(Guid id) + public override async Task<User> GetByIdAsync(Guid id) { return await this._context.Users .Include(x => x.Friends) @@ -78,11 +41,13 @@ namespace DevHive.Data.Repositories public async Task<User> GetByUsernameAsync(string username) { return await this._context.Users - .Include(u => u.Roles) + .AsNoTracking() + .Include(x => x.Languages) + .Include(x => x.Technologies) .FirstOrDefaultAsync(x => x.UserName == username); } - public IList<Language> GetUserLanguages(User user) + public HashSet<Language> GetUserLanguages(User user) { return user.Languages; } @@ -93,7 +58,7 @@ namespace DevHive.Data.Repositories .FirstOrDefault(x => x.Id == language.Id); } - public IList<Technology> GetUserTechnologies(User user) + public HashSet<Technology> GetUserTechnologies(User user) { return user.Technologies; } @@ -105,83 +70,12 @@ namespace DevHive.Data.Repositories } #endregion - #region Update - - public async Task<bool> EditAsync(User newEntity) - { - User user = await this.GetByIdAsync(newEntity.Id); - - this._context - .Entry(user) - .CurrentValues - .SetValues(newEntity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> EditUserLanguageAsync(User user, Language oldLang, Language newLang) - { - this._context.Update(user); - - user.Languages.Remove(oldLang); - user.Languages.Add(newLang); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> EditUserTechnologyAsync(User user, Technology oldTech, Technology newTech) - { - this._context.Update(user); - - user.Technologies.Remove(oldTech); - user.Technologies.Add(newTech); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - - #region Delete - - public async Task<bool> DeleteAsync(User entity) - { - this._context.Users - .Remove(entity); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> RemoveFriendAsync(User user, User friend) - { - this._context.Update(user); - user.Friends.Remove(friend); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> RemoveLanguageFromUserAsync(User user, Language language) - { - this._context.Update(user); - - user.Languages.Remove(language); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - - public async Task<bool> RemoveTechnologyFromUserAsync(User user, Technology technology) - { - this._context.Update(user); - - user.Technologies.Remove(technology); - - return await RepositoryMethods.SaveChangesAsync(this._context); - } - #endregion - #region Validations public async Task<bool> DoesUserExistAsync(Guid id) { return await this._context.Users + .AsNoTracking() .AnyAsync(x => x.Id == id); } @@ -213,6 +107,7 @@ namespace DevHive.Data.Repositories public bool DoesUserHaveThisUsername(Guid id, string username) { return this._context.Users + .AsNoTracking() .Any(x => x.Id == id && x.UserName == username); } diff --git a/src/DevHive.Services/Configurations/Mapping/LanguageMappings.cs b/src/DevHive.Services/Configurations/Mapping/LanguageMappings.cs index e483fff..9c572df 100644 --- a/src/DevHive.Services/Configurations/Mapping/LanguageMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/LanguageMappings.cs @@ -9,12 +9,14 @@ namespace DevHive.Services.Configurations.Mapping public LanguageMappings() { CreateMap<LanguageServiceModel, Language>(); + CreateMap<ReadLanguageServiceModel, Language>(); CreateMap<CreateLanguageServiceModel, Language>(); CreateMap<UpdateLanguageServiceModel, Language>(); CreateMap<Language, LanguageServiceModel>(); + CreateMap<Language, ReadLanguageServiceModel>(); CreateMap<Language, CreateLanguageServiceModel>(); CreateMap<Language, UpdateLanguageServiceModel>(); } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs index 65b0b5a..d6c8511 100644 --- a/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs +++ b/src/DevHive.Services/Configurations/Mapping/RoleMapings.cs @@ -1,15 +1,18 @@ using DevHive.Data.Models; using AutoMapper; -using DevHive.Common.Models.Identity; +using DevHive.Services.Models.Identity.Role; namespace DevHive.Services.Configurations.Mapping { - public class RoleMappings : Profile + public class RoleMappings : Profile { public RoleMappings() { - CreateMap<RoleModel, Role>(); - CreateMap<Role, RoleModel>(); + CreateMap<RoleServiceModel, Role>(); + CreateMap<UpdateRoleServiceModel, Role>(); + + CreateMap<Role, RoleServiceModel>(); + CreateMap<Role, UpdateRoleServiceModel>(); } } } diff --git a/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs b/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs index 079ec3e..0103ccf 100644 --- a/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/TechnologyMappings.cs @@ -11,8 +11,10 @@ namespace DevHive.Services.Configurations.Mapping CreateMap<CreateTechnologyServiceModel, Technology>(); CreateMap<UpdateTechnologyServiceModel, Technology>(); CreateMap<TechnologyServiceModel, Technology>(); + CreateMap<Technology, CreateTechnologyServiceModel>(); CreateMap<Technology, TechnologyServiceModel>(); + CreateMap<Technology, UpdateTechnologyServiceModel>(); } } } diff --git a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs index d57c6ba..5d9e41c 100644 --- a/src/DevHive.Services/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Services/Configurations/Mapping/UserMappings.cs @@ -1,6 +1,7 @@ using DevHive.Data.Models; using AutoMapper; using DevHive.Services.Models.Identity.User; +using DevHive.Common.Models.Misc; namespace DevHive.Services.Configurations.Mapping { @@ -10,9 +11,14 @@ namespace DevHive.Services.Configurations.Mapping { CreateMap<UserServiceModel, User>(); CreateMap<RegisterServiceModel, User>(); - CreateMap<UpdateUserServiceModel, User>(); + CreateMap<UpdateUserServiceModel, User>() + .AfterMap((src, dest) => dest.PasswordHash = PasswordModifications.GeneratePasswordHash(src.Password)); + CreateMap<FriendServiceModel, User>(); CreateMap<User, UserServiceModel>(); + CreateMap<User, UpdateUserServiceModel>() + .ForMember(x => x.Password, opt => opt.Ignore()); + CreateMap<User, FriendServiceModel>(); } } } diff --git a/src/DevHive.Services/Interfaces/ILanguageService.cs b/src/DevHive.Services/Interfaces/ILanguageService.cs index eb45a8d..0df9a95 100644 --- a/src/DevHive.Services/Interfaces/ILanguageService.cs +++ b/src/DevHive.Services/Interfaces/ILanguageService.cs @@ -6,12 +6,12 @@ namespace DevHive.Services.Interfaces { public interface ILanguageService { - Task<bool> CreateLanguage(CreateLanguageServiceModel createLanguageServiceModel); + Task<Guid> CreateLanguage(CreateLanguageServiceModel createLanguageServiceModel); - Task<LanguageServiceModel> GetLanguageById(Guid languageId); + Task<ReadLanguageServiceModel> GetLanguageById(Guid id); - Task<bool> UpdateLanguage(Guid languageId, UpdateLanguageServiceModel languageServiceModel); + Task<bool> UpdateLanguage(UpdateLanguageServiceModel languageServiceModel); - Task<bool> DeleteLanguage(Guid languageId); + Task<bool> DeleteLanguage(Guid id); } } diff --git a/src/DevHive.Services/Interfaces/IPostService.cs b/src/DevHive.Services/Interfaces/IPostService.cs index dd886b4..4364c67 100644 --- a/src/DevHive.Services/Interfaces/IPostService.cs +++ b/src/DevHive.Services/Interfaces/IPostService.cs @@ -7,8 +7,8 @@ namespace DevHive.Services.Interfaces { public interface IPostService { - Task<bool> CreatePost(CreatePostServiceModel postServiceModel); - Task<bool> AddComment(CreateCommentServiceModel commentServiceModel); + Task<Guid> CreatePost(CreatePostServiceModel postServiceModel); + Task<Guid> AddComment(CreateCommentServiceModel commentServiceModel); Task<CommentServiceModel> GetCommentById(Guid id); Task<PostServiceModel> GetPostById(Guid id); diff --git a/src/DevHive.Services/Interfaces/IRoleService.cs b/src/DevHive.Services/Interfaces/IRoleService.cs index 2c7195c..fd661be 100644 --- a/src/DevHive.Services/Interfaces/IRoleService.cs +++ b/src/DevHive.Services/Interfaces/IRoleService.cs @@ -1,16 +1,16 @@ using System; using System.Threading.Tasks; -using DevHive.Common.Models.Identity; +using DevHive.Services.Models.Identity.Role; namespace DevHive.Services.Interfaces { - public interface IRoleService + public interface IRoleService { - Task<bool> CreateRole(RoleModel roleServiceModel); + Task<Guid> CreateRole(RoleServiceModel roleServiceModel); - Task<RoleModel> GetRoleById(Guid id); + Task<RoleServiceModel> GetRoleById(Guid id); - Task<bool> UpdateRole(RoleModel roleServiceModel); + Task<bool> UpdateRole(UpdateRoleServiceModel roleServiceModel); Task<bool> DeleteRole(Guid id); } diff --git a/src/DevHive.Services/Interfaces/ITechnologyService.cs b/src/DevHive.Services/Interfaces/ITechnologyService.cs index 0797078..9c5661d 100644 --- a/src/DevHive.Services/Interfaces/ITechnologyService.cs +++ b/src/DevHive.Services/Interfaces/ITechnologyService.cs @@ -6,11 +6,11 @@ namespace DevHive.Services.Interfaces { public interface ITechnologyService { - Task<bool> Create(CreateTechnologyServiceModel technologyServiceModel); + Task<Guid> Create(CreateTechnologyServiceModel technologyServiceModel); Task<CreateTechnologyServiceModel> GetTechnologyById(Guid id); - Task<bool> UpdateTechnology(Guid technologyId, UpdateTechnologyServiceModel updateTechnologyServiceModel); + Task<bool> UpdateTechnology(UpdateTechnologyServiceModel updateTechnologyServiceModel); Task<bool> DeleteTechnology(Guid id); } diff --git a/src/DevHive.Services/Interfaces/IUserService.cs b/src/DevHive.Services/Interfaces/IUserService.cs index 5ef141f..51e3cf9 100644 --- a/src/DevHive.Services/Interfaces/IUserService.cs +++ b/src/DevHive.Services/Interfaces/IUserService.cs @@ -2,8 +2,6 @@ using System; using System.Threading.Tasks; using DevHive.Common.Models.Identity; using DevHive.Services.Models.Identity.User; -using DevHive.Services.Models.Language; -using DevHive.Services.Models.Technology; namespace DevHive.Services.Interfaces { @@ -12,19 +10,12 @@ namespace DevHive.Services.Interfaces Task<TokenModel> LoginUser(LoginServiceModel loginModel); Task<TokenModel> RegisterUser(RegisterServiceModel registerModel); - Task<bool> AddFriend(Guid userId, Guid friendId); - Task<bool> AddLanguageToUser(Guid userId, LanguageServiceModel languageServiceModel); - Task<bool> AddTechnologyToUser(Guid userId, TechnologyServiceModel technologyServiceModel); - - Task<UserServiceModel> GetFriendById(Guid friendId); + Task<UserServiceModel> GetUserByUsername(string username); Task<UserServiceModel> GetUserById(Guid id); Task<UserServiceModel> UpdateUser(UpdateUserServiceModel updateModel); Task DeleteUser(Guid id); - Task<bool> RemoveFriend(Guid userId, Guid friendId); - Task<bool> RemoveLanguageFromUser(Guid userId, LanguageServiceModel languageServiceModel); - Task<bool> RemoveTechnologyFromUser(Guid userId, TechnologyServiceModel technologyServiceModel); Task<bool> ValidJWT(Guid id, string rawTokenData); } diff --git a/src/DevHive.Services/Models/Identity/Role/CreateRoleServiceModel.cs b/src/DevHive.Services/Models/Identity/Role/CreateRoleServiceModel.cs new file mode 100644 index 0000000..53bea9e --- /dev/null +++ b/src/DevHive.Services/Models/Identity/Role/CreateRoleServiceModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + +namespace DevHive.Services.Models.Identity.Role +{ + public class CreateRoleServiceModel + { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/Role/RoleServiceModel.cs b/src/DevHive.Services/Models/Identity/Role/RoleServiceModel.cs new file mode 100644 index 0000000..07249fe --- /dev/null +++ b/src/DevHive.Services/Models/Identity/Role/RoleServiceModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Services.Models.Identity.Role +{ + public class RoleServiceModel + { + public string Name { get; set; } + } +} diff --git a/src/DevHive.Common/Models/Identity/RoleModel.cs b/src/DevHive.Services/Models/Identity/Role/UpdateRoleServiceModel.cs index 5db8df9..e21e6b4 100644 --- a/src/DevHive.Common/Models/Identity/RoleModel.cs +++ b/src/DevHive.Services/Models/Identity/Role/UpdateRoleServiceModel.cs @@ -1,8 +1,8 @@ using System; -namespace DevHive.Common.Models.Identity +namespace DevHive.Services.Models.Identity.Role { - public class RoleModel + public class UpdateRoleServiceModel { public Guid Id { get; set; } public string Name { get; set; } diff --git a/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs b/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs new file mode 100644 index 0000000..a784f5c --- /dev/null +++ b/src/DevHive.Services/Models/Identity/User/FriendServiceModel.cs @@ -0,0 +1,10 @@ +using System; + +namespace DevHive.Services.Models.Identity.User +{ + public class FriendServiceModel + { + public Guid Id { get; set; } + public string UserName { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/User/RegisterServiceModel.cs b/src/DevHive.Services/Models/Identity/User/RegisterServiceModel.cs index 74f66b4..adc4119 100644 --- a/src/DevHive.Services/Models/Identity/User/RegisterServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/RegisterServiceModel.cs @@ -6,8 +6,10 @@ namespace DevHive.Services.Models.Identity.User { public class RegisterServiceModel : BaseUserServiceModel { - public IList<LanguageServiceModel> Languages { get; set; } - public IList<TechnologyServiceModel> Technologies { get; set; } public string Password { get; set; } + + public HashSet<LanguageServiceModel> Languages { get; set; } + + public HashSet<TechnologyServiceModel> Technologies { get; set; } } } diff --git a/src/DevHive.Services/Models/Identity/User/UpdateFriendServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UpdateFriendServiceModel.cs new file mode 100644 index 0000000..83fcc34 --- /dev/null +++ b/src/DevHive.Services/Models/Identity/User/UpdateFriendServiceModel.cs @@ -0,0 +1,10 @@ +using System; + +namespace DevHive.Services.Models.Identity.User +{ + public class UpdateFriendServiceModel + { + public Guid Id { get; set; } + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs index 96d1ff0..9277e3e 100644 --- a/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UpdateUserServiceModel.cs @@ -1,9 +1,24 @@ using System; +using System.Collections.Generic; +using DevHive.Services.Models.Identity.Role; +using DevHive.Services.Models.Language; +using DevHive.Services.Models.Technology; namespace DevHive.Services.Models.Identity.User { - public class UpdateUserServiceModel : UserServiceModel + public class UpdateUserServiceModel : BaseUserServiceModel { public Guid Id { get; set; } + + public string Password { get; set; } + + public HashSet<UpdateRoleServiceModel> Roles { get; set; } = new HashSet<UpdateRoleServiceModel>(); + + public HashSet<UpdateFriendServiceModel> Friends { get; set; } = new HashSet<UpdateFriendServiceModel>(); + + public HashSet<UpdateLanguageServiceModel> Languages { get; set; } = new HashSet<UpdateLanguageServiceModel>(); + + public HashSet<UpdateTechnologyServiceModel> Technologies { get; set; } = new HashSet<UpdateTechnologyServiceModel>(); + } } diff --git a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs index 8825f50..5fcd494 100644 --- a/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs +++ b/src/DevHive.Services/Models/Identity/User/UserServiceModel.cs @@ -1,15 +1,18 @@ using System.Collections.Generic; -using DevHive.Common.Models.Identity; +using DevHive.Services.Models.Identity.Role; using DevHive.Services.Models.Language; using DevHive.Services.Models.Technology; namespace DevHive.Services.Models.Identity.User { - public class UserServiceModel : BaseUserServiceModel + public class UserServiceModel : BaseUserServiceModel { - public IList<RoleModel> Roles { get; set; } = new List<RoleModel>(); - public IList<UserServiceModel> Friends { get; set; } = new List<UserServiceModel>(); - public IList<LanguageServiceModel> Languages { get; set; } = new List<LanguageServiceModel>(); - public IList<TechnologyServiceModel> TechnologyServiceModels { get; set; } = new List<TechnologyServiceModel>(); + public HashSet<RoleServiceModel> Roles { get; set; } = new HashSet<RoleServiceModel>(); + + public HashSet<FriendServiceModel> Friends { get; set; } = new HashSet<FriendServiceModel>(); + + public HashSet<LanguageServiceModel> Languages { get; set; } = new HashSet<LanguageServiceModel>(); + + public HashSet<TechnologyServiceModel> Technologies { get; set; } = new HashSet<TechnologyServiceModel>(); } } diff --git a/src/DevHive.Services/Models/Language/ReadLanguageServiceModel.cs b/src/DevHive.Services/Models/Language/ReadLanguageServiceModel.cs new file mode 100644 index 0000000..653444e --- /dev/null +++ b/src/DevHive.Services/Models/Language/ReadLanguageServiceModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Services.Models.Language +{ + public class ReadLanguageServiceModel + { + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Models/Post/Comment/BaseCommentServiceModel.cs b/src/DevHive.Services/Models/Post/Comment/BaseCommentServiceModel.cs index 3aa92ee..54d6838 100644 --- a/src/DevHive.Services/Models/Post/Comment/BaseCommentServiceModel.cs +++ b/src/DevHive.Services/Models/Post/Comment/BaseCommentServiceModel.cs @@ -5,7 +5,8 @@ namespace DevHive.Services.Models.Post.Comment public class BaseCommentServiceModel { public Guid Id { get; set; } + public Guid PostId { get; set; } public Guid IssuerId { get; set; } public string Message { get; set; } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Services/Models/Technology/ReadTechnologyServiceModel.cs b/src/DevHive.Services/Models/Technology/ReadTechnologyServiceModel.cs new file mode 100644 index 0000000..cbfdc7d --- /dev/null +++ b/src/DevHive.Services/Models/Technology/ReadTechnologyServiceModel.cs @@ -0,0 +1,7 @@ +namespace DevHive.Services.Models.Technology +{ + public class ReadTechnologyServiceModel + { + public string Name { get; set; } + } +} diff --git a/src/DevHive.Services/Services/LanguageService.cs b/src/DevHive.Services/Services/LanguageService.cs index be035c2..89df654 100644 --- a/src/DevHive.Services/Services/LanguageService.cs +++ b/src/DevHive.Services/Services/LanguageService.cs @@ -21,45 +21,50 @@ namespace DevHive.Services.Services #region Create - public async Task<bool> CreateLanguage(CreateLanguageServiceModel createLanguageServiceModel) + public async Task<Guid> CreateLanguage(CreateLanguageServiceModel createLanguageServiceModel) { if (await this._languageRepository.DoesLanguageNameExistAsync(createLanguageServiceModel.Name)) throw new ArgumentException("Language already exists!"); Language language = this._languageMapper.Map<Language>(createLanguageServiceModel); - bool result = await this._languageRepository.AddAsync(language); - - return result; + bool success = await this._languageRepository.AddAsync(language); + + if (success) + { + Language newLanguage = await this._languageRepository.GetByNameAsync(createLanguageServiceModel.Name); + return newLanguage.Id; + } + else + return Guid.Empty; } #endregion #region Read - public async Task<LanguageServiceModel> GetLanguageById(Guid languageId) + public async Task<ReadLanguageServiceModel> GetLanguageById(Guid id) { - Language language = await this._languageRepository.GetByIdAsync(languageId); + Language language = await this._languageRepository.GetByIdAsync(id); if (language == null) throw new ArgumentException("The language does not exist"); - return this._languageMapper.Map<LanguageServiceModel>(language); + return this._languageMapper.Map<ReadLanguageServiceModel>(language); } #endregion #region Update - public async Task<bool> UpdateLanguage(Guid languageId, UpdateLanguageServiceModel languageServiceModel) + public async Task<bool> UpdateLanguage(UpdateLanguageServiceModel languageServiceModel) { - bool langExists = await this._languageRepository.DoesLanguageExistAsync(languageId); + bool langExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); bool newLangNameExists = await this._languageRepository.DoesLanguageNameExistAsync(languageServiceModel.Name); if (!langExists) throw new ArgumentException("Language does not exist!"); if (newLangNameExists) - throw new ArgumentException("This name is already in our datbase!"); + throw new ArgumentException("Language name already exists in our data base!"); - languageServiceModel.Id = languageId; Language lang = this._languageMapper.Map<Language>(languageServiceModel); return await this._languageRepository.EditAsync(lang); } @@ -67,12 +72,12 @@ namespace DevHive.Services.Services #region Delete - public async Task<bool> DeleteLanguage(Guid languageId) + public async Task<bool> DeleteLanguage(Guid id) { - if (!await this._languageRepository.DoesLanguageExistAsync(languageId)) + if (!await this._languageRepository.DoesLanguageExistAsync(id)) throw new ArgumentException("Language does not exist!"); - Language language = await this._languageRepository.GetByIdAsync(languageId); + Language language = await this._languageRepository.GetByIdAsync(id); return await this._languageRepository.DeleteAsync(language); } #endregion diff --git a/src/DevHive.Services/Services/PostService.cs b/src/DevHive.Services/Services/PostService.cs index 6e83ad4..9503b8a 100644 --- a/src/DevHive.Services/Services/PostService.cs +++ b/src/DevHive.Services/Services/PostService.cs @@ -9,6 +9,7 @@ using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using DevHive.Services.Interfaces; using DevHive.Data.Interfaces.Repositories; +using System.Linq; namespace DevHive.Services.Services { @@ -26,21 +27,35 @@ namespace DevHive.Services.Services } //Create - public async Task<bool> CreatePost(CreatePostServiceModel postServiceModel) + public async Task<Guid> CreatePost(CreatePostServiceModel postServiceModel) { Post post = this._postMapper.Map<Post>(postServiceModel); - return await this._postRepository.AddAsync(post); + bool success = await this._postRepository.AddAsync(post); + + if(success) + { + Post newPost = await this._postRepository.GetPostByIssuerAndTimeCreatedAsync(postServiceModel.IssuerId, postServiceModel.TimeCreated); + return newPost.Id; + } + else + return Guid.Empty; } - public async Task<bool> AddComment(CreateCommentServiceModel commentServiceModel) + public async Task<Guid> AddComment(CreateCommentServiceModel commentServiceModel) { commentServiceModel.TimeCreated = DateTime.Now; Comment comment = this._postMapper.Map<Comment>(commentServiceModel); - bool result = await this._postRepository.AddCommentAsync(comment); + bool success = await this._postRepository.AddCommentAsync(comment); - return result; + if(success) + { + Comment newComment = await this._postRepository.GetCommentByIssuerAndTimeCreatedAsync(commentServiceModel.IssuerId, commentServiceModel.TimeCreated); + return newComment.Id; + } + else + return Guid.Empty; } //Read @@ -117,8 +132,8 @@ namespace DevHive.Services.Services { var jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7)); - string jwtUserName = this.GetClaimTypeValues("unique_name", jwt.Claims)[0]; - //List<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims); + string jwtUserName = this.GetClaimTypeValues("unique_name", jwt.Claims).First(); + //HashSet<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims); User user = await this._userRepository.GetByUsernameAsync(jwtUserName) ?? throw new ArgumentException("User does not exist!"); diff --git a/src/DevHive.Services/Services/RoleService.cs b/src/DevHive.Services/Services/RoleService.cs index c38ac74..3ebb7c8 100644 --- a/src/DevHive.Services/Services/RoleService.cs +++ b/src/DevHive.Services/Services/RoleService.cs @@ -1,14 +1,15 @@ using System; using System.Threading.Tasks; using AutoMapper; -using DevHive.Common.Models.Identity; using DevHive.Data.Interfaces.Repositories; using DevHive.Data.Models; using DevHive.Services.Interfaces; +using DevHive.Services.Models.Identity.Role; +using DevHive.Services.Models.Language; namespace DevHive.Services.Services { - public class RoleService : IRoleService + public class RoleService : IRoleService { private readonly IRoleRepository _roleRepository; private readonly IMapper _roleMapper; @@ -19,33 +20,42 @@ namespace DevHive.Services.Services this._roleMapper = mapper; } - public async Task<bool> CreateRole(RoleModel roleServiceModel) + public async Task<Guid> CreateRole(RoleServiceModel roleServiceModel) { if (await this._roleRepository.DoesNameExist(roleServiceModel.Name)) throw new ArgumentException("Role already exists!"); + Role role = this._roleMapper.Map<Role>(roleServiceModel); + bool success = await this._roleRepository.AddAsync(role); + + if(success) + { + Role newRole = await this._roleRepository.GetByNameAsync(roleServiceModel.Name); + return newRole.Id; + } + else + return Guid.Empty; - return await this._roleRepository.AddAsync(role); } - public async Task<RoleModel> GetRoleById(Guid id) + public async Task<RoleServiceModel> GetRoleById(Guid id) { Role role = await this._roleRepository.GetByIdAsync(id) ?? throw new ArgumentException("Role does not exist!"); - return this._roleMapper.Map<RoleModel>(role); + return this._roleMapper.Map<RoleServiceModel>(role); } - public async Task<bool> UpdateRole(RoleModel roleServiceModel) + public async Task<bool> UpdateRole(UpdateRoleServiceModel updateRoleServiceModel) { - if (!await this._roleRepository.DoesRoleExist(roleServiceModel.Id)) + if (!await this._roleRepository.DoesRoleExist(updateRoleServiceModel.Id)) throw new ArgumentException("Role does not exist!"); - if (await this._roleRepository.DoesNameExist(roleServiceModel.Name)) + if (await this._roleRepository.DoesNameExist(updateRoleServiceModel.Name)) throw new ArgumentException("Role name already exists!"); - Role role = this._roleMapper.Map<Role>(roleServiceModel); + Role role = this._roleMapper.Map<Role>(updateRoleServiceModel); return await this._roleRepository.EditAsync(role); } diff --git a/src/DevHive.Services/Services/TechnologyService.cs b/src/DevHive.Services/Services/TechnologyService.cs index d8b7262..88ed702 100644 --- a/src/DevHive.Services/Services/TechnologyService.cs +++ b/src/DevHive.Services/Services/TechnologyService.cs @@ -20,24 +20,28 @@ namespace DevHive.Services.Services } #region Create - - public async Task<bool> Create(CreateTechnologyServiceModel technologyServiceModel) + public async Task<Guid> Create(CreateTechnologyServiceModel technologyServiceModel) { if (await this._technologyRepository.DoesTechnologyNameExistAsync(technologyServiceModel.Name)) throw new ArgumentException("Technology already exists!"); Technology technology = this._technologyMapper.Map<Technology>(technologyServiceModel); - bool result = await this._technologyRepository.AddAsync(technology); - - return result; + bool success = await this._technologyRepository.AddAsync(technology); + + if (success) + { + Technology newTechnology = await this._technologyRepository.GetByNameAsync(technologyServiceModel.Name); + return newTechnology.Id; + } + else + return Guid.Empty; } #endregion #region Read - - public async Task<CreateTechnologyServiceModel> GetTechnologyById(Guid technologyId) + public async Task<CreateTechnologyServiceModel> GetTechnologyById(Guid id) { - Technology technology = await this._technologyRepository.GetByIdAsync(technologyId); + Technology technology = await this._technologyRepository.GetByIdAsync(id); if (technology == null) throw new ArgumentException("The technology does not exist"); @@ -47,16 +51,14 @@ namespace DevHive.Services.Services #endregion #region Update - - public async Task<bool> UpdateTechnology(Guid technologyId, UpdateTechnologyServiceModel updateTechnologyServiceModel) + public async Task<bool> UpdateTechnology(UpdateTechnologyServiceModel updateTechnologyServiceModel) { - if (!await this._technologyRepository.DoesTechnologyExistAsync(technologyId)) + if (!await this._technologyRepository.DoesTechnologyExistAsync(updateTechnologyServiceModel.Id)) throw new ArgumentException("Technology does not exist!"); if (await this._technologyRepository.DoesTechnologyNameExistAsync(updateTechnologyServiceModel.Name)) throw new ArgumentException("Technology name already exists!"); - updateTechnologyServiceModel.Id = technologyId; Technology technology = this._technologyMapper.Map<Technology>(updateTechnologyServiceModel); bool result = await this._technologyRepository.EditAsync(technology); @@ -65,12 +67,12 @@ namespace DevHive.Services.Services #endregion #region Delete - public async Task<bool> DeleteTechnology(Guid technologyId) + public async Task<bool> DeleteTechnology(Guid id) { - if (!await this._technologyRepository.DoesTechnologyExistAsync(technologyId)) + if (!await this._technologyRepository.DoesTechnologyExistAsync(id)) throw new ArgumentException("Technology does not exist!"); - Technology technology = await this._technologyRepository.GetByIdAsync(technologyId); + Technology technology = await this._technologyRepository.GetByIdAsync(id); bool result = await this._technologyRepository.DeleteAsync(technology); return result; diff --git a/src/DevHive.Services/Services/UserService.cs b/src/DevHive.Services/Services/UserService.cs index 37dbc7b..217154e 100644 --- a/src/DevHive.Services/Services/UserService.cs +++ b/src/DevHive.Services/Services/UserService.cs @@ -7,15 +7,16 @@ using System; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using Microsoft.IdentityModel.Tokens; -using System.Security.Cryptography; using System.Text; using System.Collections.Generic; using DevHive.Common.Models.Identity; -using DevHive.Services.Models.Language; using DevHive.Services.Interfaces; -using DevHive.Services.Models.Technology; -using DevHive.Data.Repositories; using DevHive.Data.Interfaces.Repositories; +using System.Linq; +using DevHive.Common.Models.Misc; +using DevHive.Services.Models.Language; +using DevHive.Services.Models.Technology; +using DevHive.Services.Models.Identity.Role; namespace DevHive.Services.Services { @@ -52,7 +53,7 @@ namespace DevHive.Services.Services User user = await this._userRepository.GetByUsernameAsync(loginModel.UserName); - if (user.PasswordHash != GeneratePasswordHash(loginModel.Password)) + if (user.PasswordHash != PasswordModifications.GeneratePasswordHash(loginModel.Password)) throw new ArgumentException("Incorrect password!"); return new TokenModel(WriteJWTSecurityToken(user.Id, user.Roles)); @@ -67,7 +68,7 @@ namespace DevHive.Services.Services throw new ArgumentException("Email already exists!"); User user = this._userMapper.Map<User>(registerModel); - user.PasswordHash = GeneratePasswordHash(registerModel.Password); + user.PasswordHash = PasswordModifications.GeneratePasswordHash(registerModel.Password); // Make sure the default role exists if (!await this._roleRepository.DoesNameExist(Role.DefaultRole)) @@ -75,7 +76,7 @@ namespace DevHive.Services.Services // Set the default role to the user Role defaultRole = await this._roleRepository.GetByNameAsync(Role.DefaultRole); - user.Roles = new List<Role>() { defaultRole }; + user.Roles = new HashSet<Role>() { defaultRole }; await this._userRepository.AddAsync(user); @@ -83,117 +84,84 @@ namespace DevHive.Services.Services } #endregion - #region Create - - public async Task<bool> AddFriend(Guid userId, Guid friendId) + #region Read + public async Task<UserServiceModel> GetUserById(Guid id) { - Task<bool> userExists = this._userRepository.DoesUserExistAsync(userId); - Task<bool> friendExists = this._userRepository.DoesUserExistAsync(friendId); - - await Task.WhenAll(userExists, friendExists); - - if (!userExists.Result) - throw new ArgumentException("User doesn't exist!"); - - if (!friendExists.Result) - throw new ArgumentException("Friend doesn't exist!"); - - if (await this._userRepository.DoesUserHaveThisFriendAsync(userId, friendId)) - throw new ArgumentException("Friend already exists in your friends list."); - - User user = await this._userRepository.GetByIdAsync(userId); - User friend = await this._userRepository.GetByIdAsync(friendId); + User user = await this._userRepository.GetByIdAsync(id) + ?? throw new ArgumentException("User does not exist!"); - return user != default(User) && friend != default(User) ? - await this._userRepository.AddFriendToUserAsync(user, friend) : - throw new ArgumentException("Invalid user!"); + return this._userMapper.Map<UserServiceModel>(user); } - public async Task<bool> AddLanguageToUser(Guid userId, LanguageServiceModel languageServiceModel) + public async Task<UserServiceModel> GetUserByUsername(string username) { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool languageExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); + User friend = await this._userRepository.GetByUsernameAsync(username); - if (!userExists) + if (friend == null) throw new ArgumentException("User does not exist!"); - if (!languageExists) - throw new ArgumentException("Language does noy exist!"); - - User user = await this._userRepository.GetByIdAsync(userId); - Language language = await this._languageRepository.GetByIdAsync(languageServiceModel.Id); - - if (this._userRepository.DoesUserHaveThisLanguage(user, language)) - throw new ArgumentException("User already has this language!"); - - return await this._userRepository.AddLanguageToUserAsync(user, language); + return this._userMapper.Map<UserServiceModel>(friend); } + #endregion - public async Task<bool> AddTechnologyToUser(Guid userId, TechnologyServiceModel technologyServiceModel) + #region Update + public async Task<UserServiceModel> UpdateUser(UpdateUserServiceModel updateUserServiceModel) { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool technologyExists = await this._technologyRepository.DoesTechnologyExistAsync(technologyServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); + await this.ValidateUserOnUpdate(updateUserServiceModel); - if (!technologyExists) - throw new ArgumentException("Technology does not exist!"); + await this.ValidateUserCollections(updateUserServiceModel); - Technology technology = await this._technologyRepository.GetByIdAsync(technologyServiceModel.Id); - User user = await this._userRepository.GetByIdAsync(userId); + //Preserve roles + int roleCount = updateUserServiceModel.Roles.Count; + for (int i = 0; i < roleCount; i++) + { + Role role = await this._roleRepository.GetByNameAsync(updateUserServiceModel.Roles.ElementAt(i).Name) ?? + throw new ArgumentException("Invalid role name!"); - if (this._userRepository.DoesUserHaveThisTechnology(user, technology)) - throw new ArgumentException("User already has this language!"); + UpdateRoleServiceModel updateRoleServiceModel = this._userMapper.Map<UpdateRoleServiceModel>(role); - return await this._userRepository.AddTechnologyToUserAsync(user, technology); - } - #endregion - - #region Read + updateUserServiceModel.Roles.Add(updateRoleServiceModel); + } - public async Task<UserServiceModel> GetUserById(Guid id) - { - User user = await this._userRepository.GetByIdAsync(id) - ?? throw new ArgumentException("User does not exist!"); + int langCount = updateUserServiceModel.Languages.Count; + for (int i = 0; i < langCount; i++) + { + Language language = await this._languageRepository.GetByNameAsync(updateUserServiceModel.Languages.ElementAt(i).Name) ?? + throw new ArgumentException("Invalid language name!"); - return this._userMapper.Map<UserServiceModel>(user); - } + UpdateLanguageServiceModel updateLanguageServiceModel = this._userMapper.Map<UpdateLanguageServiceModel>(language); - public async Task<UserServiceModel> GetFriendById(Guid friendId) - { - if (!await _userRepository.DoesUserExistAsync(friendId)) - throw new ArgumentException("User does not exist!"); + updateUserServiceModel.Languages.Add(updateLanguageServiceModel); + } - User friend = await this._userRepository.GetByIdAsync(friendId); + //Clean the already replaced languages + updateUserServiceModel.Languages.RemoveWhere(x => x.Id == Guid.Empty); - return this._userMapper.Map<UserServiceModel>(friend); - } - #endregion + int techCount = updateUserServiceModel.Technologies.Count; + for (int i = 0; i < techCount; i++) + { + Technology technology = await this._technologyRepository.GetByNameAsync(updateUserServiceModel.Technologies.ElementAt(i).Name) ?? + throw new ArgumentException("Invalid technology name!"); - #region Update + UpdateTechnologyServiceModel updateTechnologyServiceModel = this._userMapper.Map<UpdateTechnologyServiceModel>(technology); - public async Task<UserServiceModel> UpdateUser(UpdateUserServiceModel updateModel) - { - if (!await this._userRepository.DoesUserExistAsync(updateModel.Id)) - throw new ArgumentException("User does not exist!"); + updateUserServiceModel.Technologies.Add(updateTechnologyServiceModel); + } - if (!this._userRepository.DoesUserHaveThisUsername(updateModel.Id, updateModel.UserName) - && await this._userRepository.DoesUsernameExistAsync(updateModel.UserName)) - throw new ArgumentException("Username already exists!"); + //Clean the already replaced technologies + updateUserServiceModel.Technologies.RemoveWhere(x => x.Id == Guid.Empty); - User user = this._userMapper.Map<User>(updateModel); - bool result = await this._userRepository.EditAsync(user); + User user = this._userMapper.Map<User>(updateUserServiceModel); + bool successful = await this._userRepository.EditAsync(user); - if (!result) + if (!successful) throw new InvalidOperationException("Unable to edit user!"); - return this._userMapper.Map<UserServiceModel>(user); ; + return this._userMapper.Map<UserServiceModel>(user); } #endregion #region Delete - public async Task DeleteUser(Guid id) { if (!await this._userRepository.DoesUserExistAsync(id)) @@ -205,75 +173,15 @@ namespace DevHive.Services.Services if (!result) throw new InvalidOperationException("Unable to delete user!"); } - - public async Task<bool> RemoveFriend(Guid userId, Guid friendId) - { - Task<bool> userExists = this._userRepository.DoesUserExistAsync(userId); - Task<bool> friendExists = this._userRepository.DoesUserExistAsync(friendId); - - await Task.WhenAll(userExists, friendExists); - - if (!userExists.Result) - throw new ArgumentException("User doesn't exist!"); - - if (!friendExists.Result) - throw new ArgumentException("Friend doesn't exist!"); - - if (!await this._userRepository.DoesUserHaveThisFriendAsync(userId, friendId)) - throw new ArgumentException("This ain't your friend, amigo."); - - return await this.RemoveFriend(userId, friendId); - } - - public async Task<bool> RemoveLanguageFromUser(Guid userId, LanguageServiceModel languageServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool languageExists = await this._languageRepository.DoesLanguageExistAsync(languageServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!languageExists) - throw new ArgumentException("Language does not exist!"); - - User user = await this._userRepository.GetByIdAsync(userId); - Language language = await this._languageRepository.GetByIdAsync(languageServiceModel.Id); - - if (!this._userRepository.DoesUserHaveThisLanguage(user, language)) - throw new ArgumentException("User does not have this language!"); - - return await this._userRepository.RemoveLanguageFromUserAsync(user, language); - } - - public async Task<bool> RemoveTechnologyFromUser(Guid userId, TechnologyServiceModel technologyServiceModel) - { - bool userExists = await this._userRepository.DoesUserExistAsync(userId); - bool technologyExists = await this._technologyRepository.DoesTechnologyExistAsync(technologyServiceModel.Id); - - if (!userExists) - throw new ArgumentException("User does not exist!"); - - if (!technologyExists) - throw new ArgumentException("Language does not exist!"); - - User user = await this._userRepository.GetByIdAsync(userId); - Technology technology = await this._technologyRepository.GetByIdAsync(technologyServiceModel.Id); - - if (!this._userRepository.DoesUserHaveThisTechnology(user, technology)) - throw new ArgumentException("User does not have this technology!"); - - return await this._userRepository.RemoveTechnologyFromUserAsync(user, technology); - } #endregion #region Validations - public async Task<bool> ValidJWT(Guid id, string rawTokenData) { // There is authorization name in the beginning, i.e. "Bearer eyJh..." var jwt = new JwtSecurityTokenHandler().ReadJwtToken(rawTokenData.Remove(0, 7)); - Guid jwtUserID = new Guid(this.GetClaimTypeValues("ID", jwt.Claims)[0]); + Guid jwtUserID = new Guid(this.GetClaimTypeValues("ID", jwt.Claims).First()); List<string> jwtRoleNames = this.GetClaimTypeValues("role", jwt.Claims); User user = await this._userRepository.GetByIdAsync(jwtUserID) @@ -312,11 +220,51 @@ namespace DevHive.Services.Services return toReturn; } - private string WriteJWTSecurityToken(Guid userId, IList<Role> roles) + private async Task ValidateUserOnUpdate(UpdateUserServiceModel updateUserServiceModel) + { + if (!await this._userRepository.DoesUserExistAsync(updateUserServiceModel.Id)) + throw new ArgumentException("User does not exist!"); + + if (!this._userRepository.DoesUserHaveThisUsername(updateUserServiceModel.Id, updateUserServiceModel.UserName) + && await this._userRepository.DoesUsernameExistAsync(updateUserServiceModel.UserName)) + throw new ArgumentException("Username already exists!"); + } + + private async Task ValidateUserCollections(UpdateUserServiceModel updateUserServiceModel) + { + // Friends + foreach (var friend in updateUserServiceModel.Friends) + { + User returnedFriend = await this._userRepository.GetByUsernameAsync(friend.Name); + + if (returnedFriend == null) + throw new ArgumentException($"User {friend.Name} does not exist!"); + } + + // Languages + foreach (var language in updateUserServiceModel.Languages) + { + Language returnedLanguage = await this._languageRepository.GetByNameAsync(language.Name); + + if (returnedLanguage == null) + throw new ArgumentException($"Language {language.Name} does not exist!"); + } + + // Technology + foreach (var technology in updateUserServiceModel.Technologies) + { + Technology returnedTechnology = await this._technologyRepository.GetByNameAsync(technology.Name); + + if (returnedTechnology == null) + throw new ArgumentException($"Technology {technology.Name} does not exist!"); + } + } + + private string WriteJWTSecurityToken(Guid userId, HashSet<Role> roles) { byte[] signingKey = Encoding.ASCII.GetBytes(_jwtOptions.Secret); - List<Claim> claims = new() + HashSet<Claim> claims = new() { new Claim("ID", $"{userId}"), }; @@ -339,11 +287,6 @@ namespace DevHive.Services.Services SecurityToken token = tokenHandler.CreateToken(tokenDescriptor); return tokenHandler.WriteToken(token); } - - private string GeneratePasswordHash(string password) - { - return string.Join(string.Empty, SHA512.HashData(Encoding.ASCII.GetBytes(password))); - } #endregion } } diff --git a/src/DevHive.Tests/DevHive.Data.Tests/DevHive.Data.Tests.csproj b/src/DevHive.Tests/DevHive.Data.Tests/DevHive.Data.Tests.csproj index 81e7b2b..d320450 100644 --- a/src/DevHive.Tests/DevHive.Data.Tests/DevHive.Data.Tests.csproj +++ b/src/DevHive.Tests/DevHive.Data.Tests/DevHive.Data.Tests.csproj @@ -8,7 +8,7 @@ <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.1" /> - <PackageReference Include="Moq" Version="4.15.2" /> + <PackageReference Include="Moq" Version="4.16.0" /> <PackageReference Include="NUnit" Version="3.13.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" /> diff --git a/src/DevHive.Tests/DevHive.Data.Tests/LenguageRepository.Tests.cs b/src/DevHive.Tests/DevHive.Data.Tests/LenguageRepository.Tests.cs new file mode 100644 index 0000000..aefeddd --- /dev/null +++ b/src/DevHive.Tests/DevHive.Data.Tests/LenguageRepository.Tests.cs @@ -0,0 +1,11 @@ +using System; +using NUnit.Framework; + +namespace DevHive.Data.Tests +{ + [TestFixture] + public class LenguageRepositoryTests + { + // pending repo refactoring + } +} diff --git a/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs b/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs index 18d72b9..289d846 100644 --- a/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs +++ b/src/DevHive.Tests/DevHive.Data.Tests/TechnologyRepository.Tests.cs @@ -1,4 +1,4 @@ -using DevHive.Data.Models; +using DevHive.Data.Models; using DevHive.Data.Repositories; using Microsoft.EntityFrameworkCore; using NUnit.Framework; @@ -35,11 +35,10 @@ namespace DevHive.Data.Tests } #region AddAsync - [Test] - public void AddAsync_AddsTheGivenTechnologyToTheDatabase() + public async Task AddAsync_AddsTheGivenTechnologyToTheDatabase() { - AddEntity(); + await AddEntity(); int numberOfTechnologies = Context.Technologies.Count(); @@ -48,154 +47,123 @@ namespace DevHive.Data.Tests #endregion #region GetByIdAsync - [Test] - public void GetByIdAsync_ReturnsTheCorrectTechnology_IfIdExists() + public async Task GetByIdAsync_ReturnsTheCorrectTechnology_IfIdExists() { - Task.Run(async () => - { - AddEntity(); - Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault(); - Guid id = technology.Id; + await AddEntity(); + Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault(); + Guid id = technology.Id; - Technology technologyReturned = await this.TechnologyRepository.GetByIdAsync(id); + Technology technologyReturned = await this.TechnologyRepository.GetByIdAsync(id); - Assert.AreEqual(TECHNOLOGY_NAME, technologyReturned.Name, "GetByIdAsync does not return the correct Technology when id is valid"); - }).GetAwaiter().GetResult(); + Assert.AreEqual(TECHNOLOGY_NAME, technologyReturned.Name, "GetByIdAsync does not return the correct Technology when id is valid"); } [Test] - public void GetByIdAsync_ReturnsNull_IfIdDoesNotExists() + public async Task GetByIdAsync_ReturnsNull_IfIdDoesNotExists() { - Task.Run(async () => - { - Guid id = new Guid(); + Guid id = Guid.NewGuid(); - Technology technologyReturned = await this.TechnologyRepository.GetByIdAsync(id); + Technology technologyReturned = await this.TechnologyRepository.GetByIdAsync(id); - Assert.IsNull(technologyReturned, "GetByIdAsync returns Technology when it should be null"); - }).GetAwaiter().GetResult(); + Assert.IsNull(technologyReturned, "GetByIdAsync returns Technology when it should be null"); } #endregion #region DoesTechnologyExistAsync [Test] - public void DoesTechnologyExist_ReturnsTrue_IfIdExists() + public async Task DoesTechnologyExist_ReturnsTrue_IfIdExists() { - Task.Run(async () => - { - AddEntity(); - Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault(); - Guid id = technology.Id; + await AddEntity(); + Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault(); + Guid id = technology.Id; - bool result = await this.TechnologyRepository.DoesTechnologyExistAsync(id); + bool result = await this.TechnologyRepository.DoesTechnologyExistAsync(id); - Assert.IsTrue(result, "DoesTechnologyExistAsync returns flase hwen technology exists"); - }).GetAwaiter().GetResult(); + Assert.IsTrue(result, "DoesTechnologyExistAsync returns flase hwen technology exists"); } [Test] - public void DoesTechnologyExist_ReturnsFalse_IfIdDoesNotExists() + public async Task DoesTechnologyExist_ReturnsFalse_IfIdDoesNotExists() { - Task.Run(async () => - { - Guid id = new Guid(); + Guid id = Guid.NewGuid(); - bool result = await this.TechnologyRepository.DoesTechnologyExistAsync(id); + bool result = await this.TechnologyRepository.DoesTechnologyExistAsync(id); - Assert.IsFalse(result, "DoesTechnologyExistAsync returns true when technology does not exist"); - }).GetAwaiter().GetResult(); + Assert.IsFalse(result, "DoesTechnologyExistAsync returns true when technology does not exist"); } #endregion #region DoesTechnologyNameExistAsync [Test] - public void DoesTechnologyNameExist_ReturnsTrue_IfTechnologyExists() + public async Task DoesTechnologyNameExist_ReturnsTrue_IfTechnologyExists() { - Task.Run(async () => - { - AddEntity(); + await AddEntity(); - bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME); + bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME); - Assert.IsTrue(result, "DoesTechnologyNameExists returns true when technology name does not exist"); - }).GetAwaiter().GetResult(); + Assert.IsTrue(result, "DoesTechnologyNameExists returns true when technology name does not exist"); } [Test] - public void DoesTechnologyNameExist_ReturnsFalse_IfTechnologyDoesNotExists() + public async Task DoesTechnologyNameExist_ReturnsFalse_IfTechnologyDoesNotExists() { - Task.Run(async () => - { - bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME); + bool result = await this.TechnologyRepository.DoesTechnologyNameExistAsync(TECHNOLOGY_NAME); - Assert.False(result, "DoesTechnologyNameExistAsync returns true when technology name does not exist"); - }).GetAwaiter().GetResult(); + Assert.False(result, "DoesTechnologyNameExistAsync returns true when technology name does not exist"); } #endregion #region EditAsync + //TO DO fix: check UserRepo [Test] - public void EditAsync_UpdatesEntity() + public async Task EditAsync_UpdatesEntity() { - Task.Run(async () => + string newName = "New name"; + Technology technology = new Technology { - string newName = "New name"; - Guid id = new Guid(); - Technology technology = new Technology - { - Name = TECHNOLOGY_NAME, - Id = id - }; - Technology newTechnology = new Technology - { - Name = newName, - Id = id - }; - await this.TechnologyRepository.AddAsync(technology); - - bool result = await this.TechnologyRepository.EditAsync(newTechnology); - - Assert.IsTrue(result); - }).GetAwaiter().GetResult(); + Name = TECHNOLOGY_NAME + }; Technology newTechnology = new Technology + { + Name = newName + }; + + await this.TechnologyRepository.AddAsync(technology); + + bool result = await this.TechnologyRepository.EditAsync(newTechnology); + + Assert.IsTrue(result); } #endregion #region DeleteAsync [Test] - public void DeleteAsync_ReturnsTrue_IfDeletionIsSuccesfull() + public async Task DeleteAsync_ReturnsTrue_IfDeletionIsSuccesfull() { - Task.Run(async () => - { - AddEntity(); - Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault(); - - bool result = await this.TechnologyRepository.DeleteAsync(technology); + await AddEntity(); + Technology technology = this.Context.Technologies.Where(x => x.Name == TECHNOLOGY_NAME).ToList().FirstOrDefault(); - Assert.IsTrue(result, "DeleteAsync returns false when deletion is successfull"); + bool result = await this.TechnologyRepository.DeleteAsync(technology); - }).GetAwaiter().GetResult(); + Assert.IsTrue(result, "DeleteAsync returns false when deletion is successfull"); } #endregion #region HelperMethods - private void AddEntity(string name = TECHNOLOGY_NAME) + private async Task AddEntity(string name = TECHNOLOGY_NAME) { - Task.Run(async () => + Technology technology = new Technology { - Technology technology = new Technology - { - Name = name - }; + Name = name + }; - await this.TechnologyRepository.AddAsync(technology); - }).GetAwaiter().GetResult(); + await this.TechnologyRepository.AddAsync(technology); } #endregion //Task.Run(async () => //{ - // + //}).GetAwaiter().GetResult(); } } diff --git a/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs b/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs index b0a5b93..d4daae5 100644 --- a/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs +++ b/src/DevHive.Tests/DevHive.Data.Tests/UserRepositoryTests.cs @@ -51,62 +51,6 @@ namespace DevHive.Data.Tests //Assert Assert.True(result, "User int' inserted properly into the database"); } - - [Test] - public async Task AddFriendToUserAsync_ShouldAddFriendToUsersList() - { - //Arrange - User dummyUserOne = CreateDummyUser(); - User dummyUserTwo = CreateAnotherDummyUser(); - - await this._userRepository.AddAsync(dummyUserOne); - await this._userRepository.AddAsync(dummyUserTwo); - - //Act - bool result = await this._userRepository.AddFriendToUserAsync(dummyUserOne, dummyUserTwo); - - //Assert - Assert.True(result, "Friend didn't save properly in the database"); - Assert.True(dummyUserOne.Friends.Contains(dummyUserTwo), "Friend doesn't get added to user properly"); - } - - [Test] - public async Task AddLanguageToUserAsync_ShouldAddLanguageToUser() - { - //Arrange - User dummyUser = CreateDummyUser(); - await this._userRepository.AddAsync(dummyUser); - Language language = new() - { - Name = "typescript" - }; - - //Act - bool result = await this._userRepository.AddLanguageToUserAsync(dummyUser, language); - - //Assert - Assert.True(result, "The language isn't inserted properly to the database"); - Assert.True(dummyUser.Languages.Contains(language), "The language doesn't get added properly to the user"); - } - - [Test] - public async Task AddTechnologyToUserAsync_ShouldAddTechnologyToUser() - { - //Arrange - User dummyUser = CreateDummyUser(); - await this._userRepository.AddAsync(dummyUser); - Technology technology = new() - { - Name = "Angular" - }; - - //Act - bool result = await this._userRepository.AddTechnologyToUserAsync(dummyUser, technology); - - //Assert - Assert.True(result, "The technology isn't inserted properly to the database"); - Assert.True(dummyUser.Technologies.Contains(technology), "The technology doesn't get added properly to the user"); - } #endregion #region Read @@ -165,10 +109,10 @@ namespace DevHive.Data.Tests //Arrange User dummyUser = CreateDummyUser(); await this._userRepository.AddAsync(dummyUser); - IList<Language> dummyUserLanguages = dummyUser.Languages; + HashSet<Language> dummyUserLanguages = dummyUser.Languages; //Act - IList<Language> languages = this._userRepository.GetUserLanguages(dummyUser); + HashSet<Language> languages = this._userRepository.GetUserLanguages(dummyUser); //Assert Assert.AreEqual(dummyUserLanguages, languages, "Method doesn't query languages properly"); @@ -185,7 +129,7 @@ namespace DevHive.Data.Tests // Language dummyLang = await this._languageRepository.GetByNameAsync("csharp"); // //Act - // IList<Language> languages = this._userRepository.GetUserLanguage(dummyUser, dummyLang); + // HashSet<Language> languages = this._userRepository.GetUserLanguage(dummyUser, dummyLang); // //Assert // Assert.AreEqual(dummyUserLanguages, languages, "Method doesn't query languages properly"); @@ -195,7 +139,7 @@ namespace DevHive.Data.Tests #region HelperMethods private User CreateDummyUser() { - List<Language> languages = new() + HashSet<Language> languages = new() { new Language() { @@ -204,7 +148,7 @@ namespace DevHive.Data.Tests }, }; - List<Technology> technologies = new() + HashSet<Technology> technologies = new() { new Technology() { @@ -213,7 +157,7 @@ namespace DevHive.Data.Tests }, }; - List<Role> roles = new() + HashSet<Role> roles = new() { new Role() { @@ -237,7 +181,7 @@ namespace DevHive.Data.Tests private User CreateAnotherDummyUser() { - List<Language> languages = new() + HashSet<Language> languages = new() { new Language() { @@ -246,7 +190,7 @@ namespace DevHive.Data.Tests }, }; - List<Technology> technologies = new() + HashSet<Technology> technologies = new() { new Technology() { @@ -255,7 +199,7 @@ namespace DevHive.Data.Tests }, }; - List<Role> roles = new() + HashSet<Role> roles = new() { new Role() { diff --git a/src/DevHive.Tests/DevHive.Services.Tests/DevHive.Services.Tests.csproj b/src/DevHive.Tests/DevHive.Services.Tests/DevHive.Services.Tests.csproj index c96dfb8..ce5cb62 100644 --- a/src/DevHive.Tests/DevHive.Services.Tests/DevHive.Services.Tests.csproj +++ b/src/DevHive.Tests/DevHive.Services.Tests/DevHive.Services.Tests.csproj @@ -8,7 +8,7 @@ <ItemGroup> <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.1" /> - <PackageReference Include="Moq" Version="4.15.2" /> + <PackageReference Include="Moq" Version="4.16.0" /> <PackageReference Include="NUnit" Version="3.13.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" /> diff --git a/src/DevHive.Tests/DevHive.Services.Tests/LanguageService.Tests.cs b/src/DevHive.Tests/DevHive.Services.Tests/LanguageService.Tests.cs new file mode 100644 index 0000000..67f1284 --- /dev/null +++ b/src/DevHive.Tests/DevHive.Services.Tests/LanguageService.Tests.cs @@ -0,0 +1,231 @@ +using System; +using System.Threading.Tasks; +using AutoMapper; +using DevHive.Data.Interfaces.Repositories; +using DevHive.Data.Models; +using DevHive.Services.Models.Language; +using DevHive.Services.Services; +using Moq; +using NUnit.Framework; + +namespace DevHive.Services.Tests +{ + [TestFixture] + public class LanguageServiceTests + { + private Mock<ILanguageRepository> LanguageRepositoryMock { get; set; } + private Mock<IMapper> MapperMock { get; set; } + private LanguageService LanguageService { get; set; } + + [SetUp] + public void SetUp() + { + this.LanguageRepositoryMock = new Mock<ILanguageRepository>(); + this.MapperMock = new Mock<IMapper>(); + this.LanguageService = new LanguageService(this.LanguageRepositoryMock.Object, this.MapperMock.Object); + } + + #region Create + [Test] + public async Task CreateLanguage_ReturnsNonEmptyGuid_WhenEntityIsAddedSuccessfully() + { + string technologyName = "Gosho Trapov"; + Guid id = Guid.NewGuid(); + CreateLanguageServiceModel createLanguageServiceModel = new CreateLanguageServiceModel + { + Name = technologyName + }; + Language language = new Language + { + Name = technologyName, + Id = id + }; + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); + this.LanguageRepositoryMock.Setup(p => p.AddAsync(It.IsAny<Language>())).Returns(Task.FromResult(true)); + this.LanguageRepositoryMock.Setup(p => p.GetByNameAsync(It.IsAny<string>())).Returns(Task.FromResult(language)); + this.MapperMock.Setup(p => p.Map<Language>(It.IsAny<CreateLanguageServiceModel>())).Returns(language); + + Guid result = await this.LanguageService.CreateLanguage(createLanguageServiceModel); + + Assert.AreEqual(id, result); + } + + [Test] + public async Task CreateLanguage_ReturnsEmptyGuid_WhenEntityIsNotAddedSuccessfully() + { + string languageName = "Gosho Trapov"; + + CreateLanguageServiceModel createLanguageServiceModel = new CreateLanguageServiceModel + { + Name = languageName + }; + Language language = new Language + { + Name = languageName + }; + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); + this.LanguageRepositoryMock.Setup(p => p.AddAsync(It.IsAny<Language>())).Returns(Task.FromResult(false)); + this.MapperMock.Setup(p => p.Map<Language>(It.IsAny<CreateLanguageServiceModel>())).Returns(language); + + Guid result = await this.LanguageService.CreateLanguage(createLanguageServiceModel); + + Assert.IsTrue(result == Guid.Empty); + + } + + [Test] + public void CreateLanguage_ThrowsArgumentException_WhenEntityAlreadyExists() + { + string exceptionMessage = "Language already exists!"; + string languageName = "Gosho Trapov"; + + CreateLanguageServiceModel createLanguageServiceModel = new CreateLanguageServiceModel + { + Name = languageName + }; + Language language = new Language + { + Name = languageName + }; + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(true)); + + Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.LanguageService.CreateLanguage(createLanguageServiceModel)); + + Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); + } + #endregion + + #region Read + [Test] + public async Task GetLanguageById_ReturnsTheLanguage_WhenItExists() + { + Guid id = new Guid(); + string name = "Gosho Trapov"; + Language language = new Language() + { + Name = name + }; + ReadLanguageServiceModel readLanguageServiceModel = new ReadLanguageServiceModel + { + Name = name + }; + + this.LanguageRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult(language)); + this.MapperMock.Setup(p => p.Map<ReadLanguageServiceModel>(It.IsAny<Language>())).Returns(readLanguageServiceModel); + + ReadLanguageServiceModel result = await this.LanguageService.GetLanguageById(id); + + Assert.AreEqual(name, result.Name); + } + + [Test] + public void GetLanguageById_ThrowsException_WhenLanguageDoesNotExist() + { + string exceptionMessage = "The language does not exist"; + Guid id = new Guid(); + this.LanguageRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult<Language>(null)); + + Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.LanguageService.GetLanguageById(id)); + + Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); + } + #endregion + + #region Update + [Test] + [TestCase(true)] + [TestCase(false)] + public async Task UpdateLanguage_ReturnsIfUpdateIsSuccessfull_WhenLanguageExistsy(bool shouldPass) + { + string name = "Gosho Trapov"; + Language language = new Language + { + Name = name + }; + UpdateLanguageServiceModel updateLanguageServiceModel = new UpdateLanguageServiceModel + { + Name = name, + }; + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); + this.LanguageRepositoryMock.Setup(p => p.EditAsync(It.IsAny<Language>())).Returns(Task.FromResult(shouldPass)); + this.MapperMock.Setup(p => p.Map<Language>(It.IsAny<UpdateLanguageServiceModel>())).Returns(language); + + bool result = await this.LanguageService.UpdateLanguage(updateLanguageServiceModel); + + Assert.AreEqual(shouldPass, result); + } + + [Test] + public void UpdateLanguage_ReturnsIfUpdateIsSuccessfull_WhenLanguageExistsy() + { + string exceptionMessage = "Language does not exist!"; + UpdateLanguageServiceModel updateTechnologyServiceModel = new UpdateLanguageServiceModel + { + }; + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(false)); + + Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.LanguageService.UpdateLanguage(updateTechnologyServiceModel)); + + Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); + } + + [Test] + public void UpdateLanguage_ThrowsException_WhenLanguageNameAlreadyExists() + { + string exceptionMessage = "Language name already exists in our data base!"; + UpdateLanguageServiceModel updateTechnologyServiceModel = new UpdateLanguageServiceModel + { + }; + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(true)); + + Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.LanguageService.UpdateLanguage(updateTechnologyServiceModel)); + + Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); + } + #endregion + + #region Delete + [Test] + [TestCase(true)] + [TestCase(false)] + public async Task DeleteLanguage_ShouldReturnIfDeletionIsSuccessfull_WhenLanguageExists(bool shouldPass) + { + Guid id = new Guid(); + Language language = new Language(); + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); + this.LanguageRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult(language)); + this.LanguageRepositoryMock.Setup(p => p.DeleteAsync(It.IsAny<Language>())).Returns(Task.FromResult(shouldPass)); + + bool result = await this.LanguageService.DeleteLanguage(id); + + Assert.AreEqual(shouldPass, result); + } + + [Test] + public void DeleteLanguage_ThrowsException_WhenLanguageDoesNotExist() + { + string exceptionMessage = "Language does not exist!"; + Guid id = new Guid(); + + this.LanguageRepositoryMock.Setup(p => p.DoesLanguageExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(false)); + + Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.LanguageService.DeleteLanguage(id)); + + Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); + } + #endregion + //Task.Run(async () => + //{ + + //}).GetAwaiter().GetResult(); + } +} diff --git a/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs b/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs index d028957..abd43ed 100644 --- a/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs +++ b/src/DevHive.Tests/DevHive.Services.Tests/TechnologyServices.Tests.cs @@ -26,33 +26,52 @@ namespace DevHive.Services.Tests } #region Create - [Test] - [TestCase(true)] - [TestCase(false)] - public void Create_ReturnsTrue_WhenEntityIsAddedSuccessfully(bool shouldFail) + public async Task Create_ReturnsNonEmptyGuid_WhenEntityIsAddedSuccessfully() { - Task.Run(async () => + string technologyName = "Gosho Trapov"; + Guid id = Guid.NewGuid(); + CreateTechnologyServiceModel createTechnologyServiceModel = new() { - string technologyName = "Gosho Trapov"; + Name = technologyName + }; + Technology technology = new() + { + Name = technologyName, + Id = id + }; + + this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); + this.TechnologyRepositoryMock.Setup(p => p.AddAsync(It.IsAny<Technology>())).Returns(Task.FromResult(true)); + this.TechnologyRepositoryMock.Setup(p => p.GetByNameAsync(It.IsAny<string>())).Returns(Task.FromResult(technology)); + this.MapperMock.Setup(p => p.Map<Technology>(It.IsAny<CreateTechnologyServiceModel>())).Returns(technology); + + Guid result = await this.TechnologyService.Create(createTechnologyServiceModel); + + Assert.AreEqual(id, result); + } - CreateTechnologyServiceModel createTechnologyServiceModel = new() - { - Name = technologyName - }; - Technology technology = new() - { - Name = technologyName - }; + [Test] + public async Task Create_ReturnsEmptyGuid_WhenEntityIsNotAddedSuccessfully() + { + string technologyName = "Gosho Trapov"; + + CreateTechnologyServiceModel createTechnologyServiceModel = new() + { + Name = technologyName + }; + Technology technology = new() + { + Name = technologyName + }; - this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); - this.TechnologyRepositoryMock.Setup(p => p.AddAsync(It.IsAny<Technology>())).Returns(Task.FromResult(shouldFail)); - this.MapperMock.Setup(p => p.Map<Technology>(It.IsAny<CreateTechnologyServiceModel>())).Returns(technology); + this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); + this.TechnologyRepositoryMock.Setup(p => p.AddAsync(It.IsAny<Technology>())).Returns(Task.FromResult(false)); + this.MapperMock.Setup(p => p.Map<Technology>(It.IsAny<CreateTechnologyServiceModel>())).Returns(technology); - bool result = await this.TechnologyService.Create(createTechnologyServiceModel); + Guid result = await this.TechnologyService.Create(createTechnologyServiceModel); - Assert.AreEqual(shouldFail, result); - }).GetAwaiter().GetResult(); + Assert.IsTrue(result == Guid.Empty); } [Test] @@ -79,30 +98,26 @@ namespace DevHive.Services.Tests #endregion #region Read - [Test] - public void GetTechnologyById_ReturnsTheTechnology_WhenItExists() + public async Task GetTechnologyById_ReturnsTheTechnology_WhenItExists() { - Task.Run(async () => + Guid id = new Guid(); + string name = "Gosho Trapov"; + Technology technology = new() { - Guid id = new Guid(); - string name = "Gosho Trapov"; - Technology technology = new() - { - Name = name - }; - CreateTechnologyServiceModel createTechnologyServiceModel = new() - { - Name = name - }; - - this.TechnologyRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult(technology)); - this.MapperMock.Setup(p => p.Map<CreateTechnologyServiceModel>(It.IsAny<Technology>())).Returns(createTechnologyServiceModel); - - CreateTechnologyServiceModel result = await this.TechnologyService.GetTechnologyById(id); - - Assert.AreEqual(name, result.Name); - }).GetAwaiter().GetResult(); + Name = name + }; + CreateTechnologyServiceModel createTechnologyServiceModel = new() + { + Name = name + }; + + this.TechnologyRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult(technology)); + this.MapperMock.Setup(p => p.Map<CreateTechnologyServiceModel>(It.IsAny<Technology>())).Returns(createTechnologyServiceModel); + + CreateTechnologyServiceModel result = await this.TechnologyService.GetTechnologyById(id); + + Assert.AreEqual(name, result.Name); } [Test] @@ -119,48 +134,42 @@ namespace DevHive.Services.Tests #endregion #region Update - [Test] [TestCase(true)] [TestCase(false)] - public void UpdateTechnology_ReturnsIfUpdateIsSuccessfull_WhenTechnologyExistsy(bool shouldPass) + public async Task UpdateTechnology_ReturnsIfUpdateIsSuccessfull_WhenTechnologyExistsy(bool shouldPass) { - Task.Run(async () => + string name = "Gosho Trapov"; + Technology technology = new Technology + { + Name = name + }; + UpdateTechnologyServiceModel updatetechnologyServiceModel = new UpdateTechnologyServiceModel { - Guid id = new Guid(); - string name = "Gosho Trapov"; - Technology technology = new Technology - { - Name = name - }; - UpdateTechnologyServiceModel updatetechnologyServiceModel = new UpdateTechnologyServiceModel - { - Name = name, - }; - - this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); - this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); - this.TechnologyRepositoryMock.Setup(p => p.EditAsync(It.IsAny<Technology>())).Returns(Task.FromResult(shouldPass)); - this.MapperMock.Setup(p => p.Map<Technology>(It.IsAny<UpdateTechnologyServiceModel>())).Returns(technology); - - bool result = await this.TechnologyService.UpdateTechnology(id, updatetechnologyServiceModel); - - Assert.AreEqual(shouldPass, result); - }).GetAwaiter().GetResult(); + Name = name, + }; + + this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); + this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(false)); + this.TechnologyRepositoryMock.Setup(p => p.EditAsync(It.IsAny<Technology>())).Returns(Task.FromResult(shouldPass)); + this.MapperMock.Setup(p => p.Map<Technology>(It.IsAny<UpdateTechnologyServiceModel>())).Returns(technology); + + bool result = await this.TechnologyService.UpdateTechnology(updatetechnologyServiceModel); + + Assert.AreEqual(shouldPass, result); } [Test] public void UpdateTechnology_ThrowsException_WhenTechnologyDoesNotExist() { string exceptionMessage = "Technology does not exist!"; - Guid id = new Guid(); UpdateTechnologyServiceModel updateTechnologyServiceModel = new UpdateTechnologyServiceModel { }; this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(false)); - Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.TechnologyService.UpdateTechnology(id, updateTechnologyServiceModel)); + Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.TechnologyService.UpdateTechnology(updateTechnologyServiceModel)); Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); } @@ -169,7 +178,6 @@ namespace DevHive.Services.Tests public void UpdateTechnology_ThrowsException_WhenTechnologyNameAlreadyExists() { string exceptionMessage = "Technology name already exists!"; - Guid id = new Guid(); UpdateTechnologyServiceModel updateTechnologyServiceModel = new UpdateTechnologyServiceModel { }; @@ -177,7 +185,7 @@ namespace DevHive.Services.Tests this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyNameExistAsync(It.IsAny<string>())).Returns(Task.FromResult(true)); - Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.TechnologyService.UpdateTechnology(id, updateTechnologyServiceModel)); + Exception ex = Assert.ThrowsAsync<ArgumentException>(() => this.TechnologyService.UpdateTechnology(updateTechnologyServiceModel)); Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); } @@ -188,21 +196,18 @@ namespace DevHive.Services.Tests [Test] [TestCase(true)] [TestCase(false)] - public void DeleteTechnology_ShouldReturnIfDeletionIsSuccessfull_WhenTechnologyExists(bool shouldPass) + public async Task DeleteTechnology_ShouldReturnIfDeletionIsSuccessfull_WhenTechnologyExists(bool shouldPass) { - Task.Run(async () => - { - Guid id = new Guid(); - Technology technology = new Technology(); + Guid id = new Guid(); + Technology technology = new Technology(); - this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); - this.TechnologyRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult(technology)); - this.TechnologyRepositoryMock.Setup(p => p.DeleteAsync(It.IsAny<Technology>())).Returns(Task.FromResult(shouldPass)); + this.TechnologyRepositoryMock.Setup(p => p.DoesTechnologyExistAsync(It.IsAny<Guid>())).Returns(Task.FromResult(true)); + this.TechnologyRepositoryMock.Setup(p => p.GetByIdAsync(It.IsAny<Guid>())).Returns(Task.FromResult(technology)); + this.TechnologyRepositoryMock.Setup(p => p.DeleteAsync(It.IsAny<Technology>())).Returns(Task.FromResult(shouldPass)); - bool result = await this.TechnologyService.DeleteTechnology(id); + bool result = await this.TechnologyService.DeleteTechnology(id); - Assert.AreEqual(shouldPass, result); - }).GetAwaiter().GetResult(); + Assert.AreEqual(shouldPass, result); } [Test] @@ -218,9 +223,10 @@ namespace DevHive.Services.Tests Assert.AreEqual(exceptionMessage, ex.Message, "Incorecct exception message"); } #endregion + //Task.Run(async () => //{ - // + //}).GetAwaiter().GetResult(); } } diff --git a/src/DevHive.Tests/DevHive.Web.Tests/DevHive.Web.Tests.csproj b/src/DevHive.Tests/DevHive.Web.Tests/DevHive.Web.Tests.csproj index 47f40ee..a171e0b 100644 --- a/src/DevHive.Tests/DevHive.Web.Tests/DevHive.Web.Tests.csproj +++ b/src/DevHive.Tests/DevHive.Web.Tests/DevHive.Web.Tests.csproj @@ -7,7 +7,7 @@ </PropertyGroup> <ItemGroup> - <PackageReference Include="Moq" Version="4.15.2" /> + <PackageReference Include="Moq" Version="4.16.0" /> <PackageReference Include="NUnit" Version="3.13.0" /> <PackageReference Include="NUnit3TestAdapter" Version="3.17.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" /> diff --git a/src/DevHive.Tests/DevHive.Web.Tests/LanguageController.Tests.cs b/src/DevHive.Tests/DevHive.Web.Tests/LanguageController.Tests.cs new file mode 100644 index 0000000..913d9df --- /dev/null +++ b/src/DevHive.Tests/DevHive.Web.Tests/LanguageController.Tests.cs @@ -0,0 +1,201 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using AutoMapper; +using DevHive.Services.Interfaces; +using DevHive.Services.Models.Language; +using DevHive.Web.Controllers; +using DevHive.Web.Models.Language; +using Microsoft.AspNetCore.Mvc; +using Moq; +using NUnit.Framework; + +namespace DevHive.Web.Tests +{ + [TestFixture] + public class LanguageControllerTests + { + const string NAME = "Gosho Trapov"; + private Mock<ILanguageService> LanguageServiceMock { get; set; } + private Mock<IMapper> MapperMock { get; set; } + private LanguageController LanguageController { get; set; } + + [SetUp] + public void SetUp() + { + this.LanguageServiceMock = new Mock<ILanguageService>(); + this.MapperMock = new Mock<IMapper>(); + this.LanguageController = new LanguageController(this.LanguageServiceMock.Object, this.MapperMock.Object); + } + + #region Create + [Test] + public void CreateLanguage_ReturnsOkObjectResult_WhenLanguageIsSuccessfullyCreated() + { + CreateLanguageWebModel createLanguageWebModel = new CreateLanguageWebModel + { + Name = NAME + }; + CreateLanguageServiceModel createLanguageServiceModel = new CreateLanguageServiceModel + { + Name = NAME + }; + Guid id = Guid.NewGuid(); + + this.MapperMock.Setup(p => p.Map<CreateLanguageServiceModel>(It.IsAny<CreateLanguageWebModel>())).Returns(createLanguageServiceModel); + this.LanguageServiceMock.Setup(p => p.CreateLanguage(It.IsAny<CreateLanguageServiceModel>())).Returns(Task.FromResult(id)); + + IActionResult result = this.LanguageController.Create(createLanguageWebModel).Result; + + Assert.IsInstanceOf<OkObjectResult>(result); + + var splitted = (result as OkObjectResult).Value + .ToString() + .Split('{', '}', '=', ' ') + .Where(x => !string.IsNullOrEmpty(x)) + .ToArray(); + + Guid resultId = Guid.Parse(splitted[1]); + + Assert.AreEqual(id, resultId); + } + + [Test] + public void CreateLanguage_ReturnsBadRequestObjectResult_WhenLanguageIsNotCreatedSuccessfully() + { + CreateLanguageWebModel createTechnologyWebModel = new CreateLanguageWebModel + { + Name = NAME + }; + CreateLanguageServiceModel createTechnologyServiceModel = new CreateLanguageServiceModel + { + Name = NAME + }; + Guid id = Guid.Empty; + string errorMessage = $"Could not create language {NAME}"; + + this.MapperMock.Setup(p => p.Map<CreateLanguageServiceModel>(It.IsAny<CreateLanguageWebModel>())).Returns(createTechnologyServiceModel); + this.LanguageServiceMock.Setup(p => p.CreateLanguage(It.IsAny<CreateLanguageServiceModel>())).Returns(Task.FromResult(id)); + + IActionResult result = this.LanguageController.Create(createTechnologyWebModel).Result; + + Assert.IsInstanceOf<BadRequestObjectResult>(result); + + BadRequestObjectResult badRequsetObjectResult = result as BadRequestObjectResult; + string resultMessage = badRequsetObjectResult.Value.ToString(); + + Assert.AreEqual(errorMessage, resultMessage); + } + #endregion + + #region Read + [Test] + public void GetById_ReturnsTheLanguage_WhenItExists() + { + Guid id = Guid.NewGuid(); + + ReadLanguageServiceModel readLanguageServiceModel = new ReadLanguageServiceModel + { + Name = NAME + }; + ReadLanguageWebModel readLanguageWebModel = new ReadLanguageWebModel + { + Name = NAME + }; + + this.LanguageServiceMock.Setup(p => p.GetLanguageById(It.IsAny<Guid>())).Returns(Task.FromResult(readLanguageServiceModel)); + this.MapperMock.Setup(p => p.Map<ReadLanguageWebModel>(It.IsAny<ReadLanguageServiceModel>())).Returns(readLanguageWebModel); + + IActionResult result = this.LanguageController.GetById(id).Result; + + Assert.IsInstanceOf<OkObjectResult>(result); + + OkObjectResult okObjectResult = result as OkObjectResult; + ReadLanguageWebModel resultModel = okObjectResult.Value as Models.Language.ReadLanguageWebModel; + + Assert.AreEqual(NAME, resultModel.Name); + } + #endregion + + #region Update + [Test] + public void Update_ShouldReturnOkResult_WhenLanguageIsUpdatedSuccessfully() + { + Guid id = Guid.NewGuid(); + UpdateLanguageWebModel updateLanguageWebModel = new UpdateLanguageWebModel + { + Name = NAME + }; + UpdateLanguageServiceModel updateLanguageServiceModel = new UpdateLanguageServiceModel + { + Name = NAME + }; + + this.LanguageServiceMock.Setup(p => p.UpdateLanguage(It.IsAny<UpdateLanguageServiceModel>())).Returns(Task.FromResult(true)); + this.MapperMock.Setup(p => p.Map<UpdateLanguageServiceModel>(It.IsAny<UpdateLanguageWebModel>())).Returns(updateLanguageServiceModel); + + IActionResult result = this.LanguageController.Update(id, updateLanguageWebModel).Result; + + Assert.IsInstanceOf<OkResult>(result); + } + + [Test] + public void Update_ShouldReturnOkResult_WhenLanguageIsNotUpdatedSuccessfully() + { + Guid id = Guid.NewGuid(); + string message = "Could not update Language"; + UpdateLanguageWebModel updateLanguageWebModel = new UpdateLanguageWebModel + { + Name = NAME + }; + UpdateLanguageServiceModel updateLanguageServiceModel = new UpdateLanguageServiceModel + { + Name = NAME + }; + + this.LanguageServiceMock.Setup(p => p.UpdateLanguage(It.IsAny<UpdateLanguageServiceModel>())).Returns(Task.FromResult(false)); + this.MapperMock.Setup(p => p.Map<UpdateLanguageServiceModel>(It.IsAny<UpdateLanguageWebModel>())).Returns(updateLanguageServiceModel); + + IActionResult result = this.LanguageController.Update(id, updateLanguageWebModel).Result; + Assert.IsInstanceOf<BadRequestObjectResult>(result); + + BadRequestObjectResult badRequestObjectResult = result as BadRequestObjectResult; + string resultModel = badRequestObjectResult.Value.ToString(); + + Assert.AreEqual(message, resultModel); + } + #endregion + + #region Delete + [Test] + public void Delete_ReturnsOkResult_When_LanguageIsDeletedSuccessfully() + { + Guid id = Guid.NewGuid(); + + this.LanguageServiceMock.Setup(p => p.DeleteLanguage(It.IsAny<Guid>())).Returns(Task.FromResult(true)); + + IActionResult result = this.LanguageController.Delete(id).Result; + + Assert.IsInstanceOf<OkResult>(result); + } + + [Test] + public void Delet_ReturnsBadRequestObjectResult_WhenLanguageIsNotDeletedSuccessfully() + { + string message = "Could not delete Language"; + Guid id = Guid.NewGuid(); + + this.LanguageServiceMock.Setup(p => p.DeleteLanguage(It.IsAny<Guid>())).Returns(Task.FromResult(false)); + + IActionResult result = this.LanguageController.Delete(id).Result; + + Assert.IsInstanceOf<BadRequestObjectResult>(result); + + BadRequestObjectResult badRequestObjectResult = result as BadRequestObjectResult; + string resultModel = badRequestObjectResult.Value.ToString(); + + Assert.AreEqual(message, resultModel); + } + #endregion + } +} diff --git a/src/DevHive.Tests/DevHive.Web.Tests/PostController.Tests.cs b/src/DevHive.Tests/DevHive.Web.Tests/PostController.Tests.cs new file mode 100644 index 0000000..18ed1b9 --- /dev/null +++ b/src/DevHive.Tests/DevHive.Web.Tests/PostController.Tests.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace DevHive.Web.Tests +{ + class PostController + { + } +} diff --git a/src/DevHive.Tests/DevHive.Web.Tests/TechnologyController.Tests.cs b/src/DevHive.Tests/DevHive.Web.Tests/TechnologyController.Tests.cs index 2709c9a..40434d6 100644 --- a/src/DevHive.Tests/DevHive.Web.Tests/TechnologyController.Tests.cs +++ b/src/DevHive.Tests/DevHive.Web.Tests/TechnologyController.Tests.cs @@ -1,4 +1,5 @@ using AutoMapper; +using DevHive.Common.Models.Misc; using DevHive.Services.Interfaces; using DevHive.Services.Models.Technology; using DevHive.Web.Controllers; @@ -7,6 +8,7 @@ using Microsoft.AspNetCore.Mvc; using Moq; using NUnit.Framework; using System; +using System.Linq; using System.Threading.Tasks; namespace DevHive.Web.Tests @@ -30,7 +32,7 @@ namespace DevHive.Web.Tests #region Create [Test] public void Create_ReturnsOkObjectResult_WhenTechnologyIsSuccessfullyCreated() - { + { CreateTechnologyWebModel createTechnologyWebModel = new CreateTechnologyWebModel { Name = NAME @@ -39,13 +41,24 @@ namespace DevHive.Web.Tests { Name = NAME }; + Guid id = Guid.NewGuid(); this.MapperMock.Setup(p => p.Map<CreateTechnologyServiceModel>(It.IsAny<CreateTechnologyWebModel>())).Returns(createTechnologyServiceModel); - this.TechnologyServiceMock.Setup(p => p.Create(It.IsAny<CreateTechnologyServiceModel>())).Returns(Task.FromResult(true)); + this.TechnologyServiceMock.Setup(p => p.Create(It.IsAny<CreateTechnologyServiceModel>())).Returns(Task.FromResult(id)); IActionResult result = this.TechnologyController.Create(createTechnologyWebModel).Result; - Assert.IsInstanceOf<OkResult>(result); + Assert.IsInstanceOf<OkObjectResult>(result); + + var splitted = (result as OkObjectResult).Value + .ToString() + .Split('{', '}', '=', ' ') + .Where(x => !string.IsNullOrEmpty(x)) + .ToArray(); + + Guid resultId = Guid.Parse(splitted[1]); + + Assert.AreEqual(id, resultId); } [Test] @@ -59,13 +72,20 @@ namespace DevHive.Web.Tests { Name = NAME }; + Guid id = Guid.Empty; + string errorMessage = $"Could not create technology {NAME}"; this.MapperMock.Setup(p => p.Map<CreateTechnologyServiceModel>(It.IsAny<CreateTechnologyWebModel>())).Returns(createTechnologyServiceModel); - this.TechnologyServiceMock.Setup(p => p.Create(It.IsAny<CreateTechnologyServiceModel>())).Returns(Task.FromResult(false)); + this.TechnologyServiceMock.Setup(p => p.Create(It.IsAny<CreateTechnologyServiceModel>())).Returns(Task.FromResult(id)); IActionResult result = this.TechnologyController.Create(createTechnologyWebModel).Result; Assert.IsInstanceOf<BadRequestObjectResult>(result); + + BadRequestObjectResult badRequsetObjectResult = result as BadRequestObjectResult; + string resultMessage = badRequsetObjectResult.Value.ToString(); + + Assert.AreEqual(errorMessage, resultMessage); } #endregion @@ -73,7 +93,7 @@ namespace DevHive.Web.Tests [Test] public void GetById_ReturnsTheThecnology_WhenItExists() { - Guid id = new Guid(); + Guid id = Guid.NewGuid(); CreateTechnologyServiceModel createTechnologyServiceModel = new CreateTechnologyServiceModel { @@ -102,7 +122,7 @@ namespace DevHive.Web.Tests [Test] public void Update_ShouldReturnOkResult_WhenTechnologyIsUpdatedSuccessfully() { - Guid id = new Guid(); + Guid id = Guid.NewGuid(); UpdateTechnologyWebModel updateTechnologyWebModel = new UpdateTechnologyWebModel { Name = NAME @@ -112,7 +132,7 @@ namespace DevHive.Web.Tests Name = NAME }; - this.TechnologyServiceMock.Setup(p => p.UpdateTechnology(It.IsAny<Guid>(), It.IsAny<UpdateTechnologyServiceModel>())).Returns(Task.FromResult(true)); + this.TechnologyServiceMock.Setup(p => p.UpdateTechnology(It.IsAny<UpdateTechnologyServiceModel>())).Returns(Task.FromResult(true)); this.MapperMock.Setup(p => p.Map<UpdateTechnologyServiceModel>(It.IsAny<UpdateTechnologyWebModel>())).Returns(updateTechnologyServiceModel); IActionResult result = this.TechnologyController.Update(id, updateTechnologyWebModel).Result; @@ -121,9 +141,9 @@ namespace DevHive.Web.Tests } [Test] - public void Update_ShouldReturnOkResult_WhenTechnologyIsNotUpdatedSuccessfully () + public void Update_ShouldReturnOkResult_WhenTechnologyIsNotUpdatedSuccessfully() { - Guid id = new Guid(); + Guid id = Guid.NewGuid(); string message = "Could not update Technology"; UpdateTechnologyWebModel updateTechnologyWebModel = new UpdateTechnologyWebModel { @@ -134,7 +154,7 @@ namespace DevHive.Web.Tests Name = NAME }; - this.TechnologyServiceMock.Setup(p => p.UpdateTechnology(It.IsAny<Guid>(), It.IsAny<UpdateTechnologyServiceModel>())).Returns(Task.FromResult(false)); + this.TechnologyServiceMock.Setup(p => p.UpdateTechnology(It.IsAny<UpdateTechnologyServiceModel>())).Returns(Task.FromResult(false)); this.MapperMock.Setup(p => p.Map<UpdateTechnologyServiceModel>(It.IsAny<UpdateTechnologyWebModel>())).Returns(updateTechnologyServiceModel); IActionResult result = this.TechnologyController.Update(id, updateTechnologyWebModel).Result; @@ -151,7 +171,7 @@ namespace DevHive.Web.Tests [Test] public void Delete_ReturnsOkResult_When_TechnologyIsDeletedSuccessfully() { - Guid id = new Guid(); + Guid id = Guid.NewGuid(); this.TechnologyServiceMock.Setup(p => p.DeleteTechnology(It.IsAny<Guid>())).Returns(Task.FromResult(true)); @@ -164,7 +184,7 @@ namespace DevHive.Web.Tests public void Delet_ReturnsBadRequestObjectResult_WhenTechnologyIsNotDeletedSuccessfully() { string message = "Could not delete Technology"; - Guid id = new Guid(); + Guid id = Guid.NewGuid(); this.TechnologyServiceMock.Setup(p => p.DeleteTechnology(It.IsAny<Guid>())).Returns(Task.FromResult(false)); diff --git a/src/DevHive.Web/Models/Identity/Validation/GoodPasswordModelValidation.cs b/src/DevHive.Web/Attributes/GoodPasswordModelValidation.cs index f920c35..7d6a1ea 100644 --- a/src/DevHive.Web/Models/Identity/Validation/GoodPasswordModelValidation.cs +++ b/src/DevHive.Web/Attributes/GoodPasswordModelValidation.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace DevHive.Web.Models.Identity.Validation +namespace DevHive.Web.Attributes { public class GoodPassword : ValidationAttribute { diff --git a/src/DevHive.Web/Models/Identity/Validation/OnlyAlphanumericsModelValidation.cs b/src/DevHive.Web/Attributes/OnlyAlphanumericsModelValidation.cs index 5c8c66c..26e0733 100644 --- a/src/DevHive.Web/Models/Identity/Validation/OnlyAlphanumericsModelValidation.cs +++ b/src/DevHive.Web/Attributes/OnlyAlphanumericsModelValidation.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace DevHive.Web.Models.Identity.Validation +namespace DevHive.Web.Attributes { public class OnlyAlphanumerics : ValidationAttribute { diff --git a/src/DevHive.Web/Models/Identity/Validation/OnlyLettersModelValidation.cs b/src/DevHive.Web/Attributes/OnlyLettersModelValidation.cs index 29a995a..07afee9 100644 --- a/src/DevHive.Web/Models/Identity/Validation/OnlyLettersModelValidation.cs +++ b/src/DevHive.Web/Attributes/OnlyLettersModelValidation.cs @@ -1,7 +1,7 @@ using System; using System.ComponentModel.DataAnnotations; -namespace DevHive.Web.Models.Identity.Validation +namespace DevHive.Web.Attributes { public class OnlyLetters : ValidationAttribute { diff --git a/src/DevHive.Web/Configurations/Extensions/ConfigureExceptionHandlerMiddleware.cs b/src/DevHive.Web/Configurations/Extensions/ConfigureExceptionHandlerMiddleware.cs new file mode 100644 index 0000000..286727f --- /dev/null +++ b/src/DevHive.Web/Configurations/Extensions/ConfigureExceptionHandlerMiddleware.cs @@ -0,0 +1,16 @@ +using DevHive.Web.Middleware; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; + +namespace DevHive.Web.Configurations.Extensions +{ + public static class ConfigureExceptionHandlerMiddleware + { + public static void ExceptionHandlerMiddlewareConfiguration(this IServiceCollection services) { } + + public static void UseExceptionHandlerMiddlewareConfiguration(this IApplicationBuilder app) + { + app.UseMiddleware<ExceptionMiddleware>(); + } + } +} diff --git a/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs b/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs index 3c2a4d0..eca0d1a 100644 --- a/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/LanguageMappings.cs @@ -8,11 +8,14 @@ namespace DevHive.Web.Configurations.Mapping { public LanguageMappings() { - CreateMap<LanguageWebModel, LanguageServiceModel>(); CreateMap<CreateLanguageWebModel, CreateLanguageServiceModel>(); - CreateMap<UpdateLanguageWebModel, UpdateLanguageServiceModel>(); + CreateMap<ReadLanguageWebModel, ReadLanguageServiceModel>(); + CreateMap<UpdateLanguageWebModel, UpdateLanguageServiceModel>() + .ForMember(src => src.Id, dest => dest.Ignore()); + CreateMap<LanguageWebModel, LanguageServiceModel>(); CreateMap<LanguageServiceModel, LanguageWebModel>(); + CreateMap<ReadLanguageServiceModel, ReadLanguageWebModel>(); CreateMap<CreateLanguageServiceModel, CreateLanguageWebModel>(); CreateMap<UpdateLanguageServiceModel, UpdateLanguageWebModel>(); } diff --git a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs index afa3a94..2ea2742 100644 --- a/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/RoleMappings.cs @@ -1,6 +1,6 @@ using AutoMapper; using DevHive.Web.Models.Identity.Role; -using DevHive.Common.Models.Identity; +using DevHive.Services.Models.Identity.Role; namespace DevHive.Web.Configurations.Mapping { @@ -8,11 +8,14 @@ namespace DevHive.Web.Configurations.Mapping { public RoleMappings() { - CreateMap<CreateRoleModel, RoleModel>(); - CreateMap<UpdateRoleModel, RoleModel>(); + CreateMap<CreateRoleWebModel, CreateRoleServiceModel>(); + CreateMap<UpdateRoleWebModel, UpdateRoleServiceModel>() + .ForMember(src => src.Id, dest => dest.Ignore()); + CreateMap<RoleWebModel, RoleServiceModel>(); - CreateMap<RoleModel, RoleWebModel>(); - CreateMap<RoleWebModel, RoleModel>(); + CreateMap<CreateRoleServiceModel, CreateRoleWebModel>(); + CreateMap<UpdateRoleServiceModel, UpdateRoleWebModel>(); + CreateMap<RoleServiceModel, RoleWebModel>(); } } } diff --git a/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs b/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs index 828dac1..708b6ac 100644 --- a/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/TechnologyMappings.cs @@ -9,10 +9,13 @@ namespace DevHive.Web.Configurations.Mapping public TechnologyMappings() { CreateMap<CreateTechnologyWebModel, CreateTechnologyServiceModel>(); - CreateMap<UpdateTechnologyWebModel, UpdateTechnologyServiceModel>(); + CreateMap<ReadTechnologyWebModel, ReadTechnologyServiceModel>(); + CreateMap<UpdateTechnologyWebModel, UpdateTechnologyServiceModel>() + .ForMember(src => src.Id, dest => dest.Ignore()); CreateMap<TechnologyWebModel, TechnologyServiceModel>(); CreateMap<CreateTechnologyServiceModel, CreateTechnologyWebModel>(); + CreateMap<ReadTechnologyServiceModel, ReadTechnologyWebModel>(); CreateMap<UpdateTechnologyServiceModel, UpdateTechnologyWebModel>(); CreateMap<TechnologyServiceModel, TechnologyWebModel>(); } diff --git a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs index 59003ea..9dbf613 100644 --- a/src/DevHive.Web/Configurations/Mapping/UserMappings.cs +++ b/src/DevHive.Web/Configurations/Mapping/UserMappings.cs @@ -2,6 +2,8 @@ using AutoMapper; using DevHive.Services.Models.Identity.User; using DevHive.Web.Models.Identity.User; using DevHive.Common.Models.Identity; +using DevHive.Web.Models.Language; +using DevHive.Web.Models.Technology; namespace DevHive.Web.Configurations.Mapping { @@ -17,6 +19,15 @@ namespace DevHive.Web.Configurations.Mapping CreateMap<UserServiceModel, UserWebModel>(); CreateMap<TokenModel, TokenWebModel>(); + + //Update + CreateMap<UpdateUserWebModel, UpdateUserServiceModel>() + .ForMember(src => src.Id, dest => dest.Ignore()); + CreateMap<FriendWebModel, FriendServiceModel>() + .ForMember(src => src.Id, dest => dest.Ignore()); + + CreateMap<UpdateUserServiceModel, UpdateUserWebModel>(); + CreateMap<FriendServiceModel, FriendWebModel>(); } } } diff --git a/src/DevHive.Web/Controllers/ErrorController.cs b/src/DevHive.Web/Controllers/ErrorController.cs deleted file mode 100644 index b187501..0000000 --- a/src/DevHive.Web/Controllers/ErrorController.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Diagnostics; -using AutoMapper; -using Microsoft.AspNetCore.Diagnostics; -using Microsoft.AspNetCore.Http; -using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; - -namespace DevHive.Web.Controllers -{ - public class ErrorController : ControllerBase - { - [HttpPost] - [Route("/api/Error")] - public IActionResult Error() - { - //Later for logging - string requestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; - - IExceptionHandlerFeature exception = - HttpContext.Features.Get<IExceptionHandlerFeature>(); - - object result = ProcessException(requestId, exception); - return new BadRequestObjectResult(JsonConvert.SerializeObject(result)); - } - - private object ProcessException(string requestId, IExceptionHandlerFeature exception) - { - switch (exception.Error) - { - case ArgumentException _: - case InvalidOperationException _: - case AutoMapperMappingException _: - case AutoMapperConfigurationException _: - return MessageToObject(exception.Error.Message); - default: - return MessageToObject(null); - } - } - - private object MessageToObject(string message) - { - return new - { - Error = message - }; - } - } -} - diff --git a/src/DevHive.Web/Controllers/LanguageController.cs b/src/DevHive.Web/Controllers/LanguageController.cs index 5202f16..e2d0dec 100644 --- a/src/DevHive.Web/Controllers/LanguageController.cs +++ b/src/DevHive.Web/Controllers/LanguageController.cs @@ -26,29 +26,29 @@ namespace DevHive.Web.Controllers { CreateLanguageServiceModel languageServiceModel = this._languageMapper.Map<CreateLanguageServiceModel>(createLanguageWebModel); - bool result = await this._languageService.CreateLanguage(languageServiceModel); + Guid id = await this._languageService.CreateLanguage(languageServiceModel); - if (!result) - return new BadRequestObjectResult("Could not create Language"); - - return new OkResult(); + return id == Guid.Empty ? + new BadRequestObjectResult($"Could not create language {createLanguageWebModel.Name}") : + new OkObjectResult(new { Id = id }); } [HttpGet] - public async Task<IActionResult> GetById(Guid languageId) + public async Task<IActionResult> GetById(Guid id) { - LanguageServiceModel languageServiceModel = await this._languageService.GetLanguageById(languageId); - LanguageWebModel languageWebModel = this._languageMapper.Map<LanguageWebModel>(languageServiceModel); + ReadLanguageServiceModel languageServiceModel = await this._languageService.GetLanguageById(id); + ReadLanguageWebModel languageWebModel = this._languageMapper.Map<ReadLanguageWebModel>(languageServiceModel); return new OkObjectResult(languageWebModel); } [HttpPut] - public async Task<IActionResult> Update(Guid languageId, [FromBody] UpdateLanguageWebModel updateModel) + public async Task<IActionResult> Update(Guid id, [FromBody] UpdateLanguageWebModel updateModel) { UpdateLanguageServiceModel updatelanguageServiceModel = this._languageMapper.Map<UpdateLanguageServiceModel>(updateModel); + updatelanguageServiceModel.Id = id; - bool result = await this._languageService.UpdateLanguage(languageId, updatelanguageServiceModel); + bool result = await this._languageService.UpdateLanguage(updatelanguageServiceModel); if (!result) return new BadRequestObjectResult("Could not update Language"); @@ -57,9 +57,9 @@ namespace DevHive.Web.Controllers } [HttpDelete] - public async Task<IActionResult> Delete(Guid languageId) + public async Task<IActionResult> Delete(Guid id) { - bool result = await this._languageService.DeleteLanguage(languageId); + bool result = await this._languageService.DeleteLanguage(id); if (!result) return new BadRequestObjectResult("Could not delete Language"); diff --git a/src/DevHive.Web/Controllers/PostController.cs b/src/DevHive.Web/Controllers/PostController.cs index 15adb1b..2a08605 100644 --- a/src/DevHive.Web/Controllers/PostController.cs +++ b/src/DevHive.Web/Controllers/PostController.cs @@ -32,12 +32,11 @@ namespace DevHive.Web.Controllers CreatePostServiceModel postServiceModel = this._postMapper.Map<CreatePostServiceModel>(createPostModel); - bool result = await this._postService.CreatePost(postServiceModel); + Guid id = await this._postService.CreatePost(postServiceModel); - if (!result) - return new BadRequestObjectResult("Could not create post!"); - - return new OkResult(); + return id == Guid.Empty ? + new BadRequestObjectResult("Could not create post") : + new OkObjectResult(new { Id = id }); } [HttpPost] @@ -46,12 +45,11 @@ namespace DevHive.Web.Controllers { CreateCommentServiceModel createCommentServiceModel = this._postMapper.Map<CreateCommentServiceModel>(commentWebModel); - bool result = await this._postService.AddComment(createCommentServiceModel); + Guid id = await this._postService.AddComment(createCommentServiceModel); - if (!result) - return new BadRequestObjectResult("Could not create the Comment"); - - return new OkResult(); + return id == Guid.Empty ? + new BadRequestObjectResult("Could not create language") : + new OkObjectResult(new { Id = id }); } //Read diff --git a/src/DevHive.Web/Controllers/RoleController.cs b/src/DevHive.Web/Controllers/RoleController.cs index 8ea2711..227b877 100644 --- a/src/DevHive.Web/Controllers/RoleController.cs +++ b/src/DevHive.Web/Controllers/RoleController.cs @@ -3,8 +3,8 @@ using Microsoft.AspNetCore.Mvc; using DevHive.Web.Models.Identity.Role; using AutoMapper; using System; -using DevHive.Common.Models.Identity; using DevHive.Services.Interfaces; +using DevHive.Services.Models.Identity.Role; namespace DevHive.Web.Controllers { @@ -23,36 +23,36 @@ namespace DevHive.Web.Controllers } [HttpPost] - public async Task<IActionResult> Create([FromBody] CreateRoleModel createRoleModel) + public async Task<IActionResult> Create([FromBody] CreateRoleWebModel createRoleWebModel) { - RoleModel roleServiceModel = - this._roleMapper.Map<RoleModel>(createRoleModel); + RoleServiceModel roleServiceModel = + this._roleMapper.Map<RoleServiceModel>(createRoleWebModel); - bool result = await this._roleService.CreateRole(roleServiceModel); + Guid id = await this._roleService.CreateRole(roleServiceModel); - if (!result) - return new BadRequestObjectResult("Could not create role!"); + return id == Guid.Empty ? + new BadRequestObjectResult($"Could not create role {createRoleWebModel.Name}") : + new OkObjectResult(new { Id = id }); - return new OkResult(); } [HttpGet] public async Task<IActionResult> GetById(Guid id) { - RoleModel roleServiceModel = await this._roleService.GetRoleById(id); - RoleModel roleWebModel = this._roleMapper.Map<RoleModel>(roleServiceModel); + RoleServiceModel roleServiceModel = await this._roleService.GetRoleById(id); + RoleWebModel roleWebModel = this._roleMapper.Map<RoleWebModel>(roleServiceModel); return new OkObjectResult(roleWebModel); } [HttpPut] - public async Task<IActionResult> Update(Guid id, [FromBody] UpdateRoleModel updateRoleModel) + public async Task<IActionResult> Update(Guid id, [FromBody] UpdateRoleWebModel updateRoleWebModel) { - RoleModel roleServiceModel = - this._roleMapper.Map<RoleModel>(updateRoleModel); - roleServiceModel.Id = id; + UpdateRoleServiceModel updateRoleServiceModel = + this._roleMapper.Map<UpdateRoleServiceModel>(updateRoleWebModel); + updateRoleServiceModel.Id = id; - bool result = await this._roleService.UpdateRole(roleServiceModel); + bool result = await this._roleService.UpdateRole(updateRoleServiceModel); if (!result) return new BadRequestObjectResult("Could not update role!"); diff --git a/src/DevHive.Web/Controllers/TechnologyController.cs b/src/DevHive.Web/Controllers/TechnologyController.cs index 3be3b8a..ba2ffdc 100644 --- a/src/DevHive.Web/Controllers/TechnologyController.cs +++ b/src/DevHive.Web/Controllers/TechnologyController.cs @@ -22,33 +22,33 @@ namespace DevHive.Web.Controllers } [HttpPost] - public async Task<IActionResult> Create([FromBody] CreateTechnologyWebModel technologyWebModel) + public async Task<IActionResult> Create([FromBody] CreateTechnologyWebModel createTechnologyWebModel) { - CreateTechnologyServiceModel technologyServiceModel = this._technologyMapper.Map<CreateTechnologyServiceModel>(technologyWebModel); + CreateTechnologyServiceModel technologyServiceModel = this._technologyMapper.Map<CreateTechnologyServiceModel>(createTechnologyWebModel); - bool result = await this._technologyService.Create(technologyServiceModel); + Guid id = await this._technologyService.Create(technologyServiceModel); - if (!result) - return new BadRequestObjectResult("Could not create the Technology"); - - return new OkResult(); + return id == Guid.Empty ? + new BadRequestObjectResult($"Could not create technology {createTechnologyWebModel.Name}") : + new OkObjectResult(new { Id = id }); } [HttpGet] - public async Task<IActionResult> GetById(Guid technologyId) + public async Task<IActionResult> GetById(Guid id) { - CreateTechnologyServiceModel createTechnologyServiceModel = await this._technologyService.GetTechnologyById(technologyId); + CreateTechnologyServiceModel createTechnologyServiceModel = await this._technologyService.GetTechnologyById(id); CreateTechnologyWebModel createTechnologyWebModel = this._technologyMapper.Map<CreateTechnologyWebModel>(createTechnologyServiceModel); return new OkObjectResult(createTechnologyWebModel); } [HttpPut] - public async Task<IActionResult> Update(Guid technologyId, [FromBody] UpdateTechnologyWebModel updateModel) + public async Task<IActionResult> Update(Guid id, [FromBody] UpdateTechnologyWebModel updateModel) { - UpdateTechnologyServiceModel updateTechnologyWebModel = this._technologyMapper.Map<UpdateTechnologyServiceModel>(updateModel); + UpdateTechnologyServiceModel updateTechnologyServiceModel = this._technologyMapper.Map<UpdateTechnologyServiceModel>(updateModel); + updateTechnologyServiceModel.Id = id; - bool result = await this._technologyService.UpdateTechnology(technologyId, updateTechnologyWebModel); + bool result = await this._technologyService.UpdateTechnology(updateTechnologyServiceModel); if (!result) return new BadRequestObjectResult("Could not update Technology"); @@ -57,9 +57,9 @@ namespace DevHive.Web.Controllers } [HttpDelete] - public async Task<IActionResult> Delete(Guid technologyId) + public async Task<IActionResult> Delete(Guid id) { - bool result = await this._technologyService.DeleteTechnology(technologyId); + bool result = await this._technologyService.DeleteTechnology(id); if (!result) return new BadRequestObjectResult("Could not delete Technology"); diff --git a/src/DevHive.Web/Controllers/UserController.cs b/src/DevHive.Web/Controllers/UserController.cs index b33c3b9..fbbbbff 100644 --- a/src/DevHive.Web/Controllers/UserController.cs +++ b/src/DevHive.Web/Controllers/UserController.cs @@ -6,12 +6,10 @@ using DevHive.Web.Models.Identity.User; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using DevHive.Common.Models.Identity; -using DevHive.Common.Models.Misc; -using DevHive.Web.Models.Language; -using DevHive.Services.Models.Language; -using DevHive.Web.Models.Technology; -using DevHive.Services.Models.Technology; using DevHive.Services.Interfaces; +using Microsoft.AspNetCore.JsonPatch; +using DevHive.Common.Models.Misc; +using System.Collections.Generic; namespace DevHive.Web.Controllers { @@ -57,40 +55,6 @@ namespace DevHive.Web.Controllers } #endregion - #region Create - - [HttpPost] - [Route("AddAFriend")] - public async Task<IActionResult> AddAFriend(Guid userId, [FromBody] IdModel friendIdModel) - { - return await this._userService.AddFriend(userId, friendIdModel.Id) ? - new OkResult() : - new BadRequestResult(); - } - - [HttpPost] - [Route("AddLanguageToUser")] - public async Task<IActionResult> AddLanguageToUser(Guid userId, [FromBody] LanguageWebModel languageWebModel) - { - LanguageServiceModel languageServiceModel = this._userMapper.Map<LanguageServiceModel>(languageWebModel); - - return await this._userService.AddLanguageToUser(userId, languageServiceModel) ? - new OkResult() : - new BadRequestResult(); - } - - [HttpPost] - [Route("AddTechnologyToUser")] - public async Task<IActionResult> AddTechnologyToUser(Guid userId, [FromBody] TechnologyWebModel technologyWebModel) - { - TechnologyServiceModel technologyServiceModel = this._userMapper.Map<TechnologyServiceModel>(technologyWebModel); - - return await this._userService.AddTechnologyToUser(userId, technologyServiceModel) ? - new OkResult() : - new BadRequestResult(); - } - #endregion - #region Read [HttpGet] @@ -106,10 +70,11 @@ namespace DevHive.Web.Controllers } [HttpGet] - [Route("GetAFriend")] - public async Task<IActionResult> GetAFriend(Guid friendId) + [Route("GetUser")] + [AllowAnonymous] + public async Task<IActionResult> GetUser(string username) { - UserServiceModel friendServiceModel = await this._userService.GetFriendById(friendId); + UserServiceModel friendServiceModel = await this._userService.GetUserByUsername(username); UserWebModel friend = this._userMapper.Map<UserWebModel>(friendServiceModel); return new OkObjectResult(friend); @@ -118,12 +83,12 @@ namespace DevHive.Web.Controllers #region Update [HttpPut] - public async Task<IActionResult> Update(Guid id, [FromBody] UpdateUserWebModel updateModel, [FromHeader] string authorization) + public async Task<IActionResult> Update(Guid id, [FromBody] UpdateUserWebModel updateUserWebModel, [FromHeader] string authorization) { if (!await this._userService.ValidJWT(id, authorization)) return new UnauthorizedResult(); - UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map<UpdateUserServiceModel>(updateModel); + UpdateUserServiceModel updateUserServiceModel = this._userMapper.Map<UpdateUserServiceModel>(updateUserWebModel); updateUserServiceModel.Id = id; UserServiceModel userServiceModel = await this._userService.UpdateUser(updateUserServiceModel); @@ -134,7 +99,6 @@ namespace DevHive.Web.Controllers #endregion #region Delete - [HttpDelete] public async Task<IActionResult> Delete(Guid id, [FromHeader] string authorization) { @@ -144,36 +108,6 @@ namespace DevHive.Web.Controllers await this._userService.DeleteUser(id); return new OkResult(); } - - [HttpDelete] - [Route("RemoveAFriend")] - public async Task<IActionResult> RemoveAFriend(Guid userId, Guid friendId) - { - await this._userService.RemoveFriend(userId, friendId); - return new OkResult(); - } - - [HttpDelete] - [Route("RemoveLanguageFromUser")] - public async Task<IActionResult> RemoveLanguageFromUser(Guid userId, [FromBody] LanguageWebModel languageWebModel) - { - LanguageServiceModel languageServiceModel = this._userMapper.Map<LanguageServiceModel>(languageWebModel); - - return await this._userService.RemoveLanguageFromUser(userId, languageServiceModel) ? - new OkResult() : - new BadRequestResult(); - } - - [HttpDelete] - [Route("RemoveTechnologyFromUser")] - public async Task<IActionResult> RemoveTechnologyFromUser(Guid userId, [FromBody] TechnologyWebModel technologyWebModel) - { - TechnologyServiceModel technologyServiceModel = this._userMapper.Map<TechnologyServiceModel>(technologyWebModel); - - return await this._userService.RemoveTechnologyFromUser(userId, technologyServiceModel) ? - new OkResult() : - new BadRequestResult(); - } #endregion } } diff --git a/src/DevHive.Web/Middleware/ExceptionMiddleware.cs b/src/DevHive.Web/Middleware/ExceptionMiddleware.cs new file mode 100644 index 0000000..cb6d4ca --- /dev/null +++ b/src/DevHive.Web/Middleware/ExceptionMiddleware.cs @@ -0,0 +1,50 @@ +using System; +using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; + +namespace DevHive.Web.Middleware +{ + public class ExceptionMiddleware + { + private readonly RequestDelegate _next; + // private readonly ILogger _logger; + + public ExceptionMiddleware(RequestDelegate next) + { + this._next = next; + // this._logger = logger; + } + // public ExceptionMiddleware(RequestDelegate next, ILogger logger) + // { + // this._logger = logger; + // this._next = next; + // } + + public async Task InvokeAsync(HttpContext httpContext) + { + try + { + await this._next(httpContext); + } + catch (Exception ex) + { + // this._logger.LogError($"Something went wrong: {ex}"); + await HandleExceptionAsync(httpContext, ex); + } + } + + private Task HandleExceptionAsync(HttpContext context, Exception exception) + { + context.Response.ContentType = "application/json"; + context.Response.StatusCode = (int)HttpStatusCode.BadRequest; + + return context.Response.WriteAsync(new + { + StatusCode = context.Response.StatusCode, + Message = exception.Message + }.ToString()); + } + } +} diff --git a/src/DevHive.Web/Models/Identity/Role/CreateRoleWebModel.cs b/src/DevHive.Web/Models/Identity/Role/CreateRoleWebModel.cs index becb3c9..859cdd9 100644 --- a/src/DevHive.Web/Models/Identity/Role/CreateRoleWebModel.cs +++ b/src/DevHive.Web/Models/Identity/Role/CreateRoleWebModel.cs @@ -1,7 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + namespace DevHive.Web.Models.Identity.Role { - public class CreateRoleModel + public class CreateRoleWebModel { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string Name { get; set; } } } diff --git a/src/DevHive.Web/Models/Identity/Role/RoleWebModel.cs b/src/DevHive.Web/Models/Identity/Role/RoleWebModel.cs index 9e97ffc..99b0f50 100644 --- a/src/DevHive.Web/Models/Identity/Role/RoleWebModel.cs +++ b/src/DevHive.Web/Models/Identity/Role/RoleWebModel.cs @@ -1,9 +1,14 @@ -using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Identity.Role { public class RoleWebModel { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string Name { get; set; } } } diff --git a/src/DevHive.Web/Models/Identity/Role/UpdateRoleWebModel.cs b/src/DevHive.Web/Models/Identity/Role/UpdateRoleWebModel.cs index 1eaad57..254affc 100644 --- a/src/DevHive.Web/Models/Identity/Role/UpdateRoleWebModel.cs +++ b/src/DevHive.Web/Models/Identity/Role/UpdateRoleWebModel.cs @@ -1,6 +1,13 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + namespace DevHive.Web.Models.Identity.Role { - public class UpdateRoleModel : CreateRoleModel + public class UpdateRoleWebModel : RoleWebModel { + [NotNull] + [Required] + public Guid Id { get; set; } } } diff --git a/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs b/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs index 2d99786..d7d8d29 100644 --- a/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/BaseUserWebModel.cs @@ -1,26 +1,31 @@ using System.ComponentModel.DataAnnotations; -using DevHive.Web.Models.Identity.Validation; +using System.Diagnostics.CodeAnalysis; +using DevHive.Web.Attributes; namespace DevHive.Web.Models.Identity.User { public class BaseUserWebModel { + [NotNull] [Required] [MinLength(3)] [MaxLength(50)] [OnlyAlphanumerics(ErrorMessage = "Username can only contain letters and digits!")] public string UserName { get; set; } + [NotNull] [Required] [EmailAddress] public string Email { get; set; } + [NotNull] [Required] [MinLength(3)] [MaxLength(30)] [OnlyLetters(ErrorMessage = "First name can only contain letters!")] public string FirstName { get; set; } + [NotNull] [Required] [MinLength(3)] [MaxLength(30)] diff --git a/src/DevHive.Web/Models/Identity/User/FriendWebModel.cs b/src/DevHive.Web/Models/Identity/User/FriendWebModel.cs new file mode 100644 index 0000000..d59bff5 --- /dev/null +++ b/src/DevHive.Web/Models/Identity/User/FriendWebModel.cs @@ -0,0 +1,16 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; +using DevHive.Web.Attributes; + +namespace DevHive.Web.Models.Identity.User +{ + public class FriendWebModel + { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + [OnlyAlphanumerics(ErrorMessage = "Username can only contain letters and digits!")] + public string UserName { get; set; } + } +} diff --git a/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs b/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs index 87c7416..0395274 100644 --- a/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/LoginWebModel.cs @@ -1,8 +1,21 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; +using DevHive.Web.Attributes; + namespace DevHive.Web.Models.Identity.User { public class LoginWebModel { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + [OnlyAlphanumerics(ErrorMessage = "Username can only contain letters and digits!")] public string UserName { get; set; } + + [NotNull] + [Required] + [GoodPassword] public string Password { get; set; } } } diff --git a/src/DevHive.Web/Models/Identity/User/RegisterWebModel.cs b/src/DevHive.Web/Models/Identity/User/RegisterWebModel.cs index 04fd6bd..0fc7ec6 100644 --- a/src/DevHive.Web/Models/Identity/User/RegisterWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/RegisterWebModel.cs @@ -1,10 +1,12 @@ using System.ComponentModel.DataAnnotations; -using DevHive.Web.Models.Identity.Validation; +using System.Diagnostics.CodeAnalysis; +using DevHive.Web.Attributes; namespace DevHive.Web.Models.Identity.User { public class RegisterWebModel : BaseUserWebModel { + [NotNull] [Required] [GoodPassword] public string Password { get; set; } diff --git a/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs b/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs index 9e41eb6..30c66fb 100644 --- a/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UpdateUserWebModel.cs @@ -1,12 +1,34 @@ +using System.Collections.Generic; using System.ComponentModel.DataAnnotations; -using DevHive.Web.Models.Identity.Validation; +using System.Diagnostics.CodeAnalysis; +using DevHive.Web.Attributes; +using DevHive.Web.Models.Identity.Role; +using DevHive.Web.Models.Language; +using DevHive.Web.Models.Technology; namespace DevHive.Web.Models.Identity.User { public class UpdateUserWebModel : BaseUserWebModel { + [NotNull] [Required] [GoodPassword] public string Password { get; set; } + + [NotNull] + [Required] + public HashSet<FriendWebModel> Friends { get; set; } + + [NotNull] + [Required] + public HashSet<UpdateRoleWebModel> Roles { get; set; } + + [NotNull] + [Required] + public HashSet<UpdateLanguageWebModel> Languages { get; set; } + + [NotNull] + [Required] + public HashSet<UpdateTechnologyWebModel> Technologies { get; set; } } } diff --git a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs index 8f7995c..5b80ba3 100644 --- a/src/DevHive.Web/Models/Identity/User/UserWebModel.cs +++ b/src/DevHive.Web/Models/Identity/User/UserWebModel.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; -using DevHive.Common.Models.Identity; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; using DevHive.Web.Models.Identity.Role; using DevHive.Web.Models.Language; using DevHive.Web.Models.Technology; @@ -8,9 +9,20 @@ namespace DevHive.Web.Models.Identity.User { public class UserWebModel : BaseUserWebModel { - public IList<RoleWebModel> Roles { get; set; } = new List<RoleWebModel>(); - public IList<UserWebModel> Friends { get; set; } = new List<UserWebModel>(); - public IList<LanguageWebModel> Languages { get; set; } = new List<LanguageWebModel>(); - public IList<TechnologyWebModel> Technologies { get; set; } = new List<TechnologyWebModel>(); + [NotNull] + [Required] + public HashSet<RoleWebModel> Roles { get; set; } = new HashSet<RoleWebModel>(); + + [NotNull] + [Required] + public HashSet<FriendWebModel> Friends { get; set; } = new HashSet<FriendWebModel>(); + + [NotNull] + [Required] + public HashSet<LanguageWebModel> Languages { get; set; } = new HashSet<LanguageWebModel>(); + + [NotNull] + [Required] + public HashSet<TechnologyWebModel> Technologies { get; set; } = new HashSet<TechnologyWebModel>(); } } diff --git a/src/DevHive.Web/Models/Language/CreateLanguageWebModel.cs b/src/DevHive.Web/Models/Language/CreateLanguageWebModel.cs index d261500..a739e7f 100644 --- a/src/DevHive.Web/Models/Language/CreateLanguageWebModel.cs +++ b/src/DevHive.Web/Models/Language/CreateLanguageWebModel.cs @@ -1,9 +1,14 @@ -using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Language { public class CreateLanguageWebModel { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string Name { get; set; } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Web/Models/Language/LanguageWebModel.cs b/src/DevHive.Web/Models/Language/LanguageWebModel.cs index 455b559..7515e70 100644 --- a/src/DevHive.Web/Models/Language/LanguageWebModel.cs +++ b/src/DevHive.Web/Models/Language/LanguageWebModel.cs @@ -1,9 +1,13 @@ using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Language { public class LanguageWebModel { + [NotNull] + [Required] public Guid Id { get; set; } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Web/Models/Language/ReadLanguageWebModel.cs b/src/DevHive.Web/Models/Language/ReadLanguageWebModel.cs new file mode 100644 index 0000000..ab4a089 --- /dev/null +++ b/src/DevHive.Web/Models/Language/ReadLanguageWebModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + +namespace DevHive.Web.Models.Language +{ + public class ReadLanguageWebModel + { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + public string Name { get; set; } + } +} diff --git a/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs b/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs index ed3b37c..128d534 100644 --- a/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs +++ b/src/DevHive.Web/Models/Language/UpdateLanguageWebModel.cs @@ -1,9 +1,14 @@ -using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Language { - public class UpdateLanguageWebModel : LanguageWebModel + public class UpdateLanguageWebModel { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string Name { get; set; } } } diff --git a/src/DevHive.Web/Models/Post/Comment/CommentWebModel.cs b/src/DevHive.Web/Models/Post/Comment/CommentWebModel.cs index 3cdc7c4..590851d 100644 --- a/src/DevHive.Web/Models/Post/Comment/CommentWebModel.cs +++ b/src/DevHive.Web/Models/Post/Comment/CommentWebModel.cs @@ -1,11 +1,25 @@ using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Post.Comment { public class CommentWebModel { + [NotNull] + [Required] public Guid IssuerId { get; set; } + + [NotNull] + [Required] + public Guid PostId { get; set; } + + [NotNull] + [Required] public string Message { get; set; } + + [NotNull] + [Required] public DateTime TimeCreated { get; set; } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Web/Models/Post/Post/BasePostWebModel.cs b/src/DevHive.Web/Models/Post/Post/BasePostWebModel.cs index caa9925..35ddd34 100644 --- a/src/DevHive.Web/Models/Post/Post/BasePostWebModel.cs +++ b/src/DevHive.Web/Models/Post/Post/BasePostWebModel.cs @@ -1,10 +1,17 @@ using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Post.Post { public class BasePostWebModel { + [NotNull] + [Required] public Guid IssuerId { get; set; } + + [NotNull] + [Required] public string Message { get; set; } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Web/Models/Post/Post/CreatePostWebModel.cs b/src/DevHive.Web/Models/Post/Post/CreatePostWebModel.cs index 7558b2c..389ff9e 100644 --- a/src/DevHive.Web/Models/Post/Post/CreatePostWebModel.cs +++ b/src/DevHive.Web/Models/Post/Post/CreatePostWebModel.cs @@ -2,7 +2,5 @@ using System; namespace DevHive.Web.Models.Post.Post { - public class CreatePostWebModel : BasePostWebModel - { - } -}
\ No newline at end of file + public class CreatePostWebModel : BasePostWebModel { } +} diff --git a/src/DevHive.Web/Models/Post/Post/PostWebModel.cs b/src/DevHive.Web/Models/Post/Post/PostWebModel.cs index fa18c3a..fe35cee 100644 --- a/src/DevHive.Web/Models/Post/Post/PostWebModel.cs +++ b/src/DevHive.Web/Models/Post/Post/PostWebModel.cs @@ -1,3 +1,6 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; +using DevHive.Web.Attributes; using DevHive.Web.Models.Post.Comment; namespace DevHive.Web.Models.Post.Post @@ -6,16 +9,31 @@ namespace DevHive.Web.Models.Post.Post { //public string Picture { get; set; } + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string IssuerFirstName { get; set; } + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string IssuerLastName { get; set; } + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + [OnlyAlphanumerics(ErrorMessage = "Username can only contain letters and digits!")] public string IssuerUsername { get; set; } + [NotNull] + [Required] public string Message { get; set; } //public Files[] Files { get; set; } public CommentWebModel[] Comments { get; set; } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs index 13029ee..ec9ec15 100644 --- a/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs +++ b/src/DevHive.Web/Models/Technology/CreateTechnologyWebModel.cs @@ -1,7 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + namespace DevHive.Web.Models.Technology { public class CreateTechnologyWebModel { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string Name { get; set; } } } diff --git a/src/DevHive.Web/Models/Technology/ReadTechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/ReadTechnologyWebModel.cs new file mode 100644 index 0000000..edaaaef --- /dev/null +++ b/src/DevHive.Web/Models/Technology/ReadTechnologyWebModel.cs @@ -0,0 +1,14 @@ +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; + +namespace DevHive.Web.Models.Technology +{ + public class ReadTechnologyWebModel + { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] + public string Name { get; set; } + } +} diff --git a/src/DevHive.Web/Models/Technology/TechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/TechnologyWebModel.cs index 05f7af8..6e8273b 100644 --- a/src/DevHive.Web/Models/Technology/TechnologyWebModel.cs +++ b/src/DevHive.Web/Models/Technology/TechnologyWebModel.cs @@ -1,9 +1,13 @@ using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Technology { public class TechnologyWebModel { + [NotNull] + [Required] public Guid Id { get; set; } } -}
\ No newline at end of file +} diff --git a/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs b/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs index 8bf48bf..3e9fe2a 100644 --- a/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs +++ b/src/DevHive.Web/Models/Technology/UpdateTechnologyWebModel.cs @@ -1,9 +1,15 @@ using System; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics.CodeAnalysis; namespace DevHive.Web.Models.Technology { - public class UpdateTechnologyWebModel : TechnologyWebModel + public class UpdateTechnologyWebModel { + [NotNull] + [Required] + [MinLength(3)] + [MaxLength(50)] public string Name { get; set; } } } diff --git a/src/DevHive.Web/Properties/launchSettings.json b/src/DevHive.Web/Properties/launchSettings.json index 44d86fc..5deaadb 100644 --- a/src/DevHive.Web/Properties/launchSettings.json +++ b/src/DevHive.Web/Properties/launchSettings.json @@ -1,31 +1,28 @@ -{
- "$schema": "http://json.schemastore.org/launchsettings.json",
- "iisSettings": {
- "windowsAuthentication": false,
- "anonymousAuthentication": true,
- "iisExpress": {
- "applicationUrl": "http://localhost:1955",
- "sslPort": 44326
- }
- },
- "profiles": {
- "IIS Express": {
- "commandName": "IISExpress",
- "launchBrowser": true,
- "launchUrl": "swagger",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- },
- "DevHive.Web": {
- "commandName": "Project",
- "dotnetRunMessages": "true",
- "launchBrowser": true,
- "launchUrl": "swagger",
- "applicationUrl": "http://localhost:5000",
- "environmentVariables": {
- "ASPNETCORE_ENVIRONMENT": "Development"
- }
- }
- }
-}
+{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:1955", + "sslPort": 44326 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "DevHive.Web": { + "commandName": "Project", + "dotnetRunMessages": "true", + "launchBrowser": false, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/src/DevHive.Web/Startup.cs b/src/DevHive.Web/Startup.cs index 94aabe8..92d4359 100644 --- a/src/DevHive.Web/Startup.cs +++ b/src/DevHive.Web/Startup.cs @@ -33,6 +33,7 @@ namespace DevHive.Web services.JWTConfiguration(Configuration); services.AutoMapperConfiguration(); services.DependencyInjectionConfiguration(); + services.ExceptionHandlerMiddlewareConfiguration(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -46,14 +47,13 @@ namespace DevHive.Web if (env.IsDevelopment()) { - //app.UseDeveloperExceptionPage(); - app.UseExceptionHandler("/api/Error"); + app.UseDeveloperExceptionPage(); app.UseSwaggerConfiguration(); } else { - app.UseExceptionHandler("/api/Error"); app.UseHsts(); + app.UseExceptionHandlerMiddlewareConfiguration(); } app.UseDatabaseConfiguration(); diff --git a/src/DevHive.Web/appsettings.json b/src/DevHive.Web/appsettings.json index a460532..83932a7 100644 --- a/src/DevHive.Web/appsettings.json +++ b/src/DevHive.Web/appsettings.json @@ -1,15 +1,15 @@ -{
- "AppSettings": {
- "Secret": "gXfQlU6qpDleFWyimscjYcT3tgFsQg3yoFjcvSLxG56n1Vu2yptdIUq254wlJWjm"
- },
- "ConnectionStrings": {
- "DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=;"
- },
- "Logging" : {
- "LogLevel" : {
- "Default" : "Information",
- "Microsoft" : "Warning",
- "Microsoft.Hosting.Lifetime" : "Information"
- }
- }
-}
+{ + "AppSettings": { + "Secret": "gXfQlU6qpDleFWyimscjYcT3tgFsQg3yoFjcvSLxG56n1Vu2yptdIUq254wlJWjm" + }, + "ConnectionStrings": { + "DEV": "Server=localhost;Port=5432;Database=API;User Id=postgres;Password=;" + }, + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/src/DevHive.code-workspace b/src/DevHive.code-workspace index 4f764c2..10c4276 100644 --- a/src/DevHive.code-workspace +++ b/src/DevHive.code-workspace @@ -46,7 +46,7 @@ "launch": { "configurations": [ { - "name": ".NET Core Launch (web)", + "name": "Launch API", "type": "coreclr", "request": "launch", "preLaunchTask": "workspace-build", @@ -54,16 +54,20 @@ "args": [], "cwd": "${workspaceFolder:DevHive.Web}", "stopAtEntry": false, - "serverReadyAction": { - "action": "openExternally", - "pattern": "\\bNow listening on:\\s+(https?://\\S+)" - }, "env": { "ASPNETCORE_ENVIRONMENT": "Development" }, - "launchBrowser": { - "enabled": true - } + }, + { + "name": "Launch Data Tests", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "workspace-build", + "program": "${workspaceFolder:DevHive.Tests}/DevHive.Data.Tests/bin/Debug/net5.0/DevHive.Data.Tests.dll", + "args": [], + "cwd": "${workspaceFolder:DevHive.Tests}/DevHive.Data.Tests", + "console": "internalConsole", + "stopAtEntry": false }, ], "compounds": [] |
