File: test_automation.py

package info (click to toggle)
odoo 18.0.0%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 878,716 kB
  • sloc: javascript: 927,937; python: 685,670; xml: 388,524; sh: 1,033; sql: 415; makefile: 26
file content (200 lines) | stat: -rw-r--r-- 8,614 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo.addons.base.tests.common import TransactionCaseWithUserDemo
from odoo import Command

import odoo.tests


@odoo.tests.tagged('post_install', '-at_install')
class TestAutomation(TransactionCaseWithUserDemo):

    def test_01_on_create_or_write(self):
        """ Simple on_create with admin user """
        model = self.env.ref("base.model_res_partner")
        automation = self.env["base.automation"].create({
            "name": "Force Archived Contacts",
            "trigger": "on_create_or_write",
            "model_id": model.id,
            "trigger_field_ids": [(6, 0, [
                self.env.ref("base.field_res_partner__name").id,
                self.env.ref("base.field_res_partner__vat").id,
            ])],
        })

        # trg_field should only be set when trigger is 'on_stage_set' or 'on_tag_set'
        self.assertFalse(automation.trg_field_ref)
        self.assertFalse(automation.trg_field_ref_model_name)

        action = self.env["ir.actions.server"].create({
            "name": "Set Active To False",
            "base_automation_id": automation.id,
            "state": "object_write",
            "update_path": "active",
            "update_boolean_value": "false",
            "model_id": model.id,
        })
        automation.write({"action_server_ids": [Command.link(action.id)]})

        # verify the partner can be created and the action still runs
        bilbo = self.env["res.partner"].create({"name": "Bilbo Baggins"})
        self.assertFalse(bilbo.active)

        # verify the partner can be updated and the action still runs
        bilbo.active = True
        bilbo.name = "Bilbo"
        self.assertFalse(bilbo.active)

        # verify the "Base Action Rule: check and execute" frequency is updated correctly when a new action is created.
        self.env["base.automation"].create([
            {
                "name": "Bilbo time senstive reminder in a hurry",
                "trigger": "on_time",
                "model_id": self.env.ref("base.model_res_partner").id,
                "trigger_field_ids": [],
                "trg_date_range": -60,
                "trg_date_range_type": "minutes",
                "trg_date_id": self.env.ref("base.field_res_partner__write_date").id,
            },
            {
                "name": "Bilbo time senstive reminder late",
                "trigger": "on_time",
                "model_id": self.env.ref("base.model_res_partner").id,
                "trigger_field_ids": [],
                "trg_date_range": 60,
                "trg_date_range_type": "minutes",
                "trg_date_id": self.env.ref("base.field_res_partner__write_date").id,
            }
            ])

        cron = self.env.ref('base_automation.ir_cron_data_base_automation_check', raise_if_not_found=False)
        self.assertEqual(cron.interval_number, 6)
        self.assertEqual(cron.interval_type, "minutes")

    def test_02_on_create_or_write_restricted(self):
        """ on_create action with low portal user """
        model = self.env.ref("base.model_ir_filters")
        automation = self.env["base.automation"].create({
            "name": "Force Archived Filters",
            "trigger": "on_create_or_write",
            "model_id": model.id,
            "trigger_field_ids": [(6, 0, [self.env.ref("base.field_ir_filters__name").id])],
        })
        action = self.env["ir.actions.server"].create({
            "name": "Set Active To False",
            "base_automation_id": automation.id,
            "model_id": model.id,
            "state": "object_write",
            "update_path": "active",
            "update_boolean_value": "false",
        })
        action.flush_recordset()
        automation.write({"action_server_ids": [Command.link(action.id)]})
        # action cached was cached with admin, force CacheMiss
        automation.env.clear()

        self_portal = self.env["ir.filters"].with_user(self.user_demo.id)
        # verify the portal user can create ir.filters but can not read base.automation
        self.assertTrue(self_portal.env["ir.filters"].has_access("create"))
        self.assertFalse(self_portal.env["base.automation"].has_access("read"))

        # verify the filter can be created and the action still runs
        filters = self_portal.create({
            "name": "Where is Bilbo?",
            "domain": "[('name', 'ilike', 'bilbo')]",
            "model_id": "res.partner",
        })
        self.assertFalse(filters.active)

        # verify the filter can be updated and the action still runs
        filters.active = True
        filters.name = "Where is Bilbo Baggins?"
        self.assertFalse(filters.active)

    def test_03_on_change_restricted(self):
        """ on_create action with low portal user """
        model = self.env.ref("base.model_ir_filters")
        automation = self.env["base.automation"].create({
            "name": "Force Archived Filters",
            "trigger": "on_change",
            "model_id": model.id,
            "on_change_field_ids": [(6, 0, [self.env.ref("base.field_ir_filters__name").id])],
        })
        action = self.env["ir.actions.server"].create({
            "name": "Set Active To False",
            "base_automation_id": automation.id,
            "model_id": model.id,
            "state": "code",
            "code": """action = {'value': {'active': False}}""",
        })
        automation.write({"action_server_ids": [Command.link(action.id)]})
        # action cached was cached with admin, force CacheMiss
        automation.env.clear()

        self_portal = self.env["ir.filters"].with_user(self.user_demo.id)

        # simulate a onchange call on name
        result = self_portal.onchange({}, [], {"name": {}, "active": {}})
        self.assertEqual(result["value"]["active"], False)

    def test_04_on_create_or_write_differentiate(self):
        """
            The purpose is to differentiate create and empty write.
        """
        model = self.env.ref("base.model_res_partner")
        model_field_id = self.env['ir.model.fields'].search([('model', '=', model.model), ('name', '=', 'id')], limit=1)
        automation = self.env["base.automation"].create({
            "name": "Test automated action",
            "trigger": "on_create_or_write",
            "model_id": model.id,
            "trigger_field_ids": [Command.set([model_field_id.id])],
        })
        action = self.env["ir.actions.server"].create({
            "name": "Modify name",
            "base_automation_id": automation.id,
            "model_id": model.id,
            "state": "code",
            "code": "record.write({'name': 'Modified Name'})"
        })
        action.flush_recordset()
        automation.write({"action_server_ids": [Command.link(action.id)]})
        # action cached was cached with admin, force CacheMiss
        automation.env.clear()

        server_action = self.env["ir.actions.server"].create({
            "name": "Empty write",
            "model_id": model.id,
            "state": "code",
            "code": "record.write({})"
        })

        partner = self.env[model.model].create({'name': 'Test Name'})
        self.assertEqual(partner.name, 'Modified Name', 'The automatic action must be performed')
        partner.name = 'Reset Name'
        self.assertEqual(partner.name, 'Reset Name', 'The automatic action must not be performed')

        context = {
            'active_model': model.model,
            'active_id': partner.id,
        }
        server_action.with_context(context).run()
        self.assertEqual(partner.name, 'Reset Name', 'The automatic action must not be performed')

    def test_create_automation_rule_for_valid_model(self):
        """
        Automation rules cannot be created for models that have no fields.
        """
        model_field = self.env['base.automation']._fields['model_id']
        base_model = self.env['base']

        # Verify that the base model is abstract and has _auto set to False
        self.assertTrue(base_model._abstract, "The base model should be abstract")
        self.assertFalse(base_model._auto, "The base model should have _auto set to False")

        # check whether the field hase domain attribute
        self.assertTrue(model_field.domain)
        domain = model_field.domain

        allowed_models = self.env['ir.model'].search(domain)
        self.assertTrue(base_model._name not in allowed_models.mapped('model'), "The base model should not be in the allowed models")