Library updates #432

This commit is contained in:
Daniel Grams 2023-04-16 13:47:49 +02:00
parent d2edaaa2f1
commit c3a36b94a8
32 changed files with 233 additions and 176 deletions

View File

@ -32,7 +32,9 @@ def upgrade():
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, "eventsuggestion", type_="foreignkey")
op.drop_constraint(
"eventsuggestion_event_id_fkey", "eventsuggestion", type_="foreignkey"
)
op.create_foreign_key(
"eventsuggestion_event_id_fkey",
"eventsuggestion",
@ -40,22 +42,22 @@ def downgrade():
["event_id"],
["id"],
)
op.create_table(
"spatial_ref_sys",
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column(
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
),
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
sa.Column(
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
),
sa.Column(
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
),
sa.CheckConstraint(
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
),
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
)
# op.create_table(
# "spatial_ref_sys",
# sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
# sa.Column(
# "auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
# ),
# sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
# sa.Column(
# "srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
# ),
# sa.Column(
# "proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
# ),
# sa.CheckConstraint(
# "(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
# ),
# sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
# )
# ### end Alembic commands ###

View File

@ -55,22 +55,22 @@ def downgrade():
op.drop_column("adminunit", "widget_link_color")
op.drop_column("adminunit", "widget_font")
op.drop_column("adminunit", "widget_background_color")
op.create_table(
"spatial_ref_sys",
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column(
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
),
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
sa.Column(
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
),
sa.Column(
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
),
sa.CheckConstraint(
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
),
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
)
# op.create_table(
# "spatial_ref_sys",
# sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
# sa.Column(
# "auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
# ),
# sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
# sa.Column(
# "srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
# ),
# sa.Column(
# "proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
# ),
# sa.CheckConstraint(
# "(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
# ),
# sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
# )
# ### end Alembic commands ###

View File

