Skip to content
Open
Show file tree
Hide file tree
Changes from all 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,10 +1,10 @@
<div class="po-toolbar-notification po-clickable" (click)="popup.toggle()">
<po-icon #notification p-icon="ICON_NOTIFICATION" class="po-toolbar-icon"></po-icon>
@if (notificationNumber) {
@if (notificationNumber()) {
<div class="po-toolbar-notification-badge">
{{ notificationNumber }}
{{ notificationNumber() }}
</div>
}
</div>

<po-popup #popup p-size="medium" [p-actions]="notificationActions" [p-target]="notificationRef"> </po-popup>
<po-popup #popup p-size="medium" [p-actions]="notificationActions() ?? []" [p-target]="notificationRef()"> </po-popup>
Original file line number Diff line number Diff line change
@@ -1,115 +1,114 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ChangeDetectorRef, ElementRef, NO_ERRORS_SCHEMA, Renderer2 } from '@angular/core';
import { RouterTestingModule } from '@angular/router/testing';

import { configureTestSuite, expectPropertiesValues } from '../../../util-test/util-expect.spec';
import { Component, viewChild } from '@angular/core';
import { ElementRef, NO_ERRORS_SCHEMA, Renderer2 } from '@angular/core';

import { PoControlPositionService } from '../../../services/po-control-position/po-control-position.service';
import { PoPopupComponent } from '../../po-popup//po-popup.component';

import { PoToolbarNotificationComponent } from './po-toolbar-notification.component';

@Component({
template: `<po-toolbar-notification
[p-notification-number]="notificationNumber"
[p-notification-actions]="notificationActions"
></po-toolbar-notification>`,
standalone: false
})
class HostComponent {
notificationNumber: any = 0;
notificationActions = undefined;

notification = viewChild(PoToolbarNotificationComponent);
}

