diff --git a/cms_info/README.rst b/cms_info/README.rst new file mode 100644 index 00000000..2f2c4436 --- /dev/null +++ b/cms_info/README.rst @@ -0,0 +1,148 @@ +======== +CMS info +======== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png + :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html + :alt: License: LGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fwebsite--cms-lightgray.png?logo=github + :target: https://github.com/OCA/website-cms/tree/14.0/cms_info + :alt: OCA/website-cms +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/website-cms-14-0/website-cms-14-0-cms_info + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/225/14.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Provide basic information for website records / models via `website.published.mixin`. +This module is meant to be used as a base to build your own CMS. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +New attributes +~~~~~~~~~~~~~~ + +* ``cms_create_url``: lead to create view. By default ``/cms/create/my.model`` +* ``cms_search_url``: lead to search view. By default ``/cms/search/my.model`` +* ``cms_edit_url`` (computed field): lead to edit view. By default ``/cms/edit/my.model/model_id`` + +.. note:: No routing provided. + This attributes provide only basic information on contents' URLs. + If you use `cms_form` default routes are handled automatically. + If not, is up to you to provide your own routes to handle them. + + +Permission and extra information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``record.cms_is_owner()``: current user is the owner of the record? +* ``record.cms_can_edit()``: current user can edit this record? +* ``record.cms_can_publish()``: current user can publish this record? +* ``record.cms_can_delete()``: current user can delete this record? +* ``model.cms_can_create()``: current user can create a new record? + + +Info all in one +~~~~~~~~~~~~~~~ + +When you build CMS UIs you need all those info at once. +This module provides also an helper method `cms_info()` +that gives you back a dictionary containing: + +* `is_owner`: True/False, +* `can_edit`: True/False, +* `can_create`: True/False, +* `can_publish`: True/False, +* `can_delete`: True/False, +* `create_url` +* `edit_url` +* `delete_url` + +Known issues / Roadmap +====================== + + +Get rid of `website` dependency and move `website.published.mixin` integration +to a glue module. + +Changelog +========= + +13.0.1.0.1 (2021-08-23) +**Features** + +- Migration to v13 (`#111 `_) + + +11.0.1.0.1 (2019-01-18) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Fixes** + +- Info dict default to None values +- Test coverage 100% + + +11.0.1.0.0 (2018-04-27) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Improvements** + +- Initial release + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Camptocamp + +Contributors +~~~~~~~~~~~~ + +* Simone Orsi + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +This module is part of the `OCA/website-cms `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/cms_info/__init__.py b/cms_info/__init__.py new file mode 100644 index 00000000..0650744f --- /dev/null +++ b/cms_info/__init__.py @@ -0,0 +1 @@ +from . import models diff --git a/cms_info/__manifest__.py b/cms_info/__manifest__.py new file mode 100644 index 00000000..7c9265da --- /dev/null +++ b/cms_info/__manifest__.py @@ -0,0 +1,17 @@ +# Copyright 2018 Simone Orsi - Camptocamp +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). + +{ + "name": "CMS info", + "summary": """ + A set of basic information needed to expose any kind of record in your CMS. + """, + "version": "16.0.1.0.0", + "category": "CMS", + "website": "https://github.com/OCA/website-cms", + "author": "Camptocamp, Odoo Community Association (OCA)", + "mainainers": ["simahawk"], + "license": "LGPL-3", + "installable": True, + "depends": ["base"], +} diff --git a/cms_info/i18n/ca.po b/cms_info/i18n/ca.po new file mode 100644 index 00000000..78e53bbc --- /dev/null +++ b/cms_info/i18n/ca.po @@ -0,0 +1,58 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * cms_info +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-02-17 10:45+0000\n" +"Last-Translator: claudiagn \n" +"Language-Team: none\n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: cms_info +#: model:ir.model,name:cms_info.model_cms_info_mixin +msgid "CMS Info mixin" +msgstr "CMS Informació mix" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_delete_url +msgid "CMS delete URL" +msgstr "CMS eliminar URL" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_delete_confirm_url +msgid "CMS delete confirm URL" +msgstr "CMS confirmar eliminar URL" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_edit_url +msgid "CMS edit URL" +msgstr "CMS editar URL" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__display_name +msgid "Display Name" +msgstr "Nom visible" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__id +msgid "ID" +msgstr "ID" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin____last_update +msgid "Last Modified on" +msgstr "Última modificació el" + +#~ msgid "Multi Website Published Mixin" +#~ msgstr "Mixin publicat per diversos llocs web" + +#~ msgid "Website Published Mixin" +#~ msgstr "Lloc web Mixin publicat" diff --git a/cms_info/i18n/cms_info.pot b/cms_info/i18n/cms_info.pot new file mode 100644 index 00000000..fe414caf --- /dev/null +++ b/cms_info/i18n/cms_info.pot @@ -0,0 +1,49 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * cms_info +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 14.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: cms_info +#: model:ir.model,name:cms_info.model_cms_info_mixin +msgid "CMS Info mixin" +msgstr "" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_delete_url +msgid "CMS delete URL" +msgstr "" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_delete_confirm_url +msgid "CMS delete confirm URL" +msgstr "" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_edit_url +msgid "CMS edit URL" +msgstr "" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__display_name +msgid "Display Name" +msgstr "" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__id +msgid "ID" +msgstr "" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin____last_update +msgid "Last Modified on" +msgstr "" diff --git a/cms_info/i18n/es.po b/cms_info/i18n/es.po new file mode 100644 index 00000000..b6b1f58c --- /dev/null +++ b/cms_info/i18n/es.po @@ -0,0 +1,58 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * cms_info +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 13.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2021-02-17 10:45+0000\n" +"Last-Translator: claudiagn \n" +"Language-Team: none\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.3.2\n" + +#. module: cms_info +#: model:ir.model,name:cms_info.model_cms_info_mixin +msgid "CMS Info mixin" +msgstr "CMS Información mix" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_delete_url +msgid "CMS delete URL" +msgstr "CMS eliminar URL" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_delete_confirm_url +msgid "CMS delete confirm URL" +msgstr "CMS confirmar eliminar URL" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__cms_edit_url +msgid "CMS edit URL" +msgstr "CMS editar URL" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__display_name +msgid "Display Name" +msgstr "Nombre visible" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin__id +msgid "ID" +msgstr "ID" + +#. module: cms_info +#: model:ir.model.fields,field_description:cms_info.field_cms_info_mixin____last_update +msgid "Last Modified on" +msgstr "Última modificación el" + +#~ msgid "Multi Website Published Mixin" +#~ msgstr "Mixin publicado per varias webs" + +#~ msgid "Website Published Mixin" +#~ msgstr "Web Mixin publicado" diff --git a/cms_info/models/__init__.py b/cms_info/models/__init__.py new file mode 100644 index 00000000..5dbf2b3a --- /dev/null +++ b/cms_info/models/__init__.py @@ -0,0 +1 @@ +from . import cms_mixin diff --git a/cms_info/models/cms_mixin.py b/cms_info/models/cms_mixin.py new file mode 100644 index 00000000..4b886fcc --- /dev/null +++ b/cms_info/models/cms_mixin.py @@ -0,0 +1,129 @@ +# Copyright 2018 Simone Orsi (Camptocamp) +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). +from odoo import api, exceptions, fields, models + + +class CMSInfoMixin(models.AbstractModel): + """Provide core information for CMS records.""" + + _name = "cms.info.mixin" + _description = "CMS Info mixin" + + def _cms_make_url(self, action): + return "/cms/{}/{}".format(action, self._name) + + @property + def cms_create_url(self): + return self._cms_make_url("create") + + @property + def cms_search_url(self): + return self._cms_make_url("search") + + @property + def cms_edit_url_base(self): + return self._cms_make_url("edit") + + @property + def cms_delete_url_base(self): + return self._cms_make_url("delete") + + @property + def cms_after_delete_url(self): + return "/" + + cms_edit_url = fields.Char( + string="CMS edit URL", + compute="_compute_cms_edit_url", + ) + + cms_delete_url = fields.Char( + string="CMS delete URL", + compute="_compute_cms_delete_url", + ) + + cms_delete_confirm_url = fields.Char( + string="CMS delete confirm URL", + compute="_compute_cms_delete_url", + ) + + def _compute_cms_edit_url(self): + base_url = self.cms_edit_url_base + for item in self: + item.cms_edit_url = "{}/{}".format(base_url, item.id) + + def _compute_cms_delete_url(self): + base_url = self.cms_delete_url_base + for item in self: + item.update( + { + "cms_delete_url": "{}/{}".format(base_url, item.id), + "cms_delete_confirm_url": "{}/{}/confirm".format(base_url, item.id), + } + ) + + def cms_is_owner(self, uid=None): + self.ensure_one() + uid = uid or self.env.user.id + return self.create_uid.id == uid + + @api.model + def cms_can_create(self): + return self.check_access_rights("create", raise_exception=False) + + def _cms_check_perm(self, mode): + self.ensure_one() + try: + self.check_access_rights(mode) + self.check_access_rule(mode) + can = True + except exceptions.AccessError: + can = False + return can + + def cms_can_edit(self): + return self._cms_check_perm("write") + + def cms_can_delete(self): + return self._cms_check_perm("unlink") + + def cms_can_publish(self): + # TODO: improve this + return self.cms_can_edit() + + def cms_info(self): + # do not use `ensure_one` so we can use this on an empty recordset + info = {}.fromkeys( + ( + "is_owner", + "can_edit", + "can_create", + "can_publish", + "can_delete", + "create_url", + "edit_url", + "delete_url", + ), + None, + ) + if self: + # we have a record indeed + info.update( + { + # make sure it works even on empty recordsets + "is_owner": self.cms_is_owner() if self else None, + "can_edit": self.cms_can_edit(), + "can_publish": self.cms_can_publish(), + "can_delete": self.cms_can_delete(), + "edit_url": self.cms_edit_url, + "delete_url": self.cms_delete_confirm_url, + } + ) + info.update( + { + # class-level info + "create_url": self.cms_create_url, + "can_create": self.cms_can_create(), + } + ) + return info diff --git a/cms_info/readme/CONTRIBUTORS.rst b/cms_info/readme/CONTRIBUTORS.rst new file mode 100644 index 00000000..f1c71bce --- /dev/null +++ b/cms_info/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Simone Orsi diff --git a/cms_info/readme/DESCRIPTION.rst b/cms_info/readme/DESCRIPTION.rst new file mode 100644 index 00000000..a7ef6eea --- /dev/null +++ b/cms_info/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +Provide basic information for website records / models via `website.published.mixin`. +This module is meant to be used as a base to build your own CMS. diff --git a/cms_info/readme/HISTORY.rst b/cms_info/readme/HISTORY.rst new file mode 100644 index 00000000..3c60ca43 --- /dev/null +++ b/cms_info/readme/HISTORY.rst @@ -0,0 +1,31 @@ +16.0.1.0.0 (2023-05-13) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- Migration to v16 (`#127 `_) + + +13.0.1.0.1 (2021-08-23) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Features** + +- Migration to v13 (`#111 `_) + + +11.0.1.0.1 (2019-01-18) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Fixes** + +- Info dict default to None values +- Test coverage 100% + + +11.0.1.0.0 (2018-04-27) +~~~~~~~~~~~~~~~~~~~~~~~ + +**Improvements** + +- Initial release diff --git a/cms_info/readme/ROADMAP.rst b/cms_info/readme/ROADMAP.rst new file mode 100644 index 00000000..a122bbd7 --- /dev/null +++ b/cms_info/readme/ROADMAP.rst @@ -0,0 +1,3 @@ + +Get rid of `website` dependency and move `website.published.mixin` integration +to a glue module. diff --git a/cms_info/readme/USAGE.rst b/cms_info/readme/USAGE.rst new file mode 100644 index 00000000..60886a0d --- /dev/null +++ b/cms_info/readme/USAGE.rst @@ -0,0 +1,38 @@ +New attributes +~~~~~~~~~~~~~~ + +* ``cms_create_url``: lead to create view. By default ``/cms/create/my.model`` +* ``cms_search_url``: lead to search view. By default ``/cms/search/my.model`` +* ``cms_edit_url`` (computed field): lead to edit view. By default ``/cms/edit/my.model/model_id`` + +.. note:: No routing provided. + This attributes provide only basic information on contents' URLs. + If you use `cms_form` default routes are handled automatically. + If not, is up to you to provide your own routes to handle them. + + +Permission and extra information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* ``record.cms_is_owner()``: current user is the owner of the record? +* ``record.cms_can_edit()``: current user can edit this record? +* ``record.cms_can_publish()``: current user can publish this record? +* ``record.cms_can_delete()``: current user can delete this record? +* ``model.cms_can_create()``: current user can create a new record? + + +Info all in one +~~~~~~~~~~~~~~~ + +When you build CMS UIs you need all those info at once. +This module provides also an helper method `cms_info()` +that gives you back a dictionary containing: + +* `is_owner`: True/False, +* `can_edit`: True/False, +* `can_create`: True/False, +* `can_publish`: True/False, +* `can_delete`: True/False, +* `create_url` +* `edit_url` +* `delete_url` diff --git a/cms_info/static/description/icon.png b/cms_info/static/description/icon.png new file mode 100644 index 00000000..3a0328b5 Binary files /dev/null and b/cms_info/static/description/icon.png differ diff --git a/cms_info/static/description/index.html b/cms_info/static/description/index.html new file mode 100644 index 00000000..6ce9c057 --- /dev/null +++ b/cms_info/static/description/index.html @@ -0,0 +1,504 @@ + + + + + + +CMS info + + + +
+

