import { makeAppObjectRepo } from "@vived/core";
import { ParametricLine, Vector2, Vector3 } from "@vived/core";
import { makeBaseAppState } from "../../BaseApp/Entity/BaseAppState";
import { makeMockPixelToSceneRayUC, makeMockSceneRayPickUC, } from "../../Babylon/Mocks";
import { makeChallengeEntityMock } from "../../Challenge/Mocks/ChallengeEntityMock";
import { makeMockDispatchStateChange } from "../../Dispatcher/Mocks/MockDispatchStateChange";
import { makeUndoRedoEntity } from "../../UndoRedo/Entities/UndoRedoEntity";
import { makeObjectPickEntity } from "../Entities/ObjectPickEntity";
import { makeTrySelectObjectPickUC, TrySelectObjectPickUC, } from "./TrySelectObjectPickUC";
function makeTestRig() {
    const appObjects = makeAppObjectRepo();
    const mockDispatchStateChange = makeMockDispatchStateChange(appObjects);
    const doDispatchMock = jest.fn();
    mockDispatchStateChange.doDispatch = doDispatchMock;
    const baseApp = makeBaseAppState(appObjects.getOrCreate("App"));
    const undo = makeUndoRedoEntity(appObjects.getOrCreate("Undo"));
    const challenge = makeChallengeEntityMock(appObjects);
    const objectPick = makeObjectPickEntity(appObjects.getOrCreate("ObjectPick"));
    baseApp.isAuthoring = true;
    objectPick.isSelectingCorrectObjects = true;
    challenge.selectedChallenge = "OBJECT_PICK";
    const mockPickResult = {
        hit: true,
        appObjectID: "sceneObject",
    };
    const mockRayPick = makeMockSceneRayPickUC(appObjects);
    const mockPick = jest.fn().mockReturnValue(mockPickResult);
    mockRayPick.sceneRayPick = mockPick;
    const mockPixelToRay = makeMockPixelToSceneRayUC(appObjects);
    const uc = makeTrySelectObjectPickUC(appObjects.getOrCreate("ObjectPick"));
    return {
        objectPick,
        uc,
        baseApp,
        doDispatchMock,
        appObjects,
        mockPixelToRay,
        undo,
        mockPick,
    };
}
describe("Try Select Object Pick Use Case", () => {
    it("Gets the singleton", () => {
        const { appObjects, uc } = makeTestRig();
        expect(TrySelectObjectPickUC.get(appObjects)).toEqual(uc);
    });
    it("Forms the pixel into a ray and passed it to the try with ray", () => {
        const { mockPixelToRay, uc } = makeTestRig();
        const mockRay = ParametricLine.FromTwoPoint(new Vector3(1, 2, 3), new Vector3(4, 5, 6));
        mockPixelToRay.pixelToSceneRay.mockReturnValue(mockRay);
        uc.tryWithRay = jest.fn();
        uc.tryWithPixel(new Vector2(7, 8));
        expect(mockPixelToRay.pixelToSceneRay).toHaveBeenCalledWith(new Vector2(7, 8));
        expect(uc.tryWithRay).toHaveBeenCalledWith(mockRay);
    });
    it("Tries Select Object Pick successfully", () => {
        const { uc, objectPick } = makeTestRig();
        const spy = jest.spyOn(objectPick, "addCorrectObjectId");
        uc.tryWithRay(ParametricLine.Forward());
        expect(spy).toHaveBeenCalledWith("sceneObject");
    });
    it("Does not add when the pick does not hit", () => {
        const { uc, mockPick, objectPick } = makeTestRig();
        const mockPickResult = {
            hit: false,
        };
        mockPick.mockReturnValue(mockPickResult);
        mockPickResult.hit = false;
        const spy = jest.spyOn(objectPick, "addCorrectObjectId");
        uc.tryWithRay(ParametricLine.Forward());
        expect(spy).not.toHaveBeenCalled();
    });
    it("Does not add when the pick does not an app object", () => {
        const { uc, mockPick, objectPick } = makeTestRig();
        const mockPickResult = {
            hit: true,
            appObjectID: undefined,
        };
        mockPick.mockReturnValue(mockPickResult);
        mockPickResult.hit = false;
        const spy = jest.spyOn(objectPick, "addCorrectObjectId");
        uc.tryWithRay(ParametricLine.Forward());
        expect(spy).not.toHaveBeenCalled();
    });
    it("Dispatches a state change", () => {
        const { uc, doDispatchMock } = makeTestRig();
        uc.tryWithRay(ParametricLine.Forward());
        expect(doDispatchMock).toHaveBeenCalled();
    });
    it("Is undoable and redoable", () => {
        const { uc, undo, objectPick } = makeTestRig();
        uc.tryWithRay(ParametricLine.Forward());
        expect(objectPick.correctObjectIds).toEqual(["sceneObject"]);
        undo.doUndo();
        expect(objectPick.correctObjectIds).toEqual([]);
        undo.doRedo();
        expect(objectPick.correctObjectIds).toEqual(["sceneObject"]);
    });
    it("Undo and redo dispatch a state change", () => {
        const { uc, undo, doDispatchMock } = makeTestRig();
        uc.tryWithRay(ParametricLine.Forward());
        doDispatchMock.mockClear();
        undo.doUndo();
        expect(doDispatchMock).toHaveBeenCalled();
        doDispatchMock.mockClear();
        undo.doRedo();
        expect(doDispatchMock).toHaveBeenCalled();
    });
});
//# sourceMappingURL=TrySelectObjectPickUC.test.js.map