Skip to content

Commit 444002b

Browse files
committed
Merge branch 'main' of github.com:codeforpdx/tenantfirstaid into feat/chat-refactor
2 parents 95d77a3 + d00250a commit 444002b

File tree

15 files changed

+969
-69
lines changed

15 files changed

+969
-69
lines changed

backend/tenantfirstaid/session.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import TypedDict
66
from valkey import Valkey
77
import simplejson as json
8+
from typing import Any, Dict
89

910

1011
class TenantSessionMessage(TypedDict):
@@ -82,15 +83,28 @@ def __init__(self, tenant_session: TenantSession):
8283
self.tenant_session = tenant_session
8384

8485
def dispatch_request(self):
86+
<<<<<<< HEAD
8587
data = request.json
8688
session_id = self.tenant_session.get_flask_session_id()
8789

90+
=======
91+
data: Dict[str, Any] = request.json
92+
session_id = session.get("session_id")
93+
if not session_id:
94+
session_id = str(uuid.uuid4())
95+
session["session_id"] = session_id
96+
>>>>>>> d00250a3c6e48f071c4f7ca0cca4dc686225247a
8897
city = data["city"] or "null"
8998
state = data["state"]
9099

91100
# Initialize the session with city and state
101+
<<<<<<< HEAD
92102
initial_data: TenantSessionData = {"city": city, "state": state, "messages": []}
93103
self.tenant_session.set(initial_data)
104+
=======
105+
initial_data = {"city": city, "state": state, "messages": []}
106+
self.tenant_session.set(session_id, initial_data)
107+
>>>>>>> d00250a3c6e48f071c4f7ca0cca4dc686225247a
94108

95109
return Response(
96110
status=200,

backend/tests/test_session.py

Lines changed: 107 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,34 @@
11
import pytest
2-
from tenantfirstaid.session import TenantSession
2+
from flask import Flask
3+
from tenantfirstaid.session import TenantSession, InitSessionView
4+
from typing import Dict, Any
35

46

57
@pytest.fixture
6-
def mock_valkey(mocker):
7-
"""Mock the Valkey class with the db_con.ping(), db_con.get(), and db_con.set() methods."""
8-
mock_client = mocker.Mock()
9-
mocker.patch("tenantfirstaid.session.Valkey", return_value=mock_client)
8+
def mock_valkey_ping_nop(mocker):
9+
"""Mock the Valkey class with the db_con.ping() method."""
10+
mock_valkey_client = mocker.Mock()
11+
mocker.patch("tenantfirstaid.session.Valkey", return_value=mock_valkey_client)
12+
mock_valkey_client.ping = mocker.Mock()
13+
return mock_valkey_client
14+
1015

11-
_data = {}
16+
@pytest.fixture
17+
def mock_valkey(mock_valkey_ping_nop, mocker):
18+
# mock_valkey_dbcon_client = mocker.Mock()
19+
# mocker.patch("tenantfirstaid.session.Valkey", mock_valkey_dbcon_client)
20+
21+
_data: Dict[str, Any] = {}
1222

13-
mock_client.set = mocker.Mock(
23+
mock_valkey_ping_nop.set = mocker.Mock(
1424
side_effect=lambda key, value: _data.update({key: value})
1525
)
16-
mock_client.get = mocker.Mock(side_effect=lambda key: _data.get(key, None))
17-
mock_client.ping = mocker.Mock()
18-
return mock_client
26+
27+
mock_valkey_ping_nop.get = mocker.Mock(
28+
return_value=lambda key: _data.get(key, None)
29+
)
30+
31+
return mock_valkey_ping_nop
1932

2033

2134
@pytest.fixture
@@ -26,24 +39,37 @@ def mock_environ(monkeypatch):
2639
monkeypatch.setenv("DB_USE_SSL", "false")
2740

2841

29-
def test_session_set_and_get(mock_valkey, mock_environ):
30-
tenant_session = TenantSession()
31-
32-
mock_valkey.get.return_value = '"test_value"'
33-
tenant_session.set("some_session_id", "test_value")
34-
value = tenant_session.get("some_session_id")
35-
assert value == "test_value"
42+
def test_session_init_success(mocker, mock_environ):
43+
test_data = {
44+
"city": "Test City",
45+
"state": "Test State",
46+
}
3647

48+
mock_valkey_client = mocker.Mock()
49+
mocker.patch("tenantfirstaid.session.Valkey", return_value=mock_valkey_client)
50+
mock_valkey_client.ping = mocker.Mock()
3751

38-
def test_session_get_unknown_session_id(mock_valkey, mock_environ):
3952
tenant_session = TenantSession()
53+
app = Flask(__name__)
54+
app.add_url_rule(
55+
"/api/init",
56+
view_func=InitSessionView.as_view("init", tenant_session),
57+
methods=["POST"],
58+
)
59+
app.secret_key = "test_secret_key" # Set a secret key for session management
4060

41-
mock_valkey.get.return_value = None
42-
value = tenant_session.get("some_session_id")
43-
assert value == []
61+
with app.test_request_context("/api/init", method="POST", json=test_data) as reqctx:
62+
assert (
63+
reqctx.session.get("session_id") is None
64+
) # Ensure session_id is NOT set in the request context (before dispatch)
65+
response = app.full_dispatch_request()
66+
assert response.status_code == 200 # Ensure the response is successful
67+
assert (
68+
reqctx.session.get("session_id") is not None
69+
) # Ensure session_id is set in the request context
4470

4571

46-
def test_session_init_ping_exception(mocker, mock_environ, capsys):
72+
def test_session_init_ping_exception(mocker, capsys):
4773
# Patch Valkey so that ping raises an exception
4874
mock_client = mocker.Mock()
4975
mock_client.ping = mocker.Mock(side_effect=Exception("Ping failed"))
@@ -52,3 +78,62 @@ def test_session_init_ping_exception(mocker, mock_environ, capsys):
5278
_obj = TenantSession()
5379
captured = capsys.readouterr()
5480
assert "Ping failed" in captured.out
81+
82+
83+
def test_session_get_unknown_session_id(mocker, mock_environ):
84+
test_data = {
85+
"city": "Test City",
86+
"state": "Test State",
87+
}
88+
89+
mock_valkey_client = mocker.Mock()
90+
mocker.patch("tenantfirstaid.session.Valkey", return_value=mock_valkey_client)
91+
mock_valkey_client.ping = mocker.Mock()
92+
93+
tenant_session = TenantSession()
94+
app = Flask(__name__)
95+
app.add_url_rule(
96+
"/api/init",
97+
view_func=InitSessionView.as_view("init", tenant_session),
98+
methods=["POST"],
99+
)
100+
app.secret_key = "test_secret_key" # Set a secret key for session management
101+
102+
with app.test_request_context("/api/init", method="POST", json=test_data) as reqctx:
103+
assert (
104+
reqctx.session.get("session_id") is None
105+
) # Ensure session_id is NOT set in the request context (before dispatch)
106+
assert tenant_session.get() == {
107+
"city": "",
108+
"state": "",
109+
"messages": [],
110+
}
111+
112+
113+
# def test_session_set_and_get(mocker, mock_environ, mock_valkey):
114+
# test_data: Dict[str, Any] = {
115+
# "city": "Test City",
116+
# "state": "Test State",
117+
# "messages": ["this is message 1", "this is message 2"],
118+
# }
119+
120+
# mock_valkey_client = mocker.Mock()
121+
# mocker.patch("tenantfirstaid.session.Valkey", return_value=mock_valkey_client)
122+
# mock_valkey_client.ping = mocker.Mock()
123+
124+
# tenant_session = TenantSession()
125+
# app = Flask(__name__)
126+
# app.add_url_rule(
127+
# "/api/init",
128+
# view_func=InitSessionView.as_view("init", tenant_session),
129+
# methods=["POST"],
130+
# )
131+
# app.secret_key = "test_secret_key" # Set a secret key for session management
132+
133+
# with app.test_request_context("/api/init", method="POST", json=test_data):
134+
# response = app.full_dispatch_request()
135+
# assert response.status_code == 200 # Ensure the response is successful
136+
# session_id = response.json["session_id"]
137+
138+
# tenant_session.set(session_id, test_data)
139+
# assert tenant_session.get() == test_data

frontend/src/About.tsx

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,10 @@
1-
import { useNavigate } from "react-router-dom";
1+
import BackLink from "./shared/components/BackLink";
22

33
export default function About() {
4-
const navigate = useNavigate();
5-
64
return (
7-
<div className="flex items-center h-dvh pt-16 sm:pt-0">
5+
<div className="flex items-center pt-16 sm:mt-26 sm:pt-0">
86
<div className="relative max-w-2xl m-auto p-8 bg-[#F4F4F2] rounded-lg shadow-md">
9-
<button
10-
className="absolute top-4 left-4 flex text-[#4a90e2] hover:text-[#3a7bc8] font-semibold cursor-pointer"
11-
onClick={() => navigate(-1)}
12-
aria-label="Go back"
13-
>
14-
<svg
15-
className="w-6 h-6 mr-2"
16-
fill="none"
17-
stroke="currentColor"
18-
strokeWidth={2}
19-
viewBox="0 0 24 24"
20-
>
21-
<path
22-
strokeLinecap="round"
23-
strokeLinejoin="round"
24-
d="M15 19l-7-7 7-7"
25-
/>
26-
</svg>
27-
Back
28-
</button>
7+
<BackLink />
298
<p className="my-6">
309
<strong>Tenant First Aid</strong> is an AI-powered chatbot designed to
3110
help tenants navigate rental issues, answer questions, and provides

frontend/src/App.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import Chat from "./Chat";
33
import About from "./About";
44
import SessionContextProvider from "./contexts/SessionContext";
55
import Navbar from "./pages/Chat/components/Navbar";
6+
import Disclaimer from "./Disclaimer";
7+
import PrivacyPolicy from "./PrivacyPolicy";
68

79
export default function App() {
810
return (
@@ -12,6 +14,8 @@ export default function App() {
1214
<Routes>
1315
<Route path="/" element={<Chat />} />
1416
<Route path="/about" element={<About />} />
17+
<Route path="/disclaimer" element={<Disclaimer />} />
18+
<Route path="/privacy-policy" element={<PrivacyPolicy />} />
1519
</Routes>
1620
</Router>
1721
</SessionContextProvider>

0 commit comments

Comments
 (0)