Add comprehensive test suite to reach 31% code coverage
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,156 @@
|
||||
"""Tests for the import queue data structures."""
|
||||
import pytest
|
||||
import threading
|
||||
import time
|
||||
from musicround.helpers.import_queue import ImportJob, ImportQueue
|
||||
|
||||
|
||||
class TestImportJob:
|
||||
"""Tests for the ImportJob dataclass."""
|
||||
|
||||
def test_import_job_creation(self):
|
||||
"""Test creating an ImportJob with all fields."""
|
||||
job = ImportJob(
|
||||
priority=5,
|
||||
service_name='spotify',
|
||||
item_type='playlist',
|
||||
item_id='abc123',
|
||||
user_id=1,
|
||||
)
|
||||
assert job.priority == 5
|
||||
assert job.service_name == 'spotify'
|
||||
assert job.item_type == 'playlist'
|
||||
assert job.item_id == 'abc123'
|
||||
assert job.user_id == 1
|
||||
|
||||
def test_import_job_ordering_by_priority(self):
|
||||
"""Test that ImportJobs are ordered by priority (lower = higher priority)."""
|
||||
job_high = ImportJob(priority=1, service_name='spotify', item_type='track',
|
||||
item_id='a', user_id=1)
|
||||
job_low = ImportJob(priority=10, service_name='spotify', item_type='track',
|
||||
item_id='b', user_id=1)
|
||||
assert job_high < job_low
|
||||
|
||||
def test_import_job_equality(self):
|
||||
"""Test that ImportJobs with the same priority compare as equal."""
|
||||
job1 = ImportJob(priority=5, service_name='spotify', item_type='track',
|
||||
item_id='x', user_id=1)
|
||||
job2 = ImportJob(priority=5, service_name='deezer', item_type='album',
|
||||
item_id='y', user_id=2)
|
||||
# Only priority is used for comparison
|
||||
assert job1 == job2
|
||||
|
||||
def test_import_job_deezer(self):
|
||||
"""Test creating a Deezer ImportJob."""
|
||||
job = ImportJob(
|
||||
priority=3,
|
||||
service_name='deezer',
|
||||
item_type='album',
|
||||
item_id='456',
|
||||
user_id=7,
|
||||
)
|
||||
assert job.service_name == 'deezer'
|
||||
assert job.item_type == 'album'
|
||||
|
||||
|
||||
class TestImportQueue:
|
||||
"""Tests for the ImportQueue class."""
|
||||
|
||||
def test_queue_creation(self):
|
||||
"""Test creating an ImportQueue."""
|
||||
queue = ImportQueue()
|
||||
assert queue is not None
|
||||
assert queue._counter == 0
|
||||
|
||||
def test_add_and_get_job(self):
|
||||
"""Test adding a job to the queue and retrieving it."""
|
||||
queue = ImportQueue()
|
||||
job = ImportJob(priority=5, service_name='spotify', item_type='track',
|
||||
item_id='track1', user_id=1)
|
||||
queue.add_job(job)
|
||||
retrieved = queue.get_job(timeout=1.0)
|
||||
assert retrieved is not None
|
||||
assert retrieved.item_id == 'track1'
|
||||
|
||||
def test_get_job_respects_priority(self):
|
||||
"""Test that higher-priority jobs (lower number) are retrieved first."""
|
||||
queue = ImportQueue()
|
||||
low = ImportJob(priority=10, service_name='s', item_type='t', item_id='low', user_id=1)
|
||||
high = ImportJob(priority=1, service_name='s', item_type='t', item_id='high', user_id=1)
|
||||
low_again = ImportJob(priority=10, service_name='s', item_type='t', item_id='low2', user_id=1)
|
||||
queue.add_job(low)
|
||||
queue.add_job(high)
|
||||
queue.add_job(low_again)
|
||||
|
||||
first = queue.get_job(timeout=0.1)
|
||||
assert first.item_id == 'high'
|
||||
|
||||
def test_get_job_empty_returns_none(self):
|
||||
"""Test that get_job returns None when the queue is empty."""
|
||||
queue = ImportQueue()
|
||||
result = queue.get_job(timeout=0.05)
|
||||
assert result is None
|
||||
|
||||
def test_task_done(self):
|
||||
"""Test that task_done can be called after retrieving a job."""
|
||||
queue = ImportQueue()
|
||||
job = ImportJob(priority=5, service_name='s', item_type='t', item_id='1', user_id=1)
|
||||
queue.add_job(job)
|
||||
queue.get_job(timeout=0.1)
|
||||
# Should not raise
|
||||
queue.task_done()
|
||||
|
||||
def test_counter_increments(self):
|
||||
"""Test that internal counter increments with each job added."""
|
||||
queue = ImportQueue()
|
||||
assert queue._counter == 0
|
||||
queue.add_job(ImportJob(priority=1, service_name='s', item_type='t', item_id='1', user_id=1))
|
||||
assert queue._counter == 1
|
||||
queue.add_job(ImportJob(priority=1, service_name='s', item_type='t', item_id='2', user_id=1))
|
||||
assert queue._counter == 2
|
||||
|
||||
def test_fifo_within_same_priority(self):
|
||||
"""Test that jobs with the same priority are retrieved in insertion order (FIFO)."""
|
||||
queue = ImportQueue()
|
||||
first = ImportJob(priority=5, service_name='s', item_type='t', item_id='first', user_id=1)
|
||||
second = ImportJob(priority=5, service_name='s', item_type='t', item_id='second', user_id=1)
|
||||
queue.add_job(first)
|
||||
queue.add_job(second)
|
||||
assert queue.get_job(timeout=0.1).item_id == 'first'
|
||||
assert queue.get_job(timeout=0.1).item_id == 'second'
|
||||
|
||||
def test_thread_safety(self):
|
||||
"""Test that the queue handles concurrent access safely."""
|
||||
queue = ImportQueue()
|
||||
results = []
|
||||
errors = []
|
||||
|
||||
def producer():
|
||||
try:
|
||||
for i in range(5):
|
||||
queue.add_job(ImportJob(
|
||||
priority=i, service_name='s', item_type='t',
|
||||
item_id=str(i), user_id=1,
|
||||
))
|
||||
except Exception as e:
|
||||
errors.append(e)
|
||||
|
||||
def consumer():
|
||||
try:
|
||||
for _ in range(5):
|
||||
job = queue.get_job(timeout=1.0)
|
||||
if job:
|
||||
results.append(job.item_id)
|
||||
queue.task_done()
|
||||
except Exception as e:
|
||||
errors.append(e)
|
||||
|
||||
t1 = threading.Thread(target=producer)
|
||||
t2 = threading.Thread(target=consumer)
|
||||
t1.start()
|
||||
t2.start()
|
||||
t1.join(timeout=5)
|
||||
t2.join(timeout=5)
|
||||
|
||||
assert not errors
|
||||
assert len(results) == 5
|
||||
Reference in New Issue
Block a user