Fix some test for coverage and changelog
testing/ogGui-multibranch/pipeline/head This commit is unstable Details

pull/7/head
Alvaro Puente Mella 2024-11-21 12:29:39 +01:00
parent 5962c2e051
commit 6b35bbe9d9
6 changed files with 236 additions and 25 deletions

View File

@ -22,6 +22,7 @@
- Made predefined commands read-only to prevent accidental modifications. - Made predefined commands read-only to prevent accidental modifications.
- Simplified the task creation modal to enhance user experience. - Simplified the task creation modal to enhance user experience.
- Adjusted the translation system to cover new elements and improve consistency (work in progress). - Adjusted the translation system to cover new elements and improve consistency (work in progress).
- New element view from clients on groups main view
### Fixed ### Fixed
- Resolved an issue that prevented editing software profiles correctly. - Resolved an issue that prevented editing software profiles correctly.

View File

@ -3,11 +3,13 @@ import { RouterTestingModule } from '@angular/router/testing';
import { AdminComponent } from './admin.component'; import { AdminComponent } from './admin.component';
import { MatButtonModule } from '@angular/material/button'; import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { Router } from '@angular/router';
describe('AdminComponent', () => { describe('AdminComponent', () => {
let component: AdminComponent; let component: AdminComponent;
let fixture: ComponentFixture<AdminComponent>; let fixture: ComponentFixture<AdminComponent>;
let router: Router;
beforeEach(async () => { beforeEach(async () => {
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
@ -16,9 +18,11 @@ describe('AdminComponent', () => {
RouterTestingModule, RouterTestingModule,
MatButtonModule, MatButtonModule,
MatIconModule, MatIconModule,
TranslateModule.forRoot() TranslateModule.forRoot()
] ]
}).compileComponents(); }).compileComponents();
router = TestBed.inject(Router);
}); });
beforeEach(() => { beforeEach(() => {
@ -30,4 +34,24 @@ describe('AdminComponent', () => {
it('debería crear el componente', () => { it('debería crear el componente', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('debería renderizar dos botones', () => {
const buttons = fixture.nativeElement.querySelectorAll('button');
expect(buttons.length).toBe(2);
});
it('debería tener un botón con routerLink a "/users"', () => {
const button = fixture.nativeElement.querySelector('button[routerLink="/users"]');
expect(button).toBeTruthy();
expect(button.querySelector('mat-icon').textContent.trim()).toBe('group');
});
it('debería aplicar la clase "fab-button" a ambos botones', () => {
const buttons = fixture.nativeElement.querySelectorAll('button');
buttons.forEach((button: HTMLElement) => {
expect(button.classList).toContain('fab-button');
});
});
}); });

View File

@ -51,4 +51,18 @@ describe('RolesComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should have a default itemsPerPage value', () => {
expect(component.itemsPerPage).toBeDefined();
});
it('should initialize the dataSource', () => {
expect(component.dataSource).toBeDefined();
});
it('should have a defined columns array', () => {
expect(component.columns).toBeDefined();
expect(component.columns.length).toBeGreaterThan(0);
});
}); });

View File

@ -8,15 +8,9 @@ import { of } from 'rxjs';
import { NO_ERRORS_SCHEMA } from '@angular/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
class MockUserService { class MockToastrService {
getUsers() { success() {}
return of({ error() {}
'hydra:member': [
{ id: 1, username: 'user1', allowedOrganizationalUnits: [], roles: ['admin'] },
{ id: 2, username: 'user2', allowedOrganizationalUnits: [], roles: ['user'] }
]
});
}
} }
describe('UsersComponent', () => { describe('UsersComponent', () => {
@ -30,15 +24,13 @@ describe('UsersComponent', () => {
MatTableModule, MatTableModule,
MatDialogModule, MatDialogModule,
HttpClientTestingModule, HttpClientTestingModule,
TranslateModule.forRoot() TranslateModule.forRoot(),
], ],
providers: [ providers: [
{ useClass: MockUserService }, { provide: ToastrService, useClass: MockToastrService },
{ provide: ToastrService, useValue: { success: () => {} } },
], ],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA], // Ignorar elementos desconocidos
}) }).compileComponents();
.compileComponents();
fixture = TestBed.createComponent(UsersComponent); fixture = TestBed.createComponent(UsersComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
@ -49,4 +41,27 @@ describe('UsersComponent', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should have default values for pagination', () => {
expect(component.itemsPerPage).toBe(10);
expect(component.page).toBe(0);
expect(component.pageSizeOptions).toEqual([5, 10, 20, 40, 100]);
});
it('should call search on init', () => {
spyOn(component, 'search');
component.ngOnInit();
expect(component.search).toHaveBeenCalled();
});
it('should initialize the dataSource', () => {
expect(component.dataSource).toBeDefined();
});
it('should define displayedColumns', () => {
expect(component.displayedColumns).toBeDefined();
expect(component.displayedColumns).toContain('id');
expect(component.displayedColumns).toContain('username');
expect(component.displayedColumns).toContain('roles');
expect(component.displayedColumns).toContain('actions');
});
}); });

View File

@ -8,6 +8,7 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input'; import { MatInputModule } from '@angular/material/input';
import { MatIconModule } from '@angular/material/icon'; import { MatIconModule } from '@angular/material/icon';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { of, throwError } from 'rxjs';
describe('LoginComponent', () => { describe('LoginComponent', () => {
let component: LoginComponent; let component: LoginComponent;
@ -18,17 +19,16 @@ describe('LoginComponent', () => {
declarations: [LoginComponent], declarations: [LoginComponent],
imports: [ imports: [
FormsModule, FormsModule,
ToastrModule.forRoot(), ToastrModule.forRoot(),
BrowserAnimationsModule, BrowserAnimationsModule,
MatFormFieldModule, MatFormFieldModule,
MatInputModule, MatInputModule,
MatIconModule, MatIconModule,
TranslateModule.forRoot() TranslateModule.forRoot()
], ],
providers: [provideHttpClient(withInterceptorsFromDi())] providers: [provideHttpClient(withInterceptorsFromDi())]
}) }).compileComponents();
.compileComponents();
fixture = TestBed.createComponent(LoginComponent); fixture = TestBed.createComponent(LoginComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
fixture.detectChanges(); fixture.detectChanges();
@ -37,4 +37,101 @@ describe('LoginComponent', () => {
it('should create', () => { it('should create', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should disable the login button if username or password is missing', () => {
component.loginObj.username = '';
component.loginObj.password = '';
fixture.detectChanges();
const button = fixture.nativeElement.querySelector('button[type="submit"]');
expect(button.disabled).toBeTruthy();
});
it('should enable the login button if username and password are present', () => {
component.loginObj.username = 'testUser';
component.loginObj.password = 'testPass';
fixture.detectChanges();
const button = fixture.nativeElement.querySelector('button[type="submit"]');
expect(button.disabled).toBeFalsy();
});
it('should call onLogin and navigate on successful login', () => {
const mockRouter = spyOn(component['router'], 'navigateByUrl');
const mockHttp = spyOn(component['http'], 'post').and.returnValue(of({ token: '123', refreshToken: '456' }));
component.loginObj.username = 'testUser';
component.loginObj.password = 'testPass';
component.onLogin();
expect(mockHttp).toHaveBeenCalledWith(`${component.baseUrl}/auth/login`, component.loginObj);
expect(mockRouter).toHaveBeenCalledWith('/groups');
});
it('should show error message on login failure', () => {
const mockToast = spyOn(component['toastService'], 'error');
const mockHttp = spyOn(component['http'], 'post').and.returnValue(throwError({ error: { message: 'Invalid credentials' } }));
component.loginObj.username = 'testUser';
component.loginObj.password = 'testPass';
component.onLogin();
expect(mockHttp).toHaveBeenCalled();
expect(mockToast).toHaveBeenCalledWith('Error al iniciar sesión: Invalid credentials', 'Error');
});
it('should change language to Spanish and save to localStorage', () => {
const mockTranslate = spyOn(component['translateService'], 'use');
component.changeLanguage('es');
expect(localStorage.getItem('language')).toBe('es');
expect(mockTranslate).toHaveBeenCalledWith('es');
});
it('should change language to English and save to localStorage', () => {
const mockTranslate = spyOn(component['translateService'], 'use');
component.changeLanguage('en');
expect(localStorage.getItem('language')).toBe('en');
expect(mockTranslate).toHaveBeenCalledWith('en');
});
it('should toggle password visibility when clicking the button', () => {
const initialHideState = component.hide();
const button = fixture.nativeElement.querySelector('button[mat-icon-button]');
button.click();
expect(component.hide()).toBe(!initialHideState);
});
it('should add "invalid" class to username input if it is invalid and touched', () => {
const usernameInput = fixture.nativeElement.querySelector('input[name="username"]');
usernameInput.value = ''; // Empty value makes it invalid
usernameInput.dispatchEvent(new Event('input'));
usernameInput.dispatchEvent(new Event('blur')); // Simulates "touched"
fixture.detectChanges();
expect(usernameInput.classList).toContain('invalid');
});
it('should add rotating class to the logo when loading', () => {
component.isLoading = true;
fixture.detectChanges();
const logo = fixture.nativeElement.querySelector('.login-logo');
expect(logo.classList).toContain('rotating');
});
it('should not add rotating class to the logo when not loading', () => {
component.isLoading = false;
fixture.detectChanges();
const logo = fixture.nativeElement.querySelector('.login-logo');
expect(logo.classList).not.toContain('rotating');
});
it('should show a success toast message', () => {
const mockToast = spyOn(component['toastService'], 'success');
component.openSnackBar(false, 'Welcome!');
expect(mockToast).toHaveBeenCalledWith('Welcome!', 'Éxito');
});
it('should show an error toast message', () => {
const mockToast = spyOn(component['toastService'], 'error');
component.openSnackBar(true, 'Something went wrong');
expect(mockToast).toHaveBeenCalledWith('Something went wrong', 'Error');
});
}); });

View File

@ -69,4 +69,64 @@ describe('PxeComponent', () => {
it('should create the component', () => { it('should create the component', () => {
expect(component).toBeTruthy(); expect(component).toBeTruthy();
}); });
it('should have a defined component', () => {
expect(component).toBeDefined();
});
it('should have a defined baseUrl', () => {
expect(component.baseUrl).toBeDefined();
});
it('should have a defined pxeTemplates', () => {
expect(component.pxeTemplates).toBeDefined();
});
it('should have a defined currentPage', () => {
expect(component.currentPage).toBeDefined();
});
it('should have a defined dataSource', () => {
expect(component.dataSource).toBeDefined();
});
it('should have a defined length', () => {
expect(component.length).toBeDefined();
});
it('should have a defined itemsPerPage', () => {
expect(component.itemsPerPage).toBeDefined();
});
it('should have a defined page', () => {
expect(component.page).toBeDefined();
});
it('should have a defined pageSizeOptions', () => {
expect(component.pageSizeOptions).toBeDefined();
});
it('should have a defined selectedElements', () => {
expect(component.selectedElements).toBeDefined();
});
it('should have a defined loading', () => {
expect(component.loading).toBeDefined();
});
it('should have a defined filters', () => {
expect(component.filters).toBeDefined();
});
it('should have a defined alertMessage', () => {
expect(component.alertMessage).toBeDefined();
});
it('should have a defined datePipe', () => {
expect(component.datePipe).toBeDefined();
});
it('should have a defined selectedItem', () => {
expect(component.selectedItem).toBeDefined();
});
}); });