Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

サインアップ機能 #1

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
// vscode
"editor.codeActionsOnSave": {
"source.organizeImports": true
"source.organizeImports": "explicit"
},
"editor.formatOnSave": true,
"files.eol": "\n",
Expand Down
5 changes: 5 additions & 0 deletions accounts/admin.py
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
# from django.contrib import admin
from django.contrib import admin

from .models import User

admin.site.register(User)
10 changes: 10 additions & 0 deletions accounts/forms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm

User = get_user_model() # こっちで先に変数代入する!


class SignupForm(UserCreationForm):
class Meta:
model = User # model = get_user_model() は NG
fields = ("username", "email")
95 changes: 95 additions & 0 deletions accounts/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Generated by Django 4.2.16 on 2024-09-29 02:52

import django.contrib.auth.models
import django.contrib.auth.validators
from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

initial = True

dependencies = [
("auth", "0012_alter_user_first_name_max_length"),
]

operations = [
migrations.CreateModel(
name="User",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("password", models.CharField(max_length=128, verbose_name="password")),
("last_login", models.DateTimeField(blank=True, null=True, verbose_name="last login")),
(
"is_superuser",
models.BooleanField(
default=False,
help_text="Designates that this user has all permissions without explicitly assigning them.",
verbose_name="superuser status",
),
),
(
"username",
models.CharField(
error_messages={"unique": "A user with that username already exists."},
help_text="Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
max_length=150,
unique=True,
validators=[django.contrib.auth.validators.UnicodeUsernameValidator()],
verbose_name="username",
),
),
("first_name", models.CharField(blank=True, max_length=150, verbose_name="first name")),
("last_name", models.CharField(blank=True, max_length=150, verbose_name="last name")),
(
"is_staff",
models.BooleanField(
default=False,
help_text="Designates whether the user can log into this admin site.",
verbose_name="staff status",
),
),
(
"is_active",
models.BooleanField(
default=True,
help_text="Designates whether this user should be treated as active. Unselect this instead of deleting accounts.",
verbose_name="active",
),
),
("date_joined", models.DateTimeField(default=django.utils.timezone.now, verbose_name="date joined")),
("email", models.EmailField(max_length=254)),
(
"groups",
models.ManyToManyField(
blank=True,
help_text="The groups this user belongs to. A user will get all permissions granted to each of their groups.",
related_name="user_set",
related_query_name="user",
to="auth.group",
verbose_name="groups",
),
),
(
"user_permissions",
models.ManyToManyField(
blank=True,
help_text="Specific permissions for this user.",
related_name="user_set",
related_query_name="user",
to="auth.permission",
verbose_name="user permissions",
),
),
],
options={
"verbose_name": "user",
"verbose_name_plural": "users",
"abstract": False,
},
managers=[
("objects", django.contrib.auth.models.UserManager()),
],
),
]
7 changes: 7 additions & 0 deletions accounts/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@


# class FriendShip(models.Model):

from django.contrib.auth.models import AbstractUser
from django.db import models


class User(AbstractUser):
email = models.EmailField()
234 changes: 225 additions & 9 deletions accounts/tests.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,240 @@
from django.contrib.auth import SESSION_KEY, get_user_model
from django.test import TestCase
from django.urls import reverse

User = get_user_model()


class TestSignupView(TestCase):
def setUp(self):
self.url = reverse("accounts:signup")

def test_success_get(self):
response = self.client.get(self.url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, "accounts/signup.html")

def test_success_post(self):
valid_data = {
"username": "testuser",
"email": "[email protected]",
"password1": "testpassword",
"password2": "testpassword",
}

response = self.client.post(self.url, valid_data)

# 1の確認 = tweets/homeにリダイレクトすること
self.assertRedirects(
response,
reverse("tweets:home"),
status_code=302,
target_status_code=200,
)
# 2の確認 = ユーザーが作成されること
self.assertTrue(User.objects.filter(username=valid_data["username"]).exists())
# 3の確認 = ログイン状態になること
self.assertIn(SESSION_KEY, self.client.session)

def test_failure_post_with_empty_form(self):
empty_form = {
"username": "",
"email": "",
"password1": "",
"password2": "",
}

response = self.client.post(self.url, data=empty_form)
self.assertEqual(response.status_code, 200)
self.assertEqual(User.objects.all().count(), 0)

context = response.context
form = context["form"]
self.assertFalse(form.is_valid())
self.assertEqual(form.errors["username"][0], "このフィールドは必須です。")
self.assertEqual(form.errors["email"][0], "このフィールドは必須です。")
self.assertEqual(form.errors["password1"][0], "このフィールドは必須です。")
self.assertEqual(form.errors["password2"][0], "このフィールドは必須です。")

def test_failure_post_with_empty_username(self):
data_empty_username = {
"username": "",
"email": "[email protected]",
"password1": "testpassword",
"password2": "testpassword",
}
response = self.client.post(self.url, data_empty_username)
form = response.context["form"]

self.assertEqual(response.status_code, 200)
self.assertFalse(User.objects.filter(username=data_empty_username["username"]).exists())
self.assertFalse(form.is_valid())
self.assertIn("このフィールドは必須です。", form.errors["username"])

def test_failure_post_with_empty_email(self):
data_empty_email = {
"username": "new_user",
"email": "",
"password1": "testpassword",
"password2": "testpassword",
}
response = self.client.post(self.url, data_empty_email)
form = response.context["form"]

self.assertEqual(response.status_code, 200)
self.assertFalse(User.objects.filter(email=data_empty_email["email"]).exists())
self.assertFalse(form.is_valid())
self.assertIn("このフィールドは必須です。", form.errors["email"])

