Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<label class="switch" for="user-notification-switcher">
<input id="user-notification-switcher" type="checkbox" [checked]="isChecked" (change)="onChange($event.target['checked'])" />
<input id="user-notification-switcher" type="checkbox" [checked]="displayChecked" (change)="onChange($event)" />
<span class="slider round"></span>
</label>
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';

import { UbsSwitcherComponent } from './ubs-switcher.component';
import { EventEmitter } from '@angular/core';

describe('UbsSwitcherComponent', () => {
let component: UbsSwitcherComponent;
Expand All @@ -21,4 +21,99 @@ describe('UbsSwitcherComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

describe('displayChecked getter', () => {
it('should return true when isChecked is true', () => {
component.isChecked = true;
expect(component.displayChecked).toBe(true);
});

it('should return false when isChecked is false', () => {
component.isChecked = false;
expect(component.displayChecked).toBe(false);
});

it('should return undefined when isChecked is not set', () => {
component.isChecked = undefined;
expect(component.displayChecked).toBeUndefined();
});
});

describe('onChange method', () => {
it('should emit true when checkbox is checked', () => {
component.isChecked = false;
spyOn(component.switchChanged, 'emit');

const mockCheckbox = { checked: true } as HTMLInputElement;
const mockEvent = { target: mockCheckbox } as unknown as Event;

component.onChange(mockEvent);

expect(component.switchChanged.emit).toHaveBeenCalledWith(true);
});

it('should emit false when checkbox is unchecked', () => {
component.isChecked = true;
spyOn(component.switchChanged, 'emit');

const mockCheckbox = { checked: false } as HTMLInputElement;
const mockEvent = { target: mockCheckbox } as unknown as Event;

component.onChange(mockEvent);

expect(component.switchChanged.emit).toHaveBeenCalledWith(false);
});

it('should reset checkbox.checked to isChecked value', () => {
component.isChecked = true;

const mockCheckbox = { checked: false } as HTMLInputElement;
const mockEvent = { target: mockCheckbox } as unknown as Event;

component.onChange(mockEvent);

expect(mockCheckbox.checked).toBe(true);
});

it('should handle event when isChecked is false', () => {
component.isChecked = false;
spyOn(component.switchChanged, 'emit');

const mockCheckbox = { checked: true } as HTMLInputElement;
const mockEvent = { target: mockCheckbox } as unknown as Event;

component.onChange(mockEvent);

expect(mockCheckbox.checked).toBe(false);
expect(component.switchChanged.emit).toHaveBeenCalledWith(true);
});

it('should cast event.target to HTMLInputElement', () => {
component.isChecked = false;

const mockCheckbox = { checked: true } as HTMLInputElement;
const mockEvent = { target: mockCheckbox } as unknown as Event;

expect(() => component.onChange(mockEvent)).not.toThrow();
});
});
Comment on lines +42 to +99
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

Verify edge case handling in onChange.

The tests don't cover scenarios where event.target might be null/undefined or when isChecked is undefined during onChange. Please verify how the component handles these edge cases and consider adding tests if these scenarios are possible.

Run the following script to examine the implementation:


🏁 Script executed:

#!/bin/bash
# Description: Check the onChange implementation for edge case handling

# Find the component implementation and look for onChange method
fd -e ts ubs-switcher.component.ts --exec cat {} | grep -A 10 "onChange"

Length of output: 206


🏁 Script executed:

#!/bin/bash
# Locate isChecked declaration and default
fd -e ts ubs-switcher.component.ts --exec cat {} | rg -n "isChecked"

Length of output: 104


Handle potential undefined event.target and isChecked. Guard against event.target being null before casting to HTMLInputElement, initialize the @Input() isChecked with a default value (e.g. = false), and add tests covering these edge cases.


describe('Input properties', () => {
it('should accept isChecked input', () => {
component.isChecked = true;
expect(component.isChecked).toBe(true);
});

it('should accept isEditing input', () => {
component.isEditing = true;
expect(component.isEditing).toBe(true);
});
});

describe('Output properties', () => {
it('should have switchChanged EventEmitter', () => {
expect(component.switchChanged).toBeDefined();
expect(component.switchChanged instanceof EventEmitter).toBe(true);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ export class UbsSwitcherComponent {

@Output() switchChanged: EventEmitter<boolean> = new EventEmitter<boolean>();

onChange(checked: boolean) {
this.switchChanged.emit(checked);
get displayChecked(): boolean {
return this.isChecked;
}

onChange(event: Event) {
const checkbox = event.target as HTMLInputElement;
const newValue = checkbox.checked;

checkbox.checked = this.isChecked;

this.switchChanged.emit(newValue);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,10 @@ <h5>{{ 'ubs-client-profile.contacts' | translate }}</h5>
<app-ubs-switcher
class="ubs-switcher"
[isChecked]="isTelegramNotifyChecked()"
[isEditing]="!isEditing"
[isEditing]="isEditing"
value="id1"
id="telegramNotification"
(switchChanged)="onSwitchChanged()"
(switchChanged)="onSwitchChanged($event)"
></app-ubs-switcher>
</div>
<div class="alert-mess">{{ 'ubs-client-profile.social-media-mess' | translate }}</div>
Expand Down Expand Up @@ -240,10 +240,10 @@ <h5 class="address-header">
</div>
</div>
<div class="submit-btns" *ngIf="isEditing">
<button class="ubs-primary-global-button s-btn" type="submit" (click)="onSubmit()" [disabled]="isSubmitBtnDisabled()">
<button class="ubs-primary-global-button s-btn" type="button" (click)="onSubmit()" [disabled]="isSubmitBtnDisabled()">
{{ 'ubs-client-profile.btn.save' | translate }}
</button>
<button class="ubs-secondary-global-button s-btn" type="submit" (click)="onCancel()">
<button class="ubs-secondary-global-button s-btn" type="button" (click)="onCancel()">
{{ 'ubs-client-profile.btn.cancel' | translate }}
</button>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,8 @@ describe('UbsUserProfilePageComponent', () => {
recipientEmail: new FormControl('some@gmail.com', [Validators.required]),
alternateEmail: new FormControl(''),
recipientPhone: new FormControl('1234567890'),
address: new FormArray([])
address: new FormArray([]),
telegramIsNotify: new FormControl(false)
});

component.userProfile = {
Expand All @@ -493,12 +494,18 @@ describe('UbsUserProfilePageComponent', () => {
recipientPhone: '+380923473666',
alternateEmail: '',
addressDto: [],
telegramIsNotify: true,
telegramIsNotify: false,
hasPassword: true
};

component.savedTelegramIsNotify = false;

component.userForm.markAsDirty();

expect(component.userForm.valid).toBeTrue();

clientProfileServiceMock.postDataClientProfile.and.returnValue(of(component.userProfile));

component.onSubmit();

expect(saveSpy).toHaveBeenCalled();
Expand All @@ -512,14 +519,29 @@ describe('UbsUserProfilePageComponent', () => {
recipientEmail: new FormControl(null, [Validators.required]),
alternateEmail: new FormControl(''),
recipientPhone: new FormControl(''),
address: new FormArray([])
address: new FormArray([]),
telegramIsNotify: new FormControl(false)
});

component.userProfile = {
recipientName: '',
recipientSurname: '',
recipientEmail: '',
recipientPhone: '',
alternateEmail: '',
addressDto: [],
telegramIsNotify: false,
hasPassword: true
};

component.savedTelegramIsNotify = false;
component.isEditing = false;

expect(component.userForm.valid).toBeFalse();

component.onSubmit();

expect(component.isEditing).toBeTruthy();
expect(component.userForm.get('recipientEmail').touched).toBeTrue();
});

it('on saveAddedAddresses method CreateAddress shouldnt be called if tempAddedAddressHolder is empty', () => {
Expand Down Expand Up @@ -817,6 +839,28 @@ describe('UbsUserProfilePageComponent', () => {
expect(component.tempRemovedAddressHolder.length).toBe(0);
});

it('should call "goToTelegramUrl" correctly', () => {
const windowOpenSpy = spyOn(window, 'open');
component.telegramBotURL = 'https://t.me/testbot';
component.goToTelegramUrl();
expect(windowOpenSpy).toHaveBeenCalledWith('https://t.me/testbot', '_blank');
});

it('should set telegram bot URL in setUrlToBot', () => {
component.userProfile = {
...userProfileDataMock,
botList: [{ link: 'https://t.me/bot123', type: 'telegram' }]
};
component.setUrlToBot();
expect(component.telegramBotURL).toBe('https://t.me/bot123');
});

it('should handle empty botList in setUrlToBot', () => {
component.userProfile = { ...userProfileDataMock, botList: [] };
component.setUrlToBot();
expect(component.telegramBotURL).toBeUndefined();
});

describe('Testing controls for the form:', () => {
const personalInfoControls = ['recipientName', 'recipientSurname', 'recipientEmail', 'recipientPhone'];
const controls = ['name', 'surename', 'email', 'phone'];
Expand All @@ -837,12 +881,29 @@ describe('UbsUserProfilePageComponent', () => {
});

describe('onSwitchChanged method', () => {
it('should toggle telegramIsNotify and call goToTelegramUrl when id is telegramNotification', () => {
it('should toggle telegramIsNotify and call goToTelegramUrl when newValue is true', () => {
const dialogRefSpyObj = jasmine.createSpyObj({ afterClosed: of(true) });
spyOn(TestBed.inject(MatDialog), 'open').and.returnValue(dialogRefSpyObj as any);
spyOn(component, 'goToTelegramUrl');
component.userProfile.telegramIsNotify = false;
component.onSwitchChanged();

component.userProfile = {
recipientName: 'Test',
recipientSurname: 'User',
recipientEmail: 'test@example.com',
recipientPhone: '+380991234567',
alternateEmail: '',
addressDto: [],
telegramIsNotify: false,
hasPassword: true,
botList: [{ link: 'https://t.me/testbot', type: 'telegram' }]
};

component.userInit();
component.savedTelegramIsNotify = false;
component.isEditing = true;

component.onSwitchChanged(true);

expect(component.goToTelegramUrl).toHaveBeenCalled();
expect(component.userProfile.telegramIsNotify).toBeTrue();
expect(component.userForm.get('telegramIsNotify')?.value).toBeTrue();
Expand All @@ -852,11 +913,53 @@ describe('UbsUserProfilePageComponent', () => {
const dialogRefSpyObj = jasmine.createSpyObj({ afterClosed: of(false) });
spyOn(TestBed.inject(MatDialog), 'open').and.returnValue(dialogRefSpyObj as any);
spyOn(component, 'goToTelegramUrl');
component.userProfile.telegramIsNotify = false;
const ctrl = component.userForm.get('telegramIsNotify') as FormControl;
ctrl.setValue(false);
component.onSwitchChanged();

component.userProfile = {
recipientName: 'Test',
recipientSurname: 'User',
recipientEmail: 'test@example.com',
recipientPhone: '+380991234567',
alternateEmail: '',
addressDto: [],
telegramIsNotify: false,
hasPassword: true,
botList: [{ link: 'https://t.me/testbot', type: 'telegram' }]
};

component.userInit();
component.savedTelegramIsNotify = false;
component.isEditing = true;

const initialValue = component.userProfile.telegramIsNotify;

component.onSwitchChanged(true);

expect(component.goToTelegramUrl).not.toHaveBeenCalled();
expect(component.userProfile.telegramIsNotify).toBe(initialValue);
expect(component.userForm.get('telegramIsNotify')?.value).toBe(initialValue);
});

it('should disable telegram notifications when newValue is false', () => {
component.userProfile = {
recipientName: 'Test',
recipientSurname: 'User',
recipientEmail: 'test@example.com',
recipientPhone: '+380991234567',
alternateEmail: '',
addressDto: [],
telegramIsNotify: true,
hasPassword: true,
botList: [{ link: 'https://t.me/testbot', type: 'telegram' }]
};

component.userInit();
component.savedTelegramIsNotify = true;
component.isEditing = false;

clientProfileServiceMock.postDataClientProfile.and.returnValue(of({ ...component.userProfile, telegramIsNotify: false }));

component.onSwitchChanged(false);

expect(component.userProfile.telegramIsNotify).toBeFalse();
expect(component.userForm.get('telegramIsNotify')?.value).toBeFalse();
});
Expand Down
Loading
Loading