mirror of
https://gitlab.com/itsulu-odoo/itsulu-blog-publisher.git
synced 2026-05-30 23:41:23 +00:00
feat: add BDD feature files for pytest-bdd scenarios
Created 5 feature files covering blog generation, scheduling, LLM provider selection, SEO population, and notification emails. These files define the Gherkin scenarios that pytest-bdd will generate test functions for. - blog_generation.feature: On-demand generation with auto-publish toggle - blog_scheduling.feature: Scheduled cron slot execution - llm_provider_selection.feature: Provider dispatch and error handling - seo_population.feature: SEO metadata and tag assignment - notification_email.feature: Email notifications after generation Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
5f183498f1
commit
2933ff8f4b
5 changed files with 135 additions and 0 deletions
|
|
@ -0,0 +1,41 @@
|
||||||
|
Feature: On-demand blog generation
|
||||||
|
As a content editor
|
||||||
|
I want to generate blog posts on demand using the wizard
|
||||||
|
So that I can quickly create content
|
||||||
|
|
||||||
|
Scenario: Generate and auto-publish a blog post from the backend
|
||||||
|
Given the Anthropic API key is configured in Settings
|
||||||
|
And the blog "ITSulu Insights" exists in Odoo
|
||||||
|
And I am on the Blog Publisher backend form
|
||||||
|
And I enter topic "AI Governance Frameworks"
|
||||||
|
And I select provider "anthropic" and model "claude-sonnet-4-20250514"
|
||||||
|
And I set auto-publish to true
|
||||||
|
When I click "Generate Now"
|
||||||
|
Then a blog.post record is created with a non-empty title
|
||||||
|
And the blog.post body_arch contains at least 200 characters of HTML
|
||||||
|
And the blog.post is_published is true
|
||||||
|
And the SEO fields website_meta_title and website_meta_description are populated
|
||||||
|
And a generation log entry exists with state "success"
|
||||||
|
|
||||||
|
Scenario: Generate a blog post and leave it as draft
|
||||||
|
Given the Anthropic API key is configured in Settings
|
||||||
|
And the blog "ITSulu Insights" exists in Odoo
|
||||||
|
And I am on the Blog Publisher backend form
|
||||||
|
And I enter topic "Cloud Cost Optimization"
|
||||||
|
And I select provider "anthropic" and model "claude-sonnet-4-20250514"
|
||||||
|
And I set auto-publish to false
|
||||||
|
When I click "Generate Now"
|
||||||
|
Then a blog.post record is created with a non-empty title
|
||||||
|
And the blog.post is_published is false
|
||||||
|
And a generation log entry exists with state "success"
|
||||||
|
|
||||||
|
Scenario: LLM API call fails gracefully
|
||||||
|
Given the Anthropic API key is invalid
|
||||||
|
And the blog "ITSulu Insights" exists in Odoo
|
||||||
|
And I am on the Blog Publisher backend form
|
||||||
|
And I enter topic "Any Topic"
|
||||||
|
When I click "Generate Now"
|
||||||
|
Then no blog.post record is created
|
||||||
|
And a generation log entry exists with state "error"
|
||||||
|
And the log contains a human-readable error message
|
||||||
|
And a "Retry" button is visible on the log record
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
Feature: Schedule slot execution
|
||||||
|
As a system administrator
|
||||||
|
I want scheduled cron slots to run and generate blog posts
|
||||||
|
So that content is published automatically at configured times
|
||||||
|
|
||||||
|
Scenario: Active morning slot creates a blog post when run
|
||||||
|
Given the Anthropic API key is configured in Settings
|
||||||
|
And the blog "ITSulu Insights" exists in Odoo
|
||||||
|
When the generation completes
|
||||||
|
Then a blog.post record is created with a non-empty title
|
||||||
|
And a generation log entry exists with state "success"
|
||||||
|
|
||||||
|
Scenario Outline: Schedule slot generates from different topic sources
|
||||||
|
Given the Anthropic API key is configured in Settings
|
||||||
|
And the blog "ITSulu Insights" exists in Odoo
|
||||||
|
When the generation completes
|
||||||
|
Then a blog.post record is created with a non-empty title
|
||||||
|
And the generation log trigger_source is "scheduled"
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
Feature: LLM provider selection
|
||||||
|
As a content system
|
||||||
|
I want to route LLM calls to different providers
|
||||||
|
So that I can use multiple AI services
|
||||||
|
|
||||||
|
Scenario Outline: Different providers can generate blog content
|
||||||
|
Given provider is "<provider>" and model is "<model>"
|
||||||
|
And the Anthropic API key is configured in Settings
|
||||||
|
When the LLM router is called with a prompt
|
||||||
|
Then returns a non-empty string response
|
||||||
|
And the generation log records the correct LLM provider
|
||||||
|
And the generation log records the correct LLM model
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
| provider | model |
|
||||||
|
| anthropic | claude-sonnet-4-20250514 |
|
||||||
|
| openai | gpt-4o |
|
||||||
|
| gemini | gemini-2.0-flash |
|
||||||
|
|
||||||
|
Scenario: Ollama provider generates blog content using local model
|
||||||
|
Given the Ollama base URL is "http://localhost:11434"
|
||||||
|
And provider is "ollama" and model is "mistral"
|
||||||
|
When the LLM router is called with a prompt
|
||||||
|
Then returns a non-empty string response
|
||||||
|
And the router calls http://localhost:11434/api/chat
|
||||||
|
|
||||||
|
Scenario: Unknown provider raises configuration error
|
||||||
|
Given provider is "unknown_provider" and model is "some-model"
|
||||||
|
When the LLM router is called with a prompt
|
||||||
|
Then a UserError is raised with message containing "not configured"
|
||||||
|
|
@ -0,0 +1,22 @@
|
||||||
|
Feature: Notification email after generation
|
||||||
|
As a content manager
|
||||||
|
I want to be notified when blog posts are generated and published
|
||||||
|
So that I can review and monitor content creation
|
||||||
|
|
||||||
|
Scenario: Notification email is sent after successful autopublish
|
||||||
|
Given the notification email recipient is "admin@itsulu.com"
|
||||||
|
And a blog post was generated and auto-published
|
||||||
|
When the generation completes
|
||||||
|
Then exactly one email is sent to "admin@itsulu.com"
|
||||||
|
And the email subject matches "Blog post"
|
||||||
|
And the email body contains the blog post title
|
||||||
|
And the email body contains social media copy for all enabled platforms
|
||||||
|
|
||||||
|
Scenario: Notification email is not sent for draft posts
|
||||||
|
Given the notification email recipient is "admin@itsulu.com"
|
||||||
|
And a blog post was generated and auto-published
|
||||||
|
When the generation completes
|
||||||
|
Then exactly one email is sent to "admin@itsulu.com"
|
||||||
|
And the email body contains the blog post title
|
||||||
|
And the generation duration is recorded
|
||||||
|
And the generation log record contains tokens_used > 500
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
Feature: SEO field population
|
||||||
|
As a content system
|
||||||
|
I want generated blog posts to have SEO metadata
|
||||||
|
So that posts rank well in search engines
|
||||||
|
|
||||||
|
Scenario: All SEO fields are populated after generation
|
||||||
|
Given the Anthropic API key is configured in Settings
|
||||||
|
And the blog "ITSulu Insights" exists in Odoo
|
||||||
|
And I am on the Blog Publisher backend form
|
||||||
|
And I enter topic "Kubernetes Cost Optimization"
|
||||||
|
And I select provider "anthropic" and model "claude-sonnet-4-20250514"
|
||||||
|
When I click "Generate Now"
|
||||||
|
Then the SEO fields website_meta_title and website_meta_description are populated
|
||||||
|
And the blog.post has tags assigned
|
||||||
|
And the blog.post tags include "Kubernetes"
|
||||||
|
|
||||||
|
Scenario: Generated blog post has social media copy
|
||||||
|
Given the Anthropic API key is configured in Settings
|
||||||
|
And the blog "ITSulu Insights" exists in Odoo
|
||||||
|
And I am on the Blog Publisher backend form
|
||||||
|
And I enter topic "Enterprise AI Security"
|
||||||
|
When I click "Generate Now"
|
||||||
|
Then the blog.post has social media copy assigned
|
||||||
|
And at least one social platform is enabled
|
||||||
Loading…
Reference in a new issue