Skip to content

Commit 00f36f6

Browse files
authored
Fix/maintenance date validation (#137)
Fix/maintenance date validation Fixed issues with checking maintenance end time Black-formatter changes Reviewed-by: Vladimir Hasko <[email protected]>
1 parent 9395456 commit 00f36f6

File tree

2 files changed

+68
-65
lines changed

2 files changed

+68
-65
lines changed

app/web/forms.py

Lines changed: 31 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -273,31 +273,44 @@ class IncidentForm(FlaskForm):
273273
validators=[validators.DataRequired()],
274274
format="%Y-%m-%dT%H:%M",
275275
)
276-
incident_end = DateTimeField("End", format="%Y-%m-%dT%H:%M")
276+
incident_end = DateTimeField(
277+
"End",
278+
validators=[validators.DataRequired()],
279+
format="%Y-%m-%dT%H:%M",
280+
)
277281
timezone = StringField("Timezone", validators=[validators.DataRequired()])
278282

279283
submit = SubmitField("Submit")
280284

285+
def __init__(self, *args, **kwargs):
286+
super().__init__(*args, **kwargs)
287+
288+
if self.incident_impact.data == "0":
289+
self.incident_end.validators = [validators.DataRequired()]
290+
else:
291+
self.incident_end.validators = [validators.Optional()]
292+
281293
def validate_incident_start(self, field):
294+
if not field.data:
295+
raise validators.ValidationError("Start date is required")
296+
282297
start_date_form = naive_from_dttz(
283-
self.incident_start.data,
298+
field.data,
284299
self.timezone.data,
285300
)
286-
if (
287-
self.incident_impact.data != "0"
288-
and start_date_form > naive_utcnow()
289-
):
290-
raise validators.ValidationError(
291-
"Start date of incident cannot be in the future"
292-
)
293301

