This commit is contained in:
암냥 2025-09-13 16:18:28 +09:00
commit 40266cc6e5
191 changed files with 5022 additions and 0 deletions

View file

81
Backend/tests/conftest.py Normal file
View file

@ -0,0 +1,81 @@
import pytest
from fastapi.testclient import TestClient
import sys
import os
# Add Backend to path
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
from Backend import app
@pytest.fixture(scope="module")
def client():
with TestClient(app) as c:
yield c
@pytest.fixture
def authenticated_user(client):
user_data = {
"username": "testuser_authenticated",
"email": "test_auth@example.com",
"password": "testpassword123",
}
# Register user
response = client.post("/api/user/register", data=user_data)
# Login to get token
login_data = {"username": user_data["username"], "password": user_data["password"]}
response = client.post("/api/user/login", json=login_data)
token = response.json()["access_token"]
yield {"token": token, "user_data": user_data}
# Cleanup: delete user via API
headers = {"Authorization": f"Bearer {token}"}
client.delete(f"/api/user/{user_data['username']}", headers=headers)
@pytest.fixture
def two_authenticated_users(client):
user1_data = {
"username": "testuser1",
"email": "test1@example.com",
"password": "testpassword123",
}
user2_data = {
"username": "testuser2",
"email": "test2@example.com",
"password": "testpassword123",
}
# Register users
client.post("/api/user/register", data=user1_data)
client.post("/api/user/register", data=user2_data)
# Login users
login1_data = {
"username": user1_data["username"],
"password": user1_data["password"],
}
response1 = client.post("/api/user/login", json=login1_data)
token1 = response1.json()["access_token"]
login2_data = {
"username": user2_data["username"],
"password": user2_data["password"],
}
response2 = client.post("/api/user/login", json=login2_data)
token2 = response2.json()["access_token"]
yield {
"user1": {"token": token1, "username": user1_data["username"]},
"user2": {"token": token2, "username": user2_data["username"]},
}
# Cleanup
headers1 = {"Authorization": f"Bearer {token1}"}
headers2 = {"Authorization": f"Bearer {token2}"}
client.delete(f"/api/user/{user1_data['username']}", headers=headers1)
client.delete(f"/api/user/{user2_data['username']}", headers=headers2)

View file

@ -0,0 +1,71 @@
from fastapi.testclient import TestClient
from Backend.schemas.avatar import (
AvatarUpdate,
AvatarType,
TopClothesType,
BottomClothesType,
)
def test_get_my_avatar(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
response = client.get("/api/avatar", headers=headers)
assert response.status_code == 200
avatar_data = response.json()
assert "id" in avatar_data
assert "user_id" in avatar_data
assert avatar_data["avatar_type"]["name"] == AvatarType.MALE.value
def test_update_my_avatar(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
response = client.get("/api/avatar", headers=headers)
assert response.status_code == 200
update_data = AvatarUpdate(
avatar_type=AvatarType.FEMALE,
top_clothe_type=TopClothesType.SCHOOL_CLOTHES,
bottom_clothe_type=BottomClothesType.SCHOOL_CLOTHES_2,
)
response = client.put(
"/api/avatar", json=update_data.model_dump(mode="json"), headers=headers
)
assert response.status_code == 200
avatar_data = response.json()
assert avatar_data["avatar_type"]["name"] == update_data.avatar_type.value
assert avatar_data["top_clothe_type"]["name"] == update_data.top_clothe_type.value
assert (
avatar_data["bottom_clothe_type"]["name"]
== update_data.bottom_clothe_type.value
)
def test_get_avatar_options(client: TestClient):
response = client.get("/api/avatar/options")
assert response.status_code == 200
options = response.json()
assert "avatar_types" in options
assert "top_clothe_types" in options
assert "bottom_clothe_types" in options
assert all(isinstance(item, str) for item in options["avatar_types"])
assert all(isinstance(item, str) for item in options["top_clothe_types"])
assert all(isinstance(item, str) for item in options["bottom_clothe_types"])
def test_get_avatar_by_user_id(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
response = client.get("/api/avatar", headers=headers)
assert response.status_code == 200
user_id = response.json()["user_id"]
response = client.get(f"/api/avatar/{user_id}", headers=headers)
assert response.status_code == 200
avatar_data = response.json()
assert "id" in avatar_data
assert avatar_data["user_id"] == user_id
assert avatar_data["avatar_type"]["name"] == AvatarType.MALE.value
# Test for a non-existent user
response = client.get("/api/avatar/9999", headers=headers)
assert response.status_code == 404

View file

@ -0,0 +1,52 @@
from io import BytesIO
def test_diary_operations(client, authenticated_user):
token = authenticated_user["token"]
headers = {"Authorization": f"Bearer {token}"}
# Create Diary
diary_data = {
"title": "test title",
"content": "test content",
"category": "test category",
}
response = client.post(
"/api/diary",
data=diary_data,
files={"file": ("a.jpg", BytesIO(b"aaa"), "image/jpeg")},
headers=headers,
)
assert response.status_code == 200
diary_id = response.json()["id"]
assert response.json()["title"] == "test title"
# Get Diary
response = client.get(f"/api/diary/{diary_id}", headers=headers)
assert response.status_code == 200
assert response.json()["id"] == diary_id
# List Diaries
response = client.get("/api/diary", headers=headers)
assert response.status_code == 200
assert len(response.json()) > 0
# Update Diary
updated_diary_data = {"title": "updated title", "content": "updated content"}
response = client.put(
f"/api/diary/{diary_id}",
data=updated_diary_data,
files={"file": ("b.jpg", BytesIO(b"bbb"), "image/jpeg")},
headers=headers,
)
assert response.status_code == 200
assert response.json()["title"] == "updated title"
# Delete Diary
response = client.delete(f"/api/diary/{diary_id}", headers=headers)
assert response.status_code == 200
assert response.json()["message"] == "Diary deleted successfully"
# Verify Deletion
response = client.get(f"/api/diary/{diary_id}", headers=headers)
assert response.status_code == 400

View file

@ -0,0 +1,45 @@
def test_friendship_flow(client, two_authenticated_users):
user1 = two_authenticated_users["user1"]
user2 = two_authenticated_users["user2"]
headers1 = {"Authorization": f"Bearer {user1['token']}"}
headers2 = {"Authorization": f"Bearer {user2['token']}"}
# User 1 sends friendship request to User 2
response = client.post(
"/api/friendship/request",
json={"friend_username": user2["username"]},
headers=headers1,
)
assert response.status_code == 200
friendship_id = response.json()["id"]
assert response.json()["status"] == "pending"
# User 2 accepts friendship request
response = client.put(f"/api/friendship/{friendship_id}/accept", headers=headers2)
assert response.status_code == 200
assert response.json()["status"] == "accepted"
# User 1 lists friends
response = client.get("/api/friendship", headers=headers1)
assert response.status_code == 200
assert any(f["id"] == friendship_id for f in response.json())
# User 2 lists friends
response = client.get("/api/friendship", headers=headers2)
assert response.status_code == 200
assert any(f["id"] == friendship_id for f in response.json())
# User 1 deletes friendship
response = client.delete(f"/api/friendship/{friendship_id}", headers=headers1)
assert response.status_code == 200
assert response.json()["message"] == "Friendship deleted successfully"
# Verify deletion for both users
response = client.get("/api/friendship", headers=headers1)
assert response.status_code == 200
assert not any(f["id"] == friendship_id for f in response.json())
response = client.get("/api/friendship", headers=headers2)
assert response.status_code == 200
assert not any(f["id"] == friendship_id for f in response.json())

View file

@ -0,0 +1,38 @@
def test_guest_book(client, authenticated_user):
token = authenticated_user["token"]
headers = {"Authorization": f"Bearer {token}"}
user_data = {
"username": "testtarget",
"email": "test@example.com",
"password": "testpassword123",
}
response = client.post("/api/user/register", data=user_data)
assert response.status_code == 201
user_id = response.json()["id"]
username = response.json()["username"]
response = client.post(
"/api/guestbook",
json={"target_user_id": user_id, "content": "test"},
headers=headers,
)
assert response.status_code == 201
assert response.json()["content"] == "test"
id = response.json()["id"]
response = client.get(f"/api/guestbook/{user_id}", headers=headers)
assert response.status_code == 200
assert response.json()[0]["content"] == "test"
response = client.put(
f"/api/guestbook/{id}", json={"content": "test2"}, headers=headers
)
assert response.status_code == 200
assert response.json()["content"] == "test2"
response = client.delete(f"/api/guestbook/{id}", headers=headers)
assert response.status_code == 200
client.delete(f"/api/user/{username}", headers=headers)
assert response.status_code == 200

View file

@ -0,0 +1,32 @@
# def test_letter_operations(client, authenticated_user):
# token = authenticated_user["token"]
# headers = {"Authorization": f"Bearer {token}"}
#
# # Create Letter
# letter_data = {"content": "test content"}
# response = client.post("/api/letter", json=letter_data, headers=headers)
# assert response.status_code == 200
# letter_id = response.json()["id"]
# assert response.json()["content"] == "test content"
#
# # Get Letter
# response = client.get(f"/api/letter/{letter_id}", headers=headers)
# assert response.status_code == 200
# assert response.json()["id"] == letter_id
#
# # Update Letter
# updated_letter_data = {"content": "updated content"}
# response = client.put(
# f"/api/letter/{letter_id}", json=updated_letter_data, headers=headers
# )
# assert response.status_code == 200
# assert response.json()["content"] == "updated content"
#
# # Delete Letter
# response = client.delete(f"/api/letter/{letter_id}", headers=headers)
# assert response.status_code == 200
# assert response.json()["detail"] == "Letter deleted"
#
# # Verify Deletion
# response = client.get(f"/api/letter/{letter_id}", headers=headers)
# assert response.status_code == 400

View file

@ -0,0 +1,94 @@
# from io import BytesIO
# import json
#
#
# def test_photo_upload_and_delete(client, authenticated_user):
# token = authenticated_user["token"]
# headers = {"Authorization": f"Bearer {token}"}
#
# # Upload Photo
# photo_data = {"album_name": "test_album", "title": "test_title"}
# photo_data_json = json.dumps(photo_data).encode("utf-8")
#
# response = client.post(
# "/api/photo/upload",
# files={
# "photo_data": (
# "photo_data.json",
# BytesIO(photo_data_json),
# "application/json",
# ),
# "file": ("a.jpg", BytesIO(b"aaa"), "image/jpeg"),
# },
# headers=headers,
# )
# assert response.status_code == 200
# photo_id = response.json()["id"]
# assert response.json()["album_name"] == "test_album"
#
# # Delete Photo
# response = client.delete(f"/api/photo/{photo_id}", headers=headers)
# assert response.status_code == 200
# assert response.json()["message"] == "Photo deleted successfully"
#
#
# def test_photo_commenting(client, two_authenticated_users):
# user1 = two_authenticated_users["user1"]
# user2 = two_authenticated_users["user2"]
#
# headers1 = {"Authorization": f"Bearer {user1['token']}"}
# headers2 = {"Authorization": f"Bearer {user2['token']}"}
#
# # User 1 uploads a photo
# photo_data = {"album_name": "test_album", "title": "test_title"}
# photo_data_json = json.dumps(photo_data).encode("utf-8")
# response = client.post(
# "/api/photo/upload",
# files={
# "photo_data": (
# "photo_data.json",
# BytesIO(photo_data_json),
# "application/json",
# ),
# "file": ("a.jpg", BytesIO(b"aaa"), "image/jpeg"),
# },
# headers=headers1,
# )
# assert response.status_code == 200
# photo_id = response.json()["id"]
#
# # User 2 cannot comment before being friends
# response = client.post(
# f"/api/photo/{photo_id}/comment",
# json={"content": "test comment"},
# headers=headers2,
# )
# assert response.status_code == 400
#
# # User 1 sends friendship request to User 2
# response = client.post(
# "/api/friendship/request",
# json={"friend_username": user2["username"]},
# headers=headers1,
# )
# assert response.status_code == 200
# friendship_id = response.json()["id"]
#
# # User 2 accepts friendship request
# response = client.put(f"/api/friendship/{friendship_id}/accept", headers=headers2)
# assert response.status_code == 200
#
# # User 2 can now comment
# response = client.post(
# f"/api/photo/{photo_id}/comment",
# json={"content": "test comment"},
# headers=headers2,
# )
# assert response.status_code == 200
# assert response.json()["content"] == "test comment"
#
# # User 1 can see the comment
# response = client.get(f"/api/photo/{photo_id}/comments", headers=headers1)
# assert response.status_code == 200
# assert len(response.json()) > 0
# assert response.json()[0]["content"] == "test comment"

161
Backend/tests/test_room.py Normal file
View file

@ -0,0 +1,161 @@
from fastapi.testclient import TestClient
from Backend.schemas.room import Furniture, RoomTypes
def test_get_furniture_catalog(client: TestClient):
response = client.get("/api/room/catalog")
assert response.status_code == 200
catalog = response.json()
assert isinstance(catalog, list)
assert len(catalog) > 0
for item in catalog:
assert "name" in item
assert "image_path" in item
assert "width" in item
def test_get_room_types(client: TestClient):
response = client.get("/api/room/types")
assert response.status_code == 200
types = response.json()
assert isinstance(types, list)
assert len(types) > 0
for room_type in types:
assert "type" in room_type
assert "image_path" in room_type
def test_get_my_room(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
response = client.get("/api/room/", headers=headers)
assert response.status_code == 200
room_data = response.json()
assert "id" in room_data
assert "room_name" in room_data
assert "room_type" in room_data
assert "room_image_path" in room_data
def test_update_room_name(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
response = client.get("/api/room/", headers=headers)
new_name = "My Awesome Room"
response = client.put("/api/room/", json={"new_name": new_name}, headers=headers)
assert response.status_code == 200
assert response.json() == {"message": "Room name updated successfully"}
# Verify the change
response = client.get("/api/room/", headers=headers)
assert response.status_code == 200
assert response.json()["room_name"] == new_name
def test_update_room_type(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
response = client.get("/api/room/", headers=headers)
new_type = RoomTypes.ROOM_2.value
response = client.patch("/api/room/", json={"type": new_type}, headers=headers)
assert response.status_code == 200
updated_room = response.json()
assert updated_room["room_type"] == new_type
def test_get_my_room_layout(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
response = client.get("/api/room/layout", headers=headers)
assert response.status_code == 200
layout_data = response.json()
assert "room" in layout_data
assert "furniture" in layout_data
assert isinstance(layout_data["furniture"], list)
def test_place_furniture(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
placement_data = {
"furniture_name": Furniture.SOFA_0.value,
"x": 5,
"y": 5,
}
response = client.post("/api/room/furniture", json=placement_data, headers=headers)
assert response.status_code == 200
assert response.json() == {"message": "Furniture placed successfully"}
# Verify placement
layout_response = client.get("/api/room/layout", headers=headers)
assert layout_response.status_code == 200
new_layout = layout_response.json()
assert any(
item["furniture_name"] == placement_data["furniture_name"]
and item["x"] == placement_data["x"]
and item["y"] == placement_data["y"]
for item in new_layout["furniture"]
)
# Cleanup
client.delete(
f"/api/room/furniture?x={placement_data['x']}&y={placement_data['y']}&furniture_name={placement_data['furniture_name']}",
headers=headers,
)
def test_remove_furniture(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
placement_data = {
"furniture_name": Furniture.CHAIR_0.value,
"x": 1,
"y": 1,
}
# Place furniture first
client.post("/api/room/furniture", json=placement_data, headers=headers)
# Remove furniture
response = client.delete(
f"/api/room/furniture?x={placement_data['x']}&y={placement_data['y']}&furniture_name={placement_data['furniture_name']}",
headers=headers,
)
assert response.status_code == 200
assert response.json() == {"message": "Furniture removed successfully"}
# Verify removal
final_layout_response = client.get("/api/room/layout", headers=headers)
assert final_layout_response.status_code == 200
final_layout = final_layout_response.json()
assert not any(
item["furniture_name"] == placement_data["furniture_name"]
and item["x"] == placement_data["x"]
and item["y"] == placement_data["y"]
for item in final_layout["furniture"]
)
def test_invalid_furniture_placement(client: TestClient, authenticated_user):
headers = {"Authorization": f"Bearer {authenticated_user['token']}"}
# Test with invalid coordinates (out of bounds)
invalid_coords_data = {
"furniture_name": Furniture.CHAIR_0.value,
"x": 11,
"y": -1,
}
response = client.post(
"/api/room/furniture", json=invalid_coords_data, headers=headers
)
assert response.status_code == 422 # Pydantic validation error
# Test collision
placement_data = {"furniture_name": Furniture.CHAIR_0.value, "x": 1, "y": 1}
# Place once
client.post("/api/room/furniture", json=placement_data, headers=headers)
# Try to place again in the same spot
response = client.post("/api/room/furniture", json=placement_data, headers=headers)
assert response.status_code == 400
assert "already placed" in response.json()["detail"]
# Cleanup
client.delete(
f"/api/room/furniture?x={placement_data['x']}&y={placement_data['y']}&furniture_name={placement_data['furniture_name']}",
headers=headers,
)

View file

@ -0,0 +1,68 @@
from io import BytesIO
def test_user_registration_and_login(client):
# Registration
user_data = {
"username": "testuser999",
"email": "test@example.com",
"password": "testpassword123",
}
response = client.post(
"/api/user/register",
data=user_data,
files={"file": ("a.jpg", BytesIO(b"aaa"), "image/jpeg")},
)
assert response.status_code == 201
assert response.json()["username"] == "testuser999"
# Duplicate registration
response = client.post(
"/api/user/register",
data=user_data,
files={"file": ("a.jpg", BytesIO(b"aaa"), "image/jpeg")},
)
assert response.status_code == 400
assert response.json()["detail"] == "Username already registered"
# Login
login_data = {
"username": "testuser999",
"password": "testpassword123",
}
response = client.post("/api/user/login", json=login_data)
assert response.status_code == 200
assert "access_token" in response.json()
# Login with wrong password
login_data["password"] = "wrongpassword"
response = client.post("/api/user/login", json=login_data)
assert response.status_code == 401
assert response.json()["detail"] == "Invalid username or password"
# delete
response = client.delete(f"/api/user/{user_data['username']}")
assert response.status_code == 200
def test_get_user_profile(client, authenticated_user):
token = authenticated_user["token"]
username = authenticated_user["user_data"]["username"]
headers = {"Authorization": f"Bearer {token}"}
response = client.get(f"/api/user/profile/{username}", headers=headers)
assert response.status_code == 200
assert response.json()["username"] == username
def test_user_delete(client, authenticated_user):
token = authenticated_user["token"]
username = authenticated_user["user_data"]["username"]
headers = {"Authorization": f"Bearer {token}"}
response = client.delete(f"/api/user/{username}", headers=headers)
assert response.status_code == 200
assert response.json()["detail"] == "User deleted"