更新公告功能;去除小组可见公告;增加后端测试;修改后台对应的 js 和界面

This commit is contained in:
virusdefender
2015-10-16 20:43:34 +08:00
parent b43970d058
commit 723b26a828
9 changed files with 88 additions and 6142 deletions

View File

@@ -1,43 +0,0 @@
# coding=utf-8
from functools import wraps
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from utils.shortcuts import error_response, error_page
from account.models import SUPER_ADMIN
from .models import Announcement
def check_user_announcement_permission(func):
@wraps(func)
def _check_user_announcement_permission(*args, **kwargs):
"""
这个函数检测当前用户能否查看这个公告
"""
# CBV 的情况第一个参数是self第二个参数是request
if len(args) == 2:
request = args[-1]
else:
request = args[0]
if "announcement_id" not in kwargs:
return error_page(request, u"参数错误")
announcement_id = kwargs["announcement_id"]
try:
announcement = Announcement.objects.get(id=announcement_id, visible=True)
except Announcement.DoesNotExist:
return error_page(request, u"公告不存在")
# 如果公告是只有部分小组可见的
if not announcement.is_global:
# 用户必须是登录状态的
if not request.user.is_authenticated():
return HttpResponseRedirect("/login/")
if not announcement.groups.filter(id__in=request.user.group_set.all()).exists():
return error_page(request, u"公告不存在")
return func(*args, **kwargs)
return _check_user_announcement_permission

View File

@@ -19,9 +19,6 @@ class Announcement(models.Model):
last_update_time = models.DateTimeField(auto_now=True)
# 是否可见 false的话相当于删除
visible = models.BooleanField(default=True)
# 公告可见范围 True 是全局可见 False 是部分小组可见,需要在下面的字段中存储可见的小组
is_global = models.BooleanField()
groups = models.ManyToManyField(Group)
class Meta:
db_table = "announcement"

View File

@@ -8,8 +8,6 @@ from .models import Announcement
class CreateAnnouncementSerializer(serializers.Serializer):
title = serializers.CharField(max_length=50)
content = serializers.CharField(max_length=10000)
is_global = serializers.BooleanField()
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
class AnnouncementSerializer(serializers.ModelSerializer):
@@ -29,6 +27,4 @@ class EditAnnouncementSerializer(serializers.Serializer):
id = serializers.IntegerField()
title = serializers.CharField(max_length=50)
content = serializers.CharField(max_length=10000)
visible = serializers.BooleanField()
is_global = serializers.BooleanField()
groups = serializers.ListField(child=serializers.IntegerField(), required=False, default=[])
visible = serializers.BooleanField()

View File

