267 lines
9.2 KiB
JavaScript
267 lines
9.2 KiB
JavaScript
import { describe, expect, test } from "@odoo/hoot";
|
|
import { Model, helpers } from "@odoo/o-spreadsheet";
|
|
import { addColumns, deleteColumns, redo, undo } from "@spreadsheet/../tests/helpers/commands";
|
|
import { getBasicServerData } from "@spreadsheet/../tests/helpers/data";
|
|
import {
|
|
setupCollaborativeEnv,
|
|
spExpect,
|
|
} from "@spreadsheet_edition/../tests/helpers/collaborative_helpers";
|
|
import { defineTestSpreadsheetEditionModels } from "@test_spreadsheet_edition/../tests/helpers/data";
|
|
|
|
describe.current.tags("headless");
|
|
defineTestSpreadsheetEditionModels();
|
|
|
|
const { toCartesian, toZone } = helpers;
|
|
|
|
test("Simple thread creation", () => {
|
|
const model = new Model({ sheets: [{ id: "sh1" }] });
|
|
const threadId = 1;
|
|
const cellPosition = { sheetId: "sh1", ...toCartesian("A1") };
|
|
|
|
model.dispatch("ADD_COMMENT_THREAD", { ...cellPosition, threadId });
|
|
expect(model.getters.getThreadInfo(threadId)).toEqual({
|
|
...cellPosition,
|
|
threadId,
|
|
isResolved: false,
|
|
});
|
|
const threadIds = model.getters.getCellThreads(cellPosition);
|
|
expect(threadIds).toEqual([{ threadId, isResolved: false }]);
|
|
|
|
undo(model);
|
|
expect(model.getters.getThreadInfo(threadId)).toEqual(undefined);
|
|
expect(model.getters.getCellThreads(cellPosition)).toBe(undefined);
|
|
|
|
redo(model);
|
|
expect(model.getters.getThreadInfo(threadId)).toEqual({
|
|
...cellPosition,
|
|
threadId,
|
|
isResolved: false,
|
|
});
|
|
expect(model.getters.getCellThreads(cellPosition)).toEqual([{ threadId, isResolved: false }]);
|
|
});
|
|
|
|
test("Multiple threads on the same cell", () => {
|
|
const model = new Model({ sheets: [{ id: "sh1" }] });
|
|
const cellPosition = { sheetId: "sh1", ...toCartesian("A1") };
|
|
|
|
model.dispatch("ADD_COMMENT_THREAD", { ...cellPosition, threadId: 1 });
|
|
model.dispatch("ADD_COMMENT_THREAD", { ...cellPosition, threadId: 2 });
|
|
const threadIds = model.getters.getCellThreads(cellPosition);
|
|
expect(threadIds).toEqual([
|
|
{ threadId: 1, isResolved: false },
|
|
{ threadId: 2, isResolved: false },
|
|
]);
|
|
undo(model);
|
|
expect(model.getters.getCellThreads(cellPosition)).toEqual([
|
|
{ threadId: 1, isResolved: false },
|
|
]);
|
|
undo(model);
|
|
expect(model.getters.getCellThreads(cellPosition)).toBe(undefined);
|
|
redo(model);
|
|
expect(model.getters.getCellThreads(cellPosition)).toEqual([
|
|
{ threadId: 1, isResolved: false },
|
|
]);
|
|
redo(model);
|
|
expect(model.getters.getCellThreads(cellPosition)).toEqual([
|
|
{ threadId: 1, isResolved: false },
|
|
{ threadId: 2, isResolved: false },
|
|
]);
|
|
});
|
|
|
|
test("Thread on merged cell", () => {
|
|
const model = new Model();
|
|
const threadId = 1;
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
const cellPosition = { sheetId, ...toCartesian("A1") };
|
|
model.dispatch("ADD_MERGE", {
|
|
sheetId,
|
|
target: [toZone("A1:B2")],
|
|
force: true,
|
|
});
|
|
model.dispatch("ADD_COMMENT_THREAD", { ...cellPosition, threadId });
|
|
expect(model.getters.getThreadInfo(threadId)).toEqual({
|
|
...cellPosition,
|
|
threadId,
|
|
isResolved: false,
|
|
});
|
|
});
|
|
|
|
test("Thread removed on sheet deletion", () => {
|
|
const model = new Model();
|
|
model.dispatch("CREATE_SHEET", { sheetId: "sh2" });
|
|
model.dispatch("ADD_COMMENT_THREAD", { sheetId: "sh2", col: 1, row: 1, threadId: 1 });
|
|
expect(model.getters.getSpreadsheetThreads(["sh2"])).toEqual([
|
|
{ sheetId: "sh2", col: 1, row: 1, threadId: 1, isResolved: false },
|
|
]);
|
|
model.dispatch("DELETE_SHEET", { sheetId: "sh2" });
|
|
expect(model.getters.getSpreadsheetThreads(["sh2"])).toEqual([]);
|
|
});
|
|
|
|
test("can add a column in a duplicated sheet", () => {
|
|
const model = new Model();
|
|
const activeSheetId = model.getters.getActiveSheetId();
|
|
model.dispatch("DUPLICATE_SHEET", {
|
|
sheetId: activeSheetId,
|
|
sheetIdTo: "sh2",
|
|
sheetNameTo: "sh2",
|
|
});
|
|
addColumns(model, "before", "B", 1, "sh2");
|
|
expect(model.getters.getSpreadsheetThreads(["sh2"])).toEqual([]);
|
|
});
|
|
|
|
test("Thread moved on sheet structure change", () => {
|
|
const model = new Model();
|
|
const threadId = 1;
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
model.dispatch("ADD_COMMENT_THREAD", { sheetId, ...toCartesian("B2"), threadId: 1 });
|
|
expect(model.getters.getThreadInfo(threadId)).toEqual({
|
|
sheetId,
|
|
...toCartesian("B2"),
|
|
threadId,
|
|
isResolved: false,
|
|
});
|
|
addColumns(model, "before", "B", 1);
|
|
expect(model.getters.getThreadInfo(threadId)).toEqual({
|
|
sheetId,
|
|
...toCartesian("C2"),
|
|
threadId,
|
|
isResolved: false,
|
|
});
|
|
deleteColumns(model, ["C"]);
|
|
expect(model.getters.getThreadInfo(threadId)).toEqual(undefined);
|
|
});
|
|
|
|
test("Can cut/paste a thread", () => {
|
|
const model = new Model();
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
model.dispatch("ADD_COMMENT_THREAD", {
|
|
sheetId,
|
|
...toCartesian("B2"),
|
|
threadId: 1,
|
|
});
|
|
model.selection.selectCell(1, 1);
|
|
model.dispatch("CUT");
|
|
model.dispatch("PASTE", { target: [toZone("C2")] });
|
|
expect(model.getters.getThreadInfo(1)).toEqual({
|
|
sheetId,
|
|
...toCartesian("C2"),
|
|
threadId: 1,
|
|
isResolved: false,
|
|
});
|
|
});
|
|
|
|
test("Threads are not affected by copy/paste", () => {
|
|
const model = new Model();
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
model.dispatch("ADD_COMMENT_THREAD", {
|
|
sheetId,
|
|
...toCartesian("B2"),
|
|
threadId: 1,
|
|
});
|
|
model.selection.selectCell(1, 1);
|
|
model.dispatch("COPY");
|
|
model.dispatch("PASTE", { target: [toZone("C2")] });
|
|
expect(model.getters.getThreadInfo(1)).toEqual({
|
|
sheetId,
|
|
...toCartesian("B2"),
|
|
threadId: 1,
|
|
isResolved: false,
|
|
});
|
|
});
|
|
|
|
test("Threads are not affected by paste from clipboard os", () => {
|
|
const model = new Model();
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
model.dispatch("ADD_COMMENT_THREAD", {
|
|
sheetId,
|
|
...toCartesian("B2"),
|
|
threadId: 1,
|
|
});
|
|
model.dispatch("COPY");
|
|
model.selection.selectCell(1, 1);
|
|
model.dispatch("PASTE_FROM_OS_CLIPBOARD", {
|
|
target: [toZone("C2")],
|
|
text: "coucou",
|
|
pasteOption: {},
|
|
clipboardContent: {
|
|
["text/plain"]: "Copy in OS clipboard",
|
|
},
|
|
});
|
|
model.dispatch("COPY");
|
|
model.dispatch("PASTE", { target: [toZone("C2")] });
|
|
expect(model.getters.getThreadInfo(1)).toEqual({
|
|
sheetId,
|
|
...toCartesian("B2"),
|
|
threadId: 1,
|
|
isResolved: false,
|
|
});
|
|
});
|
|
|
|
test("Resolve/re-open a thread", () => {
|
|
const model = new Model();
|
|
const threadId = 1;
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
const createPayload = { sheetId, ...toCartesian("B2"), threadId };
|
|
const resolvedThread = { ...createPayload, isResolved: true };
|
|
const openThread = { ...createPayload, isResolved: false };
|
|
model.dispatch("ADD_COMMENT_THREAD", createPayload);
|
|
model.dispatch("EDIT_COMMENT_THREAD", resolvedThread);
|
|
expect(model.getters.getThreadInfo(1)).toEqual(resolvedThread);
|
|
undo(model);
|
|
expect(model.getters.getThreadInfo(1)).toEqual(openThread);
|
|
redo(model);
|
|
expect(model.getters.getThreadInfo(1)).toEqual(resolvedThread);
|
|
});
|
|
|
|
test("Threads are imported/exported", () => {
|
|
const model = new Model();
|
|
const threadId = 1;
|
|
const sheetId = model.getters.getActiveSheetId();
|
|
model.dispatch("ADD_COMMENT_THREAD", { sheetId, ...toCartesian("B2"), threadId });
|
|
|
|
const newModel = new Model(model.exportData());
|
|
expect(newModel.getters.getSpreadsheetThreads([sheetId])).toEqual([
|
|
{ sheetId, ...toCartesian("B2"), threadId, isResolved: false },
|
|
]);
|
|
});
|
|
|
|
test("collaborative: Insert comment on sheet structure change", async () => {
|
|
const env = await setupCollaborativeEnv(getBasicServerData());
|
|
const { alice, bob, charlie, network } = env;
|
|
const sheetId = alice.getters.getActiveSheetId();
|
|
|
|
await network.concurrent(() => {
|
|
addColumns(alice, "before", "B", 1);
|
|
bob.dispatch("ADD_COMMENT_THREAD", { sheetId, col: 4, row: 4, threadId: 1 });
|
|
});
|
|
|
|
spExpect([alice, bob, charlie]).toHaveSynchronizedValue(
|
|
(user) => user.getters.getSpreadsheetThreads([sheetId]),
|
|
[{ sheetId, col: 5, row: 4, threadId: 1, isResolved: false }]
|
|
);
|
|
});
|
|
|
|
test("collaborative: Parallel insertion of comments", async () => {
|
|
const env = await setupCollaborativeEnv(getBasicServerData());
|
|
const { alice, bob, charlie, network } = env;
|
|
const sheetId = alice.getters.getActiveSheetId();
|
|
|
|
await network.concurrent(() => {
|
|
alice.dispatch("ADD_COMMENT_THREAD", { sheetId, col: 1, row: 1, threadId: 2 });
|
|
bob.dispatch("ADD_COMMENT_THREAD", { sheetId, col: 4, row: 4, threadId: 1 });
|
|
});
|
|
|
|
spExpect([alice, bob, charlie]).toHaveSynchronizedValue(
|
|
(user) => user.getters.getSpreadsheetThreads([sheetId]),
|
|
[
|
|
{ sheetId, col: 1, row: 1, threadId: 2, isResolved: false },
|
|
{ sheetId, col: 4, row: 4, threadId: 1, isResolved: false },
|
|
]
|
|
);
|
|
undo(alice);
|
|
spExpect([alice, bob, charlie]).toHaveSynchronizedValue(
|
|
(user) => user.getters.getSpreadsheetThreads([sheetId]),
|
|
[{ sheetId, col: 4, row: 4, threadId: 1, isResolved: false }]
|
|
);
|
|
});
|