From 9d2ec16fbe67bba8761bcdd8045830718902e6e0 Mon Sep 17 00:00:00 2001 From: hugcubi <hugo.cubino@estudiantes.uva.es> Date: Thu, 26 Dec 2024 21:15:57 +0100 Subject: [PATCH] =?UTF-8?q?Correcci=C3=B3n=20de=20ciertos=20fallos=20en=20?= =?UTF-8?q?angular?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .trunk/trunk.yaml | 6 +- .../RestClient/src/app/app.component.spec.ts | 30 ---- angular/RestClient/src/app/app.routes.ts | 19 +-- .../src/app/core/guards/rol.guard.spec.ts | 17 --- .../src/app/core/guards/rol.guard.ts | 12 +- .../interceptors/auth.interceptor.spec.ts | 17 --- .../src/app/core/models/Booking.interface.ts | 4 +- .../src/app/core/models/Route.interface.ts | 10 +- .../api/auth/auth-client.service.spec.ts | 18 --- .../bookings/booking-client.service.spec.ts | 16 -- .../api/bookings/booking-client.service.ts | 6 +- .../api/hotels/hotel-client.service.spec.ts | 16 -- .../api/users/user-client.service.spec.ts | 16 -- .../services/session/session.service.spec.ts | 16 -- .../core/services/session/session.service.ts | 5 +- .../storage/local-storage.service.spec.ts | 16 -- .../src/app/features/admin/admin.module.ts | 12 ++ .../src/app/features/auth/auth.routes.ts | 14 +- .../RestClient/src/app/features/auth/index.ts | 2 - .../features/auth/login/login.component.css | 21 --- .../features/auth/login/login.component.html | 73 --------- .../auth/login/login.component.spec.ts | 23 --- .../features/auth/login/login.component.ts | 64 -------- .../auth/register/register.component.css | 21 --- .../auth/register/register.component.html | 85 ----------- .../auth/register/register.component.spec.ts | 23 --- .../auth/register/register.component.ts | 79 ---------- .../booking-list.component.css | 0 .../booking-list.component.html | 0 .../booking-list.component.ts | 0 .../booking-list.component.spec.ts | 23 --- .../bookings/booking/booking.component.html | 18 +-- .../booking/booking.component.spec.ts | 56 ------- .../bookings/booking/booking.component.ts | 39 +++-- .../src/app/features/bookings/index.ts | 2 +- .../user-booking-list.component.html | 4 +- .../user-booking-list.component.spec.ts | 23 --- .../user-booking-list.component.ts | 3 +- .../hotel-list/hotel-list.component.spec.ts | 23 --- .../hotels/hotel-list/hotel-list.component.ts | 34 +++-- .../hotel-register.component.spec.ts | 23 --- .../src/app/features/hotels/hotels.routes.ts | 33 ++-- .../src/app/features/users/admin.routes.ts | 29 +++- .../main-page/main-page.component.spec.ts | 22 --- .../features/users/types/UserFormData.d.ts | 15 ++ .../user-form/user-form.component.spec.ts | 95 ------------ .../users/user-form/user-form.component.ts | 144 ++++++++---------- .../src/app/features/users/users.routes.ts | 22 ++- .../unauthorized.component.spec.ts | 23 --- .../navigation/navigation.component.spec.ts | 23 --- angular/RestClient/src/app/utils/utils.ts | 34 +++-- .../src/environments/environment.prod.ts | 2 +- .../src/environments/environment.ts | 8 +- .../RoomBookingApplicationTests.java | 13 ++ .../RoomBookingApplicationTests.java | 13 ++ .../RoomBookingApplicationTests.java | 13 ++ .../RoomBookingApplicationTests.java | 13 ++ 57 files changed, 310 insertions(+), 1081 deletions(-) delete mode 100644 angular/RestClient/src/app/app.component.spec.ts delete mode 100644 angular/RestClient/src/app/core/guards/rol.guard.spec.ts delete mode 100644 angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts delete mode 100644 angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts delete mode 100644 angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts delete mode 100644 angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts delete mode 100644 angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts delete mode 100644 angular/RestClient/src/app/core/services/session/session.service.spec.ts delete mode 100644 angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts create mode 100644 angular/RestClient/src/app/features/admin/admin.module.ts delete mode 100644 angular/RestClient/src/app/features/auth/login/login.component.css delete mode 100644 angular/RestClient/src/app/features/auth/login/login.component.html delete mode 100644 angular/RestClient/src/app/features/auth/login/login.component.spec.ts delete mode 100644 angular/RestClient/src/app/features/auth/login/login.component.ts delete mode 100644 angular/RestClient/src/app/features/auth/register/register.component.css delete mode 100644 angular/RestClient/src/app/features/auth/register/register.component.html delete mode 100644 angular/RestClient/src/app/features/auth/register/register.component.spec.ts delete mode 100644 angular/RestClient/src/app/features/auth/register/register.component.ts rename angular/RestClient/src/app/features/bookings/{booking-list => [DEL] booking-list}/booking-list.component.css (100%) rename angular/RestClient/src/app/features/bookings/{booking-list => [DEL] booking-list}/booking-list.component.html (100%) rename angular/RestClient/src/app/features/bookings/{booking-list => [DEL] booking-list}/booking-list.component.ts (100%) delete mode 100644 angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts delete mode 100644 angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts delete mode 100644 angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts delete mode 100644 angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts delete mode 100644 angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts delete mode 100644 angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts create mode 100644 angular/RestClient/src/app/features/users/types/UserFormData.d.ts delete mode 100644 angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts delete mode 100644 angular/RestClient/src/app/page/unauthorized/unauthorized.component.spec.ts delete mode 100644 angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts create mode 100644 java/services/auth/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java create mode 100644 java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java create mode 100644 java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java create mode 100644 java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml index f578845..356e1de 100644 --- a/.trunk/trunk.yaml +++ b/.trunk/trunk.yaml @@ -20,16 +20,16 @@ lint: disabled: - git-diff-check enabled: - - checkov@3.2.341 + - checkov@3.2.344 - dotenv-linter@3.3.0 - hadolint@2.12.1-beta - markdownlint@0.43.0 - - osv-scanner@1.9.1 + - osv-scanner@1.9.2 - prettier@3.4.2 - shellcheck@0.10.0 - shfmt@3.6.0 - svgo@3.3.2 - - trufflehog@3.86.1 + - trufflehog@3.88.0 - yamllint@1.35.1 actions: disabled: diff --git a/angular/RestClient/src/app/app.component.spec.ts b/angular/RestClient/src/app/app.component.spec.ts deleted file mode 100644 index 360bd69..0000000 --- a/angular/RestClient/src/app/app.component.spec.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { AppComponent } from './app.component'; -import { ReactiveFormsModule } from '@angular/forms'; - -describe('AppComponent', () => { - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [AppComponent, ReactiveFormsModule], - }).compileComponents(); - }); - - it('should create the app', () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app).toBeTruthy(); - }); - - it(`should have the 'RestClient' title`, () => { - const fixture = TestBed.createComponent(AppComponent); - const app = fixture.componentInstance; - expect(app.title).toEqual('RestClient'); - }); - - it('should render title', () => { - const fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - const compiled = fixture.nativeElement as HTMLElement; - expect(compiled.querySelector('h1')?.textContent).toContain('Hello, RestClient'); - }); -}); diff --git a/angular/RestClient/src/app/app.routes.ts b/angular/RestClient/src/app/app.routes.ts index 2853c5e..0f07bf5 100644 --- a/angular/RestClient/src/app/app.routes.ts +++ b/angular/RestClient/src/app/app.routes.ts @@ -1,13 +1,6 @@ -import { HotelListComponent } from './features/hotels/hotel-list/hotel-list.component'; -import { BookingComponent } from './features/bookings/booking/booking.component'; -import { HotelRegisterComponent } from './features/hotels/hotel-register/hotel-register.component'; -import { MainPageComponent } from './features/users/main-page/main-page.component'; -import { UserBookingListComponent } from './features/bookings/user-booking-list/user-booking-list.component'; -import { UserFormComponent } from './features/users/user-form/user-form.component'; import { UnauthorizedComponent } from './page/unauthorized/unauthorized.component'; -import { AppRoute, UserRolesArray } from './core/models'; +import { AppRoute } from './core/models'; import { rolGuard, rolGuardChild } from '@core/guards'; - export const routes: AppRoute[] = [ // Auth { @@ -40,9 +33,9 @@ export const routes: AppRoute[] = [ path: 'unauthorized', component: UnauthorizedComponent, }, - { - path: '**', - redirectTo: '/login', - pathMatch: 'full', - }, + // { + // path: '**', + // redirectTo: '/login', + // pathMatch: 'full', + // }, ]; diff --git a/angular/RestClient/src/app/core/guards/rol.guard.spec.ts b/angular/RestClient/src/app/core/guards/rol.guard.spec.ts deleted file mode 100644 index 0086470..0000000 --- a/angular/RestClient/src/app/core/guards/rol.guard.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { CanActivateFn } from '@angular/router'; - -import { rolGuard } from './rol.guard'; - -describe('rolGuard', () => { - const executeGuard: CanActivateFn = (...guardParameters) => - TestBed.runInInjectionContext(() => rolGuard(...guardParameters)); - - beforeEach(() => { - TestBed.configureTestingModule({}); - }); - - it('should be created', () => { - expect(executeGuard).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/guards/rol.guard.ts b/angular/RestClient/src/app/core/guards/rol.guard.ts index 39aca9b..b6d67d2 100644 --- a/angular/RestClient/src/app/core/guards/rol.guard.ts +++ b/angular/RestClient/src/app/core/guards/rol.guard.ts @@ -36,21 +36,27 @@ function verifyRol(expectedRole: UserRol) { router.navigate(['/login']); return false; } + + if (!expectedRole) { + console.log('any rol required'); + return true; + } + return sessionService.getSession().pipe( map((session: Session | null) => { if (!session) return false; if ( Array.isArray(expectedRole) && - (expectedRole as UserRol[]).includes(session.rol) + !(expectedRole as UserRol[]).includes(session.rol) ) { - console.log('Rol in Rol arry'); + console.log('Rol in Rol array'); return true; } else if (session.rol === expectedRole) { console.log('Rol valido'); return true; } - console.log('Unautorizado'); + console.log('Unauthorized'); // Redirige si el usuario no tiene el rol necesario router.navigate(['/unauthorized']); diff --git a/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts b/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts deleted file mode 100644 index 50f38c8..0000000 --- a/angular/RestClient/src/app/core/interceptors/auth.interceptor.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TestBed } from '@angular/core/testing'; -import { HttpInterceptorFn } from '@angular/common/http'; - -import { authInterceptor } from './auth.interceptor'; - -describe('authInterceptor', () => { - const interceptor: HttpInterceptorFn = (req, next) => - TestBed.runInInjectionContext(() => authInterceptor(req, next)); - - beforeEach(() => { - TestBed.configureTestingModule({}); - }); - - it('should be created', () => { - expect(interceptor).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/models/Booking.interface.ts b/angular/RestClient/src/app/core/models/Booking.interface.ts index e18c746..e4b65d2 100644 --- a/angular/RestClient/src/app/core/models/Booking.interface.ts +++ b/angular/RestClient/src/app/core/models/Booking.interface.ts @@ -3,8 +3,8 @@ import { User } from './User.interface'; export interface Booking { id: number; - startDate: Date; - endDate: Date; + start: Date; + end: Date; userId: User; roomId: Room; } diff --git a/angular/RestClient/src/app/core/models/Route.interface.ts b/angular/RestClient/src/app/core/models/Route.interface.ts index 4653cda..ad601f7 100644 --- a/angular/RestClient/src/app/core/models/Route.interface.ts +++ b/angular/RestClient/src/app/core/models/Route.interface.ts @@ -1,10 +1,10 @@ import { Route } from '@angular/router'; import { UserRol } from './User.interface'; -interface RouteData { - expectedRole: UserRol | UserRol[]; -} +type RolledRoute = { + expectedRole?: UserRol | UserRol[]; +}; -export type AppRoute = Omit<Route, 'data'> & { - data?: RouteData; +export type AppRoute<T = {}> = Omit<Route, 'data'> & { + data?: RolledRoute & T; }; diff --git a/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts deleted file mode 100644 index 74e8f48..0000000 --- a/angular/RestClient/src/app/core/services/api/auth/auth-client.service.spec.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { AuthClientService } from './auth-client.service'; -import { Session } from '@core/models'; - -describe('AuthClientService', () => { - let service: AuthClientService; - let s: Session; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(AuthClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts deleted file mode 100644 index 7155f3c..0000000 --- a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { BookingClientService } from './booking-client.service'; - -describe('BookingClientService', () => { - let service: BookingClientService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(BookingClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts index e504676..ec72370 100644 --- a/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts +++ b/angular/RestClient/src/app/core/services/api/bookings/booking-client.service.ts @@ -14,9 +14,9 @@ export class BookingClientService { // Método para crear una nueva reserva createBooking(bookingRequest: Booking): Observable<Booking> { - const { startDate, endDate } = bookingRequest; - const end = endDate.toISOString(); - console.log({ bookingRequest, end }); + const { start, end } = bookingRequest; + const endDate = end.toISOString(); + console.log({ bookingRequest, end: endDate }); return this.http.post<Booking>(this.URI, bookingRequest); } diff --git a/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts deleted file mode 100644 index 5d32879..0000000 --- a/angular/RestClient/src/app/core/services/api/hotels/hotel-client.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { HotelClientService } from './hotel-client.service'; - -describe('HotelClientService', () => { - let service: HotelClientService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(HotelClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts b/angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts deleted file mode 100644 index 3af6ef2..0000000 --- a/angular/RestClient/src/app/core/services/api/users/user-client.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { UserClientService } from './user-client.service'; - -describe('UserClientService', () => { - let service: UserClientService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(UserClientService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/session/session.service.spec.ts b/angular/RestClient/src/app/core/services/session/session.service.spec.ts deleted file mode 100644 index 4238e14..0000000 --- a/angular/RestClient/src/app/core/services/session/session.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { SessionService } from './session.service'; - -describe('SessionService', () => { - let service: SessionService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(SessionService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/core/services/session/session.service.ts b/angular/RestClient/src/app/core/services/session/session.service.ts index 7432502..10e7ae8 100644 --- a/angular/RestClient/src/app/core/services/session/session.service.ts +++ b/angular/RestClient/src/app/core/services/session/session.service.ts @@ -8,7 +8,7 @@ import { AuthClientService } from '../api/auth/auth-client.service'; import { Router } from '@angular/router'; interface JWTDecoded { - userId: number; + id: number; rol: UserRol; name: string; email: string; @@ -41,7 +41,8 @@ export class SessionService { private setSession(resp: any) { const decoded = jwtDecode<JWTDecoded>(resp.token); - const user: Session = { ...decoded, id: decoded.userId }; + const user: Session = { ...decoded }; + console.log({ user, decoded, resp }); this.session$.next(user); this.storage.save(this.tokenKey, { ...resp, session: user }); const mainPage = this.getMainPage(user.rol as UserRol); diff --git a/angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts b/angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts deleted file mode 100644 index ba1dbd4..0000000 --- a/angular/RestClient/src/app/core/services/storage/local-storage.service.spec.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { TestBed } from '@angular/core/testing'; - -import { LocalStorageService } from './local-storage.service'; - -describe('LocalStorageService', () => { - let service: LocalStorageService; - - beforeEach(() => { - TestBed.configureTestingModule({}); - service = TestBed.inject(LocalStorageService); - }); - - it('should be created', () => { - expect(service).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/admin/admin.module.ts b/angular/RestClient/src/app/features/admin/admin.module.ts new file mode 100644 index 0000000..f1b4844 --- /dev/null +++ b/angular/RestClient/src/app/features/admin/admin.module.ts @@ -0,0 +1,12 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; + + + +@NgModule({ + declarations: [], + imports: [ + CommonModule + ] +}) +export class AdminModule { } diff --git a/angular/RestClient/src/app/features/auth/auth.routes.ts b/angular/RestClient/src/app/features/auth/auth.routes.ts index 86d8183..25eea2c 100644 --- a/angular/RestClient/src/app/features/auth/auth.routes.ts +++ b/angular/RestClient/src/app/features/auth/auth.routes.ts @@ -1,13 +1,23 @@ -import { AppRoute } from '@core/models'; import { UserFormComponent } from 'app/features/users'; +import { UserFormRoute } from 'app/features/users/types/UserFormData'; -export const AUTH_ROUTES: AppRoute[] = [ +export const AUTH_ROUTES: UserFormRoute[] = [ { path: 'login', + data: { + mode: { + formMode: 'LOGIN', + }, + }, component: UserFormComponent, }, { path: 'register', + data: { + mode: { + formMode: 'REGISTER', + }, + }, component: UserFormComponent, }, ]; diff --git a/angular/RestClient/src/app/features/auth/index.ts b/angular/RestClient/src/app/features/auth/index.ts index bb519ed..358e0c5 100644 --- a/angular/RestClient/src/app/features/auth/index.ts +++ b/angular/RestClient/src/app/features/auth/index.ts @@ -1,3 +1 @@ export * from './auth.routes'; -export * from './login/login.component'; -export * from './register/register.component'; diff --git a/angular/RestClient/src/app/features/auth/login/login.component.css b/angular/RestClient/src/app/features/auth/login/login.component.css deleted file mode 100644 index 79b4834..0000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.css +++ /dev/null @@ -1,21 +0,0 @@ -.container { - max-width: 600px; - margin-top: 2rem; - padding: 20px; - border: 1px solid #ccc; - border-radius: 5px; - background-color: #f9f9f9; -} - -h2 { - text-align: center; - margin-bottom: 20px; -} - -.form-group { - margin-bottom: 15px; -} - -label { - font-weight: bold; -} diff --git a/angular/RestClient/src/app/features/auth/login/login.component.html b/angular/RestClient/src/app/features/auth/login/login.component.html deleted file mode 100644 index f6fcf96..0000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.html +++ /dev/null @@ -1,73 +0,0 @@ -<div class="container"> - <form [formGroup]="loginForm" (ngSubmit)="onSubmit()"> - <mat-card> - <mat-card-title class="flex text-center p-4"> - <strong class="text-5xl">Login</strong> - </mat-card-title> - <mat-card-content> - <div class="form-group"> - <label class="text-2xl" for="email">Email:</label> - <input - id="email" - type="email" - formControlName="email" - class="form-control" - /> - @if (loginForm.get('email')?.invalid && - loginForm.get('email')?.touched) { - <div> - <small class="text-red-500 font-bold" - >Email is required and must be valid.</small - > - </div> - } - </div> - - <div class="form-group"> - <label class="text-2xl" for="password">Password:</label> - <input - id="password" - type="password" - formControlName="password" - class="form-control" - /> - @if (loginForm.get('password')?.invalid && - loginForm.get('password')?.touched){ - - <div> - <small class="text-red-500 font-bold">Password is required.</small> - </div> - } - </div> - - <div class="form-group text-2xl"> - <label class="text-2xl" for="rol">Rol:</label> - <mat-form-field class="w-full" formControlName="rol"> - <mat-label class="text-2xl">Seleccione un rol</mat-label> - <mat-select [(value)]="selectedRol" name="rol"> - @for (rol of rolOptions; track rol) { - <mat-option [value]="rol"> - <span class="text-2xl">{{ rol }}</span> - </mat-option> - } - </mat-select> - </mat-form-field> - </div> - <mat-card-actions class="flex justify-center mb-5"> - <button - type="submit" - class="btn btn-success text-4xl" - [disabled]="loginForm.invalid" - > - Login - </button> - </mat-card-actions> - @if (errorMessage) { - <div class="text-red-500 font-bold"> - {{ errorMessage }} - </div> - } - </mat-card-content> - </mat-card> - </form> -</div> diff --git a/angular/RestClient/src/app/features/auth/login/login.component.spec.ts b/angular/RestClient/src/app/features/auth/login/login.component.spec.ts deleted file mode 100644 index 18f3685..0000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { LoginComponent } from './login.component'; - -describe('LoginComponent', () => { - let component: LoginComponent; - let fixture: ComponentFixture<LoginComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [LoginComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(LoginComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/auth/login/login.component.ts b/angular/RestClient/src/app/features/auth/login/login.component.ts deleted file mode 100644 index c28e44d..0000000 --- a/angular/RestClient/src/app/features/auth/login/login.component.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { Component } from '@angular/core'; -import { - FormBuilder, - FormGroup, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; -import { CommonModule } from '@angular/common'; -import { MatCardModule } from '@angular/material/card'; -import { MatInputModule } from '@angular/material/input'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSlideToggleModule } from '@angular/material/slide-toggle'; -import { Router } from '@angular/router'; -import { SessionService } from '../../../core/services/session/session.service'; -import { UserRol, UserRolesArray } from '../../../core/models'; - -@Component({ - standalone: true, - selector: 'app-login', - templateUrl: './login.component.html', - styleUrls: ['./login.component.css'], - imports: [ - ReactiveFormsModule, - CommonModule, - MatCardModule, - MatInputModule, - MatFormFieldModule, - MatSelectModule, - MatSlideToggleModule, - ], -}) -export class LoginComponent { - loginForm: FormGroup; - selectedRol?: UserRol; - rolOptions: UserRol[] = UserRolesArray; - errorMessage: string | null = null; - - constructor( - private fb: FormBuilder, - private sessionManager: SessionService, - private router: Router - ) { - this.loginForm = this.fb.group({ - email: ['', [Validators.required, Validators.email]], - password: ['', [Validators.required]], - }); - } - - onSubmit() { - if (this.loginForm.valid) { - const { email, password } = this.loginForm.value; - this.sessionManager.login(email, password).subscribe({ - next: (response) => { - this.router.navigateByUrl(response.mainPage); - }, - }); - } - } - - isAuthenticated(): boolean { - return !!localStorage.getItem('authToken'); - } -} diff --git a/angular/RestClient/src/app/features/auth/register/register.component.css b/angular/RestClient/src/app/features/auth/register/register.component.css deleted file mode 100644 index 79b4834..0000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.css +++ /dev/null @@ -1,21 +0,0 @@ -.container { - max-width: 600px; - margin-top: 2rem; - padding: 20px; - border: 1px solid #ccc; - border-radius: 5px; - background-color: #f9f9f9; -} - -h2 { - text-align: center; - margin-bottom: 20px; -} - -.form-group { - margin-bottom: 15px; -} - -label { - font-weight: bold; -} diff --git a/angular/RestClient/src/app/features/auth/register/register.component.html b/angular/RestClient/src/app/features/auth/register/register.component.html deleted file mode 100644 index 90cc523..0000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.html +++ /dev/null @@ -1,85 +0,0 @@ -<div class="container"> - <form [formGroup]="registerForm" (ngSubmit)="onSubmit()"> - <mat-card> - <mat-card-title class="flex text-center p-4"> - <strong class="text-5xl">RegÃstrate</strong> - </mat-card-title> - - <mat-card-content> - <div class="form-group"> - <label class="text-2xl" for="name">Nombre</label> - <input - id="name" - class="form-control" - formControlName="name" - placeholder="Introduce tu nombre" - required - /> - @if (registerForm.get('name')?.invalid && - registerForm.get('name')?.touched) { - - <div> - <small class="text-red-500 font-bold"> - El nombre es obligatorio y debe tener al menos 3 caracteres. - </small> - </div> - } - </div> - - <div class="form-group"> - <label class="text-2xl" for="email">Correo Electrónico</label> - <input - id="email" - type="email" - class="form-control" - formControlName="email" - placeholder="Introduce tu correo" - required - /> - @if (registerForm.get('email')?.invalid && - registerForm.get('email')?.touched) { - <div> - <small class="text-red-500 font-bold"> - El correo electrónico no es válido. - </small> - </div> - } - </div> - - <div class="form-group"> - <label class="text-2xl" for="password">Contraseña</label> - <input - id="password" - type="password" - class="form-control" - formControlName="password" - placeholder="Introduce tu contraseña" - required - /> - @if (registerForm.get('password')?.invalid && - registerForm.get('password')?.touched) { - <div> - <small class="text-red-500 font-bold"> - La contraseña debe tener al menos 6 caracteres. - </small> - </div> - } - </div> - <mat-card-actions class="flex justify-center mb-5"> - <button - type="submit" - class="btn btn-success text-4xl" - [disabled]="registerForm.invalid" - > - Registrarse - </button> - </mat-card-actions> - @if (errorMessage) { - <div class="text-red-500 font-bold"> - {{ errorMessage }} - </div> - } - </mat-card-content> - </mat-card> - </form> -</div> diff --git a/angular/RestClient/src/app/features/auth/register/register.component.spec.ts b/angular/RestClient/src/app/features/auth/register/register.component.spec.ts deleted file mode 100644 index 757b895..0000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { RegisterComponent } from './register.component'; - -describe('RegisterComponent', () => { - let component: RegisterComponent; - let fixture: ComponentFixture<RegisterComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [RegisterComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(RegisterComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/auth/register/register.component.ts b/angular/RestClient/src/app/features/auth/register/register.component.ts deleted file mode 100644 index 62d97d6..0000000 --- a/angular/RestClient/src/app/features/auth/register/register.component.ts +++ /dev/null @@ -1,79 +0,0 @@ -import { CommonModule } from '@angular/common'; -import { Component } from '@angular/core'; -import { - FormBuilder, - FormGroup, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; -import { MatCardModule } from '@angular/material/card'; -import { MatInputModule } from '@angular/material/input'; -import { MatFormFieldModule } from '@angular/material/form-field'; -import { MatSelectModule } from '@angular/material/select'; -import { MatSlideToggleModule } from '@angular/material/slide-toggle'; -import { Router } from '@angular/router'; -import { AuthClientService } from '../../../core/services/api/auth/auth-client.service'; -import { SessionService } from '../../../core/services/session/session.service'; - -// TODO agregar selector de roles - -@Component({ - standalone: true, - selector: 'app-register', - templateUrl: './register.component.html', - styleUrls: ['./register.component.css'], - imports: [ - ReactiveFormsModule, - CommonModule, - MatCardModule, - MatInputModule, - MatFormFieldModule, - MatSelectModule, - MatSlideToggleModule, - ], -}) -export class RegisterComponent { - registerForm: FormGroup; - errorMessage: string | null = null; - - constructor( - private fb: FormBuilder, - private authClient: AuthClientService, - private sessionManager: SessionService, - private router: Router - ) { - if (this.sessionManager.isValid()) { - const s = this.sessionManager.getSession(); - console.log({ s }); - } - this.registerForm = this.fb.group({ - name: ['', [Validators.required, Validators.minLength(3)]], - email: ['', [Validators.required, Validators.email]], - password: ['', [Validators.required, Validators.minLength(6)]], - }); - } - - onSubmit() { - if (this.registerForm.valid) { - const { name, email, password } = this.registerForm.value; - - this.authClient.register(name, email, password).subscribe({ - next: (res: any) => { - console.log({ res }); - this.sessionManager.login(res, ''); - alert('Usuario registrado con éxito.'); - this.router.navigate(['/']); // Redirigir al login - }, - error: (err) => { - if (err.error instanceof ErrorEvent) { - this.errorMessage = `Error: ${err.error.message}`; - } else { - // Si el backend devuelve un objeto de error - this.errorMessage = - err.error.message || 'Ocurrió un error al registrar el usuario.'; - } - }, - }); - } - } -} diff --git a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.css b/angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.css similarity index 100% rename from angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.css rename to angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.css diff --git a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.html b/angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.html similarity index 100% rename from angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.html rename to angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.html diff --git a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.ts b/angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.ts similarity index 100% rename from angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.ts rename to angular/RestClient/src/app/features/bookings/[DEL] booking-list/booking-list.component.ts diff --git a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts b/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts deleted file mode 100644 index f6b1910..0000000 --- a/angular/RestClient/src/app/features/bookings/booking-list/booking-list.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { BookingListComponent } from './booking-list.component'; - -describe('BookingListComponent', () => { - let component: BookingListComponent; - let fixture: ComponentFixture<BookingListComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [BookingListComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(BookingListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/bookings/booking/booking.component.html b/angular/RestClient/src/app/features/bookings/booking/booking.component.html index fb7485f..9cd9a61 100644 --- a/angular/RestClient/src/app/features/bookings/booking/booking.component.html +++ b/angular/RestClient/src/app/features/bookings/booking/booking.component.html @@ -26,23 +26,13 @@ </div> <div class="form-group"> - <label for="startDate">Fecha de Inicio (mm/dd/yyyy):</label> - <input - type="date" - id="startDate" - formControlName="startDate" - class="form-control" - /> + <label for="start">Fecha de Inicio (dd/mm/yyyy):</label> + <input id="start" formControlName="start" class="form-control" /> </div> <div class="form-group"> - <label for="endDate">Fecha de Fin (mm/dd/yyyy):</label> - <input - type="date" - id="endDate" - formControlName="endDate" - class="form-control" - /> + <label for="end">Fecha de Fin (dd/mm/yyyy):</label> + <input id="end" formControlName="end" class="form-control" /> </div> <button type="submit" class="btn btn-primary">Reservar</button> diff --git a/angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts b/angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts deleted file mode 100644 index 5cfaef6..0000000 --- a/angular/RestClient/src/app/features/bookings/booking/booking.component.spec.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { ReactiveFormsModule } from '@angular/forms'; -import { BookingComponent } from './booking.component'; -import { BookingService } from '../../../../shared/booking.service'; -import { of } from 'rxjs'; - -class MockBookingService { - createBooking() { - return of({}); // Simula una respuesta exitosa - } -} - -describe('BookingComponent', () => { - let component: BookingComponent; - let fixture: ComponentFixture<BookingComponent>; - let bookingService: BookingService; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - declarations: [BookingComponent], - imports: [ReactiveFormsModule], - providers: [{ provide: BookingService, useClass: MockBookingService }], - }).compileComponents(); - - fixture = TestBed.createComponent(BookingComponent); - component = fixture.componentInstance; - bookingService = TestBed.inject(BookingService); - fixture.detectChanges(); - }); - - it('should create the component', () => { - expect(component).toBeTruthy(); - }); - - it('should have a valid form when all fields are filled', () => { - component.bookingForm.controls['userId'].setValue(1); - component.bookingForm.controls['hotelId'].setValue(1); - component.bookingForm.controls['roomType'].setValue('single'); - component.bookingForm.controls['startDate'].setValue('2024-10-01'); - component.bookingForm.controls['endDate'].setValue('2024-10-05'); - - expect(component.bookingForm.valid).toBeTrue(); - }); - - it('should submit booking when form is valid', () => { - spyOn(bookingService, 'createBooking').and.callThrough(); - component.bookingForm.controls['userId'].setValue(1); - component.bookingForm.controls['hotelId'].setValue(1); - component.bookingForm.controls['roomType'].setValue('single'); - component.bookingForm.controls['startDate'].setValue('2024-10-01'); - component.bookingForm.controls['endDate'].setValue('2024-10-05'); - - component.submitBooking(); - expect(bookingService.createBooking).toHaveBeenCalled(); - }); -}); diff --git a/angular/RestClient/src/app/features/bookings/booking/booking.component.ts b/angular/RestClient/src/app/features/bookings/booking/booking.component.ts index f37e657..d8c08a9 100644 --- a/angular/RestClient/src/app/features/bookings/booking/booking.component.ts +++ b/angular/RestClient/src/app/features/bookings/booking/booking.component.ts @@ -15,8 +15,8 @@ import { SessionService } from '../../../core/services/session/session.service'; type communication = { roomId: number; - startDate: Date; - endDate: Date; + start: Date; + end: Date; }; @Component({ @@ -29,10 +29,10 @@ type communication = { export class BookingComponent { user: User = { id: 0, email: '', name: '', rol: 'CLIENT' }; bookingForm: FormGroup; - bookingLocal: { roomId: number; startDate: Date; endDate: Date } = { + bookingLocal: { roomId: number; start: Date; end: Date } = { roomId: 0, - endDate: new Date(), - startDate: new Date(), + end: new Date(), + start: new Date(), }; roomId: number = 0; @@ -48,8 +48,8 @@ export class BookingComponent { // Inicialización del formulario con validaciones this.bookingForm = this.fb.group({ roomId: [{ value: '', disabled: true }, Validators.required], - startDate: [{ value: '', disabled: true }, Validators.required], - endDate: [{ value: '', disabled: true }, Validators.required], + start: [{ value: '', disabled: true }, Validators.required], + end: [{ value: '', disabled: true }, Validators.required], }); const localBooking = storage.read<communication | null>('booking-data'); if (localBooking === null) { @@ -66,8 +66,8 @@ export class BookingComponent { } this.bookingLocal = { ...this.bookingLocal, - startDate: new Date(this.bookingLocal.startDate), - endDate: new Date(this.bookingLocal.endDate), + start: new Date(this.bookingLocal.start), + end: new Date(this.bookingLocal.end), }; this.loadBooking(); }); @@ -78,15 +78,22 @@ export class BookingComponent { }); } + private formatDate(date: Date) { + console.log(date); + return date.toISOString().split('T')[0].split('-').reverse().join('-'); + } + loadBooking() { const booking = this.bookingLocal; if (!booking) return; - const start = new Date(booking.startDate).toISOString(); - const end = new Date(booking.endDate).toISOString(); + const start = this.formatDate(booking.start); + const end = this.formatDate(booking.end); + console.log({ start, end }); + this.bookingForm = this.fb.group({ roomId: [{ value: booking.roomId, disabled: true }, Validators.required], - startDate: [{ value: start, disabled: true }, Validators.required], - endDate: [{ value: end, disabled: true }, Validators.required], + start: [{ value: start, disabled: true }, Validators.required], + end: [{ value: end, disabled: true }, Validators.required], }); } @@ -94,11 +101,13 @@ export class BookingComponent { const { id } = this.user; const bookingRequest: any = { ...this.bookingLocal, - userId: { id }, - roomId: { id: this.roomId }, + userId: id, + roomId: this.roomId, }; // Llama al servicio para crear una nueva reserva + console.log(bookingRequest); + this.bookingClient.createBooking(bookingRequest).subscribe({ next: (response) => { console.log('Reserva creada con éxito', response); diff --git a/angular/RestClient/src/app/features/bookings/index.ts b/angular/RestClient/src/app/features/bookings/index.ts index aa2b48a..295ef46 100644 --- a/angular/RestClient/src/app/features/bookings/index.ts +++ b/angular/RestClient/src/app/features/bookings/index.ts @@ -1,4 +1,4 @@ export * from './bookings.routes'; export * from './booking/booking.component'; -export * from './booking-list/booking-list.component'; +export * from './[DEL] booking-list/booking-list.component'; export * from './user-booking-list/user-booking-list.component'; diff --git a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html index 6a845bc..69a3dac 100644 --- a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html +++ b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.html @@ -25,8 +25,8 @@ <li class="booking-item"> <span class="booking-id">Reserva #{{ booking.id }}</span> - <span class="booking-start">{{ booking.startDate }}</span> - <span class="booking-end">{{ booking.endDate }}</span> + <span class="booking-start">{{ booking.start }}</span> + <span class="booking-end">{{ booking.end }}</span> <span class="booking-status">{{ genBookingState(booking) }}</span> <span class="booking-delete"> <button (click)="deleteBooking(booking.id)">Eliminar</button> diff --git a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts deleted file mode 100644 index aae5d91..0000000 --- a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { UserBookingListComponent } from './user-booking-list.component'; - -describe('UserBookingListComponent', () => { - let component: UserBookingListComponent; - let fixture: ComponentFixture<UserBookingListComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [UserBookingListComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(UserBookingListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts index a76d5b3..c3059d8 100644 --- a/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts +++ b/angular/RestClient/src/app/features/bookings/user-booking-list/user-booking-list.component.ts @@ -76,8 +76,7 @@ export class UserBookingListComponent { } genBookingState(booking: Booking) { - return new Date().setHours(0, 0, 0, 0) <= - new Date(booking.endDate).getTime() + return new Date().setHours(0, 0, 0, 0) <= new Date(booking.end).getTime() ? 'Reserva activa' : 'Reserva inactiva'; } diff --git a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts deleted file mode 100644 index ecc4715..0000000 --- a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { HotelListComponent } from './hotel-list.component'; - -describe('HotelListComponent', () => { - let component: HotelListComponent; - let fixture: ComponentFixture<HotelListComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [HotelListComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(HotelListComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts index 4cf5d5c..9ec062a 100644 --- a/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts +++ b/angular/RestClient/src/app/features/hotels/hotel-list/hotel-list.component.ts @@ -76,8 +76,11 @@ export class HotelListComponent { private storage: LocalStorageService, private sessionService: SessionService ) { - const isHotelManger = this.route.snapshot.url[0].path === 'me'; - const isAdmin = this.route.snapshot.url[0].path === 'admin'; + const url = this.router.url; + const baseUrl = getBasePath(url).split('/')[1]; + const isHotelManger = url.split('/')[1] === 'me'; + const isAdmin = baseUrl === 'admin'; + console.log({ isHotelManger, isAdmin, baseUrl }); this.isManaging = isHotelManger || isAdmin; const today = new Date(); @@ -91,6 +94,7 @@ export class HotelListComponent { this.sessionService.getSession().subscribe({ next: (session) => { + console.log({ session }); if (session && session.rol !== 'CLIENT') { this.isEditing = true; this.userId = isHotelManger @@ -116,12 +120,14 @@ export class HotelListComponent { ) .map((h) => { h = { ...h, rooms: [...h.rooms] }; - h.rooms = h.rooms.filter( - (r) => - r.available && - (this.roomTypeSelected === 'All' || - (r.type as SelectableRoomType) === this.roomTypeSelected) - ); + if (!this.isManaging) { + h.rooms = h.rooms.filter( + (r) => + r.available && + (this.roomTypeSelected === 'All' || + (r.type as SelectableRoomType) === this.roomTypeSelected) + ); + } return h; }) .filter((h) => h.rooms.length > 0); @@ -148,9 +154,10 @@ export class HotelListComponent { const { start, end } = this.dateRangeForm.value.dateRange; const observable = this.isManaging - ? this.hotelClient.getAllHotelsByUser(this.userId, start, end) + ? this.hotelClient.getAllHotelsByUser(this.userId) : this.hotelClient.getAllHotels(start, end); - console.log({ ...this }); + console.log('a', this.isManaging); + observable.subscribe({ next: (resp) => { if (!!resp && (resp as never[]).length >= 0) { @@ -201,7 +208,8 @@ export class HotelListComponent { getHotelUri(hotelId: number) { var base; try { - base = getBasePath(this.route) + '/'; + // TODO revisar + base = getBasePath(this.router.url) + '/'; } catch (error) { base = ''; } @@ -215,8 +223,8 @@ export class HotelListComponent { }; this.storage.save('booking-data', { roomId, - startDate: start.toString(), - endDate: end.toString(), + start: start.toString(), + end: end.toString(), }); this.router.navigate(['/me', 'bookings', 'new'], { queryParams: { roomId, startDate: start.toLocaleDateString() }, diff --git a/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts b/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts deleted file mode 100644 index 7c085a3..0000000 --- a/angular/RestClient/src/app/features/hotels/hotel-register/hotel-register.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { HotelRegisterComponent } from './hotel-register.component'; - -describe('HotelRegisterComponent', () => { - let component: HotelRegisterComponent; - let fixture: ComponentFixture<HotelRegisterComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [HotelRegisterComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(HotelRegisterComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/hotels/hotels.routes.ts b/angular/RestClient/src/app/features/hotels/hotels.routes.ts index 9e00041..d054f0a 100644 --- a/angular/RestClient/src/app/features/hotels/hotels.routes.ts +++ b/angular/RestClient/src/app/features/hotels/hotels.routes.ts @@ -22,24 +22,19 @@ export const HOTELS_ROUTES: AppRoute[] = [ export const MANAGERS_ROUTES: AppRoute[] = [ { - path: 'hotels', - children: [ - { - path: '', - component: HotelListComponent, - }, - { - path: ':id', - component: HotelRegisterComponent, - }, - // { - // path: ':id/bookings', - // component: BookingListComponent, - // }, - // { - // path: ':id/rooms/:id/bookings', - // component: BookingListComponent, - // }, - ], + path: '', + component: HotelListComponent, + }, + { + path: ':id', + component: HotelRegisterComponent, }, + // { + // path: ':id/bookings', + // component: BookingListComponent, + // }, + // { + // path: ':id/rooms/:id/bookings', + // component: BookingListComponent, + // }, ]; diff --git a/angular/RestClient/src/app/features/users/admin.routes.ts b/angular/RestClient/src/app/features/users/admin.routes.ts index ff36047..fdd9b4a 100644 --- a/angular/RestClient/src/app/features/users/admin.routes.ts +++ b/angular/RestClient/src/app/features/users/admin.routes.ts @@ -1,23 +1,36 @@ import { AppRoute } from '@core/models'; import { MainPageComponent } from 'app/features/users/main-page/main-page.component'; +import { UserFormRoute } from 'app/features/users/types/UserFormData'; import { UserFormComponent } from 'app/features/users/user-form/user-form.component'; import { USERS_ROUTES } from 'app/features/users/users.routes'; -function getRoutesWithoutRol(routes: AppRoute[]) { +function changeToAdminScope(routes: UserFormRoute[]) { return routes.map((r) => { - if (r.data?.expectedRole) { + if (r.data) { const { data, ...rest } = r; - return { ...rest }; + data.expectedRole = undefined; + if (data.mode) { + data.mode.admin = true; + } + return { data, ...rest }; } return r; }); } -export const ADMIN_ROUTES: AppRoute[] = [ - { - path: '', // Main - component: UserFormComponent, +const mainRoute: UserFormRoute = { + path: '', // Main + data: { + mode: { + formMode: 'VIEW', + admin: true, + }, }, + component: UserFormComponent, +}; + +export const ADMIN_ROUTES: AppRoute[] = [ + mainRoute, { path: 'users', children: [ @@ -27,7 +40,7 @@ export const ADMIN_ROUTES: AppRoute[] = [ }, { path: ':id', - children: getRoutesWithoutRol(USERS_ROUTES), + children: changeToAdminScope(USERS_ROUTES), }, ], }, diff --git a/angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts b/angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts deleted file mode 100644 index 40d589a..0000000 --- a/angular/RestClient/src/app/features/users/main-page/main-page.component.spec.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { MainPageComponent } from './main-page.component'; - -describe('MainPageComponent', () => { - let component: MainPageComponent; - let fixture: ComponentFixture<MainPageComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [MainPageComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(MainPageComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/features/users/types/UserFormData.d.ts b/angular/RestClient/src/app/features/users/types/UserFormData.d.ts new file mode 100644 index 0000000..2796c60 --- /dev/null +++ b/angular/RestClient/src/app/features/users/types/UserFormData.d.ts @@ -0,0 +1,15 @@ +import { AppRoute } from '@core/models'; + +export type UserFormMode = + | 'REGISTER' + | 'LOGIN' + | 'PASSWORD' + | 'VIEW' + | 'EDIT' + | 'OTHER'; +export type ModeType = { + formMode: UserFormMode; + admin?: boolean; +}; + +export type UserFormRoute = AppRoute<{ mode?: ModeType }>; diff --git a/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts b/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts deleted file mode 100644 index b2c1c43..0000000 --- a/angular/RestClient/src/app/features/users/user-form/user-form.component.spec.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { HttpResponse } from '@angular/common/http'; -import { UserFormComponent } from './user-form.component'; -import { UserClientService } from '../../../core/services/api/users/user-client.service'; -import { of } from 'rxjs'; - -describe('UserFormComponent', () => { - let component: UserFormComponent; - let fixture: ComponentFixture<UserFormComponent>; - let userService: UserClientService; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [ReactiveFormsModule, FormsModule], - declarations: [UserFormComponent], - providers: [UserClientService], - }).compileComponents(); - - fixture = TestBed.createComponent(UserFormComponent); - component = fixture.componentInstance; - userService = TestBed.inject(UserClientService); - - spyOn(userService, 'getCurrentUser').and.returnValue( - of({ - id: 1, - name: 'John Doe', - email: 'johndoe@example.com', - rol: 'CONSUMER', - status: 'WITH_ACTIVE_BOOKINGS', - }) - ); - - spyOn(userService, 'updateUser').and.returnValue( - of(new HttpResponse({ body: 'User updated successfully' })) - ); - spyOn(userService, 'updatePassword').and.returnValue( - of(new HttpResponse({ body: 'Password updated successfully' })) - ); - - fixture.detectChanges(); - }); - - it('should create the component', () => { - expect(component).toBeTruthy(); - }); - - it('should load user data on initialization', () => { - expect(component.userForm.value).toEqual({ - name: 'John Doe', - email: 'johndoe@example.com', - password: '', - confirmPassword: '', - }); - }); - - it('should call updateUser when saving valid user data', () => { - component.userForm.patchValue({ - name: 'Jane Doe', - email: 'janedoe@example.com', - }); - - component.saveChanges(); - - expect(userService.updateUser).toHaveBeenCalledWith({ - name: 'Jane Doe', - email: 'janedoe@example.com', - }); - }); - - it('should call updatePassword when password is updated and matches confirmPassword', () => { - component.userForm.patchValue({ - password: 'newpassword123', - confirmPassword: 'newpassword123', - }); - - component.saveChanges(); - - expect(userService.updatePassword).toHaveBeenCalledWith( - '', - 'newpassword123' - ); - }); - - it('should not call updatePassword if password and confirmPassword do not match', () => { - component.userForm.patchValue({ - password: 'newpassword123', - confirmPassword: 'differentpassword', - }); - - component.saveChanges(); - - expect(userService.updatePassword).not.toHaveBeenCalled(); - }); -}); diff --git a/angular/RestClient/src/app/features/users/user-form/user-form.component.ts b/angular/RestClient/src/app/features/users/user-form/user-form.component.ts index c57800f..8be9234 100644 --- a/angular/RestClient/src/app/features/users/user-form/user-form.component.ts +++ b/angular/RestClient/src/app/features/users/user-form/user-form.component.ts @@ -16,16 +16,12 @@ import { SessionService } from '../../../core/services/session/session.service'; import { Session, UserRol, UserRolesArray } from '../../../core/models'; import { MatSelectModule } from '@angular/material/select'; import { Observable } from 'rxjs'; -import { getBasePath } from '../../../utils/utils'; -import { environment } from '../../../../environments/environment'; +import { + UserFormMode, + UserFormRoute, +} from 'app/features/users/types/UserFormData'; +import { getBasePath } from '@utils/utils'; -type EditMode = - | 'Login' - | 'Register' - | 'ViewUser' - | 'EditUser' - | 'ChangePassword' - | 'Other'; const defaultUser: Session = { id: 0, name: 'test', @@ -52,7 +48,7 @@ const defaultUser: Session = { export class UserFormComponent implements OnInit { userForm!: FormGroup; rolOptions: UserRol[] = UserRolesArray; - mode: EditMode = 'Other'; + mode: UserFormMode = 'OTHER'; isMeRoute = false; /** is editing the user data */ @@ -84,29 +80,6 @@ export class UserFormComponent implements OnInit { private router: Router ) {} - isEditRoute(urlSegments: any[], isMeRoute: boolean): boolean { - return isMeRoute - ? urlSegments.length >= 2 && urlSegments[1].path === 'edit' - : urlSegments.length >= 4 && urlSegments[3].path === 'edit'; - } - - isChangePasswordRoute(urlSegments: any[], isMeRoute: boolean): boolean { - return isMeRoute - ? urlSegments.length >= 2 && urlSegments[1].path === 'change-passwd' - : urlSegments.length >= 4 && urlSegments[3].path === 'change-passwd'; - } - - isViewUserRoute(urlSegments: any[], isMeRoute: boolean): boolean { - return isMeRoute - ? urlSegments.length === 1 - : (urlSegments.length === 1 && urlSegments[0].path === 'admin') || - urlSegments.length === 3; - } - - isAuthRoute(urlSegments: any[], route: string): boolean { - return urlSegments.length === 1 && urlSegments[0].path === route; - } - ngOnInit(): void { this.setUp(); @@ -167,47 +140,50 @@ export class UserFormComponent implements OnInit { } setUp() { - const urlSeg = this.route.snapshot.url; - if (this.isAuthRoute(urlSeg, 'login')) { - // Login - this.isAuth = true; - this.isLogin = true; - this.mode = 'Login'; - this.currentPasswordText = 'Contraseña'; - this.submitButtonText = 'Login'; - this.titleText = 'Login'; - } else if (this.isAuthRoute(urlSeg, 'register')) { - // Register - this.isAuth = true; - this.isRegister = true; - this.mode = 'Register'; - this.currentPasswordText = 'Contraseña'; - this.submitButtonText = 'Create'; - this.titleText = 'Register'; - } else { - // Identificar si estamos usando /me o /users/:id - getBasePath(this.route); - const isMeRoute = urlSeg[0].path === 'me'; - this.isMeRoute = isMeRoute; - - if (this.isEditRoute(urlSeg, isMeRoute)) { - this.isEditing = true; - this.mode = 'EditUser'; - this.titleText = 'Editar mis datos'; - } else if (this.isChangePasswordRoute(urlSeg, isMeRoute)) { - this.mode = 'ChangePassword'; + const snapshot = this.route.snapshot; + const urlSeg = snapshot.url; + const { data } = snapshot as UserFormRoute; + const mode = data!.mode!; + + console.log(mode); + + switch (mode.formMode) { + case 'REGISTER': + this.isAuth = true; + this.isRegister = true; + this.currentPasswordText = 'Contraseña'; + this.submitButtonText = 'Create'; + this.titleText = 'Register'; + break; + case 'LOGIN': + this.isAuth = true; + this.isLogin = true; + this.currentPasswordText = 'Contraseña'; + this.submitButtonText = 'Login'; + this.titleText = 'Login'; + break; + case 'PASSWORD': this.isEditing = true; this.isChangePassword = true; this.currentPasswordText = 'Contraseña actual'; this.titleText = 'Cambiar mi contraseña'; - } else if (this.isViewUserRoute(urlSeg, isMeRoute)) { - this.mode = 'ViewUser'; + this.submitButtonText = 'Update password'; + break; + case 'VIEW': this.isViewUser = true; this.titleText = 'Mis datos'; - } - - this.submitButtonText = 'Update'; + break; + case 'EDIT': + this.isEditing = true; + this.titleText = 'Editar mis datos'; + this.submitButtonText = 'Update'; + break; + case 'OTHER': + default: + break; } + this.isAdmin = !!mode.admin; + this.mode = mode.formMode; this.initializeForm(); if (!this.isAuth) { @@ -226,31 +202,31 @@ export class UserFormComponent implements OnInit { } getHotelsUri() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' return `${basePath}/hotels`; } getBookingsUri() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' return `${basePath}/bookings`; } togglePassword() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' - - if (this.mode === 'EditUser') { + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' + console.log('->', basePath); + if (this.mode === 'EDIT') { this.router.navigateByUrl(`${basePath}/change-passwd`); - } else if (this.mode === 'ChangePassword') { + } else if (this.mode === 'PASSWORD') { this.router.navigateByUrl(`${basePath}/edit`); } } switchMode() { - const basePath = getBasePath(this.route); // Obtener la base: '/me' o '/users/:id' - console.log({ ...this }); - if (this.mode === 'EditUser') { + const basePath = getBasePath(this.router.url); // Obtener la base: '/me' o '/users/:id' + console.log('->', { basePath }); + if (this.mode === 'EDIT' || this.mode === 'PASSWORD') { this.router.navigateByUrl(basePath); - } else if (this.mode === 'ViewUser') { + } else if (this.mode === 'VIEW') { this.router.navigateByUrl(`${basePath}/edit`); } } @@ -320,17 +296,17 @@ export class UserFormComponent implements OnInit { console.log({ data }); switch (this.mode) { - case 'Login': + case 'LOGIN': this.login(data.email, data.currentPassword); break; - case 'Register': + case 'REGISTER': this.register(data.name, data.email, data.currentPassword, data.rol); break; - case 'EditUser': + case 'EDIT': this.updateUser(data.name, data.email); break; - case 'ChangePassword': - this.changePassword(data.currentPassword, data.newPassword); + case 'PASSWORD': + this.updatePassword(data.currentPassword, data.newPassword); break; default: break; @@ -370,7 +346,7 @@ export class UserFormComponent implements OnInit { private updateUser(name: string, email: string) { this.userService.updateUser(this.user.id, { name, email }).subscribe({ next: () => { - this.router.navigateByUrl(getBasePath(this.route)); + this.router.navigateByUrl(getBasePath(this.router.url)); }, error: (error) => { console.error(error); @@ -379,7 +355,7 @@ export class UserFormComponent implements OnInit { }); } - private changePassword(password: string | undefined, newPassword: string) { + private updatePassword(password: string | undefined, newPassword: string) { alert('Unimplemented yet'); } } diff --git a/angular/RestClient/src/app/features/users/users.routes.ts b/angular/RestClient/src/app/features/users/users.routes.ts index 84c240f..aca2079 100644 --- a/angular/RestClient/src/app/features/users/users.routes.ts +++ b/angular/RestClient/src/app/features/users/users.routes.ts @@ -1,22 +1,34 @@ -import { AppRoute, UserRolesArray } from '@core/models'; import { UserFormComponent } from './user-form/user-form.component'; +import { UserFormRoute } from './types/UserFormData'; -export const USERS_ROUTES: AppRoute[] = [ +export const USERS_ROUTES: UserFormRoute[] = [ // Common { path: '', - data: { expectedRole: UserRolesArray }, + data: { + mode: { + formMode: 'VIEW', + }, + }, component: UserFormComponent, }, { path: 'edit', + data: { + mode: { + formMode: 'EDIT', + }, + }, component: UserFormComponent, - data: { expectedRole: UserRolesArray }, }, { path: 'change-passwd', + data: { + mode: { + formMode: 'PASSWORD', + }, + }, component: UserFormComponent, - data: { expectedRole: UserRolesArray }, }, { // Usuario administrador de hoteles diff --git a/angular/RestClient/src/app/page/unauthorized/unauthorized.component.spec.ts b/angular/RestClient/src/app/page/unauthorized/unauthorized.component.spec.ts deleted file mode 100644 index bab5ad8..0000000 --- a/angular/RestClient/src/app/page/unauthorized/unauthorized.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { UnauthorizedComponent } from './unauthorized.component'; - -describe('UnauthorizedComponent', () => { - let component: UnauthorizedComponent; - let fixture: ComponentFixture<UnauthorizedComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [UnauthorizedComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(UnauthorizedComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts b/angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts deleted file mode 100644 index a161d31..0000000 --- a/angular/RestClient/src/app/shared/navigation/navigation.component.spec.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NavigationComponent } from './navigation.component'; - -describe('NavigationComponent', () => { - let component: NavigationComponent; - let fixture: ComponentFixture<NavigationComponent>; - - beforeEach(async () => { - await TestBed.configureTestingModule({ - imports: [NavigationComponent] - }) - .compileComponents(); - - fixture = TestBed.createComponent(NavigationComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular/RestClient/src/app/utils/utils.ts b/angular/RestClient/src/app/utils/utils.ts index 1c97d18..a32f785 100644 --- a/angular/RestClient/src/app/utils/utils.ts +++ b/angular/RestClient/src/app/utils/utils.ts @@ -1,18 +1,20 @@ -import { ActivatedRoute } from '@angular/router'; - -export function getBasePath(route: ActivatedRoute): string { - const urlSegments = route.snapshot.url; - if (urlSegments[0].path === 'me') { - return '/me'; - } else if ( - urlSegments.length >= 3 && - urlSegments[0].path === 'admin' && - urlSegments[1].path === 'users' && - urlSegments[2] - ) { - return `/admin/users/${urlSegments[2]}`; // Devuelve la ruta con el ID del usuario - } else if (urlSegments[0].path === 'admin') { - return '/me'; +export function getBasePath(route: string) { + const url = route.split('/').slice(1); + const me = '/me'; + let base = me; + if (url.length > 0 && url[0] === me) { + base = url[0]; + } else if (url.length > 0 && url[0] === 'admin') { + const i = url.indexOf('users'); + const j = url.indexOf('hotels'); + base = + i !== -1 + ? url.slice(0, i + 2).join('/') + : j !== -1 + ? url.slice(0, i + 2).join('/') + : me; } - throw new Error('Invalid route structure'); // Manejo de errores si la URL no es válida + + console.log({ url, route, base }); + return base; } diff --git a/angular/RestClient/src/environments/environment.prod.ts b/angular/RestClient/src/environments/environment.prod.ts index db34014..88bea49 100644 --- a/angular/RestClient/src/environments/environment.prod.ts +++ b/angular/RestClient/src/environments/environment.prod.ts @@ -1,4 +1,4 @@ -const gateWayUrl = 'localhost:8000'; // kong +const gateWayUrl = 'localhost:8000/api'; // kong export const environment = { production: true, diff --git a/angular/RestClient/src/environments/environment.ts b/angular/RestClient/src/environments/environment.ts index 27e9915..0d80152 100644 --- a/angular/RestClient/src/environments/environment.ts +++ b/angular/RestClient/src/environments/environment.ts @@ -1,8 +1,8 @@ const developmentHost = 'localhost'; export const environment = { production: false, - authAPI: `http://${developmentHost}:8101`, - userAPI: `http://${developmentHost}:8080/users`, - hotelAPI: `http://${developmentHost}:8080/hotels`, - bookingAPI: `http://${developmentHost}:8080/bookings`, + authAPI: `http://${developmentHost}:8101/auth`, + userAPI: `http://${developmentHost}:8201/users`, + hotelAPI: `http://${developmentHost}:8301/hotels`, + bookingAPI: `http://${developmentHost}:8401/bookings`, }; diff --git a/java/services/auth/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/auth/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000..3b50599 --- /dev/null +++ b/java/services/auth/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000..3b50599 --- /dev/null +++ b/java/services/bookings/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000..3b50599 --- /dev/null +++ b/java/services/hotels/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +} diff --git a/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java b/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java new file mode 100644 index 0000000..3b50599 --- /dev/null +++ b/java/services/users/src/test/java/com/uva/roomBooking/RoomBookingApplicationTests.java @@ -0,0 +1,13 @@ +package com.uva.roomBooking; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class RoomBookingApplicationTests { + + @Test + void contextLoads() { + } + +} -- GitLab