Skip to content

Commit

Permalink
Merge pull request #66 from OZ-Coding-School/feat/database_edit
Browse files Browse the repository at this point in the history
Feat/database edit
  • Loading branch information
dayeonkimm authored Jul 30, 2024
2 parents cdeca71 + 65e05a0 commit 06c36cd
Show file tree
Hide file tree
Showing 19 changed files with 287 additions and 100 deletions.
48 changes: 41 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,58 @@ LABEL maintainer="frog"
# 이는 Docker 컨테이너에서 로그를 더 쉽게 볼 수 있게 합니다.
ENV PYTHONUNBUFFERED 1

# # 로컬 파일 시스템의 requirements.txt 파일을 컨테이너의 /tmp/requirements.txt로 복사합니다.
# # 이 파일은 필요한 Python 패키지들을 명시합니다.
# COPY ./requirements.txt /tmp/requirements.txt
# COPY ./potato_project /app
# WORKDIR /app
# EXPOSE 8000

# # ARG DEV=false

# RUN python -m venv /py && \
# /py/bin/pip install --upgrade pip && \
# /py/bin/pip install -r /tmp/requirements.txt && \
# apk add --update --no-cache jpeg-dev && \
# apk add --update --no-cache --virtual .tmp-build-deps \
# build-base musl-dev zlib zlib-dev linux-headers && \
# # if [ $DEV = "true" ]; \
# # then /py/bin/pip install -r /tmp/requirements.dev.txt ; \
# # fi && \
# rm -rf /tmp && \
# apk del .tmp-build-deps && \
# adduser \
# --disabled-password \
# --no-create-home \
# django-user

# ENV PATH="/py/bin:$PATH"

# USER django-user

# # 이 명령어를 추가하여 pytest를 설치합니다.
# RUN /py/bin/pip install pytest pytest-django


# 로컬 파일 시스템의 requirements.txt 파일을 컨테이너의 /tmp/requirements.txt로 복사합니다.
# 이 파일은 필요한 Python 패키지들을 명시합니다.
COPY ./requirements.txt /tmp/requirements.txt
COPY ./requirements.dev.txt /tmp/requirements.dev.txt
COPY ./potato_project /app
WORKDIR /app
EXPOSE 8000

# ARG DEV=false
ARG DEV=false

RUN python -m venv /py && \
/py/bin/pip install --upgrade pip && \
/py/bin/pip install -r /tmp/requirements.txt && \
apk add --update --no-cache jpeg-dev && \
apk add --update --no-cache postgresql-client jpeg-dev && \
apk add --update --no-cache --virtual .tmp-build-deps \
build-base musl-dev zlib zlib-dev linux-headers && \
# if [ $DEV = "true" ]; \
# then /py/bin/pip install -r /tmp/requirements.dev.txt ; \
# fi && \
build-base postgresql-dev musl-dev zlib zlib-dev linux-headers && \
if [ $DEV = "true" ]; \
then /py/bin/pip install -r /tmp/requirements.dev.txt ; \
fi && \
rm -rf /tmp && \
apk del .tmp-build-deps && \
adduser \
Expand All @@ -38,4 +72,4 @@ ENV PATH="/py/bin:$PATH"
USER django-user

# 이 명령어를 추가하여 pytest를 설치합니다.
RUN /py/bin/pip install pytest pytest-django
RUN /py/bin/pip install pytest pytest-django
54 changes: 47 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# # version: "3.11"
# services:
# app:
# build:
# context: .
# args:
# - DEV=true
# ports:
# - "8000:8000"
# volumes:
# - ./potato_project:/app
# command: >
# sh -c "python manage.py makemigrations &&
# python manage.py migrate &&
# python manage.py runserver --noreload 0.0.0.0:8000"
# environment:
# - DB_HOST=${RDS_HOSTNAME} # RDS 엔드포인트
# - DB_NAME=${RDS_DB_NAME}
# - DB_USER=${RDS_USERNAME}
# - DB_PASSWORD=${RDS_PASSWORD}
# env_file:
# - .env

