Skip to content

Commit af672cb

Browse files
author
morteza.khoramdel
committed
add auth
1 parent f7d8538 commit af672cb

3 files changed

Lines changed: 105 additions & 4 deletions

File tree

src/app/guards/auth.guard.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ describe('AuthGuard', () => {
88
let guard: AuthGuard;
99
let authService: AuthService;
1010
let router: Router;
11+
const sessionUserKey = 'dsomm.auth.currentUser';
1112

1213
beforeEach(() => {
1314
TestBed.configureTestingModule({
@@ -17,11 +18,11 @@ describe('AuthGuard', () => {
1718
guard = TestBed.inject(AuthGuard);
1819
authService = TestBed.inject(AuthService);
1920
router = TestBed.inject(Router);
20-
sessionStorage.clear();
21+
sessionStorage.removeItem(sessionUserKey);
2122
});
2223

2324
afterEach(() => {
24-
sessionStorage.clear();
25+
sessionStorage.removeItem(sessionUserKey);
2526
});
2627

2728
it('allows authenticated access to protected routes', () => {
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { NO_ERRORS_SCHEMA } from '@angular/core';
2+
import { ComponentFixture, TestBed } from '@angular/core/testing';
3+
import { ReactiveFormsModule } from '@angular/forms';
4+
import { ActivatedRoute, convertToParamMap, Router } from '@angular/router';
5+
import { RouterTestingModule } from '@angular/router/testing';
6+
import { AuthService } from '../../services/auth.service';
7+
import { LoginComponent } from './login.component';
8+
9+
describe('LoginComponent', () => {
10+
let component: LoginComponent;
11+
let fixture: ComponentFixture<LoginComponent>;
12+
let authService: AuthService;
13+
let router: Router;
14+
let routeStub: { snapshot: { queryParamMap: ReturnType<typeof convertToParamMap> } };
15+
const sessionUserKey = 'dsomm.auth.currentUser';
16+
17+
beforeEach(async () => {
18+
routeStub = {
19+
snapshot: {
20+
queryParamMap: convertToParamMap({}),
21+
},
22+
};
23+
24+
await TestBed.configureTestingModule({
25+
declarations: [LoginComponent],
26+
imports: [ReactiveFormsModule, RouterTestingModule.withRoutes([])],
27+
providers: [{ provide: ActivatedRoute, useValue: routeStub }],
28+
schemas: [NO_ERRORS_SCHEMA],
29+
}).compileComponents();
30+
31+
authService = TestBed.inject(AuthService);
32+
router = TestBed.inject(Router);
33+
sessionStorage.removeItem(sessionUserKey);
34+
});
35+
36+
afterEach(() => {
37+
sessionStorage.removeItem(sessionUserKey);
38+
});
39+
40+
function createComponent(): void {
41+
fixture = TestBed.createComponent(LoginComponent);
42+
component = fixture.componentInstance;
43+
fixture.detectChanges();
44+
}
45+
46+
it('requires username and password before attempting login', () => {
47+
createComponent();
48+
const loginSpy = spyOn(authService, 'login').and.callThrough();
49+
50+
component.login();
51+
52+
expect(component.loginForm.invalid).toBeTrue();
53+
expect(loginSpy).not.toHaveBeenCalled();
54+
});
55+
56+
it('shows a generic error for invalid credentials', () => {
57+
createComponent();
58+
const navigateSpy = spyOn(router, 'navigateByUrl').and.resolveTo(true);
59+
component.loginForm.setValue({ username: 'admin', password: 'wrong-password' });
60+
61+
component.login();
62+
63+
expect(component.loginFailed).toBeTrue();
64+
expect(navigateSpy).not.toHaveBeenCalled();
65+
});
66+
67+
it('logs in and redirects to the DSOMM default page', () => {
68+
createComponent();
69+
const navigateSpy = spyOn(router, 'navigateByUrl').and.resolveTo(true);
70+
component.loginForm.setValue({ username: 'admin', password: 'dsomm-admin' });
71+
72+
component.login();
73+
74+
expect(authService.getCurrentUser()).toBe('admin');
75+
expect(navigateSpy).toHaveBeenCalledOnceWith('/');
76+
});
77+
78+
it('redirects to the originally requested URL after login', () => {
79+
routeStub.snapshot.queryParamMap = convertToParamMap({ returnUrl: '/matrix?team=Team%20A' });
80+
createComponent();
81+
const navigateSpy = spyOn(router, 'navigateByUrl').and.resolveTo(true);
82+
component.loginForm.setValue({ username: 'viewer', password: 'dsomm-view' });
83+
84+
component.login();
85+
86+
expect(navigateSpy).toHaveBeenCalledOnceWith('/matrix?team=Team%20A');
87+
});
88+
89+
it('falls back to the default route for unsafe return URLs', () => {
90+
routeStub.snapshot.queryParamMap = convertToParamMap({ returnUrl: 'https://example.com' });
91+
createComponent();
92+
const navigateSpy = spyOn(router, 'navigateByUrl').and.resolveTo(true);
93+
component.loginForm.setValue({ username: 'auditor', password: 'dsomm-audit' });
94+
95+
component.login();
96+
97+
expect(navigateSpy).toHaveBeenCalledOnceWith('/');
98+
});
99+
});

src/app/services/auth.service.spec.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,16 @@ import { AuthService } from './auth.service';
33

44
describe('AuthService', () => {
55
let service: AuthService;
6+
const sessionUserKey = 'dsomm.auth.currentUser';
67

78
beforeEach(() => {
89
TestBed.configureTestingModule({});
910
service = TestBed.inject(AuthService);
10-
sessionStorage.clear();
11+
sessionStorage.removeItem(sessionUserKey);
1112
});
1213

1314
afterEach(() => {
14-
sessionStorage.clear();
15+
sessionStorage.removeItem(sessionUserKey);
1516
});
1617

1718
it('logs in a static user with valid credentials', () => {

0 commit comments

Comments
 (0)