feat: add scene 8 entry state
This commit is contained in:
@@ -0,0 +1,45 @@
|
|||||||
|
import { describe, expect, it } from "vitest";
|
||||||
|
import {
|
||||||
|
SCENE8_REQUEST,
|
||||||
|
canSubmitScene8Entry,
|
||||||
|
initialScene8EntryState,
|
||||||
|
scene8EntryReducer,
|
||||||
|
} from "./scene8-entry-state.js";
|
||||||
|
|
||||||
|
describe("scene8EntryReducer", () => {
|
||||||
|
it("starts with the canonical request as the editable draft", () => {
|
||||||
|
expect(initialScene8EntryState).toEqual({ phase: "empty", draft: SCENE8_REQUEST });
|
||||||
|
expect(canSubmitScene8Entry(initialScene8EntryState)).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("updates only the draft while the entry is empty", () => {
|
||||||
|
expect(scene8EntryReducer(initialScene8EntryState, {
|
||||||
|
type: "draft_changed",
|
||||||
|
draft: "A narrower request",
|
||||||
|
})).toEqual({ phase: "empty", draft: "A narrower request" });
|
||||||
|
});
|
||||||
|
|
||||||
|
it("rejects whitespace-only submissions", () => {
|
||||||
|
const state = { phase: "empty" as const, draft: " \n\t" };
|
||||||
|
expect(canSubmitScene8Entry(state)).toBe(false);
|
||||||
|
expect(scene8EntryReducer(state, { type: "submit" })).toBe(state);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("stores the exact submitted text", () => {
|
||||||
|
const state = { phase: "empty" as const, draft: " Keep this spacing " };
|
||||||
|
expect(scene8EntryReducer(state, { type: "submit" })).toEqual({
|
||||||
|
phase: "submitted",
|
||||||
|
draft: state.draft,
|
||||||
|
request: state.draft,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("keeps a submitted request stable on edits or repeated submits", () => {
|
||||||
|
const submitted = scene8EntryReducer(initialScene8EntryState, { type: "submit" });
|
||||||
|
expect(scene8EntryReducer(submitted, {
|
||||||
|
type: "draft_changed",
|
||||||
|
draft: "A different request",
|
||||||
|
})).toBe(submitted);
|
||||||
|
expect(scene8EntryReducer(submitted, { type: "submit" })).toBe(submitted);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
export const SCENE8_REQUEST =
|
||||||
|
"We need to author a report workflow for the lda_report scenario. What sources and capabilities are available?";
|
||||||
|
|
||||||
|
export type Scene8EntryState =
|
||||||
|
| { readonly phase: "empty"; readonly draft: string }
|
||||||
|
| { readonly phase: "submitted"; readonly draft: string; readonly request: string };
|
||||||
|
|
||||||
|
export type Scene8EntryAction =
|
||||||
|
| { readonly type: "draft_changed"; readonly draft: string }
|
||||||
|
| { readonly type: "submit" };
|
||||||
|
|
||||||
|
export const initialScene8EntryState: Scene8EntryState = {
|
||||||
|
phase: "empty",
|
||||||
|
draft: SCENE8_REQUEST,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const canSubmitScene8Entry = (state: Scene8EntryState): boolean =>
|
||||||
|
state.phase === "empty" && state.draft.trim().length > 0;
|
||||||
|
|
||||||
|
export const scene8EntryReducer = (
|
||||||
|
state: Scene8EntryState,
|
||||||
|
action: Scene8EntryAction,
|
||||||
|
): Scene8EntryState => {
|
||||||
|
if (state.phase === "submitted") return state;
|
||||||
|
|
||||||
|
switch (action.type) {
|
||||||
|
case "draft_changed":
|
||||||
|
return { phase: "empty", draft: action.draft };
|
||||||
|
case "submit":
|
||||||
|
return canSubmitScene8Entry(state)
|
||||||
|
? { phase: "submitted", draft: state.draft, request: state.draft }
|
||||||
|
: state;
|
||||||
|
}
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user