blob: 37b5b9d68885a2565a38d74e387691ad1be13b4f [file] [log] [blame]
// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { CURRENT_VERSION, State } from '../src/state';
import { FakeWebviewAPi, logDataForTest } from './util';
import { LoggingView } from '../components/view';
import * as constant from '../src/constants';
import chai from 'chai';
import chaiDom from 'chai-dom'; // not esm
import { LogControl } from '../components/log_control';
import { Filter, FilterExpression } from '../src/filter';
import { LogViewActions } from '../components/log_view_actions';
import { WRAP_LOG_TEXT_ATTR } from '../components/log_list';
before(function () {
chai.should();
chai.use(chaiDom);
});
describe('LoggingView', () => {
const filterText = 'moniker:core/foo';
let root: HTMLElement;
let vscode: FakeWebviewAPi;
let state: State;
beforeEach(() => {
root = document.createElement('div');
document.body.appendChild(root);
vscode = new FakeWebviewAPi();
state = new State(vscode);
});
afterEach(() => {
root.remove();
});
describe('#constructor', () => {
it('crates view with a log list container and a log action container', () => {
new LoggingView(state, root);
root.children.length.should.equal(2);
root.children[0].id.should.equal('log-action-container');
root.children[1].id.should.equal('log-list-container');
});
it('creates log action container with a log control and log view actions', () => {
new LoggingView(state, root);
const container = root.children[0];
container.children.length.should.equal(2);
container.children[0].tagName.toLowerCase().should.equal('log-control');
container.children[1].tagName.toLowerCase().should.equal('log-view-actions');
});
it('initializes log control with the current state filters', async () => {
vscode.setState({
version: CURRENT_VERSION,
filter: filterText,
fields: constant.LOGS_HEADERS,
wrappingLogs: true
});
new LoggingView(new State(vscode), root);
let logControl = root.getElementsByTagName('log-control')[0] as LogControl;
await logControl.updateComplete;
logControl.value.should.equal(filterText);
});
it('initializes log actions view with the current state wrapping logs', async () => {
vscode.setState({
version: CURRENT_VERSION,
filter: filterText,
fields: constant.LOGS_HEADERS,
wrappingLogs: true
});
new LoggingView(new State(vscode), root);
let logViewActions = root.getElementsByTagName('log-view-actions')[0] as LogViewActions;
await logViewActions.updateComplete;
logViewActions.wrappingLogs.should.be.true;
});
it('crates log list container with log list', () => {
new LoggingView(state, root);
const container = root.children[1];
container.children.length.should.equal(1);
container.children[0].id.should.equal('log-list');
});
});
describe('log control integration', () => {
it('updates the state on log control filter changes', async () => {
new LoggingView(state, root);
let logControl = root.getElementsByTagName('log-control')[0] as LogControl;
await logControl.updateComplete;
const searchBox = logControl.shadowRoot!.querySelector('#search') as HTMLInputElement;
searchBox.value = filterText;
searchBox.dispatchEvent(new KeyboardEvent('keypress', { 'key': 'Enter' }));
await logControl.updateComplete;
state.currentFilter.should.deep.equal(new FilterExpression([
[
new Filter({
category: 'moniker',
operator: 'contains',
subCategory: undefined,
values: ['core/foo'],
not: false
}),
]
]));
state.currentFilterText.should.deep.equal(filterText);
});
});
describe('log actions view integration', () => {
it('clears the log list when the clear button is clicked', async () => {
const view = new LoggingView(state, root);
const logList = root.querySelector('#log-list') as HTMLElement;
view.addLog(logDataForTest('core/foo'));
logList.children.length.should.equal(2);
let logViewActions = root.getElementsByTagName('log-view-actions')[0] as LogViewActions;
await logViewActions.updateComplete;
let clearButton = logViewActions.shadowRoot!.querySelector('#clear') as HTMLDivElement;
clearButton.click();
logList.children.length.should.equal(1);
});
it('updates the state and log list when the wrap logs button is clicked', async () => {
const view = new LoggingView(state, root);
const logList = root.querySelector('#log-list') as HTMLElement;
view.addLog(logDataForTest('core/foo'));
logList.children.length.should.equal(2);
let logViewActions = root.getElementsByTagName('log-view-actions')[0] as LogViewActions;
await logViewActions.updateComplete;
let wrapLogsButton = logViewActions.shadowRoot!.querySelector('#wrap-logs') as HTMLDivElement;
// Clicking the button for the first should update the other elements to true.
// Since we started on true (default state value).
wrapLogsButton.click();
await logViewActions.updateComplete;
state.shouldWrapLogs.should.be.false;
logList.hasAttribute(WRAP_LOG_TEXT_ATTR).should.be.false;
// Clicking the button again should update the other elements to false.
wrapLogsButton.click();
await logViewActions.updateComplete;
state.shouldWrapLogs.should.be.true;
logList.hasAttribute(WRAP_LOG_TEXT_ATTR).should.be.true;
});
});
});