Skip to content

Commit

Permalink
Added sign-out component and fixed component testing
Browse files Browse the repository at this point in the history
  • Loading branch information
jdwillmsen committed Nov 13, 2023
1 parent bec8ae6 commit 23c5bc4
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { UpdateUserRolesRequest } from '@usersrole-nx/shared';
providedIn: 'root',
})
export class RolesService {
private baseUrl = `${this.environment.functionsBaseUrl}/api/users`;
private baseUrl = `${this.environment.functionsBaseUrl}/users`;

constructor(
@Inject(ENVIRONMENT) private environment: Environment,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { TestBed } from '@angular/core/testing';
import { SignOutComponent } from './sign-out.component';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { MatSnackBarModule } from '@angular/material/snack-bar';

describe(SignOutComponent.name, () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{
provide: AngularFireAuth,
useValue: {},
},
],
}).overrideComponent(SignOutComponent, {
add: {
imports: [MatSnackBarModule],
},
});
});

it('renders', () => {
cy.mount(SignOutComponent);
});

it('should be setup properly', () => {
cy.mount(SignOutComponent);
cy.getByCy('sign-out-button')
.should('be.visible')
.and('be.enabled')
.and('contain.text', 'Sign Out');
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<button
(click)="logout()"
data-cy="sign-out-button"
mat-stroked-button
type="button"
>
Sign Out
</button>
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SignOutComponent } from './sign-out.component';
import { AngularFireAuth } from '@angular/fire/compat/auth';
import { MatSnackBarModule } from '@angular/material/snack-bar';

describe('SignOutComponent', () => {
let component: SignOutComponent;
let fixture: ComponentFixture<SignOutComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [SignOutComponent, MatSnackBarModule],
providers: [
{
provide: AngularFireAuth,
useValue: {},
},
],
}).compileComponents();

fixture = TestBed.createComponent(SignOutComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { MatButtonModule } from '@angular/material/button';
import { AuthenticationService, ThemeStorageService } from '@usersrole-nx/core';

@Component({
selector: 'usersrole-nx-sign-out',
standalone: true,
imports: [CommonModule, MatButtonModule],
templateUrl: './sign-out.component.html',
styleUrls: ['./sign-out.component.scss'],
})
export class SignOutComponent {
constructor(
private authenticationService: AuthenticationService,
private themeStorageService: ThemeStorageService
) {}

logout() {
this.authenticationService.authLogout();
this.themeStorageService.clearStorage();
removeCustomTheme();
}
}

function removeCustomTheme() {
const palettes = ['primary', 'accent', 'warn', 'success', 'error', 'info'];
const colors: string[] = [
'50',
'100',
'200',
'300',
'400',
'500',
'600',
'700',
'800',
'900',
'A100',
'A200',
'A400',
'A700',
];

for (const palette of palettes) {
for (const color of colors) {
document.documentElement.style.removeProperty(`--${palette}-${color}`);
document.documentElement.style.removeProperty(
`--${palette}-contrast-${color}`
);
}
}
}
1 change: 1 addition & 0 deletions libs/usersrole-nx-app/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './lib/services/authentication/authentication.service';
export * from './lib/services/error-handler/error-handler.service';
export * from './lib/services/style-manager/style-manager.service';
export * from './lib/services/users/users.service';
export * from './lib/services/theme-storage/theme-storage.service';
export * from './lib/environment.token';
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { ThemeStorageService } from './theme-storage.service';
import { SiteTheme } from '@usersrole-nx/shared';

describe('ThemeStorageService', () => {
let themeStorageService: ThemeStorageService;
const storageKey = 'theme-storage-current-name';
const defaultTheme: SiteTheme = {
primary: '#3F51B5',
accent: '#E91E63',
displayName: 'Indigo & Pink',
name: 'indigo-pink',
isDark: false,
background: '#fafafa',
button: '#E91E63',
toolbar: '#3F51B5',
isDefault: true,
};

beforeEach(() => {
window.localStorage.clear();
themeStorageService = new ThemeStorageService();
});

it('should create an instance of ThemeStorageService', () => {
expect(themeStorageService).toBeInstanceOf(ThemeStorageService);
});

it('should store a theme', () => {
const localStorageSetItemSpy = jest.spyOn(
Object.getPrototypeOf(window.localStorage),
'setItem'
);
Object.setPrototypeOf(window.localStorage.setItem, jest.fn());
const emitSpy = jest.spyOn(themeStorageService.onThemeUpdate, 'emit');

themeStorageService.storeTheme(defaultTheme);

expect(localStorageSetItemSpy).toHaveBeenCalledWith(
storageKey,
defaultTheme.name
);
expect(emitSpy).toHaveBeenCalledWith(defaultTheme);
});

it('should get stored theme name', () => {
const storedThemeName = 'dark';
const localStorageGetItemSpy = jest.spyOn(
Object.getPrototypeOf(window.localStorage),
'getItem'
);
Object.setPrototypeOf(window.localStorage.getItem, jest.fn());
localStorageGetItemSpy.mockReturnValueOnce(storedThemeName);

const result = themeStorageService.getStoredThemeName();

expect(localStorageGetItemSpy).toHaveBeenCalledWith(storageKey);
expect(result).toBe(storedThemeName);
});

it('should clear storage', () => {
const localStorageRemoveItemSpy = jest.spyOn(
Object.getPrototypeOf(window.localStorage),
'removeItem'
);
Object.setPrototypeOf(window.localStorage.removeItem, jest.fn());

themeStorageService.clearStorage();

expect(localStorageRemoveItemSpy).toHaveBeenCalledWith(storageKey);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { EventEmitter, Injectable } from '@angular/core';
import { SiteTheme } from '@usersrole-nx/shared';

@Injectable({
providedIn: 'root',
})
export class ThemeStorageService {
static storageKey = 'theme-storage-current-name';
onThemeUpdate: EventEmitter<SiteTheme> = new EventEmitter<SiteTheme>();

storeTheme(theme: SiteTheme) {
window.localStorage.setItem(ThemeStorageService.storageKey, theme.name);
this.onThemeUpdate.emit(theme);
}

getStoredThemeName(): string | null {
return window.localStorage.getItem(ThemeStorageService.storageKey);
}

clearStorage() {
window.localStorage.removeItem(ThemeStorageService.storageKey);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import { of } from 'rxjs';

describe(ProfileComponent.name, () => {
beforeEach(() => {
cy.intercept(
{
method: 'GET',
url: '/users/*',
},
''
).as('getUsers');
TestBed.configureTestingModule({
imports: [BrowserAnimationsModule],
providers: [
Expand All @@ -27,7 +34,9 @@ describe(ProfileComponent.name, () => {
providers: [
{
provide: AngularFireAuth,
useValue: {},
useValue: {
user: of(() => true),
},
},
],
},
Expand Down Expand Up @@ -68,22 +77,9 @@ function testScreenSize(size: string, width: number, height: number) {
});

it('should be setup appropriately with values', () => {
cy.intercept(
{
method: 'GET',
url: '/users/*',
},
''
).as('getUsers');
TestBed.overrideComponent(ProfileComponent, {
set: {
add: {
providers: [
{
provide: AngularFireAuth,
useValue: {
user: of(() => true),
},
},
{
provide: UsersService,
useValue: {
Expand Down

0 comments on commit 23c5bc4

Please sign in to comment.