Library updates #432

This commit is contained in:
Daniel Grams 2023-04-17 08:18:21 +02:00
parent 84b21f28bd
commit 45e6334076
9 changed files with 34 additions and 28 deletions

View File

@ -63,7 +63,7 @@ jobs:
pip install -r requirements.txt pip install -r requirements.txt
- name: Run tests - name: Run tests
run: pytest --log-cli-level=DEBUG --cov=project --splits 4 --group ${{ matrix.group }} run: pytest --cov=project --splits 4 --group ${{ matrix.group }}
env: env:
TEST_DATABASE_URL: postgresql://postgres:postgres@localhost/eventcally_tests TEST_DATABASE_URL: postgresql://postgres:postgres@localhost/eventcally_tests
TEST_REDIS_URL: redis://localhost:6379 TEST_REDIS_URL: redis://localhost:6379

View File

@ -1,6 +1,6 @@
describe("Event", () => { describe("Event", () => {
[{ recurrence: false }, { recurrence: true }].forEach(function (test) { [{ recurrence: false }, { recurrence: true }].forEach(function (test) {
it("creates event with recurrence=" + test.recurrence, () => { it.only("creates event with recurrence=" + test.recurrence, () => {
cy.login(); cy.login();
cy.createAdminUnit().then(function (adminUnitId) { cy.createAdminUnit().then(function (adminUnitId) {
cy.visit("/admin_unit/" + adminUnitId + "/events/create"); cy.visit("/admin_unit/" + adminUnitId + "/events/create");
@ -48,7 +48,7 @@ describe("Event", () => {
}); });
}); });
it("saves draft", () => { it.only("saves draft", () => {
cy.login(); cy.login();
cy.createAdminUnit().then(function (adminUnitId) { cy.createAdminUnit().then(function (adminUnitId) {
cy.visit("/admin_unit/" + adminUnitId + "/events/create"); cy.visit("/admin_unit/" + adminUnitId + "/events/create");

View File

@ -88,11 +88,11 @@ class EventBaseSchemaMixin(TrackableSchemaMixin):
} }
) )
kid_friendly = marshmallow.auto_field( kid_friendly = marshmallow.auto_field(
missing=False, load_default=False,
metadata={"description": "If the event is particularly suitable for children."}, metadata={"description": "If the event is particularly suitable for children."},
) )
accessible_for_free = marshmallow.auto_field( accessible_for_free = marshmallow.auto_field(
missing=False, load_default=False,
metadata={"description": "If the event is accessible for free."}, metadata={"description": "If the event is accessible for free."},
) )
age_from = marshmallow.auto_field( age_from = marshmallow.auto_field(
@ -103,19 +103,19 @@ class EventBaseSchemaMixin(TrackableSchemaMixin):
) )
target_group_origin = EnumField( target_group_origin = EnumField(
EventTargetGroupOrigin, EventTargetGroupOrigin,
missing=EventTargetGroupOrigin.both, load_default=EventTargetGroupOrigin.both,
metadata={ metadata={
"description": "Whether the event is particularly suitable for tourists or residents." "description": "Whether the event is particularly suitable for tourists or residents."
}, },
) )
attendance_mode = EnumField( attendance_mode = EnumField(
EventAttendanceMode, EventAttendanceMode,
missing=EventAttendanceMode.offline, load_default=EventAttendanceMode.offline,
metadata={"description": "Choose how people can attend the event."}, metadata={"description": "Choose how people can attend the event."},
) )
status = EnumField( status = EnumField(
EventStatus, EventStatus,
missing=EventStatus.scheduled, load_default=EventStatus.scheduled,
metadata={"description": "Select the status of the event."}, metadata={"description": "Select the status of the event."},
) )
previous_start_date = CustomDateTimeField( previous_start_date = CustomDateTimeField(
@ -124,13 +124,13 @@ class EventBaseSchemaMixin(TrackableSchemaMixin):
}, },
) )
registration_required = marshmallow.auto_field( registration_required = marshmallow.auto_field(
missing=False, load_default=False,
metadata={ metadata={
"description": "If the participants needs to register for the event." "description": "If the participants needs to register for the event."
}, },
) )
booked_up = marshmallow.auto_field( booked_up = marshmallow.auto_field(
missing=False, load_default=False,
metadata={"description": "If the event is booked up or sold out."}, metadata={"description": "If the event is booked up or sold out."},
) )
expected_participants = marshmallow.auto_field( expected_participants = marshmallow.auto_field(
@ -143,7 +143,7 @@ class EventBaseSchemaMixin(TrackableSchemaMixin):
) )
public_status = EnumField( public_status = EnumField(
PublicStatus, PublicStatus,
missing=PublicStatus.published, load_default=PublicStatus.published,
metadata={"description": "Public status of the event."}, metadata={"description": "Public status of the event."},
) )
@ -296,8 +296,8 @@ class EventWriteSchemaMixin(object):
metadata={"description": "Categories that fit the event."}, metadata={"description": "Categories that fit the event."},
) )
rating = marshmallow.auto_field( rating = marshmallow.auto_field(
missing=50, load_default=50,
default=50, dump_default=50,
validate=validate.OneOf([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]), validate=validate.OneOf([0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100]),
metadata={ metadata={
"description": "How relevant the event is to your organization. 0 (Little relevant), 50 (Default), 100 (Highlight)." "description": "How relevant the event is to your organization. 0 (Little relevant), 50 (Default), 100 (Highlight)."
@ -322,7 +322,7 @@ class EventPostRequestSchema(
date_definitions = fields.List( date_definitions = fields.List(
fields.Nested(EventDateDefinitionPostRequestSchema), fields.Nested(EventDateDefinitionPostRequestSchema),
default=None, dump_default=None,
required=True, required=True,
validate=[validate.Length(min=1)], validate=[validate.Length(min=1)],
metadata={"description": "At least one date definition."}, metadata={"description": "At least one date definition."},
@ -339,7 +339,7 @@ class EventPatchRequestSchema(
date_definitions = fields.List( date_definitions = fields.List(
fields.Nested(EventDateDefinitionPatchRequestSchema), fields.Nested(EventDateDefinitionPatchRequestSchema),
default=None, dump_default=None,
required=True, required=True,
validate=[validate.Length(min=1)], validate=[validate.Length(min=1)],
metadata={"description": "At least one date definition."}, metadata={"description": "At least one date definition."},
@ -370,6 +370,6 @@ class EventImportRequestSchema(marshmallow.Schema):
) )
public_status = EnumField( public_status = EnumField(
PublicStatus, PublicStatus,
missing=PublicStatus.published, load_default=PublicStatus.published,
metadata={"description": "Public status of the event."}, metadata={"description": "Public status of the event."},
) )

View File

@ -36,7 +36,7 @@ class EventDateDefinitionBaseSchemaMixin(object):
}, },
) )
allday = fields.Bool( allday = fields.Bool(
missing=False, load_default=False,
metadata={"description": "If the event is an all-day event."}, metadata={"description": "If the event is an all-day event."},
) )
recurrence_rule = fields.Str( recurrence_rule = fields.Str(

View File

@ -25,7 +25,7 @@ class SQLAlchemyBaseSchema(marshmallow.SQLAlchemySchema):
class IdSchemaMixin(object): class IdSchemaMixin(object):
id = marshmallow.auto_field(dump_only=True, default=missing) id = marshmallow.auto_field(dump_only=True, dump_default=missing)
class WriteIdSchemaMixin(object): class WriteIdSchemaMixin(object):
@ -60,13 +60,13 @@ class UnprocessableEntityResponseSchema(ErrorResponseSchema):
class PaginationRequestSchema(marshmallow.Schema): class PaginationRequestSchema(marshmallow.Schema):
page = fields.Integer( page = fields.Integer(
required=False, required=False,
default=1, dump_default=1,
validate=validate.Range(min=1), validate=validate.Range(min=1),
metadata={"description": "The page number (1 indexed)."}, metadata={"description": "The page number (1 indexed)."},
) )
per_page = fields.Integer( per_page = fields.Integer(
required=False, required=False,
default=20, dump_default=20,
validate=validate.Range(min=1, max=50), validate=validate.Range(min=1, max=50),
metadata={"description": "Items per page"}, metadata={"description": "Items per page"},
) )

View File

@ -4,7 +4,7 @@ import click
from flask.cli import AppGroup from flask.cli import AppGroup
from flask_migrate import stamp from flask_migrate import stamp
from flask_security.confirmable import confirm_user from flask_security.confirmable import confirm_user
from sqlalchemy import MetaData from sqlalchemy import MetaData, text
from project import app, db from project import app, db
from project.api import scope_list from project.api import scope_list
@ -75,14 +75,15 @@ def _create_user(
@test_cli.command("reset") @test_cli.command("reset")
@click.option("--seed/--no-seed", default=False) @click.option("--seed/--no-seed", default=False)
def reset(seed): def reset(seed):
meta = MetaData(bind=db.engine, reflect=True) meta = MetaData()
meta.reflect(db.engine)
con = db.engine.connect() con = db.engine.connect()
trans = con.begin() trans = con.begin()
for table in meta.sorted_tables: for table in meta.sorted_tables:
con.execute(f'ALTER TABLE "{table.name}" DISABLE TRIGGER ALL;') con.execute(text(f'ALTER TABLE "{table.name}" DISABLE TRIGGER ALL;'))
con.execute(table.delete()) con.execute(table.delete())
con.execute(f'ALTER TABLE "{table.name}" ENABLE TRIGGER ALL;') con.execute(text(f'ALTER TABLE "{table.name}" ENABLE TRIGGER ALL;'))
trans.commit() trans.commit()

View File

@ -35,6 +35,10 @@ class ExtendedConfirmRegisterForm(ConfirmRegisterForm):
class ExtendedLoginForm(LoginForm): class ExtendedLoginForm(LoginForm):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self._fields["email"].flags.required = True
def validate(self, **kwargs): def validate(self, **kwargs):
result = super().validate(**kwargs) result = super().validate(**kwargs)

View File

@ -26,13 +26,14 @@ class CustomDateTimeWidget:
time = date_value.strftime("%H:%M") time = date_value.strftime("%H:%M")
kwargs_class = kwargs.pop("class", "") kwargs_class = kwargs.pop("class", "")
required = True if field.flags.required else False
date_class = kwargs_class + " datepicker" date_class = kwargs_class + " datepicker"
date_params = html_params( date_params = html_params(
name=field.name, name=field.name,
id=id, id=id,
value=date, value=date,
required=field.flags.required, required=required,
class_=date_class, class_=date_class,
**kwargs **kwargs
) )
@ -42,7 +43,7 @@ class CustomDateTimeWidget:
name=field.name, name=field.name,
id=id + "-time", id=id + "-time",
value=time, value=time,
required=field.flags.required, required=required,
class_=time_class, class_=time_class,
**kwargs **kwargs
) )

View File

@ -54,14 +54,14 @@ def resize_image_to_min(image: PIL.Image) -> PIL.Image:
width = int(math.ceil(image.width * ratio)) width = int(math.ceil(image.width * ratio))
height = int(math.ceil(image.height * ratio)) height = int(math.ceil(image.height * ratio))
format = image.format format = image.format
result = image.resize((width, height), PIL.Image.LANCZOS) result = image.resize((width, height), PIL.Image.Resampling.LANCZOS)
result.format = format result.format = format
return result return result
def resize_image_to_max(image: PIL.Image): def resize_image_to_max(image: PIL.Image):
if image.width > max_image_size or image.height > max_image_size: if image.width > max_image_size or image.height > max_image_size:
image.thumbnail((max_image_size, max_image_size), PIL.Image.ANTIALIAS) image.thumbnail((max_image_size, max_image_size), PIL.Image.Resampling.LANCZOS)
def validate_image(image: PIL.Image): def validate_image(image: PIL.Image):