// Integration test for user preferences defaultProviders persistence (Step 9) // Run with: node server/tests/preferences.test.mjs import fs from 'node:fs'; import path from 'node:path'; import os from 'node:os'; // Create isolated temp DB file const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'newtube-prefs-test-')); const dbPath = path.join(tmpDir, 'test.db'); process.env.NEWTUBE_DB_FILE = dbPath; // Dynamically import DB after setting env const dbMod = await import('../db.mjs'); const { insertUser, cryptoRandomUUID, upsertPreferences, getPreferencesForApi } = dbMod; function expect(cond, msg) { if (!cond) { throw new Error(`Assertion failed: ${msg}`); } } function logOk(msg) { console.log(`✓ ${msg}`); } const user = cryptoRandomUUID(); insertUser({ id: user, username: 'prefs-a', email: null, passwordHash: 'x' }); // 1) Fresh user: no defaultProviders yet let prefs = getPreferencesForApi(user); expect(prefs && Array.isArray(prefs.defaultProviders) && prefs.defaultProviders.length === 0 || prefs.defaultProviders === null, 'fresh user has no defaultProviders'); logOk('fresh user defaultProviders empty'); // 2) Save a multi-provider default: round-trip through JSON column upsertPreferences(user, { defaultProviders: ['yt', 'dm'] }); prefs = getPreferencesForApi(user); expect(Array.isArray(prefs.defaultProviders) && prefs.defaultProviders.join(',') === 'yt,dm', `defaultProviders round-trips (got ${JSON.stringify(prefs.defaultProviders)})`); logOk('defaultProviders persisted and read back as array'); // 3) Sanitization: unknown ids dropped, case/duplicates handled, JSON string accepted upsertPreferences(user, { defaultProviders: ['YT', 'zz', 'dm', 'yt'] }); prefs = getPreferencesForApi(user); expect(prefs.defaultProviders.join(',') === 'yt,dm', `unknown ids dropped and deduped (got ${JSON.stringify(prefs.defaultProviders)})`); logOk('sanitization of provider ids'); // 4) Partial update: patching another field keeps the stored list upsertPreferences(user, { theme: 'dark' }); prefs = getPreferencesForApi(user); expect(prefs.theme === 'dark' && prefs.defaultProviders.join(',') === 'yt,dm', 'partial update preserves defaultProviders'); logOk('partial update preserves list'); // 5) Empty array clears the preference upsertPreferences(user, { defaultProviders: [] }); prefs = getPreferencesForApi(user); expect(prefs.defaultProviders === null, 'empty array clears the list'); logOk('empty array clears defaultProviders'); // 6) Other patches still work after clearing upsertPreferences(user, { language: 'fr' }); prefs = getPreferencesForApi(user); expect(prefs.language === 'fr' && prefs.defaultProviders === null, 'language patch ok'); logOk('other preference fields unaffected'); console.log('\nAll preferences tests passed.');