Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions vue-model-api/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export { useModelsFromJson } from "./useModelsFromJson";
export { useModelClient } from "./useModelClient";
export { useReplicatedModels } from "./useReplicatedModels";
export { useReplicatedModel } from "./useReplicatedModel";
export { useReadonlyVersion } from "./useReadonlyVersion";
315 changes: 185 additions & 130 deletions vue-model-api/src/useReplicatedModel.test.ts
Original file line number Diff line number Diff line change
@@ -1,169 +1,224 @@
import { org } from "@modelix/model-client";
import type { INodeJS } from "@modelix/ts-model-api";
import { toRoleJS } from "@modelix/ts-model-api";
import { watchEffect, type Ref, ref } from "vue";
import { watchEffect } from "vue";
import { useModelClient } from "./useModelClient";
import { useReplicatedModel } from "./useReplicatedModel";
import IdSchemeJS = org.modelix.model.client2.IdSchemeJS;

type BranchJS = org.modelix.model.client2.MutableModelTreeJs;
type ReplicatedModelJS = org.modelix.model.client2.ReplicatedModelJS;
type ClientJS = org.modelix.model.client2.ClientJS;
type ReplicatedModelJS = org.modelix.model.client2.ReplicatedModelJS;

const { loadModelsFromJson } = org.modelix.model.client2;

