Skip to content
This repository was archived by the owner on Jan 2, 2023. It is now read-only.

Commit 0f65071

Browse files
committedAug 9, 2020
init
Signed-off-by: Egor Kostan <igorkostan@gmail.com>
1 parent d7be976 commit 0f65071

File tree

11 files changed

+170
-1
lines changed

11 files changed

+170
-1
lines changed
 

‎app/app/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
'django.contrib.sessions',
3838
'django.contrib.messages',
3939
'django.contrib.staticfiles',
40+
'core',
4041
]
4142

4243
MIDDLEWARE = [
@@ -118,3 +119,5 @@
118119
# https://docs.djangoproject.com/en/2.2/howto/static-files/
119120

120121
STATIC_URL = '/static/'
122+
123+
AUTH_USER_MODEL = 'core.User'

‎app/app/urls.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,9 @@
1414
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
1515
"""
1616
from django.contrib import admin
17-
from django.urls import path
17+
from django.urls import path, include
1818

1919
urlpatterns = [
2020
path('admin/', admin.site.urls),
21+
path('', include('core.urls')),
2122
]

‎app/core/__init__.py

Whitespace-only changes.

‎app/core/admin.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# from django.contrib import admin
2+
3+
# Register your models here.

‎app/core/apps.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.apps import AppConfig
2+
3+
4+
class CoreConfig(AppConfig):
5+
name = 'core'

‎app/core/migrations/0001_initial.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Generated by Django 2.2.13 on 2020-08-08 04:28
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
initial = True
9+
10+
dependencies = [
11+
('auth', '0011_update_proxy_permissions'),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name='User',
17+
fields=[
18+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
19+
('password', models.CharField(max_length=128, verbose_name='password')),
20+
('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')),
21+
('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')),
22+
('email', models.EmailField(max_length=255, unique=True)),
23+
('name', models.CharField(max_length=255)),
24+
('is_active', models.BooleanField(default=True)),
25+
('is_staff', models.BooleanField(default=False)),
26+
('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')),
27+
('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')),
28+
],
29+
options={
30+
'abstract': False,
31+
},
32+
),
33+
]

‎app/core/migrations/__init__.py

Whitespace-only changes.

‎app/core/models.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from django.db import models
2+
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager, \
3+
PermissionsMixin
4+
5+
# Create your models here.
6+
7+
MESSAGES = {
8+
'invalid_email': 'ERROR: invalid email address is not allowed!',
9+
}
10+
11+
12+
class UserManager(BaseUserManager):
13+
14+
def create_user(self, email, password=None, **extra_fields):
15+
"""Create and saves a new user"""
16+
if not email:
17+
raise ValueError(MESSAGES['invalid_email'])
18+
user = self.model(email=self.normalize_email(email),
19+
**extra_fields)
20+
user.set_password(password)
21+
user.save(using=self._db)
22+
return user
23+
24+
def create_superuser(self, email, password):
25+
"""Create and save a new superuser"""
26+
user = self.create_user(email, password)
27+
user.is_superuser = True
28+
user.is_staff = True
29+
user.save(using=self._db)
30+
return user
31+
32+
33+
class User(AbstractBaseUser, PermissionsMixin):
34+
"""Custom user model that supports user email instead of username"""
35+
email = models.EmailField(max_length=255, unique=True)
36+
name = models.CharField(max_length=255)
37+
is_active = models.BooleanField(default=True)
38+
is_staff = models.BooleanField(default=False)
39+
40+
objects = UserManager()
41+
USERNAME_FIELD = 'email'

‎app/core/tests/__init__.py

Whitespace-only changes.

‎app/core/tests/test_models.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from django.test import TestCase
2+
from django.contrib.auth import get_user_model
3+
from core.models import MESSAGES
4+
5+
6+
class ModelTests(TestCase):
7+
8+
def test_create_user_with_email_successful(self):
9+
"""Test creating a new user with email is successful"""
10+
# Arrange
11+
email = "test@testemail.com"
12+
password = 'password123'
13+
# Act
14+
user = get_user_model().objects.create_user(
15+
email=email,
16+
password=password
17+
)
18+
# Assert
19+
# compare emails
20+
self.assertEqual(user.email, email)
21+
# compare passwords
22+
self.assertTrue(user.check_password(password))
23+
24+
def test_new_user_email_normalized(self):
25+
"""Test the mmail for a new user is normalized"""
26+
# Arrange
27+
email = "tEst@teStemaiL.cOM"
28+
# Act
29+
user = get_user_model().objects.create_user(
30+
email=email,
31+
password='password123'
32+
)
33+
# Assert
34+
self.assertEqual(user.email, 'tEst@testemail.com')
35+
36+
def test_new_user_invalid_email(self):
37+
"""Test creating new user with no email raises error"""
38+
with self.assertRaises(ValueError):
39+
# Arrange & Act
40+
get_user_model().objects.create_user(
41+
email=None,
42+
password='password123'
43+
)
44+
45+
def test_invalid_email_error(self):
46+
"""Verify 'invalid_email' error"""
47+
# Arrange & Act
48+
try:
49+
get_user_model().objects.create_user(
50+
email=None,
51+
password='password123'
52+
)
53+
except ValueError as e:
54+
self.assertEqual(e.__str__(), MESSAGES['invalid_email'])
55+
56+
def test_create_new_superuser(self):
57+
"""Test creating a new superuser"""
58+
user = get_user_model().objects.create_superuser(
59+
email='superuser@test.com',
60+
password='password123'
61+
)
62+
63+
self.assertTrue(user.is_superuser)
64+
self.assertTrue(user.is_staff)

‎app/core/urls.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""app URL Configuration
2+
3+
The `urlpatterns` list routes URLs to views. For more information please see:
4+
https://docs.djangoproject.com/en/2.2/topics/http/urls/
5+
Examples:
6+
Function views
7+
1. Add an import: from my_app import views
8+
2. Add a URL to urlpatterns: path('', views.home, name='home')
9+
Class-based views
10+
1. Add an import: from other_app.views import Home
11+
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
12+
Including another URLconf
13+
1. Import the include() function: from django.urls import include, path
14+
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
15+
"""
16+
# from django.urls import path, include
17+
18+
urlpatterns = [
19+
]

0 commit comments

Comments
 (0)