You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
119 lines
4.1 KiB
Python
119 lines
4.1 KiB
Python
# Copyright (c) Jupyter Development Team.
|
|
# Distributed under the terms of the Modified BSD License.
|
|
|
|
import datetime as dt
|
|
from unittest import TestCase
|
|
from unittest.mock import MagicMock
|
|
|
|
from traitlets import TraitError
|
|
|
|
from ipywidgets import FileUpload
|
|
|
|
|
|
FILE_UPLOAD_FRONTEND_CONTENT = {
|
|
'name': 'file-name.txt',
|
|
'type': 'text/plain',
|
|
'size': 20760,
|
|
'last_modified': 1578578296434,
|
|
'content': memoryview(b'file content'),
|
|
}
|
|
|
|
|
|
class TestFileUpload(TestCase):
|
|
|
|
def test_construction(self):
|
|
uploader = FileUpload()
|
|
# Default
|
|
assert uploader.accept == ''
|
|
assert not uploader.multiple
|
|
assert not uploader.disabled
|
|
|
|
def test_construction_with_params(self):
|
|
uploader = FileUpload(
|
|
accept='.txt', multiple=True, disabled=True)
|
|
assert uploader.accept == '.txt'
|
|
assert uploader.multiple
|
|
assert uploader.disabled
|
|
|
|
def test_empty_initial_value(self):
|
|
uploader = FileUpload()
|
|
assert uploader.value == ()
|
|
|
|
def test_receive_single_file(self):
|
|
uploader = FileUpload()
|
|
message = {'value': [FILE_UPLOAD_FRONTEND_CONTENT]}
|
|
uploader.set_state(message)
|
|
assert len(uploader.value) == 1
|
|
(uploaded_file,) = uploader.value
|
|
assert uploaded_file.name == 'file-name.txt'
|
|
assert uploaded_file.type == 'text/plain'
|
|
assert uploaded_file.size == 20760
|
|
assert uploaded_file.content.tobytes() == b'file content'
|
|
assert (
|
|
uploaded_file.last_modified ==
|
|
dt.datetime(2020, 1, 9, 13, 58, 16, 434000, tzinfo=dt.timezone.utc)
|
|
)
|
|
|
|
def test_receive_multiple_files(self):
|
|
uploader = FileUpload(multiple=True)
|
|
message = {
|
|
'value': [
|
|
FILE_UPLOAD_FRONTEND_CONTENT,
|
|
{**FILE_UPLOAD_FRONTEND_CONTENT, **{'name': 'other-file-name.txt'}}
|
|
]
|
|
}
|
|
uploader.set_state(message)
|
|
assert len(uploader.value) == 2
|
|
assert uploader.value[0].name == 'file-name.txt'
|
|
assert uploader.value[1].name == 'other-file-name.txt'
|
|
|
|
def test_serialization_deserialization_integrity(self):
|
|
# The value traitlet needs to remain unchanged following
|
|
# a serialization / deserialization roundtrip, otherwise
|
|
# the kernel dispatches it back to the frontend following
|
|
# a state change, because it doesn't recognize that the
|
|
# property_lock entry is the same as the new value.
|
|
from ipykernel.comm import Comm
|
|
uploader = FileUpload()
|
|
mock_comm = MagicMock(spec=Comm)
|
|
mock_comm.send = MagicMock()
|
|
mock_comm.kernel = 'does not matter'
|
|
uploader.comm = mock_comm
|
|
message = {'value': [FILE_UPLOAD_FRONTEND_CONTENT]}
|
|
uploader.set_state(message)
|
|
|
|
# Check that no message is sent back to the frontend
|
|
# as a result of setting the state.
|
|
mock_comm.send.assert_not_called()
|
|
|
|
def test_resetting_value(self):
|
|
# Simulate an upload, then resetting the value from the
|
|
# kernel.
|
|
uploader = FileUpload()
|
|
message = {'value': [FILE_UPLOAD_FRONTEND_CONTENT]}
|
|
uploader.set_state(message)
|
|
|
|
uploader.value = [] # reset value to an empty file list
|
|
|
|
assert uploader.get_state(key='value') == {'value': []}
|
|
|
|
def test_setting_non_empty_value(self):
|
|
# Simulate user setting a value for the upload from the kernel.
|
|
uploader = FileUpload()
|
|
content = memoryview(b'some content')
|
|
uploader.value = [{
|
|
'name': 'some-name.txt',
|
|
'type': 'text/plain',
|
|
'size': 561,
|
|
'last_modified': dt.datetime(2020, 1, 9, 13, 58, 16, 434000, tzinfo=dt.timezone.utc),
|
|
'content': content
|
|
}]
|
|
state = uploader.get_state(key='value')
|
|
assert len(state['value']) == 1
|
|
[entry] = state['value']
|
|
assert entry['name'] == 'some-name.txt'
|
|
assert entry['type'] == 'text/plain'
|
|
assert entry['size'] == 561
|
|
assert entry['last_modified'] == 1578578296434
|
|
assert entry['content'] == content
|