361 lines
15 KiB
Python
361 lines
15 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
import json
|
|
import base64
|
|
|
|
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.current_revision_uuid, "START_REVISION")
|
|
|
|
def test_compute_revision_with_session(self):
|
|
spreadsheet = self.create_spreadsheet()
|
|
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.current_revision_uuid, "nextone")
|
|
|
|
def test_dispatch_new_revision(self):
|
|
spreadsheet = self.create_spreadsheet()
|
|
commands = self.new_revision_data(spreadsheet)
|
|
spreadsheet.dispatch_spreadsheet_message(commands)
|
|
self.assertEqual(
|
|
len(spreadsheet.spreadsheet_revision_ids),
|
|
1,
|
|
"It should have recorded one revision",
|
|
)
|
|
self.assertEqual(
|
|
spreadsheet.current_revision_uuid,
|
|
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()
|
|
start_revision = spreadsheet.current_revision_uuid
|
|
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.current_revision_uuid,
|
|
revision1["nextRevisionId"],
|
|
"The revision should not have been updated",
|
|
)
|
|
|
|
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.current_revision_uuid, "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.current_revision_uuid,
|
|
"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.current_revision_uuid, "snapshot-revision-id", {"sheets": [], "revisionId": "another-revision-id"},
|
|
)
|
|
|
|
|
|
def test_snapshot_spreadsheet_with_invalid_revision(self):
|
|
spreadsheet = self.create_spreadsheet()
|
|
first_revision = spreadsheet.current_revision_uuid
|
|
spreadsheet.dispatch_spreadsheet_message(self.new_revision_data(spreadsheet))
|
|
current_data = spreadsheet.spreadsheet_snapshot
|
|
current_revision = spreadsheet.current_revision_uuid
|
|
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.current_revision_uuid,
|
|
"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.current_revision_uuid, "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().setUpClass()
|
|
cls.folder.access_internal = 'none'
|
|
cls.user = new_test_user(cls.env, login="John", groups="base.group_user")
|
|
cls.admin = new_test_user(cls.env, login="John's manager", groups="base.group_system")
|
|
cls.spreadsheet = cls.env["documents.document"].create(
|
|
{
|
|
"spreadsheet_data": b"{}",
|
|
"folder_id": cls.folder.id,
|
|
"handler": "spreadsheet",
|
|
"mimetype": "application/o-spreadsheet",
|
|
"access_internal": "none",
|
|
}
|
|
)
|
|
cls.env['documents.access'].create({'document_id': cls.spreadsheet.id, 'partner_id': cls.admin.partner_id.id, 'role': 'edit'})
|
|
|
|
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_uuid": "a revision id",
|
|
}
|
|
)
|
|
|
|
def test_create_user_with_doc_access(self):
|
|
# the user can write the document
|
|
self._give_user_access('edit')
|
|
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_uuid": "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_uuid": "a revision id",
|
|
}
|
|
)
|
|
)
|
|
self.assertTrue(revision)
|
|
|
|
def _give_user_access(self, role='view'):
|
|
self.env['documents.access'].create({
|
|
'document_id': self.spreadsheet.id,
|
|
'partner_id': self.user.partner_id.id,
|
|
'role': role,
|
|
})
|
|
|
|
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):
|
|
with self.assertRaises(AccessError):
|
|
self.spreadsheet.with_user(self.user).read()
|
|
self._give_user_access()
|
|
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._give_user_access('edit')
|
|
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._give_user_access()
|
|
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_dispatch_user_with_read_doc_access(self):
|
|
self.spreadsheet.access_internal = 'view'
|
|
|
|
self.env.invalidate_all()
|
|
with self.assertRaises(AccessError):
|
|
self.spreadsheet.with_user(self.user).dispatch_spreadsheet_message(
|
|
self.new_revision_data(self.spreadsheet)
|
|
)
|
|
|
|
def test_snapshot_user(self):
|
|
with self.assertRaises(AccessError):
|
|
self.snapshot(
|
|
self.spreadsheet.with_user(self.user),
|
|
self.spreadsheet.current_revision_uuid, "snapshot-id", {"revisionId": "snapshot-id"},
|
|
)
|
|
|
|
def test_snapshot_user_with_doc_access(self):
|
|
self._give_user_access('edit')
|
|
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.current_revision_uuid, "snapshot-id", {"revisionId": "snapshot-id"},
|
|
)
|
|
self.assertEqual(len(self.spreadsheet.spreadsheet_revision_ids), 0)
|
|
|
|
def test_snapshot_user_with_read_doc_access(self):
|
|
self._give_user_access()
|
|
self.spreadsheet.current_revision_uuid
|
|
self.env.invalidate_all()
|
|
with self.assertRaises(AccessError):
|
|
self.snapshot(
|
|
self.spreadsheet.with_user(self.user),
|
|
self.spreadsheet.current_revision_uuid, "snapshot-id", "{}"
|
|
)
|
|
def test_dispatch_portal_user_with_doc_access(self):
|
|
portal_user = new_test_user(self.env, login="Raoul", groups="base.group_portal")
|
|
|
|
self.env['documents.access'].create({
|
|
'document_id': self.spreadsheet.id,
|
|
'partner_id': portal_user.partner_id.id,
|
|
'role': 'view',
|
|
})
|
|
# can't write
|
|
with self.assertRaises(AccessError):
|
|
self.spreadsheet.with_user(portal_user).dispatch_spreadsheet_message(
|
|
self.new_revision_data(self.spreadsheet)
|
|
)
|
|
|
|
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._give_user_access('edit')
|
|
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_partner_read_doc_access(self):
|
|
self._give_user_access()
|
|
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_partner_read_doc_access_move(self):
|
|
self._give_user_access()
|
|
self.env.invalidate_all()
|
|
self.spreadsheet.with_user(self.user).dispatch_spreadsheet_message(
|
|
{"type": "CLIENT_MOVED"}
|
|
)
|