# version: "3.11"
services:
app:
Expand All @@ -7,18 +30,35 @@ services:
- DEV=true
ports:
- "8000:8000"
- "3000:3000" # debugger
volumes:
- ./potato_project:/app
command: >
sh -c "python manage.py makemigrations &&
python manage.py migrate &&
python manage.py runserver --noreload 0.0.0.0:8000"
sh -c "python manage.py wait_for_db &&
python manage.py makemigrations &&
python manage.py migrate &&
python -u manage.py runserver --noreload 0.0.0.0:8000"
environment:
- DB_HOST=${RDS_HOSTNAME} # RDS 엔드포인트
- DB_NAME=${RDS_DB_NAME}
- DB_USER=${RDS_USERNAME}
- DB_PASSWORD=${RDS_PASSWORD}
- DB_HOST=${DB_HOST}
- DB_NAME=${DB_NAME}
- DB_USER=${DB_USER}
- DB_PASSWORD=${DB_PASSWORD}
- PYDEVD_DISABLE_FILE_VALIDATION=1
env_file:
- .env
depends_on:
- db


db: # PostgreSQL Database
image: postgres:16-alpine
volumes:
- ./data/db:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
env_file:
- .env


30 changes: 21 additions & 9 deletions potato_project/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,26 @@
# WSGI 애플리케이션 설정
WSGI_APPLICATION = "app.wsgi.application"

# # 데이터베이스 설정
# DATABASES = {
# "default": {
# "ENGINE": "django.db.backends.postgresql",
# "HOST": os.environ.get("RDS_HOSTNAME"),
# "NAME": os.environ.get("RDS_DB_NAME"),
# "USER": os.environ.get("RDS_USERNAME"),
# "PASSWORD": os.environ.get("RDS_PASSWORD"),
# "PORT": os.environ.get("RDS_PORT", 5432),
# }
# }

# 데이터베이스 설정
DATABASES = {
"default": {
"ENGINE": "django.db.backends.postgresql",
"HOST": os.environ.get("RDS_HOSTNAME"),
"NAME": os.environ.get("RDS_DB_NAME"),
"USER": os.environ.get("RDS_USERNAME"),
"PASSWORD": os.environ.get("RDS_PASSWORD"),
"PORT": os.environ.get("RDS_PORT", 5432),
"HOST": os.environ.get("DB_HOST"),
"NAME": os.environ.get("DB_NAME"),
"USER": os.environ.get("DB_USER"),
"PASSWORD": os.environ.get("DB_PASSWORD"),
}
}

Expand Down Expand Up @@ -155,6 +166,7 @@
"ROTATE_REFRESH_TOKENS": False, # 리프레시 토큰 순환 사용 여부
"BLACKLIST_AFTER_ROTATION": False, # 순환 사용 시 이전 리프레시 토큰 블랙리스트 등록 여부
"AUTH_HEADER_TYPES": ("Bearer",), # 인증 헤더 타입
"UPDATE_LAST_LOGIN": True,
}

REST_AUTH = {
Expand All @@ -174,8 +186,8 @@
# "client_id": os.environ.get("SOCIAL_AUTH_GITHUB_CLIENT_ID"),
# "secret": os.environ.get("SOCIAL_AUTH_GITHUB_SECRET"),
# "key": "",
# }
# }
# },
# },
# }

SOCIALACCOUNT_PROVIDERS = {
Expand All @@ -189,5 +201,5 @@
}

SOCIALACCOUNT_LOGIN_ON_GET = True
LOGIN_REDIRECT_URL = "http://43.202.0.144:8000/home"
ACCOUNT_LOGOUT_REDIRECT_URL = "http://43.202.0.144:8000/landing"
LOGIN_REDIRECT_URL = "https://d3hcv7ngm54uy8.cloudfront.net/oauth-callback"
ACCOUNT_LOGOUT_REDIRECT_URL = "https://d3hcv7ngm54uy8.cloudfront.net/landing"
92 changes: 54 additions & 38 deletions potato_project/attendances/tests.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,65 @@
from datetime import date

from attendances.models import Attendance
from django.contrib.auth.models import User
from django.test import TestCase
from django.utils import timezone
from rest_framework import status
from rest_framework.test import APIClient
from users.models import User

from .models import Attendance

class AttendanceViewSetTests(TestCase):

class AttendanceViewSetTests(TestCase):
def setUp(self):
# 테스트에 사용할 사용자 생성
self.user = User.objects.create_user(
username='testuser',
password='password',
email='testuser@example.com'
username="testuser", password="testpassword"
)
self.client = APIClient()
self.client.login(username="testuser", password="testpassword")

def test_list_attendance_no_record(self):
# 출석 기록이 없는 경우
response = self.client.get("/attendances/")
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(response.data, {"출석 기록이 없습니다."})

def test_increment_attendance(self):
# 출석 기록을 추가
response = self.client.post("/attendances/increment/")
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(response.data["coin_awarded"], 1)

def test_increment_attendance_already_exists(self):
# 출석 기록이 이미 있는 경우
today = timezone.now().date()
Attendance.objects.create(user=self.user, date=today, coin_awarded=1)

response = self.client.post("/attendances/increment/")
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data, {"오늘은 출석을 이미 하셨어요!"})

