All files / Scripts/utils ParentFrameUtils.ts

100% Statements 31/31
78.94% Branches 15/19
100% Functions 8/8
100% Lines 30/30

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  11x 11x         11x             16x   16x 16x 30x 23x 23x 11x         16x               3x 3x   2x                       5x 5x 2x     15x                     4x   4x 4x 3x 6x 6x       1x     4x 4x 2x     4x                 9x                
import { Choice } from "../Choice";
import { diagnostics } from "../Diag";
import { Errors } from "../Errors";
 
/**
 * Utility functions extracted from ParentFrame for better testability
 */
export class ParentFrameUtils {
    /**
     * Parses a query string parameter from the current URL
     * @param variable The parameter name to look for
     * @returns The parameter value or empty string if not found
     */
    static getQueryVariable(variable: string, search: string = window.location.search): string {
        const vars: string[] = search.substring(1).split("&");
 
        let found = "";
        vars.forEach((v: string) => {
            if (found === "") {
                const pair: string[] = v.split("=");
                if (pair[0] === variable) {
                    found = pair[1] ?? "";
                }
            }
        });
 
        return found;
    }
 
    /**
     * Generates a settings key based on the Office host name
     * @returns Settings key string
     */
    static getSettingsKey(): string {
        try {
            return "frame" + Office.context.mailbox.diagnostics.hostName;
        } catch {
            return "frame";
        }
    }
 
    /**
     * Sets the default choice based on query parameter or fallback
     * @param choices Array of available choices
     * @param defaultLabel Default choice label if no query parameter
     * @param search Query string to parse (defaults to window.location.search)
     * @returns Updated choices array with one marked as checked
     */
    static setDefaultChoice(choices: Choice[], defaultLabel = "new", search: string = window.location.search): Choice[] {
        let uiDefault: string = ParentFrameUtils.getQueryVariable("default", search);
        if (!uiDefault) {
            uiDefault = defaultLabel;
        }
 
        return choices.map((choice: Choice) => ({
            ...choice,
            checked: uiDefault === choice.label
        }));
    }
 
    /**
     * Generates diagnostics string from current diagnostic data and errors
     * @returns Formatted diagnostics string
     */
    static getDiagnosticsString(): string {
        let diagnosticsString = "";
 
        try {
            const diagnosticMap = diagnostics.get();
            for (const diag in diagnosticMap) {
                Eif (Object.prototype.hasOwnProperty.call(diagnosticMap, diag)) {
                    diagnosticsString += diag + " = " + diagnosticMap[diag] + "\n";
                }
            }
        } catch {
            diagnosticsString += "ERROR: Failed to get diagnostics\n";
        }
 
        const errors: string[] = Errors.get();
        errors.forEach((error: string) => {
            diagnosticsString += "ERROR: " + error + "\n";
        });
 
        return diagnosticsString;
    }
 
    /**
     * Validates a choice object
     * @param choice The choice to validate
     * @returns True if the choice is valid
     */
    static isValidChoice(choice: unknown): choice is Choice {
        return choice !== null &&
               choice !== undefined &&
               typeof choice === "object" &&
               typeof (choice as Choice).label === "string" &&
               typeof (choice as Choice).url === "string" &&
               typeof (choice as Choice).checked === "boolean";
    }
}