From b3845ae0d837393a72c49fc89378343feef28185 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Tue, 14 Sep 2021 14:18:40 +0000 Subject: [PATCH] [IMP] developer/howtos: proofread adv topics - Cleaned up the language a tiny bit - Fixed small errors/typos - Add some missing info for dashboard topic - Updated unit test exercise to match what's in the solutions repo Part-of: odoo/documentation#1146 --- .../howtos/rdtraining/B_acl_irrules.rst | 30 +++++------ .../developer/howtos/rdtraining/C_data.rst | 45 +++++++--------- .../howtos/rdtraining/E_unittest.rst | 52 +++++++++++-------- .../howtos/rdtraining/K_dashboard.rst | 16 +++++- 4 files changed, 78 insertions(+), 65 deletions(-) diff --git a/content/developer/howtos/rdtraining/B_acl_irrules.rst b/content/developer/howtos/rdtraining/B_acl_irrules.rst index a01a8a3c2..a30732d67 100644 --- a/content/developer/howtos/rdtraining/B_acl_irrules.rst +++ b/content/developer/howtos/rdtraining/B_acl_irrules.rst @@ -33,7 +33,7 @@ However: * Real-estate agents don't need or get to decide what property types or tags are *available*. * Real-estate agents can have *exclusive* properties, we do not want one agent - to be able to manage another's exclusivities. + to be able to manage another's exclusives. * All real-estate agents should be able to confirm the sale of a property they can manage, but we do not want them to be able to validate or mark as paid any invoice in the system. @@ -44,7 +44,7 @@ However: Because it's easier for users to disable unnecessary security rules than it is to create them from nothing, it's better to err on the side of caution - and limiting access: users can relax that access if necessary or convenient. + and limit access: users can relax that access if necessary or convenient. Groups ====== @@ -294,7 +294,7 @@ do so. There are two main ways to bypass existing security checks in Odoo, either wilfully or as a side-effect: -* The ``sudo()`` method will create a new recorset in "sudo mode", this ignores +* The ``sudo()`` method will create a new recordset in "sudo mode", this ignores all access rules and access rights (although hard-coded group and user checks may still apply). * Performing raw SQL queries will bypass access rules and access rights as a @@ -366,9 +366,9 @@ Explicit security checks can be performed by: specific models or records. * Checking that the current user has specific groups hard-coded to allow or deny an operation (``self.env.user.has_group``). -* Calling the ``check_access_rights(operation)`` method on a recorset, this +* Calling the ``check_access_rights(operation)`` method on a recordset, this verifies whether the current user has access to the model itself. -* Calling ``check_access_rule(operations)`` on a non-empty recorset, this +* Calling ``check_access_rule(operations)`` on a non-empty recordset, this verifies that the current user is allowed to perform the operation on *every* record of the set. @@ -380,7 +380,7 @@ Explicit security checks can be performed by: Before creating the invoice, use ``check_access_rights`` and ``check_access_rule`` to ensure that the current user can update properties - in general, and this specific property in particular. + in general as well as the specific property the invoice is for. Re-run the bypass script, check that the error occurs before the print. @@ -393,7 +393,7 @@ Multi-company security :ref:`reference/howtos/company` for an overview of multi-company facilities in general, and :ref:`multi-company security rules ` - this in particular. + in particular. Documentation on rules in general can, again, be found at :ref:`reference/security/rules`. @@ -403,15 +403,15 @@ Multi-company security At the end of this section, agents should only have access to properties of their agency (or agencies). -For one reason or an other we might need to manage our real-estate business -as multiple companies e.g. we might have largely autonomous agencies, or a +For one reason or another we might need to manage our real-estate business +as multiple companies e.g. we might have largely autonomous agencies, a franchise setup, or multiple brands (possibly from having acquired other real-estate businesses) which remain legally or financially separate from one another. Odoo can be used to manage multiple companies inside the same system, however the actual handling is up to individual modules: Odoo itself provides the tools -to manage the issue like company-dependent fields and *multi-company rules*, +to manage the issue of company-dependent fields and *multi-company rules*, which is what we're going to concern ourselves with. We want different agencies to be "siloed" from one another, with properties @@ -447,7 +447,7 @@ associated with *one* of the companies the user has access to: Multi-company rules are usually :ref:`global `, otherwise there is a high risk that additional rules would allow bypassing - the muti-company rules. + the multi-company rules. .. exercise:: @@ -472,7 +472,7 @@ Visibility != security .. admonition:: **Goal** At the end of this section, real-estate agents should not see the Settings - menu of the rea-estate application, but should still be able to set the + menu of the real-estate application, but should still be able to set the property type or tags. Specific Odoo models can be associated directly with groups (or companies, or @@ -480,7 +480,7 @@ users). It is important to figure out whether this association is a *security* or a *visibility* feature before using it: * *Visibility* features mean a user can still access the model or record - otherwise, either through an other part of the interface or by :doc:`perform + otherwise, either through another part of the interface or by :doc:`performing operations remotely using RPC <../../misc/api/odoo>`, things might just not be visible in the web interface in some contexts. * *Security* features mean a user can not access records, fields or operations. @@ -507,10 +507,10 @@ Here are some examples: .. exercise:: - Real Estate agents can not add property types or tags, and can see their + Real Estate agents can not add property types or tags, but can see their options from the Property form view when creating it. - The Settings menu just adds noise to their interface, it should only be + The Settings menu just adds noise to their interface, make it only visible to managers. Despite not having access to the Property Types and Property Tags menus anymore, diff --git a/content/developer/howtos/rdtraining/C_data.rst b/content/developer/howtos/rdtraining/C_data.rst index 86cee280e..63ab2ae26 100644 --- a/content/developer/howtos/rdtraining/C_data.rst +++ b/content/developer/howtos/rdtraining/C_data.rst @@ -23,23 +23,23 @@ We already met technical data previously since we have defined :ref:`security rules`, :ref:`views` and :ref:`actions`. Those are one kind of master data. -On top of technical data, business data can be defined: countries, currencies, units of measure but -also complete country localization (legal reports, tax definitions, chart of account), and much +On top of technical data, business data can be defined, e.g. countries, currencies, units of measure, +as well as complete country localization (legal reports, tax definitions, chart of account), and much more... Demo Data --------- -Next to master data which are requirements for the modules to work properly, we also like having -data for demonstration purpose setups: +In additional to master data, which are requirements for a module to work properly, we also like +having data for demonstration purposes: -* Help the sales representatives to make their demos quickly. -* Have a set of working data for developers to test the new features and see what it looks like - with something they might not have created without it. +* Help the sales representatives make their demos quickly. +* Have a set of working data for developers to test new features and see how these new features look + with data they might not have added themselves. * Test that the data is loaded correctly, without raising an error. -* Be ready to use most of the features quickly when creating a new database. +* Setup most of the features to be used quickly when creating a new database. -Demo data is automatically loaded when you start the server if you didn't say explicitly you don't +Demo data is automatically loaded when you start the server if you don't explicitly say you don't want it. This can be done in the database manager or with the command line. .. code-block:: console @@ -70,15 +70,15 @@ Manifest **Reference**: the documentation related to this topic can be found in :ref:`Module Manifests`. -The data is declared either in CSV either in XML. +Data is declared either in CSV or in XML. Each file containing data must be added in the manifest for them to be loaded. The keys to use in the manifest to add new data are ``data`` for the master data and ``demo`` for -the demo data. Both values should be a list of strings representing the relative path to the files +the demo data. Both values should be a list of strings representing the relative paths to the files declaring the data. -Usually, the demo data is set in a ``demo`` folder, the views and actions are put in a ``views`` -folder, the security related data is put in a ``security`` folder, and the other data is set in a +Usually, demo data is in a ``demo`` folder, views and actions are in a ``views`` +folder, security related data is in a ``security`` folder, and other data is in a ``data`` folder. If your work tree looks like this: @@ -129,7 +129,7 @@ CSV :ref:`CSV data files`. The easiest way to declare simple data is by using the CSV format. This is however limited in terms -of features: use it for long lists of simple models, but prefer XML in the other cases. +of features: use it for long lists of simple models, but prefer XML otherwise. .. code-block:: text @@ -153,7 +153,7 @@ XML **Reference**: the documentation related to this topic can be found in :ref:`Data Files`. -When the data to create is a bit more complex it can be useful, or even needed, to do it in XML. +When the data to create is more complex it can be useful, or even necessary, to do it in XML. .. code-block:: xml @@ -243,7 +243,7 @@ works too if you are in the module declaring it). Deco Addict Big Villa 1500001 14 ============== ========= ======= ======== -.. exercise:: Both properties should be Residential properties. +.. exercise:: Ensure both of your demo properties are created with their Property Type set to Residential. ``eval`` ~~~~~~~~ @@ -279,13 +279,13 @@ Sometimes, you need to call the ORM to do a ``search``. This is not feasible wit -In this code snippet, it is needed because the master data actually depends on the localization +In this code snippet, it is needed because the master data depends on the localization installed. ``function`` ~~~~~~~~~~~~ -You might also need to execute python code when loading the data. +You might also need to execute python code when loading data. .. code-block:: xml @@ -324,15 +324,8 @@ common ORM methods. -.. code-block:: text - - id,parent_id:id,name - "child1","module.parent","Name1" - "child2","module.parent","Name2" - "child3","module.parent","Name3" - .. exercise:: Create one new Property, but this time with some offers created directly inside the - One2many field linking to the Offers. + One2many field linked to the Offers. Accessing the data ================== diff --git a/content/developer/howtos/rdtraining/E_unittest.rst b/content/developer/howtos/rdtraining/E_unittest.rst index 4a4836520..e53084537 100644 --- a/content/developer/howtos/rdtraining/E_unittest.rst +++ b/content/developer/howtos/rdtraining/E_unittest.rst @@ -15,11 +15,11 @@ Advanced E: Python Unit Tests Writing tests is a necessity for multiple reasons. Here is a non exhaustive list: -* Ensure it will not be broken in the future +* Ensure code will not be broken in the future * Define the scope of your code * Give examples of use cases * It is one way to technically document the code -* Help you develop by defining your goal before working towards it +* Help your coding by defining your goal before working towards it Running Tests ============= @@ -79,7 +79,7 @@ Integration Bots ================ .. note:: This section is only for Odoo employees and people that are contributing to - `github.com/odoo`. We highly recommend having your own CI if it is not the case. + `github.com/odoo`. We highly recommend having your own CI otherwise. When a test is written, it is important to make sure it always passes when modifications are applied to the source code. To automate this task, we use a development practice called @@ -100,7 +100,7 @@ GitHub. You can see the state of a commit/branch by filtering on the runbot dashboard. -A **bundle** is created for each branch. A bundle consists of a configuration and contains the +A **bundle** is created for each branch. A bundle consists of a configuration and batches. A **batch** is a set of builds, depending on the parameters of the bundle. @@ -116,17 +116,17 @@ process. Generally it is used to split the post install tests in 4 parallel inst A sub-build is green if all the tests are passing and there are no errors/warnings logged. .. note:: - * All tests are run whatever the modifications done. Correcting a typo in an error message or - refactoring a whole module triggers the same tests. It will install all the modules. This means - something might not work if Runbot green but your changes depend on something you don't depend - on. + * All tests are run regardless of the modifications done. Correcting a typo in an error message or + refactoring a whole module triggers the same tests. All modules will be installed as well. This means + something might not work even if the Runbot is green, i.e. your changes depend on a module that the + module the changes are in doesn't depend on. * The localization modules (i.e. country-specific modules) are not installed on Runbot (except - the generic one), some modules with external dependencies can be excluded also. - * There is a nightly build running additional tests, like module operations, localization, single + the generic one). Some modules with external dependencies can also be excluded. + * There is a nightly build running additional tests: module operations, localization, single module installs, multi-builds for nondeterministic bugs, etc. These are not kept in the standard CI to shorten the time of execution. -You can also login on a build built by Runbot. There are 3 users usable: `admin`, `demo` and +You can also login to a build built by Runbot. There are 3 users usable: `admin`, `demo` and `portal`. The password is the same as the login. This is useful to quickly test things on different versions without having to build it locally. The full logs are also available; these are used for monitoring. @@ -138,9 +138,9 @@ You will most likely have to gain a little bit more experience before having the robodoo, but here are a few remarks anyways. Robodoo is the guy spamming the CI status as tags on your PRs, but he is also the guy that kindly -integrates your commits on the main repositories. +integrates your commits into the main repositories. -When the last batch is green, the reviewer can ask robodoo to merge your PR (actually it is more +When the last batch is green, the reviewer can ask robodoo to merge your PR (it is more a `rebase` than a `merge`). It will then go to the mergebot. Mergebot @@ -166,8 +166,8 @@ your branch on the target and rerun the tests locally. Modules ======= -Because Odoo is modular, the tests need to be modular also. This means the modules are defined in -the module that adds the functionality you add; and that tests cannot depend on functionality +Because Odoo is modular, the tests need to be also modular. This means tests are defined in +the module that adds the functionality you are adding in and tests cannot depend on functionality coming from modules your module doesn't depend on. **Reference**: the documentation related to this topic can be found in @@ -193,7 +193,7 @@ coming from modules your module doesn't depend on. If the behavior you want to test can be changed by the installation of another module, you need to ensure that the tag `at_install` is set; otherwise you can use the tag `post_install` to speed up -the CI, and ensure it is not changed if it shouldn't. +the CI and ensure it is not changed if it shouldn't. Writing a test ============== @@ -233,13 +233,13 @@ import the test folder/module in the ``__init__.py`` of the module. ├── __init__.py └── __manifest__.py -.. note:: Some older tests are extending ``odoo.tests.common.TransactionCase``, but they are less +.. note:: Some older tests extend ``odoo.tests.common.TransactionCase``, but they are less scalable. The difference is that the setup is done per test method and not per test class. - The data changed are rollbacked between each test in `SavepointCase` to have the same behavior as - in `TransactionCase`. + Changed data is rolled back between each test in `SavepointCase` to have the same behavior as + `TransactionCase`. All the tests should extend ``odoo.tests.common.SavepointCase``. You usually define a -``setUpClass``, and the tests. After doing the `setUpClass`, you have an `env` available on the +``setUpClass`` and the tests. After writing the `setUpClass`, you have an `env` available in the class and can start interacting with the ORM. These test classes are built on top of the ``unittest`` python module. @@ -285,12 +285,18 @@ These test classes are built on top of the ``unittest`` python module. with self.assertRaises(UserError): self.properties.forbidden_action_on_sold_property() -.. note:: For more readability, split your tests into multiple files depending on the scope of the - tests. You can also have a Common class that most of the tests should inherit from; that common +.. note:: For better readability, split your tests into multiple files depending on the scope of the + tests. You can also have a Common class that most of the tests should inherit from; this common class can define the whole set up for the module. For instance in `account `__. -.. exercise:: Ensure no one can create an offer for a sold Property, and create a test for it. +.. exercise:: Update the code so no one can: + + - Create an offer for a sold property + - Sell a property with no accepted offers on it + + and create tests for both of these cases. Additionally check that selling a property that can + be sold is correctly marked as sold after selling it. .. exercise:: Someone keeps breaking the reset of Garden Area and Orientation when you uncheck the diff --git a/content/developer/howtos/rdtraining/K_dashboard.rst b/content/developer/howtos/rdtraining/K_dashboard.rst index 6eebcc341..0006c0316 100644 --- a/content/developer/howtos/rdtraining/K_dashboard.rst +++ b/content/developer/howtos/rdtraining/K_dashboard.rst @@ -319,7 +319,7 @@ View Now that we have our model, we can make its dashboard view. There is no difference to how its made except that its file is located in the ``report`` folder. Since it is a new model not linked to any other model, we will also have to add a new menuitem to view our dashboard. Typically SQL views -are added under a first level menu called ``Reporting` (because it's a report, surprise!). Do you +are added under a first level menu called *Reporting* (because it's a report, surprise!). Do you remember how to add a ``menuitem``? If not, revisit :ref:`howto/rdtraining/06_firstui`) again. .. exercise:: Create report view. @@ -352,3 +352,17 @@ from this report. **Tip 2** If you have a field that you do not want as a measure (i.e. in your pivot or graph views), then you can add ``store=False`` to it and it will not show. + +**Tip 3** If you have a SQL View that depends on context then instead of overriding +``BaseModel.init()`` set the ``_table_query`` property:: + + @property + def _table_query(self): + return 'SELECT %s FROM %s' % (self._select(), self._from()) + +The *select* and *from* methods remain the same. + +`Here is an example `__ +of a report that depends on the currently selected companies (in a multi-company environment) context to +determine the currency exchange rates to use for accurately displaying amounts when the selected companies +have different currencies. \ No newline at end of file