Skip to content

Commit 8e0b7dc

Browse files
authored
Merge pull request #30 from simonsobs/dev
Add tests
2 parents 708a4d7 + a4b4e02 commit 8e0b7dc

File tree

8 files changed

+112
-3
lines changed

8 files changed

+112
-3
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from os import PathLike
2+
from pathlib import Path
3+
4+
from graphql import parse, print_ast
5+
6+
7+
def read_gql(path: PathLike | str) -> str:
8+
'''Load a GraphQL query from a file while checking its syntax.'''
9+
10+
text = Path(path).read_text()
11+
parsed = parse(text)
12+
reformatted = print_ast(parsed)
13+
return reformatted
14+
15+
16+
pwd = Path(__file__).resolve().parent
17+
18+
19+
sub = pwd / 'queries'
20+
QUERY_VERSION = read_gql(sub / 'Version.gql')
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
query Version {
2+
alert {
3+
version
4+
}
5+
}

tests/schema/__init__.py

Whitespace-only changes.

tests/schema/conftest.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import pytest
2+
from strawberry import Schema
3+
4+
from nextline_alert.schema import Query
5+
6+
7+
@pytest.fixture(scope='session')
8+
def schema() -> Schema:
9+
'''GraphQL schema
10+
11+
The scope is `session` because Hypothesis doesn't allow function-scoped
12+
fixtures. This is fine as the schema is stateless.
13+
'''
14+
return Schema(query=Query)

tests/schema/queries/__init__.py

Whitespace-only changes.

tests/schema/queries/test_version.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from strawberry.types import ExecutionResult
2+
3+
import nextline_alert
4+
from nextline_alert.graphql import QUERY_VERSION
5+
from tests.schema.conftest import Schema
6+
7+
8+
async def test_schema(schema: Schema) -> None:
9+
resp = await schema.execute(QUERY_VERSION)
10+
assert isinstance(resp, ExecutionResult)
11+
assert resp.data
12+
assert resp.data['alert']['version'] == nextline_alert.__version__

tests/test_emitter.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import asyncio
22
import json
3+
import logging
34
import time
45

56
import pytest
@@ -9,16 +10,16 @@
910
from nextline_alert.emitter import Emitter
1011

1112

12-
def func_success():
13+
def func_success(): # pragma: no cover
1314
time.sleep(0.001)
1415

1516

16-
def func_raise_ignore():
17+
def func_raise_ignore(): # pragma: no cover
1718
time.sleep(0.001)
1819
raise KeyboardInterrupt
1920

2021

21-
def func_raise():
22+
def func_raise(): # pragma: no cover
2223
time.sleep(0.001)
2324
raise ValueError('test')
2425

@@ -72,3 +73,39 @@ async def test_emit_alert() -> None:
7273
description = data['alerts'][0]['annotations']['description']
7374
assert platform == labels['platform']
7475
assert 'ValueError' in description
76+
77+
78+
@respx.mock
79+
async def test_emit_exception(caplog: pytest.LogCaptureFixture) -> None:
80+
nextline = Nextline(func_raise)
81+
82+
url = 'http://localhost:5000/alerts'
83+
platform = 'pytest'
84+
emitter = Emitter(url=url, platform=platform)
85+
assert nextline.register(emitter)
86+
87+
# Mock the HTTP POST request
88+
route = respx.post(url).respond(status_code=500)
89+
90+
# Run a script that raises an exception and fails to emit an alert
91+
with caplog.at_level(logging.ERROR):
92+
async with nextline:
93+
event = asyncio.Event()
94+
await nextline.run_continue_and_wait(event)
95+
96+
# Assert the log message
97+
records = [r for r in caplog.records if r.name == Emitter.__module__]
98+
assert len(records) == 1
99+
assert records[0].levelname == 'ERROR'
100+
assert 'Failed to emit alert' in records[0].message
101+
102+
# Assert the HTTP POST request
103+
assert route.called
104+
assert len(route.calls) == 1
105+
call = route.calls[0]
106+
assert url == call.request.url
107+
data = json.loads(call.request.content)
108+
labels = data['alerts'][0]['labels']
109+
description = data['alerts'][0]['annotations']['description']
110+
assert platform == labels['platform']
111+
assert 'ValueError' in description

tests/test_plugin.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import asyncio
2+
from collections.abc import AsyncIterator
3+
4+
import pytest
5+
6+
from nextline_alert.graphql import QUERY_VERSION
7+
from nextlinegraphql import create_app
8+
from nextlinegraphql.plugins.graphql.test import TestClient, gql_request
9+
10+
11+
@pytest.fixture
12+
async def client() -> AsyncIterator[TestClient]:
13+
app = create_app() # the plugin is loaded here
14+
async with TestClient(app) as y:
15+
await asyncio.sleep(0)
16+
yield y
17+
18+
19+
async def test_plugin(client: TestClient) -> None:
20+
data = await gql_request(client, QUERY_VERSION)
21+
assert data

0 commit comments

Comments
 (0)