- views/blog_schedule_views.xml: web_ribbon invisible="active" (Odoo 17
bare-expr syntax) -> attrs="{'invisible': [('active','=',True)]}".
This was the view-validation error blocking module install on Odoo 14.
- tests: Odoo 14 TransactionCase exposes self.env in setUp(), not cls.env
in setUpClass() (that pattern is Odoo 15+). Converted all 13 setUpClass
blocks across 6 test files to setUp(self) + self.env/self.factory.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
112 lines
4.1 KiB
Python
112 lines
4.1 KiB
Python
# addons/itsulu_blog_publisher/tests/test_blog_topic.py
|
|
"""
|
|
Tests for models/blog_topic.py
|
|
Behaviour: topic queue management — create, prioritise, mark used,
|
|
pop next topic, fall back gracefully when queue is empty.
|
|
|
|
RED PHASE — all tests FAIL until itsulu.blog.topic model exists.
|
|
"""
|
|
from odoo.tests import TransactionCase, tagged
|
|
from odoo.exceptions import ValidationError
|
|
from .factories import BlogPublisherFactory
|
|
|
|
|
|
@tagged('post_install', '-at_install', 'itsulu_blog_publisher', 'blog_topic')
|
|
class TestBlogTopicQueueManagement(TransactionCase):
|
|
"""Verify that the topic queue picks topics in priority order."""
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.factory = BlogPublisherFactory(self.env)
|
|
|
|
def test_topic_is_created_with_pending_state(self):
|
|
"""
|
|
1. Behaviour: newly created topic starts in state='pending'
|
|
2. ARRANGE: nothing — default factory values
|
|
3. ACT: create a topic record
|
|
4. ASSERT: state == 'pending'
|
|
5. FAIL reason: model itsulu.blog.topic does not exist
|
|
"""
|
|
# ARRANGE + ACT
|
|
topic = self.factory.blog_topic(name='AI Ethics in Healthcare')
|
|
|
|
# ASSERT
|
|
self.assertEqual(topic.state, 'pending')
|
|
|
|
def test_get_next_topic_returns_highest_priority_pending_topic(self):
|
|
"""
|
|
get_next_topic() on the model returns the pending topic
|
|
with the highest priority (urgent > high > normal > low).
|
|
"""
|
|
# ARRANGE
|
|
low = self.factory.blog_topic(name='Low priority topic', priority='low')
|
|
normal = self.factory.blog_topic(name='Normal priority topic', priority='normal')
|
|
urgent = self.factory.blog_topic(name='Urgent topic', priority='urgent')
|
|
high = self.factory.blog_topic(name='High priority topic', priority='high')
|
|
|
|
# ACT
|
|
next_topic = self.env['itsulu.blog.topic'].get_next_topic()
|
|
|
|
# ASSERT
|
|
self.assertEqual(next_topic.id, urgent.id,
|
|
"get_next_topic() must return the urgent-priority topic first")
|
|
|
|
def test_get_next_topic_returns_none_when_queue_is_empty(self):
|
|
"""get_next_topic() returns False (empty recordset) when no pending topics exist."""
|
|
# ARRANGE — mark all pending topics as used to clear the queue
|
|
self.env['itsulu.blog.topic'].search([('state', '=', 'pending')]).write(
|
|
{'state': 'used'}
|
|
)
|
|
|
|
# ACT
|
|
result = self.env['itsulu.blog.topic'].get_next_topic()
|
|
|
|
# ASSERT
|
|
self.assertFalse(result, "get_next_topic() must return empty recordset when queue is empty")
|
|
|
|
def test_mark_topic_as_used_changes_state(self):
|
|
"""Calling topic.mark_used() sets state to 'used'."""
|
|
# ARRANGE
|
|
topic = self.factory.blog_topic(name='DevOps best practices')
|
|
|
|
# ACT
|
|
topic.mark_used()
|
|
|
|
# ASSERT
|
|
self.assertEqual(topic.state, 'used')
|
|
|
|
def test_used_topic_is_excluded_from_next_topic_selection(self):
|
|
"""A used topic is never returned by get_next_topic()."""
|
|
# ARRANGE
|
|
used_topic = self.factory.blog_topic(
|
|
name='Already published topic', priority='urgent', state='used'
|
|
)
|
|
pending_topic = self.factory.blog_topic(
|
|
name='Not yet published', priority='normal', state='pending'
|
|
)
|
|
|
|
# ACT
|
|
next_topic = self.env['itsulu.blog.topic'].get_next_topic()
|
|
|
|
# ASSERT
|
|
self.assertNotEqual(next_topic.id, used_topic.id)
|
|
self.assertEqual(next_topic.id, pending_topic.id)
|
|
|
|
def test_topic_name_cannot_be_empty(self):
|
|
"""Creating a topic with an empty name raises ValidationError."""
|
|
with self.assertRaises(ValidationError):
|
|
self.factory.blog_topic(name='')
|
|
|
|
def test_topic_can_be_linked_to_a_specific_blog(self):
|
|
"""A topic can optionally specify which blog it should be published to."""
|
|
# ARRANGE
|
|
blog = self.factory.blog(name='ITSulu Insights')
|
|
|
|
# ACT
|
|
topic = self.factory.blog_topic(
|
|
name='Kubernetes for SMBs',
|
|
blog_id=blog.id,
|
|
)
|
|
|
|
# ASSERT
|
|
self.assertEqual(topic.blog_id.id, blog.id)
|