@@ -1,171 +1,64 @@
# coding=utf-8
from django.core.urlresolvers import reverse
from django.test import TestCase
from django.test import TestCase, Client
from rest_framework.test import APITestCase, APIClient
from account.models import User
from account.tests import create_user
from group.models import Group
from announcement.models import Announcement
from account.models import REGULAR_USER, ADMIN, SUPER_ADMIN
from account.models import ADMIN, SUPER_ADMIN
class AnnouncementAdminAPITest(APITestCase):
def setUp(self):
self.client = APIClient()
self.url = reverse("announcement_admin_api")
user1 = User.objects.create(username="test1", admin_type=SUPER_ADMIN)
user1.set_password("testaa")
user1.save()
user2 = User.objects.create(username="test2", admin_type=ADMIN)
user2.set_password("testbb")
user2.save()
self.group = Group.objects.create(name="group1", description="des0",
join_group_setting=0, visible=True,
admin=user2)
self.announcement = Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test2"),
is_global=False)
def setUp(self):
self.client = APIClient()
self.url = reverse("announcement_admin_api")
self.user1 = create_user(admin_type=SUPER_ADMIN)
# 以下是发布公告的测试
def test_invalid_format(self):
self.client.login(username="test1", password="testaa")
data = {"title": "test1"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data["code"], 1)
self.user2 = create_user(username="test1", email="test1@qq.com", admin_type=SUPER_ADMIN)
def test_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "content": "content0", "is_global": False}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"至少选择一个小组"})
self.announcement = Announcement.objects.create(title="bb",
content="BB",
created_by=self.user1)
def test_global_announcement_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"title": "title0", "content": "content0", "is_global": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
def test_create_announcement_successfully(self):
self.client.login(username="test", password="111111")
data = {"title": "title0", "content": "content0"}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
def test_group_announcement_successfully(self):
self.client.login(username="test2", password="testbb")
data = {"title": "title0", "content": "content0", "is_global": False, "groups": [self.group.id]}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 0, "data": u"公告发布成功!"})
def test_global_announcement_does_not_has_privileges(self):
self.client.login(username="test2", password="testbb")
data = {"title": "title0", "content": "content0", "is_global": True}
response = self.client.post(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"只有超级管理员可以创建全局公告"})
# 以下是编辑公告的测试
def test_put_invalid_data(self):
self.client.login(username="test1", password="testaa")
data = {"title": "test0", "content": "test0", "visible": "True"}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 1)
def test_announcement_does_not_exist(self):
self.client.login(username="test1", password="testaa")
announcement = Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test1"),
is_global=True)
data = {"id": announcement.id + 1, "title": "11", "content": "22",
"visible": True, "is_global": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"公告不存在"})
def test_edit_global_announcement_successfully(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.announcement.id, "title": "11", "content": "22",
"visible": True, "is_global": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
def test_edit_group_announcement_successfully(self):
self.client.login(username="test2", password="testbb")
data = {"id": self.announcement.id, "title": "11", "content": "22",
"visible": True, "is_global": False, "groups": [self.group.id]}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
self.assertEqual(response.data["data"]["title"], "11")
self.assertEqual(response.data["data"]["content"], "22")
def test_edit_group_at_least_one(self):
self.client.login(username="test1", password="testaa")
data = {"id": self.announcement.id, "title": "title0", "content": "content0",
"visible": True, "is_global": False}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data, {"code": 1, "data": u"至少选择一个小组"})
# 以下是公告分页的测试
def test_get_data_successfully(self):
self.client.login(username="test1", password="testaa")
self.assertEqual(self.client.get(self.url).data["code"], 0)
def test_keyword_global_announcement(self):
self.client.login(username="test1", password="testaa")
Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test1"),
visible=True,
is_global=True)
Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test1"),
visible=False,
is_global=True)
response = self.client.get(self.url + "?visible=true")
self.assertEqual(response.data["code"], 0)
for item in response.data["data"]:
self.assertEqual(item["visible"], True)
def test_keyword_group_announcement(self):
self.client.login(username="test2", password="testbb")
Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test2"),
visible=True,
is_global=False)
Announcement.objects.create(title="cc",
content="CC",
created_by=User.objects.get(username="test2"),
visible=False,
is_global=False)
response = self.client.get(self.url + "?visible=true")
self.assertEqual(response.data["code"], 0)
for item in response.data["data"]:
self.assertEqual(item["visible"], True)
def test_edit_announcement_successfully(self):
self.client.login(username="test", password="111111")
data = {"id": self.announcement.id, "title": "11", "content": "22", "visible": True}
response = self.client.put(self.url, data=data)
self.assertEqual(response.data["code"], 0)
class AnnouncementPageTest(TestCase):
def setUp(self):
user = User.objects.create(username="test")
user.set_password("testaa")
user.save()
Announcement.objects.create(title="aa",
content="AA",
created_by=User.objects.get(username="test"),
visible=True,
is_global=True)
self.client = Client()
user = create_user()
self.a1 = Announcement.objects.create(title="aa",
content="AA",
created_by=user,
visible=True,
)
Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test"),
visible=False,
is_global=True)
self.a2 = Announcement.objects.create(title="bb",
content="BB",
created_by=User.objects.get(username="test"),
visible=False
)
def test_visit_announcement_successfully(self):
response = self.client.get('/announcement/1/')
self.assertEqual(response.status_code, 200)
response = self.client.get('/announcement/' + str(self.a1.id) + "/")
self.assertTemplateUsed(response, "oj/announcement/announcement.html")
def test_announcement_does_not_exist(self):
response = self.client.get('/announcement/3/')
response = self.client.get('/announcement/10086/')
self.assertTemplateUsed(response, "utils/error.html")
def test_visit_hidden_announcement(self):
response = self.client.get('/announcement/' + str(self.a2.id) + "/")
self.assertTemplateUsed(response, "utils/error.html")

