Skip to content

Commit

Permalink
Merge pull request #201 from mmikita95/dev
Browse files Browse the repository at this point in the history
Making existing tests location-agnostic; add conditional check for server static path before mounting
  • Loading branch information
ramedina86 authored Jan 24, 2024
2 parents be9663e + ddfadff commit 347850b
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 20 deletions.
24 changes: 21 additions & 3 deletions src/streamsync/serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import mimetypes
from contextlib import asynccontextmanager
import sys
import textwrap
from typing import Any, Callable, Dict, List, Optional, Set, Union
import typing
from fastapi import FastAPI, Request, HTTPException
Expand Down Expand Up @@ -41,7 +42,9 @@ async def lifespan(app: FastAPI):
app_runner.hook_to_running_event_loop()
app_runner.load()

if on_load is not None:
if on_load is not None \
and hasattr(app.state, 'is_server_static_mounted') \
and app.state.is_server_static_mounted:
on_load()

try:
Expand Down Expand Up @@ -359,8 +362,23 @@ async def stream(websocket: WebSocket):

server_path = os.path.dirname(__file__)
server_static_path = pathlib.Path(server_path) / "static"
asgi_app.mount(
"/", StaticFiles(directory=str(server_static_path), html=True), name="server_static")
if server_static_path.exists():
asgi_app.mount(
"/", StaticFiles(directory=str(server_static_path), html=True), name="server_static")
asgi_app.state.is_server_static_mounted = True
else:
logging.error(
textwrap.dedent(
"""\
\x1b[31;20mError: Failed to acquire server static path. Streamsync may not be properly built.
To resolve this issue, try the following steps:
1. Run the 'npm run build' script in the 'ui' directory and then restart the app.
2. Alternatively, launch a UI instance by running 'npm run dev' in the 'ui' directory.
Please refer to the CONTRIBUTING.md for detailed instructions.\x1b[0m"""
)
)

# Return

Expand Down
3 changes: 3 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from pathlib import Path

test_app_dir = Path(__file__).resolve().parent / 'testapp'
16 changes: 9 additions & 7 deletions tests/test_app_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
from streamsync.ss_types import EventRequest, InitSessionRequest, InitSessionRequestPayload, StreamsyncEvent
import asyncio

from tests import test_app_dir

class TestAppRunner:

numberinput_instance_path = [
Expand All @@ -26,11 +28,11 @@ def test_init_wrong_path(self) -> None:

def test_init_wrong_mode(self) -> None:
with pytest.raises(ValueError):
AppRunner("./testapp", "virus")
AppRunner(test_app_dir, "virus")

@pytest.mark.asyncio
async def test_pre_session(self) -> None:
ar = AppRunner("./testapp", "run")
ar = AppRunner(test_app_dir, "run")
er = EventRequest(
type="event",
payload=StreamsyncEvent(
Expand All @@ -48,7 +50,7 @@ async def test_pre_session(self) -> None:

@pytest.mark.asyncio
async def test_valid_session_invalid_event(self) -> None:
ar = AppRunner("./testapp", "run")
ar = AppRunner(test_app_dir, "run")
ar.load()
si = InitSessionRequest(
type="sessionInit",
Expand All @@ -74,7 +76,7 @@ async def test_valid_session_invalid_event(self) -> None:

@pytest.mark.asyncio
async def test_valid_event(self) -> None:
ar = AppRunner("./testapp", "run")
ar = AppRunner(test_app_dir, "run")
ar.load()
si = InitSessionRequest(
type="sessionInit",
Expand Down Expand Up @@ -103,7 +105,7 @@ async def test_valid_event(self) -> None:

@pytest.mark.asyncio
async def test_bad_event_handler(self) -> None:
ar = AppRunner("./testapp", "run")
ar = AppRunner(test_app_dir, "run")
ar.load()
si = InitSessionRequest(
type="sessionInit",
Expand Down Expand Up @@ -131,7 +133,7 @@ async def test_bad_event_handler(self) -> None:
ar.shut_down()

def test_run_code_edit(self) -> None:
ar = AppRunner("./testapp", "run")
ar = AppRunner(test_app_dir, "run")
with pytest.raises(PermissionError):
ar.update_code(None, "exec(virus)")
with pytest.raises(PermissionError):
Expand All @@ -151,7 +153,7 @@ async def wait_for_code_update(self, app_runner: AppRunner) -> None:

@pytest.mark.asyncio
async def test_code_update(self) -> None:
ar = AppRunner("./testapp", "edit")
ar = AppRunner(test_app_dir, "edit")
ar.hook_to_running_event_loop()
ar.load()
wait_update_task = asyncio.create_task(self.wait_for_code_update(ar))
Expand Down
11 changes: 7 additions & 4 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
import pyarrow as pa
import urllib

from pathlib import Path
from tests import test_app_dir

raw_state_dict = {
"name": "Robert",
"age": 1,
Expand All @@ -34,7 +37,7 @@
}

sc = None
with open("testapp/ui.json", "r") as f:
with open(test_app_dir / "ui.json", "r") as f:
sc = json.load(f).get("components")

ss.Config.is_mail_enabled_for_log = True
Expand Down Expand Up @@ -365,7 +368,7 @@ def test_date_change(self) -> None:

class TestFileWrapper():

file_path = "testapp/assets/myfile.csv"
file_path = str(test_app_dir / "assets/myfile.csv")

def test_get_as_dataurl(self) -> None:
fw = FileWrapper(self.file_path, "text/plain")
Expand All @@ -382,8 +385,8 @@ def test_get_as_dataurl(self) -> None:
class TestStateSerialiser():

sts = StateSerialiser()
file_path = "testapp/assets/myfile.csv"
df_path = "testapp/assets/main_df.csv"
file_path = str(test_app_dir / "assets/myfile.csv")
df_path = str(test_app_dir / "assets/main_df.csv")

def test_nested_dict(self) -> None:
d = {
Expand Down
14 changes: 8 additions & 6 deletions tests/test_serve.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@
import fastapi.testclient
import pytest

from tests import test_app_dir


class TestServe:

def test_valid(self) -> None:
asgi_app: fastapi.FastAPI = streamsync.serve.get_asgi_app(
"./testapp", "run")
test_app_dir, "run")
with fastapi.testclient.TestClient(asgi_app) as client:
res = client.post("/api/init", json={
"proposedSessionId": None
Expand Down Expand Up @@ -46,7 +48,7 @@ def test_valid(self) -> None:

def test_bad_session(self) -> None:
asgi_app: fastapi.FastAPI = streamsync.serve.get_asgi_app(
"./testapp", "run")
test_app_dir, "run")
with fastapi.testclient.TestClient(asgi_app) as client:
with client.websocket_connect("/api/stream") as websocket:
websocket.send_json({
Expand All @@ -61,7 +63,7 @@ def test_bad_session(self) -> None:

def test_session_verifier_header(self) -> None:
asgi_app: fastapi.FastAPI = streamsync.serve.get_asgi_app(
"./testapp", "run")
test_app_dir, "run")
with fastapi.testclient.TestClient(asgi_app) as client:
res = client.post("/api/init", json={
"proposedSessionId": None
Expand All @@ -73,7 +75,7 @@ def test_session_verifier_header(self) -> None:

def test_session_verifier_cookies(self) -> None:
asgi_app: fastapi.FastAPI = streamsync.serve.get_asgi_app(
"./testapp", "run")
test_app_dir, "run")
with fastapi.testclient.TestClient(asgi_app, cookies={
"fail_cookie": "yes"
}) as client:
Expand All @@ -86,7 +88,7 @@ def test_session_verifier_cookies(self) -> None:

def test_session_verifier_pass(self) -> None:
asgi_app: fastapi.FastAPI = streamsync.serve.get_asgi_app(
"./testapp", "run")
test_app_dir, "run")
with fastapi.testclient.TestClient(asgi_app, cookies={
"another_cookie": "yes"
}) as client:
Expand All @@ -102,7 +104,7 @@ def test_serve_javascript_file_with_a_valid_content_type(self) -> None:
# Arrange
mimetypes.add_type("text/plain", ".js")

asgi_app: fastapi.FastAPI = streamsync.serve.get_asgi_app("./testapp", "run")
asgi_app: fastapi.FastAPI = streamsync.serve.get_asgi_app(test_app_dir, "run")
with fastapi.testclient.TestClient(asgi_app) as client:
# Acts
res = client.get("/static/file.js")
Expand Down

0 comments on commit 347850b

Please sign in to comment.