def test_decrement_attendance_no_record(self):
# 출석 기록이 없는 경우 코인 차감 시도
response = self.client.post("/attendances/decrement/", {"value": 1})
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)
self.assertEqual(response.data, {"message": "출석 기록이 없습니다."})

def test_decrement_attendance_insufficient_coins(self):
# 출석 기록이 있지만 코인이 부족한 경우
Attendance.objects.create(
user=self.user, date=timezone.now().date(), coin_awarded=1
)

response = self.client.post("/attendances/decrement/", {"value": 2})
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data, {"message": "코인이 모자라요!"})

def test_decrement_attendance_success(self):
# 출석 기록이 있고 충분한 코인이 있는 경우
Attendance.objects.create(
user=self.user, date=timezone.now().date(), coin_awarded=5
)


def test_create_attendance(self):
# 출석 기록 생성
attendance = Attendance.objects.create(user=self.user, date=date.today(), coin_awarded=10)
self.assertEqual(attendance.user, self.user)
self.assertEqual(attendance.date, date.today())
self.assertEqual(attendance.coin_awarded, 10)

def test_read_attendance(self):
# 출석 기록 생성
Attendance.objects.create(user=self.user, date=date.today(), coin_awarded=10)
attendance = Attendance.objects.get(user=self.user, date=date.today())
self.assertEqual(attendance.user.username, 'testuser')
self.assertEqual(attendance.coin_awarded, 10)

def test_update_attendance(self):
# 출석 기록 생성 및 수정
attendance = Attendance.objects.create(user=self.user, date=date.today(), coin_awarded=10)
attendance.coin_awarded = 20
attendance.save()
updated_attendance = Attendance.objects.get(user=self.user, date=date.today())
self.assertEqual(updated_attendance.coin_awarded, 20)

def test_delete_attendance(self):
# 출석 기록 생성 및 삭제
attendance = Attendance.objects.create(user=self.user, date=date.today(), coin_awarded=10)
attendance_id = attendance.id
attendance.delete()
with self.assertRaises(Attendance.DoesNotExist):
Attendance.objects.get(id=attendance_id)
response = self.client.post("/attendances/decrement/", {"value": 2})
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data["message"], "물건을 구매했습니다.")
self.assertEqual(response.data["coin_awarded"], 3)
5 changes: 3 additions & 2 deletions potato_project/potato_types/actions.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.contrib import messages
from potatoes.models import Potato
from users.models import User

from .models import PotatoType

Expand All @@ -10,10 +11,10 @@ def add_new_potato(modeladmin, request, queryset):
messages.error(request, "새로운 감자 종류를 선택해주세요.")
return

for user in User.objects.all():
for user in User.objects.filter(is_superuser=False):
Potato.objects.create(
user=user,
potato_type_id=new_potato_type,
potato_type_id=new_potato_type.id,
is_acquired=False,
is_selected=False,
)
Expand Down
5 changes: 1 addition & 4 deletions potato_project/potato_types/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from django.db import migrations, models


class Migration(migrations.Migration):

initial = True
Expand Down Expand Up @@ -31,9 +32,5 @@ class Migration(migrations.Migration):
),
("potato_description", models.TextField(verbose_name="감자설명")),
],
options={
"verbose_name": "PotatoType",
"verbose_name_plural": "PotatoTypes",
},
),
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 5.0.7 on 2024-07-29 16:12

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("potato_types", "0001_initial"),
]

operations = [
migrations.RemoveField(
model_name="potatotype",
name="potato_image",
),
]
1 change: 0 additions & 1 deletion potato_project/potato_types/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
class PotatoType(models.Model):
# 추가 필드 정의
potato_name = models.CharField(max_length=255, verbose_name="감자이름")
potato_image = models.CharField(max_length=255, verbose_name="감자이미지")
potato_description = models.TextField(verbose_name="감자설명")

def __str__(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Generated by Django 5.0.7 on 2024-07-29 14:59

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("potatoes", "0002_initial"),
]

operations = [
migrations.RenameField(
model_name="potato",
old_name="potato_type_id",
new_name="potato_type",
),
]
Loading

0 comments on commit 06c36cd

Please sign in to comment.