mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
Library updates #432
This commit is contained in:
parent
84b21f28bd
commit
45e6334076
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@ -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
|
||||||
|
|||||||
@ -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");
|
||||||
|
|||||||
@ -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."},
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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(
|
||||||
|
|||||||
@ -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"},
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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()
|
||||||
|
|
||||||
|
|||||||
@ -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)
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user