terriajs
Version:
Geospatial data visualization platform.
617 lines (553 loc) • 16.7 kB
text/typescript
import { runInAction } from "mobx";
import createGuid from "terriajs-cesium/Source/Core/createGuid";
import { getName } from "../../../lib/ModelMixins/CatalogMemberMixin";
import CatalogGroup from "../../../lib/Models/Catalog/CatalogGroup";
import GeoJsonCatalogItem from "../../../lib/Models/Catalog/CatalogItems/GeoJsonCatalogItem";
import StubCatalogItem from "../../../lib/Models/Catalog/CatalogItems/StubCatalogItem";
import CatalogMemberFactory from "../../../lib/Models/Catalog/CatalogMemberFactory";
import SplitItemReference from "../../../lib/Models/Catalog/CatalogReferences/SplitItemReference";
import WebMapServiceCatalogItem from "../../../lib/Models/Catalog/Ows/WebMapServiceCatalogItem";
import CommonStrata from "../../../lib/Models/Definition/CommonStrata";
import upsertModelFromJson from "../../../lib/Models/Definition/upsertModelFromJson";
import Terria from "../../../lib/Models/Terria";
describe("CatalogGroup", function () {
let terria: Terria, json: any, catalogGroup: CatalogGroup;
beforeEach(function () {
terria = new Terria();
json = {
type: "group",
id: "mama",
name: "Test Group",
members: [
{
type: "group",
id: "child1"
},
{
type: "group",
id: "child2"
},
{
type: "group",
id: "child3"
}
]
};
catalogGroup = upsertModelFromJson(
CatalogMemberFactory,
terria,
"",
"definition",
json,
{}
).throwIfUndefined() as CatalogGroup;
});
it("re-orders members correctly", function () {
expect(catalogGroup instanceof CatalogGroup).toBe(true);
const item = terria.getModelById(CatalogGroup, "mama") as CatalogGroup;
const child1 = terria.getModelById(CatalogGroup, "child1") as CatalogGroup;
const child2 = terria.getModelById(CatalogGroup, "child2") as CatalogGroup;
expect(item).toBeDefined();
expect(item.type).toBe("group");
expect(item.members).toEqual(["child1", "child2", "child3"]);
item.moveMemberToIndex(CommonStrata.definition, child1, 1);
expect(item.members).toEqual(["child2", "child1", "child3"]);
item.moveMemberToIndex(CommonStrata.definition, child1, 2);
expect(item.members).toEqual(["child2", "child3", "child1"]);
item.moveMemberToIndex(CommonStrata.definition, child2, 2);
expect(item.members).toEqual(["child3", "child1", "child2"]);
item.moveMemberToIndex(CommonStrata.definition, child1, 0);
expect(item.members).toEqual(["child1", "child3", "child2"]);
});
it("throws when moving to non existent indices", function () {
expect(catalogGroup instanceof CatalogGroup).toBe(true);
const item = terria.getModelById(CatalogGroup, "mama") as CatalogGroup;
const child1 = terria.getModelById(CatalogGroup, "child1") as CatalogGroup;
expect(item).toBeDefined();
expect(item.type).toBe("group");
expect(item.members).toEqual(["child1", "child2", "child3"]);
expect(() => {
item.moveMemberToIndex(CommonStrata.definition, child1, -2);
}).toThrowError("Invalid 'newIndex' target: -2");
expect(() => {
item.moveMemberToIndex(CommonStrata.definition, child1, 3);
}).toThrowError("Invalid 'newIndex' target: 3");
});
it("loads valid items and ignores broken items", function () {
const groupWithBrokenItem = [
{
type: "geojson",
name: "Invalid GeoJSON item",
url: null
},
{
type: "geojson",
name: "Valid GeoJSON item",
url: "test/bike_racks.geojson"
},
{
type: "unknown",
name: "Invalid type"
},
{
name: "Just a name with no type"
},
// Empty nothingness
{}
];
const group = new CatalogGroup("brokenGroup", terria);
group.addMembersFromJson("definition", groupWithBrokenItem);
expect(group.members.length).toBe(5);
const member0 = terria.getModelById(
GeoJsonCatalogItem,
group.members[0] as string
);
const member1 = terria.getModelById(
GeoJsonCatalogItem,
group.members[1] as string
);
const invalidType = terria.getModelById(
StubCatalogItem,
group.members[2] as string
);
const noType = terria.getModelById(
StubCatalogItem,
group.members[3] as string
);
const nothingness = terria.getModelById(
StubCatalogItem,
group.members[4] as string
);
expect(member0).toBeDefined();
expect(member1).toBeDefined();
expect(invalidType).toBeDefined();
expect(noType).toBeDefined();
expect(nothingness).toBeDefined();
if (
member0 !== undefined &&
member1 !== undefined &&
invalidType !== undefined &&
noType !== undefined &&
nothingness !== undefined
) {
expect(member0.uniqueId).toBe("brokenGroup/Invalid GeoJSON item");
expect(member0.isExperiencingIssues).toBe(true);
expect(member1.uniqueId).toBe("brokenGroup/Valid GeoJSON item");
expect(member1.isExperiencingIssues).toBe(false);
expect(invalidType.type).toBe(StubCatalogItem.type);
expect(invalidType.name).toBe("brokenGroup/Invalid type (Stub)");
expect(invalidType.isExperiencingIssues).toBe(true);
expect(noType.type).toBe(StubCatalogItem.type);
expect(noType.name).toBe("brokenGroup/Just a name with no type (Stub)");
expect(noType.isExperiencingIssues).toBe(true);
expect(nothingness.type).toBe(StubCatalogItem.type);
expect(nothingness.name).toBe("[StubCatalogItem]");
expect(nothingness.isExperiencingIssues).toBe(true);
} else {
throw "bad";
}
});
it("removes excluded items/groups from memberModels", function () {
json = {
type: "group",
id: "grandmama",
name: "Test Group",
excludeMembers: ["grandchild1", "PARENT3", "some name"]
};
upsertModelFromJson(
CatalogMemberFactory,
terria,
"",
"definition",
json,
{}
).throwIfUndefined();
const item = terria.getModelById(CatalogGroup, "grandmama") as CatalogGroup;
item.addMembersFromJson(CommonStrata.definition, [
{
type: "group",
id: "parent1",
excludeMembers: ["grandchild4"],
members: [
{
type: "group",
id: "grandchild1"
},
{
type: "group",
id: "grandchild2"
},
{
type: "group",
id: "grandchild3"
},
{
type: "group",
id: "grandchild4"
},
{
type: "group",
id: "some-id",
name: "some name"
}
]
},
{
type: "group",
id: "parent2"
},
{
type: "group",
id: "PARENT3"
}
]);
expect(item.excludeMembers).toEqual([
"grandchild1",
"PARENT3",
"some name"
]);
expect(item.mergedExcludeMembers).toEqual([
"grandchild1",
"PARENT3",
"some name"
]);
const parent1 = terria.getModelById(
CatalogGroup,
"parent1"
) as CatalogGroup;
expect(item).toBeDefined();
expect(item.type).toBe("group");
expect(item.memberModels.map((member) => member.uniqueId)).toEqual([
"parent1",
"parent2"
]);
expect(parent1).toBeDefined();
expect(parent1.type).toBe("group");
expect(parent1.memberModels.map((member) => member.uniqueId)).toEqual([
"grandchild2",
"grandchild3"
]);
expect(parent1.excludeMembers).toEqual(["grandchild4"]);
expect(parent1.mergedExcludeMembers).toEqual([
"grandchild4",
"grandchild1",
"PARENT3",
"some name"
]);
});
it("only includes items/groups with includeMembersRegex", async function () {
json = {
type: "group",
id: "test",
includeMembersRegex: ".+(1|2)",
members: [
{
type: "group",
id: "grandchild1"
},
{
type: "group",
id: "grandchild2"
},
{
type: "group",
id: "grandchild3"
},
{
type: "group",
id: "grandchild4"
}
]
};
upsertModelFromJson(
CatalogMemberFactory,
terria,
"",
"definition",
json,
{}
).throwIfUndefined();
const item = terria.getModelById(CatalogGroup, "test") as CatalogGroup;
await item.loadMembers();
expect(item.includeMembersRegex).toEqual(".+(1|2)");
expect(item.memberModels.map((member) => getName(member))).toEqual([
"grandchild1",
"grandchild2"
]);
});
it("combines includeMembersRegex and excludeMembers", async function () {
json = {
type: "group",
id: "test",
includeMembersRegex: ".+(1|2)",
excludeMembers: ["grandchild1"],
members: [
{
type: "group",
id: "grandchild1"
},
{
type: "group",
id: "grandchild2"
},
{
type: "group",
id: "grandchild3"
},
{
type: "group",
id: "grandchild4"
}
]
};
upsertModelFromJson(
CatalogMemberFactory,
terria,
"",
"definition",
json,
{}
).throwIfUndefined();
const item = terria.getModelById(CatalogGroup, "test") as CatalogGroup;
await item.loadMembers();
expect(item.includeMembersRegex).toEqual(".+(1|2)");
expect(item.mergedExcludeMembers).toEqual(["grandchild1"]);
expect(item.memberModels.map((member) => getName(member))).toEqual([
"grandchild2"
]);
});
it("sortMembersBy", function () {
const item = new CatalogGroup("what", terria);
item.addMembersFromJson(CommonStrata.definition, [
{
type: "group",
name: "1",
description: "f"
},
{
type: "group",
name: "aCC"
},
{
type: "group",
name: "10",
description: "d"
},
{
type: "group",
name: "2",
description: "c"
},
{
type: "group",
name: "AC",
description: "a"
},
{
type: "group",
name: "ab",
description: "b"
},
{ type: "terria-reference", name: "A reference" }
]);
expect(item.memberModels.map((member) => (member as any).name)).toEqual([
"1",
"aCC",
"10",
"2",
"AC",
"ab",
"A reference"
]);
item.setTrait(CommonStrata.user, "sortMembersBy", "name");
expect(item.memberModels.map((member) => (member as any).name)).toEqual([
"1",
"2",
"10",
"A reference",
"ab",
"AC",
"aCC"
]);
item.setTrait(CommonStrata.user, "sortMembersBy", "description");
expect(item.memberModels.map((member) => (member as any).name)).toEqual([
"AC",
"ab",
"2",
"10",
"1",
"aCC",
"A reference"
]);
});
describe("itemProperties, itemPropertiesByType and itemPropertiesByIds", () => {
beforeEach(() => {
json = {
type: "group",
id: "grandmama",
name: "Test Group",
itemProperties: { name: "some other name" },
itemPropertiesByType: [
{ type: "wms", itemProperties: { name: "some WMS name" } },
{
type: "geojson",
itemProperties: { url: "some geojson url (by type)" }
}
],
itemPropertiesByIds: [
{ ids: ["wms-1"], itemProperties: { url: "some WMS url" } },
{
ids: ["geojson-1"],
itemProperties: { url: "some geojson url (by ID)" }
}
],
members: [
{
type: "group",
id: "parent1",
name: "Parent 1",
members: [
{ type: "wms", id: "wms-1", name: "wms definition name" },
{
type: "geojson",
id: "geojson-1",
name: "geojson definition name"
}
]
}
]
};
upsertModelFromJson(
CatalogMemberFactory,
terria,
"",
"definition",
json,
{}
).throwIfUndefined();
});
it("correctly applies traits", async function () {
const item = terria.getModelById(
CatalogGroup,
"grandmama"
) as CatalogGroup;
await item.loadMembers();
const parent1 = terria.getModelById(
CatalogGroup,
"parent1"
) as CatalogGroup;
expect(parent1).toBeDefined();
expect(parent1.itemProperties).toEqual({ name: "some other name" });
expect(parent1.name).toBe("Parent 1");
await parent1.loadMembers();
const geojsonItem = terria.getModelById(
GeoJsonCatalogItem,
"geojson-1"
) as GeoJsonCatalogItem;
expect(geojsonItem.name).toBe("some other name");
expect(geojsonItem.url).toBe("some geojson url (by ID)");
const wmsItem = terria.getModelById(
WebMapServiceCatalogItem,
"wms-1"
) as WebMapServiceCatalogItem;
expect(wmsItem.name).toBe("some WMS name");
expect(wmsItem.url).toBe("some WMS url");
});
it("supports splitting items with itemProperties", async function () {
const item = terria.getModelById(
CatalogGroup,
"grandmama"
) as CatalogGroup;
await item.loadMembers();
const parent1 = terria.getModelById(
CatalogGroup,
"parent1"
) as CatalogGroup;
await parent1.loadMembers();
const geojsonItem = terria.getModelById(
GeoJsonCatalogItem,
"geojson-1"
) as GeoJsonCatalogItem;
const splitRef = new SplitItemReference(createGuid(), terria);
terria.addModel(splitRef);
runInAction(() => {
splitRef.setTrait(
CommonStrata.user,
"splitSourceItemId",
geojsonItem.uniqueId
);
});
await splitRef.loadReference();
expect(splitRef.target instanceof GeoJsonCatalogItem).toBe(true);
});
});
describe("mergeGroupsByName", () => {
beforeEach(() => {
json = {
type: "group",
id: "root",
name: "Test Group",
members: [
{
type: "group",
id: "group-1",
name: "Group with the same name",
members: [
// Note these two items **won't** be merged when `mergeGroupsByName = true` - as it only applies to top level
{ type: "wms", id: "wms-1", name: "wms with the same name" },
{ type: "wms", id: "wms-2", name: "wms with the same name" },
{
type: "geojson",
id: "geojson-1",
name: "geojson 1"
}
]
},
{
type: "group",
id: "group-2",
name: "Group with the same name",
members: [
{ type: "wms", id: "wms-3", name: "wms 3" },
{
type: "geojson",
id: "geojson-2",
name: "geojson 2"
}
]
}
]
};
upsertModelFromJson(
CatalogMemberFactory,
terria,
"",
"definition",
json,
{ replaceStratum: true }
).throwIfUndefined();
});
it("set to false", async function () {
const item = terria.getModelById(CatalogGroup, "root") as CatalogGroup;
item.setTrait(CommonStrata.definition, "mergeGroupsByName", false);
(await item.loadMembers()).throwIfError();
expect(item.memberModels.length).toBe(2);
const parent1 = item.memberModels[0] as CatalogGroup;
(await parent1.loadMembers()).throwIfError();
expect(parent1.memberModels.length).toBe(3);
const parent1Copy = item.memberModels[1] as CatalogGroup;
(await parent1Copy.loadMembers()).throwIfError();
expect(parent1Copy.memberModels.length).toBe(2);
expect(parent1.name).toBe(parent1Copy.name);
});
it("set to true", async function () {
const item = terria.getModelById(CatalogGroup, "root") as CatalogGroup;
item.setTrait(CommonStrata.definition, "mergeGroupsByName", true);
(await item.loadMembers()).throwIfError();
expect(item.memberModels.length).toBe(1);
const mergedGroup = item.memberModels[0] as CatalogGroup;
(await mergedGroup.loadMembers()).throwIfError();
expect(mergedGroup.memberModels.length).toBe(5);
});
});
});