Files

972 lines
42 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
import base64
from .common import SpreadsheetTestCommon, TEST_CONTENT, GIF
from odoo.exceptions import AccessError
from odoo.tests import Form
from odoo.tests.common import RecordCapturer, new_test_user
from odoo.tools import mute_logger
class SpreadsheetDocuments(SpreadsheetTestCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.folder = cls.env["documents.document"].create({
"name": "Test folder",
"type": "folder",
"access_internal": "edit",
})
def test_action_open_new_spreadsheet(self):
action = self.env["documents.document"].action_open_new_spreadsheet()
action_open = action
spreadsheet_id = action_open["params"]["spreadsheet_id"]
document = self.env["documents.document"].browse(spreadsheet_id)
self.assertTrue(document.exists())
self.assertEqual(document.handler, "spreadsheet")
self.assertEqual(document.mimetype, "application/o-spreadsheet")
self.assertEqual(document.name, "Untitled spreadsheet")
self.assertEqual(document.datas, document._empty_spreadsheet_data_base64())
self.assertEqual(action_open["type"], "ir.actions.client")
self.assertEqual(action_open["tag"], "action_open_spreadsheet")
def test_action_open_new_spreadsheet_with_locale(self):
self.env["res.lang"].create(
{
"code": "en_FR",
"name": "Custom Locale",
"thousands_sep": " ",
"decimal_point": ",",
"date_format": "%d-%m-%Y",
"time_format": "%H:%M:%S",
"active": True,
"week_start": "1",
}
)
user = self.env['res.users'].create({
"name": "Custom user",
"login": "custom_user",
"lang": "en_FR"
})
action = self.env["documents.document"].with_user(user).action_open_new_spreadsheet()
spreadsheet_id = action["params"]["spreadsheet_id"]
document = self.env["documents.document"].browse(spreadsheet_id)
self.assertTrue(document.exists())
expected_locale = {
"code": "en_FR",
"name": "Custom Locale",
"thousandsSeparator": " ",
"decimalSeparator": ",",
"dateFormat": "dd-mm-yyyy",
"timeFormat": "hh:mm:ss",
"formulaArgSeparator": ";",
"weekStart": 1,
}
self.assertEqual(json.loads(document.spreadsheet_data)["settings"]["locale"], expected_locale)
def test_action_open_new_spreadsheet_in_folder(self):
action = self.env["documents.document"].action_open_new_spreadsheet({
"folder_id": self.folder.id
})
spreadsheet_id = action["params"]["spreadsheet_id"]
document = self.env["documents.document"].browse(spreadsheet_id)
self.assertEqual(document.folder_id, self.folder)
def test_action_update_access_rights(self):
folder = self.env['documents.document'].create({'name': 'Folder', 'type': 'folder'})
frozen_folder, document = self.env['documents.document'].create([
{'name': 'Frozen Folder', 'type': 'folder', 'handler': 'frozen_folder', 'folder_id': folder.id},
{'name': 'Document', 'folder_id': folder.id},
])
frozen_spreadsheet = self.env['documents.document'].create({'name': 'Spreadsheet', 'handler': 'frozen_spreadsheet'})
partner = self.env['res.partner'].create({'name': 'Partner'})
# The update does not propagate on the frozen folders / spreadsheets
folder.action_update_access_rights(access_internal='edit', partners={partner: ('edit', None)})
self.assertEqual(folder.access_internal, 'edit')
self.assertEqual(folder.access_ids.role, 'edit')
self.assertEqual(document.access_internal, 'edit')
self.assertEqual(document.access_ids.role, 'edit')
self.assertEqual(frozen_folder.access_internal, 'none')
self.assertFalse(frozen_folder.access_ids.role)
self.assertEqual(frozen_spreadsheet.access_internal, 'none')
self.assertFalse(frozen_spreadsheet.access_ids.role)
folder.action_update_access_rights(access_internal='view', partners={partner: ('view', None)})
self.assertEqual(folder.access_internal, 'view')
self.assertEqual(folder.access_ids.role, 'view')
self.assertEqual(document.access_internal, 'view')
self.assertEqual(document.access_ids.role, 'view')
self.assertEqual(frozen_folder.access_internal, 'none')
self.assertFalse(frozen_folder.access_ids.role)
self.assertEqual(frozen_spreadsheet.access_internal, 'none')
self.assertFalse(frozen_spreadsheet.access_ids.role)
frozen_folder.action_update_access_rights(access_internal='view', partners={partner: ('view', None)})
self.assertEqual(frozen_folder.access_internal, 'view')
self.assertEqual(frozen_folder.access_ids.role, 'view')
self.assertEqual(frozen_spreadsheet.access_internal, 'none')
self.assertFalse(frozen_spreadsheet.access_ids.role)
frozen_spreadsheet.action_update_access_rights(access_internal='view', partners={partner: ('view', None)})
self.assertEqual(frozen_spreadsheet.access_internal, 'view')
self.assertEqual(frozen_spreadsheet.access_ids.role, 'view')
def test_action_create_shortcut(self):
self.archive_existing_spreadsheet()
document = self.create_spreadsheet()
shortcut = document.action_create_shortcut()
self.assertEqual(shortcut.handler, "spreadsheet")
def archive_existing_spreadsheet(self):
"""Existing spreadsheet in the database can influence some test results"""
self.env["documents.document"].search([("handler", "=", "spreadsheet")]).active = False
def test_spreadsheet_my_drive_folder(self):
user1 = new_test_user(self.env, login="Alice", groups="base.group_user")
document = self.env["documents.document"].with_user(user1).create({
"spreadsheet_data": "{}",
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
})
self.assertFalse(document.folder_id, "The spreadsheet is created in My Drive")
# And only user1 have access to it
self.assertEqual(document.owner_id, user1)
self.assertEqual(document.access_internal, 'none')
self.assertEqual(document.access_via_link, 'none')
self.assertFalse(document.access_ids.filtered(lambda a: a.partner_id != user1.partner_id))
def test_spreadsheet_no_default_folder(self):
"""Folder is not overwritten by the default spreadsheet folder"""
document = self.env["documents.document"].create({
"spreadsheet_data": "{}",
"folder_id": self.folder.id,
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
})
self.assertEqual(document.folder_id, self.folder, "It should be in the specified folder")
def test_access_rights_inherited_on_create_spreadsheet(self):
user = new_test_user(
self.env, login='Jean', groups='documents.group_documents_user',
)
document_1 = self.env['documents.document'].create({
'spreadsheet_data': '{}',
'handler': 'spreadsheet',
'mimetype': 'application/o-spreadsheet',
})
document_2 = self.env['documents.document'].create({
'spreadsheet_data': '{}',
'handler': 'spreadsheet',
'folder_id': False,
'mimetype': 'application/o-spreadsheet',
})
self.folder.write({
'access_via_link': 'none',
'access_internal': 'view',
})
self.folder.action_update_access_rights(partners={user.partner_id.id: ('view', False)})
document_3 = self.env['documents.document'].create({
'spreadsheet_data': '{}',
'handler': 'spreadsheet',
'folder_id': self.folder.id,
'mimetype': 'application/o-spreadsheet',
})
# inherit access from parent folder (My Drive)
self.assertFalse(document_1.folder_id, False)
self.assertEqual(document_1.access_internal, 'none')
self.assertEqual(document_1.access_via_link, 'none')
# inherit access from parent folder (My Drive)
self.assertEqual(document_2.access_internal, 'none')
self.assertEqual(document_2.access_via_link, 'none')
# inherit access from parent folder (Test folder)
self.assertEqual(document_3.access_internal, 'view')
self.assertEqual(document_3.access_via_link, 'none')
self.assertEqual(document_3.access_ids.partner_id, user.partner_id)
def test_spreadsheet_to_display_with_domain(self):
self.archive_existing_spreadsheet()
with self._freeze_time("2020-02-03"):
spreadsheet1 = self.create_spreadsheet(name="My Spreadsheet")
with self._freeze_time("2020-02-02"):
spreadsheet2 = self.create_spreadsheet(name="Untitled Spreadsheet")
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([("name", "ilike", "My")])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet1.id])
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([("name", "ilike", "Untitled")])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet2.id])
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([("name", "ilike", "Spreadsheet")])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet1.id, spreadsheet2.id])
def test_spreadsheet_to_display_with_offset_limit(self):
self.archive_existing_spreadsheet()
user = new_test_user(self.env, login="Jean", groups="base.group_user")
with self._freeze_time("2020-02-02"):
spreadsheet1 = self.create_spreadsheet(user=user, name="My Spreadsheet 1")
with self._freeze_time("2020-02-03"):
spreadsheet2 = self.create_spreadsheet(user=user, name="My Spreadsheet 2")
with self._freeze_time("2020-02-04"):
spreadsheet3 = self.create_spreadsheet(name="My Spreadsheet 3")
with self._freeze_time("2020-02-05"):
spreadsheet4 = self.create_spreadsheet(user=user, name="SP 4")
with self._freeze_time("2020-02-06"):
spreadsheet5 = self.create_spreadsheet(name="SP 5")
with self._freeze_time("2020-02-07"):
spreadsheet6 = self.create_spreadsheet(name="SP 6")
#########
# ADMIN #
#########
# Only the last opened spreadsheet.
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([], offset=0, limit=1)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet6.id])
# Two last opened spreadsheets.
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([], offset=0, limit=2)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet6.id, spreadsheet5.id])
# Ordered first by last opened, and then by id.
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([], offset=2, limit=2)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet3.id, spreadsheet4.id])
# Ordered first by last opened, and then by id without limit.
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([], offset=2)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet3.id, spreadsheet4.id, spreadsheet2.id, spreadsheet1.id])
# Ordered first by last opened, and then by id without limit with a domain.
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([("name", "ilike", "My Spreadsheet")])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet3.id, spreadsheet2.id, spreadsheet1.id])
# Ordered first by last opened, and then by id without limit with a domain.
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([("name", "ilike", "SP ")])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet6.id, spreadsheet5.id, spreadsheet4.id])
########
# JEAN #
########
# Only the last opened spreadsheet.
spreadsheets = self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([], offset=0, limit=1)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet4.id])
# Two last opened spreadsheets.
spreadsheets = self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([], offset=0, limit=2)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet4.id, spreadsheet2.id])
# Ordered first by last opened, and then by id.
spreadsheets = self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([], offset=2, limit=2)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet1.id, spreadsheet6.id])
# Ordered first by last opened, and then by id without limit.
spreadsheets = self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([], offset=2)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet1.id, spreadsheet6.id, spreadsheet5.id, spreadsheet3.id])
# Ordered first by last opened, and then by id without limit with a domain.
spreadsheets = self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([("name", "ilike", "My Spreadsheet")])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet2.id, spreadsheet1.id, spreadsheet3.id])
# Ordered first by last opened, and then by id without limit with a domain.
spreadsheets = self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([("name", "ilike", "SP ")])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet4.id, spreadsheet6.id, spreadsheet5.id])
def test_spreadsheet_to_display(self):
self.archive_existing_spreadsheet()
document = self.create_spreadsheet()
archived_document = self.env["documents.document"].create(
{
"spreadsheet_data": r"{}",
"folder_id": self.folder.id,
"active": False,
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
}
)
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertTrue(
document.id in spreadsheet_ids, "It should contain the new document"
)
self.assertFalse(
archived_document.id in spreadsheet_ids,
"It should not contain the archived document",
)
def test_spreadsheet_to_display_create_order(self):
self.archive_existing_spreadsheet()
with self._freeze_time("2020-02-02 18:00"):
spreadsheet1 = self.create_spreadsheet()
with self._freeze_time("2020-02-15 18:00"):
spreadsheet2 = self.create_spreadsheet()
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet2.id, spreadsheet1.id])
def test_spreadsheet_to_display_write_order(self):
self.archive_existing_spreadsheet()
with self._freeze_time("2020-02-02 18:00"):
spreadsheet1 = self.create_spreadsheet()
with self._freeze_time("2020-02-15 18:00"):
spreadsheet2 = self.create_spreadsheet()
spreadsheet1.spreadsheet_data = r"{}"
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet1.id, spreadsheet2.id])
def test_spreadsheet_to_display_join_session(self):
self.archive_existing_spreadsheet()
with self._freeze_time("2020-02-02 18:00"):
spreadsheet1 = self.create_spreadsheet()
with self._freeze_time("2020-02-15 18:00"):
spreadsheet2 = self.create_spreadsheet()
spreadsheet1._get_serialized_spreadsheet_data_body()
spreadsheets = self.env["documents.document"]._get_spreadsheets_to_display([])
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet1.id, spreadsheet2.id])
def test_spreadsheet_to_display_without_contrib(self):
self.archive_existing_spreadsheet()
user = new_test_user(
self.env, login="Jean", groups="documents.group_documents_user"
)
with self._freeze_time("2020-02-02 18:00"):
spreadsheet1 = self.create_spreadsheet(user=user)
with self._freeze_time("2020-02-15 18:00"):
spreadsheet2 = self.create_spreadsheet()
spreadsheets = (
self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([])
)
spreadsheet_ids = [s["id"] for s in spreadsheets]
self.assertEqual(spreadsheet_ids, [spreadsheet1.id, spreadsheet2.id])
def test_spreadsheet_to_display_access_portal(self):
portal = new_test_user(self.env, "Test user", groups="base.group_portal")
with self.assertRaises(
AccessError, msg="A portal user should not be able to read spreadsheet"
):
self.env["documents.document"].with_user(
portal
)._get_spreadsheets_to_display([])
def test_spreadsheet_to_display_access_ir_rule(self):
user = new_test_user(
self.env, "Test user", groups="documents.group_documents_manager"
)
model = self.env.ref("documents.model_documents_document")
group = self.env.ref("documents.group_documents_manager")
manager_doc = self.create_spreadsheet(user=user)
visible_doc = self.create_spreadsheet(user=user)
# archive existing record rules which might allow access (disjunction between record rules)
record_rules = self.env["ir.rule"].search(
[
("model_id", "=", model.id),
]
)
record_rules.active = False
self.env["ir.rule"].create(
{
"name": "test record rule",
"model_id": model.id,
"groups": [(4, group.id)],
"domain_force": f"[('id', '=', {visible_doc.id})]", # always rejects
}
)
spreadsheets = (
self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([])
)
self.assertEqual(
[s["id"] for s in spreadsheets], [visible_doc.id], "filtering issue"
)
with self.assertRaises(AccessError, msg="record rule should have raised"):
manager_doc.with_user(user).spreadsheet_data = "{}"
def test_spreadsheet_to_display_access_field_groups(self):
existing_groups = self.env["documents.document"]._fields["display_name"].groups
self.env["documents.document"]._fields["display_name"].groups = "base.group_system"
user = new_test_user(
self.env, "Test user", groups="documents.group_documents_manager"
)
with self.assertRaises(AccessError, msg="field should be protected"):
self.env["documents.document"].with_user(user)._get_spreadsheets_to_display([])
self.env["documents.document"]._fields["display_name"].groups = existing_groups
def test_save_template(self):
context = {
"default_spreadshee_name": "Spreadsheet test",
"default_template_name": "Spreadsheet test - Template",
"default_spreadsheet_data": TEST_CONTENT,
"default_thumbnail": GIF,
}
wizard = Form(
self.env["save.spreadsheet.template"].with_context(context)
).save()
wizard.save_template()
template = self.env["spreadsheet.template"].search(
[["name", "=", "Spreadsheet test - Template"]]
)
self.assertTrue(template, "It should have created a template")
self.assertEqual(template.name, "Spreadsheet test - Template")
self.assertEqual(template.spreadsheet_data, TEST_CONTENT)
self.assertEqual(template.thumbnail, GIF)
def test_save_template_purges_comments(self):
base_data = {
"sheets": [{
"comments": [
{"A1": {"threadId": 1, "isResolved": False}}
]
}],
}
context = {
"default_spreadshee_name": "Spreadsheet test",
"default_template_name": "Spreadsheet test - Template",
"default_spreadsheet_data": json.dumps(base_data),
"default_thumbnail": GIF,
}
wizard = Form(
self.env["save.spreadsheet.template"].with_context(context)
).save()
wizard.save_template()
template = self.env["spreadsheet.template"].search(
[["name", "=", "Spreadsheet test - Template"]]
)
template_data = json.loads(template.spreadsheet_data)
self.assertEqual(template_data["sheets"][0]["comments"], {})
def test_user_right_own_template(self):
user = new_test_user(
self.env, "Test user", groups="documents.group_documents_user"
)
template = (
self.env["spreadsheet.template"]
.with_user(user)
.create(
{
"name": "hello",
"spreadsheet_data": TEST_CONTENT,
}
)
)
template.write(
{
"name": "bye",
}
)
template.unlink()
def test_user_right_not_own_template(self):
manager = new_test_user(
self.env, "Test manager", groups="documents.group_documents_manager"
)
user = new_test_user(
self.env, "Test user", groups="documents.group_documents_user"
)
template = (
self.env["spreadsheet.template"]
.with_user(manager)
.create(
{
"name": "hello",
"spreadsheet_data": TEST_CONTENT,
}
)
)
with self.assertRaises(
AccessError, msg="cannot write on template of your friend"
):
template.with_user(user).write(
{
"name": "bye",
}
)
with self.assertRaises(
AccessError, msg="cannot delete template of your friend"
):
template.with_user(user).unlink()
template.name = "bye"
template.unlink()
def test_contributor_write_spreadsheet_data(self):
document = self.create_spreadsheet()
document.access_internal = "edit"
user = new_test_user(
self.env, "Test Manager", groups="documents.group_documents_manager"
)
document.with_user(user).write({"spreadsheet_data": r"{}"})
contributor = self.env["spreadsheet.contributor"].search(
[("user_id", "=", user.id), ("document_id", "=", document.id)]
)
self.assertEqual(len(contributor), 1, "The contribution should be registered")
def test_contributor_move_folder(self):
document = self.create_spreadsheet()
new_folder = self.env["documents.document"].create({
"name": "New folder",
"type": "folder",
"folder_id": self.folder.id,
"access_internal": "edit",
})
user = new_test_user(
self.env, "Test Manager", groups="documents.group_documents_manager"
)
document.access_internal = "edit"
document.with_user(user).write({"folder_id": new_folder.id})
contributor = self.env["spreadsheet.contributor"].search(
[("user_id", "=", user.id), ("document_id", "=", document.id)]
)
self.assertEqual(
len(contributor), 0, "The contribution should not be registered"
)
def test_document_replacement_with_handler(self):
document = self.env["documents.document"].create({
"spreadsheet_data": r"{}",
"folder_id": self.folder.id,
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
})
vals = {
"name": "file",
"folder_id": self.folder.id,
"spreadsheet_data": r"{}",
"handler": "spreadsheet"
}
document.write(vals)
self.assertEqual(document.handler, "spreadsheet", "The handler must contain the value of the handler mentioned in vals")
def test_document_replacement_data_only(self):
document = self.env["documents.document"].create({
"name": "file",
"spreadsheet_data": r"{}",
"folder_id": self.folder.id,
"handler": "spreadsheet",
})
vals = {
"spreadsheet_data": r"{}",
}
document.write(vals)
self.assertEqual(document.handler, "spreadsheet", "The handler should not have changed")
def test_document_replacement_with_other_mimetype(self):
document = self.env["documents.document"].create({
"spreadsheet_data": r"{}",
"folder_id": self.folder.id,
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
})
vals = {
"name": "test.txt",
"datas": b'aGVsbG8hCg==\n',
"folder_id": self.folder.id,
"mimetype": "text/plain",
}
document.write(vals)
self.assertEqual(document.handler, False, "The handler should have been reset")
def test_document_replacement_with_spreadsheet_mimetype(self):
document = self.env["documents.document"].create({
"raw": b'some text',
"folder_id": self.folder.id,
"mimetype": "text/plain",
})
vals = {
"spreadsheet_data": r"{}",
"mimetype": "application/o-spreadsheet",
}
document.write(vals)
self.assertEqual(document.handler, False, "the file should not be recognized as a spreadsheet")
def test_document_replacement_with_handler_and_other_mimetype(self):
document = self.env["documents.document"].create({
"spreadsheet_data": r"{}",
"folder_id": self.folder.id,
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
})
vals = {
"name": "spreadsheet_file",
"folder_id": self.folder.id,
"spreadsheet_data": r"{}",
"mimetype": "application/json",
"handler": "spreadsheet"
}
document.write(vals)
self.assertEqual(document.handler, "spreadsheet", "the handler must contain the value of the handler mentioned in vals")
def test_create_document_with_spreadsheet_mimetype(self):
document = self.env["documents.document"].create({
"spreadsheet_data": r"{}",
"folder_id": self.folder.id,
"mimetype": "application/o-spreadsheet",
})
self.assertEqual(document.handler, False, "the file should not be recognized as a spreadsheet")
def test_read_spreadsheet_data(self):
document = self.env["documents.document"].create({
"name": "test.txt",
"datas": base64.encodebytes(b'{ "sheets": [] }'),
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
"folder_id": self.folder.id,
})
self.assertEqual(document.spreadsheet_data, '{ "sheets": [] }')
def test_read_spreadsheet_data_bin_size_ctx(self):
document = self.env["documents.document"].with_context(bin_size=True).create({
"name": "test.txt",
"datas": base64.encodebytes(b"{}"),
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
"folder_id": self.folder.id,
})
self.assertEqual(document.spreadsheet_data, "{}")
def test_read_non_spreadsheet_data(self):
document = self.env["documents.document"].create({
"name": "test.txt",
"datas": TEST_CONTENT,
"mimetype": "text/plain",
"folder_id": self.folder.id,
})
self.assertEqual(document.spreadsheet_data, False)
def test_write_spreadsheet_data(self):
document = self.env["documents.document"].create({
"name": "test.txt",
"datas": base64.encodebytes(b"{}"),
"handler": "spreadsheet",
"mimetype": "application/o-spreadsheet",
"folder_id": self.folder.id,
})
data = b'{ "sheets": [] }'
document.spreadsheet_data = data
self.assertEqual(document.datas, base64.b64encode(data))
@mute_logger('odoo.addons.documents.models.documents_document')
def test_copy_documents_spreadsheet(self):
spreadsheet = self.create_spreadsheet(name="My Spreadsheet")
spreadsheet.flush_recordset()
with RecordCapturer(self.env['ir.attachment'], []) as capture:
copy = spreadsheet.copy()
self.assertEqual(len(capture.records), 1)
self.assertNotEqual(spreadsheet.attachment_id, copy.attachment_id)
def test_copy_spreadsheet_revisions(self):
spreadsheet = self.create_spreadsheet()
user = new_test_user(self.env, login="Jean", groups="base.group_user")
spreadsheet.dispatch_spreadsheet_message(self.new_revision_data(spreadsheet))
#########
# ADMIN #
#########
with mute_logger('odoo.addons.documents.models.documents_document'): # Creating document(s) as superuser
copy_admin = spreadsheet.copy()
self.assertEqual(
len(copy_admin.spreadsheet_revision_ids),
1,
"The revision should be copied with admin access right",
)
#############
# NON-ADMIN #
#############
spreadsheet.invalidate_recordset()
copy_non_admin = spreadsheet.with_user(user).copy()
self.assertEqual(
len(copy_non_admin.sudo().spreadsheet_revision_ids),
1,
"The revision should be copied with non-admin access right",
)
def test_copy_spreadsheet_snapshot(self):
spreadsheet = self.create_spreadsheet()
spreadsheet.dispatch_spreadsheet_message(self.new_revision_data(spreadsheet))
self.snapshot(
spreadsheet,
spreadsheet.current_revision_uuid, "snapshot-revision-id", {"sheets": [], "revisionId": "snapshot-revision-id"},
)
with mute_logger('odoo.addons.documents.models.documents_document'):
copy = spreadsheet.copy()
self.assertEqual(
copy.spreadsheet_snapshot,
spreadsheet.spreadsheet_snapshot,
"Copy should have the same snapshot data",
)
def test_copy_sheet_name(self):
spreadsheet = self.create_spreadsheet({"name": "spreadsheet"})
with mute_logger('odoo.addons.documents.models.documents_document'): # Creating document(s) as superuser
copy = spreadsheet.copy()
self.assertEqual(copy.name, 'spreadsheet (copy)')
def test_copy_default_sheet_name(self):
spreadsheet = self.create_spreadsheet({"name": "spreadsheet"})
with mute_logger('odoo.addons.documents.models.documents_document'): # Creating document(s) as superuser
copy = spreadsheet.copy({'name': 'sheet'})
self.assertEqual(copy.name, 'sheet')
def test_copy_image_in_snapshot(self):
spreadsheet = self.create_spreadsheet()
image = self.env["ir.attachment"].create({
"name": "image.png",
"datas": b"test",
"res_model": "documents.document",
"res_id": spreadsheet.id,
})
spreadsheet_data = {
"revisionId": "NEW_REVISION",
"sheets": [{
"figures": [
{
"id": "14",
"x": 0,
"y": 0,
"width": 10,
"height": 10,
"tag": "image",
"data": {
"path": f"/web/image/{image.id}",
"size": {"width": 10, "height": 10},
"mimetype": "image/png"
}
},
{
"id": "14",
"x": 0,
"y": 0,
"width": 10,
"height": 10,
"tag": "image",
"data": {
"path": f"/web/image/{image.id}?access_token={image.generate_access_token()[0]}",
"size": {"width": 10, "height": 10},
"mimetype": "image/png"
}
}
],
}],
}
spreadsheet.spreadsheet_data = json.dumps(spreadsheet_data)
self.snapshot(spreadsheet, "START_REVISION", "NEW_REVISION", spreadsheet_data)
with mute_logger('odoo.addons.documents.models.documents_document'):
copy = spreadsheet.copy({
"spreadsheet_data": spreadsheet.spreadsheet_data,
"spreadsheet_snapshot": spreadsheet.spreadsheet_snapshot,
})
copied_data = json.loads(copy.spreadsheet_data)
copied_snapshot = json.loads(copy._get_spreadsheet_serialized_snapshot())
for data_copy in (copied_data, copied_snapshot):
[figure, figure_with_token] = data_copy["sheets"][0]["figures"]
image_definition = figure["data"]
path = image_definition["path"]
attachment_copy_id = int(path.split("/")[3])
attachment_copy = self.env["ir.attachment"].browse(attachment_copy_id)
self.assertNotEqual(attachment_copy_id, image.id)
self.assertEqual(attachment_copy.res_id, copy.id)
self.assertEqual(attachment_copy.res_model, "documents.document")
self.assertEqual(image_definition["path"], f"/web/image/{attachment_copy_id}")
image_definition = figure_with_token["data"]
path = image_definition["path"]
attachment_copy_id = int(path.split("/")[3].split("?")[0])
attachment_copy = self.env["ir.attachment"].browse(attachment_copy_id)
self.assertEqual(
image_definition["path"],
f"/web/image/{attachment_copy_id}?access_token={attachment_copy.access_token}"
)
def test_copy_image_in_revision(self):
spreadsheet = self.create_spreadsheet()
image = self.env["ir.attachment"].create({
"name": "image.png",
"datas": b"test",
"res_model": "documents.document",
"res_id": spreadsheet.id,
})
commands = [{
"type": "CREATE_IMAGE",
"figureId": "image-id",
"col": 0,
"row": 0,
"offset": {"x": 0, "y": 0},
"size": {"width": 1, "height": 1},
"definition": {
"path": "/web/image/%s" % image.id,
}
}, {
"type": "CREATE_IMAGE",
"figureId": "image-id2",
"col": 0,
"row": 0,
"offset": {"x": 0, "y": 0},
"size": {"width": 1, "height": 1},
"definition": {
"path": "/web/image/%s?access_token=%s" % (image.id, image.generate_access_token()[0]),
}
}]
spreadsheet.dispatch_spreadsheet_message(self.new_revision_data(spreadsheet, commands=commands))
with mute_logger('odoo.addons.documents.models.documents_document'): # Creating document(s) as superuser
copy = spreadsheet.copy()
revision = copy.spreadsheet_revision_ids
[command, command_with_token] = json.loads(revision.commands)["commands"]
path = command["definition"]["path"]
attachment_copy_id = int(path.split("/")[3])
attachment_copy = self.env["ir.attachment"].browse(attachment_copy_id)
self.assertNotEqual(attachment_copy_id, image.id)
self.assertEqual(attachment_copy.res_id, copy.id)
self.assertEqual(attachment_copy.res_model, "documents.document")
self.assertEqual(command["definition"]["path"], f"/web/image/{attachment_copy_id}")
path = command_with_token["definition"]["path"]
attachment_copy_id = int(path.split("/")[3].split("?")[0])
attachment_copy = self.env["ir.attachment"].browse(attachment_copy_id)
self.assertEqual(
command_with_token["definition"]["path"],
f"/web/image/{attachment_copy_id}?access_token={attachment_copy.access_token}"
)
def test_create_spreadsheet_with_image_linked_to_other_record(self):
image = self.env["ir.attachment"].create({
"name": "image.png",
"datas": b"test",
"res_model": self.env.user._name,
"res_id": self.env.user.id,
})
spreadsheet_data = {
"sheets": [{
"figures": [
{
"id": "14",
"x": 0,
"y": 0,
"width": 10,
"height": 10,
"tag": "image",
"data": {
"path": f"/web/image/{image.id}",
"size": {"width": 10, "height": 10},
"mimetype": "image/png"
}
}
],
}],
}
spreadsheet = self.create_spreadsheet({
"spreadsheet_data": json.dumps(spreadsheet_data)
})
with mute_logger('odoo.addons.documents.models.documents_document'): # Creating document(s) as superuser
copy = spreadsheet.copy({
"spreadsheet_data": spreadsheet.spreadsheet_data,
"spreadsheet_snapshot": spreadsheet.spreadsheet_snapshot,
})
image_definition = json.loads(copy.spreadsheet_data)["sheets"][0]["figures"][0]["data"]
path = image_definition["path"]
attachment_copy_id = int(path.split("/")[3])
attachment_copy = self.env["ir.attachment"].browse(attachment_copy_id)
self.assertNotEqual(attachment_copy_id, image.id)
self.assertEqual(attachment_copy.res_id, copy.id)
self.assertEqual(attachment_copy.res_model, "documents.document")
self.assertEqual(image_definition["path"], f"/web/image/{attachment_copy_id}")
def test_delete_spreadsheet_delete_image(self):
spreadsheet = self.create_spreadsheet()
image = self.env["ir.attachment"].create({
"name": "image.png",
"datas": b"test",
"res_model": "documents.document",
"res_id": spreadsheet.id,
})
self.assertTrue(image)
spreadsheet.unlink()
self.assertFalse(image.exists())
def test_spreadsheet_thumbnail_checksum(self):
spreadsheet = self.create_spreadsheet()
self.assertFalse(spreadsheet.spreadsheet_thumbnail_checksum)
spreadsheet.display_thumbnail = GIF
thumbnail_attachment = self.env["ir.attachment"].search([
("res_model", "=", "documents.document"),
("res_field", "=", "thumbnail"),
("res_id", "=", spreadsheet.id),
])
self.assertTrue(
spreadsheet.spreadsheet_thumbnail_checksum,
thumbnail_attachment.checksum
)
def test_spreadsheet_thumbnail_checksum_other_document(self):
document = self.env["documents.document"].create({
"datas": GIF,
"thumbnail": GIF,
"folder_id": self.folder.id,
})
self.assertFalse(document.spreadsheet_thumbnail_checksum)
def test_get_only_spreadsheet_documents(self):
self.env["documents.document"].search([("handler", "=", "spreadsheet")]).unlink()
# a spreadsheet
spreadsheet = self.create_spreadsheet()
# a regular document
self.env["documents.document"].create({
"datas": GIF,
"thumbnail": GIF,
"folder_id": self.folder.id,
})
# a frozen spreadsheet
frozen_spreadsheet = self.create_spreadsheet()
frozen_spreadsheet.access_internal = "view"
frozen_spreadsheet.handler = "frozen_spreadsheet"
result = self.env["documents.document"].get_spreadsheets()
self.assertEqual(result, {
"records": [{
"id": spreadsheet.id,
"display_name": spreadsheet.name,
"display_thumbnail": False
}],
"total": 1,
})
def test_spreadsheet_prevent_portal_owner(self):
portal = new_test_user(self.env, "Test user", groups="base.group_portal")
spreadsheet = self.create_spreadsheet()
with self.assertRaises(
AccessError, msg="Portal users cannot be the owner of a spreadsheet."
):
spreadsheet.owner_id = portal