import BaseModel from "../BaseModel";
import mockWebapp from "./webapp.json";

import LayoutHintCollection from "../../layouthint/LayoutHintCollection";

describe("baseModel", () => {
  it("should be able to create an empty BaseModel object", () => {
    const model = new BaseModel();

    expect(model.data).toStrictEqual({});
    expect(model.contributions).toStrictEqual({});
    expect(model.hasData).toBeFalsy();

    const clonedModel = model.clone();
    expect(clonedModel).toStrictEqual(model);
  });

  it("should handle data without contributions", () => {
    const model = new BaseModel(mockWebapp.Webapp);

    expect(model).toBeInstanceOf(BaseModel);
    expect(model.contributions).toStrictEqual({});
    expect(model.clone()).toStrictEqual(model);
  });

  it("should handle data with wrong contributions", () => {
    const wrongContributionResult = {
      data: {},
    };

    const model = new BaseModel(mockWebapp.Webapp, wrongContributionResult);

    expect(model).toBeInstanceOf(BaseModel);
  });

  it("should be able to get and set layouthints", () => {
    const model = new BaseModel();

    expect(model.layouthint).toBeInstanceOf(LayoutHintCollection);
    expect(model.layouthint.all).toStrictEqual([]);

    model.layouthint = ["test-hint"];
    expect(model.layouthint.first).toBe("test-hint");
  });

  it("can handle connectKeys", () => {
    const model = new BaseModel();

    model.connectKey = "ConnectKey";
    expect(model.connectKey).toBe("ConnectKey");
  });

  it("can dehydrate and rehydrate", () => {
    const model = new BaseModel({ name: "value" }, { name: "value" });
    model.connectKey = "ConnectKey";

    const dehydrateData = model.dehydrate();
    expect(dehydrateData).toStrictEqual({
      data: { name: "value" },
      contributions: { name: "value" },
      connectKey: "ConnectKey",
      options: {
        contextPath: "/BeInformed",
        origin: "",
      },
    });

    const newModel = new BaseModel();
    newModel.rehydrate(dehydrateData);
    expect(newModel.connectKey).toBe("ConnectKey");
  });

  it("can clone deep", () => {
    const model = new BaseModel({
      prop: {
        child: "value",
      },
    });

    const deepClone = model.clone();
    expect(model).not.toBe(deepClone);
    expect(model.data.prop === deepClone.data.prop).toBeFalsy();
    expect(model.data.prop.child).toBe(deepClone.data.prop.child);
  });
});
