Files
enterprise/sign/tests/test_sign_controllers.py
2024-04-28 11:43:49 +08:00

161 lines
8.4 KiB
Python

# -*- coding: utf-8 -*-
# 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.tests.common import HttpCase
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
class TestSignControllerCommon(SignRequestCommon, HttpCase):
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.env.ref('base.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, 403)
self.assertTrue('This link has expired' 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)