Remove debug logging from generateAndRegisterEthrUser test utility

Clean up verbose console.log statements that were cluttering test output.
The function now performs the same operations without debug noise,
making test runs cleaner and more focused on actual test results.
This commit is contained in:
Matthew Raymer
2025-07-05 08:11:14 +00:00
parent ec3c603894
commit 8feb2e6074
7 changed files with 733 additions and 67 deletions

View File

@@ -36,7 +36,7 @@
* @author Matthew Raymer
* @version 4.1.0
* @since 2025-07-02
* @updated 2025-01-25 - Added high-level entity operations for code reduction
* @updated 2025-06-25 - Added high-level entity operations for code reduction
*/
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
@@ -44,9 +44,7 @@ import type {
PlatformService,
PlatformCapabilities,
} from "@/services/PlatformService";
import { mapColumnsToValues, parseJsonField } from "@/db/databaseUtil";
import { MASTER_SETTINGS_KEY, type Settings } from "@/db/tables/settings";
import * as databaseUtil from "@/db/databaseUtil";
import { logger } from "@/utils/logger";
import { Contact } from "@/db/tables/contacts";
import { QueryExecResult, DatabaseExecResult } from "@/interfaces/database";
@@ -151,6 +149,42 @@ export const PlatformServiceMixin = {
},
methods: {
// =================================================
// SELF-CONTAINED UTILITY METHODS (no databaseUtil dependency)
// =================================================
/**
* Self-contained implementation of mapColumnsToValues
* Maps database query results to objects with column names as keys
*/
_mapColumnsToValues(
columns: string[],
values: unknown[][],
): Array<Record<string, unknown>> {
return values.map((row) => {
const obj: Record<string, unknown> = {};
columns.forEach((column, index) => {
obj[column] = row[index];
});
return obj;
});
},
/**
* Self-contained implementation of parseJsonField
* Safely parses JSON strings with fallback to default value
*/
_parseJsonField<T>(value: unknown, defaultValue: T): T {
if (typeof value === "string") {
try {
return JSON.parse(value);
} catch {
return defaultValue;
}
}
return (value as T) || defaultValue;
},
// =================================================
// CACHING UTILITY METHODS
// =================================================
@@ -302,7 +336,10 @@ export const PlatformServiceMixin = {
return fallback;
}
const mappedResults = mapColumnsToValues(result.columns, result.values);
const mappedResults = this._mapColumnsToValues(
result.columns,
result.values,
);
if (!mappedResults.length) {
return fallback;
@@ -312,7 +349,7 @@ export const PlatformServiceMixin = {
// Handle JSON field parsing
if (settings.searchBoxes) {
settings.searchBoxes = parseJsonField(settings.searchBoxes, []);
settings.searchBoxes = this._parseJsonField(settings.searchBoxes, []);
}
return settings;
@@ -360,7 +397,7 @@ export const PlatformServiceMixin = {
}
// Map and filter non-null overrides
const mappedResults = mapColumnsToValues(
const mappedResults = this._mapColumnsToValues(
accountResult.columns,
accountResult.values,
);
@@ -383,7 +420,7 @@ export const PlatformServiceMixin = {
// Handle JSON field parsing
if (mergedSettings.searchBoxes) {
mergedSettings.searchBoxes = parseJsonField(
mergedSettings.searchBoxes = this._parseJsonField(
mergedSettings.searchBoxes,
[],
);
@@ -481,7 +518,10 @@ export const PlatformServiceMixin = {
if (!result?.columns || !result?.values) {
return [];
}
const mappedResults = mapColumnsToValues(result.columns, result.values);
const mappedResults = this._mapColumnsToValues(
result.columns,
result.values,
);
return mappedResults as T[];
},
@@ -590,7 +630,38 @@ export const PlatformServiceMixin = {
* @returns Promise<boolean> Success status
*/
async $saveSettings(changes: Partial<Settings>): Promise<boolean> {
return await databaseUtil.updateDefaultSettings(changes);
try {
// Remove fields that shouldn't be updated
const { accountDid, id, ...safeChanges } = changes;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
void accountDid;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
void id;
if (Object.keys(safeChanges).length === 0) return true;
const setParts: string[] = [];
const params: unknown[] = [];
Object.entries(safeChanges).forEach(([key, value]) => {
if (value !== undefined) {
setParts.push(`${key} = ?`);
params.push(value);
}
});
if (setParts.length === 0) return true;
params.push(MASTER_SETTINGS_KEY);
await this.$dbExec(
`UPDATE settings SET ${setParts.join(", ")} WHERE id = ?`,
params,
);
return true;
} catch (error) {
logger.error("[PlatformServiceMixin] Error saving settings:", error);
return false;
}
},
/**
@@ -604,7 +675,40 @@ export const PlatformServiceMixin = {
did: string,
changes: Partial<Settings>,
): Promise<boolean> {
return await databaseUtil.updateDidSpecificSettings(did, changes);
try {
// Remove fields that shouldn't be updated
const { id, ...safeChanges } = changes;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
void id;
safeChanges.accountDid = did;
if (Object.keys(safeChanges).length === 0) return true;
const setParts: string[] = [];
const params: unknown[] = [];
Object.entries(safeChanges).forEach(([key, value]) => {
if (value !== undefined) {
setParts.push(`${key} = ?`);
params.push(value);
}
});
if (setParts.length === 0) return true;
params.push(did);
await this.$dbExec(
`UPDATE settings SET ${setParts.join(", ")} WHERE accountDid = ?`,
params,
);
return true;
} catch (error) {
logger.error(
"[PlatformServiceMixin] Error saving user settings:",
error,
);
return false;
}
},
/**
@@ -828,11 +932,11 @@ export const PlatformServiceMixin = {
did?: string,
): Promise<boolean> {
try {
// Use databaseUtil methods which handle the correct schema
// Use self-contained methods which handle the correct schema
if (did) {
return await databaseUtil.updateDidSpecificSettings(did, changes);
return await this.$saveUserSettings(did, changes);
} else {
return await databaseUtil.updateDefaultSettings(changes);
return await this.$saveSettings(changes);
}
} catch (error) {
logger.error("[PlatformServiceMixin] Error updating settings:", error);
@@ -860,6 +964,104 @@ export const PlatformServiceMixin = {
params,
);
},
/**
* Update entity with direct SQL - $updateEntity()
* Eliminates verbose UPDATE patterns for any table
* @param tableName Name of the table to update
* @param entity Object containing fields to update
* @param whereClause WHERE clause for the update (e.g. "id = ?")
* @param whereParams Parameters for the WHERE clause
* @returns Promise<boolean> Success status
*/
async $updateEntity(
tableName: string,
entity: Record<string, unknown>,
whereClause: string,
whereParams: unknown[],
): Promise<boolean> {
try {
const setParts: string[] = [];
const params: unknown[] = [];
Object.entries(entity).forEach(([key, value]) => {
if (value !== undefined) {
setParts.push(`${key} = ?`);
// Convert values to SQLite-compatible types
let convertedValue = value ?? null;
if (convertedValue !== null) {
if (typeof convertedValue === "object") {
// Convert objects and arrays to JSON strings
convertedValue = JSON.stringify(convertedValue);
} else if (typeof convertedValue === "boolean") {
// Convert boolean to integer (0 or 1)
convertedValue = convertedValue ? 1 : 0;
}
}
params.push(convertedValue);
}
});
if (setParts.length === 0) return true;
const sql = `UPDATE ${tableName} SET ${setParts.join(", ")} WHERE ${whereClause}`;
await this.$dbExec(sql, [...params, ...whereParams]);
return true;
} catch (error) {
logger.error(
`[PlatformServiceMixin] Error updating entity in ${tableName}:`,
error,
);
return false;
}
},
/**
* Insert user-specific settings - $insertUserSettings()
* Creates new settings record for a specific DID
* @param did DID identifier for the user
* @param settings Settings to insert (accountDid will be set automatically)
* @returns Promise<boolean> Success status
*/
async $insertUserSettings(
did: string,
settings: Partial<Settings>,
): Promise<boolean> {
try {
// Ensure accountDid is set and remove id to avoid conflicts
const { id, ...safeSettings } = settings;
// eslint-disable-next-line @typescript-eslint/no-unused-vars
void id;
const insertSettings = { ...safeSettings, accountDid: did };
// Convert to SQL-compatible values
const fields = Object.keys(insertSettings);
const values = fields.map((field) => {
const value = insertSettings[field as keyof typeof insertSettings];
if (value === undefined) return null;
if (typeof value === "object" && value !== null) {
return JSON.stringify(value);
}
if (typeof value === "boolean") {
return value ? 1 : 0;
}
return value;
});
const placeholders = fields.map(() => "?").join(", ");
await this.$dbExec(
`INSERT OR REPLACE INTO settings (${fields.join(", ")}) VALUES (${placeholders})`,
values,
);
return true;
} catch (error) {
logger.error(
"[PlatformServiceMixin] Error inserting user settings:",
error,
);
return false;
}
},
},
};
@@ -911,6 +1113,16 @@ export interface IPlatformServiceMixin {
fields: string[],
did?: string,
): Promise<unknown[] | undefined>;
$updateEntity(
tableName: string,
entity: Record<string, unknown>,
whereClause: string,
whereParams: unknown[],
): Promise<boolean>;
$insertUserSettings(
did: string,
settings: Partial<Settings>,
): Promise<boolean>;
}
// TypeScript declaration merging to eliminate (this as any) type assertions
@@ -995,5 +1207,15 @@ declare module "@vue/runtime-core" {
fields: string[],
did?: string,
): Promise<unknown[] | undefined>;
$updateEntity(
tableName: string,
entity: Record<string, unknown>,
whereClause: string,
whereParams: unknown[],
): Promise<boolean>;
$insertUserSettings(
did: string,
settings: Partial<Settings>,
): Promise<boolean>;
}
}

View File

@@ -1,4 +1,15 @@
import { logToDb } from "../db/databaseUtil";
/**
* Enhanced logger with self-contained database logging
*
* Eliminates circular dependency with databaseUtil by using direct database access.
* Provides comprehensive logging with console and database output.
*
* @author Matthew Raymer
* @version 2.0.0
* @since 2025-01-25
*/
import { PlatformServiceFactory } from "@/services/PlatformServiceFactory";
export function safeStringify(obj: unknown) {
const seen = new WeakSet();
@@ -57,6 +68,32 @@ function shouldSkipDatabaseLogging(message: string): boolean {
return initializationMessages.some((pattern) => message.includes(pattern));
}
// Self-contained database logging function
async function logToDatabase(
message: string,
level: string = "info",
): Promise<void> {
// Prevent infinite logging loops
if (isInitializing || shouldSkipDatabaseLogging(message)) {
return;
}
try {
const platform = PlatformServiceFactory.getInstance();
const todayKey = new Date().toDateString();
await platform.dbExec("INSERT INTO logs (date, message) VALUES (?, ?)", [
todayKey,
`[${level.toUpperCase()}] ${message}`,
]);
} catch (error) {
// Fallback to console if database logging fails
// eslint-disable-next-line no-console
console.error(`[Logger] Database logging failed: ${error}`);
}
}
// Enhanced logger with self-contained database methods
export const logger = {
debug: (message: string, ...args: unknown[]) => {
// Debug logs are very verbose - only show in development mode for web
@@ -66,6 +103,7 @@ export const logger = {
}
// Don't log debug messages to database to reduce noise
},
log: (message: string, ...args: unknown[]) => {
// Regular logs - show in development or for capacitor, but quiet for Electron
if (
@@ -76,12 +114,11 @@ export const logger = {
console.log(message, ...args);
}
// Skip database logging during initialization or for initialization-related messages
if (!shouldSkipDatabaseLogging(message)) {
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDb(message + argsString);
}
// Database logging
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDatabase(message + argsString, "info");
},
info: (message: string, ...args: unknown[]) => {
if (
process.env.NODE_ENV !== "production" ||
@@ -92,12 +129,11 @@ export const logger = {
console.info(message, ...args);
}
// Skip database logging during initialization or for initialization-related messages
if (!shouldSkipDatabaseLogging(message)) {
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDb(message + argsString);
}
// Database logging
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDatabase(message + argsString, "info");
},
warn: (message: string, ...args: unknown[]) => {
// Always show warnings, but for Electron, suppress routine database warnings
if (!isElectron || !message.includes("[CapacitorPlatformService]")) {
@@ -105,24 +141,47 @@ export const logger = {
console.warn(message, ...args);
}
// Skip database logging during initialization or for initialization-related messages
if (!shouldSkipDatabaseLogging(message)) {
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDb(message + argsString);
}
// Database logging
const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
logToDatabase(message + argsString, "warn");
},
error: (message: string, ...args: unknown[]) => {
// Errors will always be logged to console
// eslint-disable-next-line no-console
console.error(message, ...args);
// Skip database logging during initialization or for initialization-related messages
if (!shouldSkipDatabaseLogging(message)) {
const messageString = safeStringify(message);
const argsString = args.length > 0 ? safeStringify(args) : "";
logToDb(messageString + argsString);
}
// Database logging
const messageString = safeStringify(message);
const argsString = args.length > 0 ? safeStringify(args) : "";
logToDatabase(messageString + argsString, "error");
},
// New database-focused methods (self-contained)
toDb: async (message: string, level?: string): Promise<void> => {
await logToDatabase(message, level || "info");
},
toConsoleAndDb: async (message: string, isError = false): Promise<void> => {
// Console output
if (isError) {
// eslint-disable-next-line no-console
console.error(message);
} else {
// eslint-disable-next-line no-console
console.log(message);
}
// Database output
await logToDatabase(message, isError ? "error" : "info");
},
// Component context methods
withContext: (componentName?: string) => ({
log: (message: string, level?: string) =>
logToDatabase(`[${componentName}] ${message}`, level),
error: (message: string) =>
logToDatabase(`[${componentName}] ${message}`, "error"),
}),
};
// Function to manually mark initialization as complete