From 1f8bfa20ad9b9aad7b9f8d8884323893bf39f955 Mon Sep 17 00:00:00 2001 From: Ruan-Carvalho Date: Wed, 21 Aug 2024 14:52:35 -0300 Subject: [PATCH 01/10] =?UTF-8?q?criar=20fun=C3=A7=C3=A3o=20de=20setar=20o?= =?UTF-8?q?=20super-admin?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/services/auth.service.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/app/services/auth.service.ts b/src/app/services/auth.service.ts index 0f6ad2f0..3f42d9ee 100755 --- a/src/app/services/auth.service.ts +++ b/src/app/services/auth.service.ts @@ -62,4 +62,8 @@ export class AuthService { setupAdmin(data: any): Observable { return this.http.post(`${this.usersAPIURL}/auth/admin-setup`, data); } + + super_admin_setup(data: any): Observable { + return this.http.post(`${this.usersAPIURL}/auth/super-admin-setup`, data); + } } From a28f794cb77dbb93289fed63b2e7f8098df3ec6f Mon Sep 17 00:00:00 2001 From: gabrielhrlima Date: Wed, 21 Aug 2024 15:21:22 -0300 Subject: [PATCH 02/10] Cria o componente que ativa o ADMIN e importa a rota --- src/app/app-routing.module.ts | 26 ++-- .../super-admin-activate.component.css | 0 .../super-admin-activate.component.html | 1 + .../super-admin-activate.component.spec.ts | 121 ++++++++++++++++++ .../super-admin-activate.component.ts | 71 ++++++++++ 5 files changed, 208 insertions(+), 11 deletions(-) create mode 100644 src/app/pages/super-admin-activate/super-admin-activate.component.css create mode 100644 src/app/pages/super-admin-activate/super-admin-activate.component.html create mode 100644 src/app/pages/super-admin-activate/super-admin-activate.component.spec.ts create mode 100644 src/app/pages/super-admin-activate/super-admin-activate.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index bc778ff5..bcf21f9e 100755 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -23,6 +23,7 @@ import { PrivacyPolicyComponent } from './pages/privacy-policy/privacy-policy.co import { HomeAdminComponent } from './pages/home-admin/home-admin.component'; import { AdminActivateComponent } from './pages/admin-activate/admin-activate.component'; +import { SuperAdminActivateComponent } from './pages/super-admin-activate/super-admin-activate.component'; import { CategoryTableComponent } from './pages/category-table/category-table.component'; import { VideoViewsComponent } from './pages/video-views/video-views.component'; import { RecordComponent } from './pages/record/record.component'; @@ -31,7 +32,6 @@ import { DashboardCategoryComponent } from './pages/dashboard-category/dashboard import { WithTokenGuard } from './guard/with-token.guard'; import { TokenAdminGuard } from './guard/admin.guard'; - const routes: Routes = [ { path: '', component: LoginComponent, canActivate: [WithTokenGuard] }, { path: 'stream', component: StreamViewComponent }, @@ -93,22 +93,26 @@ const routes: Routes = [ canActivate: [AdminGuard], }, { path: 'privacy', component: PrivacyPolicyComponent }, - - { path: 'homeAdmin', + { + path: 'homeAdmin', component: HomeAdminComponent, canActivate: [TokenAdminGuard], }, { path: 'adminActivate', - component: AdminActivateComponent + component: AdminActivateComponent, + }, + { + path: 'superAdminActivate', + component: SuperAdminActivateComponent, }, - { + { path: 'category-views', component: CategoryTableComponent, canActivate: [TokenAdminGuard], }, - { - path: 'video-views', + { + path: 'video-views', component: VideoViewsComponent, canActivate: [TokenAdminGuard], }, @@ -118,9 +122,9 @@ const routes: Routes = [ canActivate: [TokenAdminGuard], }, { - path: 'record', - component: RecordComponent, - canActivate: [AuthGuard] + path: 'record', + component: RecordComponent, + canActivate: [AuthGuard], }, ]; @@ -128,4 +132,4 @@ const routes: Routes = [ imports: [RouterModule.forRoot(routes)], exports: [RouterModule], }) -export class AppRoutingModule { } +export class AppRoutingModule {} diff --git a/src/app/pages/super-admin-activate/super-admin-activate.component.css b/src/app/pages/super-admin-activate/super-admin-activate.component.css new file mode 100644 index 00000000..e69de29b diff --git a/src/app/pages/super-admin-activate/super-admin-activate.component.html b/src/app/pages/super-admin-activate/super-admin-activate.component.html new file mode 100644 index 00000000..3c4c3fe3 --- /dev/null +++ b/src/app/pages/super-admin-activate/super-admin-activate.component.html @@ -0,0 +1 @@ +

super-admin-activate works!

diff --git a/src/app/pages/super-admin-activate/super-admin-activate.component.spec.ts b/src/app/pages/super-admin-activate/super-admin-activate.component.spec.ts new file mode 100644 index 00000000..0d14ed57 --- /dev/null +++ b/src/app/pages/super-admin-activate/super-admin-activate.component.spec.ts @@ -0,0 +1,121 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { SuperAdminActivateComponent } from './super-admin-activate.component'; +import { AuthService } from 'src/app/services/auth.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { AlertService } from 'src/app/services/alert.service'; +import { of, throwError, Subscription } from 'rxjs'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { MessageService } from 'primeng/api'; + +class MockAuthService { + super_admin_setup(data: any) { + return of({ success: true }); + } +} + +class MockAlertService { + showMessage() {} + errorMessage() {} +} + +class MockActivatedRoute { + queryParams = of({ email: 'test@example.com' }); +} + +describe('SuperAdminActivateComponent', () => { + let component: SuperAdminActivateComponent; + let fixture: ComponentFixture; + let authService: AuthService; + let alertService: AlertService; + let router: Router; + let route: ActivatedRoute; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [SuperAdminActivateComponent], + imports: [HttpClientTestingModule, RouterTestingModule], + providers: [ + { provide: AuthService, useClass: MockAuthService }, + { provide: AlertService, useClass: MockAlertService }, + { provide: ActivatedRoute, useClass: MockActivatedRoute }, + MessageService, + ], + }).compileComponents(); + + fixture = TestBed.createComponent(SuperAdminActivateComponent); + component = fixture.componentInstance; + authService = TestBed.inject(AuthService); + alertService = TestBed.inject(AlertService); + router = TestBed.inject(Router); + route = TestBed.inject(ActivatedRoute); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should call setupSuperAdmin if email is provided', () => { + spyOn(component, 'setupSuperAdmin').and.callThrough(); + spyOn(authService, 'super_admin_setup').and.returnValue(of({})); + spyOn(router, 'navigate'); + + component.ngOnInit(); + + expect(component.setupSuperAdmin).toHaveBeenCalledWith('test@example.com'); + expect(authService.super_admin_setup).toHaveBeenCalled(); + expect(router.navigate).toHaveBeenCalledWith(['/homeAdmin']); + }); + + it('should handle error if no email is provided', () => { + (route.queryParams as any) = of({}); + + spyOn(alertService, 'errorMessage').and.callThrough(); + spyOn(router, 'navigate'); + + component.ngOnInit(); + + expect(alertService.errorMessage).toHaveBeenCalledWith({ + message: 'Email não fornecido', + }); + expect(router.navigate).toHaveBeenCalledWith(['/loginsocial']); + }); + + it('should show success message on successful admin setup', () => { + spyOn(authService, 'super_admin_setup').and.returnValue(of({})); + spyOn(alertService, 'showMessage').and.callThrough(); + spyOn(router, 'navigate'); + + component.setupSuperAdmin('test@example.com'); + + expect(alertService.showMessage).toHaveBeenCalledWith( + 'success', + 'Sucesso', + 'Super Admin configurado com sucesso!' + ); + expect(alertService.showMessage).toHaveBeenCalledWith( + 'info', + 'Alerta', + 'Saia da sua conta e entre novamente para acessar a tela de administrador.' + ); + expect(router.navigate).toHaveBeenCalledWith(['/homeAdmin']); + }); + + it('should handle error during admin setup', () => { + spyOn(authService, 'super_admin_setup').and.returnValue( + throwError(() => ({ + error: { detail: 'Erro desconhecido' }, + })) + ); + spyOn(alertService, 'errorMessage').and.callThrough(); + spyOn(router, 'navigate'); + + component.setupSuperAdmin('test@example.com'); + + expect(alertService.errorMessage).toHaveBeenCalledWith({ + message: 'Erro desconhecido', + }); + expect(router.navigate).toHaveBeenCalledWith(['/loginsocial']); + }); +}); diff --git a/src/app/pages/super-admin-activate/super-admin-activate.component.ts b/src/app/pages/super-admin-activate/super-admin-activate.component.ts new file mode 100644 index 00000000..80b13db6 --- /dev/null +++ b/src/app/pages/super-admin-activate/super-admin-activate.component.ts @@ -0,0 +1,71 @@ +import { Component, OnInit } from '@angular/core'; +import { AuthService } from 'src/app/services/auth.service'; +import { ActivatedRoute, Router } from '@angular/router'; +import { AlertService } from 'src/app/services/alert.service'; +import { IError } from 'src/shared/model/http-error.model'; +import { HttpErrorResponse } from '@angular/common/http'; + +type ErrorResponseType = HttpErrorResponse; + +@Component({ + selector: 'app-super-admin-activate', + templateUrl: './super-admin-activate.component.html', + styleUrls: ['./super-admin-activate.component.css'], +}) +export class SuperAdminActivateComponent implements OnInit { + constructor( + private authService: AuthService, + private route: ActivatedRoute, + private router: Router, + private alertService: AlertService + ) {} + + ngOnInit(): void { + this.route.queryParams.subscribe({ + next: (params: any) => { + const email = params['email']; + if (email) { + this.setupSuperAdmin(email); + } else { + const error: IError = { message: 'Email não fornecido' }; + this.alertService.errorMessage(error); + this.router.navigate(['/loginsocial']); + } + }, + error: (error: ErrorResponseType) => { + const errorMsg: IError = { + message: error.error.detail || 'Erro ao obter parâmetros da URL', + }; + this.alertService.errorMessage(errorMsg); + this.router.navigate(['/loginsocial']); + }, + }); + } + + setupSuperAdmin(email: string): void { + const data = { email: email }; + + this.authService.super_admin_setup(data).subscribe({ + next: () => { + this.alertService.showMessage( + 'success', + 'Sucesso', + 'Super Admin configurado com sucesso!' + ); + this.alertService.showMessage( + 'info', + 'Alerta', + 'Saia da sua conta e entre novamente para acessar a tela de administrador.' + ); + this.router.navigate(['/homeAdmin']); + }, + error: (error: ErrorResponseType) => { + const errorMsg: IError = { + message: error.error.detail || 'Erro desconhecido', + }; + this.alertService.errorMessage(errorMsg); + this.router.navigate(['/loginsocial']); + }, + }); + } +} From e0fa94908460bf4673b95f4d0d13ac985dd2179b Mon Sep 17 00:00:00 2001 From: gabrielhrlima Date: Wed, 21 Aug 2024 15:27:17 -0300 Subject: [PATCH 03/10] Cria o guard para o ADMIN --- src/app/guard/super-admin.guard.spec.ts | 17 +++++++++++++++++ src/app/guard/super-admin.guard.ts | 5 +++++ 2 files changed, 22 insertions(+) create mode 100644 src/app/guard/super-admin.guard.spec.ts create mode 100644 src/app/guard/super-admin.guard.ts diff --git a/src/app/guard/super-admin.guard.spec.ts b/src/app/guard/super-admin.guard.spec.ts new file mode 100644 index 00000000..6dc76d9f --- /dev/null +++ b/src/app/guard/super-admin.guard.spec.ts @@ -0,0 +1,17 @@ +import { TestBed } from '@angular/core/testing'; +import { CanActivateFn } from '@angular/router'; + +import { superAdminGuard } from './guard/super-admin.guard'; + +describe('superAdminGuard', () => { + const executeGuard: CanActivateFn = (...guardParameters) => + TestBed.runInInjectionContext(() => superAdminGuard(...guardParameters)); + + beforeEach(() => { + TestBed.configureTestingModule({}); + }); + + it('should be created', () => { + expect(executeGuard).toBeTruthy(); + }); +}); diff --git a/src/app/guard/super-admin.guard.ts b/src/app/guard/super-admin.guard.ts new file mode 100644 index 00000000..aa20f89a --- /dev/null +++ b/src/app/guard/super-admin.guard.ts @@ -0,0 +1,5 @@ +import { CanActivateFn } from '@angular/router'; + +export const superAdminGuard: CanActivateFn = (route, state) => { + return true; +}; From 4e54b33b031f1a4195756ab9c3e1dc61bb9d8a5a Mon Sep 17 00:00:00 2001 From: Ruan-Carvalho Date: Wed, 21 Aug 2024 15:55:45 -0300 Subject: [PATCH 04/10] Implementa o guard para o ADMIN e modifica o guard do COADMIN --- src/app/app-routing.module.ts | 1 + src/app/guard/admin.guard.ts | 2 +- src/app/guard/super-admin.guard.spec.ts | 71 +++++++++++++++++++++---- src/app/guard/super-admin.guard.ts | 38 +++++++++++-- 4 files changed, 98 insertions(+), 14 deletions(-) diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index bcf21f9e..d6e71566 100755 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -31,6 +31,7 @@ import { DashboardCategoryComponent } from './pages/dashboard-category/dashboard import { WithTokenGuard } from './guard/with-token.guard'; import { TokenAdminGuard } from './guard/admin.guard'; +import {TokenSuperAdminGuard} from './guard/super-admin.guard' const routes: Routes = [ { path: '', component: LoginComponent, canActivate: [WithTokenGuard] }, diff --git a/src/app/guard/admin.guard.ts b/src/app/guard/admin.guard.ts index ba64eab5..e0379df8 100644 --- a/src/app/guard/admin.guard.ts +++ b/src/app/guard/admin.guard.ts @@ -13,7 +13,7 @@ export class TokenAdminGuard implements CanActivate { if (this.authService.isAuthenticated()) { const userRole = this.userService.getRoles(); - if (userRole === 'ADMIN') { + if (userRole === 'ADMIN' || userRole === 'COADMIN') { return true; } else { this.router.navigate(['/loginsocial']); diff --git a/src/app/guard/super-admin.guard.spec.ts b/src/app/guard/super-admin.guard.spec.ts index 6dc76d9f..d5b949a3 100644 --- a/src/app/guard/super-admin.guard.spec.ts +++ b/src/app/guard/super-admin.guard.spec.ts @@ -1,17 +1,70 @@ import { TestBed } from '@angular/core/testing'; -import { CanActivateFn } from '@angular/router'; +import { Router } from '@angular/router'; +import { TokenSuperAdminGuard } from './super-admin.guard'; +import { AuthService } from '../services/auth.service'; +import { UserService } from '../services/user.service'; +import { AlertService } from '../services/alert.service'; +import { RouterTestingModule } from '@angular/router/testing'; -import { superAdminGuard } from './guard/super-admin.guard'; - -describe('superAdminGuard', () => { - const executeGuard: CanActivateFn = (...guardParameters) => - TestBed.runInInjectionContext(() => superAdminGuard(...guardParameters)); +describe('TokenSuperAdminGuard', () => { + let guard: TokenSuperAdminGuard; + let authService: jasmine.SpyObj; + let userService: jasmine.SpyObj; + let alertService: jasmine.SpyObj; + let router: jasmine.SpyObj; beforeEach(() => { - TestBed.configureTestingModule({}); + const authServiceSpy = jasmine.createSpyObj('AuthService', ['isAuthenticated']); + const userServiceSpy = jasmine.createSpyObj('UserService', ['getRoles']); + const alertServiceSpy = jasmine.createSpyObj('AlertService', ['showMessage']); + const routerSpy = jasmine.createSpyObj('Router', ['navigate']); + + TestBed.configureTestingModule({ + imports: [RouterTestingModule], + providers: [ + TokenSuperAdminGuard, + { provide: AuthService, useValue: authServiceSpy }, + { provide: UserService, useValue: userServiceSpy }, + { provide: AlertService, useValue: alertServiceSpy }, + { provide: Router, useValue: routerSpy } + ], + }); + + guard = TestBed.inject(TokenSuperAdminGuard); + authService = TestBed.inject(AuthService) as jasmine.SpyObj; + userService = TestBed.inject(UserService) as jasmine.SpyObj; + alertService = TestBed.inject(AlertService) as jasmine.SpyObj; + router = TestBed.inject(Router) as jasmine.SpyObj; + }); + + it('should allow access if user is authenticated and role is ADMIN', () => { + authService.isAuthenticated.and.returnValue(true); + userService.getRoles.and.returnValue('ADMIN'); + + const result = guard.canActivate({} as any, {} as any); + + expect(result).toBe(true); }); - it('should be created', () => { - expect(executeGuard).toBeTruthy(); + it('should deny access and navigate to /homeAdmin if user is not ADMIN', () => { + authService.isAuthenticated.and.returnValue(true); + userService.getRoles.and.returnValue('USER'); + + const result = guard.canActivate({} as any, {} as any); + + expect(result).toBe(false); + expect(alertService.showMessage).toHaveBeenCalledWith('error', 'Erro', 'Você não possui acesso!'); + expect(router.navigate).toHaveBeenCalledWith(['/homeAdmin']); + }); + + it('should deny access and navigate to /loginsocial if user is not authenticated', () => { + authService.isAuthenticated.and.returnValue(false); + + const result = guard.canActivate({} as any, { url: '/someUrl' } as any); + + expect(result).toBe(false); + expect(alertService.showMessage).toHaveBeenCalledWith('error', 'Erro', 'Você não está logado!'); + expect(router.navigate).toHaveBeenCalledWith(['/loginsocial'], { queryParams: { returnUrl: '/someUrl' } }); }); }); + diff --git a/src/app/guard/super-admin.guard.ts b/src/app/guard/super-admin.guard.ts index aa20f89a..ab3a3dbc 100644 --- a/src/app/guard/super-admin.guard.ts +++ b/src/app/guard/super-admin.guard.ts @@ -1,5 +1,35 @@ -import { CanActivateFn } from '@angular/router'; +import { Injectable } from '@angular/core'; +import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; +import { AuthService } from '../services/auth.service'; +import { UserService } from '../services/user.service'; +import { AlertService } from '../services/alert.service'; -export const superAdminGuard: CanActivateFn = (route, state) => { - return true; -}; +@Injectable({ + providedIn: 'root', +}) +export class TokenSuperAdminGuard implements CanActivate { + constructor( + private authService: AuthService, + private userService: UserService, + private router: Router, + private alertService: AlertService + ) {} + + canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean { + if (this.authService.isAuthenticated()) { + const userRole = this.userService.getRoles(); + + if (userRole === 'ADMIN') { + return true; + } else { + this.alertService.showMessage('error', 'Erro', 'Você não possui acesso!') + this.router.navigate(['/homeAdmin']); + return false; + } + } else { + this.alertService.showMessage('error', 'Erro', 'Você não está logado!') + this.router.navigate(['/loginsocial'], { queryParams: { returnUrl: state.url } }); + return false; + } + } +} \ No newline at end of file From fbc1533526c705ab858d4b414b7462be79ca3e27 Mon Sep 17 00:00:00 2001 From: gabrielhrlima Date: Wed, 21 Aug 2024 16:14:05 -0300 Subject: [PATCH 05/10] Adiciona o componente exclusivo do ADMIN --- .../controle-super-admin.component.css | 123 ++++++++++++++ .../controle-super-admin.component.html | 57 +++++++ .../controle-super-admin.component.spec.ts | 158 ++++++++++++++++++ .../controle-super-admin.component.ts | 79 +++++++++ 4 files changed, 417 insertions(+) create mode 100644 src/app/pages/controle-super-admin/controle-super-admin.component.css create mode 100644 src/app/pages/controle-super-admin/controle-super-admin.component.html create mode 100644 src/app/pages/controle-super-admin/controle-super-admin.component.spec.ts create mode 100644 src/app/pages/controle-super-admin/controle-super-admin.component.ts diff --git a/src/app/pages/controle-super-admin/controle-super-admin.component.css b/src/app/pages/controle-super-admin/controle-super-admin.component.css new file mode 100644 index 00000000..8faa75ee --- /dev/null +++ b/src/app/pages/controle-super-admin/controle-super-admin.component.css @@ -0,0 +1,123 @@ +/* Estilos gerais */ +.home-container { + display: flex; +} + +aside { + width: 13.2em; + background-color: white; + padding: 1em 0.75em; + box-shadow: 0.125em 0 0.3125em rgba(0, 0, 0, 0.1); + text-align: left; + position: fixed; + height: 100%; + margin: 0; +} + +.user-info p { + margin: 0; + font-size: 1.2em; +} + +.linksBarraLateral { + display: flex; + justify-content: space-between; + align-items: center; + margin: 0.75em 0; +} + +.linkLogout, +.linkVoltar { + color: #0087c8; + text-decoration: none; +} + +.linkLogout:hover, +.linkVoltar:hover { + text-decoration: underline; + color: #0056b3; + cursor: pointer; +} + +hr.solid { + border-top: 0.0625em solid #bbb; +} + +nav ul { + list-style: none; + padding: 0; +} + +nav ul li { + margin: 0.9375em 0; +} + +nav ul li a { + text-decoration: none; + color: #1d1d1d; + font-size: 1.1em; +} + +nav ul li a:hover, +nav ul li a.linkSelecionado { + color: #00a550; +} + +main { + flex: 1; + padding: 1em; + margin-left: 14.2em; + display: flex; + flex-direction: column; +} + +header h1 { + font-size: 2.4em; + color: #00a550; + margin-top: 1em; +} + +hr.solid2 { + border-top: 0.125em solid #bbb; +} + +/* Estilos da tabela */ +table { + width: 100%; + border-collapse: collapse; + margin-top: 1em; +} + +thead { + background-color: #00a550; + color: white; +} + +th, +td { + padding: 0.75em; + text-align: left; + border: 1px solid #ddd; +} + +tbody tr:nth-child(even) { + background-color: #f9f9f9; +} + +button { + background-color: #ff4c4c; + color: white; + border: none; + padding: 0.5em 1em; + cursor: pointer; + border-radius: 5px; + margin-right: 0.5em; +} + +.btn-setRole { + background-color: #0087c8; +} + +button:hover { + background-color: #7ad0eb; +} diff --git a/src/app/pages/controle-super-admin/controle-super-admin.component.html b/src/app/pages/controle-super-admin/controle-super-admin.component.html new file mode 100644 index 00000000..779f95e7 --- /dev/null +++ b/src/app/pages/controle-super-admin/controle-super-admin.component.html @@ -0,0 +1,57 @@ +
+ +
+
+

