All files / src requestResponseLog.ts

100% Statements 54/54
100% Branches 24/24
100% Functions 9/9
100% Lines 54/54

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113  1x 1x 1x   1x 1x   1x 1x     8x     1475x 9x   1475x   1x   9x   9x   9x 9x       1314x 1314x 1x 1x     1313x 1084x 755x   1084x 324x       1313x 1311x 638x       1313x 1313x       6x 6x 1x 1x     5x 5x       168x 168x   168x 168x     168x       1646x       1393x 1391x   2x       168x 168x 168x   168x 670x 168x   502x     670x 670x                    
 
import parser from "fast-xml-parser";
import { promises as fsPromises } from "fs";
import path from "path";
import requestResponseLogEntry from "./requestResponseLogEntry";
import Logger from "./logger";
const log: Logger = new Logger();
 
export default class RequestResponseLog {
    public static readonly defaultLogDirectory: string = "RequestResponseLog/";
 
    public static deleteInstance(): void {
        RequestResponseLog.log = null;
    }
    public static getInstance(): RequestResponseLog {
        if (!RequestResponseLog.log) {
            RequestResponseLog.log = new RequestResponseLog();
        }
        return RequestResponseLog.log;
    }
    private static log: RequestResponseLog | null = null;
 
    public baseDirectory: string = RequestResponseLog.defaultLogDirectory;
    private context: string;
    private entries: requestResponseLogEntry[] = [];
    private constructor() {
        this.baseDirectory = RequestResponseLog.defaultLogDirectory;
        this.context = "";
    }
 
    public async addEntry(logEntry: requestResponseLogEntry) {
        log.debug("addEntry");
        if (!this.context) {
            log.debug("Error while recording, context not set");
            throw new Error("Error while recording, context not set");
        }
 
        if (logEntry.response.body && logEntry.response.contentType) {
            if (logEntry.response.contentType.indexOf("application/xml") !== -1) {
                logEntry.response.jsonBody = this.xmlToJson(logEntry.response.body);
            }
            if (logEntry.response.contentType.indexOf("application/json") !== -1) {
                logEntry.response.jsonBody = JSON.parse(logEntry.response.body);
            }
        }
 
        if (logEntry.request.body) {
            if (logEntry.request.body.indexOf && logEntry.request.body.indexOf("<?xml version") !== -1) {
                logEntry.request.jsonBody = this.xmlToJson(logEntry.request.body);
            }
        }
 
        this.entries.push(logEntry);
        await fsPromises.writeFile(this.getFileName(), JSON.stringify(this.entries, null, 4));
    }
 
    public async getEntries(): Promise<requestResponseLogEntry[]> {
        log.debug("getEntries");
        if (!this.context) {
            log.debug("Error while getting recording request, context not set");
            throw new Error("Error while getting recording request, context not set");
        }
 
        const entries: string = await fsPromises.readFile(this.getFileName(), { encoding: "utf8" });
        return JSON.parse(entries);
    }
 
    public async setContext(context: string) {
        log.debug("setContext");
        const newContext: string = context.replace(/ |:|\./g, "_");
        // if (this.context !== newContext) {
        this.context = newContext;
        this.entries = [];
        // }
        // create the directory
        await this.assertDirectory(this.getFileName());
    }
 
    public getFileName(): string {
        return `${this.baseDirectory}${this.context}.json`;
    }
 
    private xmlToJson(xml: string): any {
        if (parser.validate(xml) === true) {
            return parser.parse(xml, { ignoreNameSpace: true });
        }
        return { info: "invalid xml" };
    }
 
    private async assertDirectory(filename: string): Promise<void> {
        const directory = path.dirname(filename);
        const pathArray: string[] = directory.split("/");
        let p: string = "";
 
        for (const dir of pathArray) {
            if (p === "") {
                p = dir;
            } else {
                p = p + "/" + dir;
            }
 
            try {
                await fsPromises.mkdir(p);
                  /* istanbul ignore next */
                  log.debug(`directory "${p}" created`);
            } catch (e) {
                  /* istanbul ignore next */
                  log.debug(`directory "${p}" already exists`);
            }
        }
    }
}