mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
Integrated verification requests #484
This commit is contained in:
parent
b57a286ef9
commit
26870f996e
33
cypress/e2e/verification_request.cy.js
Normal file
33
cypress/e2e/verification_request.cy.js
Normal file
@ -0,0 +1,33 @@
|
||||
describe("Verification request", () => {
|
||||
it("lists", () => {
|
||||
cy.login();
|
||||
cy.createAdminUnit().then(function (adminUnitId) {
|
||||
cy.createIncomingVerificationRequest(adminUnitId).then(function (
|
||||
requestId
|
||||
) {
|
||||
cy.visit(
|
||||
"/manage/admin_unit/" + adminUnitId + "/verification_requests/incoming"
|
||||
);
|
||||
cy.screenshot("incoming");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("creates", () => {
|
||||
cy.login();
|
||||
cy.createAdminUnit().then(function (adminUnitId) {
|
||||
cy.createAdminUnit("test@test.de", "Other Crew", false).then(function (otherAdminUnitId) {
|
||||
cy.visit("/manage/admin_unit/" + otherAdminUnitId + "/verification_requests/outgoing/create/select");
|
||||
cy.screenshot("create-select");
|
||||
cy.get(".btn-primary:first").click();
|
||||
|
||||
cy.url().should("include", "/verification_requests/outgoing/create/target");
|
||||
cy.screenshot("create");
|
||||
cy.get("#submit").click();
|
||||
|
||||
cy.url().should("include", "/verification_requests/outgoing");
|
||||
cy.screenshot("outgoing");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
42
cypress/e2e/verification_request_review.cy.js
Normal file
42
cypress/e2e/verification_request_review.cy.js
Normal file
@ -0,0 +1,42 @@
|
||||
describe("Verification request review", () => {
|
||||
it("reviews", () => {
|
||||
cy.login();
|
||||
cy.createAdminUnit().then(function (adminUnitId) {
|
||||
cy.createIncomingVerificationRequest(adminUnitId).then(function (
|
||||
requestId
|
||||
) {
|
||||
// Status
|
||||
cy.visit("/verification_request/" + requestId + "/review_status");
|
||||
cy.screenshot("status");
|
||||
|
||||
// Reject
|
||||
cy.visit("/verification_request/" + requestId + "/review");
|
||||
cy.screenshot("review");
|
||||
cy.get(".decision-container .btn-danger").click();
|
||||
cy.get("#rejectFormModal select[name=rejection_reason]")
|
||||
.select("Nicht relevant")
|
||||
.should("have.value", "6");
|
||||
cy.get("#rejectFormModal").screenshot("reject");
|
||||
cy.get("#rejectFormModal .btn-danger").click();
|
||||
cy.url().should("include", "/verification_requests/incoming");
|
||||
cy.get("div.alert").should(
|
||||
"contain",
|
||||
"Verifizierungsanfrage erfolgreich aktualisiert"
|
||||
);
|
||||
cy.get("main .badge-pill").should("contain", "Abgelehnt");
|
||||
|
||||
// Accept
|
||||
cy.visit("/verification_request/" + requestId + "/review");
|
||||
cy.get(".decision-container .btn-success").click();
|
||||
cy.get("#auto_verify").parent().click();
|
||||
cy.get("#acceptFormModal").screenshot("accept");
|
||||
cy.get("#acceptFormModal .btn-success").click();
|
||||
cy.url().should("include", "/verification_requests/incoming");
|
||||
cy.get("div.alert").should(
|
||||
"contain",
|
||||
"Organisation erfolgreich verifiziert"
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -32,9 +32,11 @@ Cypress.Commands.add(
|
||||
|
||||
Cypress.Commands.add(
|
||||
"createAdminUnit",
|
||||
(userEmail = "test@test.de", name = "Meine Crew") => {
|
||||
(userEmail = "test@test.de", name = "Meine Crew", verified = true) => {
|
||||
let cmd = "flask test admin-unit-create " + userEmail + ' "' + name + '"';
|
||||
cmd += (verified) ? " --verified" : " --no-verified";
|
||||
return cy
|
||||
.logexec("flask test admin-unit-create " + userEmail + ' "' + name + '"')
|
||||
.logexec(cmd)
|
||||
.then(function (result) {
|
||||
let json = JSON.parse(result.stdout);
|
||||
return json.admin_unit_id;
|
||||
@ -114,6 +116,15 @@ Cypress.Commands.add("createOauth2Client", (userId) => {
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add("createIncomingVerificationRequest", (adminUnitId) => {
|
||||
return cy
|
||||
.logexec("flask test verification-request-create-incoming " + adminUnitId)
|
||||
.then(function (result) {
|
||||
let json = JSON.parse(result.stdout);
|
||||
return json.verification_request_id;
|
||||
});
|
||||
});
|
||||
|
||||
Cypress.Commands.add("createIncomingReferenceRequest", (adminUnitId) => {
|
||||
return cy
|
||||
.logexec("flask test reference-request-create-incoming " + adminUnitId)
|
||||
|
||||
475
messages.pot
475
messages.pot
File diff suppressed because it is too large
Load Diff
91
migrations/versions/6634c8f0b7fc_.py
Normal file
91
migrations/versions/6634c8f0b7fc_.py
Normal file
@ -0,0 +1,91 @@
|
||||
"""empty message
|
||||
|
||||
Revision ID: 6634c8f0b7fc
|
||||
Revises: becc71f97606
|
||||
Create Date: 2023-05-31 22:37:22.719433
|
||||
|
||||
"""
|
||||
import sqlalchemy as sa
|
||||
import sqlalchemy_utils
|
||||
from alembic import op
|
||||
|
||||
from project import dbtypes
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequestRejectionReason,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = "6634c8f0b7fc"
|
||||
down_revision = "becc71f97606"
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.create_table(
|
||||
"adminunitverificationrequest",
|
||||
sa.Column("id", sa.Integer(), nullable=False),
|
||||
sa.Column("source_admin_unit_id", sa.Integer(), nullable=False),
|
||||
sa.Column("target_admin_unit_id", sa.Integer(), nullable=False),
|
||||
sa.Column(
|
||||
"review_status",
|
||||
dbtypes.IntegerEnum(AdminUnitVerificationRequestReviewStatus),
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column(
|
||||
"rejection_reason",
|
||||
dbtypes.IntegerEnum(AdminUnitVerificationRequestRejectionReason),
|
||||
nullable=True,
|
||||
),
|
||||
sa.Column("created_at", sa.DateTime(), nullable=True),
|
||||
sa.Column("updated_at", sa.DateTime(), nullable=True),
|
||||
sa.Column("created_by_id", sa.Integer(), nullable=True),
|
||||
sa.Column("updated_by_id", sa.Integer(), nullable=True),
|
||||
sa.CheckConstraint(
|
||||
"source_admin_unit_id != target_admin_unit_id",
|
||||
name=op.f("ck_adminunitverificationrequest_auvr_source_neq_target"),
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["created_by_id"],
|
||||
["user.id"],
|
||||
name=op.f("fk_adminunitverificationrequest_created_by_id_user"),
|
||||
ondelete="SET NULL",
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["source_admin_unit_id"],
|
||||
["adminunit.id"],
|
||||
name=op.f("fk_adminunitverificationrequest_source_admin_unit_id_adminunit"),
|
||||
ondelete="CASCADE",
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["target_admin_unit_id"],
|
||||
["adminunit.id"],
|
||||
name=op.f("fk_adminunitverificationrequest_target_admin_unit_id_adminunit"),
|
||||
ondelete="CASCADE",
|
||||
),
|
||||
sa.ForeignKeyConstraint(
|
||||
["updated_by_id"],
|
||||
["user.id"],
|
||||
name=op.f("fk_adminunitverificationrequest_updated_by_id_user"),
|
||||
ondelete="SET NULL",
|
||||
),
|
||||
sa.PrimaryKeyConstraint("id", name=op.f("pk_adminunitverificationrequest")),
|
||||
sa.UniqueConstraint(
|
||||
"source_admin_unit_id",
|
||||
"target_admin_unit_id",
|
||||
name=op.f("uq_adminunitverificationrequest_source_admin_unit_id"),
|
||||
),
|
||||
)
|
||||
op.add_column(
|
||||
"adminunit", sa.Column("description", sa.UnicodeText(), nullable=True)
|
||||
)
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column("adminunit", "description")
|
||||
op.drop_table("adminunitverificationrequest")
|
||||
# ### end Alembic commands ###
|
||||
@ -290,7 +290,7 @@ from project.views import (
|
||||
root,
|
||||
)
|
||||
from project.views import user as user_view
|
||||
from project.views import widget
|
||||
from project.views import verification_request, verification_request_review, widget
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
app.run()
|
||||
|
||||
@ -37,6 +37,7 @@ class OrganizationBaseSchema(OrganizationIdSchema):
|
||||
email = marshmallow.auto_field()
|
||||
phone = marshmallow.auto_field()
|
||||
fax = marshmallow.auto_field()
|
||||
description = marshmallow.auto_field()
|
||||
is_verified = fields.Boolean()
|
||||
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ from project.init_data import create_initial_data
|
||||
from project.models import (
|
||||
AdminUnit,
|
||||
AdminUnitInvitation,
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
Event,
|
||||
EventAttendanceMode,
|
||||
EventDateDefinition,
|
||||
@ -152,6 +154,7 @@ def _create_admin_unit(user_id, name, verified=False):
|
||||
admin_unit.name = name
|
||||
admin_unit.short_name = name.lower().replace(" ", "")
|
||||
admin_unit.incoming_reference_requests_allowed = True
|
||||
admin_unit.incoming_verification_requests_allowed = True
|
||||
admin_unit.suggestions_enabled = True
|
||||
admin_unit.can_create_other = True
|
||||
admin_unit.can_verify_other = True
|
||||
@ -171,9 +174,10 @@ def _create_admin_unit(user_id, name, verified=False):
|
||||
@test_cli.command("admin-unit-create")
|
||||
@click.argument("user_email")
|
||||
@click.argument("name", default="Meine Crew")
|
||||
def create_admin_unit(user_email, name):
|
||||
@click.option("--verified/--no-verified", default=True)
|
||||
def create_admin_unit(user_email, name, verified):
|
||||
user = find_user_by_email(user_email)
|
||||
admin_unit_id = _create_admin_unit(user.id, name, verified=True)
|
||||
admin_unit_id = _create_admin_unit(user.id, name, verified=verified)
|
||||
result = {"admin_unit_id": admin_unit_id}
|
||||
click.echo(json.dumps(result))
|
||||
|
||||
@ -325,6 +329,48 @@ def create_incoming_reference_request(admin_unit_id):
|
||||
click.echo(json.dumps(result))
|
||||
|
||||
|
||||
def _create_admin_unit_verification_request(source_admin_unit_id, target_admin_unit_id):
|
||||
target_admin_unit = get_admin_unit_by_id(target_admin_unit_id)
|
||||
target_admin_unit.can_verify_other = True
|
||||
target_admin_unit.incoming_verification_requests_allowed = True
|
||||
|
||||
request = AdminUnitVerificationRequest()
|
||||
request.source_admin_unit_id = source_admin_unit_id
|
||||
request.target_admin_unit_id = target_admin_unit_id
|
||||
request.review_status = AdminUnitVerificationRequestReviewStatus.inbox
|
||||
db.session.add(request)
|
||||
db.session.commit()
|
||||
request_id = request.id
|
||||
return request_id
|
||||
|
||||
|
||||
def _create_incoming_admin_unit_verification_request(admin_unit_id):
|
||||
other_user_id = _create_user("other@test.de")
|
||||
other_admin_unit_id = _create_admin_unit(
|
||||
other_user_id, "Other Crew", verified=False
|
||||
)
|
||||
request_id = _create_admin_unit_verification_request(
|
||||
other_admin_unit_id, admin_unit_id
|
||||
)
|
||||
return (other_user_id, other_admin_unit_id, request_id)
|
||||
|
||||
|
||||
@test_cli.command("verification-request-create-incoming")
|
||||
@click.argument("admin_unit_id")
|
||||
def create_incoming_admin_unit_verification_request(admin_unit_id):
|
||||
(
|
||||
other_user_id,
|
||||
other_admin_unit_id,
|
||||
verification_request_id,
|
||||
) = _create_incoming_admin_unit_verification_request(admin_unit_id)
|
||||
result = {
|
||||
"other_user_id": other_user_id,
|
||||
"other_admin_unit_id": other_admin_unit_id,
|
||||
"verification_request_id": verification_request_id,
|
||||
}
|
||||
click.echo(json.dumps(result))
|
||||
|
||||
|
||||
def _create_reference(event_id, admin_unit_id):
|
||||
reference = EventReference()
|
||||
reference.event_id = event_id
|
||||
|
||||
@ -31,10 +31,12 @@ class AdminUnitLocationForm(FlaskForm):
|
||||
|
||||
class BaseAdminUnitForm(FlaskForm):
|
||||
name = HTML5StringField(
|
||||
lazy_gettext("Name"), validators=[DataRequired(), Length(min=5, max=255)]
|
||||
lazy_gettext("Name of organization"),
|
||||
description=lazy_gettext("The full name of the organization"),
|
||||
validators=[DataRequired(), Length(min=5, max=255)],
|
||||
)
|
||||
short_name = HTML5StringField(
|
||||
lazy_gettext("Short name"),
|
||||
lazy_gettext("Short name for organization"),
|
||||
description=lazy_gettext(
|
||||
"The short name is used to create a unique identifier for your events"
|
||||
),
|
||||
@ -49,6 +51,11 @@ class BaseAdminUnitForm(FlaskForm):
|
||||
),
|
||||
],
|
||||
)
|
||||
description = TextAreaField(
|
||||
lazy_gettext("Description"),
|
||||
description=lazy_gettext("Describe the organization in a few words"),
|
||||
validators=[Optional()],
|
||||
)
|
||||
url = URLField(lazy_gettext("Link URL"), validators=[Optional(), Length(max=255)])
|
||||
email = EmailField(lazy_gettext("Email"), validators=[Optional(), Length(max=255)])
|
||||
phone = TelField(lazy_gettext("Phone"), validators=[Optional(), Length(max=255)])
|
||||
|
||||
90
project/forms/verification_request.py
Normal file
90
project/forms/verification_request.py
Normal file
@ -0,0 +1,90 @@
|
||||
from flask_babel import lazy_gettext
|
||||
from flask_wtf import FlaskForm
|
||||
from wtforms import SelectField, StringField, SubmitField
|
||||
from wtforms.fields import BooleanField
|
||||
from wtforms.validators import DataRequired, Optional
|
||||
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequestRejectionReason,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
|
||||
|
||||
class CreateAdminUnitVerificationRequestForm(FlaskForm):
|
||||
submit = SubmitField(lazy_gettext("Request verification"))
|
||||
|
||||
|
||||
class DeleteVerificationRequestForm(FlaskForm):
|
||||
submit = SubmitField(lazy_gettext("Delete request"))
|
||||
name = StringField(lazy_gettext("Name"), validators=[DataRequired()])
|
||||
|
||||
|
||||
class VerificationRequestReviewForm(FlaskForm):
|
||||
review_status = SelectField(
|
||||
lazy_gettext("Review status"),
|
||||
coerce=int,
|
||||
choices=[
|
||||
(
|
||||
int(AdminUnitVerificationRequestReviewStatus.inbox),
|
||||
lazy_gettext("AdminUnitVerificationRequestReviewStatus.inbox"),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestReviewStatus.verified),
|
||||
lazy_gettext("AdminUnitVerificationRequestReviewStatus.verified"),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestReviewStatus.rejected),
|
||||
lazy_gettext("AdminUnitVerificationRequestReviewStatus.rejected"),
|
||||
),
|
||||
],
|
||||
description=lazy_gettext("Choose the result of your review."),
|
||||
)
|
||||
|
||||
rejection_reason = SelectField(
|
||||
lazy_gettext("Rejection reason"),
|
||||
coerce=int,
|
||||
choices=[
|
||||
(
|
||||
0,
|
||||
lazy_gettext("AdminUnitVerificationRequestRejectionReason.noreason"),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestRejectionReason.notresponsible),
|
||||
lazy_gettext(
|
||||
"AdminUnitVerificationRequestRejectionReason.notresponsible"
|
||||
),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestRejectionReason.missinginformation),
|
||||
lazy_gettext(
|
||||
"AdminUnitVerificationRequestRejectionReason.missinginformation"
|
||||
),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestRejectionReason.unknown),
|
||||
lazy_gettext("AdminUnitVerificationRequestRejectionReason.unknown"),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestRejectionReason.untrustworthy),
|
||||
lazy_gettext(
|
||||
"AdminUnitVerificationRequestRejectionReason.untrustworthy"
|
||||
),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestRejectionReason.illegal),
|
||||
lazy_gettext("AdminUnitVerificationRequestRejectionReason.illegal"),
|
||||
),
|
||||
(
|
||||
int(AdminUnitVerificationRequestRejectionReason.irrelevant),
|
||||
lazy_gettext("AdminUnitVerificationRequestRejectionReason.irrelevant"),
|
||||
),
|
||||
],
|
||||
description=lazy_gettext("Choose why you rejected the request."),
|
||||
)
|
||||
|
||||
auto_verify = BooleanField(
|
||||
lazy_gettext("Verify reference requests automatically"),
|
||||
validators=[Optional()],
|
||||
)
|
||||
|
||||
submit = SubmitField(lazy_gettext("Save review"))
|
||||
@ -23,6 +23,11 @@ def create_initial_data():
|
||||
"admin_unit.members:read",
|
||||
"admin_unit.members:update",
|
||||
"admin_unit.members:delete",
|
||||
"verification_request:create",
|
||||
"verification_request:read",
|
||||
"verification_request:update",
|
||||
"verification_request:delete",
|
||||
"verification_request:verify",
|
||||
]
|
||||
event_permissions = [
|
||||
"event:verify",
|
||||
|
||||
@ -83,11 +83,17 @@ def get_context_processors():
|
||||
from project.services.reference import (
|
||||
get_reference_requests_incoming_badge_query,
|
||||
)
|
||||
from project.services.verification import (
|
||||
get_verification_requests_incoming_badge_query,
|
||||
)
|
||||
|
||||
reviews_badge = 0
|
||||
reference_requests_incoming_badge = get_reference_requests_incoming_badge_query(
|
||||
admin_unit
|
||||
).count()
|
||||
verification_requests_incoming_badge = (
|
||||
get_verification_requests_incoming_badge_query(admin_unit).count()
|
||||
)
|
||||
|
||||
if has_access(admin_unit, "event:verify"):
|
||||
reviews_badge = get_event_reviews_badge_query(admin_unit).count()
|
||||
@ -95,6 +101,7 @@ def get_context_processors():
|
||||
return {
|
||||
"reviews_badge": reviews_badge,
|
||||
"reference_requests_incoming_badge": reference_requests_incoming_badge,
|
||||
"verification_requests_incoming_badge": verification_requests_incoming_badge,
|
||||
}
|
||||
|
||||
def has_tos():
|
||||
|
||||
@ -6,6 +6,11 @@ from project.models.admin_unit import (
|
||||
AdminUnitMemberRole,
|
||||
AdminUnitRelation,
|
||||
)
|
||||
from project.models.admin_unit_verification_request import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestRejectionReason,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
from project.models.custom_widget import CustomWidget
|
||||
from project.models.event import Event, EventStatus, PublicStatus
|
||||
from project.models.event_category import EventCategory
|
||||
|
||||
@ -22,6 +22,7 @@ from sqlalchemy.schema import CheckConstraint
|
||||
from sqlalchemy_utils import ColorType
|
||||
|
||||
from project import db
|
||||
from project.models.admin_unit_verification_request import AdminUnitVerificationRequest
|
||||
from project.models.trackable_mixin import TrackableMixin
|
||||
from project.utils import make_check_violation
|
||||
|
||||
@ -239,6 +240,7 @@ class AdminUnit(db.Model, TrackableMixin):
|
||||
email = deferred(Column(Unicode(255)), group="detail")
|
||||
phone = deferred(Column(Unicode(255)), group="detail")
|
||||
fax = deferred(Column(Unicode(255)), group="detail")
|
||||
description = deferred(Column(UnicodeText(), nullable=True), group="detail")
|
||||
widget_font = deferred(Column(Unicode(255)), group="widget")
|
||||
widget_background_color = deferred(Column(ColorType), group="widget")
|
||||
widget_primary_color = deferred(Column(ColorType), group="widget")
|
||||
@ -306,6 +308,27 @@ class AdminUnit(db.Model, TrackableMixin):
|
||||
lazy=True,
|
||||
),
|
||||
)
|
||||
outgoing_verification_requests = relationship(
|
||||
"AdminUnitVerificationRequest",
|
||||
primaryjoin=remote(AdminUnitVerificationRequest.source_admin_unit_id) == id,
|
||||
single_parent=True,
|
||||
cascade="all, delete-orphan",
|
||||
passive_deletes=True,
|
||||
backref=backref(
|
||||
"source_admin_unit",
|
||||
lazy=True,
|
||||
),
|
||||
)
|
||||
incoming_verification_requests = relationship(
|
||||
"AdminUnitVerificationRequest",
|
||||
primaryjoin=remote(AdminUnitVerificationRequest.target_admin_unit_id) == id,
|
||||
cascade="all, delete-orphan",
|
||||
passive_deletes=True,
|
||||
backref=backref(
|
||||
"target_admin_unit",
|
||||
lazy=True,
|
||||
),
|
||||
)
|
||||
|
||||
@hybrid_property
|
||||
def is_verified(self):
|
||||
|
||||
69
project/models/admin_unit_verification_request.py
Normal file
69
project/models/admin_unit_verification_request.py
Normal file
@ -0,0 +1,69 @@
|
||||
from enum import IntEnum
|
||||
|
||||
from sqlalchemy import CheckConstraint, Column, Integer, UniqueConstraint
|
||||
from sqlalchemy.event import listens_for
|
||||
from sqlalchemy.ext.hybrid import hybrid_property
|
||||
|
||||
from project import db
|
||||
from project.dbtypes import IntegerEnum
|
||||
from project.models.trackable_mixin import TrackableMixin
|
||||
from project.utils import make_check_violation
|
||||
|
||||
|
||||
class AdminUnitVerificationRequestReviewStatus(IntEnum):
|
||||
inbox = 1
|
||||
verified = 2
|
||||
rejected = 3
|
||||
|
||||
|
||||
class AdminUnitVerificationRequestRejectionReason(IntEnum):
|
||||
notresponsible = 1
|
||||
missinginformation = 2
|
||||
unknown = 3
|
||||
untrustworthy = 4
|
||||
illegal = 5
|
||||
irrelevant = 6
|
||||
|
||||
|
||||
class AdminUnitVerificationRequest(db.Model, TrackableMixin):
|
||||
__tablename__ = "adminunitverificationrequest"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("source_admin_unit_id", "target_admin_unit_id"),
|
||||
CheckConstraint(
|
||||
"source_admin_unit_id != target_admin_unit_id",
|
||||
name="auvr_source_neq_target",
|
||||
),
|
||||
)
|
||||
id = Column(Integer(), primary_key=True)
|
||||
source_admin_unit_id = db.Column(
|
||||
db.Integer, db.ForeignKey("adminunit.id", ondelete="CASCADE"), nullable=False
|
||||
)
|
||||
target_admin_unit_id = db.Column(
|
||||
db.Integer, db.ForeignKey("adminunit.id", ondelete="CASCADE"), nullable=False
|
||||
)
|
||||
review_status = Column(IntegerEnum(AdminUnitVerificationRequestReviewStatus))
|
||||
rejection_reason = Column(IntegerEnum(AdminUnitVerificationRequestRejectionReason))
|
||||
|
||||
@hybrid_property
|
||||
def verified(self):
|
||||
return self.review_status == AdminUnitVerificationRequestReviewStatus.verified
|
||||
|
||||
def validate(self):
|
||||
source_id = (
|
||||
self.source_admin_unit.id
|
||||
if self.source_admin_unit
|
||||
else self.source_admin_unit_id
|
||||
)
|
||||
target_id = (
|
||||
self.target_admin_unit.id
|
||||
if self.target_admin_unit
|
||||
else self.target_admin_unit_id
|
||||
)
|
||||
if source_id == target_id: # pragma: no cover
|
||||
raise make_check_violation("There must be no self-reference.")
|
||||
|
||||
|
||||
@listens_for(AdminUnitVerificationRequest, "before_insert")
|
||||
@listens_for(AdminUnitVerificationRequest, "before_update")
|
||||
def before_saving_admin_unit_verification_request(mapper, connect, self):
|
||||
self.validate()
|
||||
29
project/services/verification.py
Normal file
29
project/services/verification.py
Normal file
@ -0,0 +1,29 @@
|
||||
from sqlalchemy import and_
|
||||
from sqlalchemy.orm import load_only
|
||||
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
|
||||
|
||||
def get_verification_requests_incoming_query(admin_unit):
|
||||
return AdminUnitVerificationRequest.query.filter(
|
||||
and_(
|
||||
AdminUnitVerificationRequest.review_status
|
||||
!= AdminUnitVerificationRequestReviewStatus.verified,
|
||||
AdminUnitVerificationRequest.target_admin_unit_id == admin_unit.id,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def get_verification_requests_incoming_badge_query(admin_unit):
|
||||
return AdminUnitVerificationRequest.query.options(
|
||||
load_only(AdminUnitVerificationRequest.id)
|
||||
).filter(
|
||||
and_(
|
||||
AdminUnitVerificationRequest.review_status
|
||||
== AdminUnitVerificationRequestReviewStatus.inbox,
|
||||
AdminUnitVerificationRequest.target_admin_unit_id == admin_unit.id,
|
||||
)
|
||||
)
|
||||
@ -39,6 +39,10 @@ const OrganizationRead = {
|
||||
{{ organization.location.postalCode }} {{ organization.location.city }}
|
||||
</div>
|
||||
|
||||
<div v-if="organization.description" class="mt-3">
|
||||
<span style="white-space: pre;">{{ organization.description }}</span>
|
||||
</div>
|
||||
|
||||
<b-list-group class="mt-4">
|
||||
<b-list-group-item :href="'/eventdates?admin_unit_id=' + organization.id">
|
||||
<i class="fa fa-fw fa-list"></i>
|
||||
|
||||
@ -177,6 +177,15 @@
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_text_prop(prop, icon = None, label_key = None) %}
|
||||
{% if prop %}
|
||||
<div>
|
||||
{% if icon %}<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>{% endif %}
|
||||
<span style="white-space:pre-wrap;">{{ prop }}</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_int_prop(prop, icon = None, label_key = None) %}
|
||||
{% if prop %}
|
||||
<div>
|
||||
@ -280,6 +289,12 @@
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_verification_request_review_status_pill(reference_request) %}
|
||||
{% if reference_request.review_status %}
|
||||
<span class="badge badge-pill {% if reference_request.review_status == 1 %}badge-info{% elif reference_request.review_status == 2 %}badge-success{% else %}badge-danger{% endif %}">{{ reference_request.review_status | loc_enum }}</span>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_admin_unit_badges(admin_unit) %}
|
||||
{% if admin_unit.is_verified %}<i class="fa fa-check-circle text-primary" data-toggle="tooltip" title="{{ _('Verified') }}"></i>{% endif %}
|
||||
{% endmacro %}
|
||||
@ -340,6 +355,11 @@
|
||||
{{ render_enum_prop(reference_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_verification_request_review_status(verification_request) %}
|
||||
{{ render_enum_prop(verification_request.review_status, 'fa-certificate', 'Review status') }}
|
||||
{{ render_enum_prop(verification_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_audit(tracking_mixing, show_user=False) %}
|
||||
{% set created_at = tracking_mixing.created_at | datetimeformat('short') %}
|
||||
{% set updated_at = tracking_mixing.updated_at | datetimeformat('short') %}
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
<div class="card-body">
|
||||
{{ render_field_with_errors(form.name) }}
|
||||
{{ render_field_with_errors(form.short_name) }}
|
||||
{{ render_field_with_errors(form.description) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
<div class="card-body">
|
||||
{{ render_field_with_errors(form.name) }}
|
||||
{{ render_field_with_errors(form.short_name) }}
|
||||
{{ render_field_with_errors(form.description) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
6
project/templates/email/verification_request_notice.html
Normal file
6
project/templates/email/verification_request_notice.html
Normal file
@ -0,0 +1,6 @@
|
||||
{% extends "email/layout.html" %}
|
||||
{% from "_macros.html" import render_email_button %}
|
||||
{% block content %}
|
||||
<p>{{ _('There is a new verification request that needs to be reviewed.') }}</p>
|
||||
{{ render_email_button(url_for('admin_unit_verification_request_review', id=request.id, _external=True), _('Click here to review the request')) }}
|
||||
{% endblock %}
|
||||
3
project/templates/email/verification_request_notice.txt
Normal file
3
project/templates/email/verification_request_notice.txt
Normal file
@ -0,0 +1,3 @@
|
||||
{{ _('There is a new verification request that needs to be reviewed.') }}
|
||||
{{ _('Click the link below to review the request') }}
|
||||
{{ url_for('admin_unit_verification_request_review', id=request.id, _external=True) }}
|
||||
@ -0,0 +1,6 @@
|
||||
{% extends "email/layout.html" %}
|
||||
{% from "_macros.html" import render_email_button %}
|
||||
{% block content %}
|
||||
<p>{{ _('The review status of your verification request has been updated.') }}</p>
|
||||
{{ render_email_button(url_for('admin_unit_verification_request_review_status', id=request.id, _external=True), _('Click here to view the status')) }}
|
||||
{% endblock %}
|
||||
@ -0,0 +1,3 @@
|
||||
{{ _('The review status of your verification request has been updated.') }}
|
||||
{{ _('Click the link below to view the status') }}
|
||||
{{ url_for('admin_unit_verification_request_review_status', id=request.id, _external=True) }}
|
||||
@ -1,5 +1,5 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_radio_buttons, render_phone_prop, render_email_prop, render_string_prop, render_field_with_errors, render_field, render_event_props, render_image_with_link, render_place, render_link_prop %}
|
||||
{% from "_macros.html" import render_field_with_errors, render_field %}
|
||||
{%- block title -%}
|
||||
{{ event.name }}
|
||||
{%- endblock -%}
|
||||
|
||||
@ -255,16 +255,35 @@
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle text-truncate" href="#" id="navbarAdminUnitOrganizationDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
{{ _('Organization') }}
|
||||
{% if menu_options['verification_requests_incoming_badge'] > 0 %}
|
||||
<span class="badge badge-secondary badge-pill">{{ menu_options['verification_requests_incoming_badge'] }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarAdminUnitOrganizationDropdown">
|
||||
{% if not current_admin_unit.is_verified %}
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_verification_requests_outgoing', id=current_admin_unit.id) }}">{{ _('Outgoing verification requests') }}</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
{% endif %}
|
||||
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_organizers', id=current_admin_unit.id) }}">{{ _('Organizers') }}</a>
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_event_places', id=current_admin_unit.id) }}">{{ _('Places') }}</a>
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_members', id=current_admin_unit.id) }}">{{ _('Members') }}</a>
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_relations', id=current_admin_unit.id) }}">{{ _('Relations') }}</a>
|
||||
|
||||
{% if current_admin_unit.can_verify_other %}
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_verification_requests_incoming', id=current_admin_unit.id) }}">{{ _('Incoming verification requests') }}
|
||||
{% if menu_options['verification_requests_incoming_badge'] > 0 %}
|
||||
<span class="badge badge-secondary badge-pill">{{ menu_options['verification_requests_incoming_badge'] }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
{% if current_admin_unit.can_invite_other %}
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_organization_invitations', id=current_admin_unit.id) }}">{{ _('Organization invitations') }}</a>
|
||||
{% endif %}
|
||||
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="{{ url_for('admin_unit_update', id=current_admin_unit.id) }}">{{ _('Settings') }}</a>
|
||||
<a class="dropdown-item" href="{{ url_for('manage_admin_unit_export', id=current_admin_unit.id) }}">{{ _('Export') }}</a>
|
||||
|
||||
28
project/templates/manage/verification_requests_incoming.html
Normal file
28
project/templates/manage/verification_requests_incoming.html
Normal file
@ -0,0 +1,28 @@
|
||||
{% extends "layout.html" %}
|
||||
{% set active_id = "verification_requests_incoming" %}
|
||||
{% from "_macros.html" import render_verification_request_review_status_pill, render_pagination %}
|
||||
{%- block title -%}
|
||||
{{ _('Incoming verification requests') }}
|
||||
{%- endblock -%}
|
||||
{% block content %}
|
||||
|
||||
<h1 class="mb-1">{{ _('Incoming verification requests') }}</h1>
|
||||
|
||||
<ul class="list-group mt-4">
|
||||
{% for request in requests %}
|
||||
<li class="list-group-item">
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-link dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ request.source_admin_unit.name }}</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{{ url_for('admin_unit_verification_request_review_status', id=request.id) }}">{{ _('Show review status') }}</a>
|
||||
<a class="dropdown-item" href="{{ url_for('admin_unit_verification_request_review', id=request.id) }}">{{ _('Review request') }}…</a>
|
||||
</div>
|
||||
</div>
|
||||
{{ render_verification_request_review_status_pill(request) }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div class="my-4">{{ render_pagination(pagination) }}</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -1,45 +1,33 @@
|
||||
{% extends "layout.html" %}
|
||||
{% set active_id = "verification_requests_outgoing" %}
|
||||
{% from "_macros.html" import render_logo, render_location_prop, render_fax_prop, render_phone_prop, render_email_prop,
|
||||
render_link_prop, render_admin_unit_badges, render_pagination %}
|
||||
{% from "_macros.html" import render_verification_request_review_status_pill, render_pagination %}
|
||||
{%- block title -%}
|
||||
{{ _('Verification requests') }}
|
||||
{{ _('Outgoing verification requests') }}
|
||||
{%- endblock -%}
|
||||
{% block content %}
|
||||
|
||||
<h1 class="mb-1">
|
||||
{{ _('Verification requests') }}
|
||||
{{ _('Outgoing verification requests') }}
|
||||
<a class="btn btn-outline-secondary btn-sm m-1" href="{{ url_for('manage_admin_unit_verification_requests_outgoing_create_select', id=admin_unit.id) }}" role="button"><i class="fa fa-plus"></i> {{ _('Request verification') }}</a>
|
||||
{% if config["DOCS_URL"] %}
|
||||
<a class="btn btn-outline-info btn-sm m-1 my-auto float-right" href="{{ config["DOCS_URL"] }}/goto/organization-verify" target="_blank" rel="noopener noreferrer" role="button"><i class="fa fa-fw fa-info-circle"></i> {{ _('Docs') }}</a>
|
||||
{% endif %}
|
||||
</h1>
|
||||
<p class="text-muted">{{ _('Here you can find organizations that can verify other organizations.') }}</p>
|
||||
|
||||
{% for other_admin_unit in admin_units %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-body p-3">
|
||||
<h2 class="mt-0">
|
||||
<a href="{{ url_for('organizations', path=other_admin_unit.id) }}" class="text-body">{{
|
||||
other_admin_unit.name }}</a>
|
||||
{{ render_admin_unit_badges(other_admin_unit) }}
|
||||
</h2>
|
||||
<p>{{ other_admin_unit.incoming_verification_requests_text }}</p>
|
||||
<div class="row">
|
||||
{% if other_admin_unit.logo_id %}
|
||||
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(other_admin_unit.logo) }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col-12 col-sm">
|
||||
{{ render_link_prop(other_admin_unit.url) }}
|
||||
{{ render_email_prop(other_admin_unit.email) }}
|
||||
{{ render_phone_prop(other_admin_unit.phone) }}
|
||||
{{ render_fax_prop(other_admin_unit.fax) }}
|
||||
{{ render_location_prop(other_admin_unit.location) }}
|
||||
<ul class="list-group mt-4">
|
||||
{% for request in requests %}
|
||||
<li class="list-group-item">
|
||||
<div class="dropdown d-inline-block">
|
||||
<button class="btn btn-link dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{{ request.target_admin_unit.name }}</button>
|
||||
<div class="dropdown-menu">
|
||||
<a class="dropdown-item" href="{{ url_for('admin_unit_verification_request_review_status', id=request.id) }}">{{ _('Show review status') }}</a>
|
||||
<a class="dropdown-item" href="{{ url_for('admin_unit_verification_request_delete', id=request.id) }}">{{ _('Delete request') }}…</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{{ render_verification_request_review_status_pill(request) }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<div class="my-4">{{ render_pagination(pagination) }}</div>
|
||||
|
||||
|
||||
@ -0,0 +1,42 @@
|
||||
{% extends "layout.html" %}
|
||||
{% set active_id = "verification_requests_outgoing" %}
|
||||
{% from "_macros.html" import render_admin_unit_badges, render_logo, render_location_prop, render_text_prop, render_field_with_errors, render_field %}
|
||||
{%- block title -%}
|
||||
{{ _('Request verification for organization "%(name)s"', name=admin_unit.name) }}
|
||||
{%- endblock -%}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ _('Request verification for organization "%(name)s"', name=admin_unit.name) }}</h1>
|
||||
|
||||
<div class="w-normal">
|
||||
<p>{{ _('Ask "%(name)s" to verify your organization.', name=target_admin_unit.name) }}</p>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-body p-3">
|
||||
<h2 class="mt-0">
|
||||
<a href="{{ url_for('organizations', path=target_admin_unit.id) }}" class="text-body">{{
|
||||
target_admin_unit.name }}</a>
|
||||
{{ render_admin_unit_badges(target_admin_unit) }}
|
||||
</h2>
|
||||
<div class="row">
|
||||
{% if target_admin_unit.logo_id %}
|
||||
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(target_admin_unit.logo) }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col-12 col-sm">
|
||||
{{ render_location_prop(target_admin_unit.location) }}
|
||||
<p>{{ render_text_prop(target_admin_unit.description) }}</p>
|
||||
<p>{{ render_text_prop(target_admin_unit.incoming_verification_requests_text) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<form action="" method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
{{ render_field(form.submit) }}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
@ -0,0 +1,47 @@
|
||||
{% extends "layout.html" %}
|
||||
{% set active_id = "verification_requests_outgoing" %}
|
||||
{% from "_macros.html" import render_text_prop, render_logo, render_location_prop, render_fax_prop, render_phone_prop, render_email_prop,
|
||||
render_link_prop, render_admin_unit_badges, render_pagination %}
|
||||
{%- block title -%}
|
||||
{{ _('Verification requests') }}
|
||||
{%- endblock -%}
|
||||
{% block content %}
|
||||
|
||||
<h1 class="mb-1">
|
||||
{{ _('Verification requests') }}
|
||||
{% if config["DOCS_URL"] %}
|
||||
<a class="btn btn-outline-info btn-sm m-1 my-auto float-right" href="{{ config["DOCS_URL"] }}/goto/organization-verify" target="_blank" rel="noopener noreferrer" role="button"><i class="fa fa-fw fa-info-circle"></i> {{ _('Docs') }}</a>
|
||||
{% endif %}
|
||||
</h1>
|
||||
|
||||
<div class="w-normal">
|
||||
<p class="text-muted">{{ _('Here you can find organizations that can verify other organizations.') }}</p>
|
||||
|
||||
{% for other_admin_unit in admin_units %}
|
||||
<div class="card mb-3">
|
||||
<div class="card-body p-3">
|
||||
<h2 class="mt-0">
|
||||
<a href="{{ url_for('organizations', path=other_admin_unit.id) }}" class="text-body">{{
|
||||
other_admin_unit.name }}</a>
|
||||
{{ render_admin_unit_badges(other_admin_unit) }}
|
||||
</h2>
|
||||
<div class="row">
|
||||
{% if other_admin_unit.logo_id %}
|
||||
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(other_admin_unit.logo) }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="col-12 col-sm">
|
||||
{{ render_location_prop(other_admin_unit.location) }}
|
||||
<p>{{ render_text_prop(other_admin_unit.description) }}</p>
|
||||
<p>{{ render_text_prop(other_admin_unit.incoming_verification_requests_text) }}</p>
|
||||
<a class="btn btn-primary btn-sm" href="{{ url_for('manage_admin_unit_verification_requests_outgoing_create', id=admin_unit.id, target_id=other_admin_unit.id) }}" role="button"><i class="fa fa-plus"></i> {{ _('Request verification') }}…</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="my-4">{{ render_pagination(pagination) }}</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
24
project/templates/verification_request/delete.html
Normal file
24
project/templates/verification_request/delete.html
Normal file
@ -0,0 +1,24 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_field_with_errors, render_field %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ _('Delete verification request') }} "{{ verification_request.target_admin_unit.name }}"</h1>
|
||||
|
||||
<form action="" method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
|
||||
<div class="card mb-4">
|
||||
<div class="card-header">
|
||||
{{ _('Organization') }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ render_field_with_errors(form.name) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ render_field(form.submit) }}
|
||||
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
||||
124
project/templates/verification_request/review.html
Normal file
124
project/templates/verification_request/review.html
Normal file
@ -0,0 +1,124 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_roles, render_text_prop, render_location_prop, render_admin_unit_badges, render_fax_prop, render_logo, render_jquery_steps_header, render_phone_prop, render_email_prop, render_string_prop, render_field_with_errors, render_field, render_image_with_link, render_place, render_link_prop %}
|
||||
{%- block title -%}
|
||||
{{ request.source_admin_unit.name }}
|
||||
{%- endblock -%}
|
||||
{% block header_before_site_js %}
|
||||
{{ render_jquery_steps_header() }}
|
||||
<script>
|
||||
$( function() {
|
||||
|
||||
$('#acceptFormModal .btn-success').click(function() {
|
||||
$('#acceptFormModal form').submit();
|
||||
});
|
||||
|
||||
$('#rejectFormModal .btn-danger').click(function() {
|
||||
$('#rejectFormModal form').submit();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ _('Review verification request') }}</h1>
|
||||
|
||||
<div class="mt-3 w-normal">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
{{ _('Organization') }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ request.source_admin_unit.name }}{{ render_admin_unit_badges(request.source_admin_unit) }}</h5>
|
||||
|
||||
{% if request.source_admin_unit.logo_id %}
|
||||
<div class="my-4">{{ render_logo(request.source_admin_unit.logo) }}</div>
|
||||
{% endif %}
|
||||
|
||||
<div class="my-4">
|
||||
{{ render_link_prop(request.source_admin_unit.url) }}
|
||||
{{ render_email_prop(request.source_admin_unit.email) }}
|
||||
{{ render_phone_prop(request.source_admin_unit.phone) }}
|
||||
{{ render_fax_prop(request.source_admin_unit.fax) }}
|
||||
{{ render_location_prop(request.source_admin_unit.location) }}
|
||||
{% if request.source_admin_unit.description %}
|
||||
<div class="my-2">
|
||||
{{ render_text_prop(request.source_admin_unit.description) }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
{{ _('Members') }}
|
||||
</div>
|
||||
<ul class="list-group list-group-flush">
|
||||
{% for member in request.source_admin_unit.members %}
|
||||
<li class="list-group-item">
|
||||
<span>{{ member.user.email }}</span>
|
||||
<small class="text-secondary">{{ render_roles(member.roles)}}</small>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between my-4 decision-container">
|
||||
<button type="button" class="btn btn-success m-1" data-toggle="modal" data-target="#acceptFormModal"><i class="fa fa-check"></i> {{ _('Accept verification request') }}…</button>
|
||||
<button type="button" class="btn btn-danger m-1" data-toggle="modal" data-target="#rejectFormModal"><i class="fa fa-ban"></i> {{ _('Reject verification request') }}…</button>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="acceptFormModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">{{ _('Accept verification request') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="" method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
<input type="hidden" name="{{ form.review_status.name }}" value="2" />
|
||||
<input type="hidden" name="{{ form.rejection_reason.name }}" value="0" />
|
||||
|
||||
{{ render_field_with_errors(form.auto_verify, ri="switch") }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ _('Cancel') }}</button>
|
||||
<button type="button" class="btn btn-success">{{ _('Accept verification request') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="modal fade" id="rejectFormModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">{{ _('Reject verification request') }}</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form action="" method="POST">
|
||||
{{ form.hidden_tag() }}
|
||||
<input type="hidden" name="{{ form.review_status.name }}" value="3" />
|
||||
|
||||
{{ render_field_with_errors(form.rejection_reason) }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ _('Cancel') }}</button>
|
||||
<button type="button" class="btn btn-danger">{{ _('Reject verification request') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
19
project/templates/verification_request/review_status.html
Normal file
19
project/templates/verification_request/review_status.html
Normal file
@ -0,0 +1,19 @@
|
||||
{% extends "layout.html" %}
|
||||
{% from "_macros.html" import render_verification_request_review_status %}
|
||||
{%- block title -%}
|
||||
{{ _('Review status') }}
|
||||
{%- endblock -%}
|
||||
{% block content %}
|
||||
|
||||
<h1>{{ verification_request.source_admin_unit.name }} - {{ verification_request.target_admin_unit.name }}</h1>
|
||||
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
{{ _('Review status') }}
|
||||
</div>
|
||||
<div class="card-body">
|
||||
{{ render_verification_request_review_status(verification_request) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -40,7 +40,6 @@ from project.models import (
|
||||
from project.services.admin_unit import (
|
||||
get_admin_unit_member_invitations,
|
||||
get_admin_unit_organization_invitations,
|
||||
get_admin_unit_query,
|
||||
get_member_for_admin_unit_by_user_id,
|
||||
)
|
||||
from project.services.event import get_events_query
|
||||
@ -492,17 +491,3 @@ def manage_admin_unit_widgets(id):
|
||||
flash_errors(form)
|
||||
|
||||
return render_template("manage/widgets.html", form=form, admin_unit=admin_unit)
|
||||
|
||||
|
||||
@app.route("/manage/admin_unit/<int:id>/verification_requests/outgoing")
|
||||
@auth_required()
|
||||
def manage_admin_unit_verification_requests_outgoing(id):
|
||||
admin_unit = get_admin_unit_for_manage_or_404(id)
|
||||
admin_units = get_admin_unit_query(only_verifier=True).paginate()
|
||||
|
||||
return render_template(
|
||||
"manage/verification_requests_outgoing.html",
|
||||
admin_unit=admin_unit,
|
||||
admin_units=admin_units.items,
|
||||
pagination=get_pagination_urls(admin_units, id=id),
|
||||
)
|
||||
|
||||
204
project/views/verification_request.py
Normal file
204
project/views/verification_request.py
Normal file
@ -0,0 +1,204 @@
|
||||
from flask import flash, g, redirect, render_template, url_for
|
||||
from flask_babel import gettext
|
||||
from flask_security import auth_required
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from project import app, db
|
||||
from project.access import access_or_401, get_admin_unit_members_with_permission
|
||||
from project.forms.verification_request import (
|
||||
CreateAdminUnitVerificationRequestForm,
|
||||
DeleteVerificationRequestForm,
|
||||
)
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
from project.models.admin_unit import AdminUnit
|
||||
from project.services.admin_unit import get_admin_unit_query
|
||||
from project.services.verification import get_verification_requests_incoming_query
|
||||
from project.views.utils import (
|
||||
flash_errors,
|
||||
get_pagination_urls,
|
||||
handleSqlError,
|
||||
manage_required,
|
||||
non_match_for_deletion,
|
||||
send_mails,
|
||||
)
|
||||
|
||||
|
||||
@app.route("/manage/admin_unit/<int:id>/verification_requests/incoming")
|
||||
@auth_required()
|
||||
@manage_required("verification_request:read")
|
||||
def manage_admin_unit_verification_requests_incoming(id):
|
||||
admin_unit = g.manage_admin_unit
|
||||
requests = (
|
||||
get_verification_requests_incoming_query(admin_unit)
|
||||
.order_by(AdminUnitVerificationRequest.created_at.desc())
|
||||
.paginate()
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"manage/verification_requests_incoming.html",
|
||||
admin_unit=admin_unit,
|
||||
requests=requests.items,
|
||||
pagination=get_pagination_urls(requests, id=id),
|
||||
)
|
||||
|
||||
|
||||
@app.route("/manage/admin_unit/<int:id>/verification_requests/outgoing")
|
||||
@auth_required()
|
||||
@manage_required("verification_request:read")
|
||||
def manage_admin_unit_verification_requests_outgoing(id):
|
||||
admin_unit = g.manage_admin_unit
|
||||
requests = (
|
||||
AdminUnitVerificationRequest.query.filter(
|
||||
AdminUnitVerificationRequest.source_admin_unit_id == admin_unit.id
|
||||
)
|
||||
.order_by(AdminUnitVerificationRequest.created_at.desc())
|
||||
.paginate()
|
||||
)
|
||||
|
||||
if not admin_unit.is_verified and requests.total == 0:
|
||||
return redirect(
|
||||
url_for(
|
||||
"manage_admin_unit_verification_requests_outgoing_create_select",
|
||||
id=admin_unit.id,
|
||||
)
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"manage/verification_requests_outgoing.html",
|
||||
admin_unit=admin_unit,
|
||||
requests=requests.items,
|
||||
pagination=get_pagination_urls(requests, id=id),
|
||||
)
|
||||
|
||||
|
||||
@app.route("/manage/admin_unit/<int:id>/verification_requests/outgoing/create/select")
|
||||
@auth_required()
|
||||
@manage_required("verification_request:create")
|
||||
def manage_admin_unit_verification_requests_outgoing_create_select(id):
|
||||
admin_unit = g.manage_admin_unit
|
||||
admin_units = get_admin_unit_query(only_verifier=True).paginate()
|
||||
|
||||
return render_template(
|
||||
"manage/verification_requests_outgoing_create_select.html",
|
||||
admin_unit=admin_unit,
|
||||
admin_units=admin_units.items,
|
||||
pagination=get_pagination_urls(admin_units, id=id),
|
||||
)
|
||||
|
||||
|
||||
@app.route(
|
||||
"/manage/admin_unit/<int:id>/verification_requests/outgoing/create/target/<int:target_id>",
|
||||
methods=("GET", "POST"),
|
||||
)
|
||||
@auth_required()
|
||||
@manage_required("verification_request:create")
|
||||
def manage_admin_unit_verification_requests_outgoing_create(id, target_id):
|
||||
admin_unit = g.manage_admin_unit
|
||||
target_admin_unit = AdminUnit.query.get_or_404(target_id)
|
||||
|
||||
if (
|
||||
target_admin_unit.id == admin_unit.id
|
||||
or not target_admin_unit.can_verify_other
|
||||
or not target_admin_unit.incoming_verification_requests_allowed
|
||||
): # pragma: no cover
|
||||
return redirect(
|
||||
url_for(
|
||||
"manage_admin_unit_verification_requests_outgoing_create_select",
|
||||
id=admin_unit.id,
|
||||
)
|
||||
)
|
||||
|
||||
form = CreateAdminUnitVerificationRequestForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
request = AdminUnitVerificationRequest()
|
||||
form.populate_obj(request)
|
||||
request.source_admin_unit = admin_unit
|
||||
request.target_admin_unit = target_admin_unit
|
||||
|
||||
try:
|
||||
db.session.add(request)
|
||||
|
||||
request.review_status = AdminUnitVerificationRequestReviewStatus.inbox
|
||||
send_verification_request_inbox_mails(request)
|
||||
msg = gettext(
|
||||
"Request successfully created. You will be notified after the other organization reviewed the request."
|
||||
)
|
||||
|
||||
db.session.commit()
|
||||
flash(msg, "success")
|
||||
return redirect(
|
||||
url_for(
|
||||
"manage_admin_unit_verification_requests_outgoing",
|
||||
id=admin_unit.id,
|
||||
)
|
||||
)
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), "danger")
|
||||
else:
|
||||
flash_errors(form)
|
||||
|
||||
return render_template(
|
||||
"manage/verification_requests_outgoing_create.html",
|
||||
form=form,
|
||||
admin_unit=admin_unit,
|
||||
target_admin_unit=target_admin_unit,
|
||||
)
|
||||
|
||||
|
||||
@app.route("/verification_request/<int:id>/delete", methods=("GET", "POST"))
|
||||
@auth_required()
|
||||
def admin_unit_verification_request_delete(id):
|
||||
request = AdminUnitVerificationRequest.query.get_or_404(id)
|
||||
access_or_401(request.source_admin_unit, "verification_request:delete")
|
||||
|
||||
form = DeleteVerificationRequestForm()
|
||||
|
||||
if form.validate_on_submit():
|
||||
if non_match_for_deletion(form.name.data, request.target_admin_unit.name):
|
||||
flash(gettext("Entered name does not match organization name"), "danger")
|
||||
else:
|
||||
try:
|
||||
db.session.delete(request)
|
||||
db.session.commit()
|
||||
flash(gettext("Verification request successfully deleted"), "success")
|
||||
return redirect(
|
||||
url_for(
|
||||
"manage_admin_unit_verification_requests_outgoing",
|
||||
id=request.source_admin_unit.id,
|
||||
)
|
||||
)
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), "danger")
|
||||
else:
|
||||
flash_errors(form)
|
||||
|
||||
return render_template(
|
||||
"verification_request/delete.html", form=form, verification_request=request
|
||||
)
|
||||
|
||||
|
||||
def send_member_verification_request_verify_mails(
|
||||
admin_unit_id, subject, template, **context
|
||||
):
|
||||
# Benachrichtige alle Mitglieder der AdminUnit, die Requests verifizieren können
|
||||
members = get_admin_unit_members_with_permission(
|
||||
admin_unit_id, "verification_request:verify"
|
||||
)
|
||||
emails = list(map(lambda member: member.user.email, members))
|
||||
|
||||
send_mails(emails, subject, template, **context)
|
||||
|
||||
|
||||
def send_verification_request_inbox_mails(request):
|
||||
send_member_verification_request_verify_mails(
|
||||
request.target_admin_unit_id or request.target_admin_unit.id,
|
||||
gettext("New verification request"),
|
||||
"verification_request_notice",
|
||||
request=request,
|
||||
)
|
||||
118
project/views/verification_request_review.py
Normal file
118
project/views/verification_request_review.py
Normal file
@ -0,0 +1,118 @@
|
||||
from flask import abort, flash, redirect, render_template, url_for
|
||||
from flask_babel import gettext
|
||||
from flask_security import auth_required
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from project import app, db
|
||||
from project.access import (
|
||||
access_or_401,
|
||||
get_admin_unit_members_with_permission,
|
||||
has_access,
|
||||
)
|
||||
from project.forms.verification_request import VerificationRequestReviewForm
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
from project.services.admin_unit import upsert_admin_unit_relation
|
||||
from project.views.utils import flash_errors, handleSqlError, send_mails
|
||||
|
||||
|
||||
@app.route("/verification_request/<int:id>/review", methods=("GET", "POST"))
|
||||
@auth_required()
|
||||
def admin_unit_verification_request_review(id):
|
||||
request = AdminUnitVerificationRequest.query.get_or_404(id)
|
||||
access_or_401(request.target_admin_unit, "verification_request:verify")
|
||||
|
||||
if request.review_status == AdminUnitVerificationRequestReviewStatus.verified:
|
||||
flash(gettext("Request already verified"), "danger")
|
||||
return redirect(
|
||||
url_for(
|
||||
"manage_admin_unit_verification_requests_incoming",
|
||||
id=request.target_admin_unit_id,
|
||||
)
|
||||
)
|
||||
|
||||
form = VerificationRequestReviewForm(obj=request)
|
||||
|
||||
if form.validate_on_submit():
|
||||
form.populate_obj(request)
|
||||
|
||||
if request.review_status != AdminUnitVerificationRequestReviewStatus.rejected:
|
||||
request.rejection_reason = None
|
||||
|
||||
if request.rejection_reason == 0:
|
||||
request.rejection_reason = None
|
||||
|
||||
try:
|
||||
if (
|
||||
request.review_status
|
||||
== AdminUnitVerificationRequestReviewStatus.verified
|
||||
):
|
||||
relation = upsert_admin_unit_relation(
|
||||
request.target_admin_unit_id, request.source_admin_unit_id
|
||||
)
|
||||
relation.verify = True
|
||||
|
||||
if form.auto_verify.data:
|
||||
relation.auto_verify_event_reference_requests = True
|
||||
|
||||
msg = gettext("Organization successfully verified")
|
||||
else:
|
||||
msg = gettext("Verification request successfully updated")
|
||||
|
||||
db.session.commit()
|
||||
send_verification_request_review_status_mails(request)
|
||||
flash(msg, "success")
|
||||
return redirect(
|
||||
url_for(
|
||||
"manage_admin_unit_verification_requests_incoming",
|
||||
id=request.target_admin_unit_id,
|
||||
)
|
||||
)
|
||||
except SQLAlchemyError as e:
|
||||
db.session.rollback()
|
||||
flash(handleSqlError(e), "danger")
|
||||
else:
|
||||
flash_errors(form)
|
||||
|
||||
form.auto_verify.description = gettext(
|
||||
"If all upcoming reference requests of %(admin_unit_name)s should be verified automatically.",
|
||||
admin_unit_name=request.source_admin_unit.name,
|
||||
)
|
||||
|
||||
return render_template(
|
||||
"verification_request/review.html",
|
||||
form=form,
|
||||
request=request,
|
||||
)
|
||||
|
||||
|
||||
@app.route("/verification_request/<int:id>/review_status")
|
||||
def admin_unit_verification_request_review_status(id):
|
||||
request = AdminUnitVerificationRequest.query.get_or_404(id)
|
||||
|
||||
if not has_access(
|
||||
request.target_admin_unit, "verification_request:verify"
|
||||
) and not has_access(request.source_admin_unit, "verification_request:create"):
|
||||
abort(401)
|
||||
|
||||
return render_template(
|
||||
"verification_request/review_status.html",
|
||||
verification_request=request,
|
||||
)
|
||||
|
||||
|
||||
def send_verification_request_review_status_mails(request):
|
||||
# Benachrichtige alle Mitglieder der AdminUnit, die diesen Request erstellt hatte
|
||||
members = get_admin_unit_members_with_permission(
|
||||
request.source_admin_unit_id, "verification_request:create"
|
||||
)
|
||||
emails = list(map(lambda member: member.user.email, members))
|
||||
|
||||
send_mails(
|
||||
emails,
|
||||
gettext("Verification request review status updated"),
|
||||
"verification_request_review_status_notice",
|
||||
request=request,
|
||||
)
|
||||
@ -677,6 +677,68 @@ class Seeder(object):
|
||||
)
|
||||
return (other_user_id, other_admin_unit_id, relation_id)
|
||||
|
||||
def setup_admin_unit_missing_verification_scenario(self, log_in_verifier=False):
|
||||
verifier_user_id = self.create_user()
|
||||
verifier_admin_unit_id = self.create_admin_unit(
|
||||
verifier_user_id,
|
||||
"Stadtmarketing",
|
||||
verified=True,
|
||||
can_verify_other=True,
|
||||
incoming_verification_requests_allowed=True,
|
||||
incoming_verification_requests_text="Please give us a call",
|
||||
)
|
||||
|
||||
unverified_user_id, unverified_admin_unit_id = self.setup_base(
|
||||
log_in=not log_in_verifier,
|
||||
admin_unit_verified=False,
|
||||
email="mitglied@verein.de",
|
||||
name="Verein",
|
||||
)
|
||||
|
||||
if log_in_verifier:
|
||||
self._utils.login()
|
||||
|
||||
return (
|
||||
verifier_user_id,
|
||||
verifier_admin_unit_id,
|
||||
unverified_user_id,
|
||||
unverified_admin_unit_id,
|
||||
)
|
||||
|
||||
def create_admin_unit_verification_request(
|
||||
self, source_admin_unit_id, target_admin_unit_id
|
||||
):
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
|
||||
with self._app.app_context():
|
||||
from project.services.admin_unit import get_admin_unit_by_id
|
||||
|
||||
target_admin_unit = get_admin_unit_by_id(target_admin_unit_id)
|
||||
target_admin_unit.can_verify_other = True
|
||||
target_admin_unit.incoming_verification_requests_allowed = True
|
||||
|
||||
request = AdminUnitVerificationRequest()
|
||||
request.source_admin_unit_id = source_admin_unit_id
|
||||
request.target_admin_unit_id = target_admin_unit_id
|
||||
request.review_status = AdminUnitVerificationRequestReviewStatus.inbox
|
||||
self._db.session.add(request)
|
||||
self._db.session.commit()
|
||||
request_id = request.id
|
||||
return request_id
|
||||
|
||||
def create_incoming_admin_unit_verification_request(self, admin_unit_id):
|
||||
other_user_id = self.create_user("other@test.de")
|
||||
other_admin_unit_id = self.create_admin_unit(
|
||||
other_user_id, "Other Crew", verified=False
|
||||
)
|
||||
request_id = self.create_admin_unit_verification_request(
|
||||
other_admin_unit_id, admin_unit_id
|
||||
)
|
||||
return (other_user_id, other_admin_unit_id, request_id)
|
||||
|
||||
def create_reference_request(self, event_id, admin_unit_id):
|
||||
from project.models import (
|
||||
EventReferenceRequest,
|
||||
|
||||
@ -14,7 +14,7 @@ def test_location_update_coordinate(client, app, db):
|
||||
assert location.coordinate is not None
|
||||
|
||||
|
||||
def test_event_category(client, app, db, seeder):
|
||||
def test_event_category(client, app, db, seeder: Seeder):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -28,7 +28,7 @@ def test_event_category(client, app, db, seeder):
|
||||
assert event.category is None
|
||||
|
||||
|
||||
def test_event_properties(client, app, db, seeder):
|
||||
def test_event_properties(client, app, db, seeder: Seeder):
|
||||
with app.app_context():
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
||||
@ -51,7 +51,7 @@ def test_event_properties(client, app, db, seeder):
|
||||
assert event.min_start == start
|
||||
|
||||
|
||||
def test_event_allday(client, app, db, seeder):
|
||||
def test_event_allday(client, app, db, seeder: Seeder):
|
||||
from project.dateutils import create_berlin_date
|
||||
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
@ -93,7 +93,7 @@ def test_event_allday(client, app, db, seeder):
|
||||
assert event_date.end == create_berlin_date(2031, 1, 1, 23, 59, 59)
|
||||
|
||||
|
||||
def test_event_has_multiple_dates(client, app, db, seeder):
|
||||
def test_event_has_multiple_dates(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
event_with_recc_id = seeder.create_event(
|
||||
admin_unit_id, recurrence_rule="RRULE:FREQ=DAILY;COUNT=7"
|
||||
@ -110,7 +110,7 @@ def test_event_has_multiple_dates(client, app, db, seeder):
|
||||
assert event_without_recc.has_multiple_dates() is False
|
||||
|
||||
|
||||
def test_oauth2_token(client, app, seeder):
|
||||
def test_oauth2_token(client, app, seeder: Seeder):
|
||||
import time
|
||||
|
||||
from project.models import OAuth2Token
|
||||
@ -124,7 +124,7 @@ def test_oauth2_token(client, app, seeder):
|
||||
assert not token.is_refresh_token_active()
|
||||
|
||||
|
||||
def test_admin_unit_relations(client, app, db, seeder):
|
||||
def test_admin_unit_relations(client, app, db, seeder: Seeder):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
(
|
||||
other_user_id,
|
||||
@ -145,7 +145,34 @@ def test_admin_unit_relations(client, app, db, seeder):
|
||||
assert len(admin_unit.outgoing_relations) == 0
|
||||
|
||||
|
||||
def test_event_date_defintion_deletion(client, app, db, seeder):
|
||||
def test_admin_unit_verification_requests(client, app, db, seeder: Seeder):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
(
|
||||
other_user_id,
|
||||
other_admin_unit_id,
|
||||
request_id,
|
||||
) = seeder.create_incoming_admin_unit_verification_request(admin_unit_id)
|
||||
|
||||
with app.app_context():
|
||||
from project.services.admin_unit import get_admin_unit_by_id
|
||||
|
||||
admin_unit = get_admin_unit_by_id(admin_unit_id)
|
||||
assert len(admin_unit.incoming_verification_requests) == 1
|
||||
request = admin_unit.incoming_verification_requests[0]
|
||||
assert request.id == request_id
|
||||
|
||||
other_admin_unit = get_admin_unit_by_id(other_admin_unit_id)
|
||||
assert len(other_admin_unit.outgoing_verification_requests) == 1
|
||||
request = other_admin_unit.outgoing_verification_requests[0]
|
||||
assert request.id == request_id
|
||||
|
||||
db.session.delete(request)
|
||||
db.session.commit()
|
||||
assert len(admin_unit.incoming_verification_requests) == 0
|
||||
assert len(other_admin_unit.outgoing_verification_requests) == 0
|
||||
|
||||
|
||||
def test_event_date_defintion_deletion(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -180,7 +207,7 @@ def test_event_date_defintion_deletion(client, app, db, seeder):
|
||||
assert event.date_definitions[0].id == date_definition2_id
|
||||
|
||||
|
||||
def test_admin_unit_deletion(client, app, db, seeder):
|
||||
def test_admin_unit_deletion(client, app, db, seeder: Seeder):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
my_event_id = seeder.create_event(admin_unit_id)
|
||||
suggestion_id = seeder.create_event_suggestion(admin_unit_id)
|
||||
@ -206,12 +233,19 @@ def test_admin_unit_deletion(client, app, db, seeder):
|
||||
)
|
||||
incoming_reference_id = seeder.create_reference(other_event_id, admin_unit_id)
|
||||
outgoing_reference_id = seeder.create_reference(my_event_id, other_admin_unit_id)
|
||||
incoming_verification_request_id = seeder.create_admin_unit_verification_request(
|
||||
other_admin_unit_id, admin_unit_id
|
||||
)
|
||||
outgoing_verification_request_id = seeder.create_admin_unit_verification_request(
|
||||
admin_unit_id, other_admin_unit_id
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
from project.models import (
|
||||
AdminUnit,
|
||||
AdminUnitMemberInvitation,
|
||||
AdminUnitRelation,
|
||||
AdminUnitVerificationRequest,
|
||||
Event,
|
||||
EventDate,
|
||||
EventDateDefinition,
|
||||
@ -247,6 +281,18 @@ def test_admin_unit_deletion(client, app, db, seeder):
|
||||
assert (
|
||||
db.session.get(EventReferenceRequest, outgoing_reference_request_id) is None
|
||||
)
|
||||
assert (
|
||||
db.session.get(
|
||||
AdminUnitVerificationRequest, incoming_verification_request_id
|
||||
)
|
||||
is None
|
||||
)
|
||||
assert (
|
||||
db.session.get(
|
||||
AdminUnitVerificationRequest, outgoing_verification_request_id
|
||||
)
|
||||
is None
|
||||
)
|
||||
assert db.session.get(EventSuggestion, suggestion_id) is None
|
||||
assert db.session.get(EventPlace, event_place_id) is None
|
||||
assert db.session.get(EventOrganizer, organizer_id) is None
|
||||
@ -257,7 +303,7 @@ def test_admin_unit_deletion(client, app, db, seeder):
|
||||
assert db.session.get(Event, other_event_id) is not None
|
||||
|
||||
|
||||
def test_event_co_organizers_deletion(client, app, db, seeder):
|
||||
def test_event_co_organizers_deletion(client, app, db, seeder: Seeder):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
event_id, organizer_a_id, organizer_b_id = seeder.create_event_with_co_organizers(
|
||||
admin_unit_id
|
||||
@ -282,7 +328,7 @@ def test_event_co_organizers_deletion(client, app, db, seeder):
|
||||
assert db.session.get(EventOrganizer, organizer_b_id).id is not None
|
||||
|
||||
|
||||
def test_admin_unit_verification(client, app, db, seeder):
|
||||
def test_admin_unit_verification(client, app, db, seeder: Seeder):
|
||||
user_id, admin_unit_id = seeder.setup_base(log_in=False, admin_unit_verified=False)
|
||||
other_user_id = seeder.create_user("other@test.de")
|
||||
other_admin_unit_id = seeder.create_admin_unit(other_user_id, "Other Crew")
|
||||
@ -323,7 +369,7 @@ def test_admin_unit_verification(client, app, db, seeder):
|
||||
assert len(all_verified) == 0
|
||||
|
||||
|
||||
def test_admin_unit_invitations(client, app, db, seeder):
|
||||
def test_admin_unit_invitations(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
invitation_id = seeder.create_admin_unit_invitation(admin_unit_id)
|
||||
|
||||
@ -342,7 +388,7 @@ def test_admin_unit_invitations(client, app, db, seeder):
|
||||
assert invitation is None
|
||||
|
||||
|
||||
def test_event_list_deletion(client, app, db, seeder):
|
||||
def test_event_list_deletion(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
event_list_a_id = seeder.create_event_list(admin_unit_id, event_id, "List A")
|
||||
@ -381,7 +427,7 @@ def test_event_list_deletion(client, app, db, seeder):
|
||||
assert len(event_list_b.events) == 0
|
||||
|
||||
|
||||
def test_event_is_favored_by_current_user(client, app, db, seeder):
|
||||
def test_event_is_favored_by_current_user(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
|
||||
@ -392,7 +438,7 @@ def test_event_is_favored_by_current_user(client, app, db, seeder):
|
||||
assert event.is_favored_by_current_user() is False
|
||||
|
||||
|
||||
def test_purge_event_photo(client, app, db, seeder):
|
||||
def test_purge_event_photo(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
event_id = seeder.create_event(admin_unit_id)
|
||||
first_image_id = seeder.upsert_default_image()
|
||||
@ -414,7 +460,7 @@ def test_purge_event_photo(client, app, db, seeder):
|
||||
assert image is None
|
||||
|
||||
|
||||
def test_purge_event_place_photo(client, app, db, seeder):
|
||||
def test_purge_event_place_photo(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
first_image_id = seeder.upsert_default_image()
|
||||
@ -451,7 +497,7 @@ def test_purge_event_place_photo(client, app, db, seeder):
|
||||
assert image is None
|
||||
|
||||
|
||||
def test_purge_eventsuggestion_photo(client, app, db, seeder):
|
||||
def test_purge_eventsuggestion_photo(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
suggestion_id = seeder.create_event_suggestion(admin_unit_id)
|
||||
image_id = seeder.upsert_default_image()
|
||||
@ -475,7 +521,7 @@ def test_purge_eventsuggestion_photo(client, app, db, seeder):
|
||||
assert image is None
|
||||
|
||||
|
||||
def test_purge_adminunit(client, app, db, seeder):
|
||||
def test_purge_adminunit(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
instance_id = admin_unit_id
|
||||
image_id = seeder.upsert_default_image()
|
||||
@ -507,7 +553,7 @@ def test_purge_adminunit(client, app, db, seeder):
|
||||
assert location is None
|
||||
|
||||
|
||||
def test_purge_eventorganizer(client, app, db, seeder):
|
||||
def test_purge_eventorganizer(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
instance_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
image_id = seeder.upsert_default_image()
|
||||
@ -539,7 +585,7 @@ def test_purge_eventorganizer(client, app, db, seeder):
|
||||
assert location is None
|
||||
|
||||
|
||||
def test_delete_admin_unit(client, app, db, seeder):
|
||||
def test_delete_admin_unit(client, app, db, seeder: Seeder):
|
||||
_, admin_unit_id = seeder.setup_base(log_in=False)
|
||||
instance_id = seeder.upsert_default_event_organizer(admin_unit_id)
|
||||
image_id = seeder.upsert_default_image()
|
||||
|
||||
@ -24,7 +24,7 @@ def test_index_withValidCookie(client, seeder, app, utils):
|
||||
utils.assert_response_redirect(response, "manage_admin_unit", id=admin_unit_id)
|
||||
|
||||
|
||||
def test_index_withInvalidCookie(client, seeder, utils):
|
||||
def test_index_withInvalidCookie(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
client.set_cookie("localhost", "manage_admin_unit_id", "invalid")
|
||||
|
||||
@ -70,7 +70,7 @@ def test_index_after_login_organization_invitation(client, app, db, utils, seede
|
||||
)
|
||||
|
||||
|
||||
def test_admin_unit(client, seeder, utils):
|
||||
def test_admin_unit(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
response = utils.get_endpoint("manage_admin_unit", id=admin_unit_id)
|
||||
@ -79,7 +79,7 @@ def test_admin_unit(client, seeder, utils):
|
||||
)
|
||||
|
||||
|
||||
def test_admin_unit_404(client, seeder, utils):
|
||||
def test_admin_unit_404(client, seeder: Seeder, utils: UtilActions):
|
||||
owner_id = seeder.create_user("owner@owner")
|
||||
admin_unit_id = seeder.create_admin_unit(owner_id, "Other crew")
|
||||
seeder.create_user()
|
||||
@ -89,13 +89,13 @@ def test_admin_unit_404(client, seeder, utils):
|
||||
utils.assert_response_notFound(response)
|
||||
|
||||
|
||||
def test_admin_unit_event_reviews(client, seeder, utils):
|
||||
def test_admin_unit_event_reviews(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
utils.get_endpoint_ok("manage_admin_unit_event_reviews", id=admin_unit_id)
|
||||
|
||||
|
||||
def test_admin_unit_events(client, seeder, utils):
|
||||
def test_admin_unit_events(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base(admin_unit_verified=False)
|
||||
|
||||
utils.get_endpoint_ok(
|
||||
@ -112,7 +112,9 @@ def test_admin_unit_events(client, seeder, utils):
|
||||
utils.assert_response_contains(response, event_url)
|
||||
|
||||
|
||||
def test_admin_unit_events_invalidDateFormat(client, seeder, utils):
|
||||
def test_admin_unit_events_invalidDateFormat(
|
||||
client, seeder: Seeder, utils: UtilActions
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
utils.get_endpoint_ok(
|
||||
@ -126,7 +128,7 @@ def test_admin_unit_events_invalidDateFormat(client, seeder, utils):
|
||||
)
|
||||
|
||||
|
||||
def test_admin_unit_events_place(client, seeder, utils):
|
||||
def test_admin_unit_events_place(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base(admin_unit_verified=False)
|
||||
seeder.create_event(admin_unit_id, draft=True)
|
||||
event_place_id = seeder.upsert_default_event_place(admin_unit_id)
|
||||
@ -136,25 +138,27 @@ def test_admin_unit_events_place(client, seeder, utils):
|
||||
)
|
||||
|
||||
|
||||
def test_admin_unit_organizers(client, seeder, utils):
|
||||
def test_admin_unit_organizers(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
utils.get_endpoint_ok("manage_admin_unit_organizers", id=admin_unit_id)
|
||||
|
||||
|
||||
def test_admin_unit_event_places(client, seeder, utils):
|
||||
def test_admin_unit_event_places(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
utils.get_endpoint_ok("manage_admin_unit_event_places", id=admin_unit_id)
|
||||
|
||||
|
||||
def test_admin_unit_members(client, seeder, utils):
|
||||
def test_admin_unit_members(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
utils.get_endpoint_ok("manage_admin_unit_members", id=admin_unit_id)
|
||||
|
||||
|
||||
def test_admin_unit_members_permission_missing(client, seeder, utils):
|
||||
def test_admin_unit_members_permission_missing(
|
||||
client, seeder: Seeder, utils: UtilActions
|
||||
):
|
||||
owner_id, admin_unit_id, member_id = seeder.setup_base_event_verifier()
|
||||
|
||||
response = utils.get_endpoint("manage_admin_unit_members", id=admin_unit_id)
|
||||
@ -164,7 +168,9 @@ def test_admin_unit_members_permission_missing(client, seeder, utils):
|
||||
|
||||
|
||||
@pytest.mark.parametrize("db_error", [True, False])
|
||||
def test_admin_unit_widgets(client, seeder, utils, mocker, db_error):
|
||||
def test_admin_unit_widgets(
|
||||
client, seeder: Seeder, utils: UtilActions, mocker, db_error
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
url = utils.get_url("manage_admin_unit_widgets", id=admin_unit_id)
|
||||
@ -184,7 +190,9 @@ def test_admin_unit_widgets(client, seeder, utils, mocker, db_error):
|
||||
)
|
||||
|
||||
|
||||
def test_admin_unit_widgets_permission_missing(client, seeder, utils, mocker):
|
||||
def test_admin_unit_widgets_permission_missing(
|
||||
client, seeder: Seeder, utils: UtilActions, mocker
|
||||
):
|
||||
owner_id, admin_unit_id, member_id = seeder.setup_base_event_verifier()
|
||||
|
||||
url = utils.get_url("manage_admin_unit_widgets", id=admin_unit_id)
|
||||
@ -196,63 +204,43 @@ def test_admin_unit_widgets_permission_missing(client, seeder, utils, mocker):
|
||||
)
|
||||
|
||||
|
||||
def test_admin_unit_relations(client, seeder, utils):
|
||||
def test_admin_unit_relations(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
url = utils.get_url("manage_admin_unit_relations", id=admin_unit_id)
|
||||
utils.get_ok(url)
|
||||
|
||||
|
||||
def test_admin_unit_organization_invitations(client, seeder, utils):
|
||||
def test_admin_unit_organization_invitations(
|
||||
client, seeder: Seeder, utils: UtilActions
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
url = utils.get_url("manage_admin_unit_organization_invitations", id=admin_unit_id)
|
||||
utils.get_ok(url)
|
||||
|
||||
|
||||
def test_admin_unit_event_lists(client, seeder, utils):
|
||||
def test_admin_unit_event_lists(client, seeder: Seeder, utils: UtilActions):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
|
||||
url = utils.get_url("manage_admin_unit_event_lists", id=admin_unit_id)
|
||||
utils.get_ok(url)
|
||||
|
||||
|
||||
def test_admin_unit_custom_widgets(client, seeder, utils):
|
||||
def test_admin_unit_custom_widgets(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
|
||||
url = utils.get_url("manage_admin_unit_custom_widgets", id=admin_unit_id)
|
||||
utils.get_ok(url)
|
||||
|
||||
|
||||
def test_admin_unit_events_import(client, seeder, utils):
|
||||
def test_admin_unit_events_import(client, seeder: Seeder, utils: UtilActions):
|
||||
_, admin_unit_id = seeder.setup_base()
|
||||
|
||||
url = utils.get_url("manage_admin_unit_events_import", id=admin_unit_id)
|
||||
utils.get_ok(url)
|
||||
|
||||
|
||||
def test_verification_requests_outgoing(client, seeder, utils):
|
||||
user_id = seeder.create_user()
|
||||
seeder.create_admin_unit(
|
||||
user_id,
|
||||
"Stadtmarketing",
|
||||
verified=True,
|
||||
can_verify_other=True,
|
||||
incoming_verification_requests_allowed=True,
|
||||
incoming_verification_requests_text="Please give us a call",
|
||||
)
|
||||
|
||||
_, other_admin_unit_id = seeder.setup_base(
|
||||
admin_unit_verified=False, email="mitglied@verein.de", name="Verein"
|
||||
)
|
||||
|
||||
response = utils.get_endpoint_ok(
|
||||
"manage_admin_unit_verification_requests_outgoing", id=other_admin_unit_id
|
||||
)
|
||||
utils.assert_response_contains(response, "Stadtmarketing")
|
||||
utils.assert_response_contains(response, "Please give us a call")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("scenario", ["db_error", "default", "last_admin", "non_match"])
|
||||
def test_manage_admin_unit_delete_membership(
|
||||
client, utils: UtilActions, seeder: Seeder, app, db, mocker, scenario: str
|
||||
|
||||
166
tests/views/test_verification_request.py
Normal file
166
tests/views/test_verification_request.py
Normal file
@ -0,0 +1,166 @@
|
||||
import pytest
|
||||
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
@pytest.mark.parametrize("db_error", [True, False])
|
||||
def test_create(client, app, utils: UtilActions, seeder: Seeder, mocker, db_error):
|
||||
(
|
||||
verifier_user_id,
|
||||
verifier_admin_unit_id,
|
||||
unverified_user_id,
|
||||
unverified_admin_unit_id,
|
||||
) = seeder.setup_admin_unit_missing_verification_scenario()
|
||||
|
||||
url = utils.get_url(
|
||||
"manage_admin_unit_verification_requests_outgoing_create",
|
||||
id=unverified_admin_unit_id,
|
||||
target_id=verifier_admin_unit_id,
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
|
||||
if db_error:
|
||||
utils.mock_db_commit(mocker)
|
||||
|
||||
mail_mock = utils.mock_send_mails(mocker)
|
||||
response = utils.post_form(
|
||||
url,
|
||||
response,
|
||||
{},
|
||||
)
|
||||
|
||||
if db_error:
|
||||
utils.assert_response_db_error(response)
|
||||
return
|
||||
|
||||
utils.assert_response_redirect(
|
||||
response,
|
||||
"manage_admin_unit_verification_requests_outgoing",
|
||||
id=unverified_admin_unit_id,
|
||||
)
|
||||
utils.assert_send_mail_called(mail_mock, "test@test.de")
|
||||
|
||||
with app.app_context():
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
|
||||
verification_request = (
|
||||
AdminUnitVerificationRequest.query.filter(
|
||||
AdminUnitVerificationRequest.source_admin_unit_id
|
||||
== unverified_admin_unit_id
|
||||
)
|
||||
.filter(
|
||||
AdminUnitVerificationRequest.target_admin_unit_id
|
||||
== verifier_admin_unit_id
|
||||
)
|
||||
.first()
|
||||
)
|
||||
assert verification_request is not None
|
||||
assert (
|
||||
verification_request.review_status
|
||||
== AdminUnitVerificationRequestReviewStatus.inbox
|
||||
)
|
||||
|
||||
|
||||
def test_admin_unit_verification_requests_incoming(
|
||||
client, utils: UtilActions, seeder: Seeder
|
||||
):
|
||||
user_id, admin_unit_id = seeder.setup_base()
|
||||
seeder.create_incoming_admin_unit_verification_request(admin_unit_id)
|
||||
|
||||
utils.get_endpoint_ok(
|
||||
"manage_admin_unit_verification_requests_incoming", id=admin_unit_id
|
||||
)
|
||||
|
||||
|
||||
def test_verification_requests_outgoing(client, seeder: Seeder, utils: UtilActions):
|
||||
(
|
||||
verifier_user_id,
|
||||
verifier_admin_unit_id,
|
||||
unverified_user_id,
|
||||
unverified_admin_unit_id,
|
||||
) = seeder.setup_admin_unit_missing_verification_scenario()
|
||||
|
||||
response = utils.get_endpoint(
|
||||
"manage_admin_unit_verification_requests_outgoing", id=unverified_admin_unit_id
|
||||
)
|
||||
utils.assert_response_redirect(
|
||||
response,
|
||||
"manage_admin_unit_verification_requests_outgoing_create_select",
|
||||
id=unverified_admin_unit_id,
|
||||
)
|
||||
|
||||
response = utils.get_endpoint_ok(
|
||||
"manage_admin_unit_verification_requests_outgoing_create_select",
|
||||
id=unverified_admin_unit_id,
|
||||
)
|
||||
utils.assert_response_contains(response, "Stadtmarketing")
|
||||
utils.assert_response_contains(response, "Please give us a call")
|
||||
|
||||
seeder.create_admin_unit_verification_request(
|
||||
unverified_admin_unit_id, verifier_admin_unit_id
|
||||
)
|
||||
response = utils.get_endpoint_ok(
|
||||
"manage_admin_unit_verification_requests_outgoing",
|
||||
id=unverified_admin_unit_id,
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("db_error", [True, False])
|
||||
@pytest.mark.parametrize("non_match", [True, False])
|
||||
def test_delete(
|
||||
client, seeder: Seeder, utils: UtilActions, app, db, mocker, db_error, non_match
|
||||
):
|
||||
(
|
||||
verifier_user_id,
|
||||
verifier_admin_unit_id,
|
||||
unverified_user_id,
|
||||
unverified_admin_unit_id,
|
||||
) = seeder.setup_admin_unit_missing_verification_scenario()
|
||||
request_id = seeder.create_admin_unit_verification_request(
|
||||
unverified_admin_unit_id, verifier_admin_unit_id
|
||||
)
|
||||
|
||||
url = utils.get_url("admin_unit_verification_request_delete", id=request_id)
|
||||
response = utils.get_ok(url)
|
||||
|
||||
if db_error:
|
||||
utils.mock_db_commit(mocker)
|
||||
|
||||
form_name = "Stadtmarketing"
|
||||
|
||||
if non_match:
|
||||
form_name = "Falscher Name"
|
||||
|
||||
response = utils.post_form(
|
||||
url,
|
||||
response,
|
||||
{
|
||||
"name": form_name,
|
||||
},
|
||||
)
|
||||
|
||||
if non_match:
|
||||
utils.assert_response_error_message(
|
||||
response, "Der eingegebene Name entspricht nicht dem Namen der Organisation"
|
||||
)
|
||||
return
|
||||
|
||||
if db_error:
|
||||
utils.assert_response_db_error(response)
|
||||
return
|
||||
|
||||
utils.assert_response_redirect(
|
||||
response,
|
||||
"manage_admin_unit_verification_requests_outgoing",
|
||||
id=unverified_admin_unit_id,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
from project.models import AdminUnitVerificationRequest
|
||||
|
||||
request = db.session.get(AdminUnitVerificationRequest, request_id)
|
||||
assert request is None
|
||||
174
tests/views/test_verification_request_review.py
Normal file
174
tests/views/test_verification_request_review.py
Normal file
@ -0,0 +1,174 @@
|
||||
import pytest
|
||||
|
||||
from tests.seeder import Seeder
|
||||
from tests.utils import UtilActions
|
||||
|
||||
|
||||
@pytest.mark.parametrize("db_error", [True, False])
|
||||
@pytest.mark.parametrize("is_verified", [True, False])
|
||||
def test_review_verify(
|
||||
client, seeder: Seeder, utils: UtilActions, app, mocker, db, db_error, is_verified
|
||||
):
|
||||
(
|
||||
verifier_user_id,
|
||||
verifier_admin_unit_id,
|
||||
unverified_user_id,
|
||||
unverified_admin_unit_id,
|
||||
) = seeder.setup_admin_unit_missing_verification_scenario(log_in_verifier=True)
|
||||
verification_request_id = seeder.create_admin_unit_verification_request(
|
||||
unverified_admin_unit_id, verifier_admin_unit_id
|
||||
)
|
||||
|
||||
url = utils.get_url(
|
||||
"admin_unit_verification_request_review", id=verification_request_id
|
||||
)
|
||||
|
||||
if is_verified:
|
||||
with app.app_context():
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
|
||||
verification_request = db.session.get(
|
||||
AdminUnitVerificationRequest, verification_request_id
|
||||
)
|
||||
verification_request.review_status = (
|
||||
AdminUnitVerificationRequestReviewStatus.verified
|
||||
)
|
||||
db.session.commit()
|
||||
|
||||
response = client.get(url)
|
||||
utils.assert_response_redirect(
|
||||
response,
|
||||
"manage_admin_unit_verification_requests_incoming",
|
||||
id=verifier_admin_unit_id,
|
||||
)
|
||||
return
|
||||
|
||||
response = utils.get_ok(url)
|
||||
|
||||
if db_error:
|
||||
utils.mock_db_commit(mocker)
|
||||
|
||||
mail_mock = utils.mock_send_mails(mocker)
|
||||
response = utils.post_form(
|
||||
url,
|
||||
response,
|
||||
{
|
||||
"review_status": 2,
|
||||
"auto_verify": 1,
|
||||
},
|
||||
)
|
||||
|
||||
if db_error:
|
||||
utils.assert_response_db_error(response)
|
||||
return
|
||||
|
||||
utils.assert_response_redirect(
|
||||
response,
|
||||
"manage_admin_unit_verification_requests_incoming",
|
||||
id=verifier_admin_unit_id,
|
||||
)
|
||||
utils.assert_send_mail_called(mail_mock, "mitglied@verein.de")
|
||||
|
||||
with app.app_context():
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
from project.services.admin_unit import get_admin_unit_relation
|
||||
|
||||
verification_request = db.session.get(
|
||||
AdminUnitVerificationRequest, verification_request_id
|
||||
)
|
||||
assert verification_request.verified
|
||||
|
||||
relation = get_admin_unit_relation(
|
||||
verifier_admin_unit_id, unverified_admin_unit_id
|
||||
)
|
||||
assert relation is not None
|
||||
assert relation.verify
|
||||
assert relation.auto_verify_event_reference_requests
|
||||
|
||||
|
||||
def test_review_reject(client, seeder: Seeder, utils: UtilActions, app, db, mocker):
|
||||
(
|
||||
verifier_user_id,
|
||||
verifier_admin_unit_id,
|
||||
unverified_user_id,
|
||||
unverified_admin_unit_id,
|
||||
) = seeder.setup_admin_unit_missing_verification_scenario(log_in_verifier=True)
|
||||
verification_request_id = seeder.create_admin_unit_verification_request(
|
||||
unverified_admin_unit_id, verifier_admin_unit_id
|
||||
)
|
||||
|
||||
url = utils.get_url(
|
||||
"admin_unit_verification_request_review", id=verification_request_id
|
||||
)
|
||||
response = utils.get_ok(url)
|
||||
|
||||
response = utils.post_form(
|
||||
url,
|
||||
response,
|
||||
{
|
||||
"review_status": 3,
|
||||
"rejection_reason": 0,
|
||||
},
|
||||
)
|
||||
|
||||
utils.assert_response_redirect(
|
||||
response,
|
||||
"manage_admin_unit_verification_requests_incoming",
|
||||
id=verifier_admin_unit_id,
|
||||
)
|
||||
|
||||
with app.app_context():
|
||||
from project.models import (
|
||||
AdminUnitVerificationRequest,
|
||||
AdminUnitVerificationRequestReviewStatus,
|
||||
)
|
||||
|
||||
verification_request = db.session.get(
|
||||
AdminUnitVerificationRequest, verification_request_id
|
||||
)
|
||||
assert (
|
||||
verification_request.review_status
|
||||
== AdminUnitVerificationRequestReviewStatus.rejected
|
||||
)
|
||||
assert verification_request.rejection_reason is None
|
||||
|
||||
|
||||
def test_review_status(client, seeder: Seeder, utils: UtilActions):
|
||||
(
|
||||
verifier_user_id,
|
||||
verifier_admin_unit_id,
|
||||
unverified_user_id,
|
||||
unverified_admin_unit_id,
|
||||
) = seeder.setup_admin_unit_missing_verification_scenario(log_in_verifier=True)
|
||||
verification_request_id = seeder.create_admin_unit_verification_request(
|
||||
unverified_admin_unit_id, verifier_admin_unit_id
|
||||
)
|
||||
|
||||
url = utils.get_url(
|
||||
"admin_unit_verification_request_review_status", id=verification_request_id
|
||||
)
|
||||
utils.get_ok(url)
|
||||
|
||||
|
||||
def test_review_status_401_unauthorized(client, seeder: Seeder, utils: UtilActions):
|
||||
seeder.create_user()
|
||||
|
||||
third_user_id = seeder.create_user("third@third.de")
|
||||
third_admin_unit_id = seeder.create_admin_unit(third_user_id, "Third Crew")
|
||||
(
|
||||
other_user_id,
|
||||
other_admin_unit_id,
|
||||
verification_request_id,
|
||||
) = seeder.create_incoming_admin_unit_verification_request(third_admin_unit_id)
|
||||
|
||||
url = utils.get_url(
|
||||
"admin_unit_verification_request_review_status", id=verification_request_id
|
||||
)
|
||||
response = client.get(url)
|
||||
assert response.status_code == 401
|
||||
Loading…
x
Reference in New Issue
Block a user