[FIX] *: cache consistency
In module mail, invalidating 'message_ids' on a mail thread also invalidates its inverse field 'res_id' on messages. If you haven't flushed it before, your cache will be inconsistent, as shown by the test /mail:TestMailgateway.test_message_process_bounce_records_channel. In module purchase_stock, add depends on report.stock.quantity. This ensures that when the model is queried after changes in other models, the data on which the SQL view depends is flushed to the database before querying that model's table. closes odoo/odoo#66938 Related: odoo/enterprise#16722 Signed-off-by: Raphael Collet <rco@odoo.com> Co-authored-by: Vincent Schippefilt <vsc@odoo.com>
This commit is contained in:
co-authored by
Vincent Schippefilt
parent
9c3b9a4926
commit
eb67feb590
@@ -61,7 +61,7 @@ class TestAccountAccount(AccountTestInvoicingCommon):
|
||||
|
||||
# Set the account as reconcile and fully reconcile something.
|
||||
account.reconcile = True
|
||||
self.env['account.move.line'].invalidate_model()
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.assertRecordValues(move.line_ids, [
|
||||
{'reconciled': False, 'amount_residual': 100.0, 'amount_residual_currency': 200.0},
|
||||
@@ -77,7 +77,7 @@ class TestAccountAccount(AccountTestInvoicingCommon):
|
||||
# Set back to a not reconcile account and check the journal items.
|
||||
move.line_ids.remove_move_reconcile()
|
||||
account.reconcile = False
|
||||
self.env['account.move.line'].invalidate_model()
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.assertRecordValues(move.line_ids, [
|
||||
{'reconciled': False, 'amount_residual': 0.0, 'amount_residual_currency': 0.0},
|
||||
@@ -119,7 +119,7 @@ class TestAccountAccount(AccountTestInvoicingCommon):
|
||||
|
||||
# Set the account as reconcile and partially reconcile something.
|
||||
account.reconcile = True
|
||||
self.env['account.move.line'].invalidate_model()
|
||||
self.env.invalidate_all()
|
||||
|
||||
move.line_ids.filtered(lambda line: line.account_id == account).reconcile()
|
||||
|
||||
|
||||
@@ -15,6 +15,10 @@ class AlarmManager(models.AbstractModel):
|
||||
_description = 'Event Alarm Manager'
|
||||
|
||||
def _get_next_potential_limit_alarm(self, alarm_type, seconds=None, partners=None):
|
||||
# flush models before making queries
|
||||
for model_name in ('calendar.alarm', 'calendar.event', 'calendar.recurrence'):
|
||||
self.env[model_name].flush_model()
|
||||
|
||||
result = {}
|
||||
delta_request = """
|
||||
SELECT
|
||||
|
||||
@@ -161,6 +161,7 @@ class TestCalendar(SavepointCaseWithUserDemo):
|
||||
'stop_date': "2018-10-18",
|
||||
'allday': True,
|
||||
})
|
||||
self.env.invalidate_all()
|
||||
self.assertEqual(str(event.start), '2018-10-16 08:00:00')
|
||||
self.assertEqual(str(event.stop), '2018-10-18 18:00:00')
|
||||
|
||||
|
||||
@@ -191,6 +191,9 @@ class TestCRMPLS(TransactionCase):
|
||||
# rebuild frequencies table and recompute automated_probability for all leads.
|
||||
Lead._cron_update_automated_probabilities()
|
||||
|
||||
# As the cron is computing and writing in SQL queries, we need to invalidate the cache
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.assertEqual(tools.float_compare(leads[3].automated_probability, 33.49, 2), 0)
|
||||
self.assertEqual(tools.float_compare(leads[8].automated_probability, 7.74, 2), 0)
|
||||
lead_13_team_3_proba = leads[13].automated_probability
|
||||
@@ -403,6 +406,7 @@ class TestCRMPLS(TransactionCase):
|
||||
|
||||
# Force recompute - A priori, no need to do this as, for each won / lost, we increment tag frequency.
|
||||
Lead._cron_update_automated_probabilities()
|
||||
self.env.invalidate_all()
|
||||
|
||||
lead_tag_1 = leads_with_tags[30]
|
||||
lead_tag_2 = leads_with_tags[90]
|
||||
@@ -440,6 +444,7 @@ class TestCRMPLS(TransactionCase):
|
||||
leads.filtered(lambda lead: lead.id % 2 == 0).email_state = 'correct'
|
||||
leads.filtered(lambda lead: lead.id % 2 == 1).email_state = 'incorrect'
|
||||
Lead._cron_update_automated_probabilities()
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.assertEqual(tools.float_compare(leads[3].automated_probability, 4.21, 2), 0)
|
||||
self.assertEqual(tools.float_compare(leads[8].automated_probability, 0.23, 2), 0)
|
||||
@@ -447,6 +452,7 @@ class TestCRMPLS(TransactionCase):
|
||||
# remove all pls fields
|
||||
self.env['ir.config_parameter'].sudo().set_param("crm.pls_fields", False)
|
||||
Lead._cron_update_automated_probabilities()
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.assertEqual(tools.float_compare(leads[3].automated_probability, 34.38, 2), 0)
|
||||
self.assertEqual(tools.float_compare(leads[8].automated_probability, 50.0, 2), 0)
|
||||
@@ -454,6 +460,7 @@ class TestCRMPLS(TransactionCase):
|
||||
# check if the probabilities are the same with the old param
|
||||
self.env['ir.config_parameter'].sudo().set_param("crm.pls_fields", "country_id,state_id,email_state,phone_state,source_id")
|
||||
Lead._cron_update_automated_probabilities()
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.assertEqual(tools.float_compare(leads[3].automated_probability, 4.21, 2), 0)
|
||||
self.assertEqual(tools.float_compare(leads[8].automated_probability, 0.23, 2), 0)
|
||||
|
||||
@@ -45,10 +45,10 @@ class TestDeliveryCost(common.TransactionCase):
|
||||
# as the tests hereunder assume all the prices in USD, we must ensure
|
||||
# that the company actually uses USD
|
||||
# We do an invalidation so the cache is aware of it too.
|
||||
self.env.company.invalidate_recordset()
|
||||
self.env.cr.execute(
|
||||
"UPDATE res_company SET currency_id = %s WHERE id = %s",
|
||||
[self.env.ref('base.USD').id, self.env.company.id])
|
||||
self.env.company.invalidate_recordset()
|
||||
self.pricelist.currency_id = self.env.ref('base.USD').id
|
||||
|
||||
def test_00_delivery_cost(self):
|
||||
|
||||
@@ -181,10 +181,15 @@ class HrEmployeePrivate(models.Model):
|
||||
if self.check_access_rights('read', raise_exception=False):
|
||||
return super(HrEmployeePrivate, self)._read(fields)
|
||||
|
||||
res = self.env['hr.employee.public'].browse(self.ids).read(fields)
|
||||
for r in res:
|
||||
record = self.browse(r['id'])
|
||||
record._update_cache({k:v for k,v in r.items() if k in fields}, validate=False)
|
||||
# HACK: retrieve publicly available values from hr.employee.public and
|
||||
# copy them to the cache of self; non-public data will be missing from
|
||||
# cache, and interpreted as an access error
|
||||
self.flush_recordset(fields)
|
||||
public = self.env['hr.employee.public'].browse(self._ids)
|
||||
public._read(fields)
|
||||
for fname in fields:
|
||||
values = self.env.cache.get_values(public, public._fields[fname])
|
||||
self.env.cache.update(self, self._fields[fname], values)
|
||||
|
||||
@api.model
|
||||
def _cron_check_work_permit_validity(self):
|
||||
|
||||
@@ -158,17 +158,16 @@ class TestWorkEntryLeave(TestWorkEntryHolidaysBase):
|
||||
'date_to': datetime(2022, 3, 25, 20),
|
||||
'number_of_days': 4,
|
||||
})
|
||||
can_cancel_field = leave._fields['can_cancel']
|
||||
leave.with_user(SUPERUSER_ID).action_validate()
|
||||
# No work entries exist yet
|
||||
self.assertTrue(leave.can_cancel, "The leave should still be cancellable")
|
||||
# can not create in the future
|
||||
self.richard_emp.contract_ids._generate_work_entries(datetime(2022, 3, 21, 6), datetime(2022, 3, 25, 20))
|
||||
work_entries = self.env['hr.work.entry'].search([('employee_id', '=', self.richard_emp.id)])
|
||||
self.env.cache.invalidate([(can_cancel_field, leave.ids)])
|
||||
leave.invalidate_recordset(['can_cancel'])
|
||||
# Work entries exist but are not locked yet
|
||||
self.assertTrue(leave.can_cancel, "The leave should still be cancellable")
|
||||
work_entries.action_validate()
|
||||
self.env.cache.invalidate([(can_cancel_field, leave.ids)])
|
||||
leave.invalidate_recordset(['can_cancel'])
|
||||
# Work entries locked
|
||||
self.assertFalse(leave.can_cancel, "The leave should not be cancellable")
|
||||
|
||||
@@ -89,13 +89,18 @@ class TestEGEdiCommon(AccountEdiTestCommon):
|
||||
|
||||
@classmethod
|
||||
def create_invoice(cls, **kwargs):
|
||||
return (cls.env['account.move']
|
||||
.with_context(edi_test_mode=True)
|
||||
.create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'invoice_date': '2022-03-15',
|
||||
'date': '2022-03-15',
|
||||
**kwargs,
|
||||
'invoice_line_ids': [Command.create({**line_vals, }) for line_vals in kwargs.get('invoice_line_ids', [])]
|
||||
}))
|
||||
invoice = (
|
||||
cls.env['account.move']
|
||||
.with_context(edi_test_mode=True)
|
||||
.create({
|
||||
'move_type': 'out_invoice',
|
||||
'partner_id': cls.partner_a.id,
|
||||
'invoice_date': '2022-03-15',
|
||||
'date': '2022-03-15',
|
||||
**kwargs,
|
||||
'invoice_line_ids': [Command.create({**line_vals, }) for line_vals in kwargs.get('invoice_line_ids', [])]
|
||||
})
|
||||
)
|
||||
# this fixes rounding issues in cache
|
||||
cls.env.invalidate_all()
|
||||
return invoice
|
||||
|
||||
@@ -1093,6 +1093,7 @@ class Message(models.Model):
|
||||
def _invalidate_documents(self, model=None, res_id=None):
|
||||
""" Invalidate the cache of the documents followed by ``self``. """
|
||||
fnames = ['message_ids', 'message_needaction', 'message_needaction_counter']
|
||||
self.flush_recordset(['model', 'res_id'])
|
||||
for record in self:
|
||||
model = model or record.model
|
||||
res_id = res_id or record.res_id
|
||||
|
||||
@@ -357,7 +357,7 @@ class TestSubcontractingFlows(TestMrpSubcontractingCommon):
|
||||
'parent_id': main_partner_2.id,
|
||||
'company_id': self.env.ref('base.main_company').id,
|
||||
})
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
|
||||
# We create a different BoM for the same product
|
||||
comp3 = self.env['product.product'].create({
|
||||
|
||||
@@ -33,6 +33,9 @@ class TestProjectReport(TestProjectCommon):
|
||||
self.assertEqual(task_3.rating_avg, 0)
|
||||
self.assertEqual(task_3.rating_last_value, 0)
|
||||
|
||||
# fix cache consistency
|
||||
self.env['project.task'].invalidate_model(['rating_avg', 'rating_last_value'])
|
||||
|
||||
tasks = [self.task_1, self.task_2, task_3]
|
||||
for task in tasks:
|
||||
rating_values = task.read(['rating_avg', 'rating_last_value'])[0]
|
||||
|
||||
@@ -638,6 +638,7 @@ class PurchaseOrder(models.Model):
|
||||
# Invoice_ids may be filtered depending on the user. To ensure we get all
|
||||
# invoices related to the purchase order, we read them in sudo to fill the
|
||||
# cache.
|
||||
self.invalidate_model(['invoice_ids'])
|
||||
self.sudo()._read(['invoice_ids'])
|
||||
invoices = self.invoice_ids
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ class TestReorderingRule(TransactionCase):
|
||||
"route_ids": [],
|
||||
}
|
||||
)
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
|
||||
self.env["procurement.group"].run([procurement])
|
||||
|
||||
@@ -707,10 +707,11 @@ class TestReorderingRule(TransactionCase):
|
||||
{'qty_forecast': -1, 'qty_to_order': 1},
|
||||
])
|
||||
|
||||
delivery.scheduled_date += td(days=7)
|
||||
# invalidate the fields that will eventually be inconsistent
|
||||
orderpoint.invalidate_model(fnames=['qty_forecast', 'qty_to_order'])
|
||||
orderpoint.product_id.invalidate_model(fnames=['virtual_available'])
|
||||
|
||||
delivery.scheduled_date += td(days=7)
|
||||
self.assertRecordValues(orderpoint, [
|
||||
{'qty_forecast': 0, 'qty_to_order': 0},
|
||||
])
|
||||
|
||||
@@ -176,6 +176,7 @@ class TestSaleOrder(TestSaleCommon):
|
||||
|
||||
# upsell and invoice
|
||||
self.sol_serv_order.write({'product_uom_qty': 10})
|
||||
|
||||
# There is a bug with `new` and `_origin`
|
||||
# If you create a first new from a record, then change a value on the origin record, than create another new,
|
||||
# this other new wont have the updated value of the origin record, but the one from the previous new
|
||||
@@ -184,10 +185,7 @@ class TestSaleOrder(TestSaleCommon):
|
||||
# Here, we update `qty_delivered` on the origin record, but the `new` records which are in cache with this order line
|
||||
# as origin are not updated, nor the fields that depends on it.
|
||||
self.env.flush_all()
|
||||
for field in self.env['sale.order.line']._fields.values():
|
||||
for res_id in list(self.env.cache._data[field]):
|
||||
if not res_id:
|
||||
self.env.cache._data[field].pop(res_id)
|
||||
self.env.invalidate_all()
|
||||
|
||||
invoice3 = self.sale_order._create_invoices()
|
||||
self.assertEqual(len(invoice3.invoice_line_ids), 1, 'Sale: third invoice is missing lines')
|
||||
|
||||
@@ -269,8 +269,6 @@ class TestProgramRules(TestSaleCouponCommon):
|
||||
})
|
||||
]})
|
||||
# Invalidate total_order_count
|
||||
field_order_count = self.env['loyalty.program']._fields['order_count']
|
||||
field_total_order_count = self.env['loyalty.program']._fields['total_order_count']
|
||||
self.env.cache.invalidate([(field_order_count, self.immediate_promotion_program.ids), (field_total_order_count, self.immediate_promotion_program.ids)])
|
||||
self.immediate_promotion_program.invalidate_recordset(['order_count', 'total_order_count'])
|
||||
self._auto_rewards(order, self.immediate_promotion_program)
|
||||
self.assertEqual(len(order.order_line.ids), 2, "The promo offer shouldn't have been applied as the number of uses is exceeded")
|
||||
|
||||
@@ -93,6 +93,7 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
self.assertEqual(del_qties, del_qties_truth, 'Sale Stock: delivered quantities are wrong after complete delivery')
|
||||
# Without timesheet, we manually set the delivered qty for the product serv_del
|
||||
self.so.order_line.sorted()[1]['qty_delivered'] = 2.0
|
||||
|
||||
# There is a bug with `new` and `_origin`
|
||||
# If you create a first new from a record, then change a value on the origin record, than create another new,
|
||||
# this other new wont have the updated value of the origin record, but the one from the previous new
|
||||
@@ -101,10 +102,8 @@ class TestSaleStock(TestSaleCommon, ValuationReconciliationTestCommon):
|
||||
# Here, we update `qty_delivered` on the origin record, but the `new` records which are in cache with this order line
|
||||
# as origin are not updated, nor the fields that depends on it.
|
||||
self.env.flush_all()
|
||||
for field in self.env['sale.order.line']._fields.values():
|
||||
for res_id in list(self.env.cache._data[field]):
|
||||
if not res_id:
|
||||
self.env.cache._data[field].pop(res_id)
|
||||
self.env.invalidate_all()
|
||||
|
||||
inv_id = self.so._create_invoices()
|
||||
self.assertEqual(self.so.invoice_status, 'invoiced',
|
||||
'Sale Stock: so invoice_status should be "fully invoiced" after complete delivery and invoicing')
|
||||
|
||||
@@ -9,6 +9,15 @@ class ReportStockQuantity(models.Model):
|
||||
_auto = False
|
||||
_description = 'Stock Quantity Report'
|
||||
|
||||
_depends = {
|
||||
'product.product': ['product_tmpl_id'],
|
||||
'product.template': ['type'],
|
||||
'stock.location': ['parent_path'],
|
||||
'stock.move': ['company_id', 'date', 'location_dest_id', 'location_id', 'product_id', 'product_qty', 'state'],
|
||||
'stock.quant': ['company_id', 'location_id', 'product_id', 'quantity'],
|
||||
'stock.warehouse': ['view_location_id'],
|
||||
}
|
||||
|
||||
date = fields.Date(string='Date', readonly=True)
|
||||
product_tmpl_id = fields.Many2one('product.template', readonly=True)
|
||||
product_id = fields.Many2one('product.product', string='Product', readonly=True)
|
||||
|
||||
@@ -774,7 +774,7 @@ class TestCowViewSaving(TestViewSavingCommon):
|
||||
'arch': '<div position="replace"><p>COMPARE</p></div>',
|
||||
'key': '_website_sale_comparison.product_add_to_compare',
|
||||
})])
|
||||
Website.with_context(load_all_views=True).viewref('_website_sale_comparison.product_add_to_compare').invalidate_model()
|
||||
View.invalidate_model()
|
||||
|
||||
# Simulate end of installation/update
|
||||
View._create_all_specific_views(['_website_sale_comparison'])
|
||||
|
||||
@@ -1346,11 +1346,13 @@ class IrModelSelection(models.Model):
|
||||
if selection.value == vals['value']:
|
||||
continue
|
||||
if selection.field_id.store:
|
||||
# in order to keep the cache consistent, flush the
|
||||
# corresponding field, and invalidate it from cache
|
||||
model = self.env[selection.field_id.model]
|
||||
fname = selection.field_id.name
|
||||
model.invalidate_model([fname])
|
||||
# replace the value by the new one in the field's corresponding column
|
||||
query = 'UPDATE "{table}" SET "{field}"=%s WHERE "{field}"=%s'.format(
|
||||
table=self.env[selection.field_id.model]._table,
|
||||
field=selection.field_id.name,
|
||||
)
|
||||
query = f'UPDATE "{model._table}" SET "{fname}"=%s WHERE "{fname}"=%s'
|
||||
self.env.cr.execute(query, [vals['value'], selection.value])
|
||||
|
||||
result = super().write(vals)
|
||||
@@ -1655,6 +1657,7 @@ class IrModelRelation(models.Model):
|
||||
""" Reflect the table of a many2many field for the given model, to make
|
||||
it possible to delete it later when the module is uninstalled.
|
||||
"""
|
||||
self.env.invalidate_all()
|
||||
cr = self._cr
|
||||
query = """ SELECT 1 FROM ir_model_relation r, ir_module_module m
|
||||
WHERE r.module=m.id AND r.name=%s AND m.name=%s """
|
||||
@@ -1669,7 +1672,6 @@ class IrModelRelation(models.Model):
|
||||
(SELECT id FROM ir_module_module WHERE name=%s),
|
||||
(SELECT id FROM ir_model WHERE model=%s)) """
|
||||
cr.execute(query, (table, self.env.uid, self.env.uid, module, model._name))
|
||||
self.env.invalidate_all()
|
||||
|
||||
|
||||
class IrModelAccess(models.Model):
|
||||
|
||||
@@ -233,8 +233,7 @@ class IrRule(models.Model):
|
||||
failing_rules += "\n\n" + _('Note: this might be a multi-company issue.')
|
||||
|
||||
# clean up the cache of records prefetched with display_name above
|
||||
for record in records[:6]:
|
||||
record._cache.clear()
|
||||
records_sudo.invalidate_recordset()
|
||||
|
||||
msg = f"{operation_error}\n\n{failing_records}\n{failing_user}\n\n{failing_rules}\n\n{resolution_info}"
|
||||
return AccessError(msg)
|
||||
|
||||
@@ -112,7 +112,8 @@ class MergePartnerAutomatic(models.TransientModel):
|
||||
Partner = self.env['res.partner']
|
||||
relations = self._get_fk_on('res_partner')
|
||||
|
||||
self.env.flush_all()
|
||||
# this guarantees cache consistency
|
||||
self.env.invalidate_all()
|
||||
|
||||
for table, column in relations:
|
||||
if 'base_partner_merge_' in table: # ignore two tables
|
||||
@@ -175,8 +176,6 @@ class MergePartnerAutomatic(models.TransientModel):
|
||||
query = 'DELETE FROM "%(table)s" WHERE "%(column)s" IN %%s' % query_dic
|
||||
self._cr.execute(query, (tuple(src_partners.ids),))
|
||||
|
||||
self.env.invalidate_all()
|
||||
|
||||
@api.model
|
||||
def _update_reference_fields(self, src_partners, dst_partner):
|
||||
""" Update all reference fields from the src_partner to dst_partner.
|
||||
|
||||
@@ -935,9 +935,8 @@ class Attachment(models.Model):
|
||||
return
|
||||
comodel = self.env[self.res_model]
|
||||
if 'res_id' in fnames and 'attachment_ids' in comodel:
|
||||
field = comodel._fields['attachment_ids']
|
||||
record = comodel.browse(self.res_id)
|
||||
self.env.cache.invalidate([(field, record._ids)])
|
||||
record.invalidate_recordset(['attachment_ids'])
|
||||
record.modified(['attachment_ids'])
|
||||
return super(Attachment, self).modified(fnames, *args, **kwargs)
|
||||
|
||||
|
||||
@@ -244,6 +244,7 @@ class TestFields(TransactionCaseWithUserDemo):
|
||||
(0, 0, {'name': 'x_stuff_id', 'ttype': 'many2one', 'relation': 'ir.model'}),
|
||||
],
|
||||
})
|
||||
self.env.invalidate_all()
|
||||
# set 'x_stuff_id' refer to a model not loaded yet
|
||||
self.cr.execute("""
|
||||
UPDATE ir_model_fields
|
||||
@@ -791,7 +792,6 @@ class TestFields(TransactionCaseWithUserDemo):
|
||||
|
||||
# switch to environment with user demo
|
||||
records = records.with_user(self.user_demo)
|
||||
records.env.cache.invalidate()
|
||||
|
||||
# check that records are not accessible
|
||||
with self.assertRaises(AccessError):
|
||||
@@ -1611,7 +1611,7 @@ class TestFields(TransactionCaseWithUserDemo):
|
||||
""" test field access on new records vs real records. """
|
||||
Model = self.env['test_new_api.category']
|
||||
real_record = Model.create({'name': 'Foo'})
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
new_origin = Model.new({'name': 'Bar'}, origin=real_record)
|
||||
new_record = Model.new({'name': 'Baz'})
|
||||
|
||||
@@ -2080,6 +2080,7 @@ class TestFields(TransactionCaseWithUserDemo):
|
||||
self.assertEqual(demo_discussion.messages, discussion.messages)
|
||||
|
||||
# See YTI FIXME
|
||||
self.env.flush_all()
|
||||
self.env.invalidate_all()
|
||||
|
||||
# add a message as user demo
|
||||
@@ -2744,12 +2745,12 @@ class TestX2many(common.TransactionCase):
|
||||
self.assertEqual(parent.with_context(active_test=False).active_children_ids, act_children)
|
||||
|
||||
# check read()
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
self.assertEqual(parent.children_ids, act_children)
|
||||
self.assertEqual(parent.all_children_ids, all_children)
|
||||
self.assertEqual(parent.active_children_ids, act_children)
|
||||
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
self.assertEqual(parent.with_context(active_test=False).children_ids, all_children)
|
||||
self.assertEqual(parent.with_context(active_test=False).all_children_ids, all_children)
|
||||
self.assertEqual(parent.with_context(active_test=False).active_children_ids, act_children)
|
||||
|
||||
@@ -49,7 +49,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'author': USER.id,
|
||||
'size': 0,
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = self.Message.onchange(values, 'discussion', field_onchange)
|
||||
self.assertIn('name', result['value'])
|
||||
self.assertEqual(result['value']['name'], "[%s] %s" % (discussion.name, USER.name))
|
||||
@@ -62,7 +62,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'author': USER.id,
|
||||
'size': 0,
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = self.Message.onchange(values, 'body', field_onchange)
|
||||
self.assertIn('size', result['value'])
|
||||
self.assertEqual(result['value']['size'], len(BODY))
|
||||
@@ -76,7 +76,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'author': USER.id,
|
||||
'size': 0,
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = self.Message.onchange(values, 'body', field_onchange)
|
||||
self.assertNotIn('name', result['value'])
|
||||
|
||||
@@ -94,7 +94,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'root_categ': False,
|
||||
}
|
||||
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = Category.onchange(values, 'parent', field_onchange).get('value', {})
|
||||
self.assertIn('root_categ', result)
|
||||
self.assertEqual(result['root_categ'], root.name_get()[0])
|
||||
@@ -102,7 +102,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
values.update(result)
|
||||
values['parent'] = False
|
||||
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = Category.onchange(values, 'parent', field_onchange).get('value', {})
|
||||
self.assertIn('root_categ', result)
|
||||
self.assertIs(result['root_categ'], False)
|
||||
@@ -143,7 +143,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
}),
|
||||
],
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = self.Discussion.onchange(values, 'name', field_onchange)
|
||||
self.assertIn('messages', result['value'])
|
||||
self.assertEqual(result['value']['messages'], [
|
||||
@@ -214,7 +214,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
}),
|
||||
],
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = self.Discussion.onchange(values, 'name', field_onchange)
|
||||
self.assertIn('messages', result['value'])
|
||||
self.assertItemsEqual(result['value']['messages'], [
|
||||
@@ -263,7 +263,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'lines': [Command.set([line1.id]),
|
||||
Command.create({'name': False, 'partner': False, 'tags': [Command.clear()]})],
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
|
||||
result = multi.onchange(values, 'partner', field_onchange)
|
||||
self.assertEqual(result['value'], {
|
||||
@@ -292,7 +292,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'partner': False,
|
||||
'tags': [Command.clear(), Command.create({'name': 'Tag'})]})],
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = multi.onchange(values, 'partner', field_onchange)
|
||||
expected_value = {
|
||||
'name': partner2.name,
|
||||
@@ -313,13 +313,13 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
self.assertEqual(result['value'], expected_value)
|
||||
|
||||
# ensure ID is not returned when asked and a many2many record is set to be created
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
|
||||
result = multi.onchange(values, 'partner', dict(field_onchange, **{'lines.tags.id': None}))
|
||||
self.assertEqual(result['value'], expected_value)
|
||||
|
||||
# ensure inverse of one2many field is not returned
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
|
||||
result = multi.onchange(values, 'partner', dict(field_onchange, **{'lines.multi': None}))
|
||||
self.assertEqual(result['value'], expected_value)
|
||||
@@ -348,7 +348,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'messages': [Command.link(msg.id) for msg in discussion.messages],
|
||||
'participants': [Command.link(usr.id) for usr in discussion.participants],
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = discussion.onchange(values, 'moderator', field_onchange)
|
||||
|
||||
self.assertIn('participants', result['value'])
|
||||
@@ -368,13 +368,13 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
self.env['ir.default'].set('test_new_api.foo', 'value2', 666, condition='value1=42')
|
||||
|
||||
# setting 'value1' to 42 should trigger the change of 'value2'
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
values = {'name': 'X', 'value1': 42, 'value2': False}
|
||||
result = Foo.onchange(values, 'value1', field_onchange)
|
||||
self.assertEqual(result['value'], {'value2': 666})
|
||||
|
||||
# setting 'value1' to 24 should not trigger the change of 'value2'
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
values = {'name': 'X', 'value1': 24, 'value2': False}
|
||||
result = Foo.onchange(values, 'value1', field_onchange)
|
||||
self.assertEqual(result['value'], {})
|
||||
@@ -442,7 +442,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
})
|
||||
|
||||
# check if server-side cache is working correctly
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
self.assertIn(email, discussion.emails)
|
||||
self.assertNotIn(email, discussion.important_emails)
|
||||
email.important = True
|
||||
@@ -451,7 +451,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
# check that when trigger an onchange, we don't reset important emails
|
||||
# (force `invalidate` as but appear in onchange only when we get a cache
|
||||
# miss)
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
self.assertEqual(len(discussion.messages), 4)
|
||||
values = {
|
||||
'name': "Foo Bar",
|
||||
@@ -462,7 +462,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'important_messages': [Command.link(msg.id) for msg in discussion.important_messages],
|
||||
'important_emails': [Command.link(eml.id) for eml in discussion.important_emails],
|
||||
}
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
result = discussion.onchange(values, 'name', field_onchange)
|
||||
|
||||
self.assertEqual(
|
||||
@@ -494,13 +494,13 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
'message_currency': self.env.user.name_get()[0],
|
||||
}
|
||||
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
Message = self.env['test_new_api.related']
|
||||
result = Message.onchange(value, 'message', field_onchange)
|
||||
|
||||
self.assertEqual(result['value'], onchange_result)
|
||||
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
Message = self.env(user=self.user_demo.id)['test_new_api.related']
|
||||
result = Message.onchange(value, 'message', field_onchange)
|
||||
|
||||
@@ -530,7 +530,7 @@ class TestOnChange(SavepointCaseWithUserDemo):
|
||||
|
||||
# changing 'discussion' on message should not read 'messages' on discussion
|
||||
with patch.object(type(discussion), 'read', mock_read, create=True):
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
self.Message.onchange(values, 'discussion', field_onchange)
|
||||
|
||||
self.assertFalse(called[0], "discussion.messages has been read")
|
||||
|
||||
@@ -66,7 +66,7 @@ class TestTermCount(common.TransactionCase):
|
||||
odoo.tools.trans_load(self.cr, 'test_translation_import/i18n/fr.po', 'fr_FR', verbose=False, overwrite=True)
|
||||
|
||||
# trans_load invalidates ormcache but not record cache
|
||||
menu.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
self.assertEqual(menu.name, "New Name")
|
||||
self.assertEqual(menu.with_context(lang='fr_FR').name, "Nouveau nom")
|
||||
|
||||
|
||||
@@ -1734,7 +1734,7 @@ def users(*logins):
|
||||
func(*args, **kwargs)
|
||||
# Invalidate the cache between subtests, in order to not reuse
|
||||
# the former user's cache (`test_read_mail`, `test_write_mail`)
|
||||
self.env.cache.invalidate()
|
||||
self.env.invalidate_all()
|
||||
finally:
|
||||
self.uid = old_uid
|
||||
|
||||
|
||||
Reference in New Issue
Block a user