@ -65,7 +65,7 @@ def upgrade():
sa.PrimaryKeyConstraint("id"),
)
migrate_category_to_categories()
upgrade_category_to_categories()
# op.drop_table('spatial_ref_sys')
op.drop_constraint("event_category_id_fkey", "event", type_="foreignkey")
@ -73,7 +73,7 @@ def upgrade():
# ### end Alembic commands ###
def migrate_category_to_categories():
def upgrade_category_to_categories():
bind = op.get_bind()
session = orm.Session(bind=bind)
@ -83,32 +83,53 @@ def migrate_category_to_categories():
session.commit()
def downgrade_categories_to_category():
bind = op.get_bind()
session = orm.Session(bind=bind)
for event in session.query(Event):
event.category = event.categories[0]
session.commit()
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column(
"event",
sa.Column("category_id", sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column("category_id", sa.INTEGER(), autoincrement=False, nullable=True),
)
downgrade_categories_to_category()
op.alter_column(
"event",
sa.Column(
"category_id",
existing_type=sa.INTEGER(),
autoincrement=False,
nullable=False,
),
)
op.create_foreign_key(
"event_category_id_fkey", "event", "eventcategory", ["category_id"], ["id"]
)
op.create_table(
"spatial_ref_sys",
sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
sa.Column(
"auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
),
sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
sa.Column(
"srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
),
sa.Column(
"proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
),
sa.CheckConstraint(
"(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
),
sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
)
# op.create_table(
# "spatial_ref_sys",
# sa.Column("srid", sa.INTEGER(), autoincrement=False, nullable=False),
# sa.Column(
# "auth_name", sa.VARCHAR(length=256), autoincrement=False, nullable=True
# ),
# sa.Column("auth_srid", sa.INTEGER(), autoincrement=False, nullable=True),
# sa.Column(
# "srtext", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
# ),
# sa.Column(
# "proj4text", sa.VARCHAR(length=2048), autoincrement=False, nullable=True
# ),
# sa.CheckConstraint(
# "(srid > 0) AND (srid <= 998999)", name="spatial_ref_sys_srid_check"
# ),
# sa.PrimaryKeyConstraint("srid", name="spatial_ref_sys_pkey"),
# )
op.drop_table("event_eventcategories")
# ### end Alembic commands ###

View File

@ -73,34 +73,46 @@ def upgrade():
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, "settings", type_="foreignkey")
op.drop_constraint("settings_updated_by_id_fkey", "settings", type_="foreignkey")
op.drop_column("settings", "updated_by_id")
op.drop_column("settings", "updated_at")
op.drop_constraint(None, "location", type_="foreignkey")
op.drop_constraint("location_updated_by_id_fkey", "location", type_="foreignkey")
op.drop_column("location", "updated_by_id")
op.drop_column("location", "updated_at")
op.drop_constraint(None, "image", type_="foreignkey")
op.drop_constraint("image_updated_by_id_fkey", "image", type_="foreignkey")
op.drop_column("image", "updated_by_id")
op.drop_column("image", "updated_at")
op.drop_constraint(None, "eventsuggestion", type_="foreignkey")
op.drop_constraint(
"eventsuggestion_updated_by_id_fkey", "eventsuggestion", type_="foreignkey"
)
op.drop_column("eventsuggestion", "updated_by_id")
op.drop_column("eventsuggestion", "updated_at")
op.drop_constraint(None, "eventreferencerequest", type_="foreignkey")
op.drop_constraint(
"eventreferencerequest_updated_by_id_fkey",
"eventreferencerequest",
type_="foreignkey",
)
op.drop_column("eventreferencerequest", "updated_by_id")
op.drop_column("eventreferencerequest", "updated_at")
op.drop_constraint(None, "eventreference", type_="foreignkey")
op.drop_constraint(
"eventreference_updated_by_id_fkey", "eventreference", type_="foreignkey"
)
op.drop_column("eventreference", "updated_by_id")
op.drop_column("eventreference", "updated_at")
op.drop_constraint(None, "eventplace", type_="foreignkey")
op.drop_constraint(
"eventplace_updated_by_id_fkey", "eventplace", type_="foreignkey"
)
op.drop_column("eventplace", "updated_by_id")
op.drop_column("eventplace", "updated_at")
op.drop_constraint(None, "eventorganizer", type_="foreignkey")
op.drop_constraint(
"eventorganizer_updated_by_id_fkey", "eventorganizer", type_="foreignkey"
)
op.drop_column("eventorganizer", "updated_by_id")
op.drop_column("eventorganizer", "updated_at")
op.drop_constraint(None, "event", type_="foreignkey")
op.drop_constraint("event_updated_by_id_fkey", "event", type_="foreignkey")
op.drop_column("event", "updated_by_id")
op.drop_column("event", "updated_at")
op.drop_constraint(None, "adminunit", type_="foreignkey")
op.drop_constraint("adminunit_updated_by_id_fkey", "adminunit", type_="foreignkey")
op.drop_column("adminunit", "updated_by_id")
op.drop_column("adminunit", "updated_at")
# ### end Alembic commands ###

View File

@ -1,7 +1,7 @@
from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm
from wtforms import BooleanField, RadioField, StringField, SubmitField, TextAreaField
from wtforms.fields.html5 import EmailField
from wtforms.fields import EmailField
from wtforms.validators import DataRequired, Optional
from project.forms.widgets import MultiCheckboxField

View File

@ -1,10 +1,9 @@
from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm
from wtforms import DecimalField, FormField, StringField, SubmitField, TextAreaField
from wtforms.fields.core import BooleanField
from wtforms.fields.html5 import EmailField, TelField, URLField
from wtforms.fields import BooleanField, EmailField, TelField, URLField
from wtforms.validators import DataRequired, Length, Optional, Regexp
from wtforms.widgets.html5 import ColorInput
from wtforms.widgets import ColorInput
from project.forms.common import Base64ImageForm
from project.forms.widgets import HTML5StringField

View File

@ -1,7 +1,7 @@
from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm
from wtforms import SubmitField
from wtforms.fields.html5 import EmailField
from wtforms.fields import EmailField
from wtforms.validators import DataRequired
from project.forms.widgets import MultiCheckboxField

View File

