1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/documents_spreadsheet/tests/test_spreadsheet_collaborative.py
2024-12-10 09:04:09 +07:00

422 lines
17 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
import base64
from freezegun import freeze_time
from uuid import uuid4
from .common import SpreadsheetTestCommon
from odoo.tests.common import new_test_user, tagged
from odoo.exceptions import AccessError
@tagged("collaborative_spreadsheet")
class SpreadsheetCollaborative(SpreadsheetTestCommon):
def test_compute_revision_without_session(self):
spreadsheet = self.create_spreadsheet()
self.assertEqual(spreadsheet.server_revision_id, "START_REVISION")
def test_compute_revision_with_session(self):
spreadsheet = self.create_spreadsheet()
spreadsheet.join_spreadsheet_session()
commands = self.new_revision_data(spreadsheet)
spreadsheet.dispatch_spreadsheet_message(commands)
revision_data2 = self.new_revision_data(spreadsheet, nextRevisionId="nextone")
spreadsheet.dispatch_spreadsheet_message(revision_data2)
self.assertEqual(spreadsheet.server_revision_id, "nextone")
def test_dispatch_new_revision(self):
spreadsheet = self.create_spreadsheet()
commands = self.new_revision_data(spreadsheet)
spreadsheet.join_spreadsheet_session()
spreadsheet.dispatch_spreadsheet_message(commands)
self.assertEqual(
len(spreadsheet.spreadsheet_revision_ids),
1,
"It should have recorded one revision",
)
self.assertEqual(
spreadsheet.server_revision_id,
commands["nextRevisionId"],
"It should have updated its revision",
)
self.assertEqual(
json.loads(spreadsheet.spreadsheet_revision_ids.commands),
{"commands": commands["commands"], "id": spreadsheet.id, "type": commands["type"]},
"It should have saved the revision data",
)
def test_dispatch_revision_concurrent_first_revision_id(self):
spreadsheet = self.create_spreadsheet()
spreadsheet.join_spreadsheet_session()
start_revision = spreadsheet.server_revision_id
revision1 = self.new_revision_data(spreadsheet, serverRevisionId=start_revision)
spreadsheet.dispatch_spreadsheet_message(revision1)
self.assertEqual(
len(spreadsheet.spreadsheet_revision_ids),
1,
"It should have recorded the revision",
)
revision2 = self.new_revision_data(spreadsheet, serverRevisionId=start_revision)
spreadsheet.dispatch_spreadsheet_message(revision2)
self.assertEqual(
len(spreadsheet.spreadsheet_revision_ids),
1,
"It should not have recorded the revision",
)
self.assertEqual(
spreadsheet.server_revision_id,
revision1["nextRevisionId"],
"The revision should not have been updated",
)
def test_join_spreadsheet_session(self):
spreadsheet = self.create_spreadsheet()
data = spreadsheet.join_spreadsheet_session()
self.assertEqual(data["data"], {})
self.assertEqual(data["revisions"], [], "It should not have past revisions")
def test_join_active_spreadsheet_session(self):
spreadsheet = self.create_spreadsheet()
commands = self.new_revision_data(spreadsheet)
spreadsheet.join_spreadsheet_session()
spreadsheet.dispatch_spreadsheet_message(commands)
spreadsheet = spreadsheet.join_spreadsheet_session()
del commands["clientId"]
self.assertEqual(spreadsheet["data"], {})
self.assertEqual(spreadsheet["revisions"], [commands], "It should have past revisions")
def test_snapshot_spreadsheet_save_data(self):
spreadsheet = self.create_spreadsheet()
spreadsheet.dispatch_spreadsheet_message(self.new_revision_data(spreadsheet))
self.assertEqual(
len(spreadsheet.spreadsheet_revision_ids), 1, "It should have 1 revision"
)
is_accepted = self.snapshot(
spreadsheet,
spreadsheet.server_revision_id, "snapshot-revision-id", {"sheets": [], "revisionId": "snapshot-revision-id"},
)
self.assertTrue(is_accepted, "It should have accepted the snapshot")
self.assertEqual(
len(spreadsheet.spreadsheet_revision_ids),
0,
"It should have archived the revision history",
)
snapshot_revision = spreadsheet.with_context(active_test=False).spreadsheet_revision_ids[-1]
self.assertEqual(
json.loads(snapshot_revision.commands),
{"type": "SNAPSHOT_CREATED", "version": 1},
"It should have saved a snapshot revision"
)
self.assertEqual(base64.decodebytes(spreadsheet.spreadsheet_snapshot), b'{"sheets": [], "revisionId": "snapshot-revision-id"}', "It should have saved the data")
self.assertEqual(
spreadsheet.server_revision_id,
"snapshot-revision-id",
"It should have updated the snapshot revision"
)
def test_snapshot_inconsistent_revision_id(self):
spreadsheet = self.create_spreadsheet()
with self.assertRaises(ValueError):
self.snapshot(
spreadsheet,
spreadsheet.server_revision_id, "snapshot-revision-id", {"sheets": [], "revisionId": "another-revision-id"},
)
def test_snapshot_spreadsheet_with_invalid_revision(self):
spreadsheet = self.create_spreadsheet()
spreadsheet.join_spreadsheet_session()
first_revision = spreadsheet.server_revision_id
spreadsheet.dispatch_spreadsheet_message(self.new_revision_data(spreadsheet))
current_data = spreadsheet.spreadsheet_snapshot
current_revision = spreadsheet.server_revision_id
self.assertEqual(
len(spreadsheet.spreadsheet_revision_ids), 1, "It should have 1 revision"
)
is_accepted = self.snapshot(spreadsheet, first_revision, "snapshot-revision-id", {"revisionId": "snapshot-revision-id"})
self.assertFalse(is_accepted, "It should not have accepted the snapshot")
self.assertEqual(spreadsheet.spreadsheet_snapshot, current_data, "It should not have saved the data")
self.assertEqual(
current_revision,
spreadsheet.server_revision_id,
"The revision should not have been updated",
)
def test_unlink_revisions(self):
spreadsheet = self.create_spreadsheet()
spreadsheet.dispatch_spreadsheet_message(
self.new_revision_data(spreadsheet)
)
ids = spreadsheet.spreadsheet_revision_ids.ids
spreadsheet.unlink()
self.assertFalse(self.env["spreadsheet.revision"].browse(ids).exists())
def test_unlink_archived_revisions(self):
spreadsheet = self.create_spreadsheet()
spreadsheet.dispatch_spreadsheet_message(
self.new_revision_data(spreadsheet)
)
self.snapshot(
spreadsheet,
spreadsheet.server_revision_id, "snapshot-id", {"revisionId": "snapshot-id"},
)
revisions = spreadsheet.with_context(active_test=False).spreadsheet_revision_ids
self.assertTrue(revisions)
self.assertFalse(any(revisions.mapped('active')))
spreadsheet.unlink()
self.assertFalse(revisions.exists())
@tagged("collaborative_spreadsheet")
class SpreadsheetORMAccess(SpreadsheetTestCommon):
@classmethod
def setUpClass(cls):
super(SpreadsheetORMAccess, cls).setUpClass()
cls.group = cls.env["res.groups"].create({"name": "test group"})
cls.folder.group_ids = cls.group
cls.user = new_test_user(
cls.env, login="John", groups="documents.group_documents_user"
)
cls.admin = new_test_user(
cls.env, login="John's manager", groups="documents.group_documents_manager,base.group_system"
)
cls.spreadsheet = cls.env["documents.document"].create(
{
"spreadsheet_data": b"{}",
"folder_id": cls.folder.id,
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
}
)
cls.spreadsheet.join_spreadsheet_session()
def test_create_user(self):
with self.assertRaises(AccessError):
self.env["spreadsheet.revision"].with_user(self.user).create(
{
"commands": self.new_revision_data(self.spreadsheet),
"document_id": self.spreadsheet.id,
"revision_id": "a revision id",
}
)
def test_create_user_with_doc_access(self):
self.user.groups_id |= self.group
self.spreadsheet.with_user(self.user).write(
{}
) # the user can write the document
with self.assertRaises(AccessError):
self.env["spreadsheet.revision"].with_user(self.user).create(
{
"commands": self.new_revision_data(self.spreadsheet),
"res_id": self.spreadsheet.id,
"res_model": "documents.document",
"revision_id": "a revision id",
}
)
def test_create_manager(self):
revision = (
self.env["spreadsheet.revision"]
.with_user(self.admin)
.create(
{
"commands": self.new_revision_data(self.spreadsheet),
"res_id": self.spreadsheet.id,
"res_model": "documents.document",
"revision_id": "a revision id",
"parent_revision_id": uuid4().hex,
}
)
)
self.assertTrue(revision)
def test_read_user(self):
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).spreadsheet_revision_ids.read()
with self.assertRaises(AccessError):
self.env["spreadsheet.revision"].with_user(self.user).search([])
def test_read_user_with_doc_access(self):
self.user.groups_id |= self.group
self.spreadsheet.with_user(self.user).read() # the user can read the document
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).spreadsheet_revision_ids.read()
with self.assertRaises(AccessError):
self.env["spreadsheet.revision"].with_user(self.user).search([])
def test_read_manager(self):
self.spreadsheet.dispatch_spreadsheet_message(
self.new_revision_data(self.spreadsheet)
)
self.env.invalidate_all()
revision = self.env["spreadsheet.revision"].with_user(self.admin).search([])
self.assertTrue(revision)
self.assertTrue(revision.read())
def test_write_user(self):
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).spreadsheet_revision_ids.write({})
def test_write_user_with_doc_access(self):
self.user.groups_id |= self.group
self.env.invalidate_all()
self.spreadsheet.with_user(self.user).write(
{"name": "new name"}
) # the user can write the document
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).spreadsheet_revision_ids.write({})
def test_write_manager(self):
self.spreadsheet.dispatch_spreadsheet_message(
self.new_revision_data(self.spreadsheet)
)
self.env.invalidate_all()
self.spreadsheet.with_user(self.admin).spreadsheet_revision_ids.write(
{"commands": "coucou"}
)
self.assertEqual(self.spreadsheet.spreadsheet_revision_ids.commands, "coucou")
def test_unlink_user(self):
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).spreadsheet_revision_ids.unlink()
def test_unlink_user_with_doc_access(self):
self.user.groups_id |= self.group
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).spreadsheet_revision_ids.unlink()
def test_unlink_manager(self):
self.spreadsheet.dispatch_spreadsheet_message(
self.new_revision_data(self.spreadsheet)
)
self.assertTrue(self.spreadsheet.spreadsheet_revision_ids)
self.env.invalidate_all()
self.spreadsheet.with_user(self.admin).spreadsheet_revision_ids.unlink()
self.assertFalse(self.spreadsheet.spreadsheet_revision_ids)
def test_join_user(self):
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).join_spreadsheet_session()
def test_join_user_with_doc_access(self):
self.user.groups_id |= self.group
self.env.invalidate_all()
self.spreadsheet.with_user(self.user).join_spreadsheet_session()
def test_join_user_with_read_doc_access(self):
self.user.groups_id |= self.group
self.folder.group_ids = False
self.folder.read_group_ids = self.group
self.env.invalidate_all()
self.spreadsheet.with_user(self.user).join_spreadsheet_session()
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).dispatch_spreadsheet_message(
self.new_revision_data(self.spreadsheet)
)
def test_join_new_spreadsheet_user(self):
# only read access
self.user.groups_id |= self.group
self.folder.group_ids = False
self.folder.read_group_ids = self.group
spreadsheet = self.env["documents.document"].create(
{
"spreadsheet_data": b"{}",
"folder_id": self.folder.id,
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
}
)
# no one ever joined this spreadsheet
result = spreadsheet.with_user(self.user).join_spreadsheet_session()
self.assertEqual(result["data"], {})
def test_join_snapshot_request(self):
with freeze_time("2020-02-02 18:00"):
self.spreadsheet.dispatch_spreadsheet_message(
self.new_revision_data(self.spreadsheet)
)
self.user.groups_id |= self.group
self.folder.group_ids = False
self.folder.read_group_ids = self.group
with freeze_time("2020-02-03 18:00"):
self.assertFalse(
self.spreadsheet.with_user(self.user).join_spreadsheet_session().get("snapshot_requested"),
"It should not have requested a snapshot",
)
self.folder.group_ids = self.group # grant write access
self.assertTrue(
self.spreadsheet.with_user(self.user).join_spreadsheet_session().get("snapshot_requested"),
"It should have requested a snapshot",
)
def test_snapshot_user(self):
with self.assertRaises(AccessError):
self.snapshot(
self.spreadsheet.with_user(self.user),
self.spreadsheet.server_revision_id, "snapshot-id", {"revisionId": "snapshot-id"},
)
def test_snapshot_user_with_doc_access(self):
self.user.groups_id |= self.group
self.spreadsheet.dispatch_spreadsheet_message(
# add at least one revision
self.new_revision_data(self.spreadsheet)
)
self.env.invalidate_all()
self.snapshot(
self.spreadsheet.with_user(self.user),
self.spreadsheet.server_revision_id, "snapshot-id", {"revisionId": "snapshot-id"},
)
self.assertEqual(len(self.spreadsheet.spreadsheet_revision_ids), 0)
def test_snapshot_user_with_read_doc_access(self):
self.user.groups_id |= self.group
self.folder.group_ids = False
self.folder.read_group_ids = self.group
self.spreadsheet.server_revision_id
self.env.invalidate_all()
with self.assertRaises(AccessError):
self.snapshot(
self.spreadsheet.with_user(self.user),
self.spreadsheet.server_revision_id, "snapshot-id", "{}"
)
def test_dispatch_user(self):
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).dispatch_spreadsheet_message(
self.new_revision_data(self.spreadsheet)
)
def test_dispatch_user_with_doc_access(self):
self.user.groups_id |= self.group
commands = self.new_revision_data(self.spreadsheet)
self.env.invalidate_all()
self.spreadsheet.with_user(self.user).dispatch_spreadsheet_message(commands)
self.assertEqual(
json.loads(self.spreadsheet.spreadsheet_revision_ids.commands),
{"commands": commands["commands"], "id": self.spreadsheet.id, "type": commands["type"]},
)
def test_dispatch_user_with_read_doc_access(self):
self.user.groups_id |= self.group
self.folder.group_ids = False
self.folder.read_group_ids = self.group
commands = self.new_revision_data(self.spreadsheet)
with self.assertRaises(AccessError):
self.spreadsheet.with_user(self.user).dispatch_spreadsheet_message(
commands
)
def test_dispatch_user_with_read_doc_access_move(self):
self.user.groups_id |= self.group
self.folder.group_ids = False
self.folder.read_group_ids = self.group
self.env.invalidate_all()
self.spreadsheet.with_user(self.user).dispatch_spreadsheet_message(
{"type": "CLIENT_MOVED"}
)