// Licensed to Cloudera, Inc. under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. Cloudera, Inc. licenses this file
// to you 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 React from 'react';
import { act, getByRole, render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import userEvent from '@testing-library/user-event';
import huePubSub from '../../utils/huePubSub';
import GlobalAlert, { HueAlert } from './GlobalAlert';
import {
GLOBAL_ERROR_TOPIC,
GLOBAL_INFO_TOPIC,
GLOBAL_WARNING_TOPIC,
HIDE_GLOBAL_ALERTS_TOPIC
} from './events';
describe('GlobalAlert', () => {
it('should show a global error message', async () => {
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Some error' }));
const alerts = screen.queryAllByRole('alert');
expect(alerts).toHaveLength(1);
expect(alerts[0]).toHaveTextContent('Some error');
});
it('should show multiple global error messages', async () => {
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 1' }));
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 2' }));
const alerts = screen.queryAllByRole('alert');
expect(alerts).toHaveLength(2);
expect(alerts[0]).toHaveTextContent('Error 1');
expect(alerts[1]).toHaveTextContent('Error 2');
});
it("shouldn't show empty error messages", async () => {
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() => huePubSub.publish('hue.global.error', { message: '' }));
expect(screen.queryAllByRole('alert')).toHaveLength(0);
});
it('should show unique error messages', async () => {
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 1' }));
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 2' }));
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 1' }));
const alerts = screen.queryAllByRole('alert');
expect(alerts).toHaveLength(2);
expect(alerts[0]).toHaveTextContent('Error 1');
expect(alerts[1]).toHaveTextContent('Error 2');
});
it('should close alerts when clicked', async () => {
const user = userEvent.setup();
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 1' }));
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 2' }));
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Error 3' }));
// Closing "Error 2"
const initialAlerts = screen.queryAllByRole('alert');
expect(initialAlerts).toHaveLength(3);
const closeButton = getByRole(initialAlerts[1], 'button');
await user.click(closeButton);
const alertsAfterClosing = screen.queryAllByRole('alert');
expect(alertsAfterClosing).toHaveLength(2);
expect(alertsAfterClosing[0]).toHaveTextContent('Error 1');
expect(alertsAfterClosing[1]).toHaveTextContent('Error 3');
});
const expectAlertToBeGoneAfterThreeSeconds = () => {
// It should still be open after 2 seconds
act(() => {
jest.advanceTimersByTime(2000);
});
expect(screen.queryAllByRole('alert')).toHaveLength(1);
// After 3.1 seconds, it should really be closed
act(() => {
jest.advanceTimersByTime(1100);
});
expect(screen.queryAllByRole('alert')).toHaveLength(0);
};
it('should close info alerts automatically after 3 seconds', async () => {
jest.useFakeTimers();
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() => huePubSub.publish(GLOBAL_INFO_TOPIC, { message: 'info' }));
expect(screen.queryAllByRole('alert')).toHaveLength(1);
expectAlertToBeGoneAfterThreeSeconds();
jest.useRealTimers();
});
it('should close warning alerts when when noStick is set to true', async () => {
jest.useFakeTimers();
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() =>
huePubSub.publish(GLOBAL_WARNING_TOPIC, { message: 'Some warning', noStick: true })
);
expect(screen.queryAllByRole('alert')).toHaveLength(1);
expectAlertToBeGoneAfterThreeSeconds();
jest.useRealTimers();
});
it('should close error alerts when when noStick is set to true', async () => {
jest.useFakeTimers();
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() =>
huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Some error', noStick: true })
);
expect(screen.queryAllByRole('alert')).toHaveLength(1);
expectAlertToBeGoneAfterThreeSeconds();
jest.useRealTimers();
});
it('should close all alerts "hide.global.alerts" is published', async () => {
render();
expect(screen.queryAllByRole('alert')).toHaveLength(0);
act(() => huePubSub.publish(GLOBAL_INFO_TOPIC, { message: 'Some info' }));
act(() => huePubSub.publish(GLOBAL_WARNING_TOPIC, { message: 'Some warning' }));
act(() => huePubSub.publish(GLOBAL_ERROR_TOPIC, { message: 'Some error' }));
expect(screen.queryAllByRole('alert')).toHaveLength(3);
act(() => huePubSub.publish(HIDE_GLOBAL_ALERTS_TOPIC));
expect(screen.queryAllByRole('alert')).toHaveLength(0);
});
});