def test_simple_file_input_exceptions(web_fixture): """Usually, when a DomainException happens during a form submit Inputs save the input they received so that such input can be pre-populated on the screen rendered by a subsequent GET for a user to correct possible mistakes and resubmit. In the case of a SimpleFileInput however, the UploadedFile objects that serve as user input to a SimpleFileInput are discarded when a DomainException happens. This is because it is not possible to prepopulate its value using HTML or JS as this would be a security risk. """ file_to_upload = temp_file_with('some content') failing_constraint = FailingConstraint('I am breaking') class DomainObject: def __init__(self): self.file = None @exposed def fields(self, fields): fields.file = FileField(allow_multiple=False, label='Attached files') # FailingConstraint is declared in module level scope for it to be pickleable fields.file.add_validation_constraint(failing_constraint) @exposed def events(self, events): events.upload = Event(label='Upload') domain_object = DomainObject() class FileUploadForm(Form): def __init__(self, view): super().__init__(view, 'test') file_input = self.add_child( SimpleFileInput(self, domain_object.fields.file)) if file_input.validation_error: self.add_child(self.create_error_label(file_input)) self.define_event_handler(domain_object.events.upload) self.add_child(ButtonInput(self, domain_object.events.upload)) wsgi_app = web_fixture.new_wsgi_app(child_factory=FileUploadForm.factory(), enable_js=False) web_fixture.reahl_server.set_app(wsgi_app) browser = web_fixture.driver_browser browser.open('/') browser.type(XPath.input_of_type('file'), file_to_upload.name) browser.click(XPath.button_labelled('Upload')) assert browser.is_element_present('//label[text()="I am breaking"]') # Message is cleared on second attempt failing_constraint.fail = False browser.type(XPath.input_of_type('file'), file_to_upload.name) browser.click(XPath.button_labelled('Upload')) assert not browser.is_element_present('//label[text()="I am breaking"]')
def test_simple_file_input(web_fixture): """A SimpleFileInput is a Widget with which a user can choose one or more files. The SimpleFileInput transforms the chosen files to UploadedFile objects, and passes these to its associated FileField upon a Form submit.""" expected_content = b'some content' file_to_upload = temp_file_with(expected_content, mode='w+b') class DomainObject: def __init__(self): self.file = None @exposed def fields(self, fields): fields.file = FileField(allow_multiple=False, label='Attached files') @exposed def events(self, events): events.upload = Event(label='Upload') domain_object = DomainObject() class FileUploadForm(Form): def __init__(self, view): super().__init__(view, 'test') self.add_child(SimpleFileInput(self, domain_object.fields.file)) self.define_event_handler(domain_object.events.upload) self.add_child(ButtonInput(self, domain_object.events.upload)) wsgi_app = web_fixture.new_wsgi_app(child_factory=FileUploadForm.factory(), enable_js=False) web_fixture.reahl_server.set_app(wsgi_app) browser = web_fixture.driver_browser browser.open('/') browser.type(XPath.input_of_type('file'), file_to_upload.name) browser.click(XPath.button_labelled('Upload')) assert isinstance(domain_object.file, UploadedFile) assert domain_object.file.filename == os.path.basename(file_to_upload.name) with domain_object.file.open() as opened_file: read_contents = opened_file.read() assert read_contents == expected_content