Add isRinging query to check alarm state via API
Features: - New GraphQL query 'isRinging' returns true/false if wecker is active - Checks the wecker process via PID file (PID_FILE in common.py) DRY refactoring: - Extract PID_FILE into shared common.py module - Both wecker.py and api/schema.py import from common - DRY enforcement tests verify identity (is) not just equality Tests: - test_is_ringing_returns_false_when_not_running - test_is_ringing_returns_true_when_running - test_pid_file_defined_once_across_modules (DRY enforcement) - test_pid_file_same_shared_constant_in_api (DRY enforcement) - Cleaned up unused imports in test_single_instance.py Docs: - Updated README.md with isRinging query documentation
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
from unittest.mock import patch
|
||||
from fastapi.testclient import TestClient
|
||||
import tempfile
|
||||
import os
|
||||
@@ -14,6 +15,33 @@ from api.main import app # noqa: E402
|
||||
client = TestClient(app)
|
||||
|
||||
|
||||
def test_is_ringing_returns_false_when_not_running():
|
||||
"""Test that isRinging returns False when no wecker process is running."""
|
||||
headers = {"X-API-Key": "test-secret"}
|
||||
query = """
|
||||
query {
|
||||
isRinging
|
||||
}
|
||||
"""
|
||||
res = client.post("/graphql", json={"query": query}, headers=headers)
|
||||
assert res.status_code == 200
|
||||
assert res.json()["data"]["isRinging"] is False
|
||||
|
||||
|
||||
@patch("api.schema.is_wecker_ringing", return_value=True)
|
||||
def test_is_ringing_returns_true_when_running(mock_is_ringing):
|
||||
"""Test that isRinging returns True when a wecker process is running."""
|
||||
headers = {"X-API-Key": "test-secret"}
|
||||
query = """
|
||||
query {
|
||||
isRinging
|
||||
}
|
||||
"""
|
||||
res = client.post("/graphql", json={"query": query}, headers=headers)
|
||||
assert res.status_code == 200
|
||||
assert res.json()["data"]["isRinging"] is True
|
||||
|
||||
|
||||
def test_auth_missing():
|
||||
query = """
|
||||
query {
|
||||
@@ -173,3 +201,13 @@ def test_graphql_workflow():
|
||||
# 7. List again is empty
|
||||
res = client.post("/graphql", json={"query": query_get}, headers=headers)
|
||||
assert res.json()["data"]["getAlarms"] == []
|
||||
|
||||
|
||||
def test_pid_file_same_shared_constant_in_api():
|
||||
"""Ensure api.schema uses the same PID_FILE from common, not a redefinition."""
|
||||
from api import schema as api_schema
|
||||
import common
|
||||
|
||||
assert api_schema.PID_FILE is common.PID_FILE, (
|
||||
"api.schema.PID_FILE must reference common.PID_FILE, not redefine it"
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import sys
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from unittest.mock import patch
|
||||
|
||||
import common
|
||||
import wecker
|
||||
|
||||
# We need to mock the PID file existence and os.kill to test the logic
|
||||
@@ -80,3 +80,17 @@ def test_remove_pid_file_wrong_pid(mock_pid_file):
|
||||
|
||||
wecker.remove_pid_file()
|
||||
assert mock_pid_file.exists()
|
||||
|
||||
|
||||
def test_pid_file_defined_once_across_modules():
|
||||
"""
|
||||
DRY principle: PID_FILE must be defined in common.py and imported by
|
||||
both wecker.py and api/schema.py — not redefined in each.
|
||||
"""
|
||||
# wecker.py imports PID_FILE from common — verify it's the same object
|
||||
assert wecker.PID_FILE is common.PID_FILE, (
|
||||
"wecker.PID_FILE must reference common.PID_FILE, not redefine it"
|
||||
)
|
||||
|
||||
# Verify the path ends with "wecker.pid"
|
||||
assert common.PID_FILE.endswith("wecker.pid")
|
||||
|
||||
Reference in New Issue
Block a user