CMS info

+ + +

Beta License: LGPL-3 OCA/website-cms Translate me on Weblate Try me on Runbot

+

Provide basic information for website records / models via website.published.mixin. +This module is meant to be used as a base to build your own CMS.

+

Table of contents

+ +
+

Usage

+
+

New attributes

+
    +
  • cms_create_url: lead to create view. By default /cms/create/my.model
  • +
  • cms_search_url: lead to search view. By default /cms/search/my.model
  • +
  • cms_edit_url (computed field): lead to edit view. By default /cms/edit/my.model/model_id
  • +
+
+

Note

+

No routing provided. +This attributes provide only basic information on contents’ URLs. +If you use cms_form default routes are handled automatically. +If not, is up to you to provide your own routes to handle them.

+
+
+
+

Permission and extra information

+
    +
  • record.cms_is_owner(): current user is the owner of the record?
  • +
  • record.cms_can_edit(): current user can edit this record?
  • +
  • record.cms_can_publish(): current user can publish this record?
  • +
  • record.cms_can_delete(): current user can delete this record?
  • +
  • model.cms_can_create(): current user can create a new record?
  • +
+
+
+

Info all in one

+

When you build CMS UIs you need all those info at once. +This module provides also an helper method cms_info() +that gives you back a dictionary containing:

+
    +
  • is_owner: True/False,
  • +
  • can_edit: True/False,
  • +
  • can_create: True/False,
  • +
  • can_publish: True/False,
  • +
  • can_delete: True/False,
  • +
  • create_url
  • +
  • edit_url
  • +
  • delete_url
  • +
+
+
+
+

Known issues / Roadmap

+

Get rid of website dependency and move website.published.mixin integration +to a glue module.

+
+
+

Changelog

+

13.0.1.0.1 (2021-08-23) +Features

+
    +
  • Migration to v13 (#111)
  • +
+
+

11.0.1.0.1 (2019-01-18)

+

Fixes

+
    +
  • Info dict default to None values
  • +
  • Test coverage 100%
  • +
+
+
+

11.0.1.0.0 (2018-04-27)

+

Improvements

+
    +
  • Initial release
  • +
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us smashing it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Camptocamp
  • +
+
+ +
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

This module is part of the OCA/website-cms project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/cms_info/tests/__init__.py b/cms_info/tests/__init__.py new file mode 100644 index 00000000..9dc826c7 --- /dev/null +++ b/cms_info/tests/__init__.py @@ -0,0 +1 @@ +from . import test_info_mixin diff --git a/cms_info/tests/fake_models.py b/cms_info/tests/fake_models.py new file mode 100644 index 00000000..26b7ccd6 --- /dev/null +++ b/cms_info/tests/fake_models.py @@ -0,0 +1,12 @@ +# Copyright 2018 Camptocamp SA +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) + +from odoo import fields, models + + +class FakeModel(models.TransientModel): + _name = "fake.model" + _inherit = "cms.info.mixin" + _description = "Testing fake model" + + name = fields.Char() diff --git a/cms_info/tests/test_info_mixin.py b/cms_info/tests/test_info_mixin.py new file mode 100644 index 00000000..0b1e3dcd --- /dev/null +++ b/cms_info/tests/test_info_mixin.py @@ -0,0 +1,153 @@ +# Copyright 2018 Simone Orsi +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) +from unittest import mock + +from odoo_test_helper import FakeModelLoader + +from odoo import exceptions +from odoo.tests.common import TransactionCase + + +class TestInfoMixin(TransactionCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.loader = FakeModelLoader(cls.env, cls.__module__) + cls.loader.backup_registry() + from .fake_models import FakeModel + + cls.loader.update_registry((FakeModel,)) + cls.model = cls.env[FakeModel._name] + cls.record = cls.model.create({"name": "Foo"}) + user_model = cls.env["res.users"].with_context( + tracking_disable=True, no_reset_password=True + ) + cls.user1 = user_model.create( + { + "name": "User 1", + "login": "user1", + "email": "user1@email.com", + } + ) + + @classmethod + def tearDownClass(cls): + cls.loader.restore_registry() + super().tearDownClass() + + def test_create_url(self): + self.assertEqual(self.record.cms_create_url, "/cms/create/fake.model") + + def test_search_url(self): + self.assertEqual(self.record.cms_search_url, "/cms/search/fake.model") + + def test_edit_url(self): + self.assertEqual( + self.record.cms_edit_url, + "/cms/edit/fake.model/%s" % self.record.id, + ) + + def test_delete_url(self): + self.assertEqual( + self.record.cms_delete_url, + "/cms/delete/fake.model/%s" % self.record.id, + ) + self.assertEqual( + self.record.cms_delete_confirm_url, + "/cms/delete/fake.model/%s/confirm" % self.record.id, + ) + self.assertEqual( + self.record.cms_after_delete_url, + "/", + ) + + def test_is_owner(self): + self.assertTrue(self.record.cms_is_owner()) + self.assertFalse(self.record.with_user(self.user1).cms_is_owner()) + + # No special ACL nor record rule. + # Rely on the fact that access rights checks are called in the right way + # and depending on their result we get proper cms info. + def test_can_create(self): + path_rights = "odoo.models.Model.check_access_rights" + with mock.patch(path_rights) as mocked: + mocked.return_value = False + self.assertFalse(self.model.with_user(self.user1).cms_can_create()) + mocked.assert_called_with("create", raise_exception=False) + mocked.return_value = True + self.assertTrue(self.model.with_user(self.user1).cms_can_create()) + mocked.assert_called_with("create", raise_exception=False) + + def _test_can(self, record, mode, handler): + path_rights = "odoo.models.Model.check_access_rights" + path_rule = "odoo.models.Model.check_access_rule" + with mock.patch(path_rights) as mocked_rights, mock.patch( + path_rule + ) as mocked_rule: + # test false + mocked_rights.side_effect = exceptions.AccessError("BAM!") + mocked_rule.side_effect = exceptions.AccessError("BAM!") + self.assertFalse(handler()) + mocked_rights.assert_called_with(mode) + # failed on ACL check, no call here + mocked_rule.assert_not_called() + + with mock.patch(path_rights) as mocked_rights, mock.patch( + path_rule + ) as mocked_rule: + # test true only rights + mocked_rights.return_value = True + mocked_rule.side_effect = exceptions.AccessError("BAM!") + self.assertFalse(handler()) + mocked_rights.assert_called_with(mode) + mocked_rule.assert_called_with(mode) + + with mock.patch(path_rights) as mocked_rights, mock.patch( + path_rule + ) as mocked_rule: + # test true + mocked_rights.return_value = True + mocked_rule.return_value = True + self.assertTrue(handler()) + mocked_rights.assert_called_with(mode) + mocked_rule.assert_called_with(mode) + + def test_can_edit(self): + record = self.record.with_user(self.user1) + self._test_can(record, "write", record.cms_can_edit) + + def test_can_delete(self): + record = self.record.with_user(self.user1) + self._test_can(record, "unlink", record.cms_can_delete) + + def test_can_publish(self): + record = self.record.with_user(self.user1) + self._test_can(record, "write", record.cms_can_publish) + + def test_info_on_record(self): + info = self.record.cms_info() + keys = ( + "is_owner", + "can_edit", + "can_create", + "can_publish", + "can_delete", + "create_url", + "edit_url", + "delete_url", + ) + self.assertEqual(sorted(keys), sorted(info.keys())) + + def test_info_on_model(self): + info = self.record.browse().cms_info() + keys = ( + "is_owner", + "can_edit", + "can_create", + "can_publish", + "can_delete", + "create_url", + "edit_url", + "delete_url", + ) + self.assertEqual(sorted(keys), sorted(info.keys())) diff --git a/setup/cms_info/odoo/addons/cms_info b/setup/cms_info/odoo/addons/cms_info new file mode 120000 index 00000000..ff2e4661 --- /dev/null +++ b/setup/cms_info/odoo/addons/cms_info @@ -0,0 +1 @@ +../../../../cms_info \ No newline at end of file diff --git a/setup/cms_info/setup.py b/setup/cms_info/setup.py new file mode 100644 index 00000000..28c57bb6 --- /dev/null +++ b/setup/cms_info/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) diff --git a/test-requirements.txt b/test-requirements.txt new file mode 100644 index 00000000..4ad8e0ec --- /dev/null +++ b/test-requirements.txt @@ -0,0 +1 @@ +odoo-test-helper