19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:30:27 +01:00
parent d1963a3c3a
commit 2d3ee4855a
7430 changed files with 2687981 additions and 2965473 deletions

View file

@ -1,7 +1,15 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import unittest
from psycopg2 import IntegrityError
from odoo import Command
from odoo.addons.mail.tests.common import mail_new_test_user
from odoo.addons.onboarding.tests.common import TestOnboardingCommon
from odoo.exceptions import ValidationError
from odoo.tools import mute_logger
class TestOnboarding(TestOnboardingCommon):
@ -12,7 +20,8 @@ class TestOnboarding(TestOnboardingCommon):
self.onboarding_1.current_progress_id._get_and_update_onboarding_state(),
{self.onboarding_1_step_1.id: 'not_done', self.onboarding_1_step_2.id: 'not_done'})
self.onboarding_1_step_1.action_set_just_done()
self.assertEqual(self.onboarding_1_step_1.action_set_just_done(), self.onboarding_1_step_1,
"The onboarding step just validated should have been returned.")
# Test completed step state consolidation from `just_done` to `done`
self.assertDictEqual(
self.onboarding_1.current_progress_id._get_and_update_onboarding_state(),
@ -21,6 +30,8 @@ class TestOnboarding(TestOnboardingCommon):
self.onboarding_1.current_progress_id._get_and_update_onboarding_state(),
{self.onboarding_1_step_1.id: 'done', self.onboarding_1_step_2.id: 'not_done'})
self.assert_step_is_done(self.onboarding_1_step_1, self.company_2)
self.assertFalse(self.onboarding_1_step_1.action_set_just_done(),
"The onboarding step already validated should not have been returned.")
self.assert_onboarding_is_not_done(self.onboarding_1, self.company_2)
self.onboarding_1_step_2.action_set_just_done()
@ -42,7 +53,8 @@ class TestOnboarding(TestOnboardingCommon):
# Adding new step resets onboarding state to 'not_done' even if closed
onboarding_1_step_3 = self.env['onboarding.onboarding.step'].create({
'title': 'Test Onboarding 1 - Step 3',
'onboarding_id': self.onboarding_1.id,
'onboarding_ids': [self.onboarding_1.id],
'is_per_company': False,
'panel_step_open_action_name': 'action_fake_open_onboarding_step',
})
self.assert_step_is_not_done(onboarding_1_step_3)
@ -62,7 +74,8 @@ class TestOnboarding(TestOnboardingCommon):
# Adding new step resets onboarding state to 'not_done'
self.env['onboarding.onboarding.step'].create({
'title': 'Test Onboarding 1 - Step 4',
'onboarding_id': self.onboarding_1.id,
'onboarding_ids': [self.onboarding_1.id],
'is_per_company': False,
'panel_step_open_action_name': 'action_fake_open_onboarding_step',
})
@ -79,14 +92,16 @@ class TestOnboarding(TestOnboardingCommon):
# Completing onboarding as company_1
self.assertEqual(self.env.company, self.company_1)
# Updating onboarding to per-company
self.onboarding_1.is_per_company = True
# Updating onboarding (and steps) to per-company
self.onboarding_1_step_1.is_per_company = True
# Required after progress reset (simulate role of controller)
self.onboarding_1._search_or_create_progress()
self.onboarding_1_step_1.action_set_just_done()
self.assert_step_is_done(self.onboarding_1_step_1)
self.assertFalse(self.onboarding_1_step_2.is_per_company)
self.onboarding_1_step_2.action_set_just_done()
self.assert_onboarding_is_done(self.onboarding_1)
@ -95,19 +110,14 @@ class TestOnboarding(TestOnboardingCommon):
# First access from company_2
self.onboarding_1._search_or_create_progress()
# Blank state for company 2
# Blank state for company 2 for step 1
self.assert_step_is_not_done(self.onboarding_1_step_1)
# But step 2 is done
self.assert_step_is_done(self.onboarding_1_step_2)
self.assert_onboarding_is_not_done(self.onboarding_1)
# But no change for company 1
self.assert_step_is_done(self.onboarding_1_step_1.with_company(self.company_1))
self.assert_onboarding_is_done(self.onboarding_1.with_company(self.company_1))
self.onboarding_1_step_1.action_set_just_done()
self.assert_step_is_done(self.onboarding_1_step_1)
self.assert_onboarding_is_not_done(self.onboarding_1)
self.onboarding_1_step_2.with_company(self.company_2).action_set_just_done()
self.assert_step_is_done(self.onboarding_1_step_2)
self.assert_onboarding_is_done(self.onboarding_1)
# is_onboarding_closed status is also company-independent
@ -116,51 +126,113 @@ class TestOnboarding(TestOnboardingCommon):
self.assertFalse(self.onboarding_1.with_company(self.company_1).current_progress_id.is_onboarding_closed)
def test_onboarding_to_company_change(self):
"""Checks that changing onboarding to per-company resets completions states.
"""
""" Checks that changing an onboarding step to per-company resets
completion states."""
# Completing onboarding as company_1
self.assertEqual(self.env.company, self.company_1)
self.onboarding_1_step_1.action_set_just_done()
self.onboarding_1_step_2.action_set_just_done()
self.assert_onboarding_is_done(self.onboarding_1)
# Updating onboarding to per-company
self.onboarding_1.is_per_company = True
# Updating onboarding step 1 to per-company
self.onboarding_1_step_1.is_per_company = True
self.assertTrue(self.onboarding_1.is_per_company)
# Required after progress reset (simulate role of controller)
self.onboarding_1._search_or_create_progress()
self.assert_onboarding_is_not_done(self.onboarding_1)
def test_no_crash_on_multiple_progress_records(self):
existing_progress = self.env['onboarding.progress'].search([
('onboarding_id', '=', self.onboarding_1.id), ('company_id', '=', False)
])
self.assertEqual(len(existing_progress), 1)
def test_onboarding_shared_steps(self):
self.onboarding_2_step_2.action_set_just_done()
self.assert_step_is_done(self.onboarding_2_step_2)
# Completing common step is also required to be "done"
self.assert_onboarding_is_not_done(self.onboarding_2)
extra_progress = self.env['onboarding.progress'].create({
'onboarding_id': self.onboarding_1.id,
'company_id': False
})
self.env['onboarding.progress.step'].create([{
'step_id': self.onboarding_1_step_1.id,
'progress_id': progress.id
} for progress in (existing_progress, extra_progress)
])
nb_progress = self.env['onboarding.progress'].search([
('onboarding_id', '=', self.onboarding_1.id), ('company_id', '=', False)], count=True)
nb_progress_steps = self.env['onboarding.progress.step'].search([
('step_id', '=', self.onboarding_1_step_1.id)], count=True)
# Even though multiple onboarding progress (& steps) records exist
self.assertEqual(nb_progress, 2)
self.assertEqual(nb_progress_steps, 2)
# no error is raised, and so we can interact
_ = self.onboarding_1_step_1.current_progress_step_id
self.onboarding_1_step_1.action_set_just_done()
self.assert_onboarding_is_not_done(self.onboarding_1)
self.assert_onboarding_is_done(self.onboarding_2)
# Same with onboarding progress
_ = self.onboarding_1.current_progress_id
self.onboarding_1.action_close()
@mute_logger('odoo.sql_db')
def test_progress_no_company_uniqueness(self):
"""Check that there cannot be two progress records created for
the same onboarding when it is configured to be completed only
once for the whole db and not per-company (is_per_company=False).
NB: Postgresql UNIQUE constraint failures raise IntegrityErrors.
"""
self.assertFalse(self.onboarding_1.current_progress_id.company_id)
with self.assertRaises(IntegrityError):
self.env['onboarding.progress'].create({
'onboarding_id': self.onboarding_1.id,
'company_id': False
})
@mute_logger('odoo.sql_db')
def test_progress_per_company_uniqueness(self):
"""Check that there cannot be two progress records created for
the same company and the same onboarding when the onboarding is
configured to be completed per-company.
See also ``test_progress_no_company_uniqueness``
"""
# Updating onboarding to per-company
self.onboarding_1_step_1.is_per_company = True
# Create an onboarding_progress (simulate role of controller)
self.onboarding_1._search_or_create_progress()
with self.assertRaises(IntegrityError):
self.env['onboarding.progress'].create({
'onboarding_id': self.onboarding_1.id,
'company_id': self.env.company.id
})
def test_onboarding_step_without_onboarding(self):
self.step_initially_w_o_onboarding = self.env['onboarding.onboarding.step'].create({
'title': 'Step Initially Without Onboarding',
})
self.assertEqual(self.step_initially_w_o_onboarding.current_step_state, 'not_done')
self.step_initially_w_o_onboarding.action_set_just_done()
self.assert_step_is_done(self.step_initially_w_o_onboarding)
self.onboarding_3 = self.env['onboarding.onboarding'].create({
'name': 'Test Onboarding 3',
'route_name': 'onboarding3',
})
self.onboarding_3._search_or_create_progress()
with self.assertRaises(ValidationError):
self.step_initially_w_o_onboarding.onboarding_ids = [Command.link(self.onboarding_3.id)]
self.step_initially_w_o_onboarding.write({
'panel_step_open_action_name': 'action_fake_open_onboarding_step'
})
self.step_initially_w_o_onboarding.onboarding_ids = [Command.link(self.onboarding_3.id)]
with self.subTest('Progress records are recreated for companies with completed steps'):
# Onboarding is done as only step was already done by company 1
self.assert_onboarding_is_done(self.onboarding_3)
# Not by company 2
self.onboarding_3.with_company(self.company_2)._search_or_create_progress()
self.assert_onboarding_is_not_done(self.onboarding_3.with_company(self.company_2))
# But it can
self.step_initially_w_o_onboarding.with_company(self.company_2).action_set_just_done()
self.assert_onboarding_is_done(self.onboarding_3.with_company(self.company_2))
@unittest.skip("Company deletion can fail because of other foreign key constraints.")
def test_remove_company_with_progress(self):
user = mail_new_test_user(
self.env,
login='erp_manager',
groups="base.group_erp_manager",
)
self.onboarding_1_step_1.is_per_company = True
self.onboarding_1._search_or_create_progress()
self.onboarding_1.with_company(self.company_2)._search_or_create_progress()
self.assertEqual(len(self.onboarding_1.progress_ids), 2)
# group_erp_manager has no access to onboardng, compute_current_progress is the focus of this test
self.company_2.with_user(user).unlink()
self.onboarding_1._compute_current_progress()
self.assertEqual(len(self.onboarding_1.progress_ids), 1)