Commit 8e5e788b authored by ibuler's avatar ibuler

Test case added

parent f45690b3
...@@ -29,13 +29,12 @@ class UserUpdateForm(ModelForm): ...@@ -29,13 +29,12 @@ class UserUpdateForm(ModelForm):
class Meta: class Meta:
model = User model = User
fields = [ fields = [
'name', 'email', 'groups', 'wechat', 'avatar', 'name', 'email', 'groups', 'wechat',
'phone', 'enable_otp', 'role', 'date_expired', 'comment', 'phone', 'enable_otp', 'role', 'date_expired', 'comment',
] ]
help_texts = { help_texts = {
'username': '* required', 'username': '* required',
'name': '* required',
'email': '* required', 'email': '* required',
'groups': '* required' 'groups': '* required'
} }
......
...@@ -7,6 +7,7 @@ from django.contrib.auth.hashers import make_password ...@@ -7,6 +7,7 @@ from django.contrib.auth.hashers import make_password
from django.utils import timezone from django.utils import timezone
from django.db import models from django.db import models
from django.contrib.auth.models import AbstractUser, Permission from django.contrib.auth.models import AbstractUser, Permission
from django.db import OperationalError
class Role(models.Model): class Role(models.Model):
...@@ -23,6 +24,12 @@ class Role(models.Model): ...@@ -23,6 +24,12 @@ class Role(models.Model):
def __unicode__(self): def __unicode__(self):
return self.name return self.name
def delete(self, using=None, keep_parents=False):
if self.user_set.all().count() > 0:
raise OperationalError('Role %s has some member, should not be delete.' % self.name)
else:
return super(Role, self).delete(using=using, keep_parents=keep_parents)
class Meta: class Meta:
db_table = 'role' db_table = 'role'
...@@ -56,7 +63,7 @@ class UserGroup(models.Model): ...@@ -56,7 +63,7 @@ class UserGroup(models.Model):
@classmethod @classmethod
def initial(cls): def initial(cls):
group_or_create = cls.objects.get_or_create(name='All', comment='Default user group for all user', group_or_create = cls.objects.get_or_create(name='Default', comment='Default user group for all user',
created_by='System') created_by='System')
return group_or_create[0] return group_or_create[0]
...@@ -93,7 +100,7 @@ class User(AbstractUser): ...@@ -93,7 +100,7 @@ class User(AbstractUser):
phone = models.CharField(max_length=20, blank=True, verbose_name='手机号') phone = models.CharField(max_length=20, blank=True, verbose_name='手机号')
enable_otp = models.BooleanField(default=False, verbose_name='启用二次验证') enable_otp = models.BooleanField(default=False, verbose_name='启用二次验证')
secret_key_otp = models.CharField(max_length=16, blank=True) secret_key_otp = models.CharField(max_length=16, blank=True)
role = models.ForeignKey(Role, on_delete=models.PROTECT, verbose_name='角色') role = models.ForeignKey(Role, on_delete=models.SET('None'), verbose_name='角色')
private_key = models.CharField(max_length=5000, blank=True, verbose_name='ssh私钥') # ssh key max length 4096 bit private_key = models.CharField(max_length=5000, blank=True, verbose_name='ssh私钥') # ssh key max length 4096 bit
public_key = models.CharField(max_length=1000, blank=True, verbose_name='公钥') public_key = models.CharField(max_length=1000, blank=True, verbose_name='公钥')
comment = models.TextField(max_length=200, blank=True, verbose_name='描述') comment = models.TextField(max_length=200, blank=True, verbose_name='描述')
...@@ -124,10 +131,12 @@ class User(AbstractUser): ...@@ -124,10 +131,12 @@ class User(AbstractUser):
if not self.name: if not self.name:
self.name = self.username self.name = self.username
super(User, self).save(args, **kwargs) super(User, self).save(args, **kwargs)
# Set user default group 'All' # Set user default group 'All'
# Todo: It's have bug
group = UserGroup.initial() group = UserGroup.initial()
self.groups.add(group) if group not in self.groups.all():
self.groups.add(group)
super(User, self).save(args, **kwargs)
class Meta: class Meta:
db_table = 'user' db_table = 'user'
......
...@@ -41,13 +41,14 @@ ...@@ -41,13 +41,14 @@
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<h3>角色安全</h3> <h3>角色安全</h3>
{{ form.role|bootstrap_horizontal }} {{ form.role|bootstrap_horizontal }}
<div class="form-group" id="date_5"> <div class="form-group {% if form.date_expired.errors %} has-error {% endif %}" id="date_5">
<label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label> <label for="{{ form.date_expired.id_for_label }}" class="col-sm-2 control-label">{{ form.date_expired.label }}</label>
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group date"> <div class="input-group date">
<span class="input-group-addon"><i class="fa fa-calendar"></i></span> <span class="input-group-addon"><i class="fa fa-calendar"></i></span>
<input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'m/d/Y' }}"> <input id="{{ form.date_expired.id_for_label }}" name="{{ form.date_expired.html_name }}" type="text" class="form-control" value="{{ form.date_expired.value|date:'m/d/Y' }}">
</div> </div>
<span class="help-block ">{{ form.date_expired.errors }}</span>
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
......
...@@ -4,26 +4,12 @@ from random import choice ...@@ -4,26 +4,12 @@ from random import choice
import forgery_py import forgery_py
from django.utils import timezone from django.utils import timezone
from django.shortcuts import reverse
from django.test import TestCase, Client, TransactionTestCase from django.test import TestCase, Client, TransactionTestCase
from django.test.utils import setup_test_environment from django.test.utils import setup_test_environment
from django.db import IntegrityError, transaction from django.db import IntegrityError, transaction
from .models import User, UserGroup, Role, init_all_models from .models import User, UserGroup, Role, init_all_models
from django.contrib.auth.models import Permission
setup_test_environment()
client = Client()
def create_usergroup(name):
pass
def get_random_usergroup():
pass
def create_user(username, name, email, groups):
pass
def gen_username(): def gen_username():
...@@ -42,54 +28,113 @@ class UserModelTest(TransactionTestCase): ...@@ -42,54 +28,113 @@ class UserModelTest(TransactionTestCase):
def setUp(self): def setUp(self):
init_all_models() init_all_models()
def test_user_duplicate(self): # 创建一个用户用于测试
# 创建一个基准测试用户
role = choice(Role.objects.all()) role = choice(Role.objects.all())
user = User(name='test', username='test', email='test@email.org', role=role) user = User(name='test', username='test', email='test@email.org', role=role)
user.save() user.save()
# 创建一个姓名一致的用户, 应该创建成功 def test_initial(self):
self.assertEqual(User.objects.all().count(), 2)
self.assertEqual(Role.objects.all().count(), 3)
self.assertEqual(UserGroup.objects.all().count(), 1)
@property
def role(self):
return choice(Role.objects.all())
# 创建一个姓名一致的用户, 应该创建成功
def test_user_name_duplicate(self):
user1 = User(name='test', username=gen_username(), password_raw=gen_username(), user1 = User(name='test', username=gen_username(), password_raw=gen_username(),
email=gen_email(), role=role) email=gen_email(), role=self.role)
try: try:
user1.save() user1.save()
user1.delete() user1.delete()
except IntegrityError: except IntegrityError:
self.assertTrue(0, 'Duplicate <name> not allowed.') self.assertTrue(0, 'Duplicate <name> not allowed.')
# 创建一个用户名一致的用户, 应该创建不成功 # 创建一个用户名一致的用户, 应该创建不成功
user2 = User(username='test', email=gen_email(), role=role) def test_user_username_duplicate(self):
user2 = User(username='test', email=gen_email(), role=self.role)
try: try:
user2.save() user2.save()
self.assertTrue(0, 'Duplicate <username> allowed.') self.assertTrue(0, 'Duplicate <username> allowed.')
except IntegrityError: except IntegrityError:
pass pass
# 创建一个Email一致的用户,应该创建不成功 # 创建一个Email一致的用户,应该创建不成功
user3 = User(username=gen_username(), email='test@email.org', role=role) def test_user_email_duplicate(self):
user3 = User(username=gen_username(), email='test@email.org', role=self.role)
try: try:
user3.save() user3.save()
self.assertTrue(0, 'Duplicate <email> allowed.') self.assertTrue(0, 'Duplicate <email> allowed.')
except IntegrityError: except IntegrityError:
pass pass
# 用户过期测试
def test_user_was_expired(self): def test_user_was_expired(self):
role = choice(Role.objects.all())
date = timezone.now() - timezone.timedelta(days=1) date = timezone.now() - timezone.timedelta(days=1)
user = User(name=gen_name(), username=gen_username(), user = User(name=gen_name(), username=gen_username(),
email=gen_email(), role=role, date_expired=date) email=gen_email(), role=self.role, date_expired=date)
self.assertTrue(user.is_expired()) self.assertTrue(user.is_expired())
# 测试用户默认会输入All用户组
def test_user_with_default_group(self): def test_user_with_default_group(self):
role = choice(Role.objects.all()) role = choice(Role.objects.all())
user = User(username=gen_username(), email=gen_email(), role=role) user = User(username=gen_username(), email=gen_email(), role=role)
user.save() user.save()
self.assertEqual(user.groups.count(), 1) self.assertEqual(user.groups.count(), 1)
self.assertEqual(user.groups.first().name, 'All') self.assertEqual(user.groups.first().name, 'Default')
def test_user_password_authenticated(self):
password = gen_username() * 3
user = User(username=gen_username(), password_raw=password, role=self.role)
user.save()
self.assertTrue(user.check_password(password))
self.assertFalse(user.check_password(password*2))
class UserListViewTests(TestCase): def tearDown(self):
User.objects.all().delete()
UserGroup.objects.all().delete()
Role.objects.all().delete()
class RoleModelTestCase(TransactionTestCase):
def setUp(self):
Role.objects.all().delete()
Role.initial()
def test_role_initial(self):
self.assertEqual(Role.objects.all().count(), 3)
def test_create_new_role(self):
role = Role(name=gen_name(), comment=gen_name()*3)
role.save()
role.permissions = Permission.objects.all()
role.save()
self.assertEqual(Role.objects.count(), 4)
role = Role.objects.last()
self.assertEqual(role.permissions.all().count(), Permission.objects.all().count())
class UserGroupModelTestCase(TransactionTestCase):
pass pass
class UserListViewTests(TestCase):
def setUp(self):
init_all_models()
User.generate_fake()
def test_list_view_with_one_user(self):
response = self.client.get(reverse('users:user-list'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, 'Admin')
self.assertQuerysetEqual(response.context['user_list'], [repr(user) for user in User.objects.all()])
def test_pagination(self):
response = self.client.get(reverse('users:user-list'))
self.assertContains(response.status_code, 200)
...@@ -72,6 +72,10 @@ class UserUpdateView(UpdateView): ...@@ -72,6 +72,10 @@ class UserUpdateView(UpdateView):
user.set_password(password) user.set_password(password)
return super(UserUpdateView, self).form_valid(form) return super(UserUpdateView, self).form_valid(form)
def form_invalid(self, form):
print(form.errors)
return super(UserUpdateView, self).form_invalid(form)
class UserDeleteView(DeleteView): class UserDeleteView(DeleteView):
model = User model = User
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment