refs #1867 Add MatDialog to LoginComponent for displaying GlobalStatusComponent on successful login
testing/ogGui-multibranch/pipeline/head This commit looks good
Details
testing/ogGui-multibranch/pipeline/head This commit looks good
Details
parent
bd0135b796
commit
02fbf57384
|
@ -7,9 +7,11 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatDialogModule } from '@angular/material/dialog';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { GlobalStatusComponent } from '../global-status/global-status.component';
|
||||
|
||||
describe('LoginComponent', () => {
|
||||
let component: LoginComponent;
|
||||
|
@ -22,7 +24,7 @@ describe('LoginComponent', () => {
|
|||
};
|
||||
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [LoginComponent],
|
||||
declarations: [LoginComponent, GlobalStatusComponent],
|
||||
imports: [
|
||||
FormsModule,
|
||||
ToastrModule.forRoot(),
|
||||
|
@ -30,6 +32,7 @@ describe('LoginComponent', () => {
|
|||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
MatIconModule,
|
||||
MatDialogModule,
|
||||
TranslateModule.forRoot()
|
||||
],
|
||||
providers: [
|
||||
|
@ -46,101 +49,4 @@ describe('LoginComponent', () => {
|
|||
it('should create', () => {
|
||||
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: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c', 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');
|
||||
});
|
||||
});
|
|
@ -5,6 +5,8 @@ import { TranslateService } from '@ngx-translate/core';
|
|||
import { ToastrService } from "ngx-toastr";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
import { ConfigService } from '@services/config.service';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { GlobalStatusComponent } from '../global-status/global-status.component'
|
||||
|
||||
@Component({
|
||||
selector: 'app-login',
|
||||
|
@ -27,7 +29,8 @@ export class LoginComponent {
|
|||
private router: Router,
|
||||
private configService: ConfigService,
|
||||
private toastService: ToastrService,
|
||||
private translateService: TranslateService
|
||||
private translateService: TranslateService,
|
||||
private dialog: MatDialog
|
||||
) {
|
||||
this.baseUrl = this.configService.apiUrl;
|
||||
const savedLanguage = localStorage.getItem('language') || 'es';
|
||||
|
@ -67,6 +70,10 @@ export class LoginComponent {
|
|||
|
||||
this.openSnackBar(false, 'Bienvenido ' + this.loginObj.username);
|
||||
this.router.navigateByUrl('/groups');
|
||||
this.dialog.open(GlobalStatusComponent, {
|
||||
width: '45vw',
|
||||
height: '80vh',
|
||||
});
|
||||
}
|
||||
this.isLoading = false;
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue