Commit Graph
37 Commits
Author SHA1 Message Date
Raphael Collet be73b9ae26 [FIX] core: in onchange, assign inherited fields that have changed
This allows onchange to recompute fields that depend on the inherited
field that has changed.  The use-case we have is a model that inherits
from 'account.move'.  On its form view, setting the (inherited) journal
field does not recompute the (inherited) company field.

When the field 'journal_id' is modified, the onchange should:
 - assign the new value to move_id.journal_id (*)
 - recompute move_id.company_id (related='journal_id.company_id')
 - recompute company_id

This commit adds the missing part (*).

X-original-commit: 2e05d0a361aa06a34eecf64613821f2e92295298
2021-07-08 15:29:17 +00:00
Raphael Collet 8ff079366d [FIX] core: computed editable one2many field with a domain
Manually adding a line should not trigger the computation of the field,
just like modifying the line fields that occur in the field's domain.
In other words, the dependencies of the field should be limited to the
ones declared on field or its compute method.

closes odoo/odoo#71049

X-original-commit: 1c39814bd729cc08882f1545c7d88b0592e63f9a
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-05-19 16:29:53 +00:00
Raphael Collet 81ff2717cf [REM] core: remove optimization sharing fields across registries
The optimization will be reintroduced later in a different form.
2021-05-03 12:33:29 +00:00
Raphael Collet 34d6f87d54 [REF] core: put field.depends on registry and make field.recursive explicit
The attributes field.depends and field.depends_context are problematic
for sharing fields across registries, because they depend on the model's
registry class, which may vary from one registry to another.  In order
to make computed fields shareable, we have to move those values away
from fields.

For the same reason, field.recursive should not be inferred, because its
value may depend on the registry, although it is generally not the case.
Moreover, the flag recursive=True is set on a field when field triggers
are determined (on the registry).  A compute method may be called before
the flag is set (if no update has been done yet), and that can lead to
incorrect computations.

This happened in test TestUsers2.test_reified_groups in module 'base'.
The user groups view was apparently determined without the flag being
set, and the view depends on the recursive field 'trans_implied_ids',
which was not correctly computed.

We thus force developers to be explicit about recursive computed fields.
The code now logs a warning when the flag is not set up properly.
2021-05-03 12:33:29 +00:00
Adrian Torres ab7b5af3e8 [FIX] base: properly execute Selection field ondelete actions
With this commit, 2 changes are made to the way that the
fields.Selection.ondelete cleanup action works:

1) We manually delete ir.model.fields.selection **before** the deletion
of ir.model.fields purposefully to **avoid** SQL CASCADE deletes, as we
do not know which selections are deleted in cascade and thus we cannot
perform the corresponding ondelete cleanup action (which is implemented
within the ORM).

2) In some actions, namely 'set default' and 'set null', we write a
"safe" value to the records containing the Selection being deleted,
before this commit this would go through the ORM (records.write()) but
this is problematic if there's a write override for the record's model
that raises an error for the field being written to. With this commit,
we first try to go through the ORM but if there's a failure (because of
the raise in a write override) then we will bypass the ORM and set it
with SQL.

opw-2451126

closes odoo/odoo#67616

X-original-commit: f5c7e861ee3ca0cdeb6c2f06d227ada07f923ed0
Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
2021-03-11 06:45:42 +00:00
Raphael ColletandThibault Delavallée 65fd4373c5 [FIX] core: invoke constraint methods once per write
Consider a constraint method with two fields: a normal field, and a
field with an inverse method.  When calling write() with both fields,
the constraint method should be invoked once.

closes odoo/odoo#64433

X-original-commit: 25760348859f594abb796b5bc7b28f63e298cd53
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Co-authored-by: Thibault Delavallée <tde@odoo.com>
2021-01-12 15:59:10 +00:00
Raphael Collet 1e7659ad48 [FIX] core: avoid access error when flushing
This takes a former patch one step further.

Assume you recompute a field on two records, and the computation assigns
the first record but not the second one.  Before this patch, the
recomputation process was accessing the field on both records.  When
accessing the first record, both records are recomputed, and the value
of the first one is found in cache.  When accessing the second record,
no recomputation is made (it has been done already), and the cache is
empty. The field is thus fetched from database, and this crashes because
of insufficient access rights.

This scenario was causing some obscure nondeterministic crashes in
tests. The nondeterminism comes from the choice of the environment for
flushing (it should not be in superuser mode); the order of records in
the set to compute; the order in which records are assigned in the
compute method; the fact that the compute method should assign some
records and some not.

The fix consists in adding a method that processes pending computations,
without doing anything special for unassigned records.  The method is
used in field accessors (__get__ and mapped) and in method recompute().
The access error is gone because the recomputation no longer tries to
get the value of a field to compute.

closes odoo/odoo#64264

X-original-commit: b7676ec33172e6196b5fd1eda4df730ebf90eb6b
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-01-08 13:06:25 +00:00
Guewen BaconnierandRaphael Collet e14b52a56d [FIX] core: marking of stored computed recursive fields during creation
Fixes 3a6ac95 that ignores computation of recursive stored fields during
creation of records.

The problem happens when we have:

* a recursive stored computed field
* an `api.depends` of this field which is a relation to another record

When this "another record" is created and should recompute the recursive
field, it is ignored.

closes odoo/odoo#64117

X-original-commit: 9fe4fe404b73e9ab18ab6b3b913f075c64bb6954
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Co-authored-by: Raphael Collet (rco) <rco@openerp.com>
2021-01-05 19:09:16 +00:00
Raphael Collet 0a098aceaf [FIX] core: marking and traversing computed fields before modification
This fixes an issue that occurs when marking fields to compute in the
following situation:
 - it occurs before the actual modification,
 - a relational field is marked to compute,
 - the same field is traversed to inverse some dependency.

When the marking occurs after the modification, the traversal of the
field should actually recompute the field.  However, if the marking
occurs before the modification, the inversion of dependencies must be
based on the current value of the field.  This is the case with method
unlink(): we call method modified() to mark the fields that currently
depend on the records to be deleted, and the fields must be computed
only after the deletion!

X-original-commit: cd19c2d93db8911fe42802640ea32e5d87aadeec
2021-01-04 09:16:20 +00:00
svs-odoo 603d907450 [FIX] core: avoid duplicate onchanges
When performing the onchange for the first time on a new record, if a
field has a default value, it could be two times in the `todo` field
list to compute.

closes odoo/odoo#64005

X-original-commit: cf2b0a505c117a50a91fa022bc1d6bf1eb6d9f77
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2021-01-04 12:16:46 +00:00
Raphael Collet dcc2a7e39d [FIX] core: first onchange should always compute fields
When a form view is opened, the first call to `onchange` should always
compute fields, even if their dependencies have no default value.  Make
sure it is the case for main records, and for records inside one2many
fields.  The latter case was actually not working as expected.

closes odoo/odoo#63646

X-original-commit: 45422d56bce413b8577f1784e10dd22ede93c751
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-12-21 13:55:20 +00:00
Adrian Torres 1c8a958098 [IMP] core: introduce api.ondelete decorator
With this commit, a new ORM api decorator is introduced:
`api.ondelete(*, at_uninstall)`.

This decorator is to be applied to Model methods that check for specific
business conditions when attempting to unlink a record via the
interface.

E.g. trying to unlink a validated journal entry

This decorator allows this logic to exist outside the `BaseModel.unlink`
method and is automatically bypassed when in uninstall mode, this means
that during an uninstall any and all data related to a module can and
will be removed easily and cleanly while still being able to apply
business logic to manual deletion of records.

This feature opens the gates to solving a very big problem with
uninstalls: records and tables that remain in a database despite the
relevant module being uninstalled, because if an override to unlink
raises an error, the data will never be deleted from the database.

Henceforth, overrides of unlink shall solely be used for data-cleaning
purposes, i.e. deletion or modification of data that is related to the
one currently being deleted but cannot be automatically deleted because
there are no proper SQL relations.

In certain very specific, low-level scenarios an unlink may be
overridden to raise an error, but this should only be done if you know
what the fuck you're doing, most of the time you'll want to resort to
`@api.ondelete`.

Note that this new decorator includes a keyword-only, required argument
called `at_uninstall`, in most business cases this argument shall be
False as this argument dictates whether or not this method should be
executed in the `unlink` call during uninstall. It should only be set to
True if you are certain of all the implications which most likely means
that the records of the model in which this ondelete function is defined
will NOT be removed during uninstall, they will forever linger in the DB
until manual intervention, this in turn can mean a wide range of
undefined problems due to crap left on the database.

Following commits will replace any `unlink` overrides that raise
business errors by methods decorated with `api.ondelete`, another commit
will introduce a pylint checker that will raise a warning any time that
an unlink override raises an error.
2020-12-04 09:15:51 +00:00
Laurent Smet 6f2a6f7f2e [FIX] core: invalidation of computed editable field in one2many
This fixes the issue introduced by revision fd50ba9fb8

The way computed fields are invalidated depends on the order of the dict
passed as a parameter to method onchange().  This causes some unexpected
behavior when dealing with computed editable fields: the user loses the
value in that field because of the onchange.

Explanation: during the onchange, the modified field is cached by

    record._update_cache(changed_values, validate=True)

If the field is a one2many, 'value' contains an update command for each
modified line.  Because of 'validate=True', the assignment triggers
field computations on the lines, which are already handled by another
call to onchange().  In case anything on the parent model modifies some
line, the whole one2many values are returned to the user, and
accidentally recomputed fields show up in the interface.

closes odoo/odoo#62748

Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-12-02 15:36:51 +00:00
Julien Castiaux ca903577d2 [REF] test_*: Use Command helper for x2many
Task: 2366606
2020-11-30 10:16:09 +00:00
Xavier-Do 71549030c7 [FIX] core: cache consistency of one2many field with computed inverse
Consider a one2many field with a corresponding many2one field that is
computed.  After modifying the many2one field's dependencies, the cached
value of the one2many field is inconsistent until the many2one field has
been recomputed.  Therefore, one has to force the computation of the
many2one field before accessing the cached value of the one2many field.

closes odoo/odoo#59034

X-original-commit: b9201ebdd65eaabab9257cf97c58410681783fa6
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-10-02 17:20:10 +00:00
Raphael Collet f55fcbe15f [FIX] core: always evaluate field.depends upon setup
This is necessary when a field's dependencies are given by a callable.
This functionality was broken with the support for an explicit parameter
`depends` in the fields' definition, because the implementation could
not distinguish between the field parameter `depends` and the `depends`
evaluated from compute functions.

The fix consists in storing the field parameter `depends` into
`field._depends`, and the result of the setup into `field.depends`.

closes odoo/odoo#58144

X-original-commit: aebe9a76c9b35e84eda1f46bec3ef6da152b1539
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-09-21 14:04:25 +00:00
Raphael Collet 75ad1559ec [FIX] core: flush() domain returned by search method
Assume field B depends on A, and searching on B is rewritten as a domain
that mentions A.  If A is modified, and then we search on B, one has to
flush A to the database before searching.

closes odoo/odoo#57963

X-original-commit: b242b7b1382ee39ebefa58c556931b7dae77f669
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-09-17 14:33:44 +00:00
Raphael Collet 126ebbc905 [IMP] core: error message for computed field left unassigned
Non-stored readonly computed fields must be assigned by compute method.
Make the error message more explicit.

closes odoo/odoo#56269

Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-08-21 09:39:27 +00:00
Raphael Collet 3e91fa1dbf [FIX] core: first onchange on new one2many line
Consider models `M` and `L`, with a one2many field `M.l_ids` with
inverse `L.m_id`.  Consider also a computed field `L.foo` that depends
on `L.m_id`.

The field `L.foo` is not computed correctly by `onchange` on a new line
in the form view of `M`: its value is forced to `False` because it has
no default, and is not recomputed by `onchange` since the field `L.m_id`
is never triggered an `onchange`.

Modify the method `onchange` to not force fields without a default to
`False`, and return all fields.
2020-08-20 13:39:04 +00:00
Yannick Tivisse 62355b6ad3 [FIX] test_new_api: Fix bad shared cache usage for stored computed fields
Purpose
=======

Since the 13.0, a regression has been introduced in hr_timesheet.

Considering:
- The account.analytic.line model, representing a timesheet entry
- The project.task model, representing a task, on which we have the fields:
    - timesheet_ids: One2many
    - planned_hours: Computed (sudo), stored, representing the sum of the timesheet amounts
- An ir.rule restricting the timesheets CRUD to his own only.

A user can only see its own timesheets on a task, but the field "Planned Hours",
which is stored-compute_sudo, should take all the timesheet lines into account

However, when adding a new line and then recomputing the value, no existing line
from another user is binded on self, then the value is erased and saved on the
database.

Specification
=============

This commit introduces a test that illustrates that bad usage of a shared cache.

A correct way to fix this could be to avoid using the cache if an ir.rule is pointing
to the related model. That would force the recomputation in a real sudoed environment.

closes odoo/odoo#55408

Taskid: 2285924
X-original-commit: 50e229fe66b2a82717d4260287e18a875bbd26f5
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
2020-08-04 15:01:45 +00:00
Raphael Collet dd8a6b8a82 [ADD] test_new_api: tests on queries made by create with computed fields
closes odoo/odoo#54209

Related: odoo/upgrade#1464
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-07-08 11:58:33 +00:00
Raphael Collet b768cf7e8b [FIX] core: normalize domain from field.search()
When search is implemented on a given field, the domain returned by
`field.search()` must be normalized, otherwise its processing just
crashes (because of missing logic operators).

closes odoo/odoo#51927

X-original-commit: c83974ac5d797d38760a46c97468a74214218575
Signed-off-by: Xavier Dollé (xdo) <xdo@odoo.com>
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-05-26 16:37:15 +00:00
Raphael Collet 8d99fd9448 [FIX] core: selection override with str or callable
If the original field is defined with a selection list, overrides with
method or methods names fall back on the list.

closes odoo/odoo#51232

X-original-commit: 272ba8d2238d1d1b87f47b114b55e6eed25314a8
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-05-14 08:41:44 +00:00
Raphael Collet eb08e2c228 [FIX] core: unexpected cache invalidation when updating one2many
When setting a many2one field, the corresponding one2many fields are
updated in cache.  When such a one2many field has a domain, the
evaluation of the domain may require to fetch some fields from the
database.  If the `towrite` cache has not been updated yet, the many2one
field is overridden by the database value.

Fix by setting the `towrite` cache before updating inverse fields.

closes odoo/odoo#50788

X-original-commit: c1ebfe05a66cfebc7ced36e25db5f6ff4bfb2d46
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-05-06 19:25:17 +00:00
Raphael Collet e7b98b811c [FIX] fields: screwing up cache when rounding monetary value
Consider a sales order with a single line.  Edit the sales order: remove
the line, and add another line with the same subtotal.  When saving, the
total of the sales order is 0.0.

Here is the explanation: the form view performs a `write` on the sales
order, and modifies the lines with a command `2` (remove line) and a
command `0` (create line).

After deleting the first order line, the cache is emptied, and a call to
`flush()` forces the recomputation of the total.  The value is computed
to be 0, and assigned to the field.  The assignment converts the value
for the cache, without prefetching the currency field (optimization),
and puts 0.0 in cache.  The assignment then converts the value for the
database, which prefetches most fields on the sales order: the cache is
now inconsistent and contains the old value V, while the database is
then updated with 0.0.

