Skip to content

Commit

Permalink
Angular: Remove ngx-webstorage dependency
Browse files Browse the repository at this point in the history
  • Loading branch information
qmonmert committed Jul 23, 2022
1 parent d0fd707 commit 97aa52e
Show file tree
Hide file tree
Showing 11 changed files with 23 additions and 121 deletions.
Original file line number Diff line number Diff line change
@@ -1,16 +1,11 @@
package tech.jhipster.lite.generator.client.angular.security.jwt.domain;

import java.util.List;
import java.util.Map;

public class AngularJwt {

private AngularJwt() {}

public static List<String> jwtDependencies() {
return List.of("ngx-webstorage");
}

public static Map<String, String> angularJwtFiles() {
String primaryAppAuth = "app/auth";
String primaryAppLogin = "app/login";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,10 @@ public void addJwtAngular(Project project) {
public void addAppJwtFiles(Project project) {
project.addDefaultConfig(BASE_NAME);

addJwtDependencies(project);
addAngularJwtFiles(project);
updateAngularFilesForJwt(project);
}

public void addJwtDependencies(Project project) {
AngularJwt.jwtDependencies().forEach(dependency -> addDependency(project, dependency));
}

public void updateAngularFilesForJwt(Project project) {
String oldHtml = "// jhipster-needle-angular-route";
String newHtml =
Expand All @@ -59,11 +54,9 @@ public void updateAngularFilesForJwt(Project project) {
projectRepository.replaceText(project, APP, APP_ROUTING_MODULE, oldHtml, newHtml);

oldHtml = "import \\{ NgModule \\} from '@angular/core';";
newHtml =
"""
newHtml = """
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { NgxWebstorageModule } from 'ngx-webstorage';""";
import { ReactiveFormsModule } from '@angular/forms';""";
projectRepository.replaceText(project, APP, APP_MODULE, oldHtml, newHtml);

oldHtml = "import \\{ AppComponent \\} from './app.component';";
Expand All @@ -76,9 +69,7 @@ public void updateAngularFilesForJwt(Project project) {

oldHtml = "imports: \\[" + angularCommonService.getAngularModules().stream().collect(Collectors.joining(", ")) + "\\],";
newHtml =
"imports: \\[" +
angularCommonService.getAngularModules().stream().collect(Collectors.joining(", ")) +
", ReactiveFormsModule, NgxWebstorageModule.forRoot()\\],";
"imports: \\[" + angularCommonService.getAngularModules().stream().collect(Collectors.joining(", ")) + ", ReactiveFormsModule\\],";
projectRepository.replaceText(project, APP, APP_MODULE, oldHtml, newHtml);

oldHtml = "bootstrap: \\[AppComponent\\],";
Expand Down Expand Up @@ -111,15 +102,4 @@ public void addAngularJwtFiles(Project project) {
.toList();
projectRepository.template(files);
}

private void addDependency(Project project, String dependency) {
npmService
.getVersion("angular", dependency)
.ifPresentOrElse(
version -> npmService.addDependency(project, dependency, version),
() -> {
throw new GeneratorException("Dependency not found: " + dependency);
}
);
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { NgxWebstorageModule } from 'ngx-webstorage';

import { Account } from './account.model';

Expand Down Expand Up @@ -30,7 +29,7 @@ describe('Account Service', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule.withRoutes([]), NgxWebstorageModule.forRoot()],
imports: [HttpClientTestingModule, RouterTestingModule.withRoutes([])],
});

service = TestBed.inject(AccountService);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,54 +1,45 @@
import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { AuthServerProvider } from './auth-jwt.service';
import { LocalStorageService, NgxWebstorageModule, SessionStorageService } from 'ngx-webstorage';

describe('Auth JWT', () => {
let service: AuthServerProvider;
let localStorageService: LocalStorageService;
let sessionStorageService: SessionStorageService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, NgxWebstorageModule.forRoot()],
imports: [HttpClientTestingModule],
});

httpMock = TestBed.inject(HttpTestingController);
service = TestBed.inject(AuthServerProvider);
localStorageService = TestBed.inject(LocalStorageService);
sessionStorageService = TestBed.inject(SessionStorageService);
});

describe('Login', () => {
it('should clear session storage and save in local storage', () => {
// GIVEN
localStorageService.store = jest.fn();
sessionStorageService.clear = jest.fn();
jest.spyOn(Storage.prototype, 'setItem');
// WHEN
service.login({ username: 'John', password: '123' }).subscribe();
httpMock.expectOne('api/authenticate').flush({ id_token: '1' });

// THEN
httpMock.verify();
expect(localStorageService.store).toHaveBeenCalledWith('authenticationToken', '1');
expect(sessionStorageService.clear).toHaveBeenCalled();
expect(localStorage.setItem).toHaveBeenCalledWith('authenticationToken', '1');
});
});

describe('Logout', () => {
it('should clear storage', () => {
// GIVEN
sessionStorageService.clear = jest.fn();
localStorageService.clear = jest.fn();
jest.spyOn(Storage.prototype, 'removeItem');
// WHEN
service.logout().subscribe();
// THEN
expect(localStorageService.clear).toHaveBeenCalled();
expect(sessionStorageService.clear).toHaveBeenCalled();
expect(localStorage.removeItem).toHaveBeenCalledWith('authenticationToken');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { LocalStorageService, SessionStorageService } from 'ngx-webstorage';

import { Login } from '../login/login.model';

Expand All @@ -13,28 +12,22 @@ type JwtToken = {
@Injectable({ providedIn: 'root' })
export class AuthServerProvider {
constructor(
private http: HttpClient,
private localStorageService: LocalStorageService,
private sessionStorageService: SessionStorageService
private http: HttpClient
) {}

login(credentials: Login): Observable<void> {
return this.http
.post<JwtToken>('api/authenticate', credentials)
.pipe(map(response => this.authenticateSuccess(response)));
return this.http.post<JwtToken>('api/authenticate', credentials).pipe(map(response => this.authenticateSuccess(response)));
}

logout(): Observable<void> {
return new Observable(observer => {
this.localStorageService.clear('authenticationToken');
this.sessionStorageService.clear('authenticationToken');
localStorage.removeItem('authenticationToken');
observer.complete();
});
}

private authenticateSuccess(response: JwtToken): void {
const jwt = response.id_token;
this.localStorageService.store('authenticationToken', jwt);
this.sessionStorageService.clear('authenticationToken');
localStorage.setItem('authenticationToken', jwt);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,28 @@ import { getTestBed, TestBed } from '@angular/core/testing';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

import { LocalStorageService, NgxWebstorageModule, SessionStorageService } from 'ngx-webstorage';

import { AuthServerProvider } from './auth-jwt.service';
import { AuthInterceptor } from './auth.interceptor';

describe('Auth Interceptor', () => {
let service: AuthServerProvider;
let localStorageService: LocalStorageService;
let sessionStorageService: SessionStorageService;
let injector: TestBed;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, NgxWebstorageModule.forRoot()],
imports: [HttpClientTestingModule],
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: AuthInterceptor,
multi: true
}
]
multi: true,
},
],
});

injector = getTestBed();
httpMock = TestBed.inject(HttpTestingController);
localStorageService = TestBed.inject(LocalStorageService);
sessionStorageService = TestBed.inject(SessionStorageService);
service = TestBed.inject(AuthServerProvider);
});

Expand All @@ -41,20 +35,7 @@ describe('Auth Interceptor', () => {
it('should add authorization header with localStorageService', () => {
// GIVEN
const token = 'azerty';
localStorageService.retrieve = jest.fn(() => token);
// WHEN
service.login({ username: 'John', password: '123' }).subscribe();

// THEN
const httpReq = httpMock.expectOne('api/authenticate');
expect(httpReq.request.headers.has('Authorization')).toBe(true);
});

it('should add authorization header with sessionStorageService', () => {
// GIVEN
const token = 'azerty';
sessionStorageService.retrieve = jest.fn(() => token);
Storage.prototype.getItem = jest.fn(() => token);
// WHEN
service.login({ username: 'John', password: '123' }).subscribe();
Expand All @@ -64,5 +45,4 @@ describe('Auth Interceptor', () => {
expect(httpReq.request.headers.has('Authorization')).toBe(true);
});
});

});
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http';
import { Observable } from 'rxjs';
import { LocalStorageService, SessionStorageService } from 'ngx-webstorage';

@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(
private localStorageService: LocalStorageService,
private sessionStorageService: SessionStorageService
) {}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token: string | null =
this.localStorageService.retrieve('authenticationToken') ?? this.sessionStorageService.retrieve('authenticationToken');
const token: string | null = localStorage.getItem('authenticationToken');
if (token) {
request = request.clone({
setHeaders: {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { NgxWebstorageModule } from 'ngx-webstorage';
import { FormBuilder } from '@angular/forms';
import { of, Subject } from 'rxjs';
import { LoginService } from './login.service';
Expand All @@ -27,7 +26,7 @@ describe('Login Component', () => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [LoginComponent],
imports: [HttpClientTestingModule, NgxWebstorageModule.forRoot()],
imports: [HttpClientTestingModule],
providers: [
FormBuilder,
AccountService,
Expand Down Expand Up @@ -61,7 +60,7 @@ describe('Login Component', () => {
comp.ngOnInit();
// THEN
expect(comp.appName).toEqual('{{baseName}}');
expect(comp.appName).toEqual('angularapp');
expect(mockAccountService.getAuthenticationState).toHaveBeenCalled();
// THEN
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { TestBed } from '@angular/core/testing';
import { NgxWebstorageModule } from 'ngx-webstorage';

import { LoginService } from './login.service';
import { AuthServerProvider } from '../auth/auth-jwt.service';
Expand All @@ -16,10 +15,8 @@ describe('Login Service', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule, RouterTestingModule.withRoutes([]), NgxWebstorageModule.forRoot()],
providers: [
AccountService,
],
imports: [HttpClientTestingModule, RouterTestingModule.withRoutes([])],
providers: [AccountService],
});

service = TestBed.inject(LoginService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
"@angular/platform-browser-dynamic": "14.1.0",
"@angular/router": "14.1.0",
"keycloak-js": "18.0.1",
"ngx-webstorage": "10.0.1",
"rxjs": "7.5.6",
"tslib": "2.4.0",
"zone.js": "0.11.7"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,35 +37,10 @@ class AngularJwtDomainServiceTest {
@Test
void shouldAddJwtAngular() {
Project project = tmpProjectWithPackageJson();
when(npmService.getVersion(anyString(), anyString())).thenReturn(Optional.of("0.0.0"));

assertThatCode(() -> angularJwtDomainService.addJwtAngular(project)).doesNotThrowAnyException();
}

@Test
void shouldNotAddJwtAngular() {
Project project = tmpProjectWithPackageJson();

assertThatThrownBy(() -> angularJwtDomainService.addJwtAngular(project)).isExactlyInstanceOf(GeneratorException.class);
}

@Test
void shouldAddJwtDependencies() {
Project project = tmpProjectWithPackageJson();
when(npmService.getVersion(anyString(), anyString())).thenReturn(Optional.of("0.0.0"));

angularJwtDomainService.addJwtDependencies(project);

verify(npmService, times(1)).addDependency(any(Project.class), anyString(), anyString());
}

@Test
void shouldNotAddJwtDependencies() {
Project project = tmpProjectWithPackageJson();

assertThatThrownBy(() -> angularJwtDomainService.addJwtDependencies(project)).isExactlyInstanceOf(GeneratorException.class);
}

@Test
void shouldAddAngularJwtFiles() {
Project project = tmpProjectWithPackageJson();
Expand Down

0 comments on commit 97aa52e

Please sign in to comment.