From 487046081e707c8513737f31a93d69001efbfddd Mon Sep 17 00:00:00 2001 From: SvyatoslavArtymovych Date: Mon, 24 Apr 2023 11:30:44 +0300 Subject: [PATCH] add contributor feat --- app/forms/__init__.py | 2 +- app/forms/book.py | 17 ++++++++++++- app/views/book.py | 31 +++++++++++++++++++++--- tests/test_book.py | 56 +++++++++++++++++++++++++++++++++---------- 4 files changed, 88 insertions(+), 18 deletions(-) diff --git a/app/forms/__init__.py b/app/forms/__init__.py index c98a5d5..7004f24 100644 --- a/app/forms/__init__.py +++ b/app/forms/__init__.py @@ -1,4 +1,4 @@ # flake8: noqa F401 from .auth import LoginForm from .user import UserForm, NewUserForm -from .book import CreateBookForm +from .book import CreateBookForm, AddContributorForm diff --git a/app/forms/book.py b/app/forms/book.py index fecb7b4..c9d5ec9 100644 --- a/app/forms/book.py +++ b/app/forms/book.py @@ -1,8 +1,23 @@ from flask_wtf import FlaskForm -from wtforms import StringField, SubmitField +from wtforms import StringField, SubmitField, SelectField from wtforms.validators import DataRequired, Length +from app import models as m + class CreateBookForm(FlaskForm): label = StringField("Label", [DataRequired(), Length(6, 1024)]) submit = SubmitField("Add new book") + + +class AddContributorForm(FlaskForm): + user_id = StringField("User ID", [DataRequired()]) + role = SelectField( + "Role", + choices=[ + (member.value, name.capitalize()) + for name, member in m.BookContributor.Roles.__members__.items() + ], + ) + + submit = SubmitField("Add Contributor") diff --git a/app/views/book.py b/app/views/book.py index 629c314..594d992 100644 --- a/app/views/book.py +++ b/app/views/book.py @@ -1,8 +1,7 @@ from flask import Blueprint, render_template, flash, redirect, url_for -from flask_login import login_required +from flask_login import login_required, current_user -from app import models as m -from app import forms as f +from app import models as m, db, forms as f from app.logger import log bp = Blueprint("book", __name__, url_prefix="/book") @@ -49,3 +48,29 @@ def create(): for error in errors: flash(error.replace("Field", field_label), "danger") return redirect(url_for("book.get_all")) + + +@bp.route("//add_contributor", methods=["POST"]) +@login_required +def add_contributor(book_id): + # TODO replace redirects to book.edit/settings + book: m.Book = db.session.get(m.Book, book_id) + if book.owner != current_user: + flash("You are not owner of this book!", "danger") + return redirect(url_for("book.get_all")) + + form = f.AddContributorForm() + + if form.validate_on_submit(): + role = m.BookContributor.Roles(int(form.role.data)) + m.BookContributor(user_id=form.user_id.data, book_id=book_id, role=role).save() + + flash("Contributor was added!", "success") + return redirect(url_for("book.get_all")) + else: + log(log.ERROR, "Book create errors: [%s]", form.errors) + for field, errors in form.errors.items(): + field_label = form._fields[field].label.text + for error in errors: + flash(error.replace("Field", field_label), "danger") + return redirect(url_for("book.get_all")) diff --git a/tests/test_book.py b/tests/test_book.py index 94b8355..3ddef7c 100644 --- a/tests/test_book.py +++ b/tests/test_book.py @@ -62,21 +62,51 @@ def test_create_book(client: FlaskClient): assert len(book.versions) == 1 -# def test_add_c(client: FlaskClient): -# login(client) +def test_add_contributor(client: FlaskClient): + _, user = login(client) + user: m.User + moderator = m.User(username="Moderator", password="test").save() -# response: Response = client.post( -# "/book/create", -# data=dict( -# label=BOOK_NAME, -# ), -# follow_redirects=True, -# ) + moderators_book = m.Book(label="Test Book", user_id=moderator.id).save() + response: Response = client.post( + f"/book/{moderators_book.id}/add_contributor", + data=dict(user_id=moderator.id, role=m.BookContributor.Roles.MODERATOR), + follow_redirects=True, + ) -# assert response.status_code == 200 -# assert b"Book added!" in response.data + assert response.status_code == 200 + assert b"You are not owner of this book!" in response.data -# book = m.Book.query.filter_by(label=BOOK_NAME).first() + book = m.Book(label="Test Book", user_id=user.id).save() -# assert book + response: Response = client.post( + f"/book/{book.id}/add_contributor", + data=dict(user_id=moderator.id, role=m.BookContributor.Roles.MODERATOR), + follow_redirects=True, + ) + + assert response.status_code == 200 + assert b"Contributor was added!" in response.data + + contributor: m.BookContributor = m.BookContributor.query.filter_by( + user=moderator, book=book + ).first() + assert contributor.role == m.BookContributor.Roles.MODERATOR + assert len(book.contributors) == 1 + + editor = m.User(username="Editor", password="test").save() + response: Response = client.post( + f"/book/{book.id}/add_contributor", + data=dict(user_id=editor.id, role=m.BookContributor.Roles.EDITOR), + follow_redirects=True, + ) + + assert response.status_code == 200 + assert b"Contributor was added!" in response.data + + contributor: m.BookContributor = m.BookContributor.query.filter_by( + user=editor, book=book + ).first() + assert contributor.role == m.BookContributor.Roles.EDITOR + assert len(book.contributors) == 2