diff options
| -rw-r--r-- | addons/account/tests/test_portal_attachment.py | 265 |
1 files changed, 177 insertions, 88 deletions
diff --git a/addons/account/tests/test_portal_attachment.py b/addons/account/tests/test_portal_attachment.py index c36daf3086a..02ac0cf04a7 100644 --- a/addons/account/tests/test_portal_attachment.py +++ b/addons/account/tests/test_portal_attachment.py @@ -1,51 +1,66 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from odoo.addons.account.tests.common import AccountTestInvoicingHttpCommon +from odoo.tests.common import tagged import json -from odoo import http, tests +from odoo import http from odoo.tools import mute_logger -@tests.tagged('post_install', '-at_install') -class TestUi(tests.HttpCase): +@tagged('post_install', '-at_install') +class TestPortalAttachment(AccountTestInvoicingHttpCommon): - @mute_logger('odoo.addons.http_routing.models.ir_http', 'odoo.http') - def test_01_portal_attachment(self): - """Test the portal chatter attachment route.""" + @classmethod + def setUpClass(cls, chart_template_ref=None): + super().setUpClass(chart_template_ref=chart_template_ref) - partner = self.env['res.partner'].create({'name': 'Test partner'}) - - base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url') - # For this test we need a parent document with an access_token field - # (in this case from portal.mixin) and also inheriting mail.thread. - invoice = self.env['account.move'].with_context(tracking_disable=True).create({ + cls.out_invoice = cls.env['account.move'].with_context(tracking_disable=True).create({ 'move_type': 'out_invoice', - 'date': '2017-01-01', - 'invoice_date': '2017-01-01', - 'partner_id': partner.id, - 'invoice_line_ids': [(0, 0, {'name': 'aaaa', 'price_unit': 100.0})], + 'partner_id': cls.partner_a.id, + 'invoice_date': '2019-05-01', + 'date': '2019-05-01', + 'invoice_line_ids': [ + (0, 0, {'name': 'line1', 'price_unit': 100.0}), + ], }) + cls.base_url = cls.env['ir.config_parameter'].sudo().get_param('web.base.url') + + @mute_logger('odoo.addons.http_routing.models.ir_http', 'odoo.http') + def test_01_portal_attachment(self): + """Test the portal chatter attachment route.""" + # Test public user can't create attachment without token of document - create_data = { - 'name': "new attachment", - 'res_model': invoice._name, - 'res_id': invoice.id, - 'csrf_token': http.WebRequest.csrf_token(self), - } - create_url = base_url + '/portal/attachment/add' - files = [('file', ('test.txt', b'test', 'plain/text'))] - res = self.url_open(url=create_url, data=create_data, files=files) + res = self.url_open( + url='%s/portal/attachment/add' % self.base_url, + data={ + 'name': "new attachment", + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'csrf_token': http.WebRequest.csrf_token(self), + }, + files=[('file', ('test.txt', b'test', 'plain/text'))], + ) self.assertEqual(res.status_code, 400) self.assertIn("you do not have the rights", res.text) # Test public user can create attachment with token - create_data['access_token'] = invoice._portal_ensure_token() - res = self.url_open(url=create_url, data=create_data, files=files) + res = self.url_open( + url='%s/portal/attachment/add' % self.base_url, + data={ + 'name': "new attachment", + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'csrf_token': http.WebRequest.csrf_token(self), + 'access_token': self.out_invoice._portal_ensure_token(), + }, + files=[('file', ('test.txt', b'test', 'plain/text'))], + ) self.assertEqual(res.status_code, 200) create_res = json.loads(res.content.decode('utf-8')) - self.assertEqual(create_res['name'], "new attachment") + self.assertTrue(self.env['ir.attachment'].sudo().search([('id', '=', create_res['id'])])) # Test created attachment is private res_binary = self.url_open('/web/content/%d' % create_res['id']) @@ -56,8 +71,17 @@ class TestUi(tests.HttpCase): self.assertEqual(res_binary.status_code, 200) # Test mimetype is neutered as non-admin - files = [('file', ('test.svg', b'<svg></svg>', 'image/svg+xml'))] - res = self.url_open(url=create_url, data=create_data, files=files) + res = self.url_open( + url='%s/portal/attachment/add' % self.base_url, + data={ + 'name': "new attachment", + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'csrf_token': http.WebRequest.csrf_token(self), + 'access_token': self.out_invoice._portal_ensure_token(), + }, + files=[('file', ('test.svg', b'<svg></svg>', 'image/svg+xml'))], + ) self.assertEqual(res.status_code, 200) create_res = json.loads(res.content.decode('utf-8')) self.assertEqual(create_res['mimetype'], 'text/plain') @@ -71,36 +95,50 @@ class TestUi(tests.HttpCase): self.assertEqual(res_image.content, b'<svg></svg>') # Test attachment can't be removed without valid token - remove_data = { - 'attachment_id': create_res['id'], - 'access_token': 'wrong', - } - remove_url = base_url + '/portal/attachment/remove' - res = self.opener.post(url=remove_url, json={'params': remove_data}) + res = self.opener.post( + url='%s/portal/attachment/remove' % self.base_url, + json={ + 'params': { + 'attachment_id': create_res['id'], + 'access_token': "wrong", + }, + }, + ) self.assertEqual(res.status_code, 200) - self.assertTrue(self.env['ir.attachment'].search([('id', '=', create_res['id'])])) + self.assertTrue(self.env['ir.attachment'].sudo().search([('id', '=', create_res['id'])])) self.assertIn("you do not have the rights", res.text) # Test attachment can be removed with token if "pending" state - remove_data['access_token'] = create_res['access_token'] - res = self.opener.post(url=remove_url, json={'params': remove_data}) + res = self.opener.post( + url='%s/portal/attachment/remove' % self.base_url, + json={ + 'params': { + 'attachment_id': create_res['id'], + 'access_token': create_res['access_token'], + }, + }, + ) self.assertEqual(res.status_code, 200) remove_res = json.loads(res.content.decode('utf-8'))['result'] - self.assertFalse(self.env['ir.attachment'].search([('id', '=', create_res['id'])])) + self.assertFalse(self.env['ir.attachment'].sudo().search([('id', '=', create_res['id'])])) self.assertTrue(remove_res is True) # Test attachment can't be removed if not "pending" state attachment = self.env['ir.attachment'].create({ - 'name': "an attachment", + 'name': 'an attachment', 'access_token': self.env['ir.attachment']._generate_access_token(), }) - remove_data = { - 'attachment_id': attachment.id, - 'access_token': attachment.access_token, - } - res = self.opener.post(url=remove_url, json={'params': remove_data}) + res = self.opener.post( + url='%s/portal/attachment/remove' % self.base_url, + json={ + 'params': { + 'attachment_id': attachment.id, + 'access_token': attachment.access_token, + }, + }, + ) self.assertEqual(res.status_code, 200) - self.assertTrue(self.env['ir.attachment'].search([('id', '=', attachment.id)])) + self.assertTrue(self.env['ir.attachment'].sudo().search([('id', '=', attachment.id)])) self.assertIn("not in a pending state", res.text) # Test attachment can't be removed if attached to a message @@ -112,70 +150,121 @@ class TestUi(tests.HttpCase): message = self.env['mail.message'].create({ 'attachment_ids': [(6, 0, attachment.ids)], }) - remove_data = { - 'attachment_id': attachment.id, - 'access_token': attachment.access_token, - } - res = self.opener.post(url=remove_url, json={'params': remove_data}) + res = self.opener.post( + url='%s/portal/attachment/remove' % self.base_url, + json={ + 'params': { + 'attachment_id': attachment.id, + 'access_token': attachment.access_token, + }, + }, + ) self.assertEqual(res.status_code, 200) self.assertTrue(attachment.exists()) self.assertIn("it is linked to a message", res.text) - message.unlink() + message.sudo().unlink() # Test attachment can't be associated if no attachment token. - post_url = base_url + '/mail/chatter_post' - post_data = { - 'res_model': invoice._name, - 'res_id': invoice.id, - 'message': "test message 1", - 'attachment_ids': attachment.id, - 'attachment_tokens': 'false', - 'csrf_token': http.WebRequest.csrf_token(self), - } - res = self.url_open(url=post_url, data=post_data) + res = self.url_open( + url='%s/mail/chatter_post' % self.base_url, + data={ + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'message': "test message 1", + 'attachment_ids': attachment.id, + 'attachment_tokens': 'false', + 'csrf_token': http.WebRequest.csrf_token(self), + }, + ) self.assertEqual(res.status_code, 400) self.assertIn("The attachment %s does not exist or you do not have the rights to access it." % attachment.id, res.text) # Test attachment can't be associated if no main document token - post_data['attachment_tokens'] = attachment.access_token - res = self.url_open(url=post_url, data=post_data) + res = self.url_open( + url='%s/mail/chatter_post' % self.base_url, + data={ + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'message': "test message 1", + 'attachment_ids': attachment.id, + 'attachment_tokens': attachment.access_token, + 'csrf_token': http.WebRequest.csrf_token(self), + }, + ) self.assertEqual(res.status_code, 403) self.assertIn("You are not allowed to access 'Journal Entry' (account.move) records.", res.text) # Test attachment can't be associated if not "pending" state - post_data['token'] = invoice._portal_ensure_token() - self.assertFalse(invoice.message_ids) + self.assertFalse(self.out_invoice.message_ids) attachment.write({'res_model': 'model'}) - res = self.url_open(url=post_url, data=post_data) + res = self.url_open( + url='%s/mail/chatter_post' % self.base_url, + data={ + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'message': "test message 1", + 'attachment_ids': attachment.id, + 'attachment_tokens': attachment.access_token, + 'csrf_token': http.WebRequest.csrf_token(self), + 'token': self.out_invoice._portal_ensure_token(), + }, + ) self.assertEqual(res.status_code, 200) - invoice.invalidate_cache(fnames=['message_ids'], ids=invoice.ids) - self.assertEqual(len(invoice.message_ids), 1) - self.assertEqual(invoice.message_ids.body, "<p>test message 1</p>") - self.assertFalse(invoice.message_ids.attachment_ids) + self.out_invoice.invalidate_cache(fnames=['message_ids'], ids=self.out_invoice.ids) + self.assertEqual(len(self.out_invoice.message_ids), 1) + self.assertEqual(self.out_invoice.message_ids.body, "<p>test message 1</p>") + self.assertFalse(self.out_invoice.message_ids.attachment_ids) # Test attachment can't be associated if not correct user attachment.write({'res_model': 'mail.compose.message'}) - post_data['message'] = "test message 2" - res = self.url_open(url=post_url, data=post_data) + res = self.url_open( + url='%s/mail/chatter_post' % self.base_url, + data={ + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'message': "test message 2", + 'attachment_ids': attachment.id, + 'attachment_tokens': attachment.access_token, + 'csrf_token': http.WebRequest.csrf_token(self), + 'token': self.out_invoice._portal_ensure_token(), + }, + ) self.assertEqual(res.status_code, 200) - invoice.invalidate_cache(fnames=['message_ids'], ids=invoice.ids) - self.assertEqual(len(invoice.message_ids), 2) - self.assertEqual(invoice.message_ids[0].body, "<p>test message 2</p>") - self.assertFalse(invoice.message_ids.attachment_ids) + self.out_invoice.invalidate_cache(fnames=['message_ids'], ids=self.out_invoice.ids) + self.assertEqual(len(self.out_invoice.message_ids), 2) + self.assertEqual(self.out_invoice.message_ids[0].body, "<p>test message 2</p>") + self.assertFalse(self.out_invoice.message_ids.attachment_ids) # Test attachment can be associated if all good (complete flow) - create_data['name'] = "final attachment" - res = self.url_open(url=create_url, data=create_data, files=files) + res = self.url_open( + url='%s/portal/attachment/add' % self.base_url, + data={ + 'name': "final attachment", + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'csrf_token': http.WebRequest.csrf_token(self), + 'access_token': self.out_invoice._portal_ensure_token(), + }, + files=[('file', ('test.txt', b'test', 'plain/text'))], + ) self.assertEqual(res.status_code, 200) create_res = json.loads(res.content.decode('utf-8')) self.assertEqual(create_res['name'], "final attachment") - post_data['message'] = "test message 3" - post_data['attachment_ids'] = create_res['id'] - post_data['attachment_tokens'] = create_res['access_token'] - res = self.url_open(url=post_url, data=post_data) + res = self.url_open( + url='%s/mail/chatter_post' % self.base_url, + data={ + 'res_model': self.out_invoice._name, + 'res_id': self.out_invoice.id, + 'message': "test message 3", + 'attachment_ids': create_res['id'], + 'attachment_tokens': create_res['access_token'], + 'csrf_token': http.WebRequest.csrf_token(self), + 'token': self.out_invoice._portal_ensure_token(), + }, + ) self.assertEqual(res.status_code, 200) - invoice.invalidate_cache(fnames=['message_ids'], ids=invoice.ids) - self.assertEqual(len(invoice.message_ids), 3) - self.assertEqual(invoice.message_ids[0].body, "<p>test message 3</p>") - self.assertEqual(len(invoice.message_ids[0].attachment_ids), 1) + self.out_invoice.invalidate_cache(fnames=['message_ids'], ids=self.out_invoice.ids) + self.assertEqual(len(self.out_invoice.message_ids), 3) + self.assertEqual(self.out_invoice.message_ids[0].body, "<p>test message 3</p>") + self.assertEqual(len(self.out_invoice.message_ids[0].attachment_ids), 1) |