def test_failure_post_with_empty_password(self):
data_empty_password = {
"username": "new_user",
"email": "[email protected]",
"password1": "",
"password2": "",
}
response = self.client.post(self.url, data_empty_password)
form = response.context["form"]

self.assertEqual(response.status_code, 200)
self.assertFalse(User.objects.filter(password=data_empty_password["password1"]).exists())
self.assertFalse(form.is_valid())
self.assertIn("このフィールドは必須です。", form.errors["password1"])

def test_failure_post_with_duplicated_user(self):
duplicated_data = {
"username": "testuser",
"email": "[email protected]",
"password1": "testpassword",
"password2": "testpassword",
}

User.objects.create_user(
username="testuser",
email="[email protected]",
password="testpassword",
)

response = self.client.post(self.url, data=duplicated_data)
self.assertEqual(response.status_code, 200)
self.assertEqual(User.objects.all().count(), 1)

context = response.context
form = context["form"]
self.assertFalse(form.is_valid())
self.assertEqual(form.errors["username"][0], "同じユーザー名が既に登録済みです。")

def test_failure_post_with_invalid_email(self):
invalid_email_data = {
"username": "testuser",
"email": "test",
"password": "testpassword",
"password": "testpassword",
}

response = self.client.post(self.url, data=invalid_email_data)
self.assertEqual(response.status_code, 200)
self.assertEqual(User.objects.all().count(), 0)

context = response.context
form = context["form"]
self.assertFalse(form.is_valid())
self.assertEqual(form.errors["email"][0], "有効なメールアドレスを入力してください。")

def test_failure_post_with_too_short_password(self):
short_password_data = {
"username": "testuser",
"email": "[email protected]",
"password1": "short",
"password2": "short",
}

response = self.client.post(self.url, data=short_password_data)
self.assertEqual(response.status_code, 200) # assertEqualは、第1引数と第2引数が等しいことを確認する
self.assertEqual(User.objects.all().count(), 0)

context = response.context
form = context["form"]
self.assertFalse(form.is_valid())
self.assertEqual(form.errors["password2"][0], "このパスワードは短すぎます。最低 8 文字以上必要です。")

def test_failure_post_with_password_similar_to_username(self):
password_similar_to_username_data = {
"username": "testuser",
"email": "[email protected]",
"password1": "testuserr",
"password2": "testuserr",
}

response = self.client.post(self.url, data=password_similar_to_username_data)
self.assertEqual(response.status_code, 200)
self.assertEqual(User.objects.all().count(), 0)

# responseは第1引数のurlに対して第2引数を送信したときのレスポンスの一覧

context = response.context
form = context["form"]
self.assertFalse(form.is_valid())
self.assertEqual(form.errors["password2"][0], "このパスワードは ユーザー名 と似すぎています。")

def test_failure_post_with_only_numbers_password(self):
only_numbers_password_data = {
"username": "testuser",
"email": "[email protected]",
"password1": "84927274",
"password2": "84927274",
}

response = self.client.post(self.url, data=only_numbers_password_data)
self.assertEqual(response.status_code, 200)
self.assertEqual(User.objects.all().count(), 0)

context = response.context
form = context["form"]
self.assertFalse(form.is_valid())
self.assertEqual(form.errors["password2"][0], "このパスワードは数字しか使われていません。")

def test_failure_post_with_mismatch_password(self):
mismatch_password_data = {
"username": "testuser",
"email": "[email protected]",
"password1": "firstpassword",
"password2": "secondpassword",
}

response = self.client.post(self.url, data=mismatch_password_data)
self.assertEqual(response.status_code, 200) # Response Status Code: 200
self.assertEqual(User.objects.all().count(), 0)

context = response.context
form = context["form"]
self.assertFalse(form.is_valid())
self.assertEqual(
form.errors["password2"][0], "確認用パスワードが一致しません。"
) # フォームに適切なエラーメッセージが含まれている


# from django.test import TestCase


# class TestSignupView(TestCase):
# def test_success_get(self):
# def test_success_get(self):

# def test_success_post(self):
# def test_success_post(self):

# def test_failure_post_with_empty_form(self):
# def test_failure_post_with_empty_form(self):

# def test_failure_post_with_empty_username(self):
# def test_failure_post_with_empty_username(self):

# def test_failure_post_with_empty_email(self):
# def test_failure_post_with_empty_email(self):

# def test_failure_post_with_empty_password(self):
# def test_failure_post_with_empty_password(self):

# def test_failure_post_with_duplicated_user(self):
# def test_failure_post_with_duplicated_user(self):

# def test_failure_post_with_invalid_email(self):
# def test_failure_post_with_invalid_email(self):

# def test_failure_post_with_too_short_password(self):
# def test_failure_post_with_too_short_password(self):

# def test_failure_post_with_password_similar_to_username(self):

Expand Down
6 changes: 3 additions & 3 deletions accounts/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# from django.contrib.auth import views as auth_views
# from django.urls import path
from django.urls import path

# from . import views
from . import views

app_name = "accounts"

urlpatterns = [
# path('signup/', views.SignupView.as_view(), name='signup'),
path("signup/", views.SignupView.as_view(), name="signup"),
# path('login/', auth_views.LoginView.as_view(), name='login'),
# path('logout/', auth_views.LogoutView.as_view(), name='logout'),
# path('<str:username>/', views.UserProfileView.as_view(), name='user_profile'),
Expand Down
Loading
Loading