Test report
What is tested in Employee Document Expiry, and how to run the suite.
Module: hr_document_expiry 18.0.1.0.0 Date of run: 29 August 2026 Result: 63 tests, 0 failures, 0 errors
Environment
| Odoo | 18.0 (community, source checkout) |
| Python | 3.12.3 |
| PostgreSQL | 16.15 |
| OS | Ubuntu 24.04 LTS |
| Database | created empty, module installed with demo data, tests run in the same pass |
Command:
odoo-bin -d doc_test -i hr_document_expiry \
--test-enable --test-tags /hr_document_expiry --stop-after-init
Every run starts from a dropped and recreated database, so nothing carries over between runs.
Coverage by area
| Suite | Tests | What it covers |
|---|---|---|
| test_document_type | 7 | Shipped types, reminder-order constraint, negative and zero lead times, duplicate names, document counts, the drill-down action |
| test_expiry_state | 13 | The four statuses, the boundary day, "expires today", documents that never expire, date sanity, recomputation on renewal, duplicate numbers, the renewal action |
| test_reminders | 12 | First and second reminders, the no-repeat rule, expired documents, flag reset on renewal, per-document failure isolation, mail template rendering |
| test_employee_summary | 13 | Counts and the warning banner, the grouped-query performance guarantee, missing mandatory documents and the Missing drill-down, cascade deletion |
| test_security | 11 | Own vs. direct reports vs. company visibility, delete permissions, type management, users with no group, multi-company isolation |
| test_config_settings | 7 | Defaults, persistence, validation, live counters, the cron record, the post-install group grant |
| Total | 63 |
Things the tests deliberately pin down
The daily cron must not nag. test_reminder_is_not_repeated runs the cron three times over an expiring document and asserts exactly one activity exists. A daily job that resends every day is worse than no job, because people learn to ignore it.
A renewal must re-arm the reminders. test_renewal_resets_the_flags proves that moving the expiry date clears both "already told" flags. Without this the second expiry passes in total silence — the most dangerous possible failure for this module, and one that would only be noticed years later.
One broken document must not silence the rest. test_a_broken_document_does_not_stop_the_run makes a single document raise during sending and asserts that the others still got their reminders, and that the failure was logged rather than swallowed.
The employee list must stay usable. test_summary_is_one_query_for_many_employees creates 25 employees and asserts the whole warning computation costs no more than four queries. A per-employee scan would make the employee list view unusable at any real headcount, and that regression is easy to introduce accidentally.
Personal data must not outlive its owner. test_deleting_an_employee_removes_their_documents proves the cascade actually fires.
Passport numbers must not be visible to everyone. Six of the eleven security tests exist purely to assert that someone cannot see something.
The mail template must actually render. Two tests render the template against real records, for both the "expires in N days" and the "already expired" branch. A template that raises at send time fails silently inside the cron's error handler and would otherwise go unnoticed.
Known warnings during the run
Two PostgreSQL duplicate key errors appear in the log. Both are expected and asserted: they come from the tests that prove the uniqueness constraints on document type name and on (employee, type, number) are enforced. Odoo logs constraint violations at ERROR level even when the test catches them.
Not covered by automated tests
- Rendering of the views in a browser — checked manually against a running Odoo 18 instance (list, form, kanban, search, pivot, the settings page, and the employee-form banner and stat button).
- Actual SMTP delivery. The tests assert the mail is queued and renders; they do not open a socket.