Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions backend/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,21 @@ def get_db():
db.close()


@app.get("/tests", response_model=list[schemas.TestRecord])
@app.get("/tests", response_model=schemas.TestsResponse)
def read_tests(db: Session = Depends(get_db)):
return db.query(models.TestRecord).all()
"""Return all stored test records.

If the database is empty a friendly message is included in the response so
that browsing to ``/tests`` does not simply yield an empty page.
"""

records = db.query(models.TestRecord).all()
if not records:
return {
"message": "No test records found. POST to /tests to create one.",
"records": [],
}
return {"records": records}


@app.post("/tests", response_model=schemas.TestRecord)
Expand Down
13 changes: 13 additions & 0 deletions backend/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,16 @@ class TestRecord(TestRecordBase):

class Config:
from_attributes = True


class TestsResponse(BaseModel):
"""Response model for ``GET /tests``.

When there are no records in the database we return an empty ``records``
list together with a human friendly ``message`` that guides the user to
create their first test record. This prevents the endpoint from appearing
"empty" when accessed in a browser.
"""

message: str | None = None
records: list[TestRecord] = []
26 changes: 20 additions & 6 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@ interface TestRecord {
test_target?: string | null;
}

interface TestsResponse {
message?: string;
records: TestRecord[];
}

function App() {
const [info, setInfo] = useState<TestRecord | null>(null);
const [records, setRecords] = useState<TestRecord[]>([]);
const [recordsMessage, setRecordsMessage] = useState<string | null>(null);
const [pingTarget, setPingTarget] = useState('8.8.8.8');
const [pingOutput, setPingOutput] = useState<string | null>(null);

Expand All @@ -36,7 +42,11 @@ function App() {
const loadRecords = async () => {
try {
const res = await fetch('/tests');
setRecords(await res.json());
const data: TestsResponse = await res.json();
setRecords(data.records || []);
if (data.message) {
setRecordsMessage(data.message);
}
} catch (err) {
console.error('Failed to load previous tests', err);
}
Expand Down Expand Up @@ -77,9 +87,9 @@ function App() {
<div>Loading...</div>
)}

{records.length > 0 && (
<div className="space-y-2">
<h2 className="text-xl mb-2 text-center">Recent Tests</h2>
<div className="space-y-2">
<h2 className="text-xl mb-2 text-center">Recent Tests</h2>
{records.length > 0 ? (
<ul className="text-sm space-y-1">
{records
.slice(-5)
Expand All @@ -91,8 +101,12 @@ function App() {
</li>
))}
</ul>
</div>
)}
) : (
<div className="text-sm text-center text-gray-400">
{recordsMessage || 'No test records found. Run a test to get started.'}
</div>
)}
</div>

<div className="space-y-2 text-center">
<h2 className="text-xl mb-2">Manual Tests</h2>
Expand Down