@carbon/ibm-products-web-components
Version:
Carbon for IBM Products Web Components
150 lines (147 loc) • 7.54 kB
JavaScript
/**
* Copyright IBM Corp. 2024
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
import { describe, it, expect } from 'vitest';
import { fixture, elementUpdated, oneEvent, html } from '@open-wc/testing';
import './notification-panel.js';
import './notification.js';
import './notification-footer.js';
import { dateTimeFormat as r } from '../../node_modules/@carbon/utilities/es/dateTimeFormat/index.js';
import '../../node_modules/@carbon/utilities/es/documentLang/documentLang.js';
/**
* Copyright IBM Corp. 2025
*
* This source code is licensed under the Apache-2.0 license found in the
* LICENSE file in the root directory of this source tree.
*/
const templateNotification = () => {
const timeStamp = new Date(new Date().getTime() - 30 * 1000);
return html `
<c4p-notification
slot="today"
@c4p-notification-dismiss=${() => {
console.log('dismiss notification');
}}
type="error"
?unread="true"
.timestamp=${timeStamp}
>
<h4 class="c4p--notifications-panel__notification" slot="title">
LogDNA cannot be reached.
</h4>
<div slot="description">Unable to communicate with LogDNA.</div>
</c4p-notification>
`;
};
describe('c4p-notification', () => {
it('should render the notification', async () => {
const notification = (await fixture(templateNotification()));
expect(notification).toBeDefined();
});
it('should render appropriate icon based the "type" prop passed', async () => {
var _a, _b, _c, _d;
const notification = (await fixture(templateNotification()));
expect(notification.type).toBe('error');
let iconElement = (_a = notification.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.c4p--notifications-panel__notification-status-icon-error');
expect(iconElement).not.toBeNull();
notification.type = 'success';
await elementUpdated(notification);
iconElement = (_b = notification.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.c4p--notifications-panel__notification-status-icon-success');
expect(iconElement).not.toBeNull();
notification.type = 'warning';
await elementUpdated(notification);
iconElement = (_c = notification.shadowRoot) === null || _c === void 0 ? void 0 : _c.querySelector('.c4p--notifications-panel__notification-status-icon-warning');
expect(iconElement).not.toBeNull();
notification.type = 'informational';
await elementUpdated(notification);
iconElement = (_d = notification.shadowRoot) === null || _d === void 0 ? void 0 : _d.querySelector('.c4p--notifications-panel__notification-status-icon-informational');
expect(iconElement).not.toBeNull();
});
it('should render appropriate time label based the "timestamp" prop passed', async () => {
var _a, _b, _c;
const notification = (await fixture(templateNotification()));
const dateTimeValue = r.relative.format(notification.timestamp, {
locale: 'en-US',
style: 'long',
});
const expected = new Date(Date.now() - 30 * 1000);
expect((_a = notification.timestamp) === null || _a === void 0 ? void 0 : _a.getTime()).toBeCloseTo(expected.getTime(), -1);
const notificationTimeLabel = (_b = notification.shadowRoot) === null || _b === void 0 ? void 0 : _b.querySelector('.c4p--notifications-panel__notification-time-label');
expect((_c = notificationTimeLabel === null || notificationTimeLabel === void 0 ? void 0 : notificationTimeLabel.textContent) === null || _c === void 0 ? void 0 : _c.trim()).toBe(dateTimeValue);
});
it('should render heading as "title" slot', async () => {
var _a, _b;
const notification = (await fixture(templateNotification()));
await elementUpdated(notification);
const titleSlot = (_a = notification.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot[name="title"]');
expect(titleSlot).toBeDefined();
const assignedElements = titleSlot.assignedElements({
flatten: true,
});
const titleElement = assignedElements[0];
expect(titleElement.tagName).toBe('H4');
expect(titleElement.classList.contains('c4p--notifications-panel__notification')).toBe(true);
expect(titleElement.getAttribute('slot')).toBe('title');
expect((_b = titleElement.textContent) === null || _b === void 0 ? void 0 : _b.trim()).toBe('LogDNA cannot be reached.');
});
it('should render description as "description" slot', async () => {
var _a, _b;
const notification = (await fixture(templateNotification()));
await elementUpdated(notification);
const descriptionSlot = (_a = notification.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('slot[name="description"]');
expect(descriptionSlot).toBeDefined();
const assignedElements = descriptionSlot.assignedElements({
flatten: true,
});
const descriptionElement = assignedElements[0];
expect(descriptionElement.tagName).toBe('DIV');
expect(descriptionElement.getAttribute('slot')).toBe('description');
expect((_b = descriptionElement.textContent) === null || _b === void 0 ? void 0 : _b.trim()).toBe('Unable to communicate with LogDNA.');
});
it('should emit "c4p-notification-dismiss" when clicked on single dismiss button', async () => {
var _a;
const notification = (await fixture(templateNotification()));
const eventPromise = oneEvent(notification, 'c4p-notification-dismiss');
const singleDismissButton = (_a = notification.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('.c4p--notifications-panel__notification__dismiss-single-button');
singleDismissButton === null || singleDismissButton === void 0 ? void 0 : singleDismissButton.click();
const event = await eventPromise;
expect(event).toBeDefined();
});
it('triggers click() on Enter key', async () => {
let clickCalled = false;
const notification = (await fixture(templateNotification()));
notification.click = () => {
clickCalled = true;
}; // Mock click()
const enterEvent = new KeyboardEvent('keydown', { key: 'Enter' });
//@ts-ignore
notification._handleKeyDown(enterEvent);
expect(clickCalled).to.be.true;
});
it('triggers click() on Space key', async () => {
let clickCalled = false;
const notification = (await fixture(templateNotification()));
notification.click = () => {
clickCalled = true;
}; // Mock click()
const spaceEvent = new KeyboardEvent('keydown', { key: ' ' });
//@ts-ignore
notification._handleKeyDown(spaceEvent);
expect(clickCalled).to.be.true;
});
it('does nothing for other keys', async () => {
let clickCalled = false;
const notification = (await fixture(templateNotification()));
notification.click = () => {
clickCalled = true;
};
const otherKeyEvent = new KeyboardEvent('keydown', { key: 'Escape' });
//@ts-ignore
notification._handleKeyDown(otherKeyEvent);
expect(clickCalled).to.be.false;
});
});
//# sourceMappingURL=notification.test.js.map