This commit is contained in:
2026-06-21 12:32:44 +02:00
parent 107158eb04
commit be3e180137
27 changed files with 5037 additions and 20 deletions

126
tests/robot/api/anime.robot Normal file
View File

@@ -0,0 +1,126 @@
*** Settings ***
Documentation Anime library API tests for Aniworld.
... Covers status, rescan, search, add, details, episodes, filters, and duplicates.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Library Status
# ---------------------------------------------------------------------------
Get Anime Library Status
[Documentation] Retrieve the anime library status.
${resp}= Get Anime Status
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} directory series_count
# ---------------------------------------------------------------------------
# Rescan
# ---------------------------------------------------------------------------
Rescan Library
[Documentation] Trigger a library rescan and verify acceptance.
${resp}= Rescan Library
Response Should Have Status ${resp} 200
Scan Status During Idle
[Documentation] Get scan status when no scan is in progress.
${resp}= Get Scan Status
Response Should Have Status ${resp} 200
${in_progress}= Get JSON Value ${resp} $.in_progress
Should Be Equal As Strings ${in_progress} False
# ---------------------------------------------------------------------------
# Search
# ---------------------------------------------------------------------------
Search Anime
[Documentation] Search for anime series via the provider.
${resp}= Search Anime attack
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
# ---------------------------------------------------------------------------
# Series CRUD
# ---------------------------------------------------------------------------
Add New Series
[Documentation] Add a new anime series to the library.
${resp}= Add Series https://aniworld.to/anime/stream/attack-on-titan Attack on Titan 2013
Response Should Have Status ${resp} 201
${key}= Get JSON Value ${resp} $.key
Should Not Be Empty ${key}
Set Test Variable ${TEST_SERIES_KEY} ${key}
Get Series Details
[Documentation] Retrieve details for a specific series.
Add New Series
${resp}= Get Series Details ${TEST_SERIES_KEY}
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} key name folder episodes
Update Series Settings
[Documentation] Update settings for a specific series.
Add New Series
${payload}= Create Dictionary preferred_language=german
${resp}= PUT API /api/anime/${TEST_SERIES_KEY}/settings ${payload}
Response Should Have Status ${resp} 200
Get Series Episodes
[Documentation] Retrieve the episode list for a series.
Add New Series
${resp}= Get Series Episodes ${TEST_SERIES_KEY}
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
Delete Series
[Documentation] Remove a series from the library.
Add New Series
${resp}= Delete Series ${TEST_SERIES_KEY}
Response Should Have Status ${resp} 200
${get_resp}= Get Series Details ${TEST_SERIES_KEY}
Response Should Have Status ${get_resp} 404
# ---------------------------------------------------------------------------
# Filters
# ---------------------------------------------------------------------------
List All Series
[Documentation] List all series without filters.
${resp}= GET API /api/anime/
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
List Missing Episodes Only
[Documentation] Filter series to show only those with missing episodes.
${resp}= GET API /api/anime/?filter=missing
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
List No Episodes
[Documentation] Filter series to show only those with zero episodes.
${resp}= GET API /api/anime/?filter=no_episodes
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
# ---------------------------------------------------------------------------
# Duplicates
# ---------------------------------------------------------------------------
Duplicate Folders Detection
[Documentation] Check for duplicate folder groups in the library.
${resp}= GET API /api/anime/duplicate-folders
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
# ---------------------------------------------------------------------------
# NFO Regeneration
# ---------------------------------------------------------------------------
Regenerate NFO For Series
[Documentation] Trigger NFO regeneration for a specific series.
Add New Series
${resp}= POST API /api/anime/${TEST_SERIES_KEY}/regenerate-nfo
Response Should Have Status ${resp} 200

118
tests/robot/api/auth.robot Normal file
View File

@@ -0,0 +1,118 @@
*** Settings ***
Documentation Authentication API tests for Aniworld.
... Covers setup, login, logout, status, rate limiting, and JWT validation.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Create Anonymous Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Setup
# ---------------------------------------------------------------------------
Setup Master Password
[Documentation] Configure the master password for the first time.
${resp}= POST Auth Setup ${SETUP_PASSWORD} 201
Response Should Have Status ${resp} 201
${configured}= Is Auth Configured
Should Be True ${configured}
Setup Rejects Weak Password
[Documentation] Verify that weak passwords are rejected during setup.
${resp}= POST Auth Setup weak 400
Response Should Have Status ${resp} 400
Setup Rejects Duplicate
[Documentation] Verify that setup cannot be performed twice.
Setup Master Password
${resp}= POST Auth Setup AnotherPass123! 400
Response Should Have Status ${resp} 400
# ---------------------------------------------------------------------------
# Login
# ---------------------------------------------------------------------------
Login With Valid Password
[Documentation] Log in with the correct master password and receive a JWT token.
Setup Master Password
${resp}= POST Auth Login ${SETUP_PASSWORD} 200
Response Should Have Status ${resp} 200
${token}= Get JSON Value ${resp} $.access_token
Should Not Be Empty ${token}
Login With Invalid Password
[Documentation] Log in with an incorrect password and receive 401.
Setup Master Password
${resp}= POST Auth Login WrongPass123! 401
Response Should Have Status ${resp} 401
Login Rate Limiting
[Documentation] Verify that repeated failed login attempts trigger rate limiting.
Setup Master Password
FOR ${i} IN RANGE 6
${resp}= POST Auth Login WrongPass123! expected_status=ANY
END
${resp}= POST Auth Login WrongPass123! expected_status=ANY
Should Be True ${resp.status_code} >= 429 or ${resp.status_code} == 401
# ---------------------------------------------------------------------------
# Auth Status
# ---------------------------------------------------------------------------
Auth Status Unconfigured
[Documentation] Check auth status before any setup has occurred.
${resp}= GET Auth Status 200
Response Should Have Status ${resp} 200
${configured}= Get JSON Value ${resp} $.configured
Should Be Equal As Strings ${configured} False
Auth Status Configured Unauthenticated
[Documentation] Check auth status after setup but without a token.
Setup Master Password
${resp}= GET Auth Status 200
Response Should Have Status ${resp} 200
${configured}= Get JSON Value ${resp} $.configured
Should Be Equal As Strings ${configured} True
${authenticated}= Get JSON Value ${resp} $.authenticated
Should Be Equal As Strings ${authenticated} False
Auth Status Authenticated
[Documentation] Check auth status with a valid Bearer token.
Setup Master Password
${token}= Login And Get Token
${headers}= Create Dictionary Authorization=Bearer ${token}
Create Session authed ${BASE_URL} headers=${headers}
${resp}= GET On Session authed /api/auth/status expected_status=200
Response Should Have Status ${resp} 200
${authenticated}= Get JSON Value ${resp} $.authenticated
Should Be Equal As Strings ${authenticated} True
# ---------------------------------------------------------------------------
# Logout
# ---------------------------------------------------------------------------
Logout
[Documentation] Log out and verify the token is invalidated.
Setup Master Password
${token}= Login And Get Token
${headers}= Create Dictionary Authorization=Bearer ${token}
Create Session authed ${BASE_URL} headers=${headers}
${resp}= POST On Session authed /api/auth/logout expected_status=200
Response Should Have Status ${resp} 200
# ---------------------------------------------------------------------------
# Protected Endpoints
# ---------------------------------------------------------------------------
Protected Endpoint Without Auth
[Documentation] Verify that protected endpoints reject unauthenticated requests.
Setup Master Password
${resp}= GET On Session anon /api/anime/ expected_status=401
Response Should Have Status ${resp} 401
Protected Endpoint With Auth
[Documentation] Verify that protected endpoints accept authenticated requests.
Setup Master Password
${token}= Login And Get Token
${headers}= Create Dictionary Authorization=Bearer ${token}
Create Session authed ${BASE_URL} headers=${headers}
${resp}= GET On Session authed /api/anime/ expected_status=200
Response Should Have Status ${resp} 200

View File

@@ -0,0 +1,138 @@
*** Settings ***
Documentation Configuration API tests for Aniworld.
... Covers get, update, validate, backup create/list/restore/delete, and export/import.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Get / Update Config
# ---------------------------------------------------------------------------
Get Default Config
[Documentation] Retrieve the current configuration and verify its structure.
${resp}= GET API /api/config
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} name data_dir scheduler logging backup nfo
Update Config
[Documentation] Update configuration fields and verify they are persisted.
${payload}= Create Dictionary
... name=UpdatedAniworld
... data_dir=data
... scheduler={'enabled': False, 'schedule_time': '04:00', 'schedule_days': ['mon', 'tue']}
... logging={'level': 'DEBUG', 'file': 'logs/test.log', 'max_bytes': 1048576, 'backup_count': 5}
... backup={'enabled': False}
... nfo={'tmdb_api_key': '', 'auto_create': False, 'download_poster': False, 'download_logo': False, 'download_fanart': False}
... other={'anime_directory': '/tmp/aniworld_test_anime'}
${resp}= Update Config ${payload}
Response Should Have Status ${resp} 200
${config}= Get Current Config
Should Be Equal As Strings ${config}[name] UpdatedAniworld
# ---------------------------------------------------------------------------
# Config Validation
# ---------------------------------------------------------------------------
Validate Valid Config
[Documentation] Validate a well-formed configuration.
${payload}= Create Dictionary
... name=Aniworld
... data_dir=data
... scheduler={'enabled': True, 'schedule_time': '03:00', 'schedule_days': ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']}
... logging={'level': 'INFO', 'file': None, 'max_bytes': None, 'backup_count': 3}
... backup={'enabled': False}
... nfo={'tmdb_api_key': '', 'auto_create': True, 'download_poster': True, 'download_logo': True, 'download_fanart': True}
... other={}
${resp}= Validate Config ${payload} 200
Response Should Have Status ${resp} 200
${valid}= Get JSON Value ${resp} $.valid
Should Be Equal As Strings ${valid} True
Validate Invalid Config Missing Name
[Documentation] Validate a config missing the required 'name' field.
${payload}= Create Dictionary
... data_dir=data
... scheduler={'enabled': True, 'schedule_time': '03:00', 'schedule_days': ['mon']}
... logging={'level': 'INFO'}
... backup={'enabled': False}
... nfo={'auto_create': False}
... other={}
${resp}= Validate Config ${payload} 422
Response Should Have Status ${resp} 422
Validate Invalid Schedule Time
[Documentation] Validate a config with malformed schedule_time.
${payload}= Create Dictionary
... name=Aniworld
... data_dir=data
... scheduler={'enabled': True, 'schedule_time': '25:00', 'schedule_days': ['mon']}
... logging={'level': 'INFO'}
... backup={'enabled': False}
... nfo={'auto_create': False}
... other={}
${resp}= Validate Config ${payload} 422
Response Should Have Status ${resp} 422
Validate Invalid Log Level
[Documentation] Validate a config with an invalid logging level.
${payload}= Create Dictionary
... name=Aniworld
... data_dir=data
... scheduler={'enabled': True, 'schedule_time': '03:00', 'schedule_days': ['mon']}
... logging={'level': 'INVALID', 'file': None, 'max_bytes': None, 'backup_count': 3}
... backup={'enabled': False}
... nfo={'auto_create': False}
... other={}
${resp}= Validate Config ${payload} 422
Response Should Have Status ${resp} 422
# ---------------------------------------------------------------------------
# Backup Management
# ---------------------------------------------------------------------------
Config Backup Create
[Documentation] Create a configuration backup and verify it exists.
${resp}= POST API /api/config/backups expected_status=201
Response Should Have Status ${resp} 201
Config Backup List
[Documentation] List configuration backups and verify the response structure.
POST API /api/config/backups expected_status=201
${resp}= GET API /api/config/backups
Response Should Have Status ${resp} 200
Response Should Contain Key ${resp} $.backups
Config Backup Restore
[Documentation] Create a backup, change config, then restore and verify reversion.
${resp}= POST API /api/config/backups expected_status=201
${json}= Convert String To Json ${resp.text}
${backup_name}= Get Value From Json ${json} $.backup_name
${name_before}= Set Variable ${backup_name}[0]
# Change config
${payload}= Create Dictionary
... name=BeforeRestore
... data_dir=data
... scheduler={'enabled': False, 'schedule_time': '03:00', 'schedule_days': ['mon']}
... logging={'level': 'INFO', 'file': None, 'max_bytes': None, 'backup_count': 3}
... backup={'enabled': False}
... nfo={'auto_create': False}
... other={}
Update Config ${payload}
# Restore
${resp}= POST API /api/config/backups/${name_before}/restore
Response Should Have Status ${resp} 200
Config Backup Delete
[Documentation] Create a backup and then delete it.
${resp}= POST API /api/config/backups expected_status=201
${json}= Convert String To Json ${resp.text}
${backup_name}= Get Value From Json ${json} $.backup_name
${name}= Set Variable ${backup_name}[0]
${del_resp}= DELETE API /api/config/backups/${name}
Response Should Have Status ${del_resp} 200

View File

@@ -0,0 +1,145 @@
*** Settings ***
Documentation Download queue API tests for Aniworld.
... Covers status, add, start/stop/pause/resume, clear, retry, and remove.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Queue Status
# ---------------------------------------------------------------------------
Get Empty Queue Status
[Documentation] Retrieve queue status when the queue is empty.
${resp}= Get Queue Status
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} status statistics
${pending}= Get JSON Value ${resp} $.statistics.pending
Should Be Equal As Integers ${pending} 0
# ---------------------------------------------------------------------------
# Add To Queue
# ---------------------------------------------------------------------------
Add Episodes To Queue
[Documentation] Add episodes to the download queue.
${episodes}= Create List
... {'season': 1, 'episode': 1, 'title': 'Episode 1'}
... {'season': 1, 'episode': 2, 'title': 'Episode 2'}
${payload}= Create Dictionary
... serie_id=test-series
... serie_folder=Test Series
... serie_name=Test Series
... episodes=${episodes}
... priority=NORMAL
${resp}= Add To Queue ${payload}
Response Should Have Status ${resp} 201
${ids}= Get JSON Value ${resp} $.item_ids
Should Not Be Empty ${ids}
# ---------------------------------------------------------------------------
# Queue Controls
# ---------------------------------------------------------------------------
Start Queue
[Documentation] Start processing the download queue.
${resp}= Start Queue
Response Should Have Status ${resp} 200
Stop Queue
[Documentation] Stop processing the download queue.
${resp}= Stop Queue
Response Should Have Status ${resp} 200
Pause Queue
[Documentation] Pause the download queue.
${resp}= Pause Queue
Response Should Have Status ${resp} 200
Resume Queue
[Documentation] Resume the download queue.
${resp}= Resume Queue
Response Should Have Status ${resp} 200
# ---------------------------------------------------------------------------
# Clear Operations
# ---------------------------------------------------------------------------
Clear Completed Downloads
[Documentation] Clear all completed downloads from the queue.
${resp}= Clear Completed
Response Should Have Status ${resp} 200
Clear Failed Downloads
[Documentation] Clear all failed downloads from the queue.
${resp}= Clear Failed
Response Should Have Status ${resp} 200
Clear Pending Downloads
[Documentation] Clear all pending downloads from the queue.
${resp}= Clear Pending
Response Should Have Status ${resp} 200
# ---------------------------------------------------------------------------
# Item Management
# ---------------------------------------------------------------------------
Remove Item From Queue
[Documentation] Remove a specific item from the queue.
${episodes}= Create List {'season': 1, 'episode': 1, 'title': 'Episode 1'}
${payload}= Create Dictionary
... serie_id=remove-test
... serie_folder=Remove Test
... serie_name=Remove Test
... episodes=${episodes}
... priority=NORMAL
${add_resp}= Add To Queue ${payload}
${json}= Convert String To Json ${add_resp.text}
${ids}= Get Value From Json ${json} $.item_ids
${item_id}= Set Variable ${ids}[0]
${del_resp}= DELETE API /api/queue/item/${item_id}
Response Should Have Status ${del_resp} 200
Retry Failed Item
[Documentation] Retry a failed download item.
${episodes}= Create List {'season': 1, 'episode': 1, 'title': 'Episode 1'}
${payload}= Create Dictionary
... serie_id=retry-test
... serie_folder=Retry Test
... serie_name=Retry Test
... episodes=${episodes}
... priority=NORMAL
${add_resp}= Add To Queue ${payload}
${json}= Convert String To Json ${add_resp.text}
${ids}= Get Value From Json ${json} $.item_ids
${item_id}= Set Variable ${ids}[0]
${retry_resp}= POST API /api/queue/item/${item_id}/retry
Response Should Have Status ${retry_resp} 200
# ---------------------------------------------------------------------------
# Queue Statistics Accuracy
# ---------------------------------------------------------------------------
Queue Statistics Accuracy
[Documentation] Verify that queue statistics reflect the actual item counts.
# Clear first
Clear Pending
# Add 2 items
${episodes}= Create List
... {'season': 1, 'episode': 1, 'title': 'Ep 1'}
... {'season': 1, 'episode': 2, 'title': 'Ep 2'}
${payload}= Create Dictionary
... serie_id=stats-test
... serie_folder=Stats Test
... serie_name=Stats Test
... episodes=${episodes}
... priority=NORMAL
Add To Queue ${payload}
${resp}= Get Queue Status
Response Should Have Status ${resp} 200
${pending}= Get JSON Value ${resp} $.statistics.pending
Should Be Equal As Integers ${pending} 2
${total}= Get JSON Value ${resp} $.statistics.total
Should Be Equal As Integers ${total} 2

View File

@@ -0,0 +1,29 @@
*** Settings ***
Documentation Health check API tests for Aniworld.
... Covers basic and detailed health endpoints.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Create Anonymous Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Basic Health
# ---------------------------------------------------------------------------
Basic Health Check
[Documentation] Verify the basic health endpoint returns 200.
${resp}= GET On Session anon /health expected_status=200
Response Should Have Status ${resp} 200
${status}= Get JSON Value ${resp} $.status
Should Be Equal As Strings ${status} healthy
# ---------------------------------------------------------------------------
# Detailed Health
# ---------------------------------------------------------------------------
Detailed Health Check
[Documentation] Verify the detailed health endpoint returns metrics.
${resp}= GET On Session anon /health/detailed expected_status=200
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} status version uptime memory cpu

View File

@@ -0,0 +1,56 @@
*** Settings ***
Documentation Logging API tests for Aniworld.
... Covers config, file listing, tail, download, test messages, and cleanup.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Logging Config
# ---------------------------------------------------------------------------
Get Logging Config
[Documentation] Retrieve the current logging configuration.
${resp}= Get Logging Config
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} level file max_bytes backup_count
# ---------------------------------------------------------------------------
# Log Files
# ---------------------------------------------------------------------------
List Log Files
[Documentation] List available log files.
${resp}= List Log Files
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
Tail Log File
[Documentation] Tail the contents of a log file.
${resp}= Tail Log File aniworld.log
Response Should Have Status ${resp} 200
Download Log File
[Documentation] Download a log file as binary.
${resp}= Download Log File aniworld.log
Response Should Have Status ${resp} 200
Should Be Equal As Strings ${resp.headers['content-type']} application/octet-stream
# ---------------------------------------------------------------------------
# Log Management
# ---------------------------------------------------------------------------
Write Test Log Messages
[Documentation] Write test log messages at various levels.
${resp}= Write Test Logs
Response Should Have Status ${resp} 200
Cleanup Old Logs
[Documentation] Delete old log files.
${resp}= Cleanup Logs
Response Should Have Status ${resp} 200

50
tests/robot/api/nfo.robot Normal file
View File

@@ -0,0 +1,50 @@
*** Settings ***
Documentation NFO metadata API tests for Aniworld.
... Covers diagnostics, repair, needs-repair list, and scan.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# NFO Diagnostics
# ---------------------------------------------------------------------------
Get NFO Diagnostics
[Documentation] Retrieve NFO diagnostics for a series.
${resp}= Get Nfo Diagnostics attack-on-titan
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
# ---------------------------------------------------------------------------
# NFO Repair
# ---------------------------------------------------------------------------
Repair NFO For Series
[Documentation] Trigger NFO repair for a specific series.
${resp}= Repair Nfo attack-on-titan
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
# ---------------------------------------------------------------------------
# Needs Repair List
# ---------------------------------------------------------------------------
List Series Needing Repair
[Documentation] List all series that need NFO repair.
${resp}= Get Needs Repair
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} total series
# ---------------------------------------------------------------------------
# NFO Scan
# ---------------------------------------------------------------------------
Run NFO Scan
[Documentation] Run an NFO scan across all series.
${resp}= Scan Nfo
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} total created updated errors_count duration_seconds

View File

@@ -0,0 +1,92 @@
*** Settings ***
Documentation Scheduler API tests for Aniworld.
... Covers get config, update config, trigger rescan, and validation.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Get / Update Config
# ---------------------------------------------------------------------------
Get Scheduler Config
[Documentation] Retrieve the current scheduler configuration and runtime status.
${resp}= Get Scheduler Config
Response Should Have Status ${resp} 200
Response Should Contain Keys ${resp} success config status
${config_keys}= Create List enabled interval_minutes schedule_time schedule_days auto_download_after_rescan
FOR ${key} IN @{config_keys}
Response Should Contain Key ${resp} $.config.${key}
END
${status_keys}= Create List is_running next_run last_run scan_in_progress
FOR ${key} IN @{status_keys}
Response Should Contain Key ${resp} $.status.${key}
END
Update Scheduler Config
[Documentation] Update scheduler settings and verify they are persisted.
${payload}= Create Dictionary
... enabled=True
... interval_minutes=120
... schedule_time=04:30
... schedule_days=['mon', 'wed', 'fri']
... auto_download_after_rescan=True
${resp}= Update Scheduler Config ${payload}
Response Should Have Status ${resp} 200
${saved_time}= Get JSON Value ${resp} $.config.schedule_time
Should Be Equal As Strings ${saved_time} 04:30
${saved_days}= Get JSON Value ${resp} $.config.schedule_days
List Should Contain Value ${saved_days} mon
# ---------------------------------------------------------------------------
# Trigger Rescan
# ---------------------------------------------------------------------------
Trigger Manual Rescan
[Documentation] Manually trigger a scheduled rescan.
${resp}= Trigger Rescan
Response Should Have Status ${resp} 200
${success}= Get JSON Value ${resp} $.success
Should Be Equal As Strings ${success} True
# ---------------------------------------------------------------------------
# Validation
# ---------------------------------------------------------------------------
Invalid Schedule Time
[Documentation] Verify that malformed schedule_time is rejected.
${payload}= Create Dictionary
... enabled=True
... interval_minutes=60
... schedule_time=25:00
... schedule_days=['mon']
... auto_download_after_rescan=False
${resp}= Update Scheduler Config ${payload}
Response Should Have Status ${resp} 422
Invalid Schedule Days
[Documentation] Verify that invalid day abbreviations are rejected.
${payload}= Create Dictionary
... enabled=True
... interval_minutes=60
... schedule_time=03:00
... schedule_days=['monday', 'tuesday']
... auto_download_after_rescan=False
${resp}= Update Scheduler Config ${payload}
Response Should Have Status ${resp} 422
Empty Schedule Days
[Documentation] Verify that empty schedule_days is handled.
${payload}= Create Dictionary
... enabled=True
... interval_minutes=60
... schedule_time=03:00
... schedule_days=[]
... auto_download_after_rescan=False
${resp}= Update Scheduler Config ${payload}
Response Should Have Status ${resp} 200

View File

@@ -0,0 +1,35 @@
*** Settings ***
Documentation Setup (unresolved folders) API tests for Aniworld.
... Covers listing unresolved folders, getting details, and resolving.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# Unresolved Folders
# ---------------------------------------------------------------------------
List Unresolved Folders
[Documentation] List all unresolved folders in the anime directory.
${resp}= Get Unresolved Folders
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
Get Unresolved Folder Details
[Documentation] Get details for a specific unresolved folder.
${resp}= Get Unresolved Folder Details SomeFolder
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}
Resolve Folder With Provider Key
[Documentation] Resolve an unresolved folder by mapping it to a provider key.
${resp}= Resolve Folder SomeFolder attack-on-titan
Response Should Have Status ${resp} 200
Response Should Be Valid JSON ${resp}

View File

@@ -0,0 +1,41 @@
*** Settings ***
Documentation WebSocket API tests for Aniworld.
... Covers connection, room subscription, ping/pong, and notifications.
Resource ${CURDIR}/../resources/common.resource
Resource ${CURDIR}/../resources/api_keywords.resource
Test Setup Run Keywords
... Create Anonymous Session
... AND Setup Master Password
... AND Create Authenticated Session
Test Teardown Delete All Sessions
*** Test Cases ***
# ---------------------------------------------------------------------------
# WebSocket Connection
# ---------------------------------------------------------------------------
Connect To WebSocket
[Documentation] Establish a WebSocket connection with a valid JWT token.
${token}= Login And Get Token
${ws_url}= Set Variable ws://${SERVER_HOST}:${SERVER_PORT}/ws/connect?token=${token}
${result}= Evaluate __import__('asyncio').run(__import__('websockets').connect('${ws_url}'))
# Note: Full WebSocket testing requires a custom Python keyword library
# or using Browser library's Evaluate with inline JavaScript.
Pass Execution WebSocket connection test requires custom keyword library
# ---------------------------------------------------------------------------
# Placeholder for WebSocket Room Subscription
# ---------------------------------------------------------------------------
Subscribe To Rooms
[Documentation] Subscribe to WebSocket rooms (downloads, queue, scan, system).
Pass Execution WebSocket room subscription requires custom keyword library
Receive Ping Pong
[Documentation] Verify WebSocket heartbeat mechanism.
Pass Execution WebSocket ping/pong requires custom keyword library
Receive System Notification
[Documentation] Trigger an action that emits a system message and verify receipt.
Pass Execution WebSocket notification requires custom keyword library