/// /// Copyright 2015-2026 Micro Focus or one of its affiliates. /// /// Licensed under the Apache License, Version 2.0 (the "License"); /// you may not use this file except in compliance with the License. /// You may obtain a copy of the License at /// /// http://www.apache.org/licenses/LICENSE-2.0 /// /// Unless required by applicable law or agreed to in writing, software /// distributed under the License is distributed on an "AS IS" BASIS, /// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. /// See the License for the specific language governing permissions and /// limitations under the License. /// import { Component } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { ColorService } from '../../services/color/color.service'; import { ContrastService } from '../accessibility'; import { BadgeModule } from './badge.module'; const buttonSelector = 'button[class^=ux-badge]'; const badgeSelector = '.ux-badge'; @Component({ selector: 'app-badge-test', template: ` `, imports: [BadgeModule], }) export class BadgeTestComponent { badgeContentText: string | number = 'Some badge'; badgeColor: string = null; borderColor: string = null; maxValue: number = null; hidden: boolean = false; size: string = 'medium'; verticalPosition: string = 'above'; horizontalPosition: string = 'after'; overlap: boolean = false; } describe('Badge', () => { let component: BadgeTestComponent; let fixture: ComponentFixture; let nativeElement: HTMLElement; beforeEach(() => { TestBed.configureTestingModule({ imports: [BadgeModule, BadgeTestComponent], providers: [ContrastService, ColorService], }).compileComponents(); }); beforeEach(() => { fixture = TestBed.createComponent(BadgeTestComponent); component = fixture.componentInstance; nativeElement = fixture.nativeElement; fixture.detectChanges(); }); it('should have a badge directive attached', () => { const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(buttonWithBadge).toBeTruthy(); expect(buttonWithBadge.classList.contains('ux-badge-container')).toBeTruthy(); expect(buttonWithBadge.classList.contains('ux-badge-above')).toBeTruthy(); expect(buttonWithBadge.classList.contains('ux-badge-after')).toBeTruthy(); expect(badge.classList.contains('ux-badge-medium')).toBeTruthy(); expect(badge.textContent).toBe('Some badge'); expect(badge.style.color).toBe('rgb(255, 255, 255)'); }); it('should be able to create an empty badge (no content)', async () => { component.badgeContentText = null; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.textContent.replace(/ /g, '')).toBe(''); }); it('should set the background color with theme color', async () => { component.badgeColor = 'critical'; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.style.backgroundColor).toBe('rgb(255, 69, 79)'); expect(badge.style.color).toBe('rgb(0, 0, 0)'); }); it('should set the background color with hex color', async () => { component.badgeColor = '#FFF'; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.style.backgroundColor).toBe('rgb(255, 255, 255)'); expect(badge.style.color).toBe('rgb(0, 0, 0)'); }); it('should set the background color with rgba color', async () => { component.badgeColor = 'rgba(255, 255, 255, 0.5)'; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.style.backgroundColor).toBe('rgba(255, 255, 255, 0.5)'); expect(badge.style.color).toBe('rgb(0, 0, 0)'); }); it('should set the border color correctly', async () => { component.borderColor = 'critical'; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.style.borderColor).toBe('rgb(255, 69, 79)'); }); it('should truncate the text when max value is set (string length)', async () => { const t = 'A really long badge title'; component.badgeContentText = t; component.maxValue = 13; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.textContent).toBe('A really long…'); }); it('should not affect a string shorter than the max value (string length)', async () => { const t = 'What`s new'; component.badgeContentText = t; component.maxValue = 13; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.textContent).toBe(t); expect(badge.getAttribute('title')).toBeFalsy(); }); it('should limit a number when max value is set (actual value)', async () => { component.badgeContentText = '1849'; component.maxValue = 999; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.innerHTML).toBe('999+'); }); it('should not affect number smaller than max value (actual value)', async () => { component.badgeContentText = '998'; component.maxValue = 999; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.innerHTML).toBe('998'); }); it('should limit a number when max value is set (numeric value)', async () => { component.badgeContentText = 1849; component.maxValue = 999; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.innerHTML).toBe('999+'); }); it('should not affect number smaller than max value (numeric value)', async () => { component.badgeContentText = 998; component.maxValue = 999; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.innerHTML).toBe('998'); }); it('should not be visible', async () => { component.hidden = true; fixture.detectChanges(); await fixture.whenStable(); let buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); expect(buttonWithBadge.classList.contains('ux-badge-hidden')).toBeTruthy(); component.hidden = false; fixture.detectChanges(); await fixture.whenStable(); buttonWithBadge = document.querySelector(buttonSelector); expect(buttonWithBadge.classList.contains('ux-badge-hidden')).toBeFalsy(); }); it('should change the size of the badge', async () => { component.size = 'large'; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); const badge: HTMLSpanElement = buttonWithBadge.querySelector(badgeSelector); expect(badge.classList.contains('ux-badge-large')).toBeTruthy(); }); it('should be able to set to overlap the subject element', async () => { component.overlap = true; fixture.detectChanges(); await fixture.whenStable(); const buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); expect(buttonWithBadge.classList.contains('ux-badge-overlap')).toBeTruthy(); }); it('should change the alignment of the badge', async () => { component.verticalPosition = 'above'; component.horizontalPosition = 'before'; fixture.detectChanges(); await fixture.whenStable(); let buttonWithBadge: HTMLButtonElement = document.querySelector(buttonSelector); expect(buttonWithBadge.classList.contains('ux-badge-above')).toBeTruthy(); expect(buttonWithBadge.classList.contains('ux-badge-before')).toBeTruthy(); expect(buttonWithBadge.classList.contains('ux-badge-below')).toBeFalsy(); expect(buttonWithBadge.classList.contains('ux-badge-after')).toBeFalsy(); // change removes old styles, add new component.verticalPosition = 'below'; component.horizontalPosition = 'after'; fixture.detectChanges(); await fixture.whenStable(); buttonWithBadge = document.querySelector(buttonSelector); expect(buttonWithBadge.classList.contains('ux-badge-below')).toBeTruthy(); expect(buttonWithBadge.classList.contains('ux-badge-above')).toBeFalsy(); expect(buttonWithBadge.classList.contains('ux-badge-after')).toBeTruthy(); expect(buttonWithBadge.classList.contains('ux-badge-before')).toBeFalsy(); }); });