Skip to content

Commit 6ef63c2

Browse files
committed
fixe front/back test ci
1 parent b9e06c0 commit 6ef63c2

19 files changed

Lines changed: 686 additions & 215 deletions

File tree

.github/workflows/ci.yml

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -120,26 +120,26 @@ jobs:
120120
poetry config virtualenvs.create false
121121
poetry install --no-root
122122
123-
# - name: Run Ruff linter
124-
# working-directory: backend
125-
# run: |
126-
# ruff check app/ --output-format=github
127-
# ruff format app/ --check
128-
129-
# - name: Run Bandit security checks
130-
# working-directory: backend
131-
# run: |
132-
# poetry install bandit
133-
# bandit -r app/ -f json -o bandit-report.json
134-
# continue-on-error: true
135-
136-
# - name: Upload Bandit results
137-
# if: always()
138-
# uses: github/codeql-action/upload-sarif@v3
139-
# with:
140-
# sarif_file: "backend/bandit-report.json"
141-
# category: "bandit"
142-
# continue-on-error: true
123+
- name: Run Ruff linter
124+
working-directory: backend
125+
run: |
126+
poetry run ruff check app/ --output-format=github
127+
poetry run ruff format app/ --check
128+
129+
- name: Run Bandit security checks
130+
working-directory: backend
131+
run: |
132+
poetry add bandit
133+
poetry runbandit -r app/ -f json -o bandit-report.json
134+
continue-on-error: true
135+
136+
- name: Upload Bandit results
137+
if: always()
138+
uses: github/codeql-action/upload-sarif@v3
139+
with:
140+
sarif_file: "backend/bandit-report.json"
141+
category: "bandit"
142+
continue-on-error: true
143143

144144
- name: Run pytest with coverage
145145
working-directory: backend
@@ -233,7 +233,7 @@ jobs:
233233

234234
- name: Run ESLint
235235
working-directory: frontend
236-
run: npm run lint -- --format json --output-file eslint-report.json
236+
run: npx eslint "src/**/*.{ts,tsx,js,jsx}" -f json -o eslint-report.jso
237237
continue-on-error: true
238238

239239
- name: Run TypeScript type-check

backend/app/api/game.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,22 @@
88
from app.core.security import get_current_user # JWT-based dependency
99
from typing import Optional
1010

11-
router = APIRouter(
12-
prefix="/games",
13-
tags=["Games"]
14-
)
11+
router = APIRouter(prefix="/games", tags=["Games"])
12+
1513

1614
# -----------------------------
1715
# Create a new game
1816
# -----------------------------
1917
# -----------------------------
2018
# Create a new game
2119
# -----------------------------
22-
@router.post("/create_game", response_model=GameResponse, status_code=status.HTTP_201_CREATED)
20+
@router.post(
21+
"/create_game", response_model=GameResponse, status_code=status.HTTP_201_CREATED
22+
)
2323
def create_game(
2424
payload: Optional[GameCreate] = None, # if you want extra info later
2525
current_user: User = Depends(get_current_user),
26-
db: Session = Depends(get_db)
26+
db: Session = Depends(get_db),
2727
):
2828
"""
2929
Create a new game for the current user. Player2 is optional and can join later.
@@ -32,11 +32,11 @@ def create_game(
3232
new_game = Game(
3333
game_id=uuid.uuid4(),
3434
player1=current_user.id,
35-
player2=None, # nullable, will join later
36-
board=[" "] * 9, # initialize empty board as JSON list
35+
player2=None, # nullable, will join later
36+
board=[" "] * 9, # initialize empty board as JSON list
3737
current_turn=current_user.id,
3838
winner=None,
39-
status="in_progress"
39+
status="in_progress",
4040
)
4141

4242
db.add(new_game)
@@ -50,14 +50,15 @@ def create_game(
5050
# Make a move
5151
# -----------------------------
5252
@router.post("/move")
53-
def make_move(payload: MoveRequest, current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
53+
def make_move(
54+
payload: MoveRequest,
55+
current_user: User = Depends(get_current_user),
56+
db: Session = Depends(get_db),
57+
):
5458

5559
# Fetch the game and lock it for update
5660
game = (
57-
db.query(Game)
58-
.filter(Game.game_id == payload.game_id)
59-
.with_for_update()
60-
.first()
61+
db.query(Game).filter(Game.game_id == payload.game_id).with_for_update().first()
6162
)
6263

6364
if not game:
@@ -67,7 +68,7 @@ def make_move(payload: MoveRequest, current_user: User = Depends(get_current_use
6768
return {
6869
"message": "Game already finished",
6970
"board": game.board,
70-
"winner": game.winner
71+
"winner": game.winner,
7172
}
7273

7374
if game.current_turn != current_user.id:
@@ -109,15 +110,19 @@ def make_move(payload: MoveRequest, current_user: User = Depends(get_current_use
109110
"message": "Move applied",
110111
"board": game.board,
111112
"current_turn": game.current_turn,
112-
"winner": game.winner
113+
"winner": game.winner,
113114
}
114115

115116

116117
# -----------------------------
117118
# Get game state
118119
# -----------------------------
119120
@router.get("/{game_id}", response_model=GameResponse)
120-
def get_game_state(game_id: uuid.UUID, current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
121+
def get_game_state(
122+
game_id: uuid.UUID,
123+
current_user: User = Depends(get_current_user),
124+
db: Session = Depends(get_db),
125+
):
121126

122127
game = db.query(Game).filter(Game.game_id == game_id).first()
123128

@@ -126,6 +131,8 @@ def get_game_state(game_id: uuid.UUID, current_user: User = Depends(get_current_
126131

127132
# Optional: restrict to players only
128133
if current_user.id not in [game.player1, game.player2]:
129-
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Not a player in this game")
134+
raise HTTPException(
135+
status_code=status.HTTP_403_FORBIDDEN, detail="Not a player in this game"
136+
)
130137

131-
return game
138+
return game

backend/app/api/health.py

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ def liveness():
2020
Returns basic status and uptime.
2121
"""
2222
return HealthResponse(
23-
status="healthy",
24-
details={"uptime_seconds": int(time.time() - START_TIME)}
23+
status="healthy", details={"uptime_seconds": int(time.time() - START_TIME)}
2524
)
2625

2726

@@ -36,15 +35,9 @@ def readiness(db: Session = Depends(get_db)):
3635
"""
3736
try:
3837
db.execute(text("SELECT 1"))
39-
return HealthResponse(
40-
status="healthy",
41-
details={"database": "connected"}
42-
)
38+
return HealthResponse(status="healthy", details={"database": "connected"})
4339
except Exception:
44-
return HealthResponse(
45-
status="unhealthy",
46-
details={"database": "not reachable"}
47-
)
40+
return HealthResponse(status="unhealthy", details={"database": "not reachable"})
4841

4942

5043
# -------------------------
@@ -68,6 +61,6 @@ def health(db: Session = Depends(get_db)):
6861
status=overall_status,
6962
details={
7063
"database": db_status,
71-
"uptime_seconds": int(time.time() - START_TIME)
72-
}
73-
)
64+
"uptime_seconds": int(time.time() - START_TIME),
65+
},
66+
)

backend/app/api/users.py

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,27 @@
77
from app.schemas.user import UserCreate, UserResponse
88
from app.core.security import get_current_user, create_access_token
99

10+
router = APIRouter(prefix="/users", tags=["Users"])
1011

11-
router = APIRouter(
12-
prefix="/users",
13-
tags=["Users"]
14-
)
1512

1613
# -----------------------
1714
# Register User
1815
# -----------------------
19-
@router.post("/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED)
16+
@router.post(
17+
"/register", response_model=UserResponse, status_code=status.HTTP_201_CREATED
18+
)
2019
def register(user: UserCreate, db: Session = Depends(get_db)):
2120

2221
# Check if username already exists
2322
existing_user = db.query(User).filter(User.username == user.username).first()
2423
if existing_user:
2524
raise HTTPException(
26-
status_code=status.HTTP_400_BAD_REQUEST,
27-
detail="Username already exists"
25+
status_code=status.HTTP_400_BAD_REQUEST, detail="Username already exists"
2826
)
2927

3028
# Create user
3129
new_user = User(
32-
username=user.username,
33-
password=hash_password(user.password),
34-
wins=0
30+
username=user.username, password=hash_password(user.password), wins=0
3531
)
3632

3733
db.add(new_user)
@@ -46,15 +42,13 @@ def read_my_profile(current_user: User = Depends(get_current_user)):
4642
return {
4743
"id": current_user.id,
4844
"username": current_user.username,
49-
"wins": current_user.wins
45+
"wins": current_user.wins,
5046
}
5147

5248

53-
5449
@router.post("/login", response_model=dict, status_code=status.HTTP_200_OK)
5550
def login(
56-
form_data: OAuth2PasswordRequestForm = Depends(),
57-
db: Session = Depends(get_db)
51+
form_data: OAuth2PasswordRequestForm = Depends(), db: Session = Depends(get_db)
5852
):
5953
"""
6054
OAuth2 password login (Swagger compatible)
@@ -66,9 +60,9 @@ def login(
6660
raise HTTPException(
6761
status_code=status.HTTP_401_UNAUTHORIZED,
6862
detail="Invalid username or password",
69-
headers={"WWW-Authenticate": "Bearer"}
63+
headers={"WWW-Authenticate": "Bearer"},
7064
)
7165

7266
access_token = create_access_token({"sub": str(db_user.id)})
7367

74-
return {"access_token": access_token, "token_type": "bearer"}
68+
return {"access_token": access_token, "token_type": "bearer"}

0 commit comments

Comments
 (0)