mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-20 12:32:02 +02:00
vanilla 18.0
This commit is contained in:
parent
5454004ff9
commit
d7f6d2725e
979 changed files with 428093 additions and 0 deletions
117
odoo-bringout-oca-ocb-web/web/tests/test_partner.py
Normal file
117
odoo-bringout-oca-ocb-web/web/tests/test_partner.py
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import io
|
||||
import logging
|
||||
import unittest
|
||||
import zipfile
|
||||
from odoo.fields import Command
|
||||
|
||||
from odoo.tests.common import HttpCase, tagged
|
||||
from base64 import b64decode
|
||||
|
||||
from odoo.tools import mute_logger
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import vobject
|
||||
except ImportError:
|
||||
_logger.warning("`vobject` Python module not found, vcard file generation disabled. Consider installing this module if you want to generate vcard files")
|
||||
vobject = None
|
||||
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestPartnerVCard(HttpCase):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
if not vobject:
|
||||
raise unittest.SkipTest("Skip tests when `vobject` Python module is not found.")
|
||||
|
||||
self.partners = self.env['res.partner'].create([{
|
||||
'name': 'John Doe',
|
||||
'email': 'john.doe@test.example.com',
|
||||
'mobile': '+1 202 555 0888',
|
||||
'phone': '+1 202 555 0122',
|
||||
'function': 'Painter',
|
||||
'street': 'Cookieville Minimum-Security Orphanarium',
|
||||
'city': 'New York',
|
||||
'country_id': self.env.ref('base.us').id,
|
||||
'zip': '97648',
|
||||
'website': 'https://test.exemple.com',
|
||||
}, {
|
||||
'name': 'shut',
|
||||
'email': 'shut@test.example.com',
|
||||
'mobile': '+1 202 555 0999',
|
||||
'phone': '+1 202 555 0123',
|
||||
'function': 'Developer',
|
||||
'street': 'Donutville Maximum-Security Orphanarium',
|
||||
'city': 'Washington DC',
|
||||
'country_id': self.env.ref('base.us').id,
|
||||
'zip': '97649',
|
||||
'website': 'https://test.example.com',
|
||||
'child_ids': [
|
||||
Command.create({'type': 'other'})
|
||||
]
|
||||
}])
|
||||
self.authenticate("admin", "admin")
|
||||
|
||||
def check_vcard_contents(self, vcard, partner):
|
||||
self.assertEqual(vcard.contents["n"][0].value.family, partner.name, "Vcard should have the same name")
|
||||
self.assertEqual(vcard.contents["adr"][0].value.street, partner.street, "Vcard should have the same street")
|
||||
self.assertEqual(vcard.contents["adr"][0].value.city, partner.city, "Vcard should have the same city")
|
||||
self.assertEqual(vcard.contents["adr"][0].value.code, partner.zip, "Vcard should have the same zip")
|
||||
self.assertEqual(vcard.contents["adr"][0].value.country, self.env.ref('base.us').name, "Vcard should have the same country")
|
||||
self.assertEqual(vcard.contents["email"][0].value, partner.email, "Vcard should have the same email")
|
||||
self.assertEqual(vcard.contents["url"][0].value, partner.website, "Vcard should have the same website")
|
||||
self.assertEqual(vcard.contents["tel"][0].params['TYPE'], ["work"], "Vcard should have the same phone")
|
||||
self.assertEqual(vcard.contents["tel"][0].value, partner.phone, "Vcard should have the same phone")
|
||||
self.assertEqual(vcard.contents["tel"][1].params['TYPE'], ["cell"], "Vcard should have the same mobile")
|
||||
self.assertEqual(vcard.contents["tel"][1].value, partner.mobile, "Vcard should have the same mobile")
|
||||
self.assertEqual(vcard.contents["title"][0].value, partner.function, "Vcard should have the same function")
|
||||
self.assertEqual(len(vcard.contents['photo'][0].value), len(b64decode(partner.avatar_512)), "Vcard should have the same photo")
|
||||
|
||||
def test_fetch_single_partner_vcard(self):
|
||||
res = self.url_open('/web_enterprise/partner/%d/vcard' % self.partners[0].id)
|
||||
vcard = vobject.readOne(res.text)
|
||||
self.check_vcard_contents(vcard, self.partners[0])
|
||||
|
||||
def test_fetch_multiple_partners_vcard(self):
|
||||
res = self.url_open('/web/partner/vcard?partner_ids=%s,%s'
|
||||
% (self.partners[0].id, self.partners[1].id))
|
||||
with io.BytesIO(res.content) as buffer:
|
||||
with zipfile.ZipFile(buffer, 'r') as zipf:
|
||||
vcfFileList = zipf.namelist()
|
||||
for i, vcfFile in enumerate(vcfFileList):
|
||||
vcardFile = zipf.read(vcfFile).decode()
|
||||
self.check_vcard_contents(vobject.readOne(vcardFile), self.partners[i])
|
||||
|
||||
@unittest.skip
|
||||
def test_not_exist_partner_vcard(self):
|
||||
partner_id = self.partner.id
|
||||
self.partner.unlink()
|
||||
res = self.url_open('/web/partner/%d/vcard' % partner_id)
|
||||
self.assertEqual(res.status_code, 404)
|
||||
|
||||
def test_check_partner_access_for_user(self):
|
||||
self.env['res.users'].create({
|
||||
'groups_id': [Command.set([self.env.ref('base.group_public').id])],
|
||||
'name': 'Test User',
|
||||
'login': 'testuser',
|
||||
'password': 'testuser',
|
||||
})
|
||||
self.authenticate('testuser', 'testuser')
|
||||
with mute_logger('odoo.http'): # mute 403 warning
|
||||
res = self.url_open('/web/partner/vcard?partner_ids=%s,%s' %
|
||||
(self.partners[0].id, self.partners[1].id))
|
||||
self.assertEqual(res.status_code, 403)
|
||||
|
||||
def test_fetch_single_partner_vcard_without_name(self):
|
||||
"""
|
||||
Test to fetch a vcard of a partner create through
|
||||
child of another partner without name
|
||||
"""
|
||||
partner = self.partners[1].child_ids[0]
|
||||
res = self.url_open('/web/partner/vcard?partner_ids=%s' % partner.id)
|
||||
vcard = vobject.readOne(res.text)
|
||||
self.assertEqual(vcard.contents["n"][0].value.family, partner.complete_name, "Vcard will have the complete name when it dosen't have name")
|
||||
50
odoo-bringout-oca-ocb-web/web/tests/test_pivot_export.py
Normal file
50
odoo-bringout-oca-ocb-web/web/tests/test_pivot_export.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import io
|
||||
import json
|
||||
from lxml import etree
|
||||
from zipfile import ZipFile
|
||||
|
||||
from odoo import http
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
class TestPivotExport(HttpCase):
|
||||
|
||||
def test_export_xlsx_with_integer_column(self):
|
||||
""" Test the export_xlsx method of the pivot controller with int columns """
|
||||
self.authenticate('admin', 'admin')
|
||||
jdata = {
|
||||
'title': 'Sales Analysis',
|
||||
'model': 'sale.report',
|
||||
'measure_count': 1,
|
||||
'origin_count': 1,
|
||||
'col_group_headers': [
|
||||
[{'title': 500, 'width': 1, 'height': 1}],
|
||||
],
|
||||
'measure_headers': [],
|
||||
'origin_headers': [],
|
||||
'rows': [
|
||||
{'title': 1, 'indent': 0, 'values': [{'value': 42}]},
|
||||
],
|
||||
}
|
||||
response = self.url_open(
|
||||
'/web/pivot/export_xlsx',
|
||||
data={
|
||||
'data': json.dumps(jdata),
|
||||
'csrf_token': http.Request.csrf_token(self),
|
||||
},
|
||||
)
|
||||
response.raise_for_status()
|
||||
zip_file = ZipFile(io.BytesIO(response.content))
|
||||
|
||||
with zip_file.open('xl/worksheets/sheet1.xml') as file:
|
||||
sheet_tree = etree.parse(file)
|
||||
xml_data = {}
|
||||
|
||||
for c in sheet_tree.iterfind('.//{http://schemas.openxmlformats.org/spreadsheetml/2006/main}c'):
|
||||
cell_ref = c.attrib['r']
|
||||
value = c.findtext('{http://schemas.openxmlformats.org/spreadsheetml/2006/main}v')
|
||||
xml_data[cell_ref] = value
|
||||
|
||||
self.assertEqual(xml_data['B1'], '500')
|
||||
self.assertEqual(xml_data['A2'], '0')
|
||||
self.assertEqual(xml_data['B2'], '42')
|
||||
61
odoo-bringout-oca-ocb-web/web/tests/test_res_users.py
Normal file
61
odoo-bringout-oca-ocb-web/web/tests/test_res_users.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests import Form, TransactionCase
|
||||
|
||||
|
||||
class TestResUsers(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.users = cls.env["res.users"].create([
|
||||
{'name': 'Jean', 'login': 'jean@mail.com', 'password': 'jean@mail.com'},
|
||||
{'name': 'Jean-Paul', 'login': 'jean-paul@mail.com', 'password': 'jean-paul@mail.com'},
|
||||
{'name': 'Jean-Jacques', 'login': 'jean-jacques@mail.com', 'password': 'jean-jacques@mail.com'},
|
||||
{'name': 'Georges', 'login': 'georges@mail.com', 'password': 'georges@mail.com'},
|
||||
{'name': 'Claude', 'login': 'claude@mail.com', 'password': 'claude@mail.com'},
|
||||
{'name': 'Pascal', 'login': 'pascal@mail.com', 'password': 'pascal@mail.com'},
|
||||
])
|
||||
|
||||
def test_name_search(self):
|
||||
"""
|
||||
Test name search with self assign feature
|
||||
The self assign feature is present only when a limit is present,
|
||||
which is the case with the public name_search by default
|
||||
"""
|
||||
ResUsers = self.env['res.users']
|
||||
jean = self.users[0]
|
||||
user_ids = [id_ for id_, __ in ResUsers.with_user(jean).name_search('')]
|
||||
self.assertEqual(jean.id, user_ids[0], "The current user, Jean, should be the first in the result.")
|
||||
user_ids = [id_ for id_, __ in ResUsers.with_user(jean).name_search('Claude')]
|
||||
self.assertNotIn(jean.id, user_ids, "The current user, Jean, should not be in the result because his name does not fit the condition.")
|
||||
pascal = self.users[-1]
|
||||
user_ids = [id_ for id_, __ in ResUsers.with_user(pascal).name_search('')]
|
||||
self.assertEqual(pascal.id, user_ids[0], "The current user, Pascal, should be the first in the result.")
|
||||
user_ids = [id_ for id_, __ in ResUsers.with_user(pascal).name_search('', limit=3)]
|
||||
self.assertEqual(pascal.id, user_ids[0], "The current user, Pascal, should be the first in the result.")
|
||||
self.assertEqual(len(user_ids), 3, "The number of results found should still respect the limit set.")
|
||||
jean_paul = self.users[1]
|
||||
user_ids = [id_ for id_, __ in ResUsers.with_user(jean_paul).name_search('Jean')]
|
||||
self.assertEqual(jean_paul.id, user_ids[0], "The current user, Jean-Paul, should be the first in the result")
|
||||
claude = self.users[4]
|
||||
user_ids = [id_ for id_, __ in ResUsers.with_user(claude).name_search('', limit=2)]
|
||||
self.assertEqual(claude.id, user_ids[0], "The current user, Claude, should be the first in the result.")
|
||||
self.assertNotEqual(claude.id, user_ids[1], "The current user, Claude, should not appear twice in the result")
|
||||
user_ids = [id_ for id_, __ in ResUsers.with_user(claude).name_search('', limit=5)]
|
||||
self.assertEqual(len(user_ids), len(set(user_ids)), "Some user(s), appear multiple times in the result")
|
||||
|
||||
def test_change_password(self):
|
||||
'''
|
||||
We should be able to change user password without any issue
|
||||
'''
|
||||
user_internal = self.env['res.users'].create({
|
||||
'name': 'Internal',
|
||||
'login': 'user_internal',
|
||||
'password': 'password',
|
||||
'groups_id': [self.env.ref('base.group_user').id],
|
||||
})
|
||||
with Form(self.env['change.password.wizard'].with_context(active_model='res.users', active_ids=user_internal.ids), view='base.change_password_wizard_view') as form:
|
||||
with form.user_ids.edit(0) as line:
|
||||
line.new_passwd = 'bla'
|
||||
rec = form.save()
|
||||
rec.change_password_button()
|
||||
84
odoo-bringout-oca-ocb-web/web/tests/test_router.py
Normal file
84
odoo-bringout-oca-ocb-web/web/tests/test_router.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
from odoo.tests.common import TransactionCase
|
||||
from odoo.addons.web.controllers.utils import get_action_triples, get_action
|
||||
|
||||
|
||||
class TestWebRouter(TransactionCase):
|
||||
def test_router_get_action_exist(self):
|
||||
ir_cron_act = self.env.ref('base.ir_cron_act')
|
||||
valid_actions = [
|
||||
f'action-{ir_cron_act.id}', # record id
|
||||
'action-base.ir_cron_act', # xml id
|
||||
'm-ir.cron', # m- model name (for website)
|
||||
'ir.cron', # dotted model name
|
||||
'crons', # action path
|
||||
]
|
||||
for action in valid_actions:
|
||||
with self.subTest(action=action):
|
||||
self.assertEqual(get_action(self.env, action), ir_cron_act)
|
||||
|
||||
def test_router_get_action_missing(self):
|
||||
Actions = self.env['ir.actions.actions']
|
||||
missing_actions = [
|
||||
'action-999999999',
|
||||
'action-base.idontexist',
|
||||
'm-base', # abstract model
|
||||
'm-idontexist',
|
||||
'base.idontexist',
|
||||
'idontexist',
|
||||
]
|
||||
for action in missing_actions:
|
||||
with self.subTest(action=action):
|
||||
self.assertEqual(get_action(self.env, action), Actions)
|
||||
|
||||
def test_router_get_action_triples_exist(self):
|
||||
base = self.env['ir.module.module'].search([('name', '=', 'base')])
|
||||
user = self.env.user
|
||||
ir_cron_act = self.env.ref('base.ir_cron_act')
|
||||
|
||||
matrix = {
|
||||
# single action
|
||||
f'action-{ir_cron_act.id}': [(None, ir_cron_act, None)],
|
||||
'action-base.ir_cron_act': [(None, ir_cron_act, None)],
|
||||
'm-ir.cron': [(None, ir_cron_act, None)],
|
||||
'ir.cron': [(None, ir_cron_act, None)],
|
||||
'crons': [(None, ir_cron_act, None)],
|
||||
|
||||
# multiple actions, all are accessible by clicking in the web client
|
||||
|
||||
# Apps > Base > Module info
|
||||
f'apps/{base.id}/ir.module.module/{base.id}': [
|
||||
(None, self.env.ref('base.open_module_tree'), base.id),
|
||||
(base.id, self.env.ref('base.open_module_tree'), base.id)],
|
||||
|
||||
# Settings > Users & Companies > Users > Marc Demo > Related Partner
|
||||
f'users/{user.id}/res.partner/{user.partner_id.id}': [
|
||||
(None, self.env.ref('base.action_res_users'), user.id),
|
||||
(user.id, self.env.ref('base.action_partner_form'), user.partner_id.id)],
|
||||
|
||||
# Settings > Users & Companies > Users > Marc Demo > Access Right > TOTP
|
||||
f'users/{user.id}/ir.model.access/ir.model.access/146': [
|
||||
(None, self.env.ref('base.action_res_users'), user.id),
|
||||
(user.id, self.env.ref('base.ir_access_act'), None),
|
||||
(user.id, self.env.ref('base.ir_access_act'), 146),
|
||||
]
|
||||
}
|
||||
for path, triples in matrix.items():
|
||||
with self.subTest(path=path):
|
||||
self.assertEqual(list(get_action_triples(self.env, path)), triples)
|
||||
|
||||
def test_router_get_action_triples_missing(self):
|
||||
# single unknown action
|
||||
missing_actions = [
|
||||
'action-999999999',
|
||||
'action-base.idontexist',
|
||||
'm-base',
|
||||
'm-idontexist',
|
||||
'base.idontexist',
|
||||
'idontexist',
|
||||
]
|
||||
for action in missing_actions:
|
||||
with self.subTest(path=action):
|
||||
with self.assertRaises(ValueError) as capture:
|
||||
all(get_action_triples(self.env, action))
|
||||
self.assertEqual(capture.exception.args[0],
|
||||
f"expected action at word 0 but found “{action}”")
|
||||
42
odoo-bringout-oca-ocb-web/web/tests/test_translate.py
Normal file
42
odoo-bringout-oca-ocb-web/web/tests/test_translate.py
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.tests.common import TransactionCase
|
||||
|
||||
class TestTranslationOverride(TransactionCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
cls.category = cls.env['res.partner.category'].create({'name': 'Reblochon'})
|
||||
cls.custom = cls.env['ir.model.fields'].create({
|
||||
'name': 'x_html_test',
|
||||
'ttype': 'html',
|
||||
'model_id': cls.category.id,
|
||||
'translate': True,
|
||||
})
|
||||
|
||||
def test_web_override_translations(self):
|
||||
self.env['res.lang']._activate_lang('fr_FR')
|
||||
categoryEN = self.category.with_context(lang='en_US')
|
||||
categoryFR = self.category.with_context(lang='fr_FR')
|
||||
customEN = self.custom.with_context(lang='en_US')
|
||||
customFR = self.custom.with_context(lang='fr_FR')
|
||||
|
||||
self.category.web_override_translations({'name': 'commonName'})
|
||||
self.assertEqual(categoryEN.name, 'commonName')
|
||||
self.assertEqual(categoryFR.name, 'commonName')
|
||||
|
||||
# cannot void translations (incluiding en_US)
|
||||
self.category.web_override_translations({'name': False})
|
||||
self.assertEqual(categoryEN.name, 'commonName')
|
||||
self.assertEqual(categoryFR.name, 'commonName')
|
||||
|
||||
# empty str is a valid translation
|
||||
self.category.web_override_translations({'name': ''})
|
||||
self.assertEqual(categoryEN.name, '')
|
||||
self.assertEqual(categoryFR.name, '')
|
||||
|
||||
# translated html fields are not changed
|
||||
self.custom.web_override_translations({'name': '<div>dont</div><div>change</div>'})
|
||||
self.assertEqual(customEN.name, 'x_html_test')
|
||||
self.assertEqual(customFR.name, 'x_html_test')
|
||||
27
odoo-bringout-oca-ocb-web/web/tests/test_web_read_group.py
Normal file
27
odoo-bringout-oca-ocb-web/web/tests/test_web_read_group.py
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
from odoo import fields
|
||||
from odoo.tests import common
|
||||
|
||||
|
||||
@common.tagged('post_install', '-at_install')
|
||||
class TestWebReadGroup(common.TransactionCase):
|
||||
|
||||
def test_web_read_group_with_date_groupby_and_limit(self):
|
||||
res_partner_model_id = self.env["ir.model"].search([("model", "=", "res.partner")]).id
|
||||
self.env["ir.model.fields"].create({
|
||||
"name": "x_date",
|
||||
"ttype": "date",
|
||||
"model": "res.partner",
|
||||
"model_id": res_partner_model_id,
|
||||
})
|
||||
first, second = self.env["res.partner"].create([
|
||||
{
|
||||
"name": "first",
|
||||
"x_date": fields.Date.to_date("2021-06-01")
|
||||
},
|
||||
{
|
||||
"name": "second",
|
||||
"x_date": fields.Date.to_date("2021-07-01")
|
||||
}
|
||||
])
|
||||
groups = self.env["res.partner"].web_read_group([["id", "in", [first.id, second.id]]], [], groupby=["x_date"], limit=1)
|
||||
self.assertEqual(groups["length"], 2)
|
||||
26
odoo-bringout-oca-ocb-web/web/tests/test_web_redirect.py
Normal file
26
odoo-bringout-oca-ocb-web/web/tests/test_web_redirect.py
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from werkzeug.urls import url_parse
|
||||
|
||||
from odoo.tests.common import HttpCase
|
||||
|
||||
|
||||
class TestWebRedirect(HttpCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
def test_web_route_redirect_param_legacy(self):
|
||||
# This test is for legacy routes with /web and fragement
|
||||
web_response = self.url_open('/web#cids=1&action=887&menu_id=124')
|
||||
web_response.raise_for_status()
|
||||
response_url_query = url_parse(web_response.url).query
|
||||
|
||||
self.assertEqual(response_url_query, 'redirect=%2Fweb%3F')
|
||||
|
||||
def test_web_route_redirect_param(self):
|
||||
# This test if for the new routes with /odoo, pathname and query params
|
||||
web_response = self.url_open('/odoo/action-887?cids=1')
|
||||
web_response.raise_for_status()
|
||||
response_url_query = url_parse(web_response.url).query
|
||||
|
||||
self.assertEqual(response_url_query, 'redirect=%2Fodoo%2Faction-887%3Fcids%3D1')
|
||||
109
odoo-bringout-oca-ocb-web/web/tests/test_webmanifest.py
Normal file
109
odoo-bringout-oca-ocb-web/web/tests/test_webmanifest.py
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.base.tests.common import HttpCaseWithUserDemo
|
||||
from odoo.tests.common import tagged
|
||||
|
||||
|
||||
@tagged("-at_install", "post_install")
|
||||
class WebManifestRoutesTest(HttpCaseWithUserDemo):
|
||||
"""
|
||||
This test suite is used to request the routes used by the PWA backend implementation
|
||||
"""
|
||||
|
||||
def test_webmanifest(self):
|
||||
"""
|
||||
This route returns a well formed backend's WebManifest
|
||||
"""
|
||||
self.authenticate("admin", "admin")
|
||||
response = self.url_open("/web/manifest.webmanifest")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers["Content-Type"], "application/manifest+json")
|
||||
data = response.json()
|
||||
self.assertEqual(data["name"], "Odoo")
|
||||
self.assertEqual(data["scope"], "/odoo")
|
||||
self.assertEqual(data["start_url"], "/odoo")
|
||||
self.assertEqual(data["display"], "standalone")
|
||||
self.assertEqual(data["background_color"], "#714B67")
|
||||
self.assertEqual(data["theme_color"], "#714B67")
|
||||
self.assertEqual(data["prefer_related_applications"], False)
|
||||
self.assertCountEqual(data["icons"], [
|
||||
{'src': '/web/static/img/odoo-icon-192x192.png', 'sizes': '192x192', 'type': 'image/png'},
|
||||
{'src': '/web/static/img/odoo-icon-512x512.png', 'sizes': '512x512', 'type': 'image/png'}
|
||||
])
|
||||
self.assertGreaterEqual(len(data["shortcuts"]), 0)
|
||||
for shortcut in data["shortcuts"]:
|
||||
self.assertGreater(len(shortcut["name"]), 0)
|
||||
self.assertGreater(len(shortcut["description"]), 0)
|
||||
self.assertGreater(len(shortcut["icons"]), 0)
|
||||
self.assertTrue(shortcut["url"].startswith("/odoo?menu_id="))
|
||||
|
||||
def test_webmanifest_unauthenticated(self):
|
||||
"""
|
||||
This route returns a well formed backend's WebManifest
|
||||
"""
|
||||
response = self.url_open("/web/manifest.webmanifest")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers["Content-Type"], "application/manifest+json")
|
||||
data = response.json()
|
||||
self.assertEqual(data["name"], "Odoo")
|
||||
self.assertEqual(data["scope"], "/odoo")
|
||||
self.assertEqual(data["start_url"], "/odoo")
|
||||
self.assertEqual(data["display"], "standalone")
|
||||
self.assertEqual(data["background_color"], "#714B67")
|
||||
self.assertEqual(data["theme_color"], "#714B67")
|
||||
self.assertEqual(data["prefer_related_applications"], False)
|
||||
self.assertCountEqual(data["icons"], [
|
||||
{'src': '/web/static/img/odoo-icon-192x192.png', 'sizes': '192x192', 'type': 'image/png'},
|
||||
{'src': '/web/static/img/odoo-icon-512x512.png', 'sizes': '512x512', 'type': 'image/png'}
|
||||
])
|
||||
self.assertEqual(len(data["shortcuts"]), 0)
|
||||
|
||||
def test_webmanifest_scoped(self):
|
||||
response = self.url_open("/web/manifest.scoped_app_manifest?app_id=test&path=/test&app_name=Test")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers["Content-Type"], "application/manifest+json")
|
||||
data = response.json()
|
||||
self.assertEqual(data["name"], "Test")
|
||||
self.assertEqual(data["scope"], "/test")
|
||||
self.assertEqual(data["start_url"], "/test")
|
||||
self.assertEqual(data["display"], "standalone")
|
||||
self.assertEqual(data["background_color"], "#714B67")
|
||||
self.assertEqual(data["theme_color"], "#714B67")
|
||||
self.assertEqual(data["prefer_related_applications"], False)
|
||||
self.assertCountEqual(data["icons"], [
|
||||
{'src': "/web/static/img/odoo-icon-192x192.png", 'sizes': 'any', 'type': 'image/png'}
|
||||
])
|
||||
self.assertEqual(len(data["shortcuts"]), 0)
|
||||
|
||||
def test_serviceworker(self):
|
||||
"""
|
||||
This route returns a JavaScript's ServiceWorker
|
||||
"""
|
||||
response = self.url_open("/web/service-worker.js")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers["Content-Type"], "text/javascript")
|
||||
self.assertEqual(response.headers["Service-Worker-Allowed"], "/odoo")
|
||||
|
||||
def test_offline_url(self):
|
||||
"""
|
||||
This route returns the offline page
|
||||
"""
|
||||
response = self.url_open("/odoo/offline")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(response.headers["Content-Type"], "text/html; charset=utf-8")
|
||||
|
||||
def test_apple_touch_icon(self):
|
||||
"""
|
||||
This request tests the presence of an apple-touch-icon image route for the PWA icon and
|
||||
its presence from the head of the document.
|
||||
"""
|
||||
self.authenticate("demo", "demo")
|
||||
response = self.url_open("/web/static/img/odoo-icon-ios.png")
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
document = self.url_open("/odoo")
|
||||
self.assertIn(
|
||||
'<link rel="apple-touch-icon" href="/web/static/img/odoo-icon-ios.png"/>', document.text,
|
||||
"Icon for iOS is present in the head of the document.",
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue