mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-21 22:31:46 +00:00
Add comprehensive backend test suite (#339)
* add test suite, mostly covers integration testing, tests are only backend side * workflow runs the correct script * workflow runs the correct script * workflow runs the correct script * unit tests incoming * Fix multer silent rejections and error handler info leak - Revert cb(null, false) to cb(new Error(...)) in auth.ts, collab.ts, and files.ts so invalid uploads return an error instead of silently dropping the file - Error handler in app.ts now always returns 500 / "Internal server error" instead of forwarding err.message to the client * Use statusCode consistently for multer errors and error handler - Error handler in app.ts reads err.statusCode to forward the correct HTTP status while keeping the response body generic
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import * as crypto from 'crypto';
|
||||
import * as crypto from 'node:crypto';
|
||||
import { ENCRYPTION_KEY } from '../config';
|
||||
|
||||
const ENCRYPTED_PREFIX = 'enc:v1:';
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Response } from 'express';
|
||||
|
||||
const COOKIE_NAME = 'trek_session';
|
||||
|
||||
function cookieOptions(clear = false) {
|
||||
export function cookieOptions(clear = false) {
|
||||
const secure = process.env.COOKIE_SECURE !== 'false' && (process.env.NODE_ENV === 'production' || process.env.FORCE_HTTPS === 'true');
|
||||
return {
|
||||
httpOnly: true,
|
||||
|
||||
@@ -175,14 +175,14 @@ const EVENT_TEXTS: Record<string, Record<EventType, EventTextFn>> = {
|
||||
};
|
||||
|
||||
// Get localized event text
|
||||
function getEventText(lang: string, event: EventType, params: Record<string, string>): EventText {
|
||||
export function getEventText(lang: string, event: EventType, params: Record<string, string>): EventText {
|
||||
const texts = EVENT_TEXTS[lang] || EVENT_TEXTS.en;
|
||||
return texts[event](params);
|
||||
}
|
||||
|
||||
// ── Email HTML builder ─────────────────────────────────────────────────────
|
||||
|
||||
function buildEmailHtml(subject: string, body: string, lang: string): string {
|
||||
export function buildEmailHtml(subject: string, body: string, lang: string): string {
|
||||
const s = I18N[lang] || I18N.en;
|
||||
const appUrl = getAppUrl();
|
||||
const ctaHref = appUrl || '#';
|
||||
@@ -256,7 +256,7 @@ async function sendEmail(to: string, subject: string, body: string, userId?: num
|
||||
}
|
||||
}
|
||||
|
||||
function buildWebhookBody(url: string, payload: { event: string; title: string; body: string; tripName?: string }): string {
|
||||
export function buildWebhookBody(url: string, payload: { event: string; title: string; body: string; tripName?: string }): string {
|
||||
const isDiscord = /discord(?:app)?\.com\/api\/webhooks\//.test(url);
|
||||
const isSlack = /hooks\.slack\.com\//.test(url);
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ const TTL_FORECAST_MS = 60 * 60 * 1000; // 1 hour
|
||||
const TTL_CURRENT_MS = 15 * 60 * 1000; // 15 minutes
|
||||
const TTL_CLIMATE_MS = 24 * 60 * 60 * 1000; // 24 hours
|
||||
|
||||
function cacheKey(lat: string, lng: string, date?: string): string {
|
||||
export function cacheKey(lat: string, lng: string, date?: string): string {
|
||||
const rlat = parseFloat(lat).toFixed(2);
|
||||
const rlng = parseFloat(lng).toFixed(2);
|
||||
return `${rlat}_${rlng}_${date || 'current'}`;
|
||||
@@ -138,7 +138,7 @@ function setCache(key: string, data: WeatherResult, ttlMs: number): void {
|
||||
|
||||
// ── Helpers ─────────────────────────────────────────────────────────────
|
||||
|
||||
function estimateCondition(tempAvg: number, precipMm: number): string {
|
||||
export function estimateCondition(tempAvg: number, precipMm: number): string {
|
||||
if (precipMm > 5) return tempAvg <= 0 ? 'Snow' : 'Rain';
|
||||
if (precipMm > 1) return tempAvg <= 0 ? 'Snow' : 'Drizzle';
|
||||
if (precipMm > 0.3) return 'Clouds';
|
||||
|
||||
Reference in New Issue
Block a user