/**
 * deleteUserFolder — removes a user's filesystem folder on account deletion.
 *
 * The DB cascade-deletes owned rows, but the user folder
 * ({root}/{ownerId}/...) is on disk and was previously orphaned on delete.
 * See docs/superpowers/plans/2026-06-09-local-auth.md.
 */
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
import { mkdtempSync, rmSync, mkdirSync, writeFileSync, existsSync } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';
import { deleteUserFolder, ensureUserFolder } from './paths.js';

describe('deleteUserFolder', () => {
  let root = '';
  beforeEach(() => { root = mkdtempSync(join(tmpdir(), 'maestro-uf-')); });
  afterEach(() => { if (root) { rmSync(root, { recursive: true, force: true }); root = ''; } });

  it('removes the entire user folder', () => {
    const dir = ensureUserFolder(root, 'alice');
    writeFileSync(join(dir, 'notes', 'x.md'), 'hi');
    expect(existsSync(dir)).toBe(true);
    deleteUserFolder(root, 'alice');
    expect(existsSync(dir)).toBe(false);
  });

  it('NEVER removes the local/system folder (shared no-auth owner)', () => {
    const dir = ensureUserFolder(root, 'local');
    deleteUserFolder(root, 'local');
    expect(existsSync(dir)).toBe(true); // preserved
  });

  it('is a no-op when the folder does not exist', () => {
    expect(() => deleteUserFolder(root, 'ghost')).not.toThrow();
  });

  it('refuses path-traversal ids (no escape outside root)', () => {
    // userRoot rejects these; deleteUserFolder must not delete anything outside.
    const sibling = mkdtempSync(join(tmpdir(), 'maestro-sibling-'));
    writeFileSync(join(sibling, 'keep.txt'), 'keep');
    expect(() => deleteUserFolder(root, '../../etc')).not.toThrow();
    expect(existsSync(join(sibling, 'keep.txt'))).toBe(true);
    rmSync(sibling, { recursive: true, force: true });
  });
});
