Files

521 lines
29 KiB
Python

from datetime import timedelta
from dateutil.relativedelta import relativedelta
from odoo import Command, fields
from odoo.addons.documents.tests.test_documents_common import TransactionCaseDocuments
from odoo.addons.mail.tests.common import MockEmail
from odoo.tests import Form, freeze_time, users
from odoo.tools import mute_logger
class TestDocumentsSharingCommon(TransactionCaseDocuments):
@staticmethod
def form_get_access_edit(form, partner):
"""Get a sub-form of the form to edit the share_access_id of the given partner."""
access_idx = next(idx for idx, a in enumerate(form.share_access_ids._records) if a['partner_id'] == partner.id)
return form.share_access_ids.edit(access_idx)
def create_documents_sharing(self, documents):
return self.env['documents.sharing'].browse(
[self.env['documents.sharing'].action_open(documents.ids)['res_id']])
def assert_open_wizard(self, action, documents):
"""Assert the action will open the wizard with the given documents and return the wizard instance."""
res_id = action['res_id']
document0 = documents[0]
self.assertEqual(self.env['documents.sharing'].browse([res_id]).document_ids, documents)
self.assertEqual(
action,
{
'context': {
'dialog_size': 'medium',
},
'name': f'Share: {document0.name}' if len(documents) == 1 else f"Share: {len(documents)} files",
'res_id': res_id,
'res_model': 'documents.sharing',
'target': 'new',
'type': 'ir.actions.act_window',
'view_mode': 'form',
'views': [[False, 'form']],
})
return self.env['documents.sharing'].browse([action['res_id']])
class TestDocumentsSharing(TestDocumentsSharingCommon, MockEmail):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.manager_doc, cls.user_doc = cls.env['documents.document'].create([{
'name': 'Manager document',
'folder_id': cls.folder_a.id,
'owner_id': cls.document_manager.id,
'access_ids': False,
}, {
'name': 'User document',
'folder_id': cls.folder_a.id,
'owner_id': cls.doc_user.id,
'access_ids': False,
}])
cls.manager_doc_shortcut, cls.user_doc_shortcut = cls.env['documents.document'].create([{
'name': 'Manager document (shortcut)',
'shortcut_document_id': cls.manager_doc.id,
}, {
'name': 'User document (shortcut)',
'shortcut_document_id': cls.user_doc.id,
}])
cls.partner_without_user = cls.env['res.partner'].create({
'name': 'Dave',
'email': '[email protected]',
})
cls.portal_user.email = '[email protected]'
cls.portal_partner = cls.portal_user.partner_id
cls.internal_user.email = '[email protected]'
def set_documents_env_user_to_current(self):
"""Helper to ensure the env of the test documents are self.env.user (to work with @users decorator)."""
self.manager_doc = self.manager_doc.with_user(self.env.user)
self.user_doc = self.user_doc.with_user(self.env.user)
self.manager_doc_shortcut = self.manager_doc_shortcut.with_user(self.env.user)
self.user_doc_shortcut = self.user_doc_shortcut.with_user(self.env.user)
self.folder_a = self.folder_a.with_user(self.env.user)
self.folder_b = self.folder_b.with_user(self.env.user)
@freeze_time('2025-02-26 15:02:00')
def test_filtered_relevant_access(self):
"""Check filtered_relevant_access on document access."""
YESTERDAY = fields.Datetime.now() - timedelta(days=1)
TOMORROW = fields.Datetime.now() + timedelta(days=1)
user_doc2 = self.env['res.users'].create([{
'email': '[email protected]',
'group_ids': [Command.link(self.env.ref('documents.group_documents_user').id)],
'login': '[email protected]',
'name': 'Documents User 2',
}])
self.document_gif.action_update_access_rights(partners={
user_id.partner_id: (role, expiration_date)
for user_id, role, expiration_date in (
(self.doc_user, 'edit', False), # should be ignored as doc_user is the owner
(user_doc2, 'edit', TOMORROW),
(self.document_manager, 'edit', False),
(self.internal_user, 'view', YESTERDAY), # should be ignored as expired
)
}, access_via_link='view')
# Simulate access as a portal user by writing an access log
self.env['documents.access'].sudo().create([{
'document_id': self.document_gif.id,
'partner_id': self.portal_user.partner_id.id,
'last_access_date': fields.Datetime.now(),
}])
self.assertEqual(len(self.document_gif.access_ids), 5)
self.assertEqual(self.document_gif.owner_id, self.doc_user)
self.assertEqual(
set(self.env['documents.sharing']._filtered_relevant_access(self.document_gif).mapped(
lambda a: (a.partner_id, a.role, a.expiration_date))),
{(user_doc2.partner_id, 'edit', TOMORROW), (self.document_manager.partner_id, 'edit', False)},
"filtered_relevant_access must filter out access logs, owner and expired access."
)
@users("[email protected]")
def test_init_multi_owners(self):
"""Test that the owner isn't shown when all the doc doesn't have the same owner (but well in the accesses)."""
self.set_documents_env_user_to_current()
user_doc_copy = self.user_doc.copy(default={'owner_id': False})
self.assertEqual(self.user_doc.owner_id, self.doc_user)
self.assertFalse(user_doc_copy.owner_id)
owner_and_no_owner_docs = self.user_doc | user_doc_copy
with Form(self.create_documents_sharing(owner_and_no_owner_docs)) as form:
self.assertFalse(form.owner_id)
self.assertEqual(
[(r['partner_id'], r['role']) for r in form.share_access_ids._records],
[(self.doc_user.partner_id.id, 'mixed')],
)
user_doc_copy.sudo().owner_id = self.doc_user
mono_owner_docs = self.user_doc | user_doc_copy
with Form(self.create_documents_sharing(mono_owner_docs)) as form:
self.assertEqual(form.owner_id, self.user_doc.owner_id)
self.assertFalse([(r['partner_id'], r['role']) for r in form.share_access_ids._records])
multi_owner_docs = self.manager_doc | self.user_doc
with Form(self.create_documents_sharing(multi_owner_docs)) as form:
self.assertFalse(form.owner_id)
self.assertEqual(
{(r['partner_id'], r['role']) for r in form.share_access_ids._records},
{(self.doc_user.partner_id.id, 'mixed'), (self.document_manager.partner_id.id, 'mixed')},
)
def test_init_with_log_and_owner(self):
"""Test that owner and logs are not shown as document access members."""
doc = self.manager_doc
self.assertEqual(doc.access_ids.partner_id, self.document_manager.partner_id)
self.env['documents.access'].create({
'document_id': doc.id,
'last_access_date': fields.Datetime.now(),
'partner_id': self.internal_user.partner_id.id,
'role': False,
})
doc.owner_id = False
self.assertEqual(len(doc.access_ids), 2)
with Form(self.create_documents_sharing(doc)) as form:
self.assertEqual(len(form.share_access_ids._records), 1)
self.assertEqual(form.share_access_ids._records[0]['partner_id'], self.document_manager.partner_id.id,
"Non-owner should be shown")
doc.owner_id = self.document_manager
self.assertEqual(len(doc.access_ids), 2)
with Form(self.create_documents_sharing(doc)) as form:
self.assertFalse(form.share_access_ids._records, "Owner, and logs shouldn't be shown")
@users("[email protected]")
def test_invite_members(self):
"""Test invitation."""
DocumentsSharing = self.env['documents.sharing']
self.set_documents_env_user_to_current()
doc = self.user_doc
doc.access_internal = 'edit'
doc.access_via_link = 'view'
doc1, doc2, doc3, doc4, doc5 = [
self.user_doc.copy(default={'name': f'doc{i + 1}'}) for i in range(5)]
for sender, documents, recipients, role, notify, notify_message in (
(self.document_manager, doc1, self.partner_without_user, 'view', True, 'Notify message'),
(self.doc_user, doc2 | doc3, self.portal_partner, 'edit', False, False),
(self.doc_user, doc4, self.internal_user.partner_id, 'view', True, False),
(self.doc_user, doc5, (self.document_manager | self.internal_user).partner_id, 'edit', True, False),
):
with self.with_user(sender.login), self.subTest(
sender=sender.email, documents=documents.mapped('name'), recipients=recipients.mapped('email')):
self.assertTrue(all(r.email for r in recipients))
self.assertFalse(DocumentsSharing._filtered_relevant_access(documents))
action = self.env['documents.sharing'].action_open(documents.ids)
doc_sharing = self.assert_open_wizard(action, documents)
with Form(doc_sharing) as form:
form.invite_partner_ids = recipients
self.assertTrue(form.invite_notify, "Notify is enabled by default")
self.assertEqual(form.invite_role, 'view', "Role is view by default")
form.invite_role = role
form.invite_notify = notify
if notify:
form.invite_notify_message = notify_message
with self.mock_mail_gateway():
action = doc_sharing.action_invite_members()
self.assertEqual(action['params']['type'], 'success')
self.assert_open_wizard(action['params']['next'], documents)
self.assertEqual(DocumentsSharing._filtered_relevant_access(documents).partner_id, recipients)
self.assertEqual(set(DocumentsSharing._filtered_relevant_access(documents).mapped('role')), {role})
if notify:
for recipient in recipients:
if notify_message:
self.assertMailMail(recipient, "outgoing", content=notify_message, author=sender.partner_id)
for document in documents:
self.assertMailMail(recipient, "outgoing", content=document.name, author=sender.partner_id)
else:
self.assertNoMail(recipient, author=sender.partner_id)
@users("[email protected]")
def test_invite_missing_email_notification_warning(self):
"""Test partner email missing notification warning."""
self.set_documents_env_user_to_current()
self.partner_without_user.email = False
doc_sharing = self.create_documents_sharing(self.user_doc)
with Form(doc_sharing) as form:
form.invite_partner_ids = self.partner_without_user
action = doc_sharing.action_invite_members()
self.assertEqual(action['params']['type'], 'warning')
self.assertEqual(action['params']['title'], 'Some emails are missing')
self.assertFalse(action.get('next'), 'The wizard remains open.')
@users("[email protected]")
def test_invite_no_partner_notification_warning(self):
"""Test no partner notification warning."""
self.set_documents_env_user_to_current()
self.partner_without_user.email = False
action = self.create_documents_sharing(self.user_doc).action_invite_members()
self.assertEqual(action['params']['type'], 'warning')
self.assertEqual(action['params']['title'], 'No partners')
self.assertFalse(action.get('next'), 'The wizard remains open.')
@mute_logger('odoo.addons.base.models.ir_rule')
@users("[email protected]")
def test_invite_reset_expiration_date(self):
"""Re-inviting a member reset its expiration date."""
self.set_documents_env_user_to_current()
doc = self.user_doc
expired = fields.Datetime.now() - timedelta(days=1)
doc.action_update_access_rights(partners={self.portal_partner: ('view', expired),
self.internal_user.partner_id: ('edit', False)})
self._assert_raises_check_access_rule(doc.with_user(self.portal_user), 'read')
doc_sharing = self.create_documents_sharing(doc)
with Form(doc_sharing) as form:
form.invite_partner_ids = self.portal_partner
form.invite_role = 'view'
form.invite_notify = False
self.assertEqual(doc_sharing.share_access_ids.partner_id, self.internal_user.partner_id,
"Expired member is hidden from People with access.")
self.assertEqual(doc_sharing.action_invite_members()['params']['type'], 'success')
doc_sharing = self.create_documents_sharing(doc)
self.assertIn(self.portal_partner, doc_sharing.share_access_ids.partner_id,
"Re-invited member reappears under People with access.")
self.assertFalse(
doc_sharing.share_access_ids.filtered(lambda ds: ds.partner_id == self.portal_partner).expiration_date,
"Expiration date has been reset.")
self.assertEqual(doc.with_user(self.portal_user).user_permission, 'view',
"Re-invited member has access to the document again.")
@users("[email protected]")
def test_invite_warning_partners_without_access(self):
"""Test the warning about sharing documents to external partners without access (without user)."""
self.set_documents_env_user_to_current()
(self.user_doc | self.manager_doc).sudo().access_internal = 'edit'
for documents in (self.user_doc, self.user_doc.copy() | self.manager_doc):
with self.subTest(documents=documents.mapped('name')):
action = self.env['documents.sharing'].action_open(documents.ids)
doc_sharing = self.assert_open_wizard(action, documents)
with Form(doc_sharing) as form:
self.assertFalse(form.has_warning_partners_without_access)
form.invite_partner_ids = self.partner_without_user | self.internal_user.partner_id
action = doc_sharing.action_invite_members()
self.assertTrue(action)
self.assertTrue({'type': 'ir.actions.client', 'tag': 'display_notification'}.items() <= action.items())
self.assertTrue(
{'type': 'success', 'title': 'Successfully Shared'}.items() <= action.get('params', {}).items())
self.assert_open_wizard(action.get('params', {}).get('next'), documents)
with Form(self.create_documents_sharing(documents)) as form:
self.assertTrue(form.has_warning_partners_without_access)
with (self.form_get_access_edit(form, self.internal_user.partner_id) as access_internal_form,
self.form_get_access_edit(form, self.partner_without_user) as access_part_without_user_form):
self.assertFalse(access_internal_form.has_warning_no_access)
self.assertTrue(access_part_without_user_form.has_warning_no_access)
form.save()
form.record.action_allow_link_access()
with Form(self.create_documents_sharing(documents)) as form:
self.assertFalse(form.has_warning_partners_without_access)
with (self.form_get_access_edit(form, self.internal_user.partner_id) as access_internal_form,
self.form_get_access_edit(form, self.partner_without_user) as access_part_without_user_form):
self.assertFalse(access_internal_form.has_warning_no_access)
self.assertFalse(access_part_without_user_form.has_warning_no_access)
def test_open_wizard_with_shortcuts(self):
"""Test that open sharing wizard on shortcuts open the wizard on the target of the shortcut."""
DocumentSharing = self.env['documents.sharing']
self.assert_open_wizard(DocumentSharing.action_open(self.user_doc_shortcut.ids), self.user_doc)
self.assert_open_wizard(
DocumentSharing.action_open((self.user_doc_shortcut | self.manager_doc_shortcut).ids),
self.user_doc | self.manager_doc)
self.assert_open_wizard(
DocumentSharing.action_open((self.user_doc | self.manager_doc_shortcut).ids),
self.user_doc | self.manager_doc)
@users("[email protected]")
def test_readonly(self):
"""Test that the form is read-only when the user doesn't have edit access to all the selected documents"""
self.set_documents_env_user_to_current()
self.assertTrue(self.create_documents_sharing(self.manager_doc).is_readonly)
self.assertFalse(self.create_documents_sharing(self.user_doc).is_readonly)
self.assertTrue(self.create_documents_sharing(self.manager_doc | self.user_doc).is_readonly)
self.manager_doc.sudo().action_update_access_rights(partners={self.doc_user.partner_id: ('edit', False)})
self.assertFalse(self.create_documents_sharing(self.manager_doc | self.user_doc).is_readonly)
def check_update_access_right(self, doc_main, doc_other=None, doc_child=None, must_propagate=False):
"""Check update rights using the wizard.
:param doc_main: The main document or folder on which the update is performed.
:param doc_other: The other document or folder on which the update is performed.
:param doc_child: Child of doc_main if defined. In that case doc_main must be a folder.
:param must_propagate: whether to check if the update performed on doc_main is propagated to doc_child.
"""
doc_child = doc_child if doc_child else self.env['documents.document']
doc_main = doc_main if doc_main else self.env['documents.document']
doc_other = doc_other if doc_other else self.env['documents.document']
self.assertTrue(not doc_child or (doc_main.type == 'folder' and doc_child.folder_id == doc_main))
portal_user_2 = self.portal_user.copy()
portal_partner, portal_partner_2 = self.portal_partner, portal_user_2.partner_id
documents = doc_main | doc_other
all_docs = documents | doc_child
all_docs.owner_id = self.doc_user
all_docs.action_update_access_rights(partners={self.doc_user.partner_id: (False, False)})
all_docs.access_internal = 'none'
all_docs.access_via_link = 'none'
all_docs.is_access_via_link_hidden = True
is_single_doc = len(documents) == 1
docs_to_check = documents if not must_propagate else documents | doc_child
doc_main.action_update_access_rights(
partners={portal_partner: ('view', None), portal_partner_2: ('view', None)}, no_propagation=True)
# Check update a member right
action = self.env['documents.sharing'].action_open(documents.ids)
doc_sharing = self.assert_open_wizard(action, documents)
form = Form(doc_sharing)
# Check initialization
self.assertFalse(doc_sharing.is_access_modified)
self.assertEqual(form.owner_id, self.doc_user)
self.assertEqual({a['role'] for a in form.share_access_ids._records},
{'view' if is_single_doc else 'mixed'})
self.assertEqual(form.access_internal, 'none')
self.assertEqual(form.access_via_link, 'none')
self.assertEqual(form.access_via_link_mode, 'link_required')
# Update and check modification
with self.form_get_access_edit(form, portal_partner) as access_edit_form:
access_edit_form.role = 'write_edit'
self.assertTrue(form.is_access_modified)
form.save()
self.assertEqual(doc_sharing._get_update_rights_params(),
{'partners': {portal_partner: ('edit', False if is_single_doc else None)}})
action = doc_sharing.action_update_rights()
self.assert_open_wizard(action, documents)
self.assertTrue(
all(d.access_ids.filtered(lambda a: a.partner_id == portal_partner).role == 'edit' for d in docs_to_check))
self.assertFalse(
(doc_other | doc_child).access_ids.filtered(lambda a: a.partner_id == portal_partner_2 and a.role))
# Check change multiple values and remove a member
doc_other.access_via_link = 'view'
doc_other.is_access_via_link_hidden = False
doc_sharing = self.create_documents_sharing(documents)
form = Form(doc_sharing)
# Check initialization
self.assertFalse(form.is_access_modified)
self.assertEqual(
{s['partner_id']: s['role'] for s in form.share_access_ids._records},
{portal_partner.id: 'edit', portal_partner_2.id: 'view' if is_single_doc else 'mixed'})
self.assertEqual(form.access_internal, 'none')
self.assertEqual(form.access_via_link, 'none' if is_single_doc else 'mixed')
self.assertEqual(form.access_via_link_mode, 'link_required' if is_single_doc else 'mixed')
# Update and check modification
# Expiration is only supported with single document selection
expiration_date = fields.Datetime.now() + relativedelta(days=1, hour=11) if is_single_doc else False
with self.form_get_access_edit(form, portal_partner_2) as access_edit_form:
access_edit_form.role = 'write_edit'
access_edit_form.expiration_date = expiration_date
with self.form_get_access_edit(form, portal_partner) as access_edit_form:
access_edit_form.is_deleted = True
form.access_internal = 'write_edit'
form.access_via_link = 'write_view'
form.access_via_link_mode = 'write_discoverable'
self.assertTrue(form.is_access_modified)
form.save()
self.assertEqual(
doc_sharing._get_update_rights_params(),
{'partners': {
portal_partner_2: ('edit', expiration_date if is_single_doc else None),
portal_partner: (False, False),
}, 'access_internal': 'edit', 'access_via_link': 'view', 'is_access_via_link_hidden': False})
action = doc_sharing.action_update_rights()
self.assert_open_wizard(action, documents)
self.assertEqual(set(docs_to_check.mapped('access_internal')), {'edit'})
self.assertEqual({(a.partner_id, a.role, a.expiration_date) for a in docs_to_check.access_ids.filtered('role')},
{(portal_partner_2, 'edit', expiration_date if is_single_doc else False)})
self.assertEqual(set(docs_to_check.mapped('access_via_link')), {'view'})
# No propagation for is_access_via_link_hidden
self.assertEqual(set(documents.mapped('is_access_via_link_hidden')), {False})
if doc_child:
self.assertEqual(set(doc_child.mapped('is_access_via_link_hidden')), {True})
@users("dtdm")
def test_update_access_rights_expiration_date(self):
"""Test that expiration are unaltered when updating rights on multiple documents."""
self.set_documents_env_user_to_current()
expiration_date = fields.Datetime.now() + relativedelta(days=1, hour=11)
self.manager_doc.action_update_access_rights(partners={self.portal_partner: ('view', expiration_date)})
doc_sharing = self.create_documents_sharing(self.user_doc | self.manager_doc)
with (Form(doc_sharing) as form,
self.form_get_access_edit(form, self.portal_partner) as portal_access_form):
self.assertFalse(portal_access_form.expiration_date, 'Expiration not supported with multiple documents')
self.assertEqual(portal_access_form.role, 'mixed')
portal_access_form.role = 'write_view'
self.assertEqual(doc_sharing._get_update_rights_params(),
{'partners': {self.portal_partner: ('view', None)}})
doc_sharing.action_update_rights()
portal_access_manager_doc = self.manager_doc.access_ids.filtered(lambda a: a.partner_id == self.portal_partner)
self.assertEqual(portal_access_manager_doc.expiration_date, expiration_date,
'Expiration must remain untouched')
self.assertEqual(portal_access_manager_doc.role, 'view')
portal_access_user_doc = self.user_doc.access_ids.filtered(lambda a: a.partner_id == self.portal_partner)
self.assertFalse(portal_access_user_doc.expiration_date)
self.assertEqual(portal_access_user_doc.role, 'view')
@users("dtdm")
def test_update_access_rights_of_owners(self):
"""Test modifying member access of partner that owns some of the selected documents."""
DocumentsSharing = self.env['documents.sharing']
self.set_documents_env_user_to_current()
self.assertFalse(self.user_doc.access_ids.filtered('role'))
self.assertFalse(self.manager_doc.access_ids.filtered('role'))
doc_sharing = self.create_documents_sharing(self.user_doc | self.manager_doc)
with (Form(doc_sharing) as form):
self.assertFalse(form.owner_id)
self.assertEqual(self.form_get_access_edit(form, self.doc_user.partner_id).role, 'mixed')
self.assertEqual(self.form_get_access_edit(form, self.document_manager.partner_id).role, 'mixed')
with self.form_get_access_edit(form, self.doc_user.partner_id) as access_edit_form:
access_edit_form.role = 'write_edit'
doc_sharing.action_update_rights()
self.assertEqual(
{a.partner_id: a.role for a in DocumentsSharing._filtered_relevant_access(self.manager_doc)},
{self.doc_user.partner_id: 'edit'})
doc_sharing = self.create_documents_sharing(self.user_doc | self.manager_doc)
with Form(doc_sharing) as form:
self.assertFalse(form.owner_id)
self.assertEqual(self.form_get_access_edit(form, self.doc_user.partner_id).role, 'edit')
self.assertEqual(self.form_get_access_edit(form, self.document_manager.partner_id).role, 'mixed')
with self.form_get_access_edit(form, self.doc_user.partner_id) as access_edit_form:
access_edit_form.is_deleted = True
doc_sharing.action_update_rights()
self.assertFalse(DocumentsSharing._filtered_relevant_access(self.manager_doc))
@users("[email protected]")
def test_update_access_rights_multi_mixed(self):
"""Test access rights edition on a documents and a folder."""
self.set_documents_env_user_to_current()
self.check_update_access_right(self.folder_b, self.user_doc, doc_child=self.document_gif, must_propagate=False)
@users("[email protected]")
def test_update_access_rights_multi_folders(self):
"""Test access rights edition on multiple folders."""
self.set_documents_env_user_to_current()
self.check_update_access_right(self.folder_b, self.folder_a, doc_child=self.document_gif, must_propagate=True)
@users("[email protected]")
def test_update_access_rights_multi_documents(self):
"""Test access rights edition on multiple documents."""
self.set_documents_env_user_to_current()
self.check_update_access_right(self.user_doc, self.user_doc.copy())
@users("[email protected]")
def test_update_access_rights_single_document(self):
"""Test access rights edition on a single document."""
self.set_documents_env_user_to_current()
self.check_update_access_right(self.user_doc)
@users("[email protected]")
def test_update_access_rights_single_folder(self):
"""Test access rights edition on a single folder."""
self.set_documents_env_user_to_current()
self.check_update_access_right(self.folder_b, doc_child=self.document_gif, must_propagate=True)
@users("[email protected]")
def test_update_access_rights_warning_link_with_more_rights(self):
"""Test the warning about gaining indirectly "edit" permission through access_via_link being "edit"."""
self.set_documents_env_user_to_current()
for documents in (self.user_doc, self.user_doc.copy() | self.user_doc.copy()):
documents.action_update_access_rights(partners={self.portal_partner: ('view', False)})
with self.subTest(documents=documents):
documents.access_internal = 'edit'
documents.access_via_link = 'edit'
action = self.env['documents.sharing'].action_open(documents.ids)
doc_sharing = self.assert_open_wizard(action, documents)
with Form(doc_sharing) as form:
# portal user gains indirectly "edit" access as access_via_link = "edit"
self.assertTrue(form.has_warning_link_with_more_rights)
with self.form_get_access_edit(form, self.portal_partner) as access_edit_form:
access_edit_form.is_deleted = True
self.assertFalse(form.has_warning_link_with_more_rights)
# internal users gain indirectly "edit" access as access_via_link = "edit"
form.access_internal = 'view'
self.assertTrue(form.has_warning_link_with_more_rights)