Skip to content

Commit

Permalink
Added tests for the backend API
Browse files Browse the repository at this point in the history
  • Loading branch information
irishrain committed Dec 9, 2024
1 parent 677cdbf commit 83b4c1a
Show file tree
Hide file tree
Showing 8 changed files with 560 additions and 0 deletions.
Empty file added backend/tests/api/__init__.py
Empty file.
212 changes: 212 additions & 0 deletions backend/tests/api/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
import pytest
from app import app, db


@pytest.fixture
def client():
app_context = app.app_context()
app_context.push()
app.config['TESTING'] = True
db.create_all()
client = app.test_client()
yield client
db.session.rollback()
db.drop_all()
app_context.pop()


@pytest.fixture
def username():
return "testuser"


@pytest.fixture
def name():
return "testname"


@pytest.fixture
def password():
return "testpwd"


@pytest.fixture
def admin_username():
return "testadmin"


@pytest.fixture
def admin_name():
return "adminname"


@pytest.fixture
def admin_password():
return "adminpwd"


@pytest.fixture
def household_name():
return "testhousehold"


@pytest.fixture
def item_name():
return "testitem"

@pytest.fixture
def recipe_name():
return "Test Recipe"

@pytest.fixture
def recipe_description():
return "A test recipe description"

@pytest.fixture
def recipe_yields():
return 4

@pytest.fixture
def recipe_time():
return 30


@pytest.fixture
def onboarded_client(client, admin_username, admin_name, admin_password):
onboard_data = {
'username': admin_username,
'name': admin_name,
'password': admin_password
}
response = client.post('/api/onboarding', json=onboard_data)
return client


@pytest.fixture
def admin_client(client, admin_username, admin_name, admin_password):
onboard_data = {
'username': admin_username,
'name': admin_name,
'password': admin_password
}
response = client.post('/api/onboarding', json=onboard_data)
data = response.get_json()
client.environ_base['HTTP_AUTHORIZATION'] = f'Bearer {data["access_token"]}'
return client


@pytest.fixture
def user_client(admin_client, username, name, password):
data = {
'username': username,
'name': name,
'password': password
}
response = admin_client.post('/api/user/new', json=data)
data = {
'username': username,
'password': password
}
response = admin_client.post('/api/auth', json=data)
data = response.get_json()
admin_client.environ_base['HTTP_AUTHORIZATION'] = f'Bearer {data["access_token"]}'
return admin_client


@pytest.fixture
def user_client_with_household(user_client, household_name):
response = user_client.get('/api/user',)
assert response.status_code == 200
data = response.get_json()
user_id = data['id']
data = {
'name': household_name,
'member': [user_id]
}
response = user_client.post('/api/household', json=data)
return user_client


@pytest.fixture
def household_id(user_client_with_household):
response = user_client_with_household.get('/api/household',)
assert response.status_code == 200
data = response.get_json()
assert len(data) == 1
assert "id" in data[0]
return data[0]["id"]


@pytest.fixture
def shoppinglist_id(user_client_with_household, household_id):
response = user_client_with_household.get(
f'/api/household/{household_id}/shoppinglist',)
assert response.status_code == 200
data = response.get_json()
assert len(data) == 1
assert "id" in data[0]
return data[0]["id"]


@pytest.fixture
def shoppinglist_id_with_item(user_client_with_household, shoppinglist_id, item_name):
data = {"name": item_name}
response = user_client_with_household.post(
f'/api/shoppinglist/{shoppinglist_id}/add-item-by-name', json=data)
assert response.status_code == 200
return shoppinglist_id


@pytest.fixture
def item_id(user_client_with_household, shoppinglist_id_with_item):
response = user_client_with_household.get(
f'/api/shoppinglist/{shoppinglist_id_with_item}/items')
assert response.status_code == 200
data = response.get_json()
assert len(data) == 1
assert "id" in data[0]
return data[0]["id"]

@pytest.fixture
def recipe_with_items(user_client_with_household, household_id, recipe_name, recipe_description, recipe_yields, recipe_time, item_name):
# Create recipe with the item
recipe_data = {
'name': recipe_name,
'description': recipe_description,
'yields': recipe_yields,
'time': recipe_time,
'items': [{'name': item_name, 'description': '2 pieces'}]
}

response = user_client_with_household.post(
f'/api/household/{household_id}/recipe',
json=recipe_data
)
assert response.status_code == 200
recipe = response.get_json()
assert 'id' in recipe
return recipe['id']

@pytest.fixture
def planned_recipe(user_client_with_household, household_id, recipe_with_items):
"""Fixture that creates a meal plan with the test recipe"""
plan_data = {
'recipe_id': recipe_with_items,
'day': 0 # Plan for today
}
response = user_client_with_household.post(
f'/api/household/{household_id}/planner/recipe',
json=plan_data
)
assert response.status_code == 200

# Verify plan was created
response = user_client_with_household.get(
f'/api/household/{household_id}/planner'
)
assert response.status_code == 200
planned_meals = response.get_json()
assert len(planned_meals) > 0
assert any(meal['recipe']['id'] == recipe_with_items for meal in planned_meals)

return recipe_with_items # Return recipe_id for convenience
42 changes: 42 additions & 0 deletions backend/tests/api/test_api_household.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import pytest


def test_get_all_households_empty(admin_client):
response = admin_client.get('/api/household',)
assert response.status_code == 200
data = response.get_json()
assert len(data) == 0


def test_add_household_admin(admin_client, household_name):
response = admin_client.get('/api/user',)
assert response.status_code == 200
data = response.get_json()
admin_user_id = data['id']
data = {
'name': household_name,
'member': [admin_user_id]
}
response = admin_client.post('/api/household', json=data)
assert response.status_code == 200


def test_add_household_user(user_client, household_name):
response = user_client.get('/api/user',)
assert response.status_code == 200
data = response.get_json()
user_id = data['id']
data = {
'name': household_name,
'member': [user_id]
}
response = user_client.post('/api/household', json=data)
assert response.status_code == 200


def test_get_all_households(user_client_with_household, household_name):
response = user_client_with_household.get('/api/household',)
assert response.status_code == 200
data = response.get_json()
assert len(data) == 1
assert data[0]["name"] == household_name
30 changes: 30 additions & 0 deletions backend/tests/api/test_api_onboarding.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pytest


def test_onboarding_status_true(client):
response = client.get('/api/onboarding',)
assert response.status_code == 200
data = response.get_json()
assert "onboarding" in data
assert data["onboarding"] == True


def test_onboarding_status_false(onboarded_client):
response = onboarded_client.get('/api/onboarding',)
assert response.status_code == 200
data = response.get_json()
assert "onboarding" in data
assert data["onboarding"] == False


def test_onboarding(client, admin_username, admin_name, admin_password):
onboard_data = {
'username': admin_username,
'name': admin_name,
'password': admin_password
}
response = client.post('/api/onboarding', json=onboard_data)
assert response.status_code == 200
data = response.get_json()
assert "access_token" in data
assert "refresh_token" in data
66 changes: 66 additions & 0 deletions backend/tests/api/test_api_planner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
def test_meal_planning_basic(user_client_with_household, household_id, planned_recipe):
"""Test basic meal planning operations"""
# Get planned meals and verify the recipe is there
response = user_client_with_household.get(
f'/api/household/{household_id}/planner'
)
assert response.status_code == 200
planned_meals = response.get_json()
assert len(planned_meals) > 0
assert any(meal['recipe']['id'] == planned_recipe for meal in planned_meals)


def test_meal_planning_remove(user_client_with_household, household_id, planned_recipe):
"""Test removing meals from plan"""
# Remove from meal plan
response = user_client_with_household.delete(
f'/api/household/{household_id}/planner/recipe/{planned_recipe}',
json={'day': 0}
)
assert response.status_code == 200

# Verify removal
response = user_client_with_household.get(
f'/api/household/{household_id}/planner'
)
assert response.status_code == 200
planned_meals = response.get_json()
assert not any(meal['recipe']['id'] == planned_recipe for meal in planned_meals)


def test_recent_planned_recipes(user_client_with_household, household_id, planned_recipe):
"""Test getting recently planned recipes"""
# First remove the recipe from the plan
response = user_client_with_household.delete(
f'/api/household/{household_id}/planner/recipe/{planned_recipe}',
json={'day': 0}
)
assert response.status_code == 200

# Now get recent recipes - should include our recently dropped recipe
response = user_client_with_household.get(
f'/api/household/{household_id}/planner/recent-recipes'
)
assert response.status_code == 200
recent_recipes = response.get_json()
assert len(recent_recipes) > 0
assert any(recipe['id'] == planned_recipe for recipe in recent_recipes)


def test_suggested_recipes(user_client_with_household, household_id, recipe_with_items):
"""Test recipe suggestions functionality"""
# Get suggested recipes
response = user_client_with_household.get(
f'/api/household/{household_id}/planner/suggested-recipes'
)
assert response.status_code == 200
suggested_recipes = response.get_json()
assert isinstance(suggested_recipes, list) # Should return a list, even if empty

# Refresh suggestions
response = user_client_with_household.get(
f'/api/household/{household_id}/planner/refresh-suggested-recipes'
)
assert response.status_code == 200
refreshed_suggestions = response.get_json()
assert isinstance(refreshed_suggestions, list)
Loading

0 comments on commit 83b4c1a

Please sign in to comment.