Merge dev to main: Security improvements and comprehensive test infrastructure #39
@@ -25,14 +25,37 @@ jobs:
|
||||
python3 --version
|
||||
pip3 --version
|
||||
|
||||
- name: Cache Python dependencies
|
||||
id: cache-python
|
||||
run: |
|
||||
CACHE_KEY="python-$(md5sum dashboard/backend/requirements.txt dashboard/backend/requirements-dev.txt | md5sum | cut -d' ' -f1)"
|
||||
CACHE_DIR="/tmp/pytest-cache/$CACHE_KEY"
|
||||
echo "CACHE_DIR=$CACHE_DIR" >> $GITHUB_ENV
|
||||
if [ -d "$CACHE_DIR" ]; then
|
||||
echo "Cache hit for $CACHE_KEY"
|
||||
echo "cache-hit=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Cache miss for $CACHE_KEY"
|
||||
echo "cache-hit=false" >> $GITHUB_OUTPUT
|
||||
mkdir -p "$CACHE_DIR"
|
||||
fi
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd dashboard/backend
|
||||
python3 -m venv venv
|
||||
. venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-dev.txt
|
||||
pip install pytest-timeout
|
||||
if [ "${{ steps.cache-python.outputs.cache-hit }}" = "true" ]; then
|
||||
echo "Restoring from cache..."
|
||||
cp -r $CACHE_DIR/venv .
|
||||
else
|
||||
echo "Installing fresh dependencies..."
|
||||
python3 -m venv venv
|
||||
. venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
pip install -r requirements-dev.txt
|
||||
pip install pytest-timeout
|
||||
# Save to cache
|
||||
cp -r venv $CACHE_DIR/
|
||||
fi
|
||||
|
||||
- name: Run unit tests
|
||||
run: |
|
||||
@@ -62,12 +85,35 @@ jobs:
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
- name: Cache Node dependencies
|
||||
id: cache-node
|
||||
run: |
|
||||
CACHE_KEY="node-$(md5sum dashboard/frontend/package-lock.json | cut -d' ' -f1)"
|
||||
CACHE_DIR="/tmp/npm-cache/$CACHE_KEY"
|
||||
echo "CACHE_DIR=$CACHE_DIR" >> $GITHUB_ENV
|
||||
if [ -d "$CACHE_DIR" ]; then
|
||||
echo "Cache hit for $CACHE_KEY"
|
||||
echo "cache-hit=true" >> $GITHUB_OUTPUT
|
||||
else
|
||||
echo "Cache miss for $CACHE_KEY"
|
||||
echo "cache-hit=false" >> $GITHUB_OUTPUT
|
||||
mkdir -p "$CACHE_DIR"
|
||||
fi
|
||||
|
||||
- name: Install dependencies
|
||||
env:
|
||||
NODE_OPTIONS: "--max-old-space-size=2048"
|
||||
run: |
|
||||
cd dashboard/frontend
|
||||
npm ci
|
||||
if [ "${{ steps.cache-node.outputs.cache-hit }}" = "true" ]; then
|
||||
echo "Restoring from cache..."
|
||||
cp -r $CACHE_DIR/node_modules .
|
||||
else
|
||||
echo "Installing fresh dependencies..."
|
||||
npm ci
|
||||
# Save to cache
|
||||
cp -r node_modules $CACHE_DIR/
|
||||
fi
|
||||
|
||||
- name: Run tests
|
||||
env:
|
||||
|
||||
@@ -195,7 +195,7 @@ class TestLogoutFlow:
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["message"] == "Logged out successfully"
|
||||
assert data["ok"] is True
|
||||
|
||||
def test_logout_clears_cookies(self, test_app, mock_config, temp_auth_file, admin_headers):
|
||||
"""Test that logout clears auth cookies."""
|
||||
@@ -206,10 +206,12 @@ class TestLogoutFlow:
|
||||
# TestClient doesn't fully simulate cookie deletion, but we can check response
|
||||
|
||||
def test_logout_without_auth(self, test_app, mock_config, temp_auth_file):
|
||||
"""Test logout without authentication."""
|
||||
"""Test logout without authentication - should succeed as logout doesn't require auth."""
|
||||
response = test_app.post("/api/auth/logout")
|
||||
|
||||
assert response.status_code == 401
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["ok"] is True
|
||||
|
||||
|
||||
class TestUserInfo:
|
||||
@@ -281,7 +283,7 @@ class TestPasswordChange:
|
||||
"/api/auth/change-password",
|
||||
headers=admin_headers,
|
||||
json={
|
||||
"old_password": old_password,
|
||||
"current_password": old_password,
|
||||
"new_password": new_password
|
||||
}
|
||||
)
|
||||
@@ -298,19 +300,19 @@ class TestPasswordChange:
|
||||
"/api/auth/change-password",
|
||||
headers=admin_headers,
|
||||
json={
|
||||
"old_password": "wrong_password",
|
||||
"current_password": "wrong_password",
|
||||
"new_password": "new_password_123"
|
||||
}
|
||||
)
|
||||
|
||||
assert response.status_code == 401
|
||||
assert response.status_code == 400
|
||||
|
||||
def test_change_password_without_auth(self, test_app, mock_config, temp_auth_file):
|
||||
"""Test password change without authentication."""
|
||||
response = test_app.post(
|
||||
"/api/auth/change-password",
|
||||
json={
|
||||
"old_password": "old",
|
||||
"current_password": "old",
|
||||
"new_password": "new"
|
||||
}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user