def test_invalid_comment(self) -> None: """测试无效的评论""" post = Post.query.get(1) with db.auto_commit(): post.trash = True db.session.add(post) data = self.get_response_text_data('web.post', 'post', data={ 'author': 'replyAuthor', 'content': 'replyContent' }, follow_redirects=True, post_id=1) self.assertIn('找不到您要访问的页面', data) with db.auto_commit(): post.trash = False post.published = False db.session.add(post) data = self.get_response_text_data('web.post', 'post', data={ 'author': 'replyAuthor', 'content': 'replyContent' }, follow_redirects=True, post_id=1) self.assertIn('找不到您要访问的页面', data) with db.auto_commit(): post.trash = False post.published = True post.can_comment = False data = self.get_response_text_data('web.post', 'post', data={ 'author': 'replyAuthor', 'content': 'replyContent' }, follow_redirects=True, post_id=1) self.assertIn('评论已关闭', data) self.assertNotIn('test content', data)
def new_post(): """新建文章视图""" form = PostForm(request.form) if form.validate_on_submit(): form.content.data = request.form['markdownEditor-html-code'] form.categories.data = [Category.query.get(category_id) for category_id in form.categories.data] if not form.description.data: form.description.data = remove_html_tag(form.content.data)[0:150] if form.publish.data: with db.auto_commit(): post = Post() post.set_attr(form.data) db.session.add(post) flash('文章已发布', 'success') if form.save.data: with db.auto_commit(): post = Post() post.set_attr(form.data) post.published = False db.session.add(post) flash('文章已保存为草稿', 'success') return redirect(url_for('web.manage_post')) return render_template('admin/post_editor.html', form=form)
def fake_comments(count=500): """Generate comment""" with db.auto_commit(): # reviewed comments for i in range(count): comment = Comment(author=faker.name(), email=faker.email(), site=faker.url(), body=faker.sentence(), timestamp=faker.date_time_this_year(), reviewed=True, post=Post.query.get( random.randint(1, Post.query.count()))) db.session.add(comment) salt = int(count * 0.1) with db.auto_commit(): # unreviewed comments for i in range(salt): comment = Comment(author=faker.name(), email=faker.email(), site=faker.url(), body=faker.sentence(), timestamp=faker.date_time_this_year(), reviewed=False, post=Post.query.get( random.randint(1, Post.query.count()))) db.session.add(comment) with db.auto_commit(): # admin comments for i in range(salt): comment = Comment(author='我是管理员', email='*****@*****.**', site='localhost:5000', body=faker.sentence(), timestamp=faker.date_time_this_year(), from_admin=True, reviewed=True, post=Post.query.get( random.randint(1, Post.query.count()))) db.session.add(comment) with db.auto_commit(): # reply comments for i in range(salt): comment = Comment(author=faker.name(), email=faker.email(), site=faker.url(), body=faker.sentence(), timestamp=faker.date_time_this_year(), reviewed=True, replied=Comment.query.get( random.randint(1, Comment.query.count())), post=Post.query.get( random.randint(1, Post.query.count()))) db.session.add(comment)
def delete(self): """ 执行删除分类操作 """ if self.posts: for post in self.posts: # 如果要删除的分类文章没有其它分类则将其移动至默认分类下 if len(post.categories) == 1: with db.auto_commit(): post.categories = [Category.query.get(1)] db.session.add(post) with db.auto_commit(): db.session.delete(self)
def manage_settings(): form = BlogSettingForm() admin = Admin.query.first() if form.validate_on_submit(): with db.auto_commit(): admin.set_attrs(form.data) db.session.add(admin) index_image = form.blog_index_image.data if index_image: upload_file(index_image, 'index_image') nav_image = form.blog_nav_image.data if nav_image: upload_file(nav_image, 'nav_image') favicon = form.blog_favicon.data if favicon: upload_file(favicon, 'favicon') flash('博客设置成功', 'success') return redirect_back() form.blog_title.data = admin.blog_title form.blog_sub_title.data = admin.blog_sub_title form.name.data = admin.name form.about.data = admin.about form.theme.data = admin.theme form.blog_index_image_url.data = admin.blog_index_image_url form.blog_description.data = admin.blog_description return render_template('admin/manage_settings.html', form=form)
def setUp(self) -> None: """启动测试前执行""" app = create_app(config='test') self.context = app.test_request_context() self.context.push() self.client = app.test_client() self.runner = app.test_cli_runner() self.runner.invoke(args=['initdb', '--_init']) self.fake_data = FakeData() self.fake_data.fake_admin() # 测试前生成一些少部分测试数据以供使用 category = Category( name='testCategory', alias='test-alias', ) link = Link( name='testLink', url='https://www.test.com', ) post = Post(title='testTitle', content='<p>testContent<p>', content_markdown='testContent', description='testDescription', categories=[category]) comment = Comment(author='testAuthor', content='testCommentContent', post=post, reviewed=True) with db.auto_commit(): db.session.add_all([category, link, post, comment])
def init(username, password): """ Init Admin account """ click.echo('Initializing Database...') db.create_all() admin = Admin.query.first() with db.auto_commit(): if admin: click.echo('The administrator already exists, updating...') admin.username = username admin.set_password(password) else: click.echo('Creating the temporary administrator account...') admin = Admin( username=username, blog_title='临时博客名', blog_sub_title='临时副标题', name='临时昵称', about='临时关于' ) admin.set_password(password) db.session.add(admin) category = Category.query.first() if category is None: click.echo('Create the default category...') category = Category(name='默认') db.session.add(category) click.echo('Done.')
def test_manage_comment_page(self) -> None: """测试评论管理页面""" self.fake_data.fake_comments(100) with db.auto_commit(): admin = Admin.query.first() admin.comment_per_page = 100 db.session.add(admin) data = self.get_response_text_data('web.manage_comment', 'get') self.assertIn('评论管理', data) self.assertNotIn('移出回收站', data) data = self.get_response_text_data('web.manage_comment', 'get', status='mine') self.assertNotIn('通过审核', data) data = self.get_response_text_data('web.manage_comment', 'get', status='unreviewed') self.assertNotIn('撤销审核', data) data = self.get_response_text_data('web.manage_comment', 'get', status='reviewed') self.assertNotIn('通过审核', data) data = self.get_response_text_data('web.manage_comment', 'get', status='trash') self.assertIn('暂无评论', data)
def fake_posts(cls, count: int = 50): """ 生成博客文章虚拟数据 :param count: default=50,生成 50 条文章记录 :return: None """ for i in range(count): with db.auto_commit(): post = Post() post.title = FakeData.FAKER.sentence() post.content = FakeData.FAKER.text(4000) # description 字段是为了 SEO 准备的,最大不超过 150 字符,默认取文章开头前 150 个字符 post.description = post.content[0: 149] category_id_one = random.randint(1, Category.query.count()) category_id_two = random.randint(1, Category.query.count()) # 分类 id 为 1 是默认分类,如果出现,则只给文章默认分类 if category_id_one == 1 or category_id_two == 1: post.categories = [Category.query.get(1)] # 如果分类 id 相同那么只取其中一个 elif category_id_one == category_id_two: post.categories = [Category.query.get(category_id_one)] else: post.categories = [ Category.query.get(category_id_one), Category.query.get(category_id_two) ] db.session.add(post)
def _generate_comments( _count: int, reviewed: bool = True, from_admin: bool = False, is_replied: bool = False ): """ 生成评论数据,内部调用 :param _count: 生成的评论数量 :param reviewed: default=True,默认是已审核评论 :param from_admin: default=False,默认不是管理员评论 :param is_replied: default=False,默认不是回复评论 :return: None """ comments_count = Comment.query.count() posts_count = Post.query.count() for i in range(_count): with db.auto_commit(): comment = Comment() if not from_admin: comment.author = cls.FAKER.name() comment.email = cls.FAKER.email() comment.site = cls.FAKER.url() else: comment.author = Admin.query.get(1).nickname comment.email = "*****@*****.**" comment.site = "localhost:5000" comment.content = cls.FAKER.text(random.randint(40, 200)) comment.from_admin = from_admin comment.reviewed = reviewed if is_replied: comment.replied = Comment.query.get(random.randint(1, comments_count)) comment.post = Post.query.get(random.randint(1, posts_count)) db.session.add(comment)
def admin(username, password): """设置管理员用户名与密码""" # 处理 MySQL 错误 try: admin = Admin.query.first() except Exception as e: if '1146' in str(e.orig): click.echo('数据表不存在,请执行 `flask initdb` 创建数据表') else: print(e) click.echo('请检查错误信息') return with db.auto_commit(): if admin: click.echo('更新管理员账户信息...') admin.username = username admin.password = password else: click.echo('创建管理员账户中...') admin = Admin() admin.username = username admin.password = password admin.blog_title = '临时博客名' admin.blog_subtitle = '临时博客副标题' admin.blog_about = '临时博客关于' admin.nickname = '临时昵称' db.session.add(admin) click.echo('Done.')
def test_delete_post(self) -> None: """测试删除文章功能""" self.client.post( url_for('web.delete_record', record_id=1, action='one', model_name='Post')) data = self.get_response_text_data('web.post', 'get', follow_redirects=True, post_id=1) self.assertIn('找不到您要访问的页面', data) data = self.get_response_text_data('web.manage_post', 'get') self.assertIn('暂无文章', data) self.fake_data.fake_posts(3) posts = Post.query.all() for post in posts: with db.auto_commit(): post.trash = True db.session.add(post) self.client.post( url_for('web.delete_record', action='all', model_name='Post')) data = self.get_response_text_data('web.manage_post', 'get') self.assertIn('暂无文章', data)
def delete(self): default_category = Category.query.get(1) posts = self.posts[:] for post in posts: post.category = default_category with db.auto_commit(): db.session.delete(self)
def test_admin(self) -> None: """测试 admin 命令""" result = self.runner.invoke(args=[ 'admin', '--username', 'newAdmin', '--password', '87654321', '--email', '*****@*****.**' ]) admin = Admin.query.first() self.assertIn('更新管理员账户信息', result.output) self.assertEqual('newAdmin', admin.username) self.assertEqual(True, admin.check_password('87654321')) with db.auto_commit(): db.session.delete(admin) result = self.runner.invoke(args=[ 'admin', '--username', 'newAdmin', '--password', '87654321', '--email', '*****@*****.**' ]) self.assertIn('创建管理员账户中', result.output) db.drop_all() result = self.runner.invoke(args=[ 'admin', '--username', 'newAdmin', '--password', '87654321', '--email', '*****@*****.**' ]) self.assertIn('请检查错误信息', result.output)
def test_delete_comment(self) -> None: """测试删除评论功能""" self.client.post( url_for('web.delete_record', record_id=1, action='one', model_name='Comment')) data = self.get_response_text_data('web.manage_comment', 'get') self.assertIn('暂无评论', data) self.fake_data.fake_comments(10) comments = Comment.query.all() for comment in comments: with db.auto_commit(): comment.trash = True db.session.add(comment) self.client.post( url_for('web.delete_record', action='all', model_name='Comment')) data = self.get_response_text_data('web.manage_comment', 'get') self.assertIn('暂无评论', data) data = self.get_response_text_data('web.delete_record', 'post', follow_redirects=True, record_id=1, action='one', model_name='Comment') self.assertIn('找不到您要访问的页面', data) self.check_login_required('web.delete_record', 'post', record_id=1, action='one', model_name='Comment')
def fake_category(count=10): """Generate post category""" with db.auto_commit(): category = Category(name='默认') db.session.add(category) for i in range(count): category = Category(name=faker.word()) db.session.add(category)
def fake_admin(): """Generate admin info""" with db.auto_commit(): admin = Admin(username='******', blog_title='测试博客名', blog_sub_title='测试副标题', name='测试昵称', about='测试关于,这个字符串需要稍微长一点,字数补丁...') db.session.add(admin)
def new_category(): form = CategoryForm() if form.validate_on_submit(): with db.auto_commit(): name = form.name.data db.session.add(Category(name=name)) flash('分类创建成功', 'success') return redirect(url_for('web.manage_categories')) return render_template('admin/new_category.html', form=form)
def set_comment(post_id): post = Post.query.get_or_404(post_id) with db.auto_commit(): if post.can_comment: post.can_comment = False flash('评论已关闭', 'info') else: post.can_comment = True flash('评论已开启', 'info') return redirect(url_for('web.show_post', post_id=post.id))
def fake_posts(count=50): """Generate post""" with db.auto_commit(): for i in range(count): post = Post(title=faker.sentence(), body=faker.text(2000), category=Category.query.get( random.randint(1, Category.query.count())), timestamp=faker.date_time_this_year()) db.session.add(post)
def new_link(): form = LinkForm() if form.validate_on_submit(): with db.auto_commit(): link = Link() link.set__attrs(form.data) db.session.add(link) flash('添加链接成功', 'success') return redirect(url_for('web.manage_links')) return render_template('admin/new_link.html', form=form)
def edit_post(post_id): """ 编辑文章视图 :param post_id: 文章 id """ post = Post.query.get_or_404(post_id) form = PostForm(request.form) if form.validate_on_submit(): form.content.data = request.form['markdownEditor-html-code'] form.categories.data = [ Category.query.get(category_id) for category_id in form.categories.data ] if not form.description.data: form.description.data = remove_html_tag(form.content.data)[0:150] if form.publish.data: with db.auto_commit(): post.set_attr(form.data) post.published = True db.session.add(post) flash('文章已更新', 'success') if form.save.data: with db.auto_commit(): post.set_attr(form.data) post.published = False db.session.add(post) flash('文章已保存为草稿', 'success') return redirect(url_for('web.manage_post')) if not form.errors: form.title.data = post.title form.categories.data = [category.id for category in post.categories] form.content_markdown.data = post.content_markdown form.description.data = post.description form.can_comment.data = post.can_comment return render_template('admin/post_editor.html', form=form, post=post)
def test_invalid_reply(self) -> None: """测试无效的回复""" data = self.get_response_text_data('web.post', 'post', data={ 'author': 'replyAuthor', 'content': 'replyContent' }, follow_redirects=True, post_id=1, reply_id=2) self.assertIn('找不到您要访问的页面', data) comment = Comment.query.get(1) with db.auto_commit(): comment.trash = True db.session.add(comment) data = self.get_response_text_data('web.post', 'post', data={ 'author': 'replyAuthor', 'content': 'replyContent' }, follow_redirects=True, post_id=1, reply_id=1) self.assertIn('找不到您要访问的页面', data) with db.auto_commit(): comment.trash = False comment.reviewed = False db.session.add(comment) data = self.get_response_text_data('web.post', 'post', data={ 'author': 'replyAuthor', 'content': 'replyContent' }, follow_redirects=True, post_id=1, reply_id=1) self.assertIn('找不到您要访问的页面', data) self.fake_data.fake_posts(1) with db.auto_commit(): comment.trash = False comment.reviewed = True comment.post_id = 2 db.session.add(comment) data = self.get_response_text_data('web.post', 'post', data={ 'author': 'replyAuthor', 'content': 'replyContent' }, follow_redirects=True, post_id=1, reply_id=1) self.assertIn('找不到您要访问的页面', data)
def delete_record(model_name, record_id, action): """ 删除文章或评论视图 :param model_name: 数据表模型名称,model_name = Comment or Post :param record_id: 记录 id :param action: 执行操作 action = all 删除全部回收站评论 """ model = current_app.config['MODELS'].get(model_name) if action == 'all': with db.auto_commit(): for record in model.query.filter_by(trash=True).all(): db.session.delete(record) flash('回收站已清空', 'success') return redirect_back(default_endpoint='web.manage_comment') record = model.query.get_or_404(record_id) with db.auto_commit(): db.session.delete(record) flash_message = '评论已删除' if model_name == 'Comment' else '文章已删除' flash(flash_message, 'success') return redirect_back()
def new_post(): form = PostForm() if form.validate_on_submit(): title = form.title.data body = form.body.data category = Category.query.get(form.category.data) with db.auto_commit(): post = Post(title=title, body=body, category=category) db.session.add(post) flash('文章发布成功', 'success') return redirect(url_for('web.show_post', post_id=post.id)) return render_template('admin/new_post.html', form=form)
def edit_category(category_id): form = CategoryForm() category = Category.query.get_or_404(category_id) if category.id == 1: flash('默认分类不能修改!', 'warning') return redirect(url_for('web.index')) if form.validate_on_submit(): with db.auto_commit(): category.name = form.name.data flash('分类更新成功', 'success') return redirect(url_for('web.manage_categories')) form.name.data = category.name return render_template('admin/edit_category.html', form=form)
def edit_link(link_id): form = LinkForm() link = Link.query.get_or_404(link_id) if form.validate_on_submit(): with db.auto_commit(): link.set__attrs(form.data) db.session.add(link) flash('链接更新成功!', 'success') return redirect(url_for('web.manage_links')) form.name.data = link.name form.tag.data = link.tag form.url.data = link.url return render_template('admin/edit_link.html', form=form)
def initdb(drop): """初始化数据库""" if drop: click.confirm('确定要删除所有数据表?', abort=True) db.drop_all() click.echo('数据表删除成功') db.create_all() # 初始化数据后在分类表中添加一条记录作为默认默认分类 with db.auto_commit(): category = Category() category.name = "未分类" category.show = False db.session.add(category) click.echo('数据表已成功创建')
def edit_post(post_id): form = PostForm() post = Post.query.get_or_404(post_id) if form.validate_on_submit(): with db.auto_commit(): post.title = form.title.data post.body = form.body.data post.category = Category.query.get(form.category.data) flash('文章更新成功', 'success') return redirect(url_for('web.show_post', post_id=post.id)) form.title.data = post.title form.body.data = post.body form.category.data = post.category_id return render_template('admin/edit_post.html', form=form)
def fake_admin(cls): """ 生成 admin 表虚拟数据 :return: None """ with db.auto_commit(): admin = Admin() admin.username = '******' admin.password = '******' admin.nickname = '临时管理员昵称' admin.blog_title = '临时博客名' admin.blog_subtitle = '临时博客副标题' admin.blog_about = FakeData.FAKER.text(1000) db.session.add(admin)