/**
 * Focused test: handleCompleteMilestone rejects unsafe milestoneId values
 * before any filesystem or DB operation.
 *
 * Part of the validation-safe-id-path-segments self-feedback fix.
 */

import assert from "node:assert/strict";
import { test } from 'vitest';
import { handleCompleteMilestone } from "../tools/complete-milestone.ts";

const BASE_PARAMS = {
	title: "Test Milestone",
	oneLiner: "A test.",
	narrative: "Narrative here.",
	verificationPassed: true,
};

test("handleCompleteMilestone rejects path-traversal milestoneId (../etc)", async () => {
	const result = await handleCompleteMilestone(
		{ ...BASE_PARAMS, milestoneId: "../etc" },
		"/tmp/nonexistent-base",
	);
	assert.ok("error" in result, "should return an error response");
	const err = result as { error: string; field?: string; reason?: string };
	assert.equal(err.error, "unsafe_id");
	assert.equal(err.field, "milestone_id");
	assert.ok(
		typeof err.reason === "string" && err.reason.length > 0,
		"reason should be a non-empty string",
	);
});

test("handleCompleteMilestone rejects milestoneId with embedded newline (M001\\nbad)", async () => {
	const result = await handleCompleteMilestone(
		{ ...BASE_PARAMS, milestoneId: "M001\nbad" },
		"/tmp/nonexistent-base",
	);
	assert.ok("error" in result, "should return an error response");
	const err = result as { error: string; field?: string; reason?: string };
	assert.equal(err.error, "unsafe_id");
	assert.equal(err.field, "milestone_id");
	assert.ok(
		typeof err.reason === "string" && err.reason.length > 0,
		"reason should be a non-empty string",
	);
});