After creating the new order line, the total is once again recomputed.
Its value is V, and because the cache also contains that value, no
update is performed to the database, which remains at 0.0!

The fix consists in avoiding the prefetching of fields when accessing
the currency field to round a monetary value.

opw-2223134

closes odoo/odoo#49741

X-original-commit: 048ea2f20a0a2fa6d629cbe262cbbe765248d36f
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-04-18 09:46:33 +00:00
Adrian Torres f0481392c6 [IMP] core: introduce mechanism for selection_add cleanup
- Let A and B be two different modules.
- A defines a required Selection field F of model M and B extends
  it through the `selection_add` argument.
- Create records of model M and have some of them have any of the
  options introduced by module B selected for field F.
- Uninstall module B.

The result will be records of Model M with an option for field F that no
longer exists, this makes the registry inconsistent and prone to
crashing (it is sufficient to access the form view of such a record to
trigger a crash).

This commit introduces a mechanism similar to the `ondelete` argument
found in Many2one fields, the argument name is the same but it's
different both in behaviour and in implementation.

The `ondelete` mechanism for Selection fields is enforced for **any**
Selection field with required set to `True`, this means that the
developer is required to set a cleanup behaviour for when their module
is uninstalled. For possible cleanup options, see fields.Selection's
docstring.

As far as implementation goes, everything is implemented in Python
unlike with Many2one fields where the behaviour is delegated to
PostgreSQL.

The `ondelete` setting will be processed during
`ir.model.fields.selection.unlink()` to ensure that the registry is left
in an appropriate state after module uninstall.
2020-03-30 13:42:04 +00:00
Thibault DelavalléeandRaphael Collet a1654e59b9 [FIX] core: computed fields can be copied if editable
Purpose of this commit is to let computed stored editable fields being
copied if their field class allows it.

Indeed the value of those fields is computed based on some triggers but
can also be updated manually by users.  When copying a record, it makes
sense to consider that this value is what the user expects and allow its
copy, if the original field allows it.  Either it was computed, and
copied value will be correct without having to call computation again
(well, provided all dependencies have been copied, too), or it was
updated and the copied value will be the one the user entered.

Without this fix, an edited field is not copied, and will be recomputed,
which may look like an inconsistent value.

Task ID 2209163

closes odoo/odoo#48383

X-original-commit: 4b274d3b4101fbae154a572cdf40d23838899773
Signed-off-by: Olivier Dony (odo) <odo@openerp.com>
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
2020-03-25 17:36:02 +00:00
Martin Trigaux b51129bd30 [FIX] base: proper unlink of abtract model
Context:
Since 7593b887df an entry of ir.model.fields.selection is created
for each entry in a selection field. This allow a more modular
approach of tagging entries with an external id and translating
selections in the module that defined the selection (and not the one
that defined the field)

Problem:
When removing a selection, every record that used this selection is
updated with a 'set null'.
This was also intented on abstract models that do not have a table.

To reproduce:

1. create two models:

class ModelA(models.Abstract):
  _name = 'abstract.a'
  select = fields.Selection([
    ('foo', 'Foo'),
    ('bar', 'Bar'),
  ])

class ModelB(models.Model):
   _name = 'model.b'
   _inherit = 'abstract.a'

2. update code and removes the key 'foo'
3. update the module
   -> error
   psycopg2.errors.UndefinedTable: relation "abstract_a" does not exist
   LINE 1: UPDATE "abstract_a" SET "select"=NULL WHERE "re...

When updating the values in db, only update on real models

closes odoo/odoo#48288

X-original-commit: 6b20a8241300ebfc185500eb64e210db755574a8
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
2020-03-24 20:53:36 +00:00
Raphael Collet fd50ba9fb8 [IMP] core: do not recompute stored field on new record
The use case is a cache miss of a stored field with compute on a new
record with origin.  The field should be computed only when explicitly
triggered, i.e., when a dependency has been modified.  Otherwise it
should be fetched from the origin record.

closes odoo/odoo#47353

Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-03-23 09:04:59 +00:00
Sébastien TheysandRaphael Collet 5d62e4954f [FIX] core: fix _flush_search() when _order depends on m2o
closes odoo/odoo#46365

X-original-commit: 604b6a22db8eddfb37f9be31d3826394e25bd86c
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
Co-authored-by: Raphael Collet <rco@odoo.com>
Co-authored-by: Sébastien Theys <seb@odoo.com>
2020-02-26 17:56:32 +00:00
Raphael Collet 9ce78bff5f [FIX] core: search on one2many fields with context
Consider an x2many field `foo_ids` with `context={'active_test': False}`
in its definition, and a comodel with an active field.  The value of the
field includes inactive records.

Now consider a search with a domain like `[('foo_ids.bar', op, value)]`.
The search should return all the records with corecords that satisfy the
domain `[('bar', op, value)]`, including inactive corecords, because the
field's context explicitly disables filtering on the active field.

closes odoo/odoo#43625

Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-01-21 09:31:58 +00:00
Yannick Tivisse 472ac63f1f [FIX] models.py: Fix check_company mechanism
Purpose
=======

If check company is set on a field and if the user has no access
right to the field value (example: address_id on an expense sheet
could be set to a private res.partner, on an onchange method when
setting the employee), then the check_company mechanism will
raise an AccessError when trying the validate the companies on
the different records.

Specification
=============

As we only wish to validate the new record values and not the
access rights, the validation could be done as a superuser to
avoid unecessary errors.

closes odoo/odoo#43240

Taskid: 2170006
X-original-commit: 37a9b6c63dcbc268013fbe1a890cf9390eb8e223
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
2020-01-14 08:26:05 +00:00
Raphael Collet 1639b614eb [FIX] fields: x2many field with 'active_test' in own context
Consider an x2many field with `context={'active_test': False}`.  The
value of that field should always contain inactive records, as the
field's own context overrides the context of the current record.

closes odoo/odoo#42824

X-original-commit: a2fc37adc179fb8bfc11251137334f0a43c58135
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2020-01-07 09:37:11 +00:00
Raphael Collet 2448ff2c8c [FIX] models: avoid neverending recomputation on missing records
Assume F and G are computed by the same method on a missing record R.
During recomputation of F on R, the compute method is called but fails
because R is missing.  Both fields are re-marked to compute (because
computation failed), then F is discarded (because R is missing).  Then
comes G's turn: G is accessed on R and the computation fails.  Both
fields are re-marked to compute (because computation failed), then G is
discarded (because R is missing).  Now F is marked again to compute: the
process never ends.

To avoid this situation, discard all fields to recompute on missing
records.

closes odoo/odoo#42234

X-original-commit: 78bf4dbaa1c4adfa1dac68a4d79b87800003ac05
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
2019-12-20 09:21:38 +00:00
Jorge Pinna PuissantandRaphaël Collet 578deee45d [FIX] fields: check if the inverse must change
Before this commit, when modifying a Many2one in a form view to add a
new record,  it will create the new record, and calculate the inverse
and write it in all the records of the list. This will call the write
method in all records even if they weren't changed.

Now, the inverse is set to be modified only if it's different from the
current value.

opw-2091842

closes odoo/odoo#40258

X-original-commit: 417cee7f0fdb7ed7eb424178efb656b967fa0a5e
Signed-off-by: Jorge Pinna Puissant (jpp) <jpp@odoo.com>
Co-authored-by: Raphaël Collet <rco@odoo.com>
2019-11-14 12:13:06 +00:00
Adrian Torres 3da477dfc5 [FIX] *: adapt code to comply with new ondelete policy
The ondelete policy must be explicitly set for m2o fields whose inverse
is a reflection model (ir.*)
2019-11-07 08:39:17 +00:00
Yannick Tivisse 4aa5ba35af [IMP] base/test_*: Adapt tests to work with/without demo data 2019-11-05 13:08:02 +01:00