metatroncubeswdev bd9b449ded fix: create the four backend demo logins the demo script actually needs
shared/DEMO_SCRIPT.md's cast table names six logins. Two - the parent
and student portal accounts - were created in mc_education_portal.
The other four (Principal, Front Office, Teacher, Accountant) were
explicitly punted to O9: mc_education_base's demo/mc_teacher_demo.xml
says outright "res.users/login creation is O9's job (demo rehearsal),
not this base module." That job was never actually done - found only
now, while writing a demo handbook that needed to print real, working
credentials and I checked them against a live container before
printing anything.

Concretely this means a from-scratch rehearsal of the demo script
would have stalled at Scene 1: there was no way to log in as Rekha
Nair, Sunitha R, or David Fernandes at all, and logging in as
"Arun Prakash" would have meant either sharing the admin account or
creating an unlinked user that fails Scene 4's actual point - a
teacher seeing only their own batch, which the attendance record rule
resolves through batch_id.class_teacher_id.user_id. Arun's login is
now attached to the same hr.employee record mc_education_base's own
demo data already made Grade 8-A's class teacher, not a fresh one.

Real Odoo behaviour learned fixing this, worth recording since it
will bite again: demo data loads with noupdate=True so a school's own
edits survive a later module update, and that guard is checked by
xmlid, not by which file is doing the writing - a <record> in this
module trying to set an existing mc_education_base demo record's
field was silently skipped, no error, nothing in the log. <function>
calls the ORM directly and is the correct tool, but carries the same
guard one level up in Odoo's loader (convert.py's _tag_function skips
entirely unless the module is being freshly installed, mode == 'init'
- an update on an already-installed database is a no-op). That is
exactly the real story this product cares about (a clean machine,
installing the whole suite once), so it's the right fix going
forward - verified on a from-scratch install of all nine modules
together. The one already-running database that had this module
installed before this fix existed needed a one-off manual correction
outside the codebase, not a workaround inside it.

Added a regression test asserting all four logins exist in the right
group and that Arun's employee record and Grade 8-A's class_teacher_id
actually resolve to the same person - not just "a teacher login
exists somewhere."

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-11 15:06:31 -04:00

67 lines
3.3 KiB
Python

from odoo.tests.common import TransactionCase
class TestTheme(TransactionCase):
def test_two_branded_companies_exist(self):
main = self.env.ref("base.main_company")
self.assertEqual(main.name, "St. Aloysius Public School")
# No currency assertion here on purpose: base.main_company's
# currency is deliberately left untouched by this module (see the
# comment in demo/mc_theme_demo.xml) - changing it would fail
# once any financial module has posted journal items for this
# company, which a combined install of the full suite does
# before this module's demo data runs.
self.assertTrue(main.logo)
waterloo = self.env.ref("mc_education_theme.demo_company_waterloo_heights")
self.assertEqual(waterloo.name, "Waterloo Heights Academy")
self.assertEqual(waterloo.currency_id, self.env.ref("base.CAD"))
self.assertTrue(waterloo.logo)
# The "swap" is switching companies - each must actually be
# distinct, not the same record twice under different refs.
self.assertNotEqual(main.id, waterloo.id)
def test_portal_sidebar_has_no_odoo_branding(self):
html = str(self.env["ir.qweb"]._render("portal.portal_record_sidebar", {
"classes": "", "title": False, "entries": False,
}))
self.assertNotIn("Powered by", html)
self.assertNotIn("odoo.com", html)
self.assertNotIn("Odoo Logo", html)
def test_backend_cast_logins_exist_in_the_right_groups(self):
# shared/DEMO_SCRIPT.md's cast table names six logins. Two
# (parent@demo.school, student@demo.school) are created by
# mc_education_portal. The other four were explicitly deferred
# to this module (see demo/mc_cast_users_demo.xml) and, until
# that file existed, were never actually created anywhere -
# the demo script would have stalled at Scene 1 on a clean
# rehearsal. This test is the regression guard for that gap.
principal = self.env["res.users"].search([("login", "=", "principal@demo.school")])
self.assertTrue(principal)
self.assertIn(
self.env.ref("mc_education_base.group_school_administrator"), principal.group_ids
)
office = self.env["res.users"].search([("login", "=", "office@demo.school")])
self.assertTrue(office)
self.assertIn(self.env.ref("mc_education_base.group_school_staff"), office.group_ids)
accountant = self.env["res.users"].search([("login", "=", "accounts@demo.school")])
self.assertTrue(accountant)
self.assertIn(self.env.ref("mc_education_base.group_accountant"), accountant.group_ids)
teacher = self.env["res.users"].search([("login", "=", "teacher@demo.school")])
self.assertTrue(teacher)
self.assertIn(self.env.ref("mc_education_base.group_teacher"), teacher.group_ids)
# Not just "a teacher login exists" - it has to be *the* login
# that Grade 8-A's class_teacher_id points at, because that is
# what mc_education_attendance's record rule actually checks.
arun = self.env.ref("mc_education_base.demo_employee_arun_prakash")
self.assertEqual(arun.user_id, teacher)
grade_8a = self.env.ref("mc_education_base.demo_batch_grade8_a")
self.assertEqual(grade_8a.class_teacher_id, arun)