"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@vived/core");
const Mocks_1 = require("../../Dispatcher/Mocks");
const GLBModel_1 = require("../../GLBModel");
const Entities_1 = require("../Entities");
const LoadChannelModelUC_1 = require("./LoadChannelModelUC");
const ChannelModelViewFactoryMock_1 = require("../Mocks/ChannelModelViewFactoryMock");
function makeTestRig() {
    const appObjects = (0, core_1.makeAppObjectRepo)();
    const registerSingletonSpy = jest.spyOn(appObjects, "registerSingleton");
    const channelModelRepo = (0, Entities_1.makeChannelModelRepo)(appObjects.getOrCreate("channelModelRepo"));
    const glbRepo = (0, GLBModel_1.makeGlbModelRepo)(appObjects.getOrCreate("GLB Repo"));
    const mockLoadGLB = (0, GLBModel_1.makeLoadGlbFileUCMock)(appObjects);
    mockLoadGLB.loadBlobURL.mockResolvedValue(undefined);
    const mockModelViewFactory = (0, ChannelModelViewFactoryMock_1.makeChannelModelViewFactoryMock)(appObjects);
    const mockGetBlob = (0, Mocks_1.makeGetAssetBlobURLUCMock)(appObjects);
    mockGetBlob.doDispatch.mockResolvedValue("some.blob.url");
    const mockGetLinkedAsset = (0, Mocks_1.makeGetLinkedAssetsUCMock)(appObjects);
    mockGetLinkedAsset.doDispatch.mockResolvedValue([
        {
            id: "dataID",
        },
    ]);
    const mockShowSpinner = (0, Mocks_1.makeMockShowSpinner)(appObjects);
    const hideSpinner = jest.fn();
    mockShowSpinner.showSpinner.mockResolvedValue(hideSpinner);
    const ao = appObjects.getOrCreate("ao");
    const uc = (0, LoadChannelModelUC_1.makeLoadChannelModelUC)(ao);
    const mockBlobToJSON = jest.fn().mockResolvedValue({ foo: "bar" });
    uc.blobToJSON = mockBlobToJSON;
    return {
        uc,
        appObjects,
        registerSingletonSpy,
        channelModelRepo,
        glbRepo,
        mockLoadGLB,
        mockModelViewFactory,
        mockGetBlob,
        mockGetLinkedAsset,
        mockBlobToJSON,
        hideSpinner,
        mockShowSpinner,
    };
}
describe("Load Channel Model UC", () => {
    it("Gets the singleton", () => {
        const { appObjects, uc } = makeTestRig();
        expect(LoadChannelModelUC_1.LoadChannelModelUC.get(appObjects)).toEqual(uc);
    });
    it("Registers the singleton", () => {
        const { registerSingletonSpy, uc } = makeTestRig();
        expect(registerSingletonSpy).toHaveBeenCalledWith(uc);
    });
    it("Returns an existing an ready Channel Model", async () => {
        const { channelModelRepo, uc } = makeTestRig();
        const channelModel = channelModelRepo.createChannelModel("readyChannelModel");
        channelModel.state = Entities_1.ChannelModelState.READY;
        const returnedCM = await uc.loadChannelModel("readyChannelModel");
        expect(returnedCM).toEqual(channelModel);
    });
    it("Resolve after an existing channel model is done loading", (done) => {
        const { channelModelRepo, uc } = makeTestRig();
        const channelModel = channelModelRepo.createChannelModel("readyChannelModel");
        channelModel.state = Entities_1.ChannelModelState.LOADING;
        uc.loadChannelModel("readyChannelModel").then((ch) => {
            expect(ch).toEqual(channelModel);
            done();
        });
        channelModel.state = Entities_1.ChannelModelState.READY;
    });
    it("Does not show a spinner if the model exists", async () => {
        const { uc, mockShowSpinner, channelModelRepo } = makeTestRig();
        const channelModel = channelModelRepo.createChannelModel("readyChannelModel");
        channelModel.state = Entities_1.ChannelModelState.READY;
        await uc.loadChannelModel("readyChannelModel");
        expect(mockShowSpinner.showSpinner).not.toHaveBeenCalled();
    });
    it("Rejects if existing throws an error while loading", (done) => {
        const { channelModelRepo, uc } = makeTestRig();
        const channelModel = channelModelRepo.createChannelModel("readyChannelModel");
        channelModel.state = Entities_1.ChannelModelState.LOADING;
        uc.loadChannelModel("readyChannelModel").catch((e) => {
            // eslint-disable-next-line jest/no-conditional-expect
            expect(e).toEqual(new Error("Some Error"));
            done();
        });
        channelModel.modelError = new Error("Some Error");
    });
    it("Rejects if the existing already has an error", () => {
        const { channelModelRepo, uc } = makeTestRig();
        const channelModel = channelModelRepo.createChannelModel("readyChannelModel");
        channelModel.modelError = new Error("Some Error");
        return expect(uc.loadChannelModel("readyChannelModel")).rejects.toEqual(new Error("Some Error"));
    });
    it("Sets the channel model to ready when completed", async () => {
        const { channelModelRepo, uc } = makeTestRig();
        await uc.loadChannelModel("modelID");
        expect(channelModelRepo.getChannelModel("modelID", false)?.state).toEqual(Entities_1.ChannelModelState.READY);
    });
    it("Shows a spinner", async () => {
        const { uc, mockShowSpinner } = makeTestRig();
        await uc.loadChannelModel("modelID");
        expect(mockShowSpinner.showSpinner).toHaveBeenCalled();
    });
    it("Hides the spinner on complete", async () => {
        const { uc, hideSpinner } = makeTestRig();
        await uc.loadChannelModel("modelID");
        expect(hideSpinner).toHaveBeenCalled();
    });
    it("Immediately sets the channel model to loading", () => {
        const { channelModelRepo, uc } = makeTestRig();
        uc.loadChannelModel("modelID");
        expect(channelModelRepo.getChannelModel("modelID", false)?.state).toEqual(Entities_1.ChannelModelState.LOADING);
    });
    it("Gets the model blob URL", async () => {
        const { mockGetBlob, uc } = makeTestRig();
        await uc.loadChannelModel("modelID");
        expect(mockGetBlob.doDispatch).toHaveBeenCalledWith("modelID");
    });
    it("Makes the GLB Entity", async () => {
        const { glbRepo, uc } = makeTestRig();
        expect(glbRepo.hasForAppObject("modelID")).toEqual(false);
        await uc.loadChannelModel("modelID");
        expect(glbRepo.hasForAppObject("modelID")).toEqual(true);
    });
    it("Gets the linked data asset", async () => {
        const { mockGetLinkedAsset, uc } = makeTestRig();
        await uc.loadChannelModel("modelID");
        expect(mockGetLinkedAsset.doDispatch).toHaveBeenCalledWith("modelID", LoadChannelModelUC_1.SCENE_MODEL_DATA_ASSET_LINK_TYPE);
    });
    it("Gets the data asset blob", async () => {
        const { mockGetLinkedAsset, uc, mockGetBlob } = makeTestRig();
        mockGetLinkedAsset.doDispatch.mockResolvedValue([
            {
                id: "dataID",
            },
        ]);
        await uc.loadChannelModel("modelID");
        expect(mockGetBlob.doDispatch).toHaveBeenCalledWith("dataID");
    });
    it("Rejects if there are no data assets linked to the model", () => {
        const { mockGetLinkedAsset, uc } = makeTestRig();
        mockGetLinkedAsset.doDispatch.mockResolvedValue([]);
        return expect(uc.loadChannelModel("modelID")).rejects.toEqual(new Error("Model asset does not have data"));
    });
    it("Converts the blob to an object", async () => {
        const { mockBlobToJSON, uc } = makeTestRig();
        await uc.loadChannelModel("modelID");
        expect(mockBlobToJSON).toHaveBeenCalledWith("some.blob.url");
    });
    it("Sets up the channel model data", async () => {
        const { mockBlobToJSON, uc, appObjects, channelModelRepo } = makeTestRig();
        mockBlobToJSON.mockResolvedValue({ foo: "bar" });
        const newModel = (0, Entities_1.makeChannelModelEntity)(appObjects.getOrCreate("modelID"));
        newModel.setupFromData = jest.fn();
        channelModelRepo.createChannelModel = jest.fn().mockReturnValue(newModel);
        await uc.loadChannelModel("modelID");
        expect(newModel.setupFromData).toHaveBeenCalledWith({ foo: "bar" });
    });
    it("Initializes the view", async () => {
        const { mockModelViewFactory, uc, appObjects, channelModelRepo } = makeTestRig();
        const newModel = (0, Entities_1.makeChannelModelEntity)(appObjects.getOrCreate("modelID"));
        newModel.setupFromData = jest.fn();
        channelModelRepo.createChannelModel = jest.fn().mockReturnValue(newModel);
        await uc.loadChannelModel("modelID");
        expect(mockModelViewFactory.initializeView).toHaveBeenCalledWith(newModel);
    });
    it("Hides the spinner if something rejects", (done) => {
        const { mockGetLinkedAsset, uc, hideSpinner } = makeTestRig();
        mockGetLinkedAsset.doDispatch.mockResolvedValue([]);
        expect.assertions(1);
        uc.loadChannelModel("modelID").catch((e) => {
            // eslint-disable-next-line jest/no-conditional-expect
            expect(hideSpinner).toHaveBeenCalled();
            done();
        });
    });
});
//# sourceMappingURL=LoadChannelModelUC.test.js.map