View File

@@ -6,20 +6,26 @@ from utils.shortcuts import serializer_invalid_response, error_response, success
from utils.shortcuts import paginate, error_page
from account.models import SUPER_ADMIN, ADMIN
from account.decorators import super_admin_required
from group.models import Group
from .models import Announcement
from .serializers import (CreateAnnouncementSerializer, AnnouncementSerializer,
EditAnnouncementSerializer)
from .decorators import check_user_announcement_permission
@check_user_announcement_permission
def announcement_page(request, announcement_id):
announcement = Announcement.objects.get(id=announcement_id, visible=True)
"""
公告的详情页面
"""
try:
announcement = Announcement.objects.get(id=announcement_id, visible=True)
except Announcement.DoesNotExist:
return error_page(request, u"公告不存在")
return render(request, "oj/announcement/announcement.html", {"announcement": announcement})
class AnnouncementAdminAPIView(APIView):
@super_admin_required
def post(self, request):
"""
公告发布json api接口
@@ -29,29 +35,12 @@ class AnnouncementAdminAPIView(APIView):
serializer = CreateAnnouncementSerializer(data=request.data)
if serializer.is_valid():
data = serializer.data
groups = []
# 如果不是全局公告就去查询一下小组的id 列表中的内容,注意用户身份
if not data["is_global"]:
if request.user.admin_type == SUPER_ADMIN:
groups = Group.objects.filter(id__in=data["groups"])
else:
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
if not groups.count():
return error_response(u"至少选择一个小组")
else:
if request.user.admin_type != SUPER_ADMIN:
return error_response(u"只有超级管理员可以创建全局公告")
announcement = Announcement.objects.create(title=data["title"],
content=data["content"],
created_by=request.user,
is_global=data["is_global"])
announcement.groups.add(*groups)
Announcement.objects.create(title=data["title"], content=data["content"], created_by=request.user)
return success_response(u"公告发布成功!")
else:
return serializer_invalid_response(serializer)
@super_admin_required
def put(self, request):
"""
公告编辑json api接口
@@ -63,43 +52,27 @@ class AnnouncementAdminAPIView(APIView):
if serializer.is_valid():
data = serializer.data
try:
if request.user.admin_type == SUPER_ADMIN:
announcement = Announcement.objects.get(id=data["id"])
else:
announcement = Announcement.objects.get(id=data["id"], created_by=request.user)
announcement = Announcement.objects.get(id=data["id"])
except Announcement.DoesNotExist:
return error_response(u"公告不存在")
groups = []
if not data["is_global"]:
if request.user.admin_type == SUPER_ADMIN:
groups = Group.objects.filter(id__in=data["groups"])
else:
groups = Group.objects.filter(id__in=data["groups"], admin=request.user)
if not groups.count():
return error_response(u"至少选择一个小组")
announcement.title = data["title"]
announcement.content = data["content"]
announcement.visible = data["visible"]
announcement.is_global = data["is_global"]
announcement.save()
# 重建小组和公告的对应关系
announcement.groups.clear()
announcement.groups.add(*groups)
return success_response(AnnouncementSerializer(announcement).data)
else:
return serializer_invalid_response(serializer)
@super_admin_required
def get(self, request):
"""
公告分页json api接口
---
response_serializer: AnnouncementSerializer
"""
if request.user.admin_type == SUPER_ADMIN:
announcement = Announcement.objects.all().order_by("-last_update_time")
else:
announcement = Announcement.objects.filter(created_by=request.user)
announcement = Announcement.objects.all().order_by("-create_time")
visible = request.GET.get("visible", None)
if visible:
announcement = announcement.filter(visible=(visible == "true"))