Skip to content
Snippets Groups Projects
Commit c83d1956 authored by OZGCloud's avatar OZGCloud
Browse files

Merge pull request 'OZG-4321-Login' (#443) from OZG-4321-Login into master

parents 05e212c1 76a60043
No related branches found
No related tags found
No related merge requests found
Showing
with 184 additions and 306 deletions
...@@ -49,3 +49,5 @@ testem.log ...@@ -49,3 +49,5 @@ testem.log
.DS_Store .DS_Store
Thumbs.db Thumbs.db
.angular
<ng-container *ngIf="(apiRoot$ | async)?.resource as apiRoot"> <ng-container *ngIf="(apiRootStateResource$ | async)?.resource as apiRoot">
<header class="flex items-center justify-between bg-white p-6" data-test-id="admin-header"> <header class="flex items-center justify-between bg-white p-6" data-test-id="admin-header">
<div class="text-ozgblue font-extrabold">OZG-Cloud Administration</div> <div class="text-ozgblue font-extrabold">OZG-Cloud Administration</div>
<div> <div>
......
...@@ -3,7 +3,7 @@ import { RouterTestingModule } from '@angular/router/testing'; ...@@ -3,7 +3,7 @@ import { RouterTestingModule } from '@angular/router/testing';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { AuthService } from '../common/auth/auth.service'; import { AuthService } from '../common/auth/auth.service';
import { Mock, mock, existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils'; import { Mock, mock, existsAsHtmlElement, notExistsAsHtmlElement } from '@alfa-client/test-utils';
import { ApiRootService } from '@alfa-client/api-root-shared'; import { ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared';
import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
import { createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared'; import { createEmptyStateResource, createStateResource } from '@alfa-client/tech-shared';
import { of } from 'rxjs'; import { of } from 'rxjs';
...@@ -11,6 +11,7 @@ import { createApiRootResource } from 'libs/api-root-shared/test/api-root'; ...@@ -11,6 +11,7 @@ import { createApiRootResource } from 'libs/api-root-shared/test/api-root';
import { MockComponent } from 'ng-mocks'; import { MockComponent } from 'ng-mocks';
import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component'; import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component';
import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navigation-item/postfach-navigation-item.component'; import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navigation-item/postfach-navigation-item.component';
import { Router } from '@angular/router';
describe('AppComponent', () => { describe('AppComponent', () => {
let component: AppComponent; let component: AppComponent;
...@@ -21,7 +22,12 @@ describe('AppComponent', () => { ...@@ -21,7 +22,12 @@ describe('AppComponent', () => {
const userProfileButton: string = getDataTestIdOf('user-profile-button'); const userProfileButton: string = getDataTestIdOf('user-profile-button');
const postfachNavigationItem: string = getDataTestIdOf('postfach-navigation-item'); const postfachNavigationItem: string = getDataTestIdOf('postfach-navigation-item');
const authService: Mock<AuthService> = mock(AuthService); const authService: Mock<AuthService> = {
...mock(AuthService),
login: jest.fn().mockResolvedValue(Promise.resolve()),
};
const router: Mock<Router> = mock(Router);
const apiRootService: Mock<ApiRootService> = mock(ApiRootService); const apiRootService: Mock<ApiRootService> = mock(ApiRootService);
beforeEach(async () => { beforeEach(async () => {
...@@ -41,6 +47,10 @@ describe('AppComponent', () => { ...@@ -41,6 +47,10 @@ describe('AppComponent', () => {
provide: ApiRootService, provide: ApiRootService,
useValue: apiRootService, useValue: apiRootService,
}, },
{
provide: Router,
useValue: router,
},
], ],
}).compileComponents(); }).compileComponents();
}); });
...@@ -65,10 +75,10 @@ describe('AppComponent', () => { ...@@ -65,10 +75,10 @@ describe('AppComponent', () => {
}); });
it('should call doAfterLoggedIn', async () => { it('should call doAfterLoggedIn', async () => {
authService.login.mockImplementation(() => Promise.resolve());
component.doAfterLoggedIn = jest.fn(); component.doAfterLoggedIn = jest.fn();
await component.ngOnInit(); component.ngOnInit();
await fixture.whenStable();
expect(component.doAfterLoggedIn).toHaveBeenCalled(); expect(component.doAfterLoggedIn).toHaveBeenCalled();
}); });
...@@ -79,18 +89,24 @@ describe('AppComponent', () => { ...@@ -79,18 +89,24 @@ describe('AppComponent', () => {
expect(apiRootService.getApiRoot).toHaveBeenCalled(); expect(apiRootService.getApiRoot).toHaveBeenCalled();
}); });
it('should navigate to default route', () => {
component.doAfterLoggedIn();
expect(router.navigate).toHaveBeenCalledWith(['/']);
});
}); });
}); });
it('show not show header if apiRoot is not loaded', () => { it('show not show header if apiRoot is not loaded', () => {
component.apiRoot$ = of(createEmptyStateResource()); component.apiRootStateResource$ = of(createEmptyStateResource<ApiRootResource>());
notExistsAsHtmlElement(fixture, adminHeader); notExistsAsHtmlElement(fixture, adminHeader);
}); });
describe('user profile button', () => { describe('user profile button', () => {
beforeEach(() => { beforeEach(() => {
component.apiRoot$ = of(createStateResource(createApiRootResource())); component.apiRootStateResource$ = of(createStateResource(createApiRootResource()));
}); });
it('should show if apiRoot exists', () => { it('should show if apiRoot exists', () => {
...@@ -102,7 +118,7 @@ describe('AppComponent', () => { ...@@ -102,7 +118,7 @@ describe('AppComponent', () => {
describe('navigation', () => { describe('navigation', () => {
beforeEach(() => { beforeEach(() => {
component.apiRoot$ = of(createStateResource(createApiRootResource())); component.apiRootStateResource$ = of(createStateResource(createApiRootResource()));
}); });
it('should have postfach item', () => { it('should have postfach item', () => {
fixture.detectChanges(); fixture.detectChanges();
...@@ -113,7 +129,7 @@ describe('AppComponent', () => { ...@@ -113,7 +129,7 @@ describe('AppComponent', () => {
describe('build version', () => { describe('build version', () => {
beforeEach(() => { beforeEach(() => {
component.apiRoot$ = of(createStateResource(createApiRootResource())); component.apiRootStateResource$ = of(createStateResource(createApiRootResource()));
}); });
it('should show after apiRoot loaded', () => { it('should show after apiRoot loaded', () => {
......
import { ApiRootService } from '@alfa-client/api-root-shared'; import { ApiRootResource, ApiRootService } from '@alfa-client/api-root-shared';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { AuthService } from '../common/auth/auth.service'; import { StateResource } from '@alfa-client/tech-shared';
import { Router } from '@angular/router';
import { AuthenticationService } from 'libs/authentication/src/lib/authentication.service';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
...@@ -11,18 +13,20 @@ import { AuthService } from '../common/auth/auth.service'; ...@@ -11,18 +13,20 @@ import { AuthService } from '../common/auth/auth.service';
export class AppComponent implements OnInit { export class AppComponent implements OnInit {
readonly title = 'admin'; readonly title = 'admin';
public apiRoot$: Observable<any>; public apiRootStateResource$: Observable<StateResource<ApiRootResource>>;
constructor( constructor(
public authService: AuthService, public authenticationService: AuthenticationService,
private apiRootService: ApiRootService, private apiRootService: ApiRootService,
private router: Router,
) {} ) {}
public async ngOnInit(): Promise<void> { ngOnInit(): void {
await this.authService.login().then(() => this.doAfterLoggedIn()); this.authenticationService.login().then(() => this.doAfterLoggedIn());
} }
doAfterLoggedIn(): void { doAfterLoggedIn(): void {
this.apiRoot$ = this.apiRootService.getApiRoot(); this.apiRootStateResource$ = this.apiRootService.getApiRoot();
this.router.navigate(['/']);
} }
} }
import { Environment } from '@alfa-client/environment-shared';
import { KeycloakService } from 'keycloak-angular';
export function initializeKeycloak(keycloak: KeycloakService, envConfig: Environment) {
return () =>
keycloak.init({
config: {
url: envConfig.authServer,
realm: envConfig.realm,
clientId: envConfig.clientId,
},
initOptions: {
adapter: 'default',
checkLoginIframe: false,
enableLogging: true,
scope: 'offline_access',
onLoad: 'login-required',
silentCheckSsoRedirectUri: window.location.origin + '/assets/silent-check-sso.html',
silentCheckSsoFallback: true,
},
updateMinValidity: 1,
bearerExcludedUrls: ['/assets', '/clients/public'],
});
}
import { ApiRootModule } from '@alfa-client/api-root-shared'; import { ApiRootModule } from '@alfa-client/api-root-shared';
import { ENVIRONMENT_CONFIG, EnvironmentModule } from '@alfa-client/environment-shared'; import { EnvironmentModule } from '@alfa-client/environment-shared';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { HttpClientModule } from '@angular/common/http'; import { HTTP_INTERCEPTORS, HttpClientModule } from '@angular/common/http';
import { APP_INITIALIZER, NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'; import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { RouterModule } from '@angular/router'; import { RouterModule } from '@angular/router';
...@@ -11,16 +11,16 @@ import { StoreRouterConnectingModule } from '@ngrx/router-store'; ...@@ -11,16 +11,16 @@ import { StoreRouterConnectingModule } from '@ngrx/router-store';
import { StoreModule } from '@ngrx/store'; import { StoreModule } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools'; import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { TestbtnComponent } from 'design-system'; import { TestbtnComponent } from 'design-system';
import { KeycloakAngularModule, KeycloakService } from 'keycloak-angular';
import { environment } from '../environments/environment'; import { environment } from '../environments/environment';
import { AppComponent } from './app.component'; import { AppComponent } from './app.component';
import { initializeKeycloak } from './app.config';
import { appRoutes } from './app.routes'; import { appRoutes } from './app.routes';
import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component'; import { PostfachPageComponent } from '../pages/postfach/postfach-page/postfach-page.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component'; import { UserProfileButtonContainerComponent } from '../common/user-profile-button-container/user-profile.button-container.component';
import { AdminSettingsModule } from '@admin-client/admin-settings'; import { AdminSettingsModule } from '@admin-client/admin-settings';
import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navigation-item/postfach-navigation-item.component'; import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navigation-item/postfach-navigation-item.component';
import { OAuthModule } from 'angular-oauth2-oidc';
import { HttpUnauthorizedInterceptor } from 'libs/authentication/src/lib/http-unauthorized.interceptor';
@NgModule({ @NgModule({
declarations: [ declarations: [
...@@ -36,7 +36,6 @@ import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navi ...@@ -36,7 +36,6 @@ import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navi
BrowserModule, BrowserModule,
BrowserAnimationsModule, BrowserAnimationsModule,
HttpClientModule, HttpClientModule,
KeycloakAngularModule,
ApiRootModule, ApiRootModule,
EnvironmentModule, EnvironmentModule,
environment.production ? [] : StoreDevtoolsModule.instrument(), environment.production ? [] : StoreDevtoolsModule.instrument(),
...@@ -46,13 +45,17 @@ import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navi ...@@ -46,13 +45,17 @@ import { PostfachNavigationItemComponent } from '../pages/postfach/postfach-navi
FormsModule, FormsModule,
ReactiveFormsModule, ReactiveFormsModule,
AdminSettingsModule, AdminSettingsModule,
OAuthModule.forRoot({
resourceServer: {
sendAccessToken: true,
},
}),
], ],
providers: [ providers: [
{ {
provide: APP_INITIALIZER, provide: HTTP_INTERCEPTORS,
useFactory: initializeKeycloak, useClass: HttpUnauthorizedInterceptor,
multi: true, multi: true,
deps: [KeycloakService, ENVIRONMENT_CONFIG],
}, },
], ],
bootstrap: [AppComponent], bootstrap: [AppComponent],
......
import { Mock, mock, useFromMock } from '@alfa-client/test-utils';
import { AuthService } from './auth.service';
import { KeycloakService, KeycloakEvent, KeycloakEventType } from 'keycloak-angular';
import { of } from 'rxjs';
import { KeycloakProfile } from 'keycloak-js';
import { StateResource, createStateResource } from '@alfa-client/tech-shared';
import { UserProfileResource } from '@alfa-client/user-profile-shared';
import { createUserProfileResource } from '../../../../../libs/user-profile-shared/test/user-profile';
describe('AuthService', () => {
let service: AuthService;
let keycloakService: Mock<KeycloakService>;
const event: KeycloakEvent = <any>{};
beforeEach(() => {
keycloakService = { ...mock(KeycloakService), keycloakEvents$: <any>of(event) };
service = new AuthService(useFromMock(keycloakService));
});
describe('listenToKeycloakEvent', () => {
it('should call handleEvent', () => {
service.handleEvent = jest.fn();
service.listenToKeycloakEvent();
expect(service.handleEvent).toHaveBeenCalledWith(event);
});
});
describe('handleEvent', () => {
describe('on token expired event', () => {
const tokenExpiredEvent: KeycloakEvent = { type: KeycloakEventType.OnTokenExpired };
it('should updateToken', () => {
service.handleEvent(tokenExpiredEvent);
expect(keycloakService.updateToken).toHaveBeenCalledWith(10);
});
it('should call handleTokenExpireEvent', async () => {
const updateTokenReturnValue: boolean = true;
service.handleTokenExpiredEvent = jest.fn();
keycloakService.updateToken.mockImplementation(() =>
Promise.resolve(updateTokenReturnValue),
);
await service.handleEvent(tokenExpiredEvent);
expect(service.handleTokenExpiredEvent).toHaveBeenCalledWith(updateTokenReturnValue);
});
});
});
describe('handleTokenExpiredEvent', () => {
it('should getToken if refresh was success', () => {
service.handleTokenExpiredEvent(true);
expect(keycloakService.getToken).toHaveBeenCalled();
});
it('should store token', async () => {
const token: string = 'tokenDummy';
service.storeAccessToken = jest.fn();
keycloakService.getToken.mockImplementation(() => Promise.resolve(token));
await service.handleTokenExpiredEvent(true);
expect(service.storeAccessToken).toHaveBeenCalledWith(token);
});
});
describe('login', () => {
it('should call isLoggedIn', () => {
service.login();
expect(keycloakService.isLoggedIn());
});
describe('after loggedIn', () => {
const isLoggedIn: boolean = true;
beforeEach(() => {
keycloakService.isLoggedIn.mockImplementation(() => Promise.resolve(isLoggedIn));
service.setCurrentUser = jest.fn();
});
it('should store token', async () => {
const token: string = 'tokenDummy';
keycloakService.getToken.mockImplementation(() => Promise.resolve(token));
service.storeAccessToken = jest.fn();
await service.login();
expect(service.storeAccessToken).toHaveBeenCalledWith(token);
});
it('should set currentUser', async () => {
await service.login();
expect(service.setCurrentUser).toHaveBeenCalled();
});
});
describe('if not logged in yet', () => {
it('should call login', async () => {
const isLoggedIn: boolean = false;
keycloakService.isLoggedIn.mockImplementation(() => Promise.resolve(isLoggedIn));
await service.login();
expect(keycloakService.login).toHaveBeenCalledWith({ scope: 'offline_access' });
});
});
});
describe('store access token', () => {
it('should put token in sessionStorage', () => {
const token: string = 'tokenDummy';
service.storeAccessToken(token);
const accessTokenInSessionStorage: string = sessionStorage.getItem('access_token');
expect(accessTokenInSessionStorage).toStrictEqual(token);
});
});
describe('logout', () => {
it('should call keycloakservice logout', () => {
service.logout();
expect(keycloakService.logout).toHaveBeenCalled();
});
});
describe('set current user', () => {
it('should load user profile', () => {
service.setCurrentUser();
expect(keycloakService.loadUserProfile).toHaveBeenCalled();
});
it('should update current user state resource', async () => {
const profile: KeycloakProfile = { firstName: 'blubb', lastName: 'blabb' };
keycloakService.loadUserProfile.mockImplementation(() => Promise.resolve(profile));
await service.setCurrentUser();
expect(service.currentUserStateResource()).toEqual(createStateResource(profile));
});
});
describe('getCurrentUserInitials', () => {
it('should return currentUserStateResource', () => {
const userProfile: UserProfileResource = createUserProfileResource();
const userStateResource: StateResource<UserProfileResource> =
createStateResource(userProfile);
service.currentUserStateResource.set(userStateResource);
const currentUserInitials: string = service.getCurrentUserInitials();
const initials: string =
userProfile.firstName.substring(0, 1) + '' + userProfile.lastName.substring(0, 1);
expect(currentUserInitials).toEqual(initials);
});
});
});
import {
StateResource,
createEmptyStateResource,
createStateResource,
} from '@alfa-client/tech-shared';
import { Injectable, WritableSignal, signal } from '@angular/core';
import { KeycloakEvent, KeycloakEventType, KeycloakService } from 'keycloak-angular';
import { KeycloakProfile } from 'keycloak-js';
import { UserProfileResource } from 'libs/user-profile-shared/src/lib/user-profile.model';
import { getUserNameInitials } from 'libs/user-profile-shared/src/lib/user-profile.util';
@Injectable({ providedIn: 'root' })
export class AuthService {
currentUserStateResource: WritableSignal<StateResource<UserProfileResource>> = signal<
StateResource<UserProfileResource>
>(createEmptyStateResource());
public isLoggedIn = false;
constructor(private keycloak: KeycloakService) {
this.listenToKeycloakEvent();
}
listenToKeycloakEvent(): void {
this.keycloak.keycloakEvents$.subscribe((event: KeycloakEvent) => this.handleEvent(event));
}
async handleEvent(event: KeycloakEvent): Promise<void> {
if (event.type === KeycloakEventType.OnTokenExpired) {
await this.keycloak
.updateToken(10)
.then((refreshed) => this.handleTokenExpiredEvent(refreshed));
}
}
async handleTokenExpiredEvent(refreshed: boolean): Promise<void> {
if (refreshed) {
await this.keycloak.getToken().then((token) => this.storeAccessToken(token));
}
}
public async login(): Promise<void> {
this.isLoggedIn = await this.keycloak.isLoggedIn();
if (this.isLoggedIn) {
const token: string = await this.keycloak.getToken();
this.storeAccessToken(token);
await this.setCurrentUser();
} else {
this.keycloak.login({ scope: 'offline_access' });
}
}
storeAccessToken(token: string): void {
sessionStorage.setItem('access_token', token);
}
async setCurrentUser(): Promise<void> {
const profile: KeycloakProfile = await this.keycloak.loadUserProfile();
this.currentUserStateResource.set(createStateResource(this.buildUserProfileResource(profile)));
}
private buildUserProfileResource(profile: KeycloakProfile): UserProfileResource {
return <any>{
firstName: profile.firstName,
lastName: profile.lastName,
};
}
public logout(): void {
this.keycloak.logout();
}
public getCurrentUserInitials(): string {
return getUserNameInitials(this.currentUserStateResource().resource);
}
}
<div class="dropdown"> <div class="dropdown">
<button (click)="showDropDown()" class="dropbtn" data-test-id="drop-down-button">{{ currentUserInitials }}</button> <button (click)="showDropDown()" class="dropbtn" data-test-id="drop-down-button">
{{ currentUserInitials }}
</button>
<div id="myDropdown" class="dropdown-content"> <div id="myDropdown" class="dropdown-content">
<span style="cursor: pointer" (click)="authService.logout()" data-test-id="logout">Abmelden</span> <span style="cursor: pointer" (click)="authenticationService.logout()" data-test-id="logout"
>Abmelden</span
>
</div> </div>
</div> </div>
...@@ -6,15 +6,15 @@ import { ...@@ -6,15 +6,15 @@ import {
} from '@alfa-client/test-utils'; } from '@alfa-client/test-utils';
import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { AuthService } from '../auth/auth.service';
import { UserProfileButtonContainerComponent } from './user-profile.button-container.component'; import { UserProfileButtonContainerComponent } from './user-profile.button-container.component';
import { getDataTestIdOf } from 'libs/tech-shared/test/data-test'; import { getDataTestIdOf } from 'libs/tech-shared/test/data-test';
import { AuthenticationService } from 'authentication';
describe('UserProfileButtonContainerComponent', () => { describe('UserProfileButtonContainerComponent', () => {
let component: UserProfileButtonContainerComponent; let component: UserProfileButtonContainerComponent;
let fixture: ComponentFixture<UserProfileButtonContainerComponent>; let fixture: ComponentFixture<UserProfileButtonContainerComponent>;
const authService: Mock<AuthService> = mock(AuthService); const authenticationService: Mock<AuthenticationService> = mock(AuthenticationService);
const dropDownButton: string = getDataTestIdOf('drop-down-button'); const dropDownButton: string = getDataTestIdOf('drop-down-button');
const logout: string = getDataTestIdOf('logout'); const logout: string = getDataTestIdOf('logout');
...@@ -25,8 +25,8 @@ describe('UserProfileButtonContainerComponent', () => { ...@@ -25,8 +25,8 @@ describe('UserProfileButtonContainerComponent', () => {
imports: [RouterTestingModule], imports: [RouterTestingModule],
providers: [ providers: [
{ {
provide: AuthService, provide: AuthenticationService,
useValue: authService, useValue: authenticationService,
}, },
], ],
}).compileComponents(); }).compileComponents();
...@@ -46,7 +46,7 @@ describe('UserProfileButtonContainerComponent', () => { ...@@ -46,7 +46,7 @@ describe('UserProfileButtonContainerComponent', () => {
it('should call authService to get current user initials', () => { it('should call authService to get current user initials', () => {
component.ngOnInit(); component.ngOnInit();
expect(authService.getCurrentUserInitials).toHaveBeenCalled(); expect(authenticationService.getCurrentUserInitials).toHaveBeenCalled();
}); });
}); });
...@@ -66,7 +66,7 @@ describe('UserProfileButtonContainerComponent', () => { ...@@ -66,7 +66,7 @@ describe('UserProfileButtonContainerComponent', () => {
fixture.detectChanges(); fixture.detectChanges();
const buttonElement: HTMLElement = getElementFromFixture(fixture, dropDownButton); const buttonElement: HTMLElement = getElementFromFixture(fixture, dropDownButton);
expect(buttonElement.textContent).toEqual('AV'); expect(buttonElement.textContent.trim()).toEqual('AV');
}); });
}); });
...@@ -74,7 +74,7 @@ describe('UserProfileButtonContainerComponent', () => { ...@@ -74,7 +74,7 @@ describe('UserProfileButtonContainerComponent', () => {
it('should call authService logout', () => { it('should call authService logout', () => {
dispatchEventFromFixture(fixture, logout, 'click'); dispatchEventFromFixture(fixture, logout, 'click');
expect(authService.logout).toHaveBeenCalled(); expect(authenticationService.logout).toHaveBeenCalled();
}); });
}); });
}); });
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth/auth.service'; import { AuthenticationService } from 'libs/authentication/src/lib/authentication.service';
@Component({ @Component({
selector: 'user-profile-button-container', selector: 'user-profile-button-container',
...@@ -9,10 +9,10 @@ import { AuthService } from '../auth/auth.service'; ...@@ -9,10 +9,10 @@ import { AuthService } from '../auth/auth.service';
export class UserProfileButtonContainerComponent implements OnInit { export class UserProfileButtonContainerComponent implements OnInit {
public currentUserInitials: string; public currentUserInitials: string;
constructor(public authService: AuthService) {} constructor(public authenticationService: AuthenticationService) {}
ngOnInit(): void { ngOnInit(): void {
this.currentUserInitials = this.authService.getCurrentUserInitials(); this.currentUserInitials = this.authenticationService.getCurrentUserInitials();
} }
public showDropDown(): void { public showDropDown(): void {
......
...@@ -14,9 +14,6 @@ loadEnvironment(environment.environmentUrl).then((env) => { ...@@ -14,9 +14,6 @@ loadEnvironment(environment.environmentUrl).then((env) => {
if (env.production) { if (env.production) {
enableProdMode(); enableProdMode();
} }
console.info('init bootstrap application...');
//Für Standalone AppComponent
//bootstrapApplication(AppComponent, appConfig).catch(err => console.error(err));
platformBrowserDynamic() platformBrowserDynamic()
.bootstrapModule(AppModule) .bootstrapModule(AppModule)
.catch((err) => console.log(err)); .catch((err) => console.log(err));
......
...@@ -33,7 +33,6 @@ export class PostfachFormService extends AbstractFormService { ...@@ -33,7 +33,6 @@ export class PostfachFormService extends AbstractFormService {
} }
protected doSubmit(): Observable<StateResource<Resource>> { protected doSubmit(): Observable<StateResource<Resource>> {
console.info('FormValue: ', this.getFormValue());
return of(createEmptyStateResource<Resource>()); return of(createEmptyStateResource<Resource>());
} }
......
{
"extends": ["../../.eslintrc.json"],
"ignorePatterns": ["!**/*"],
"overrides": [
{
"files": ["*.ts"],
"extends": ["plugin:@nx/angular", "plugin:@angular-eslint/template/process-inline-templates"],
"rules": {
"@angular-eslint/directive-selector": [
"error",
{
"type": "attribute",
"prefix": "lib",
"style": "camelCase"
}
],
"@angular-eslint/component-selector": [
"error",
{
"type": "element",
"prefix": "lib",
"style": "kebab-case"
}
]
}
},
{
"files": ["*.html"],
"extends": ["plugin:@nx/angular-template"],
"rules": {}
}
]
}
# authentication
This library was generated with [Nx](https://nx.dev).
## Running unit tests
Run `nx test authentication` to execute the unit tests.
/* eslint-disable */
export default {
displayName: 'authentication',
preset: '../../jest.preset.js',
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
coverageDirectory: '../../coverage/libs/authentication',
transform: {
'^.+\\.(ts|mjs|js|html)$': [
'jest-preset-angular',
{
tsconfig: '<rootDir>/tsconfig.spec.json',
stringifyContentPathRegex: '\\.(html|svg)$',
},
],
},
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
snapshotSerializers: [
'jest-preset-angular/build/serializers/no-ng-attributes',
'jest-preset-angular/build/serializers/ng-snapshot',
'jest-preset-angular/build/serializers/html-comment',
],
};
{
"name": "authentication",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "libs/authentication/src",
"prefix": "lib",
"tags": [],
"projectType": "library",
"targets": {
"test": {
"executor": "@nx/jest:jest",
"outputs": ["{workspaceRoot}/coverage/{projectRoot}"],
"options": {
"jestConfig": "libs/authentication/jest.config.ts",
"passWithNoTests": true
},
"configurations": {
"ci": {
"ci": true,
"codeCoverage": true
}
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"],
"options": {
"lintFilePatterns": ["libs/authentication/**/*.ts", "libs/authentication/**/*.html"]
}
}
}
}
export * from './lib/authentication.module';
export * from './lib/authentication.service';
import { AuthenticationModule } from './authentication.module';
import { TestBed } from '@angular/core/testing';
describe('AuthenticationModule', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [AuthenticationModule],
}).compileComponents();
});
it('should create', () => {
expect(AuthenticationModule).toBeDefined();
});
});
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpUnauthorizedInterceptor } from './http-unauthorized.interceptor';
@NgModule({
imports: [CommonModule],
providers: [HttpUnauthorizedInterceptor],
})
export class AuthenticationModule {}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment