"""Regression tests for the QotNews API server. Run unit tests from this directory with ``python tests.py`` (or ``python -m unittest``). They mock network calls and use an in-memory database. Live integrations are opt-in: run ``QOTNEWS_RUN_INTEGRATION=1 python tests.py`` to call configured services and public feed APIs. The Meilisearch integration test creates and removes a temporary ``qotnews_test`` index. """ import contextlib import datetime import io import json import os import sys import time import unittest from types import SimpleNamespace from unittest import mock # The application modules use top-level imports (``import settings``), so make # this file runnable both from apiserver/ and from the repository root. APISERVER_DIR = os.path.dirname(os.path.abspath(__file__)) if APISERVER_DIR not in sys.path: sys.path.insert(0, APISERVER_DIR) import database import feed import search import utils from feeds import hackernews, lobsters, manual, reddit, tildes class UtilityTests(unittest.TestCase): def test_generated_ids_have_expected_length_and_alphabet(self): value = utils.gen_rand_id() self.assertEqual(len(value), utils.NUM_ID_CHARS) self.assertTrue(value.isalpha()) self.assertTrue(value.isupper()) def test_render_markdown_handles_empty_and_formatted_input(self): self.assertEqual(utils.render_md(''), '') self.assertIn('bold', utils.render_md('**bold**')) def test_clean_removes_disallowed_markup(self): cleaned = utils.clean('
safe
') self.assertIn('safe
', cleaned) self.assertNotIn('