Won't store validation results in the controller.

Instead the form itself keeps track of the active async task.
The validation state is returned from the task object itself.
This commit is contained in:
Carlos Nihelton 2022-05-11 16:12:37 -03:00
parent 888eb344a2
commit f576c6fc85
No known key found for this signature in database
GPG Key ID: 6FE346D245197E9A
3 changed files with 31 additions and 13 deletions

View File

@ -50,9 +50,5 @@ class IdentityController(SubiquityTuiController):
identity_data) identity_data)
self.app.next_screen(self.endpoint.POST(identity_data)) self.app.next_screen(self.endpoint.POST(identity_data))
async def _validate_username(self, username): async def validate_username(self, username):
self.username_validation = \ return await self.endpoint.validate_username.GET(username)
await self.endpoint.validate_username.GET(username)
def validate_username(self, _, value):
self.app.aio_loop.create_task(self._validate_username(value))

View File

@ -20,6 +20,7 @@ import re
from urwid import ( from urwid import (
connect_signal, connect_signal,
) )
from subiquitycore.async_helpers import schedule_task
from subiquitycore.ui.interactive import ( from subiquitycore.ui.interactive import (
PasswordEditor, PasswordEditor,
@ -85,9 +86,10 @@ class IdentityForm(Form):
def __init__(self, controller, initial): def __init__(self, controller, initial):
self.controller = controller self.controller = controller
self.validation_task = None
super().__init__(initial=initial) super().__init__(initial=initial)
connect_signal(self.username.widget, 'change', connect_signal(self.username.widget, 'change',
controller.validate_username) self.on_username_change)
realname = RealnameField(_("Your name:")) realname = RealnameField(_("Your name:"))
hostname = UsernameField( hostname = UsernameField(
@ -97,6 +99,23 @@ class IdentityForm(Form):
password = PasswordField(_("Choose a password:")) password = PasswordField(_("Choose a password:"))
confirm_password = PasswordField(_("Confirm your password:")) confirm_password = PasswordField(_("Confirm your password:"))
def on_username_change(self, _, value):
if len(value) < 2:
return
if self.validation_task is not None:
self.validation_task.cancel()
self.validation_task = \
schedule_task(self.controller.validate_username(value))
def username_validation_state(self):
task = self.validation_task
if task is None or not task.done():
return UsernameValidation.OK
return task.result()
def validate_realname(self): def validate_realname(self):
if len(self.realname.value) > REALNAME_MAXLEN: if len(self.realname.value) > REALNAME_MAXLEN:
return _( return _(
@ -118,7 +137,6 @@ class IdentityForm(Form):
def validate_username(self): def validate_username(self):
username = self.username.value username = self.username.value
state = self.controller.username_validation
if len(username) < 1: if len(username) < 1:
return _("Username missing") return _("Username missing")
@ -131,6 +149,7 @@ class IdentityForm(Form):
return _( return _(
"Username must match USERNAME_REGEX: " + USERNAME_REGEX) "Username must match USERNAME_REGEX: " + USERNAME_REGEX)
state = self.username_validation_state()
if state == UsernameValidation.SYSTEM_RESERVED: if state == UsernameValidation.SYSTEM_RESERVED:
return _( return _(
'The username "{username}" is reserved for use by the system.' 'The username "{username}" is reserved for use by the system.'

View File

@ -1,3 +1,4 @@
import asyncio
import unittest import unittest
from unittest import mock from unittest import mock
@ -65,22 +66,24 @@ class IdentityViewTests(unittest.TestCase):
view_helpers.enter_data(view.form, valid_data) view_helpers.enter_data(view.form, valid_data)
self.assertTrue(view.form.done_btn.enabled) self.assertTrue(view.form.done_btn.enabled)
def test_username_validation_system_reserved(self): async def test_username_validation_system_reserved(self):
view = self.make_view() view = self.make_view()
view.controller.username_validation = \ view.controller.validate_username.return_value = \
UsernameValidation.SYSTEM_RESERVED UsernameValidation.SYSTEM_RESERVED
view_helpers.enter_data(view.form, system_reserved) view_helpers.enter_data(view.form, system_reserved)
await asyncio.wait(view.form.validation_task)
self.assertFalse(view.form.done_btn.enabled) self.assertFalse(view.form.done_btn.enabled)
def test_username_validation_in_use(self): async def test_username_validation_in_use(self):
view = self.make_view() view = self.make_view()
view.controller.username_validation = UsernameValidation.ALREADY_IN_USE view.controller.validate_username.return_value = \
UsernameValidation.ALREADY_IN_USE
view_helpers.enter_data(view.form, already_taken) view_helpers.enter_data(view.form, already_taken)
await asyncio.wait(view.form.validation_task)
self.assertFalse(view.form.done_btn.enabled) self.assertFalse(view.form.done_btn.enabled)
def test_username_validation_too_long(self): def test_username_validation_too_long(self):
view = self.make_view() view = self.make_view()
view.controller.username_validation = UsernameValidation.TOO_LONG
view_helpers.enter_data(view.form, too_long) view_helpers.enter_data(view.form, too_long)
self.assertFalse(view.form.done_btn.enabled) self.assertFalse(view.form.done_btn.enabled)