class SuccessfulBranchJS {
public rootNode: INodeJS;
import ReplicatedModelParameters = org.modelix.model.client2.ReplicatedModelParameters;

constructor(branchId: string) {
const root = {
root: {},
};
test("test wrapper backwards compatibility", (done) => {
/* eslint-disable */
class SuccessfulClientJS implements ClientJS {
startReplicatedModel(
repositoryId: string,
branchId: string,
idScheme: org.modelix.model.client2.IdSchemeJS,
): Promise<org.modelix.model.client2.ReplicatedModelJS> {
// Mock implementation that returns a dummy object with a branch
const rootNode = loadModelsFromJson([JSON.stringify({ root: {} })]);
rootNode.setPropertyValue(toRoleJS("branchId"), branchId);

const branch = {
rootNode,
getRootNodes: () => [rootNode],
addListener: jest.fn(),
removeListener: jest.fn(),
resolveNode: jest.fn(),
};

const replicatedModel = {
getBranch: () => branch,
dispose: jest.fn(),
getCurrentVersionInformation: jest.fn(),
} as unknown as ReplicatedModelJS;

return Promise.resolve(replicatedModel);
}

this.rootNode = loadModelsFromJson([JSON.stringify(root)]);
this.rootNode.setPropertyValue(toRoleJS("branchId"), branchId);
}
startReplicatedModels(
parameters: ReplicatedModelParameters[],
): Promise<ReplicatedModelJS> {
// Mock implementation that returns a dummy object with a branch
const branchId = parameters[0].branchId;
const rootNode = loadModelsFromJson([JSON.stringify({ root: {} })]);
rootNode.setPropertyValue(toRoleJS("branchId"), branchId);

const branch = {
rootNode,
getRootNodes: () => [rootNode],
addListener: jest.fn(),
removeListener: jest.fn(),
resolveNode: jest.fn(),
};

const replicatedModel = {
getBranch: () => branch,
dispose: jest.fn(),
getCurrentVersionInformation: jest.fn(),
} as unknown as ReplicatedModelJS;

return Promise.resolve(replicatedModel);
}

addListener = jest.fn();
}
readonly __doNotUseOrImplementIt: any;

class SuccessfulReplicatedModelJS {
private branch: BranchJS;
constructor(branchId: string) {
this.branch = new SuccessfulBranchJS(branchId) as unknown as BranchJS;
}
createBranch(
repositoryId: string,
branchId: string,
versionHash: string,
): Promise<void> {
throw Error("Not implemented");
}

getBranch() {
return this.branch;
}
dispose = jest.fn();
}
deleteBranch(repositoryId: string, branchId: string): Promise<boolean> {
throw Error("Not implemented");
}

test("test branch connects", (done) => {
class SuccessfulClientJS {
startReplicatedModel(
_repositoryId: string,
branchId: string,
): Promise<ReplicatedModelJS> {
return Promise.resolve(
new SuccessfulReplicatedModelJS(
branchId,
) as unknown as ReplicatedModelJS,
);
diffAsMutationParameters(
repositoryId: string,
newVersion: string,
oldVersion: string,
): Promise<Array<org.modelix.model.client2.MutationParametersJS>> {
throw Error("Not implemented");
}
}

const { client } = useModelClient("anURL", () =>
Promise.resolve(new SuccessfulClientJS() as unknown as ClientJS),
);
const { rootNode, replicatedModel } = useReplicatedModel(
client,
"aRepository",
"aBranch",
IdSchemeJS.MODELIX,
);
watchEffect(() => {
if (rootNode.value !== null && replicatedModel.value !== null) {
expect(rootNode.value.getPropertyValue(toRoleJS("branchId"))).toBe(
"aBranch",
);
done();
dispose(): void {
throw Error("Not implemented");
}
});
});

test("test branch connection error is exposed", (done) => {
class FailingClientJS {
startReplicatedModel(
_repositoryId: string,
_branchId: string,
): Promise<BranchJS> {
return Promise.reject("Could not connect branch.");
fetchBranches(repositoryId: string): Promise<Array<string>> {
throw Error("Not implemented");
}
}

const { client } = useModelClient("anURL", () =>
Promise.resolve(new FailingClientJS() as unknown as ClientJS),
);
fetchBranchesWithHashes(
repositoryId: string,
): Promise<Array<org.modelix.model.server.api.BranchInfo>> {
throw Error("Not implemented");
}

const { error } = useReplicatedModel(
client,
"aRepository",
"aBranch",
IdSchemeJS.MODELIX,
);
fetchRepositories(): Promise<Array<string>> {
throw Error("Not implemented");
}

watchEffect(() => {
if (error.value !== null) {
expect(error.value).toBe("Could not connect branch.");
done();
getHistoryForFixedIntervals(
repositoryId: string,
headVersion: string,
intervalDurationSeconds: number,
skip: number,
limit: number,
): Promise<Array<org.modelix.model.client2.HistoryIntervalJS>> {
throw Error("Not implemented");
}
});
});

describe("does not start model", () => {
const startReplicatedModel = jest.fn((repositoryId, branchId) =>
Promise.resolve(
new SuccessfulReplicatedModelJS(branchId) as unknown as ReplicatedModelJS,
),
);
getHistoryForFixedIntervalsForBranch(
repositoryId: string,
branchId: string,
intervalDurationSeconds: number,
skip: number,
limit: number,
): Promise<Array<org.modelix.model.client2.HistoryIntervalJS>> {
throw Error("Not implemented");
}

let client: Ref<ClientJS | null>;
class MockClientJS {
startReplicatedModel(
_repositoryId: string,
_branchId: string,
): Promise<ReplicatedModelJS> {
return startReplicatedModel(_repositoryId, _branchId);
getHistoryForProvidedIntervals(
repositoryId: string,
headVersion: string,
splitAt: Array<Date>,
): Promise<Array<org.modelix.model.client2.HistoryIntervalJS>> {
throw Error("Not implemented");
}
}

beforeEach(() => {
jest.clearAllMocks();
client = useModelClient("anURL", () =>
Promise.resolve(new MockClientJS() as unknown as ClientJS),
).client;
});
getHistoryForProvidedIntervalsForBranch(
repositoryId: string,
branchId: string,
splitAt: Array<Date>,
): Promise<Array<org.modelix.model.client2.HistoryIntervalJS>> {
throw Error("Not implemented");
}

test("if client is undefined", () => {
useReplicatedModel(undefined, "aRepository", "aBranch", IdSchemeJS.MODELIX);
expect(startReplicatedModel).not.toHaveBeenCalled();
});
getHistoryRange(
repositoryId: string,
headVersion: string,
skip: number,
limit: number,
): Promise<Array<org.modelix.model.client2.VersionInformationJS>> {
throw Error("Not implemented");
}

test("if repositoryId is undefined", () => {
useReplicatedModel(client, undefined, "aBranch", IdSchemeJS.MODELIX);
expect(startReplicatedModel).not.toHaveBeenCalled();
});
getHistoryRangeForBranch(
repositoryId: string,
branchId: string,
skip: number,
limit: number,
): Promise<Array<org.modelix.model.client2.VersionInformationJS>> {
throw Error("Not implemented");
}

test("if branchId is undefined", () => {
useReplicatedModel(client, "aRepository", undefined, IdSchemeJS.MODELIX);
expect(startReplicatedModel).not.toHaveBeenCalled();
});
getHistorySessions(
repositoryId: string,
headVersion: string,
delaySeconds: number,
skip: number,
limit: number,
): Promise<Array<org.modelix.model.client2.HistoryIntervalJS>> {
throw Error("Not implemented");
}

test("if idScheme is undefined", () => {
useReplicatedModel(client, "aRepository", "aBranch", undefined);
expect(startReplicatedModel).not.toHaveBeenCalled();
});
getHistorySessionsForBranch(
repositoryId: string,
branchId: string,
delaySeconds: number,
skip: number,
limit: number,
): Promise<Array<org.modelix.model.client2.HistoryIntervalJS>> {
throw Error("Not implemented");
}

test("if repositoryId switches to another value", async () => {
const repositoryId = ref<string | undefined>("aRepository");
useReplicatedModel(client, repositoryId, "aBranch", IdSchemeJS.MODELIX);
expect(startReplicatedModel).toHaveBeenCalled();
initRepository(repositoryId: string, useRoleIds?: boolean): Promise<void> {
throw Error("Not implemented");
}

startReplicatedModel.mockClear();
repositoryId.value = "aNewValue";
await new Promise(process.nextTick);
expect(startReplicatedModel).toHaveBeenCalled();
});
loadReadonlyVersion(
repositoryId: string,
versionHash: string,
): Promise<org.modelix.model.client2.VersionInformationWithModelTree> {
throw Error("Not implemented");
}

revertTo(
repositoryId: string,
branchId: string,
targetVersionHash: string,
): Promise<string> {
throw Error("Not implemented");
}

setClientProvidedUserId(userId: string): void {}
}

test("if repositoryId switches to undefined", async () => {
const repositoryId = ref<string | undefined>("aRepository");
useReplicatedModel(client, repositoryId, "aBranch", IdSchemeJS.MODELIX);
expect(startReplicatedModel).toHaveBeenCalled();
const { client } = useModelClient("anURL", () =>
Promise.resolve(new SuccessfulClientJS() as unknown as ClientJS),
);

startReplicatedModel.mockClear();
repositoryId.value = undefined;
await new Promise(process.nextTick);
expect(startReplicatedModel).not.toHaveBeenCalled();
const { rootNode, replicatedModel } = useReplicatedModel(
client,
"aRepository",
"aBranch",
IdSchemeJS.MODELIX,
);

watchEffect(() => {
if (rootNode.value !== null && replicatedModel.value !== null) {
expect(rootNode.value.getPropertyValue(toRoleJS("branchId"))).toBe(
"aBranch",
);
done();
}
});
});
Loading
Loading