Skip to content

Commit 65cb63c

Browse files
committed
updated Docker Prod File, additional ViewSet tests added
1 parent 8ded729 commit 65cb63c

File tree

9 files changed

+1398
-278
lines changed

9 files changed

+1398
-278
lines changed

app/drf_project/settings.py

+30-29
Original file line numberDiff line numberDiff line change
@@ -82,37 +82,38 @@
8282
# Database
8383
# https://docs.djangoproject.com/en/5.0/ref/settings/#databases
8484

85-
# ----------------------------------------------------------------------------
86-
# LOCAL DEV
87-
# ----------------------------------------------------------------------------
88-
# DATABASES = {
89-
# "default": {
90-
# "ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
91-
# "NAME": os.environ.get("SQL_DATABASE", Path(BASE_DIR, "db.sqlite3")),
92-
# "USER": os.environ.get("SQL_USER", "user"),
93-
# "PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
94-
# "HOST": os.environ.get("SQL_HOST", "localhost"),
95-
# "PORT": os.environ.get("SQL_PORT", "5432"),
96-
# },
97-
# }
98-
99-
# ----------------------------------------------------------------------------
100-
# PRODUCTION
101-
# ----------------------------------------------------------------------------
102-
DATABASES = {
103-
"default": {
104-
"ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
105-
"NAME": os.environ.get("SQL_DATABASE", Path(BASE_DIR) / "db.sqlite3"),
106-
"USER": os.environ.get("SQL_USER", "user"),
107-
"PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
108-
"HOST": os.environ.get("SQL_HOST", "localhost"),
109-
"PORT": os.environ.get("SQL_PORT", "5432"),
110-
},
111-
}
85+
# Get the environment type (e.g., development or production)
86+
ENV_TYPE = os.getenv("DJANGO_ENV", "production")
87+
88+
if ENV_TYPE == "development":
89+
# Local Dev Configuration
90+
DATABASES = {
91+
"default": {
92+
"ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
93+
"NAME": os.environ.get("SQL_DATABASE", Path(BASE_DIR, "db.sqlite3")),
94+
"USER": os.environ.get("SQL_USER", "user"),
95+
"PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
96+
"HOST": os.environ.get("SQL_HOST", "localhost"),
97+
"PORT": os.environ.get("SQL_PORT", "5432"),
98+
},
99+
}
100+
else:
101+
# Production Configuration
102+
DATABASES = {
103+
"default": {
104+
"ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"),
105+
"NAME": os.environ.get("SQL_DATABASE", Path(BASE_DIR) / "db.sqlite3"),
106+
"USER": os.environ.get("SQL_USER", "user"),
107+
"PASSWORD": os.environ.get("SQL_PASSWORD", "password"),
108+
"HOST": os.environ.get("SQL_HOST", "localhost"),
109+
"PORT": os.environ.get("SQL_PORT", "5432"),
110+
},
111+
}
112112

113113
DATABASE_URL = os.environ.get("DATABASE_URL")
114-
db_from_env = dj_database_url.config(default=DATABASE_URL, conn_max_age=500)
115-
DATABASES["default"].update(db_from_env)
114+
if DATABASE_URL:
115+
db_from_env = dj_database_url.config(default=DATABASE_URL, conn_max_age=500)
116+
DATABASES["default"].update(db_from_env)
116117

117118

118119
# Password validation

app/requirements.txt

+36-6
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,79 @@
11
asgiref==3.8.1 ; python_version >= "3.12" and python_version < "4.0"
22
bandit==1.7.10 ; python_version >= "3.12" and python_version < "4.0"
33
black==24.10.0 ; python_version >= "3.12" and python_version < "4.0"
4+
build==1.2.2.post1 ; python_version >= "3.12" and python_version < "4.0"
5+
cachecontrol[filecache]==0.14.0 ; python_version >= "3.12" and python_version < "4.0"
46
certifi==2024.8.30 ; python_version >= "3.12" and python_version < "4.0"
7+
cffi==1.17.1 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy")
58
cfgv==3.4.0 ; python_version >= "3.12" and python_version < "4.0"
69
charset-normalizer==3.4.0 ; python_version >= "3.12" and python_version < "4.0"
10+
cleo==2.1.0 ; python_version >= "3.12" and python_version < "4.0"
711
click==8.1.7 ; python_version >= "3.12" and python_version < "4.0"
8-
colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows")
12+
colorama==0.4.6 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "win32" or platform_system == "Windows" or os_name == "nt")
913
compose==1.6.2 ; python_version >= "3.12" and python_version < "4.0"
10-
coverage[toml]==7.6.3 ; python_version >= "3.12" and python_version < "4.0"
14+
coverage[toml]==7.6.4 ; python_version >= "3.12" and python_version < "4.0"
15+
crashtest==0.4.1 ; python_version >= "3.12" and python_version < "4.0"
16+
cryptography==43.0.3 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux"
1117
distlib==0.3.9 ; python_version >= "3.12" and python_version < "4.0"
12-
dj-database-url==2.2.0 ; python_version >= "3.12" and python_version < "4.0"
18+
dj-database-url==2.3.0 ; python_version >= "3.12" and python_version < "4.0"
1319
django==5.0.7 ; python_version >= "3.12" and python_version < "4.0"
1420
djangorestframework==3.15.2 ; python_version >= "3.12" and python_version < "4.0"
1521
docker==7.1.0 ; python_version >= "3.12" and python_version < "4.0"
22+
dulwich==0.21.7 ; python_version >= "3.12" and python_version < "4.0"
23+
fastjsonschema==2.20.0 ; python_version >= "3.12" and python_version < "4.0"
1624
filelock==3.16.1 ; python_version >= "3.12" and python_version < "4.0"
1725
gunicorn==23.0.0 ; python_version >= "3.12" and python_version < "4.0"
1826
identify==2.6.1 ; python_version >= "3.12" and python_version < "4.0"
1927
idna==3.10 ; python_version >= "3.12" and python_version < "4.0"
2028
iniconfig==2.0.0 ; python_version >= "3.12" and python_version < "4.0"
29+
installer==0.7.0 ; python_version >= "3.12" and python_version < "4.0"
2130
invoke==2.2.0 ; python_version >= "3.12" and python_version < "4.0"
31+
jaraco-classes==3.4.0 ; python_version >= "3.12" and python_version < "4.0"
32+
jeepney==0.8.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux"
33+
keyring==24.3.1 ; python_version >= "3.12" and python_version < "4.0"
2234
markdown-it-py==3.0.0 ; python_version >= "3.12" and python_version < "4.0"
2335
mdurl==0.1.2 ; python_version >= "3.12" and python_version < "4.0"
36+
more-itertools==10.5.0 ; python_version >= "3.12" and python_version < "4.0"
37+
msgpack==1.1.0 ; python_version >= "3.12" and python_version < "4.0"
2438
mypy-extensions==1.0.0 ; python_version >= "3.12" and python_version < "4.0"
2539
nodeenv==1.9.1 ; python_version >= "3.12" and python_version < "4.0"
2640
packaging==24.1 ; python_version >= "3.12" and python_version < "4.0"
2741
pathspec==0.12.1 ; python_version >= "3.12" and python_version < "4.0"
2842
pbr==6.1.0 ; python_version >= "3.12" and python_version < "4.0"
43+
pexpect==4.9.0 ; python_version >= "3.12" and python_version < "4.0"
44+
pkginfo==1.11.2 ; python_version >= "3.12" and python_version < "4.0"
2945
platformdirs==4.3.6 ; python_version >= "3.12" and python_version < "4.0"
3046
pluggy==1.5.0 ; python_version >= "3.12" and python_version < "4.0"
47+
poetry-core==1.9.1 ; python_version >= "3.12" and python_version < "4.0"
48+
poetry-plugin-export==1.8.0 ; python_version >= "3.12" and python_version < "4.0"
49+
poetry==1.8.4 ; python_version >= "3.12" and python_version < "4.0"
3150
pre-commit==3.8.0 ; python_version >= "3.12" and python_version < "4.0"
32-
psycopg2-binary==2.9.9 ; python_version >= "3.12" and python_version < "4.0"
51+
psycopg2-binary==2.9.10 ; python_version >= "3.12" and python_version < "4.0"
52+
ptyprocess==0.7.0 ; python_version >= "3.12" and python_version < "4.0"
53+
pycparser==2.22 ; python_version >= "3.12" and python_version < "4.0" and (sys_platform == "darwin" or sys_platform == "linux") and (sys_platform == "darwin" or platform_python_implementation != "PyPy")
3354
pygments==2.18.0 ; python_version >= "3.12" and python_version < "4.0"
55+
pyproject-hooks==1.2.0 ; python_version >= "3.12" and python_version < "4.0"
3456
pytest-cov==5.0.0 ; python_version >= "3.12" and python_version < "4.0"
3557
pytest-django==4.8.0 ; python_version >= "3.12" and python_version < "4.0"
3658
pytest==8.3.3 ; python_version >= "3.12" and python_version < "4.0"
3759
python-dotenv==1.0.1 ; python_version >= "3.12" and python_version < "4.0"
60+
pywin32-ctypes==0.2.3 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32"
3861
pywin32==308 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32"
3962
pyyaml==6.0.2 ; python_version >= "3.12" and python_version < "4.0"
63+
rapidfuzz==3.10.1 ; python_version >= "3.12" and python_version < "4.0"
64+
requests-toolbelt==1.0.0 ; python_version >= "3.12" and python_version < "4.0"
4065
requests==2.32.3 ; python_version >= "3.12" and python_version < "4.0"
41-
rich==13.9.2 ; python_version >= "3.12" and python_version < "4.0"
66+
rich==13.9.3 ; python_version >= "3.12" and python_version < "4.0"
4267
ruff==0.6.9 ; python_version >= "3.12" and python_version < "4.0"
68+
secretstorage==3.3.3 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "linux"
69+
shellingham==1.5.4 ; python_version >= "3.12" and python_version < "4.0"
4370
sqlparse==0.5.1 ; python_version >= "3.12" and python_version < "4.0"
4471
stevedore==5.3.0 ; python_version >= "3.12" and python_version < "4.0"
72+
tomlkit==0.13.2 ; python_version >= "3.12" and python_version < "4.0"
73+
trove-classifiers==2024.10.21.16 ; python_version >= "3.12" and python_version < "4.0"
4574
typing-extensions==4.12.2 ; python_version >= "3.12" and python_version < "4.0"
4675
tzdata==2024.2 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "win32"
4776
urllib3==2.2.3 ; python_version >= "3.12" and python_version < "4.0"
48-
virtualenv==20.26.6 ; python_version >= "3.12" and python_version < "4.0"
77+
virtualenv==20.27.0 ; python_version >= "3.12" and python_version < "4.0"
4978
whitenoise==6.7.0 ; python_version >= "3.12" and python_version < "4.0"
79+
xattr==1.1.0 ; python_version >= "3.12" and python_version < "4.0" and sys_platform == "darwin"

app/tests/movies/conftest.py

+27
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
from unittest.mock import MagicMock
2+
13
import pytest
24
from movies.models import Movie
5+
from movies.serializers import MovieSerializer
36

47

58
@pytest.fixture(scope="function")
@@ -9,3 +12,27 @@ def _add_movie(title, genre, year):
912
return movie
1013

1114
return _add_movie
15+
16+
17+
@pytest.fixture
18+
def mock_movie():
19+
"""Fixture for a mock Movie object."""
20+
movie = MagicMock()
21+
movie.id = 1
22+
movie.title = "The Big Lebowski"
23+
movie.genre = "comedy"
24+
movie.year = "1998"
25+
return movie
26+
27+
28+
@pytest.fixture
29+
def mock_serializer(mock_movie):
30+
"""Fixture for a mock MovieSerializer."""
31+
serializer = MagicMock(spec=MovieSerializer)
32+
serializer.data = {
33+
"id": mock_movie.id,
34+
"title": mock_movie.title,
35+
"genre": mock_movie.genre,
36+
"year": mock_movie.year,
37+
}
38+
return serializer

app/tests/movies/test_views.py

+90-22
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
from movies.models import Movie
33

44

5+
# -------------------------------
6+
# POST TESTS
7+
# -------------------------------
58
@pytest.mark.django_db
69
def test_add_movie(client):
710
movies = Movie.objects.all()
@@ -24,36 +27,27 @@ def test_add_movie(client):
2427

2528

2629
@pytest.mark.django_db
27-
def test_add_movie_invalid_json(client):
30+
@pytest.mark.parametrize(
31+
"payload, status_code",
32+
[
33+
[{}, 400],
34+
[{"title": "The Big Lebowski", "genre": "comedy"}, 400],
35+
],
36+
)
37+
def test_add_movie_invalid_json(client, payload, status_code):
2838
movies = Movie.objects.all()
2939
assert len(movies) == 0
3040

31-
resp = client.post("/api/movies/", {}, content_type="application/json")
32-
assert resp.status_code == 400
33-
34-
movies = Movie.objects.all()
35-
assert len(movies) == 0
36-
37-
38-
@pytest.mark.django_db
39-
def test_add_movie_invalid_json_keys(client):
40-
movies = Movie.objects.all()
41-
assert len(movies) == 0
42-
43-
resp = client.post(
44-
"/api/movies/",
45-
{
46-
"title": "The Big Lebowski",
47-
"genre": "comedy",
48-
},
49-
content_type="application/json",
50-
)
51-
assert resp.status_code == 400
41+
resp = client.post("/api/movies/", payload, content_type="application/json")
42+
assert resp.status_code == status_code
5243

5344
movies = Movie.objects.all()
5445
assert len(movies) == 0
5546

5647

48+
# -------------------------------
49+
# GET TESTS
50+
# -------------------------------
5751
@pytest.mark.django_db
5852
def test_get_single_movie(client, add_movie):
5953
movie = add_movie(title="The Big Lebowski", genre="comedy", year="1998")
@@ -75,3 +69,77 @@ def test_get_all_movies(client, add_movie):
7569
assert resp.status_code == 200
7670
assert resp.data[0]["title"] == movie_one.title
7771
assert resp.data[1]["title"] == movie_two.title
72+
73+
74+
# -------------------------------
75+
# PUT TESTS
76+
# -------------------------------
77+
@pytest.mark.django_db
78+
def test_update_movie(client, add_movie):
79+
movie = add_movie(title="The Big Lebowski", genre="comedy", year="1998")
80+
81+
resp = client.put(
82+
f"/api/movies/{movie.id}/",
83+
{"title": "The Big Lebowski", "genre": "comedy", "year": "1997"},
84+
content_type="application/json",
85+
)
86+
assert resp.status_code == 200
87+
assert resp.data["title"] == "The Big Lebowski"
88+
assert resp.data["year"] == "1997"
89+
90+
resp_two = client.get(f"/api/movies/{movie.id}/")
91+
assert resp_two.status_code == 200
92+
assert resp_two.data["title"] == "The Big Lebowski"
93+
assert resp.data["year"] == "1997"
94+
95+
96+
@pytest.mark.django_db
97+
def test_update_movie_incorrect_id(client):
98+
resp = client.put("/api/movies/99/")
99+
assert resp.status_code == 404
100+
101+
102+
@pytest.mark.django_db
103+
@pytest.mark.parametrize(
104+
"add_movie, payload, status_code",
105+
[
106+
["add_movie", {}, 400],
107+
["add_movie", {"title": "The Big Lebowski", "genre": "comedy"}, 400],
108+
],
109+
indirect=["add_movie"],
110+
)
111+
def test_update_movie_invalid_json(client, add_movie, payload, status_code):
112+
movie = add_movie(title="The Big Lebowski", genre="comedy", year="1998")
113+
resp = client.put(
114+
f"/api/movies/{movie.id}/",
115+
payload,
116+
content_type="application/json",
117+
)
118+
assert resp.status_code == status_code
119+
120+
121+
# -------------------------------
122+
# DELETE TESTS
123+
# -------------------------------
124+
125+
126+
@pytest.mark.django_db
127+
def test_remove_movie(client, add_movie):
128+
movie = add_movie(title="The Big Lebowski", genre="comedy", year="1998")
129+
130+
resp = client.get(f"/api/movies/{movie.id}/")
131+
assert resp.status_code == 200
132+
assert resp.data["title"] == "The Big Lebowski"
133+
134+
resp_two = client.delete(f"/api/movies/{movie.id}/")
135+
assert resp_two.status_code == 204
136+
137+
resp_three = client.get("/api/movies/")
138+
assert resp_three.status_code == 200
139+
assert len(resp_three.data) == 0
140+
141+
142+
@pytest.mark.django_db
143+
def test_remove_movie_incorrect_id(client):
144+
resp = client.delete("/api/movies/99/")
145+
assert resp.status_code == 404

0 commit comments

Comments
 (0)