1315 lines
45 KiB
JavaScript
1315 lines
45 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||
"use strict";
|
||
|
||
const {
|
||
getAllMessagesUiById,
|
||
getAllCssMessagesMatchingElements,
|
||
getAllNetworkMessagesUpdateById,
|
||
getAllRepeatById,
|
||
getAllDisabledMessagesById,
|
||
getCurrentGroup,
|
||
getGroupsById,
|
||
getMutableMessagesById,
|
||
getVisibleMessages,
|
||
} = require("resource://devtools/client/webconsole/selectors/messages.js");
|
||
|
||
const {
|
||
clonePacket,
|
||
getFirstMessage,
|
||
getLastMessage,
|
||
getMessageAt,
|
||
setupActions,
|
||
setupStore,
|
||
} = require("resource://devtools/client/webconsole/test/node/helpers.js");
|
||
const {
|
||
stubPackets,
|
||
stubPreparedMessages,
|
||
} = require("resource://devtools/client/webconsole/test/node/fixtures/stubs/index.js");
|
||
const {
|
||
MESSAGE_TYPE,
|
||
CSS_MESSAGE_ADD_MATCHING_ELEMENTS,
|
||
} = require("resource://devtools/client/webconsole/constants.js");
|
||
const {
|
||
createWarningGroupMessage,
|
||
} = require("resource://devtools/client/webconsole/utils/messages.js");
|
||
|
||
const expect = require("expect");
|
||
|
||
describe("Message reducer:", () => {
|
||
let actions;
|
||
|
||
beforeAll(() => {
|
||
actions = setupActions();
|
||
});
|
||
|
||
describe("mutableMessagesById", () => {
|
||
it("adds a message to an empty store", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const packet = stubPackets.get("console.log('foobar', 'test')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const message = stubPreparedMessages.get("console.log('foobar', 'test')");
|
||
|
||
expect(getFirstMessage(getState())).toEqual(message);
|
||
});
|
||
|
||
it("increments repeat on a repeating log message", () => {
|
||
const key1 = "console.log('foobar', 'test')";
|
||
const { dispatch, getState } = setupStore([key1, key1], { actions });
|
||
|
||
const packet = clonePacket(stubPackets.get(key1));
|
||
const packet2 = clonePacket(packet);
|
||
|
||
// Repeat ID must be the same even if the timestamp is different.
|
||
packet.timeStamp = 1;
|
||
packet2.timeStamp = 2;
|
||
dispatch(actions.messagesAdd([packet, packet2]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
expect(messages.size).toBe(1);
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(repeat[getFirstMessage(getState()).id]).toBe(4);
|
||
});
|
||
|
||
it("doesn't increment repeat on same log message with different locations", () => {
|
||
const key1 = "console.log('foobar', 'test')";
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const packet = clonePacket(stubPackets.get(key1));
|
||
|
||
// Dispatch original packet.
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// Dispatch same packet with modified column number.
|
||
packet.columnNumber = packet.columnNumber + 1;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// Dispatch same packet with modified line number.
|
||
packet.lineNumber = packet.lineNumber + 1;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
expect(messages.size).toBe(3);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(Object.keys(repeat).length).toBe(0);
|
||
});
|
||
|
||
it("increments repeat on a repeating css message", () => {
|
||
const key1 =
|
||
"Unknown property ‘such-unknown-property’. Declaration dropped.";
|
||
const { dispatch, getState } = setupStore([key1, key1]);
|
||
|
||
const packet = clonePacket(stubPackets.get(key1));
|
||
|
||
// Repeat ID must be the same even if the timestamp is different.
|
||
packet.pageError.timeStamp = 1;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
packet.pageError.timeStamp = 2;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
expect(messages.size).toBe(1);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(repeat[getFirstMessage(getState()).id]).toBe(4);
|
||
});
|
||
|
||
it("doesn't increment repeat on same css message with different locations", () => {
|
||
const key1 =
|
||
"Unknown property ‘such-unknown-property’. Declaration dropped.";
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const packet = clonePacket(stubPackets.get(key1));
|
||
|
||
// Dispatch original packet.
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// Dispatch same packet with modified column number.
|
||
packet.pageError.columnNumber = packet.pageError.columnNumber + 1;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// Dispatch same packet with modified line number.
|
||
packet.pageError.lineNumber = packet.pageError.lineNumber + 1;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
expect(messages.size).toBe(3);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(Object.keys(repeat).length).toBe(0);
|
||
});
|
||
|
||
it("increments repeat on a repeating error message", () => {
|
||
const key1 = "ReferenceError: asdf is not defined";
|
||
const { dispatch, getState } = setupStore([key1, key1]);
|
||
|
||
const packet = clonePacket(stubPackets.get(key1));
|
||
|
||
// Repeat ID must be the same even if the timestamp is different.
|
||
packet.pageError.timeStamp = 1;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
packet.pageError.timeStamp = 2;
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
expect(messages.size).toBe(1);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(repeat[getFirstMessage(getState()).id]).toBe(4);
|
||
});
|
||
|
||
it("does not increment repeat after closing a group", () => {
|
||
const logKey = "console.log('foobar', 'test')";
|
||
const { getState } = setupStore([
|
||
logKey,
|
||
logKey,
|
||
"console.group('bar')",
|
||
logKey,
|
||
logKey,
|
||
logKey,
|
||
"console.groupEnd()",
|
||
logKey,
|
||
]);
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
expect(messages.size).toBe(4);
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(repeat[getFirstMessage(getState()).id]).toBe(2);
|
||
expect(repeat[getMessageAt(getState(), 2).id]).toBe(3);
|
||
expect(repeat[getLastMessage(getState()).id]).toBe(undefined);
|
||
});
|
||
|
||
it("doesn't increment undefined messages coming from different places", () => {
|
||
const { getState } = setupStore(["console.log(undefined)", "undefined"]);
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(2);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(Object.keys(repeat).length).toBe(0);
|
||
});
|
||
|
||
it("doesn't increment successive falsy but different messages", () => {
|
||
const { getState } = setupStore(
|
||
["console.log(NaN)", "console.log(undefined)", "console.log(null)"],
|
||
{ actions }
|
||
);
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(3);
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(Object.keys(repeat).length).toBe(0);
|
||
});
|
||
|
||
it("increment falsy messages when expected", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const nanPacket = stubPackets.get("console.log(NaN)");
|
||
dispatch(actions.messagesAdd([nanPacket, nanPacket]));
|
||
let messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(1);
|
||
let repeat = getAllRepeatById(getState());
|
||
expect(repeat[getLastMessage(getState()).id]).toBe(2);
|
||
|
||
const undefinedPacket = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([undefinedPacket, undefinedPacket]));
|
||
messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(2);
|
||
repeat = getAllRepeatById(getState());
|
||
expect(repeat[getLastMessage(getState()).id]).toBe(2);
|
||
|
||
const nullPacket = stubPackets.get("console.log(null)");
|
||
dispatch(actions.messagesAdd([nullPacket, nullPacket]));
|
||
messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(3);
|
||
repeat = getAllRepeatById(getState());
|
||
expect(repeat[getLastMessage(getState()).id]).toBe(2);
|
||
});
|
||
|
||
it("does not clobber a unique message", () => {
|
||
const key1 = "console.log('foobar', 'test')";
|
||
const { dispatch, getState } = setupStore([key1, key1]);
|
||
|
||
const packet = stubPackets.get(key1);
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const packet2 = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([packet2]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(2);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(repeat[getFirstMessage(getState()).id]).toBe(3);
|
||
expect(repeat[getLastMessage(getState()).id]).toBe(undefined);
|
||
});
|
||
|
||
it("does not increment repeat after adding similar warning group", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
// Mocking a warning message that would create a warning group
|
||
const warningMessage = stubPreparedMessages.get(
|
||
"ReferenceError: asdf is not defined"
|
||
);
|
||
warningMessage.messageText =
|
||
"The resource at “https://evil.com” was blocked.";
|
||
warningMessage.category = "cookieBlockedPermission";
|
||
|
||
const type = MESSAGE_TYPE.CONTENT_BLOCKING_GROUP;
|
||
const firstMessageId = `${warningMessage.type}-${warningMessage.innerWindowID}`;
|
||
const message1 = createWarningGroupMessage(
|
||
firstMessageId,
|
||
type,
|
||
warningMessage
|
||
);
|
||
const secondMessageId = `${warningMessage.type}-${
|
||
warningMessage.innerWindowID + 10
|
||
}`;
|
||
const message2 = createWarningGroupMessage(
|
||
secondMessageId,
|
||
type,
|
||
warningMessage
|
||
);
|
||
|
||
dispatch(actions.messagesAdd([message1, message2]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(2);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(Object.keys(repeat).length).toBe(0);
|
||
});
|
||
|
||
it("does not increment repeat after adding different Symbols", () => {
|
||
const { getState } = setupStore([
|
||
"console.log(Symbol.for('foo'))",
|
||
"console.log(Symbol.for('bar'))",
|
||
]);
|
||
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(Object.keys(repeat).length).toBe(0);
|
||
});
|
||
|
||
it("adds a message in response to console.clear()", () => {
|
||
const { dispatch, getState } = setupStore([]);
|
||
|
||
dispatch(actions.messagesAdd([stubPackets.get("console.clear()")]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
expect(messages.size).toBe(1);
|
||
expect(getFirstMessage(getState()).parameters[0]).toBe(
|
||
"Console was cleared."
|
||
);
|
||
});
|
||
|
||
it("clears the messages list in response to MESSAGES_CLEAR action", () => {
|
||
const { dispatch, getState } = setupStore([
|
||
"console.log('foobar', 'test')",
|
||
"console.log('foobar', 'test')",
|
||
"console.log(undefined)",
|
||
"console.table(['red', 'green', 'blue']);",
|
||
"console.group('bar')",
|
||
]);
|
||
|
||
dispatch(actions.messagesClear());
|
||
|
||
const state = getState();
|
||
expect(getMutableMessagesById(state).size).toBe(0);
|
||
expect(getVisibleMessages(state).length).toBe(0);
|
||
expect(getAllMessagesUiById(state).length).toBe(0);
|
||
expect(getGroupsById(state).size).toBe(0);
|
||
expect(getAllCssMessagesMatchingElements(state).size).toBe(0);
|
||
expect(getCurrentGroup(state)).toBe(null);
|
||
expect(getAllRepeatById(state)).toEqual({});
|
||
expect(state.messages.mutableMessagesOrder).toEqual([]);
|
||
});
|
||
|
||
it("cleans the repeatsById object when messages are pruned", () => {
|
||
const { dispatch, getState } = setupStore(
|
||
[
|
||
"console.log('foobar', 'test')",
|
||
"console.log('foobar', 'test')",
|
||
"console.log(undefined)",
|
||
"console.log(undefined)",
|
||
],
|
||
{
|
||
actions,
|
||
storeOptions: {
|
||
logLimit: 2,
|
||
},
|
||
}
|
||
);
|
||
|
||
// Check that we have the expected data.
|
||
let repeats = getAllRepeatById(getState());
|
||
expect(Object.keys(repeats).length).toBe(2);
|
||
const lastMessageId = getLastMessage(getState()).id;
|
||
|
||
// This addition will prune the first message out of the store.
|
||
let packet = stubPackets.get("console.log('foobar', 'test')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
repeats = getAllRepeatById(getState());
|
||
|
||
// There should be only the data for the "undefined" message.
|
||
expect(Object.keys(repeats)).toEqual([lastMessageId]);
|
||
expect(Object.keys(repeats).length).toBe(1);
|
||
expect(repeats[lastMessageId]).toBe(2);
|
||
|
||
// This addition will prune the first message out of the store.
|
||
packet = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// repeatById should now be empty.
|
||
expect(getAllRepeatById(getState())).toEqual({});
|
||
});
|
||
|
||
it("properly limits number of messages", () => {
|
||
const logLimit = 1000;
|
||
const { dispatch, getState } = setupStore([], {
|
||
storeOptions: {
|
||
logLimit,
|
||
},
|
||
});
|
||
|
||
const packet = clonePacket(stubPackets.get("console.log(undefined)"));
|
||
|
||
for (let i = 1; i <= logLimit + 2; i++) {
|
||
packet.arguments = [`message num ${i}`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
}
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(logLimit);
|
||
expect(getFirstMessage(getState()).parameters[0]).toBe(`message num 3`);
|
||
expect(getLastMessage(getState()).parameters[0]).toBe(
|
||
`message num ${logLimit + 2}`
|
||
);
|
||
|
||
const { mutableMessagesOrder } = getState().messages;
|
||
expect(mutableMessagesOrder.length).toBe(logLimit);
|
||
});
|
||
|
||
it("properly limits number of messages when there are nested groups", () => {
|
||
const logLimit = 1000;
|
||
const { dispatch, getState } = setupStore([], {
|
||
storeOptions: {
|
||
logLimit,
|
||
},
|
||
});
|
||
|
||
const packet = clonePacket(stubPackets.get("console.log(undefined)"));
|
||
const packetGroup = clonePacket(stubPackets.get("console.group('bar')"));
|
||
const packetGroupEnd = clonePacket(stubPackets.get("console.groupEnd()"));
|
||
|
||
packetGroup.arguments = [`group-1`];
|
||
dispatch(actions.messagesAdd([packetGroup]));
|
||
packetGroup.arguments = [`group-1-1`];
|
||
dispatch(actions.messagesAdd([packetGroup]));
|
||
packetGroup.arguments = [`group-1-1-1`];
|
||
dispatch(actions.messagesAdd([packetGroup]));
|
||
packet.arguments = [`message-in-group-1`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
packet.arguments = [`message-in-group-2`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
// Closing group-1-1-1
|
||
dispatch(actions.messagesAdd([packetGroupEnd]));
|
||
// Closing group-1-1
|
||
dispatch(actions.messagesAdd([packetGroupEnd]));
|
||
// Closing group-1
|
||
dispatch(actions.messagesAdd([packetGroupEnd]));
|
||
|
||
for (let i = 0; i < logLimit; i++) {
|
||
packet.arguments = [`message-${i}`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
}
|
||
|
||
const visibleMessages = getVisibleMessages(getState());
|
||
const messages = getMutableMessagesById(getState());
|
||
const { mutableMessagesOrder } = getState().messages;
|
||
|
||
expect(messages.size).toBe(logLimit);
|
||
expect(visibleMessages.length).toBe(logLimit);
|
||
expect(mutableMessagesOrder.length).toBe(logLimit);
|
||
|
||
expect(messages.get(visibleMessages[0]).parameters[0]).toBe(`message-0`);
|
||
expect(messages.get(visibleMessages[logLimit - 1]).parameters[0]).toBe(
|
||
`message-${logLimit - 1}`
|
||
);
|
||
|
||
// The groups were cleaned up.
|
||
const groups = getGroupsById(getState());
|
||
expect(groups.size).toBe(0);
|
||
});
|
||
|
||
it("properly limits number of groups", () => {
|
||
const logLimit = 100;
|
||
const { dispatch, getState } = setupStore([], {
|
||
storeOptions: { logLimit },
|
||
});
|
||
|
||
const packet = clonePacket(stubPackets.get("console.log(undefined)"));
|
||
const packetGroup = clonePacket(stubPackets.get("console.group('bar')"));
|
||
const packetGroupEnd = clonePacket(stubPackets.get("console.groupEnd()"));
|
||
|
||
for (let i = 0; i < logLimit + 2; i++) {
|
||
dispatch(actions.messagesAdd([packetGroup]));
|
||
packet.arguments = [`message-${i}-a`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
packet.arguments = [`message-${i}-b`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
dispatch(actions.messagesAdd([packetGroupEnd]));
|
||
}
|
||
|
||
const visibleMessages = getVisibleMessages(getState());
|
||
const messages = getMutableMessagesById(getState());
|
||
// We should have three times the logLimit since each group has one message inside.
|
||
expect(messages.size).toBe(logLimit * 3);
|
||
|
||
// We should have logLimit number of groups
|
||
const groups = getGroupsById(getState());
|
||
expect(groups.size).toBe(logLimit);
|
||
|
||
expect(messages.get(visibleMessages[1]).parameters[0]).toBe(
|
||
`message-2-a`
|
||
);
|
||
expect(getLastMessage(getState()).parameters[0]).toBe(
|
||
`message-${logLimit + 1}-b`
|
||
);
|
||
});
|
||
|
||
it("properly limits number of collapsed groups", () => {
|
||
const logLimit = 100;
|
||
const { dispatch, getState } = setupStore([], {
|
||
storeOptions: { logLimit },
|
||
});
|
||
|
||
const packet = clonePacket(stubPackets.get("console.log(undefined)"));
|
||
const packetGroupCollapsed = clonePacket(
|
||
stubPackets.get("console.groupCollapsed('foo')")
|
||
);
|
||
const packetGroupEnd = clonePacket(stubPackets.get("console.groupEnd()"));
|
||
|
||
for (let i = 0; i < logLimit + 2; i++) {
|
||
packetGroupCollapsed.arguments = [`group-${i}`];
|
||
dispatch(actions.messagesAdd([packetGroupCollapsed]));
|
||
packet.arguments = [`message-${i}-a`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
packet.arguments = [`message-${i}-b`];
|
||
dispatch(actions.messagesAdd([packet]));
|
||
dispatch(actions.messagesAdd([packetGroupEnd]));
|
||
}
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
// We should have three times the logLimit since each group has two message inside.
|
||
expect(messages.size).toBe(logLimit * 3);
|
||
|
||
// We should have logLimit number of groups
|
||
const groups = getGroupsById(getState());
|
||
expect(groups.size).toBe(logLimit);
|
||
|
||
expect(getFirstMessage(getState()).parameters[0]).toBe(`group-2`);
|
||
expect(getLastMessage(getState()).parameters[0]).toBe(
|
||
`message-${logLimit + 1}-b`
|
||
);
|
||
|
||
const visibleMessages = getVisibleMessages(getState());
|
||
expect(visibleMessages.length).toBe(logLimit);
|
||
const lastVisibleMessageId = visibleMessages[visibleMessages.length - 1];
|
||
expect(messages.get(lastVisibleMessageId).parameters[0]).toBe(
|
||
`group-${logLimit + 1}`
|
||
);
|
||
});
|
||
|
||
it("does not add null messages to the store", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const message = stubPackets.get("console.time('bar')");
|
||
dispatch(actions.messagesAdd([message]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(0);
|
||
});
|
||
|
||
it("adds console.table call with unsupported type as console.log", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const packet = stubPackets.get("console.table('bar')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const tableMessage = getLastMessage(getState());
|
||
expect(tableMessage.level).toEqual(MESSAGE_TYPE.LOG);
|
||
});
|
||
|
||
it("adds console.group messages to the store", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const message = stubPackets.get("console.group('bar')");
|
||
dispatch(actions.messagesAdd([message]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(1);
|
||
});
|
||
|
||
it("adds messages in console.group to the store", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const groupPacket = stubPackets.get("console.group('bar')");
|
||
const groupEndPacket = stubPackets.get("console.groupEnd('bar')");
|
||
const logPacket = stubPackets.get("console.log('foobar', 'test')");
|
||
|
||
const packets = [
|
||
groupPacket,
|
||
logPacket,
|
||
groupPacket,
|
||
groupPacket,
|
||
logPacket,
|
||
groupEndPacket,
|
||
logPacket,
|
||
groupEndPacket,
|
||
logPacket,
|
||
groupEndPacket,
|
||
logPacket,
|
||
];
|
||
dispatch(actions.messagesAdd(packets));
|
||
|
||
// Here is what we should have (8 messages)
|
||
// ▼ bar
|
||
// | foobar test
|
||
// | ▼ bar
|
||
// | | ▼ bar
|
||
// | | | foobar test
|
||
// | | foobar test
|
||
// | foobar test
|
||
// foobar test
|
||
|
||
const isNotGroupEnd = p => p !== groupEndPacket;
|
||
const messageCount = packets.filter(isNotGroupEnd).length;
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
const visibleMessages = getVisibleMessages(getState());
|
||
expect(messages.size).toBe(messageCount);
|
||
expect(visibleMessages.length).toBe(messageCount);
|
||
});
|
||
|
||
it("sets groupId property as expected", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
dispatch(
|
||
actions.messagesAdd([
|
||
stubPackets.get("console.group('bar')"),
|
||
stubPackets.get("console.log('foobar', 'test')"),
|
||
])
|
||
);
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(2);
|
||
expect(getLastMessage(getState()).groupId).toBe(
|
||
getFirstMessage(getState()).id
|
||
);
|
||
});
|
||
|
||
it("does not display console.groupEnd messages to the store", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const message = stubPackets.get("console.groupEnd('bar')");
|
||
dispatch(actions.messagesAdd([message]));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(0);
|
||
});
|
||
|
||
it("filters out message added after a console.groupCollapsed message", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
dispatch(
|
||
actions.messagesAdd([
|
||
stubPackets.get("console.groupCollapsed('foo')"),
|
||
stubPackets.get("console.log('foobar', 'test')"),
|
||
])
|
||
);
|
||
|
||
const messages = getVisibleMessages(getState());
|
||
expect(messages.length).toBe(1);
|
||
});
|
||
|
||
it("adds console.dirxml call as console.log", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const packet = stubPackets.get("console.dirxml(window)");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const dirxmlMessage = getLastMessage(getState());
|
||
expect(dirxmlMessage.level).toEqual(MESSAGE_TYPE.LOG);
|
||
});
|
||
|
||
it("does not throw when adding incomplete console.count packet", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
const packet = clonePacket(stubPackets.get(`console.count('bar')`));
|
||
|
||
// Remove counter information to mimick packet we receive in the browser console.
|
||
delete packet.counter;
|
||
|
||
dispatch(actions.messagesAdd([packet]));
|
||
// The message should not be added to the state.
|
||
expect(getMutableMessagesById(getState()).size).toBe(0);
|
||
});
|
||
});
|
||
|
||
describe("mutableMessagesOrder", () => {
|
||
it("adds a message to an empty store", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const packet = stubPackets.get("console.log('foobar', 'test')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const { mutableMessagesOrder } = getState().messages;
|
||
expect(mutableMessagesOrder.length).toBe(1);
|
||
expect(mutableMessagesOrder[0]).toBe(
|
||
// Don't get getMessageIndexAt/getFirstMessage since it relies on mutableMessagesOrder
|
||
[...getMutableMessagesById(getState()).keys()][0]
|
||
);
|
||
});
|
||
|
||
it("reorder messages", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const naNpacket = stubPackets.get("console.log(NaN)");
|
||
dispatch(actions.messagesAdd([naNpacket]));
|
||
|
||
// Add a message that has a shorter timestamp than the previous one, and thus, should
|
||
// be displayed before
|
||
const nullPacket = clonePacket(stubPackets.get("console.log(null)"));
|
||
nullPacket.timeStamp = naNpacket.timeStamp - 10;
|
||
dispatch(actions.messagesAdd([nullPacket]));
|
||
|
||
// Add a message that should be display between the 2 previous messages
|
||
const undefinedPacket = clonePacket(
|
||
stubPackets.get("console.log(undefined)")
|
||
);
|
||
undefinedPacket.timeStamp = naNpacket.timeStamp - 5;
|
||
dispatch(actions.messagesAdd([undefinedPacket]));
|
||
|
||
const { mutableMessagesOrder } = getState().messages;
|
||
const [nanMessage, nullMessage, undefinedMessage] = [
|
||
...getMutableMessagesById(getState()).values(),
|
||
];
|
||
const visibleMessages = getVisibleMessages(getState());
|
||
|
||
// Checking that messages in the Map are the expected ones
|
||
expect(nanMessage.parameters[0].type).toBe("NaN");
|
||
expect(nullMessage.parameters[0].type).toBe("null");
|
||
expect(undefinedMessage.parameters[0].type).toBe("undefined");
|
||
|
||
// Check that mutableMessagesOrder has the message ids in the chronological order
|
||
expect(mutableMessagesOrder).toEqual([
|
||
nullMessage.id,
|
||
undefinedMessage.id,
|
||
nanMessage.id,
|
||
]);
|
||
|
||
// Since we didn't filtered anything, visibleMessages should be similar to mutableMessagesOrder
|
||
expect(mutableMessagesOrder).toEqual(visibleMessages);
|
||
|
||
// Check that visibleMessages is computed from mutableMessagesOrder when filtering
|
||
dispatch(actions.filterToggle("log"));
|
||
expect(getVisibleMessages(getState())).toEqual([]);
|
||
dispatch(actions.filterToggle("log"));
|
||
expect(getVisibleMessages(getState())).toEqual([
|
||
nullMessage.id,
|
||
undefinedMessage.id,
|
||
nanMessage.id,
|
||
]);
|
||
});
|
||
});
|
||
|
||
describe("expandedMessageIds", () => {
|
||
it("opens console.trace messages when they are added", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const message = stubPackets.get("console.trace()");
|
||
dispatch(actions.messagesAdd([message]));
|
||
|
||
const expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(1);
|
||
expect(expanded[0]).toBe(getFirstMessage(getState()).id);
|
||
});
|
||
|
||
it("clears the messages UI list in response to MESSAGES_CLEAR action", () => {
|
||
const { dispatch, getState } = setupStore([
|
||
"console.log('foobar', 'test')",
|
||
"console.log(undefined)",
|
||
]);
|
||
|
||
const traceMessage = stubPackets.get("console.trace()");
|
||
dispatch(actions.messagesAdd([traceMessage]));
|
||
|
||
dispatch(actions.messagesClear());
|
||
|
||
const expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(0);
|
||
});
|
||
|
||
it("cleans the messages UI list when messages are pruned", () => {
|
||
const { dispatch, getState } = setupStore(
|
||
["console.trace()", "console.log(undefined)", "console.trace()"],
|
||
{
|
||
storeOptions: {
|
||
logLimit: 3,
|
||
},
|
||
}
|
||
);
|
||
|
||
// Check that we have the expected data.
|
||
let expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(2);
|
||
expect(expanded[0]).toBe(getFirstMessage(getState()).id);
|
||
const lastMessageId = getLastMessage(getState()).id;
|
||
expect(expanded[expanded.length - 1]).toBe(lastMessageId);
|
||
|
||
// This addition will prune the first message out of the store.
|
||
let packet = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
expanded = getAllMessagesUiById(getState());
|
||
|
||
// There should be only the id of the last console.trace message.
|
||
expect(expanded.length).toBe(1);
|
||
expect(expanded[0]).toBe(lastMessageId);
|
||
|
||
// These additions will prune the last console.trace message out of the store.
|
||
packet = stubPackets.get("console.log('foobar', 'test')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
packet = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// expandedMessageIds should now be empty.
|
||
expect(getAllMessagesUiById(getState()).length).toBe(0);
|
||
});
|
||
|
||
it("opens console.group messages when they are added", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const message = stubPackets.get("console.group('bar')");
|
||
dispatch(actions.messagesAdd([message]));
|
||
|
||
const expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(1);
|
||
expect(expanded[0]).toBe(getFirstMessage(getState()).id);
|
||
});
|
||
|
||
it("does not open console.groupCollapsed messages when they are added", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const message = stubPackets.get("console.groupCollapsed('foo')");
|
||
dispatch(actions.messagesAdd([message]));
|
||
|
||
const expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(0);
|
||
});
|
||
|
||
it("reacts to messageClose/messageOpen actions on console.group", () => {
|
||
const { dispatch, getState } = setupStore(["console.group('bar')"]);
|
||
const firstMessageId = getFirstMessage(getState()).id;
|
||
|
||
let expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(1);
|
||
expect(expanded[0]).toBe(firstMessageId);
|
||
|
||
dispatch(actions.messageClose(firstMessageId));
|
||
|
||
expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(0);
|
||
|
||
dispatch(actions.messageOpen(firstMessageId));
|
||
|
||
expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(1);
|
||
expect(expanded[0]).toBe(firstMessageId);
|
||
});
|
||
|
||
it("reacts to messageClose/messageOpen actions on exception", () => {
|
||
const { dispatch, getState } = setupStore([
|
||
"ReferenceError: asdf is not defined",
|
||
]);
|
||
const firstMessageId = getFirstMessage(getState()).id;
|
||
|
||
let expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(0);
|
||
|
||
dispatch(actions.messageOpen(firstMessageId));
|
||
|
||
expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(1);
|
||
expect(expanded[0]).toBe(firstMessageId);
|
||
|
||
dispatch(actions.messageClose(firstMessageId));
|
||
|
||
expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(0);
|
||
});
|
||
});
|
||
|
||
describe("currentGroup", () => {
|
||
it("sets the currentGroup when console.group message is added", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const packet = stubPackets.get("console.group('bar')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
const currentGroup = getCurrentGroup(getState());
|
||
expect(currentGroup).toBe(getFirstMessage(getState()).id);
|
||
});
|
||
|
||
it("sets currentGroup to expected value when console.groupEnd is added", () => {
|
||
const { dispatch, getState } = setupStore([
|
||
"console.group('bar')",
|
||
"console.groupCollapsed('foo')",
|
||
"console.group('bar')",
|
||
"console.groupEnd('bar')",
|
||
]);
|
||
|
||
let currentGroup = getCurrentGroup(getState());
|
||
expect(currentGroup).toBe(getMessageAt(getState(), 1).id);
|
||
|
||
const endFooPacket = stubPackets.get("console.groupEnd('foo')");
|
||
dispatch(actions.messagesAdd([endFooPacket]));
|
||
currentGroup = getCurrentGroup(getState());
|
||
expect(currentGroup).toBe(getFirstMessage(getState()).id);
|
||
|
||
const endBarPacket = stubPackets.get("console.groupEnd('bar')");
|
||
dispatch(actions.messagesAdd([endBarPacket]));
|
||
currentGroup = getCurrentGroup(getState());
|
||
expect(currentGroup).toBe(null);
|
||
});
|
||
|
||
it("resets the currentGroup to null in response to MESSAGES_CLEAR action", () => {
|
||
const { dispatch, getState } = setupStore(["console.group('bar')"]);
|
||
|
||
dispatch(actions.messagesClear());
|
||
|
||
const currentGroup = getCurrentGroup(getState());
|
||
expect(currentGroup).toBe(null);
|
||
});
|
||
});
|
||
|
||
describe("groupsById", () => {
|
||
it("adds the group with expected array when console.group message is added", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
const barPacket = stubPackets.get("console.group('bar')");
|
||
dispatch(actions.messagesAdd([barPacket]));
|
||
|
||
let groupsById = getGroupsById(getState());
|
||
expect(groupsById.size).toBe(1);
|
||
expect(groupsById.has(getFirstMessage(getState()).id)).toBe(true);
|
||
expect(groupsById.get(getFirstMessage(getState()).id)).toEqual([]);
|
||
|
||
const fooPacket = stubPackets.get("console.groupCollapsed('foo')");
|
||
dispatch(actions.messagesAdd([fooPacket]));
|
||
|
||
groupsById = getGroupsById(getState());
|
||
expect(groupsById.size).toBe(2);
|
||
expect(groupsById.has(getLastMessage(getState()).id)).toBe(true);
|
||
expect(groupsById.get(getLastMessage(getState()).id)).toEqual([
|
||
getFirstMessage(getState()).id,
|
||
]);
|
||
});
|
||
|
||
it("resets groupsById in response to MESSAGES_CLEAR action", () => {
|
||
const { dispatch, getState } = setupStore([
|
||
"console.group('bar')",
|
||
"console.groupCollapsed('foo')",
|
||
]);
|
||
|
||
let groupsById = getGroupsById(getState());
|
||
expect(groupsById.size).toBe(2);
|
||
|
||
dispatch(actions.messagesClear());
|
||
|
||
groupsById = getGroupsById(getState());
|
||
expect(groupsById.size).toBe(0);
|
||
});
|
||
|
||
it("cleans the groupsById property when messages are pruned", () => {
|
||
const { dispatch, getState } = setupStore(
|
||
[
|
||
"console.group('bar')",
|
||
"console.group()",
|
||
"console.groupEnd()",
|
||
"console.groupEnd('bar')",
|
||
"console.group('bar')",
|
||
"console.groupEnd('bar')",
|
||
"console.log('foobar', 'test')",
|
||
],
|
||
{
|
||
actions,
|
||
storeOptions: {
|
||
logLimit: 3,
|
||
},
|
||
}
|
||
);
|
||
|
||
/*
|
||
* Here is the initial state of the console:
|
||
* ▶︎ bar
|
||
* ▶︎ noLabel
|
||
* ▶︎ bar
|
||
* foobar test
|
||
*/
|
||
|
||
// Check that we have the expected data.
|
||
let groupsById = getGroupsById(getState());
|
||
expect(groupsById.size).toBe(3);
|
||
|
||
// This addition will prune the first group (and its child group) out of the store.
|
||
/*
|
||
* ▶︎ bar
|
||
* foobar test
|
||
* undefined
|
||
*/
|
||
let packet = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
groupsById = getGroupsById(getState());
|
||
|
||
// There should be only the id of the last console.group message.
|
||
expect(groupsById.size).toBe(1);
|
||
|
||
// This additions will prune the last group message out of the store.
|
||
/*
|
||
* foobar test
|
||
* undefined
|
||
* foobar test
|
||
*/
|
||
packet = stubPackets.get("console.log('foobar', 'test')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// groupsById should now be empty.
|
||
expect(getGroupsById(getState()).size).toBe(0);
|
||
});
|
||
});
|
||
|
||
describe("networkMessagesUpdateById", () => {
|
||
it("adds the network update message when network update action is called", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
let packet = clonePacket(stubPackets.get("GET request"));
|
||
let updatePacket = clonePacket(stubPackets.get("GET request update"));
|
||
|
||
packet.actor = "message1";
|
||
updatePacket.actor = "message1";
|
||
dispatch(actions.messagesAdd([packet]));
|
||
dispatch(actions.networkMessageUpdates([updatePacket], null));
|
||
|
||
let networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(Object.keys(networkUpdates)).toEqual(["message1"]);
|
||
|
||
packet = clonePacket(stubPackets.get("GET request"));
|
||
updatePacket = stubPackets.get("XHR GET request update");
|
||
packet.actor = "message2";
|
||
updatePacket.actor = "message2";
|
||
dispatch(actions.messagesAdd([packet]));
|
||
dispatch(actions.networkMessageUpdates([updatePacket], null));
|
||
|
||
networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(Object.keys(networkUpdates)).toEqual(["message1", "message2"]);
|
||
});
|
||
|
||
it("resets networkMessagesUpdateById in response to MESSAGES_CLEAR action", () => {
|
||
const { dispatch, getState } = setupStore(["XHR GET request"]);
|
||
|
||
const updatePacket = stubPackets.get("XHR GET request update");
|
||
dispatch(actions.networkMessageUpdates([updatePacket], null));
|
||
|
||
let networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(!!Object.keys(networkUpdates).length).toBe(true);
|
||
|
||
dispatch(actions.messagesClear());
|
||
|
||
networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(Object.keys(networkUpdates).length).toBe(0);
|
||
});
|
||
|
||
it("cleans the networkMessagesUpdateById property when messages are pruned", () => {
|
||
const { dispatch, getState } = setupStore([], {
|
||
storeOptions: {
|
||
logLimit: 3,
|
||
},
|
||
});
|
||
|
||
// Add 3 network messages and their updates
|
||
let packet = clonePacket(stubPackets.get("XHR GET request"));
|
||
const updatePacket = clonePacket(
|
||
stubPackets.get("XHR GET request update")
|
||
);
|
||
packet.actor = "message1";
|
||
updatePacket.actor = "message1";
|
||
dispatch(actions.messagesAdd([packet]));
|
||
dispatch(actions.networkMessageUpdates([updatePacket], null));
|
||
|
||
packet.actor = "message2";
|
||
updatePacket.actor = "message2";
|
||
dispatch(actions.messagesAdd([packet]));
|
||
dispatch(actions.networkMessageUpdates([updatePacket], null));
|
||
|
||
packet.actor = "message3";
|
||
updatePacket.actor = "message3";
|
||
dispatch(actions.messagesAdd([packet]));
|
||
dispatch(actions.networkMessageUpdates([updatePacket], null));
|
||
|
||
// Check that we have the expected data.
|
||
const messages = getMutableMessagesById(getState());
|
||
const [
|
||
firstNetworkMessageId,
|
||
secondNetworkMessageId,
|
||
thirdNetworkMessageId,
|
||
] = [...messages.keys()];
|
||
|
||
let networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(Object.keys(networkUpdates)).toEqual([
|
||
firstNetworkMessageId,
|
||
secondNetworkMessageId,
|
||
thirdNetworkMessageId,
|
||
]);
|
||
|
||
// This addition will remove the first network message.
|
||
packet = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(Object.keys(networkUpdates)).toEqual([
|
||
secondNetworkMessageId,
|
||
thirdNetworkMessageId,
|
||
]);
|
||
|
||
// This addition will remove the second network message.
|
||
packet = stubPackets.get("console.log('foobar', 'test')");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(Object.keys(networkUpdates)).toEqual([thirdNetworkMessageId]);
|
||
|
||
// This addition will remove the last network message.
|
||
packet = stubPackets.get("console.log(undefined)");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
// networkMessageUpdateById should now be empty.
|
||
networkUpdates = getAllNetworkMessagesUpdateById(getState());
|
||
expect(Object.keys(networkUpdates)).toEqual([]);
|
||
});
|
||
});
|
||
|
||
describe("cssMessagesMatchingElements", () => {
|
||
it("resets cssMessagesMatchingElements in response to MESSAGES_CLEAR action", () => {
|
||
const { dispatch, getState } = setupStore([
|
||
`Unknown property ‘such-unknown-property’. Declaration dropped.`,
|
||
]);
|
||
|
||
const data = Symbol();
|
||
dispatch({
|
||
type: CSS_MESSAGE_ADD_MATCHING_ELEMENTS,
|
||
id: getFirstMessage(getState()).id,
|
||
elements: data,
|
||
});
|
||
|
||
const matchingElements = getAllCssMessagesMatchingElements(getState());
|
||
expect(matchingElements.size).toBe(1);
|
||
expect(matchingElements.get(getFirstMessage(getState()).id)).toBe(data);
|
||
|
||
dispatch(actions.messagesClear());
|
||
|
||
expect(getAllCssMessagesMatchingElements(getState()).size).toBe(0);
|
||
});
|
||
|
||
it("cleans the cssMessagesMatchingElements property when messages are pruned", () => {
|
||
const { dispatch, getState } = setupStore([], {
|
||
storeOptions: {
|
||
logLimit: 2,
|
||
},
|
||
});
|
||
|
||
// Add 2 css warnings message and their associated data.
|
||
dispatch(
|
||
actions.messagesAdd([
|
||
stubPackets.get(
|
||
`Unknown property ‘such-unknown-property’. Declaration dropped.`
|
||
),
|
||
])
|
||
);
|
||
dispatch(
|
||
actions.messagesAdd([
|
||
stubPackets.get(
|
||
`Error in parsing value for ‘padding-top’. Declaration dropped.`
|
||
),
|
||
])
|
||
);
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
|
||
const data1 = Symbol();
|
||
const data2 = Symbol();
|
||
const [id1, id2] = [...messages.keys()];
|
||
|
||
dispatch({
|
||
type: CSS_MESSAGE_ADD_MATCHING_ELEMENTS,
|
||
id: id1,
|
||
elements: data1,
|
||
});
|
||
dispatch({
|
||
type: CSS_MESSAGE_ADD_MATCHING_ELEMENTS,
|
||
id: id2,
|
||
elements: data2,
|
||
});
|
||
|
||
let matchingElements = getAllCssMessagesMatchingElements(getState());
|
||
expect(matchingElements.size).toBe(2);
|
||
|
||
// This addition will remove the first css warning.
|
||
dispatch(
|
||
actions.messagesAdd([stubPackets.get("console.log(undefined)")])
|
||
);
|
||
|
||
matchingElements = getAllCssMessagesMatchingElements(getState());
|
||
expect(matchingElements.size).toBe(1);
|
||
expect(matchingElements.get(id2)).toBe(data2);
|
||
|
||
// This addition will remove the second css warning.
|
||
dispatch(
|
||
actions.messagesAdd([stubPackets.get("console.log('foobar', 'test')")])
|
||
);
|
||
|
||
expect(getAllCssMessagesMatchingElements(getState()).size).toBe(0);
|
||
});
|
||
});
|
||
|
||
describe("messagesAdd", () => {
|
||
it("still log repeated message over logLimit, but only repeated ones", () => {
|
||
// Log two distinct messages
|
||
const key1 = "console.log('foobar', 'test')";
|
||
const key2 = "console.log(undefined)";
|
||
const { dispatch, getState } = setupStore([key1, key2], {
|
||
storeOptions: {
|
||
logLimit: 2,
|
||
},
|
||
});
|
||
|
||
// Then repeat the last one two times and log the first one again
|
||
const packet1 = clonePacket(stubPackets.get(key2));
|
||
const packet2 = clonePacket(stubPackets.get(key2));
|
||
const packet3 = clonePacket(stubPackets.get(key1));
|
||
|
||
// Repeat ID must be the same even if the timestamp is different.
|
||
packet1.timeStamp = packet1.timeStamp + 1;
|
||
packet2.timeStamp = packet2.timeStamp + 2;
|
||
packet3.timeStamp = packet3.timeStamp + 3;
|
||
dispatch(actions.messagesAdd([packet1, packet2, packet3]));
|
||
|
||
// There is still only two messages being logged,
|
||
const messages = getMutableMessagesById(getState());
|
||
expect(messages.size).toBe(2);
|
||
|
||
// the second one being repeated 3 times
|
||
const repeat = getAllRepeatById(getState());
|
||
expect(repeat[getFirstMessage(getState()).id]).toBe(3);
|
||
expect(repeat[getLastMessage(getState()).id]).toBe(undefined);
|
||
});
|
||
});
|
||
|
||
describe("messageRemove", () => {
|
||
it("removes the message from the store", () => {
|
||
const { dispatch, getState } = setupStore([
|
||
"console.trace()",
|
||
"console.log(undefined)",
|
||
"console.trace()",
|
||
"console.log(undefined)",
|
||
]);
|
||
|
||
let expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(2);
|
||
|
||
const secondTraceMessage = getMessageAt(getState(), 2);
|
||
dispatch(actions.messageRemove(secondTraceMessage.id));
|
||
|
||
const messages = getMutableMessagesById(getState());
|
||
const { mutableMessagesOrder } = getState().messages;
|
||
// The messages was removed
|
||
expect(messages.size).toBe(3);
|
||
expect(mutableMessagesOrder.length).toBe(3);
|
||
|
||
// Its id was removed from the messagesUI property as well
|
||
expanded = getAllMessagesUiById(getState());
|
||
expect(expanded.length).toBe(1);
|
||
expect(expanded.includes(secondTraceMessage.id)).toBeFalsy();
|
||
});
|
||
});
|
||
|
||
describe("disabledMessagesById", () => {
|
||
it("adds messages ids to disabledMessagesById when message disable action is called", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
dispatch(actions.messagesDisable(["message1", "message2"]));
|
||
|
||
const disabledMessages = getAllDisabledMessagesById(getState());
|
||
expect(disabledMessages).toEqual(["message1", "message2"]);
|
||
});
|
||
|
||
it("clears disabledMessagesById in response to MESSAGES_CLEAR action", () => {
|
||
const { dispatch, getState } = setupStore();
|
||
|
||
dispatch(actions.messagesDisable(["message1", "message2"]));
|
||
|
||
let disabledMessages = getAllDisabledMessagesById(getState());
|
||
expect(disabledMessages).toEqual(["message1", "message2"]);
|
||
|
||
dispatch(actions.messagesClear());
|
||
|
||
disabledMessages = getAllDisabledMessagesById(getState());
|
||
expect(disabledMessages).toEqual([]);
|
||
});
|
||
|
||
it("remove message id from disabledMessagesById when the message is removed", () => {
|
||
const { dispatch, getState } = setupStore(
|
||
[
|
||
"console.log('foobar', 'test')",
|
||
"XHR GET request update",
|
||
"console.log(undefined)",
|
||
],
|
||
{
|
||
actions,
|
||
storeOptions: {
|
||
logLimit: 3,
|
||
},
|
||
}
|
||
);
|
||
|
||
// This is `console.log('foobar', 'test'`
|
||
const firstMessageId = getMessageAt(getState(), 0).id;
|
||
// This is for `XHR GET request update`
|
||
const secondMessageId = getMessageAt(getState(), 1).id;
|
||
|
||
dispatch(actions.messagesDisable([firstMessageId, secondMessageId]));
|
||
|
||
let disabledMessages = getAllDisabledMessagesById(getState());
|
||
expect(disabledMessages).toEqual([firstMessageId, secondMessageId]);
|
||
|
||
// Adding a new message should prune the first(oldest) message and should
|
||
// remove its id from the disabled messages list.
|
||
const packet = stubPackets.get("GET request");
|
||
dispatch(actions.messagesAdd([packet]));
|
||
|
||
disabledMessages = getAllDisabledMessagesById(getState());
|
||
expect(disabledMessages).toEqual([secondMessageId]);
|
||
});
|
||
});
|
||
});
|