@ -32,8 +32,8 @@ class Base64ImageForm(BaseImageForm):
obj.data, obj.encoding_format
)
def validate(self):
result = super().validate()
def validate(self, extra_validators=None):
result = super().validate(extra_validators)
if self.image_base64.data:
image = get_image_from_base64_str(self.image_base64.data)

View File

@ -14,8 +14,7 @@ from wtforms import (
SubmitField,
TextAreaField,
)
from wtforms.fields.core import FieldList
from wtforms.fields.html5 import EmailField, URLField
from wtforms.fields import EmailField, FieldList, URLField
from wtforms.validators import DataRequired, Length, Optional
from project.forms.common import Base64ImageForm, distance_choices, event_rating_choices
@ -72,8 +71,8 @@ class EventDateDefinitionFormMixin:
class EventDateDefinitionForm(FlaskForm, EventDateDefinitionFormMixin):
def validate(self):
result = super().validate()
def validate(self, extra_validators=None):
result = super().validate(extra_validators)
if not self.validate_date_definition():
result = False
@ -270,8 +269,8 @@ class BaseEventForm(SharedEventForm):
),
)
def validate(self):
result = super().validate()
def validate(self, extra_validators=None):
result = super().validate(extra_validators)
if self.co_organizer_ids.data and self.organizer_id.data:
if self.organizer_id.data in self.co_organizer_ids.data:
@ -342,8 +341,8 @@ class CreateEventForm(BaseEventForm):
PublicStatus.published if self.submit.data else PublicStatus.draft
)
def validate(self):
result = super().validate()
def validate(self, extra_validators=None):
result = super().validate(extra_validators)
if (
not self.event_place_id.data or self.event_place_id.data == 0

View File

@ -1,7 +1,7 @@
from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm
from wtforms import DecimalField, FormField, StringField, SubmitField, TextAreaField
from wtforms.fields.html5 import URLField
from wtforms.fields import URLField
from wtforms.validators import DataRequired, Optional
from project.forms.common import Base64ImageForm

View File

@ -7,7 +7,7 @@ from wtforms import (
StringField,
SubmitField,
)
from wtforms.fields.html5 import EmailField, TelField
from wtforms.fields import EmailField, TelField
from wtforms.validators import DataRequired, Optional
from project.forms.common import get_accept_tos_markup
@ -110,8 +110,8 @@ class CreateEventSuggestionForm(SharedEventForm, EventDateDefinitionFormMixin):
else:
field.populate_obj(obj, name)
def validate(self):
result = super().validate()
def validate(self, extra_validators=None):
result = super().validate(extra_validators)
if not self.validate_date_definition():
result = False

View File

@ -1,7 +1,7 @@
from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm
from wtforms import DecimalField, FormField, StringField, SubmitField
from wtforms.fields.html5 import EmailField, TelField, URLField
from wtforms.fields import EmailField, TelField, URLField
from wtforms.validators import DataRequired, Optional
from project.forms.common import Base64ImageForm

View File

@ -1,7 +1,7 @@
from flask_babelex import lazy_gettext
from flask_wtf import FlaskForm
from wtforms import SelectField, StringField, SubmitField
from wtforms.fields.core import BooleanField
from wtforms.fields import BooleanField
from wtforms.validators import DataRequired, Optional
from project.forms.common import event_rating_choices

View File

@ -35,8 +35,8 @@ class ExtendedConfirmRegisterForm(ConfirmRegisterForm):
class ExtendedLoginForm(LoginForm):
def validate(self):
result = super().validate()
def validate(self, **kwargs):
result = super().validate(**kwargs)
if not result and self.requires_confirmation:
flash_message(

View File

@ -3,7 +3,7 @@ from datetime import datetime
from flask_babelex import gettext, to_user_timezone
from markupsafe import Markup
from wtforms import DateTimeField, SelectField, SelectMultipleField
from wtforms.fields.core import StringField
from wtforms.fields import StringField
from wtforms.validators import Length, StopValidation
from wtforms.widgets import CheckboxInput, ListWidget, html_params
@ -164,14 +164,14 @@ class HTML5StringField(StringField):
self,
label=None,
validators=None,
filters=tuple(),
filters=(),
description="",
id=None,
default=None,
widget=None,
render_kw=None,
name=None,
_form=None,
_name=None,
_prefix="",
_translations=None,
_meta=None,
@ -194,8 +194,8 @@ class HTML5StringField(StringField):
default,
widget,
render_kw,
name,
_form,
_name,
_prefix,
_translations,
_meta,

View File

@ -1,4 +1,4 @@
from flask_security import RoleMixin
from flask_security import AsaList, RoleMixin
from sqlalchemy import (
Boolean,
Column,
@ -14,6 +14,7 @@ from sqlalchemy import (
)
from sqlalchemy.event import listens_for
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.ext.mutable import MutableList
from sqlalchemy.orm import aliased, backref, deferred, relationship
from sqlalchemy.orm.relationships import remote
from sqlalchemy.schema import CheckConstraint
@ -37,7 +38,7 @@ class AdminUnitMemberRole(db.Model, RoleMixin):
name = Column(String(80), unique=True)
title = Column(Unicode(255))
description = Column(String(255))
permissions = Column(UnicodeText())
permissions = Column(MutableList.as_mutable(AsaList()), nullable=True)
class AdminUnitMember(db.Model):
@ -299,7 +300,7 @@ class AdminUnit(db.Model, TrackableMixin):
AdminUnitRelation.source_admin_unit_id == SourceAdminUnit.id,
)
return (
select([func.count()])
select(func.count())
.select_from(j)
.where(
and_(
@ -308,7 +309,7 @@ class AdminUnit(db.Model, TrackableMixin):
SourceAdminUnit.can_verify_other,
)
)
.as_scalar()
.scalar_subquery()
> 0
)

View File

@ -91,11 +91,11 @@ class Event(db.Model, TrackableMixin, EventMixin):
@min_start.expression
def min_start(cls):
return (
select([EventDateDefinition.start])
select(EventDateDefinition.start)
.where(EventDateDefinition.event_id == cls.id)
.order_by(EventDateDefinition.start)
.limit(1)
.as_scalar()
.scalar_subquery()
)
@hybrid_property
@ -108,7 +108,7 @@ class Event(db.Model, TrackableMixin, EventMixin):
@is_recurring.expression
def is_recurring(cls):
return (
select([func.count()])
select(func.count())
.select_from(EventDateDefinition.__table__)
.where(
and_(
@ -116,7 +116,7 @@ class Event(db.Model, TrackableMixin, EventMixin):
func.coalesce(EventDateDefinition.recurrence_rule, "") != "",
)
)
.as_scalar()
.scalar_subquery()
) > 0
date_definitions = relationship(

View File

@ -9,8 +9,7 @@ from sqlalchemy import (
Unicode,
UnicodeText,
)
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.orm import relationship
from sqlalchemy.orm import declared_attr, relationship
from project.dbtypes import IntegerEnum
from project.models.functions import create_tsvector

View File

@ -1,8 +1,7 @@
import datetime
from sqlalchemy import Column, DateTime, ForeignKey
from sqlalchemy.ext.declarative import declared_attr
from sqlalchemy.orm import deferred, relationship
from sqlalchemy.orm import declared_attr, deferred, relationship
from project.models.functions import _current_user_id_or_none

View File

@ -1,7 +1,7 @@
import datetime
from flask_dance.consumer.storage.sqla import OAuthConsumerMixin
from flask_security import RoleMixin, UserMixin
from flask_security import AsaList, RoleMixin, UserMixin
from sqlalchemy import (
Boolean,
Column,
@ -10,9 +10,9 @@ from sqlalchemy import (
Integer,
String,
Unicode,
UnicodeText,
UniqueConstraint,
)
from sqlalchemy.ext.mutable import MutableList
from sqlalchemy.orm import backref, deferred, relationship
from project import db
@ -31,7 +31,7 @@ class Role(db.Model, RoleMixin):
name = Column(String(80), unique=True)
title = Column(Unicode(255))
description = Column(String(255))
permissions = Column(UnicodeText())
permissions = Column(MutableList.as_mutable(AsaList()), nullable=True)
class User(db.Model, UserMixin):

View File

@ -118,8 +118,7 @@ def upsert_admin_unit_member_role(role_name, role_title, permissions):
db.session.add(result)
result.title = role_title
result.remove_permissions(result.get_permissions())
result.add_permissions(permissions)
result.permissions = permissions
return result

View File

@ -7,7 +7,14 @@ from flask import url_for
from flask_babelex import format_date, format_time, gettext
from icalendar.prop import vDDDLists
from sqlalchemy import and_, case, func, or_
from sqlalchemy.orm import aliased, contains_eager, defaultload, joinedload, lazyload
from sqlalchemy.orm import (
aliased,
contains_eager,
defaultload,
joinedload,
lazyload,
undefer_group,
)
from sqlalchemy.sql import extract
from project import app, db
@ -194,7 +201,7 @@ def get_event_dates_query(params):
result = (
result.options(
contains_eager(EventDate.event)
joinedload(EventDate.event)
.contains_eager(Event.event_place)
.contains_eager(EventPlace.location),
joinedload(EventDate.event)
@ -216,12 +223,10 @@ def get_event_dates_query(params):
if admin_unit_reference:
result = result.order_by(
case(
[
(
admin_unit_reference.rating.isnot(None),
admin_unit_reference.rating,
),
],
(
admin_unit_reference.rating.isnot(None),
admin_unit_reference.rating,
),
else_=Event.rating,
).desc()
)
@ -238,12 +243,12 @@ def get_event_date_with_details_or_404(event_id):
.join(Event.event_place, isouter=True)
.join(EventPlace.location, isouter=True)
.options(
contains_eager(EventDate.event)
joinedload(EventDate.event)
.contains_eager(Event.event_place)
.contains_eager(EventPlace.location),
joinedload(EventDate.event).undefer_group("trackable"),
# Place
defaultload(EventDate.event)
joinedload(EventDate.event)
.defaultload(Event.event_place)
.joinedload(EventPlace.photo),
# Category
@ -254,19 +259,19 @@ def get_event_date_with_details_or_404(event_id):
joinedload(EventDate.event)
.joinedload(Event.organizer)
.undefer_group("detail")
.undefer("logo_id")
.undefer(EventOrganizer.logo_id)
.joinedload(EventOrganizer.logo),
# Photo
joinedload(EventDate.event).joinedload(Event.photo),
# Admin unit
joinedload(EventDate.event)
.joinedload(Event.admin_unit)
.undefer("logo_id")
.undefer(AdminUnit.logo_id)
.undefer_group("detail")
.undefer_group("widget")
.joinedload(AdminUnit.location),
# Admin unit logo
defaultload(EventDate.event)
joinedload(EventDate.event)
.defaultload(Event.admin_unit)
.joinedload(AdminUnit.logo),
)
@ -277,12 +282,12 @@ def get_event_date_with_details_or_404(event_id):
def get_event_with_details_or_404(event_id):
return (
Event.query.join(EventPlace, isouter=True)
Event.query.join(Event.event_place, isouter=True)
.join(Location, isouter=True)
.options(
contains_eager(Event.event_place).contains_eager(EventPlace.location),
defaultload(Event).undefer_group("trackable"),
undefer_group("trackable"),
# Place
joinedload(Event.event_place).contains_eager(EventPlace.location),
joinedload(Event.event_place).joinedload(EventPlace.photo),
# Category
joinedload(Event.categories).load_only(
@ -291,13 +296,13 @@ def get_event_with_details_or_404(event_id):
# Organizer
joinedload(Event.organizer)
.undefer_group("detail")
.undefer("logo_id")
.undefer(EventOrganizer.logo_id)
.joinedload(EventOrganizer.logo),
# Photo
joinedload(Event.photo),
# Admin unit with location
joinedload(Event.admin_unit)
.undefer("logo_id")
.undefer(AdminUnit.logo_id)
.undefer_group("detail")
.undefer_group("widget")
.joinedload(AdminUnit.location),
@ -635,8 +640,10 @@ def create_ical_events_for_search(
def update_recurring_dates():
from sqlalchemy import text
# Setting the timezone is neccessary for cli command
db.session.execute("SET timezone TO :val;", {"val": berlin_tz.zone})
db.session.execute(text("SET timezone TO :val;"), {"val": berlin_tz.zone})
events = get_recurring_events()

View File

@ -42,8 +42,7 @@ def set_roles_for_user(email, roles):
def upsert_user_role(role_name, role_title, permissions):
role = user_datastore.find_or_create_role(role_name)
role.title = role_title
role.remove_permissions(role.get_permissions())
role.add_permissions(permissions)
role.permissions = permissions
return role

View File

@ -299,6 +299,9 @@ def prepare_event_place(form):
if place:
form.event_place_id.choices = [(place.id, get_place_str(place))]
if not form.event_place_id.choices:
form.event_place_id.choices = []
def prepare_organizer(form):
if form.organizer_id.data and form.organizer_id.data > 0:
@ -313,6 +316,12 @@ def prepare_organizer(form):
).all()
form.co_organizer_ids.choices = [(o.id, o.name) for o in co_organizers]
if not form.organizer_id.choices:
form.organizer_id.choices = []
if not form.co_organizer_ids.choices:
form.co_organizer_ids.choices = []
def prepare_event_form(form):
form.category_ids.choices = get_event_category_choices()

View File

@ -26,6 +26,7 @@ from project.views.utils import (
def prepare_event_date_form(form):
form.category_id.choices = get_event_category_choices()
form.category_id.choices.insert(0, (0, ""))
form.location.choices = []
@app.route("/eventdates")

View File

@ -176,6 +176,8 @@ def manage_admin_unit_events(id):
if form.location.data: # pragma: no cover
form.location.choices = [(form.location.data, form.location_name.data)]
else:
form.location.choices = []
if form.validate():
form.populate_obj(params)

View File

@ -4,6 +4,7 @@ import os.path
from flask import render_template, request, send_from_directory, url_for
from flask_babelex import gettext
from markupsafe import Markup
from sqlalchemy import text
from project import (
app,
@ -40,7 +41,8 @@ def home():
@app.route("/up")
def up():
db.engine.execute("SELECT 1")
with db.engine.connect() as conn:
conn.execute(text("SELECT 1"))
if "REDIS_URL" in app.config and app.config["REDIS_URL"]: # pragma: no cover
celery.control.ping()

View File

@ -305,14 +305,19 @@ class Seeder(object):
def get_event_category_id(self, category_name):
from project.services.event import get_event_category
category = get_event_category(category_name)
with self._app.app_context():
category = get_event_category(category_name)
return category.id
def get_event_date_id(self, event_id):
from project.models import Event
event = Event.query.get(event_id)
return event.dates[0].id
with self._app.app_context():
event = Event.query.get(event_id)
event_date_id = event.dates[0].id
return event_date_id
def create_event(
self,

View File

@ -13,9 +13,11 @@ def test_mail_server():
def drop_db(db):
db.drop_all()
db.engine.execute("DROP TABLE IF EXISTS alembic_version;")
db.engine.execute("DROP TABLE IF EXISTS analytics;")
with db.engine.connect() as conn:
with conn.begin():
db.drop_all()
conn.execute(sqlalchemy.text("DROP TABLE IF EXISTS alembic_version;"))
conn.execute(sqlalchemy.text("DROP TABLE IF EXISTS analytics;"))
def populate_db(db):
@ -33,7 +35,9 @@ BEGIN
INSERT INTO event (name, admin_unit_id, event_place_id, organizer_id, start) VALUES ('Event', admin_unit_id, event_place_id, organizer_id, current_timestamp) RETURNING id INTO event_id;
END $$;
"""
db.engine.execute(sqlalchemy.text(sql).execution_options(autocommit=True))
with db.engine.connect() as conn:
with conn.begin():
conn.execute(sqlalchemy.text(sql).execution_options(autocommit=True))
def test_migrations(app, seeder):
@ -54,6 +58,7 @@ def test_migrations(app, seeder):
seeder.create_event_suggestion(admin_unit_id)
seeder.create_any_reference(admin_unit_id)
seeder.create_reference_request(event_id, admin_unit_id)
db.session.commit()
downgrade()

View File

@ -64,28 +64,28 @@ class UtilActions(object):
response = self._client.get("/login")
assert response.status_code == 200
with self._client:
response = self._client.post(
"/login",
data={
"email": email,
"password": password,
"csrf_token": self.get_csrf(response),
"submit": "Anmelden",
},
follow_redirects=follow_redirects,
)
if follow_redirects:
assert response.status_code == 200
else:
assert response.status_code == 302
assert g.identity.user.email == email
with self._app.app_context():
user = find_user_by_email(email)
user_id = user.id
with self._client:
response = self._client.post(
"/login",
data={
"email": email,
"password": password,
"csrf_token": self.get_csrf(response),
"submit": "Anmelden",
},
follow_redirects=follow_redirects,
)
if follow_redirects:
assert response.status_code == 200
else:
assert response.status_code == 302
assert g.identity.user.email == email
user = find_user_by_email(email)
user_id = user.id
return user_id
@ -300,8 +300,10 @@ class UtilActions(object):
def assert_response_redirect(self, response, endpoint, **values):
assert response.status_code == 302
redirect_url = "http://localhost" + self.get_url(endpoint, **values)
assert response.headers["Location"] == redirect_url
response_location = response.headers["Location"]
redirect_url = self.get_url(endpoint, **values)
absolute_url = "http://localhost" + redirect_url
assert response_location == redirect_url or response_location == absolute_url
def assert_response_contains_alert(self, response, category, message=None):
assert response.status_code == 200

View File

@ -155,8 +155,7 @@ def test_read_decline(client, app, db, utils, seeder):
"decline": "Ablehnen",
},
)
assert response.status_code == 302
assert response.headers["Location"] == "http://localhost/manage"
utils.assert_response_redirect(response, "manage")
with app.app_context():
from project.services.admin_unit import (
@ -211,8 +210,7 @@ def test_read_new_member_not_registered(client, app, utils, seeder):
url = "/invitations/%d" % invitation_id
response = client.get(url)
assert response.status_code == 302
assert response.headers["Location"] == "http://localhost/register"
utils.assert_response_redirect(response, "security.register")
def test_read_new_member_not_authenticated(client, app, utils, seeder):
@ -226,8 +224,7 @@ def test_read_new_member_not_authenticated(client, app, utils, seeder):
url = "/invitations/%d" % invitation_id
response = client.get(url)
assert response.status_code == 302
assert response.headers["Location"].startswith("http://localhost/login")
utils.assert_response_redirect(response, "security.login", next=url)
@pytest.mark.parametrize("user_exists", [True, False])
@ -245,9 +242,8 @@ def test_read_currentUserDoesNotMatchInvitationEmail(
seeder.create_user(email)
url = "/invitations/%d" % invitation_id
environ, response = client.get(url, follow_redirects=True, as_tuple=True)
response = client.get(url, follow_redirects=True)
assert environ["REQUEST_URI"] == "/profile"
utils.assert_response_ok(response)
utils.assert_response_contains(
response, "Die Einladung wurde für einen anderen Nutzer ausgestellt."

View File

@ -25,8 +25,7 @@ def test_organization_invitation_not_authenticated(client, app, utils, seeder):
seeder.create_user("invited@test.de")
url = utils.get_url("user_organization_invitation", id=invitation_id)
response = client.get(url)
assert response.status_code == 302
assert response.headers["Location"].startswith("http://localhost/login")
utils.assert_response_redirect(response, "security.login", next=url)
@pytest.mark.parametrize("user_exists", [True, False])
@ -40,9 +39,8 @@ def test_organization_invitation_currentUserDoesNotMatchInvitationEmail(
seeder.create_user("invited@test.de")
url = utils.get_url("user_organization_invitation", id=invitation_id)
environ, response = client.get(url, follow_redirects=True, as_tuple=True)
response = client.get(url, follow_redirects=True)
assert environ["REQUEST_URI"] == "/profile"
utils.assert_response_ok(response)
utils.assert_response_contains(
response, "Die Einladung wurde für einen anderen Nutzer ausgestellt."