amos-ionic-logging
Version:
Components for Ionic logging
581 lines (423 loc) • 17.6 kB
text/typescript
/* eslint-disable no-magic-numbers */
import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing";
import { getTestBed, TestBed } from "@angular/core/testing";
import * as log4javascript from "log4javascript";
import { AjaxAppender } from "./ajax-appender.model";
import { LocalStorageAppender } from "./local-storage-appender.model";
import { LogMessage } from "./log-message.model";
import { Logger } from "./logger.model";
import { LoggingServiceConfiguration } from "./logging-service.configuration";
import { LoggingService } from "./logging.service";
import { MemoryAppender } from "./memory-appender.model";
describe("LoggingService", () => {
let loggingService: LoggingService;
let httpMock: HttpTestingController;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
providers: [
LoggingService,
],
});
loggingService = TestBed.inject(LoggingService);
httpMock = TestBed.inject(HttpTestingController);
});
afterEach(() => {
httpMock.verify();
log4javascript.resetConfiguration();
log4javascript.getRootLogger().removeAllAppenders();
});
describe("ctor()", () => {
it("root logger has log level WARN", () => {
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const browserConsoleAppender = appenders.find((a) => a.toString() === "BrowserConsoleAppender");
browserConsoleAppender.setThreshold(log4javascript.Level.OFF);
loggingService.getRootLogger().info("test");
loggingService.getRootLogger().warn("test");
const messages = loggingService.getLogMessages();
expect(messages.length).toBe(1);
});
});
describe("configure(configuration: LoggingServiceConfiguration): void", () => {
it("throws no error if no configuration is provided", () => {
loggingService.configure(undefined);
});
it("throws no error if configuration is empty", () => {
const config: LoggingServiceConfiguration = {};
loggingService.configure(config);
});
describe("logLevels", () => {
it("throws no error if logLevels is empty", () => {
const logLevels: Array<{ loggerName: string; logLevel: string }> = [];
const config: LoggingServiceConfiguration = {
logLevels,
};
loggingService.configure(config);
});
it("change log level of root logger", () => {
const logLevels = [{ loggerName: "root", logLevel: "INFO" }];
const config: LoggingServiceConfiguration = {
logLevels,
};
loggingService.configure(config);
const internalLogger = new Logger().getInternalLogger();
expect(internalLogger.getEffectiveLevel()).toBe(log4javascript.Level.INFO);
});
it("change log level of custom logger, root logger remains unchanged", () => {
const logLevels = [{ loggerName: "me", logLevel: "INFO" }];
const config: LoggingServiceConfiguration = {
logLevels,
};
loggingService.configure(config);
const internalLoggerMe = new Logger("me").getInternalLogger();
expect(internalLoggerMe.getEffectiveLevel()).toBe(log4javascript.Level.INFO);
const internalLoggerRoot = new Logger().getInternalLogger();
expect(internalLoggerRoot.getEffectiveLevel()).toBe(log4javascript.Level.WARN);
});
it("throws error if custom logger has an invalid log level", () => {
const logLevels = [{ loggerName: "me", logLevel: "xxx" }];
const config: LoggingServiceConfiguration = {
logLevels,
};
expect(() => loggingService.configure(config)).toThrowError("invalid log level xxx");
});
});
describe("ajaxAppender", () => {
it("adds no ajaxAppender if not configured", () => {
const config: LoggingServiceConfiguration = {
};
const internalLogger = new Logger().getInternalLogger();
const oldAppenderCount = internalLogger.getEffectiveAppenders().length;
loggingService.configure(config);
const newAppenderCount = internalLogger.getEffectiveAppenders().length;
expect(newAppenderCount).toBe(oldAppenderCount);
});
it("adds ajaxAppender if configured", () => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
url: "myUrl",
},
};
const internalLogger = new Logger().getInternalLogger();
const oldAppenderCount = internalLogger.getEffectiveAppenders().length;
loggingService.configure(config);
const newAppenderCount = internalLogger.getEffectiveAppenders().length;
expect(newAppenderCount).toBe(oldAppenderCount + 1);
});
it("throws error if ajaxAppender has an invalid threshold", () => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
threshold: "xxx",
url: "myUrl",
},
};
expect(() => loggingService.configure(config)).toThrowError("invalid level xxx");
});
it("ajaxAppender has default threshold of WARN", () => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
url: "myUrl",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const ajaxAppender = appenders.find((a) => a.toString() === "Ionic.Logging.AjaxAppender") as AjaxAppender;
expect(ajaxAppender.getThreshold()).toBe(log4javascript.Level.WARN);
});
it("ajaxAppender has default timer interval of 0", () => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
url: "myUrl",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const ajaxAppender = appenders.find((a) => a.toString() === "Ionic.Logging.AjaxAppender") as AjaxAppender;
expect(ajaxAppender.getInternalAppender().isTimed()).toBeFalsy();
expect(ajaxAppender.getTimerInterval()).toBe(0);
});
it("ajaxAppender has given timer interval", () => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
timerInterval: 1234,
url: "myUrl",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const ajaxAppender = appenders.find((a) => a.toString() === "Ionic.Logging.AjaxAppender") as AjaxAppender;
expect(ajaxAppender.getInternalAppender().isTimed()).toBeTruthy();
expect(ajaxAppender.getTimerInterval()).toBe(1234);
});
it("ajaxAppender has default batch size of 1", () => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
url: "myUrl",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const ajaxAppender = appenders.find((a) => a.toString() === "Ionic.Logging.AjaxAppender") as AjaxAppender;
expect(ajaxAppender.getBatchSize()).toBe(1);
});
it("ajaxAppender has given timer interval", () => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
batchSize: 1234,
url: "myUrl",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const ajaxAppender = appenders.find((a) => a.toString() === "Ionic.Logging.AjaxAppender") as AjaxAppender;
expect(ajaxAppender.getBatchSize()).toBe(1234);
});
});
describe("localStorageAppender", () => {
it("adds no localStorageAppender if not configured", () => {
const config: LoggingServiceConfiguration = {
};
const internalLogger = new Logger().getInternalLogger();
const oldAppenderCount = internalLogger.getEffectiveAppenders().length;
loggingService.configure(config);
const newAppenderCount = internalLogger.getEffectiveAppenders().length;
expect(newAppenderCount).toBe(oldAppenderCount);
});
it("adds localStorageAppender if configured", () => {
const config: LoggingServiceConfiguration = {
localStorageAppender: {
localStorageKey: "myLocalStorage",
},
};
const internalLogger = new Logger().getInternalLogger();
const oldAppenderCount = internalLogger.getEffectiveAppenders().length;
loggingService.configure(config);
const newAppenderCount = internalLogger.getEffectiveAppenders().length;
expect(newAppenderCount).toBe(oldAppenderCount + 1);
});
it("throws error if localStorageAppender has an invalid threshold", () => {
const config: LoggingServiceConfiguration = {
localStorageAppender: {
localStorageKey: "myLocalStorage",
threshold: "xxx",
},
};
expect(() => loggingService.configure(config)).toThrowError("invalid level xxx");
});
it("localStorageAppender has default threshold of WARN", () => {
const config: LoggingServiceConfiguration = {
localStorageAppender: {
localStorageKey: "myLocalStorage",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const localStorageAppender = appenders.find(
(a) => a.toString() === "Ionic.Logging.LocalStorageAppender") as LocalStorageAppender;
expect(localStorageAppender.getThreshold()).toBe(log4javascript.Level.WARN);
});
it("localStorageAppender has given threshold", () => {
const config: LoggingServiceConfiguration = {
localStorageAppender: {
localStorageKey: "myLocalStorage",
threshold: "INFO",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const localStorageAppender = appenders.find(
(a) => a.toString() === "Ionic.Logging.LocalStorageAppender") as LocalStorageAppender;
expect(localStorageAppender.getThreshold()).toBe(log4javascript.Level.INFO);
});
it("localStorageAppender has default max messages of 250", () => {
const config: LoggingServiceConfiguration = {
localStorageAppender: {
localStorageKey: "myLocalStorage",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const localStorageAppender = appenders.find(
(a) => a.toString() === "Ionic.Logging.LocalStorageAppender") as LocalStorageAppender;
expect(localStorageAppender.getMaxMessages()).toBe(250);
});
it("localStorageAppender has given max messages", () => {
const config: LoggingServiceConfiguration = {
localStorageAppender: {
localStorageKey: "myLocalStorage",
maxMessages: 1234,
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const localStorageAppender = appenders.find(
(a) => a.toString() === "Ionic.Logging.LocalStorageAppender") as LocalStorageAppender;
expect(localStorageAppender.getMaxMessages()).toBe(1234);
});
});
describe("memoryAppender", () => {
it("memoryAppender has default max messages of 250", () => {
const config: LoggingServiceConfiguration = {
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const memoryAppender = appenders.find((a) => a.toString() === "Ionic.Logging.MemoryAppender") as MemoryAppender;
expect(memoryAppender.getMaxMessages()).toBe(250);
});
it("memoryAppender has default configuration id memoryAppender configuration is empty", () => {
const config: LoggingServiceConfiguration = {
memoryAppender: {},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const memoryAppender = appenders.find((a) => a.toString() === "Ionic.Logging.MemoryAppender") as MemoryAppender;
expect(memoryAppender.getMaxMessages()).toBe(250);
});
it("memoryAppender has given max messages", () => {
const config: LoggingServiceConfiguration = {
memoryAppender: {
maxMessages: 1234,
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const memoryAppender = appenders.find((a) => a.toString() === "Ionic.Logging.MemoryAppender") as MemoryAppender;
expect(memoryAppender.getMaxMessages()).toBe(1234);
});
});
describe("browserConsoleAppender", () => {
it("browserConsoleAppender has default threshold", () => {
const config: LoggingServiceConfiguration = {
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const browserConsoleAppender = appenders.find((a) => a.toString() === "BrowserConsoleAppender");
expect(browserConsoleAppender.getThreshold()).toBe(log4javascript.Level.ALL);
});
it("empty configuration for browserConsoleAppender", () => {
const config: LoggingServiceConfiguration = {
browserConsoleAppender: {},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const browserConsoleAppender = appenders.find((a) => a.toString() === "BrowserConsoleAppender");
expect(browserConsoleAppender.getThreshold()).toBe(log4javascript.Level.ALL);
});
it("browserConsoleAppender has given threshold", () => {
const config: LoggingServiceConfiguration = {
browserConsoleAppender: {
threshold: "OFF",
},
};
loggingService.configure(config);
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const browserConsoleAppender = appenders.find((a) => a.toString() === "BrowserConsoleAppender");
expect(browserConsoleAppender.getThreshold()).toBe(log4javascript.Level.OFF);
});
});
});
describe("getLogger(loggerName: string): Logger", () => {
it("returns logger with given name", () => {
const logger = loggingService.getLogger("myLogger");
const loggerName = logger.getInternalLogger().name;
expect(loggerName).toBe("myLogger");
});
});
describe("getRootLogger(): Logger", () => {
it("returns logger with root name", () => {
const logger = loggingService.getRootLogger();
const loggerName = logger.getInternalLogger().name;
expect(loggerName).toBe("root");
});
});
describe("getLogMessages(): LogMessage[]", () => {
it("returns empty array if no log message is written", () => {
const messages = loggingService.getLogMessages();
expect(messages.length).toBe(0);
});
it("returns array with written log message", () => {
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const browserConsoleAppender = appenders.find((a) => a.toString() === "BrowserConsoleAppender");
browserConsoleAppender.setThreshold(log4javascript.Level.OFF);
loggingService.getRootLogger().warn("test");
const messages = loggingService.getLogMessages();
expect(messages.length).toBe(1);
});
});
describe("logMessagesChanged: EventEmitter<void>", () => {
it("logged messages are emitted", (done: () => void) => {
const appenders = new Logger().getInternalLogger().getEffectiveAppenders();
const browserConsoleAppender = appenders.find((a) => a.toString() === "BrowserConsoleAppender");
browserConsoleAppender.setThreshold(log4javascript.Level.OFF);
loggingService.logMessagesChanged.subscribe(() => {
expect(1).toBe(loggingService.getLogMessages().length);
done();
});
loggingService.getRootLogger().warn("test");
});
});
describe("ajaxAppenderFailed: EventEmitter<string>", () => {
it("error message emitted", (done: () => void) => {
const config: LoggingServiceConfiguration = {
ajaxAppender: {
url: "badUrl",
},
browserConsoleAppender: {
threshold: "OFF",
},
};
loggingService.configure(config);
loggingService.ajaxAppenderFailed.subscribe((message: string) => {
expect(message).toBe("AjaxAppender.append: XMLHttpRequest request to URL badUrl returned status code 404");
done();
});
loggingService.getRootLogger().warn("test");
});
});
describe("getLogMessagesFromLocalStorage(localStorageKey: string): LogMessage[]", () => {
it("returns empty array if no log message is written", () => {
localStorage.removeItem("xxx");
const messages = loggingService.getLogMessagesFromLocalStorage("xxx");
expect(messages.length).toBe(0);
});
it("returns array with written log message", () => {
const messagesIn = [{
level: "DEBUG",
logger: "myLogger",
message: ["myMessage"],
methodName: "myMethod",
timeStamp: new Date(),
}];
localStorage.setItem("xxx", JSON.stringify(messagesIn));
const messages = loggingService.getLogMessagesFromLocalStorage("xxx");
expect(messages.length).toBe(1);
});
});
describe("removeLogMessages(): void", () => {
it("removes messages", (done: () => void) => {
loggingService.getRootLogger().info("test");
loggingService.logMessagesChanged.subscribe(() => {
expect(loggingService.getLogMessages().length).toBe(0);
done();
});
loggingService.removeLogMessages();
});
});
describe("removeLogMessagesFromLocalStorage(localStorageKey: string): void", () => {
it("removes messages", (done: () => void) => {
const messagesIn = [{
level: "DEBUG",
logger: "myLogger",
message: ["myMessage"],
methodName: "myMethod",
timeStamp: new Date(),
}];
localStorage.setItem("xxx", JSON.stringify(messagesIn));
loggingService.logMessagesChanged.subscribe(() => {
expect(localStorage.getItem("xxx")).toBeNull();
done();
});
loggingService.removeLogMessagesFromLocalStorage("xxx");
});
});
});