294-
def validate_incident_end(self, field):
295-
if self.incident_impact.data == "0" and field.data is None:
296-
raise validators.ValidationError(
297-
"Expected end date field is mandatory for maintenance"
302+
if self.incident_impact.data and self.incident_impact.data != "0":
303+
if start_date_form > naive_utcnow():
304+
raise validators.ValidationError(
305+
"Start date of incident cannot be in the future"
306+
)
307+
elif self.incident_impact.data == "0" and self.incident_end.data:
308+
# For maintenance, validate against end date
309+
end_date_form = naive_from_dttz(
310+
self.incident_end.data,
311+
self.timezone.data,
298312
)
299-
elif self.incident_impact.data != "0" and field.data is None:
300-
# Making field optional requres dropping "Not a valid datetime
301-
# value." error as well
302-
field.errors[:] = []
303-
raise validators.StopValidation()
313+
if start_date_form >= end_date_form:
314+
raise validators.ValidationError(
315+
"Start date cannot be later than or equal to the end date"
316+
)

app/web/routes.py

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,7 @@
4040

4141
@bp.route("/", methods=["GET"])
4242
@bp.route("/index", methods=["GET"])
43-
@cache.cached(unless=lambda: "user" in session,
44-
key_prefix="/index"
45-
)
43+
@cache.cached(unless=lambda: "user" in session, key_prefix="/index")
4644
def index():
4745
return render_template(
4846
"index.html",
@@ -84,10 +82,14 @@ def update_incident(
8482
def form_submission(form, incident):
8583
new_impact = form.update_impact.data
8684
new_status = form.update_status.data
87-
update_date = naive_from_dttz(
88-
form.update_date.data,
89-
form.timezone.data,
90-
) if form.update_date.data else None
85+
update_date = (
86+
naive_from_dttz(
87+
form.update_date.data,
88+
form.timezone.data,
89+
)
90+
if form.update_date.data
91+
else None
92+
)
9193

9294
redirect_path_map = {
9395
"completed": "/history",
@@ -181,7 +183,6 @@ def new_incident(current_user):
181183
incident_components = [
182184
comp for comp in all_components if comp.id in selected_components
183185
]
184-
185186
new_incident = Incident(
186187
text=form.incident_text.data,
187188
impact=form.incident_impact.data,
@@ -225,21 +226,15 @@ def new_incident(current_user):
225226
comp_name = comp.name
226227
comp_attributes = comp.attributes
227228
comp_attributes_str = ", ".join(
228-
[
229-
f"{attr.value}" for attr in comp_attributes
230-
]
229+
[f"{attr.value}" for attr in comp_attributes]
231230
)
232231
comp_with_attrs = (
233-
f"{comp_name} "
234-
f"({comp_attributes_str})")
235-
url_s = url_for(
236-
'web.incident',
237-
incident_id=inc.id
232+
f"{comp_name} " f"({comp_attributes_str})"
238233
)
234+
url_s = url_for("web.incident", incident_id=inc.id)
239235
link_s = f"<a href='{url_s}'>{inc.text}</a>"
240236
url_d = url_for(
241-
'web.incident',
242-
incident_id=new_incident.id
237+
"web.incident", incident_id=new_incident.id
243238
)
244239
link_d = f"<a href='{url_d}'>{new_incident.text}</a>"
245240
update_s = f"{comp_with_attrs} moved to {link_d}"
@@ -253,13 +248,16 @@ def new_incident(current_user):
253248
messages_to.append("Incident closed by system")
254249
inc.end_date = naive_utcnow()
255250
if messages_to:
256-
update_incident(inc, ', '.join(messages_to))
251+
update_incident(inc, ", ".join(messages_to))
257252
if messages_from:
258-
update_incident(new_incident, ', '.join(messages_from))
253+
update_incident(new_incident, ", ".join(messages_from))
259254
db.session.commit()
260255

261-
return (redirect("/") if new_incident.impact != 0
262-
else redirect("/incidents/" + str(new_incident.id)))
256+
return (
257+
redirect("/")
258+
if new_incident.impact != 0
259+
else redirect("/incidents/" + str(new_incident.id))
260+
)
263261

264262
return render_template(
265263
"create_incident.html",
@@ -287,7 +285,10 @@ def incident(incident_id):
287285
end_date = None
288286
updates = incident.updates
289287
updates_ts = [
290-
u.timestamp for u in updates if u.status not in [
288+
u.timestamp
289+
for u in updates
290+
if u.status
291+
not in [
291292
"resolved",
292293
"description",
293294
"changed",
@@ -317,11 +318,14 @@ def incident(incident_id):
317318
form.update_status.choices = [
318319
(k, v)
319320
for (k, v) in current_app.config.get(
320-
"INCIDENT_ACTIONS"
321-
if incident.end_date and incident.impact != 0 else (
322-
"MAINTENANCE_STATUSES"
323-
if incident.impact == 0
324-
else "INCIDENT_STATUSES"
321+
(
322+
"INCIDENT_ACTIONS"
323+
if incident.end_date and incident.impact != 0
324+
else (
325+
"MAINTENANCE_STATUSES"
326+
if incident.impact == 0
327+
else "INCIDENT_STATUSES"
328+
)
325329
),
326330
{},
327331
).items()
@@ -367,34 +371,20 @@ def separate_incident(current_user, incident_id, component_id):
367371
comp_name = component.name
368372
comp_attributes = component.attributes
369373
comp_attributes_str = ", ".join(
370-
[
371-
f"{attr.value}" for attr in comp_attributes
372-
]
374+
[f"{attr.value}" for attr in comp_attributes]
373375
)
374376
comp_with_attrs = f"{comp_name} ({comp_attributes_str})"
375377

376-
url_s = url_for(
377-
'web.incident',
378-
incident_id=incident.id
379-
)
378+
url_s = url_for("web.incident", incident_id=incident.id)
380379
link_s = f"<a href='{url_s}'>{incident.text}</a>"
381-
url_d = url_for(
382-
'web.incident',
383-
incident_id=new_incident.id
384-
)
380+
url_d = url_for("web.incident", incident_id=new_incident.id)
385381
link_d = f"<a href='{url_d}'>{new_incident.text}</a>"
386382

387383
update_s = f"{comp_with_attrs} moved to {link_d}"
388384
update_n = f"{comp_with_attrs} moved from {link_s}"
389385

390-
update_incident(
391-
incident,
392-
update_s
393-
)
394-
update_incident(
395-
new_incident,
396-
update_n
397-
)
386+
update_incident(incident, update_s)
387+
update_incident(new_incident, update_n)
398388
db.session.commit()
399389
return redirect("/")
400390

0 commit comments

Comments
 (0)