describe('PoToolbarNotificationComponent: ', () => {
let hostComponent: HostComponent;
let component: PoToolbarNotificationComponent;
let fixture: ComponentFixture<PoToolbarNotificationComponent>;
let nativeElement;
let fixture: ComponentFixture<HostComponent>;
let nativeElement: HTMLElement;

configureTestSuite(() => {
const elementRef = {};
const renderer2 = {
listen: () => ({})
};
beforeEach(async () => {
const renderer2 = { listen: () => ({}) };
const poControlPositionService = {
setElements: () => ({}),
setElementPosition: () => ({})
};

TestBed.configureTestingModule({
imports: [RouterTestingModule.withRoutes([])],
declarations: [PoToolbarNotificationComponent, PoPopupComponent],
await TestBed.configureTestingModule({
declarations: [HostComponent, PoToolbarNotificationComponent, PoPopupComponent],
schemas: [NO_ERRORS_SCHEMA],
providers: [
{ provide: ElementRef, useValue: { elementRef } },
{ provide: Renderer2, useValue: renderer2 },
{ provide: PoControlPositionService, useValue: poControlPositionService }
]
});
});

beforeEach(() => {
fixture = TestBed.createComponent(PoToolbarNotificationComponent);
component = fixture.componentInstance;
nativeElement = fixture.debugElement.nativeElement;

component['_notificationNumber'] = 0;
}).compileComponents();

fixture = TestBed.createComponent(HostComponent);
hostComponent = fixture.componentInstance;
fixture.detectChanges();
component = hostComponent.notification();
nativeElement = fixture.debugElement.nativeElement;
});

it('should be created', () => {
expect(component).toBeTruthy();
});

it('should call detectChanges after view init', async () => {
const detectChangesSpy = spyOn(component['cdr'], 'detectChanges');

component.ngAfterViewInit();

expect(detectChangesSpy).toHaveBeenCalled();
});

it('should correctly reference the ViewChild notification element', () => {
fixture.detectChanges(); // Garante que o ViewChild foi inicializado após a renderização

const notificationElement = fixture.nativeElement.querySelector('po-icon');
expect(component.notificationRef.nativeElement).toBe(notificationElement);
const notificationElement = nativeElement.querySelector('po-icon');
expect(component.notificationRef().nativeElement).toBe(notificationElement);
});

describe('Properties: ', () => {
it('notificationNumber: should update property `p-notification-number` with `0` when invalid values', () => {
it('notificationNumber: should return `0` when invalid values', () => {
const invalidValues = [undefined, null, {}, NaN, 'string', 0.1, false, true];

expectPropertiesValues(component, 'notificationNumber', invalidValues, 0);
invalidValues.forEach(val => {
hostComponent.notificationNumber = val;
fixture.detectChanges();
expect(component.notificationNumber()).toBe(0);
});
});

it('notificationNumber: should update property `p-notification-number` with valid values', () => {
const validValues = [2, 3];
it('notificationNumber: should return valid integer values', () => {
hostComponent.notificationNumber = 2;
fixture.detectChanges();
expect(component.notificationNumber()).toBe(2);

expectPropertiesValues(component, 'notificationNumber', validValues, validValues);
hostComponent.notificationNumber = 3;
fixture.detectChanges();
expect(component.notificationNumber()).toBe(3);
});
});

describe('Templates: ', () => {
it('should not show count badge when notificationNumber is 0', () => {
component['_notificationNumber'] = 0;

hostComponent.notificationNumber = 0;
fixture.detectChanges();

expect(nativeElement.querySelector('.po-toolbar-notification-badge')).toBeFalsy();
});

it('should not show count badge when notificationNumber is undefined', () => {
component['_notificationNumber'] = undefined;

it('should show count badge when notificationNumber transitions from 0 to positive', () => {
hostComponent.notificationNumber = 0;
fixture.detectChanges();

expect(nativeElement.querySelector('.po-toolbar-notification-badge')).toBeFalsy();
});

it('should not show count badge when notificationNumber is null', () => {
component['_notificationNumber'] = null;

hostComponent.notificationNumber = 1;
fixture.detectChanges();

expect(nativeElement.querySelector('.po-toolbar-notification-badge')).toBeFalsy();
const badge = nativeElement.querySelector('.po-toolbar-notification-badge');
expect(badge).toBeTruthy();
expect(badge.textContent.trim()).toBe('1');
});

it('should show count badge when have notificationNumber', () => {
component['_notificationNumber'] = 10;

hostComponent.notificationNumber = 10;
fixture.detectChanges();

expect(nativeElement.querySelector('.po-toolbar-notification-badge')).toBeTruthy();
const badge = nativeElement.querySelector('.po-toolbar-notification-badge');
expect(badge).toBeTruthy();
expect(badge.textContent.trim()).toBe('10');
});
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
import { AfterViewInit, ChangeDetectorRef, Component, ElementRef, Input, ViewChild, inject } from '@angular/core';
import { Component, ElementRef, input, viewChild } from '@angular/core';

import { PoControlPositionService } from '../../../services/po-control-position/po-control-position.service';

import { PoToolbarAction } from '../po-toolbar-action.interface';

function toIntegerOrZero(value: unknown): number {
return Number.isInteger(value) ? (value as number) : 0;
}

/**
* @docsPrivate
*
Expand All @@ -23,24 +27,13 @@ import { PoToolbarAction } from '../po-toolbar-action.interface';
providers: [PoControlPositionService],
standalone: false
})
export class PoToolbarNotificationComponent implements AfterViewInit {
private cdr = inject(ChangeDetectorRef);

@ViewChild('notification', { read: ElementRef }) notificationRef: ElementRef;

@Input('p-notification-actions') notificationActions?: Array<PoToolbarAction>;

private _notificationNumber?: number = 0;

@Input('p-notification-number') set notificationNumber(value: number) {
this._notificationNumber = Number.isInteger(value) ? value : 0;
}
export class PoToolbarNotificationComponent {
readonly notificationRef = viewChild('notification', { read: ElementRef });

get notificationNumber() {
return this._notificationNumber;
}
readonly notificationActions = input<Array<PoToolbarAction>>(undefined, { alias: 'p-notification-actions' });

ngAfterViewInit() {
this.cdr.detectChanges();
}
readonly notificationNumber = input<number, unknown>(0, {
alias: 'p-notification-number',
transform: toIntegerOrZero
});
}
Loading