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

198 lines
11 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
import json
from unittest.mock import patch
from freezegun import freeze_time
from .sign_request_common import SignRequestCommon
from odoo.addons.base.tests.common import HttpCaseWithUserDemo
from odoo.addons.sign.controllers.main import Sign
from odoo.exceptions import AccessError, ValidationError
from odoo.addons.website.tools import MockRequest
from odoo.tests import tagged
from odoo.tools import formataddr
class TestSignControllerCommon(SignRequestCommon, HttpCaseWithUserDemo):
def setUp(self):
super().setUp()
self.SignController = Sign()
def _json_url_open(self, url, data, **kwargs):
data = {
"id": 0,
"jsonrpc": "2.0",
"method": "call",
"params": data,
}
headers = {
"Content-Type": "application/json",
**kwargs.get('headers', {})
}
return self.url_open(url, data=json.dumps(data).encode(), headers=headers)
@tagged('post_install', '-at_install')
class TestSignController(TestSignControllerCommon):
# test float auto_field display
def test_sign_controller_float(self):
sign_request = self.create_sign_request_no_item(signer=self.partner_1, cc_partners=self.partner_4)
text_type = self.env['sign.item.type'].search([('name', '=', 'Text')])
# the partner_latitude expects 7 zeros of decimal precision
text_type.auto_field = 'partner_latitude'
token_a = self.env["sign.request.item"].search([('sign_request_id', '=', sign_request.id)]).access_token
with MockRequest(sign_request.env):
values = self.SignController.get_document_qweb_context(sign_request.id, token=token_a)
sign_type = list(filter(lambda sign_type: sign_type["name"] == "Text", values["sign_item_types"]))[0]
latitude = sign_type["auto_value"]
self.assertEqual(latitude, 0)
# test auto_field with wrong partner field
def test_sign_controller_dummy_fields(self):
text_type = self.env['sign.item.type'].search([('name', '=', 'Text')])
# we set a dummy field that raises an error
with self.assertRaises(ValidationError):
text_type.auto_field = 'this_is_not_a_partner_field'
# we set a field the demo user does not have access and must not be able to set as auto_field
self.patch(type(self.env['res.partner']).function, 'groups', 'base.group_system')
with self.assertRaises(AccessError):
text_type.with_user(self.user_demo).auto_field = 'function'
# test auto_field with multiple sub steps
def test_sign_controller_multi_step_auto_field(self):
self.partner_1.company_id = self.env.ref('base.main_company')
self.partner_1.company_id.country_id = self.env.ref('base.be').id
sign_request = self.create_sign_request_no_item(signer=self.partner_1, cc_partners=self.partner_4)
text_type = self.env['sign.item.type'].search([('name', '=', 'Text')])
text_type.auto_field = 'company_id.country_id.name'
token_a = self.env["sign.request.item"].search([('sign_request_id', '=', sign_request.id)]).access_token
with MockRequest(sign_request.env):
values = self.SignController.get_document_qweb_context(sign_request.id, token=token_a)
sign_type = list(filter(lambda sign_type: sign_type["name"] == "Text", values["sign_item_types"]))[0]
country = sign_type["auto_value"]
self.assertEqual(country, "Belgium")
def test_sign_request_requires_auth_when_credits_are_available(self):
sign_request = self.create_sign_request_1_role_sms_auth(self.partner_1, self.env['res.partner'])
sign_request_item = sign_request.request_item_ids[0]
self.assertFalse(sign_request_item.signed_without_extra_auth)
self.assertEqual(sign_request_item.role_id.auth_method, 'sms')
sign_vals = self.create_sign_values(sign_request.template_id.sign_item_ids, sign_request_item.role_id.id)
with patch('odoo.addons.iap.models.iap_account.IapAccount.get_credits', lambda self, x: 10):
response = self._json_url_open(
'/sign/sign/%d/%s' % (sign_request.id, sign_request_item.access_token),
data={'signature': sign_vals}
).json()['result']
self.assertFalse(response.get('success'))
self.assertTrue(sign_request_item.state, 'sent')
self.assertFalse(sign_request_item.signed_without_extra_auth)
def test_sign_request_allows_no_auth_when_credits_are_not_available(self):
sign_request = self.create_sign_request_1_role_sms_auth(self.partner_1, self.env['res.partner'])
sign_request_item = sign_request.request_item_ids[0]
self.assertFalse(sign_request_item.signed_without_extra_auth)
self.assertEqual(sign_request_item.role_id.auth_method, 'sms')
sign_vals = self.create_sign_values(sign_request.template_id.sign_item_ids, sign_request_item.role_id.id)
with patch('odoo.addons.iap.models.iap_account.IapAccount.get_credits', lambda self, x: 0):
response = self._json_url_open(
'/sign/sign/%d/%s' % (sign_request.id, sign_request_item.access_token),
data={'signature': sign_vals}
).json()['result']
self.assertTrue(response.get('success'))
self.assertTrue(sign_request_item.state, 'completed')
self.assertTrue(sign_request.state, 'done')
self.assertTrue(sign_request_item.signed_without_extra_auth)
def test_sign_from_mail_no_expiry_params(self):
sign_request = self.create_sign_request_1_role(self.partner_1, self.env['res.partner'])
url = '/sign/document/mail/%s/%s' % (sign_request.id, sign_request.request_item_ids[0].access_token)
response = self.url_open(url)
self.assertEqual(response.status_code, 404)
self.assertTrue('The signature request might have been deleted or modified.' in response.text)
def test_sign_from_mail_link_not_expired(self):
with freeze_time('2020-01-01'):
sign_request = self.create_sign_request_1_role(self.partner_1, self.env['res.partner'])
sign_request_item_id = sign_request.request_item_ids[0]
timestamp = sign_request_item_id._generate_expiry_link_timestamp()
expiry_hash = sign_request_item_id._generate_expiry_signature(sign_request_item_id.id, timestamp)
url = '/sign/document/mail/%(sign_request_id)s/%(access_token)s?timestamp=%(timestamp)s&exp=%(exp)s' % {
'sign_request_id': sign_request.id,
'access_token': sign_request.request_item_ids[0].access_token,
'timestamp': timestamp,
'exp': expiry_hash
}
response = self.url_open(url)
self.assertEqual(response.status_code, 200)
self.assertTrue('/sign/document/%s/%s' % (sign_request.id, sign_request_item_id.access_token) in response.url)
def test_sign_from_mail_with_expired_link(self):
with freeze_time('2020-01-01'):
sign_request = self.create_sign_request_1_role(self.partner_1, self.env['res.partner'])
sign_request_item_id = sign_request.request_item_ids[0]
timestamp = sign_request_item_id._generate_expiry_link_timestamp()
expiry_hash = sign_request_item_id._generate_expiry_signature(sign_request_item_id.id, timestamp)
with freeze_time('2020-01-04'):
url = '/sign/document/mail/%(sign_request_id)s/%(access_token)s?timestamp=%(timestamp)s&exp=%(exp)s' % {
'sign_request_id': sign_request.id,
'access_token': sign_request.request_item_ids[0].access_token,
'timestamp': timestamp,
'exp': expiry_hash
}
response = self.url_open(url)
self.assertEqual(response.status_code, 403)
self.assertTrue('This link has expired' in response.text)
def test_shared_sign_request_without_expiry_params(self):
sign_request = self.create_sign_request_1_role(self.partner_1, self.env['res.partner'])
sign_request.state = 'shared'
sign_request_item_id = sign_request.request_item_ids[0]
url = '/sign/document/mail/%s/%s' % (sign_request.id, sign_request_item_id.access_token)
response = self.url_open(url)
self.assertEqual(response.status_code, 200)
self.assertTrue('/sign/document/%s/%s' % (sign_request.id, sign_request_item_id.access_token) in response.url)
def test_sign_from_resend_expired_link(self):
with freeze_time('2020-01-01'):
sign_request = self.create_sign_request_1_role(self.partner_1, self.env['res.partner'])
sign_request_item_id = sign_request.request_item_ids[0]
timestamp = sign_request_item_id._generate_expiry_link_timestamp()
expiry_hash = sign_request_item_id._generate_expiry_signature(sign_request_item_id.id, timestamp)
url = '/sign/document/mail/%(sign_request_id)s/%(access_token)s?timestamp=%(timestamp)s&exp=%(exp)s' % {
'sign_request_id': sign_request.id,
'access_token': sign_request.request_item_ids[0].access_token,
'timestamp': timestamp,
'exp': expiry_hash
}
response = self.url_open(url)
self.assertEqual(response.status_code, 200)
self.assertTrue('/sign/document/%s/%s' % (sign_request.id, sign_request_item_id.access_token) in response.url)
sign_request_item = {sign_request_item.role_id: sign_request_item for sign_request_item in sign_request.request_item_ids}
sign_request_item_customer = sign_request_item[self.role_customer]
sign_request_item_customer.sudo()._edit_and_sign(self.single_role_customer_sign_values)
mail = self.env['mail.mail'].search([('email_to', '=', formataddr((self.partner_1.name, self.partner_1.email)))])
self.assertEqual(len(mail.ids), 2)
with freeze_time('2020-01-04'):
self.start_tour(url, 'sign_resend_expired_link_tour', login='demo')
def test_sign_request_ignore_from_mail(self):
"""Only GET requests should lead to a sign request being ignored."""
sign_request = self.create_sign_request_1_role(self.partner_1, self.env['res.partner'])
request_item = sign_request.request_item_ids[0]
url = '/sign/sign_ignore/%s/%s' % (request_item.id, request_item.access_token)
self.url_open(url, head=True)
self.assertEqual(request_item.ignored, False)
self.url_open(url)
self.assertEqual(request_item.ignored, True)