Lista de usuários cadastrados:

+
+
+ + + + + + + + + + + + + + + + + + + + +
NomeVínculoEmailRoleAções
{{ user.name }}{{ user.connection }}{{ user.email }}{{ user.role }} + +
+ + +

Carregando usuários...

+
+
+
diff --git a/src/app/pages/controle-super-admin/controle-super-admin.component.spec.ts b/src/app/pages/controle-super-admin/controle-super-admin.component.spec.ts new file mode 100644 index 00000000..837765f7 --- /dev/null +++ b/src/app/pages/controle-super-admin/controle-super-admin.component.spec.ts @@ -0,0 +1,158 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ControleSuperAdminComponent } from './controle-super-admin.component'; +import { UserService } from 'src/app/services/user.service'; +import { AlertService } from 'src/app/services/alert.service'; +import { ConfirmationService, MessageService } from 'primeng/api'; +import { AuthService } from 'src/app/services/auth.service'; +import { Router } from '@angular/router'; +import { of, throwError } from 'rxjs'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { VideoService } from 'src/app/services/video.service'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Confirmation } from 'primeng/api'; + +class UserServiceMock { + getAllUsers() { + return of({ + body: [{ id: 1, name: 'User 1' }, { id: 2, name: 'User 2' }] + }); + } + + deleteUser(userId: number) { + // Simulate successful user deletion + return of(null); + } +} + +class AlertServiceMock { + showMessage(type: string, title: string, message: string) { + console.log(`[AlertService] ${type.toUpperCase()}: ${title} - ${message}`); + } + + errorMessage(error: any) { + console.error(`[AlertService] ERROR: ${error.status} - ${error.statusText}`); + } +} + +class ConfirmationServiceMock { + confirm(options: any) { + if (options.accept) { + console.log("[ConfirmationService] User accepted the confirmation."); + options.accept(); + } else if (options.reject) { + console.log("[ConfirmationService] User rejected the confirmation."); + options.reject(); + } + } +} + +class AuthServiceMock { + logout() { + console.log("[AuthService] User logged out."); + } +} + +describe('ControleSuperAdminComponent', () => { + let component: ControleSuperAdminComponent; + let fixture: ComponentFixture; + let userService: UserService; + let alertService: AlertService; + let confirmationService: ConfirmationService; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ControleSuperAdminComponent], + imports: [HttpClientTestingModule, RouterTestingModule], + providers: [ + { provide: UserService, useClass: UserServiceMock }, + { provide: AlertService, useClass: AlertServiceMock }, + { provide: ConfirmationService, useClass: ConfirmationServiceMock }, + { provide: AuthService, useClass: AuthServiceMock }, + { provide: VideoService, useClass: VideoService }, + MessageService, + Router + ] + }) + .compileComponents(); + + fixture = TestBed.createComponent(ControleSuperAdminComponent); + component = fixture.componentInstance; + userService = TestBed.inject(UserService); + alertService = TestBed.inject(AlertService); + confirmationService = TestBed.inject(ConfirmationService); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should load users on init', () => { + spyOn(userService, 'getAllUsers').and.callThrough(); + component.ngOnInit(); + expect(userService.getAllUsers).toHaveBeenCalled(); + expect(component.users.length).toBe(2); + }); + + it('should handle error when loading users fails', () => { + const errorResponse = new HttpErrorResponse({ + error: 'Erro de rede', + status: 500, + statusText: 'Erro Interno do Servidor' + }); + spyOn(userService, 'getAllUsers').and.returnValue(throwError(() => errorResponse)); + spyOn(alertService, 'errorMessage').and.callThrough(); + component.loadUsers(); + expect(alertService.errorMessage).toHaveBeenCalledWith(errorResponse); + expect(component.loading).toBeFalse(); + }); + + it('should delete a user and reload users', () => { + spyOn(userService, 'deleteUser').and.callThrough(); + spyOn(component, 'loadUsers').and.callThrough(); + component.deleteUser(1); + expect(userService.deleteUser).toHaveBeenCalledWith(1); + expect(component.loadUsers).toHaveBeenCalled(); + }); + + it('should handle error when deleting user fails', () => { + const errorResponse = new HttpErrorResponse({ + error: 'Erro de rede', + status: 500, + statusText: 'Erro Interno do Servidor' + }); + spyOn(userService, 'deleteUser').and.returnValue(throwError(() => errorResponse)); + spyOn(alertService, 'errorMessage').and.callThrough(); + component.deleteUser(1); + expect(alertService.errorMessage).toHaveBeenCalledWith(errorResponse); + }); + + it('should confirm logout', () => { + spyOn(confirmationService, 'confirm').and.callThrough(); + const authService = TestBed.inject(AuthService); + spyOn(authService, 'logout').and.callThrough(); + + component.logoutUser(); + + expect(confirmationService.confirm).toHaveBeenCalled(); + expect(authService.logout).toHaveBeenCalled(); + }); + + it('should not logout if reject is called', () => { + spyOn(confirmationService, 'confirm').and.callFake((confirmation: Confirmation) => { + if (confirmation.reject) { + confirmation.reject(); + } + return confirmationService; // Retorna o próprio serviço para respeitar o tipo esperado + }); + + const authService = TestBed.inject(AuthService); + spyOn(authService, 'logout').and.callThrough(); + + component.logoutUser(); + + expect(confirmationService.confirm).toHaveBeenCalled(); + expect(authService.logout).not.toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/src/app/pages/controle-super-admin/controle-super-admin.component.ts b/src/app/pages/controle-super-admin/controle-super-admin.component.ts new file mode 100644 index 00000000..3c935930 --- /dev/null +++ b/src/app/pages/controle-super-admin/controle-super-admin.component.ts @@ -0,0 +1,79 @@ +import { Component, OnInit } from '@angular/core'; +import { UserService } from 'src/app/services/user.service'; +import { HttpErrorResponse } from '@angular/common/http'; +import { AlertService } from 'src/app/services/alert.service'; +import { ConfirmationService } from 'primeng/api'; +import { MessageService } from 'primeng/api'; + +import { AuthService } from 'src/app/services/auth.service'; +import { Router } from '@angular/router'; +import { VideoService } from 'src/app/services/video.service'; + +@Component({ + selector: 'app-controle-super-admin', + templateUrl: './controle-super-admin.component.html', + styleUrls: ['./controle-super-admin.component.css'], +}) +export class ControleSuperAdminComponent implements OnInit { + users: any[] = []; + loading: boolean = true; + + constructor( + private videoService: VideoService, + private router: Router, + private authService: AuthService, + private userService: UserService, + private alertService: AlertService, + private confirmationService: ConfirmationService, + private messageService: MessageService + ) {} + + ngOnInit(): void { + this.loadUsers(); + } + + loadUsers() { + this.userService.getAllUsers({}).subscribe({ + next: (response: any) => { + console.log('API response:', response); + this.users = response.body; + this.loading = false; + }, + error: (error: HttpErrorResponse) => { + console.error('Error loading users:', error); + this.loading = false; + this.alertService.errorMessage(error); + }, + }); + } + + deleteUser(userId: any) { + this.userService.deleteUser(userId).subscribe({ + next: () => { + this.alertService.showMessage( + 'success', + 'Sucesso', + 'Usuário excluído com sucesso.' + ); + this.loadUsers(); // Recarrega a lista de usuários após exclusão + }, + error: (error: HttpErrorResponse) => { + console.error('Error deleting user:', error); + this.alertService.errorMessage(error); + }, + }); + } + + logoutUser() { + this.confirmationService.confirm({ + message: 'Tem certeza que deseja sair?', + header: 'Confirmação', + key: 'myDialog', + icon: 'pi pi-exclamation-triangle', + accept: () => { + this.authService.logout(); + }, + reject: () => {}, + }); + } +} From 2ef7304e6fb7ba14f2d2d008e5e367e75eb10787 Mon Sep 17 00:00:00 2001 From: gabrielhrlima Date: Wed, 21 Aug 2024 16:15:08 -0300 Subject: [PATCH 06/10] Adiciona a rota para o componente exclusivo do ADMIN --- src/app/app-routing.module.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d6e71566..038d38fc 100755 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -28,10 +28,11 @@ import { CategoryTableComponent } from './pages/category-table/category-table.co import { VideoViewsComponent } from './pages/video-views/video-views.component'; import { RecordComponent } from './pages/record/record.component'; import { DashboardCategoryComponent } from './pages/dashboard-category/dashboard-category.component'; +import { ControleSuperAdminComponent } from './pages/controle-super-admin/controle-super-admin.component'; import { WithTokenGuard } from './guard/with-token.guard'; import { TokenAdminGuard } from './guard/admin.guard'; -import {TokenSuperAdminGuard} from './guard/super-admin.guard' +import { TokenSuperAdminGuard } from './guard/super-admin.guard'; const routes: Routes = [ { path: '', component: LoginComponent, canActivate: [WithTokenGuard] }, @@ -127,6 +128,11 @@ const routes: Routes = [ component: RecordComponent, canActivate: [AuthGuard], }, + { + path: 'controleSuperAdmin', + component: ControleSuperAdminComponent, + canActivate: [TokenSuperAdminGuard], + }, ]; @NgModule({ From 8fa1471be73bc23eec8e6051957d14dd394d08ab Mon Sep 17 00:00:00 2001 From: Ruan-Carvalho Date: Wed, 21 Aug 2024 16:28:32 -0300 Subject: [PATCH 07/10] Adiciona o link para a pagina exclusiva do ADMIN --- .../category-table.component.html | 1 + .../dashboard-category.component.html | 1 + test-reports/TESTS.xml | 489 ++++++++++-------- 3 files changed, 262 insertions(+), 229 deletions(-) diff --git a/src/app/pages/category-table/category-table.component.html b/src/app/pages/category-table/category-table.component.html index 474864f4..5cda73a6 100644 --- a/src/app/pages/category-table/category-table.component.html +++ b/src/app/pages/category-table/category-table.component.html @@ -13,6 +13,7 @@
  • Dados - Vídeos
  • Dados - Categorias
  • Dashboard - Categorias
  • +
  • Administração de Usuários
  • diff --git a/src/app/pages/dashboard-category/dashboard-category.component.html b/src/app/pages/dashboard-category/dashboard-category.component.html index 3f99126b..3d89799f 100644 --- a/src/app/pages/dashboard-category/dashboard-category.component.html +++ b/src/app/pages/dashboard-category/dashboard-category.component.html @@ -13,6 +13,7 @@
  • Dados - Vídeos
  • Dados - Categorias
  • Dashboard - Categorias
  • +
  • Administração de Usuários
  • diff --git a/test-reports/TESTS.xml b/test-reports/TESTS.xml index ee1e040d..8c381a5e 100644 --- a/test-reports/TESTS.xml +++ b/test-reports/TESTS.xml @@ -1,259 +1,274 @@ - + - - + + - + - - - - + + + + + + + - + - - - - - - + + + + + + - + - - + + - + - - - - + + + + - - + + - - + + - - - - - - - + + + + + + + - - + + - + - - - + + + - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - - - - - - - - + + + + + + + + + + + - + - - - + + + - - - - + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + Date: Wed, 21 Aug 2024 16:39:18 -0300 Subject: [PATCH 08/10] Adiciona o link para a pagina do ADMIN --- .../home-admin/home-admin.component.html | 8 +-- .../video-views/video-views.component.html | 55 +++++++++++++++---- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/app/pages/home-admin/home-admin.component.html b/src/app/pages/home-admin/home-admin.component.html index 0bc84a1c..89fa701a 100644 --- a/src/app/pages/home-admin/home-admin.component.html +++ b/src/app/pages/home-admin/home-admin.component.html @@ -3,22 +3,23 @@ -
    +

    Olá, administrador!

    -
    +
    @@ -33,4 +34,3 @@

    Olá, administrador!

    - diff --git a/src/app/pages/video-views/video-views.component.html b/src/app/pages/video-views/video-views.component.html index 8881ac66..c29d9d2c 100755 --- a/src/app/pages/video-views/video-views.component.html +++ b/src/app/pages/video-views/video-views.component.html @@ -7,39 +7,66 @@ Voltar -
    +
    - +

    Dados - Vídeos

    - +
    -
    +
    - +
    - +
    - +