Example #1
0
def test_parse_parts_with_head_boundary():
    bndry = '---boundary---'
    part_bndry = bytes('--' + bndry + '\r\n', 'ascii')
    file_bndry = bytes('--' + bndry + '--\r\n', 'ascii')
    # head boundary - announce part
    assert mhtml.parse_parts(b'\r\n' + part_bndry +
                             b'CH: CV\r\n\r\n'
                             b'content\r\n', bndry, 2) \
        == ([(mhtml.ResourceHeader([('CH', 'CV')]),
              20, 30, 39)], -1)

    # TODO: work with monkeypatching?

    # TODO: should recognize empty part?
    # something like first part, then another follows but is somewhat vague ...
    assert mhtml.parse_parts(b'\r\n' + part_bndry +
                             b'CH: CV\r\n\r\n'
                             b'content\r\n'
                             + part_bndry, bndry, 2) \
        == ([(mhtml.ResourceHeader([('CH', 'CV')]),
              20, 30, 39),
             (mhtml.ResourceHeader(),
              57, -1, 57)], -1)

    # single part (use-case: last-part before file boundary)
    assert mhtml.parse_parts(b'\r\n' + part_bndry +
                             b'CH: CV\r\n\r\n'
                             b'content\r\n'
                             + file_bndry, bndry, 0) \
        == ([(mhtml.ResourceHeader([('CH', 'CV')]),
              20, 30, 39)], -1)
Example #2
0
def test_MHTMLArchive_properties(mocker):  # noqa: N802
    mhtarc = mhtml.MHTMLArchive(b'content', mhtml.ResourceHeader(), 0,
                                '---boundary---')
    assert mhtarc.headers == mhtml.ResourceHeader()
    mhtarc = mhtml.MHTMLArchive(b'content', None, 0, '---boundary---')
    assert mhtarc.headers == mhtml.ResourceHeader()

    mock_headers = mocker.Mock(content_type='content-abc',
                               location='location-abc')
    mhtarc._headers = mock_headers
    assert mhtarc.headers == mock_headers
    assert mhtarc.content_type == 'content-abc'
    assert mhtarc.location == 'location-abc'
    assert mhtarc.boundary == '---boundary---'

    assert mhtarc.content == b'content'

    # WIP no boundary? - may need to create one
    mock_method = mocker.patch('mhtml.get_boundary', return_value=None)
    mock_headers = mocker.Mock(spec=mhtml.ResourceHeader)
    mhtarc = mhtml.MHTMLArchive(b'content', mock_headers, 0, None)
    assert mhtarc.boundary is None
    mock_method.assert_called_once_with(mock_headers)
    # check if in headers
    mocker.patch('mhtml.get_boundary', return_value=mocker.sentinel.bndry)
    mhtarc = mhtml.MHTMLArchive(b'content', mhtml.ResourceHeader(), 0, None)
    assert mhtarc.boundary == mocker.sentinel.bndry
Example #3
0
def test_get_boundary():
    # no headers
    with pytest.raises(AttributeError):
        mhtml.get_boundary(None)

    # no content-type
    assert mhtml.get_boundary(mhtml.ResourceHeader()) is None
    # missing boundary declaration
    assert mhtml.get_boundary(
        mhtml.ResourceHeader([('conTent-TyPe', 'text/html')])) is None

    assert mhtml.get_boundary(
        mhtml.ResourceHeader(
            [('conTent-TyPe', 'text/html;\r\n\tabc\r\n\tboundary="'
              '---test-boundary---'
              '"')])) is None

    # has to be multipart
    assert mhtml.get_boundary(
        mhtml.ResourceHeader(
            [('Content-Type', 'multipart/related;\r\n\tabc\r\n'
              '\tnothing-here')])) is None
    # has to be multipart and contain a boundary declaration
    assert mhtml.get_boundary(
        mhtml.ResourceHeader([('Content-Type',
                               'multipart/related;\r\n\tabc\r\n\tboundary="'
                               '---test-boundary---'
                               '"')])) == '---test-boundary---'
Example #4
0
def test_get_content_type():
    # more verbose construction
    mock_headers = mhtml.ResourceHeader()
    mock_headers['Content-Type'] = 'text/html'
    assert mhtml.get_content_type(mock_headers) == 'text/html'

    # case insensitive
    assert mhtml.get_content_type(
        mhtml.ResourceHeader([('conTent-TyPe', 'text/html')])) == 'text/html'

    # multipart/related
    assert mhtml.get_content_type(
        mhtml.ResourceHeader([('conTent-TyPe', 'multipart/related;\r\n\t...')
                              ])) == 'multipart/related'

    # empty headers -> None
    assert mhtml.get_content_type(mhtml.ResourceHeader()) is None

    # no headers
    with pytest.raises(AttributeError):
        mhtml.get_content_type(None)

    # even standard dicts, but case sensitive
    assert mhtml.get_content_type({'Content-Type': 'text/abc'}) == 'text/abc'
    assert mhtml.get_content_type({'conTent-TyPe': 'text/abc'}) is None
Example #5
0
def test_parse_header():
    assert mhtml.parse_header(b'', 0) == (mhtml.ResourceHeader(), -1)

    # needs two linebreaks (a single empty line) after the header fields
    with pytest.raises(AssertionError):
        assert mhtml.parse_header(b'CH: CV\r\n', 0) == \
            (mhtml.ResourceHeader([('CH', 'CV')]), -1)

    # really short header
    assert mhtml.parse_header(b'CH: CV\r\n\r\n', 0) == \
        (mhtml.ResourceHeader([('CH', 'CV')]), -1)
    assert mhtml.parse_header(b'CH: CV\r\nCH2: CV2\r\nCH3: CV3\r\n\r\n', 0) \
        == (mhtml.ResourceHeader([('CH', 'CV'), ('CH2', 'CV2'),
                                  ('CH3', 'CV3')]), -1)

    # TODO: how to handle multiple spaces -> trim()?
    assert mhtml.parse_header(b'CH:     CV\r\n\r\n', 0) == \
        (mhtml.ResourceHeader([('CH', '    CV')]), -1)
    # needs at least a single space
    assert mhtml.parse_header(b'CH:CV\r\n\r\n', 0) == \
        (mhtml.ResourceHeader([]), -1)

    assert mhtml.parse_header(b'CH: CV\r\n\r\n\r\n-----boundary---', 0) == \
        (mhtml.ResourceHeader([('CH', 'CV')]), 10)

    # value with linebreaks
    assert mhtml.parse_header(b'CH: CV;\r\n\tCV2\r\n\r\n', 0) == \
        (mhtml.ResourceHeader([('CH', 'CV;\r\n\tCV2')]), -1)

    assert mhtml.parse_header(b'CH: CV;\r\n\tCV2\r\nCH2: CV3\r\n\r\n', 0) == \
        (mhtml.ResourceHeader([('CH', 'CV;\r\n\tCV2'), ('CH2', 'CV3')]), -1)
Example #6
0
def test_ResourceHeader_magic():  # noqa: N802
    # eq / ne
    rh1 = mhtml.ResourceHeader([('a', 'b')])
    rh2 = mhtml.ResourceHeader([('A', 'b')])
    rh3 = mhtml.ResourceHeader([('A', 'b')])
    rh4 = mhtml.ResourceHeader([('c', 'b')])
    assert not rh1 == rh2  # pylint: disable=unneeded-not
    assert rh2 == rh3
    assert rh1 != rh2
    assert not rh2 != rh3  # pylint: disable=unneeded-not
    assert rh2 != rh4
    assert not rh1 == rh4  # pylint: disable=unneeded-not
    assert (not rh1.__eq__(rh2)) == rh1.__ne__(rh2)
    assert rh3.__eq__(rh2) == (not rh3.__ne__(rh2))

    # checks type, not only content
    assert rh1 != rh1._headers

    # str / repr
    assert str(rh2) == str(rh2._headers)
    assert repr(rh2) == 'ResourceHeader: ' + repr(rh2._headers)

    # as_list
    rh = mhtml.ResourceHeader([('a', 'b'), ('A', 'c'), ('D', 'e')])
    assert rh.as_list() == [('a', 'b'), ('A', 'c'), ('D', 'e')]

    hl = rh.as_list()
    hl.append(('t', 't'))
    assert rh.as_list() != hl

    # as_dict
    rh = mhtml.ResourceHeader([('a', 'b'), ('A', 'c'), ('D', 'e')])
    assert rh.as_dict() == {'a': 'b', 'A': 'c', 'D': 'e'}

    # TODO: items() modification ?

    # iter
    rh = mhtml.ResourceHeader([('a', 'b'), ('A', 'c'), ('D', 'e')])
    assert iter(rh)
    assert list(rh) == ['a', 'A', 'D']

    # del
    rh = mhtml.ResourceHeader([('a', 'b'), ('A', 'c'), ('D', 'e')])
    del rh['a']
    assert rh.items() == [('D', 'e')]
    del rh[None]
    assert len(rh) == 1

    # TODO: get/del/set empty strings?
    rh = mhtml.ResourceHeader()
    rh[''] = 'h'
    assert len(rh) == 1
    assert rh[''] == 'h'
    del rh['']
    assert len(rh) == 0
Example #7
0
def test_make_filename():
    # no headers given
    assert mhtml.make_filename(None, default='abc') == 'abc'
    # empty header
    assert mhtml.make_filename(mhtml.ResourceHeader(), default='abd') == 'abd'
    assert mhtml.make_filename(mhtml.ResourceHeader([('CH', 'CV')]),
                               default='abd') == 'abd'

    # assume we have extensions
    mock_headers = mhtml.ResourceHeader()
    mock_headers['Content-Location'] = 'proto://path/to/file.ext'
    assert mhtml.make_filename(mock_headers,
                               guess_extension=False) == 'file.ext'
    assert mhtml.make_filename(mock_headers,
                               folder='abc',
                               guess_extension=False) == 'abc/file.ext'
    assert mhtml.make_filename(mock_headers,
                               guess_extension=True) == 'file.ext'
    assert mhtml.make_filename(mock_headers) == 'file.ext'

    # test guessing extensions
    del mock_headers['Content-Location']
    mock_headers['Content-Location'] = 'proto://path/to/file'

    assert mhtml.make_filename(mock_headers, default='abc.hhh') == 'file.hhh'
    # if not extension, then .bin ?
    assert mhtml.make_filename(mock_headers, default=None) == 'file.bin'
    assert mhtml.make_filename(mock_headers, default='ooo') == 'file.bin'

    assert mhtml.make_filename(mock_headers,
                               default='lolo.olo',
                               ext_from_default=True) == 'file.olo'

    # add content-type
    mock_headers['Content-Type'] = 'myster/lexi'
    assert mhtml.make_filename(mock_headers, default='ooo.hhh') == 'file.lexi'
    assert mhtml.make_filename(mock_headers,
                               folder='ddd/bbb/',
                               default='ooo.hhh') == 'ddd/bbb/file.lexi'
    del mock_headers['Content-Type']
    mock_headers['Content-Type'] = 'mystery'
    assert mhtml.make_filename(mock_headers) == 'file.mystery'

    # force use of default extension
    del mock_headers['Content-Location']
    mock_headers['Content-Location'] = 'proto://path/to/file'
    assert mhtml.make_filename(mock_headers,
                               default='lolo.olo',
                               ext_from_default=True) == 'file.olo'
Example #8
0
def test_ResourceHeader_methods_get():  # noqa: N802
    rh = mhtml.ResourceHeader()
    rh['a'] = 'b'

    assert rh.get(None, None) is None
    assert rh.get(None, 'y') == 'y'

    assert rh.get('A') == 'b'
    assert rh.get('a') == 'b'
    assert rh.get('a', None) == 'b'
    assert rh.get('c', 'x') == 'x'

    assert rh.get_all('a') == ['b']
    assert rh.get_all('c') == []
    # return default list on invalid key/name
    assert rh.get_all(None) == []
    assert rh.get_all(None, default=1) == 1

    rh['A'] = 'F'
    assert rh.get_all('a') == ['b', 'F']

    # getter
    assert rh['a'] == 'b'
    rh['C'] = 1
    rh['c'] = 2
    assert rh['c'] == 1
Example #9
0
def test_MHTMLArchive_properties_resources(mocker):  # noqa: N802
    mhtarc = mhtml.MHTMLArchive(b'content', mhtml.ResourceHeader(), 0,
                                '---boundary---')
    assert mhtarc.resources == []
    assert mhtarc.get_resource(0) is None
    assert mhtarc.get_resource(-1) is None
    assert mhtarc.get_resource(10) is None

    # setting resources
    mhtarc._set_resources(None)
    assert isinstance(mhtarc.resources, list)
    mhtarc._set_resources('a')
    assert isinstance(mhtarc.resources, list)
    mhtarc._set_resources([])
    assert isinstance(mhtarc.resources, list)

    # TODO: checking resources from type Resource?
    mhtarc._set_resources([1])
    assert mhtarc.resources == [1]
    assert mhtarc.get_resource(0) == 1
    assert mhtarc.get_resource(1) is None
    assert mhtarc.remove_resource(-1) is False
    # wrong resource type should raise an error
    with pytest.raises(AttributeError,
                       match="""'int' object has no attribute 'get_resource_range'"""):  # noqa: E501  pylint: disable=line-too-long
        mhtarc.remove_resource(0)
Example #10
0
def test_MHTMLArchive_update_offsets(mocker):  # noqa: N802
    mhtarc = mhtml.MHTMLArchive(b'content', mhtml.ResourceHeader(), 0,
                                '---boundary---')

    mock_resource = mocker.Mock()
    mock_resource2 = mocker.Mock()
    mhtarc._set_resources([mock_resource, mock_resource2])

    # abort if not valid
    mhtarc._update_offsets(-5, None)
    mock_resource._update_offsets.assert_not_called()
    mock_resource2._update_offsets.assert_not_called()

    mhtarc._update_offsets(-5, 1)
    mock_resource._update_offsets.assert_not_called()
    mock_resource2._update_offsets.assert_called_once_with(-5)

    mhtarc._update_offsets(2, 0)
    mock_resource._update_offsets.assert_called_once_with(2)
    mock_resource2._update_offsets.assert_any_call(2)

    mock_method = mocker.Mock(return_value=False)
    mhtarc._is_valid_resource_index = mock_method
    mhtarc._update_offsets(2, 0)
    mock_method.assert_called_once_with(0)
Example #11
0
def test_Resource_properties(mocker):  # noqa: N802
    with pytest.raises(AssertionError,
                       match='mhtml_file should be a MHTMLArchive'):
        mhtml.Resource(None, None, 0, 0, 0)

    mhtarc = mhtml.MHTMLArchive(b'', None, 0, '---boundary---')

    # default resource headers
    res = mhtml.Resource(mhtarc, None, 0, 0, 0)
    assert res.headers == mhtml.ResourceHeader()
    assert res.headers == res._headers

    assert mhtml.Resource(mhtarc, None, 0, 0, 0).headers == \
        mhtml.ResourceHeader()
    assert mhtml.Resource(mhtarc, [], 0, 0, 0).headers == \
        mhtml.ResourceHeader()
    assert mhtml.Resource(mhtarc, {}, 0, 0, 0).headers == \
        mhtml.ResourceHeader()

    # properties
    mock_headers = mocker.Mock(content_type='content-abc',
                               location='location-abc',
                               encoding='encoding-123')
    res._headers = mock_headers
    assert res.content_type == 'content-abc'
    assert res.location == 'location-abc'
    assert res.encoding == 'encoding-123'

    # filename
    mock_method = mocker.patch('mhtml.make_filename')
    mock_method.return_value = 'name'
    assert res.get_short_filename(default='foo') == 'name'
    mock_method.assert_called_once_with(res._headers, default='foo')

    # content
    mock_prop = mocker.Mock(return_value=b'123')
    res.get_content = mock_prop
    assert res.content == b'123'
    mock_prop.assert_called_once_with()

    # content set
    mock_prop_set = mocker.Mock()
    res.set_content = mock_prop_set
    res.content = b'abc123'
    mock_prop_set.assert_called_once_with(b'abc123')
Example #12
0
def test_ResourceHeader_headers():  # noqa: N802
    # single header as list or dict
    rh = mhtml.ResourceHeader([('a', 'b')])
    assert rh._headers == [('a', 'b')]
    rh = mhtml.ResourceHeader({'aA': 'BbC'})
    assert rh._headers == [('aA', 'BbC')]

    # empty header + add some
    rh = mhtml.ResourceHeader()
    assert rh._headers == []
    assert len(rh) == 0  # pylint: disable=len-as-condition
    rh['C'] = 'BbBb'
    rh['AAaA'] = 'BbBb'
    rh['AAaA'] = 'BbBb'
    rh['aaaa'] = 'bbbb'
    assert rh._headers == [('C', 'BbBb'), ('AAaA', 'BbBb'), ('AAaA', 'BbBb'),
                           ('aaaa', 'bbbb')]
    assert rh.items() == [('C', 'BbBb'), ('AAaA', 'BbBb'), ('AAaA', 'BbBb'),
                          ('aaaa', 'bbbb')]
    assert len(rh) == 4

    # none as key is ignored
    rh[None] = 1
    assert len(rh) == 4
    rh[''] = 1
    assert len(rh) == 5

    # set converts name to string
    rh[1] = 2
    assert len(rh) == 6
    assert rh._headers[5] == ('1', 2)

    # check contains, case insensitive
    assert '1' in rh
    assert 'c' in rh
    assert 'aaaa' in rh
    assert 'AAAA' in rh
    assert 'xxxxx' not in rh
    assert not 'xxxxx' in rh  # noqa: E713 pylint: disable=unneeded-not

    rh[None] = 1
    assert None not in rh
Example #13
0
def test_MHTMLArchive_move_resource(mocker):  # noqa: N802
    bndry = '---boundary---'
    content = b'content'
    mhtarc = mhtml.MHTMLArchive(content, mhtml.ResourceHeader(), 0, bndry)
    mock_resource = mocker.Mock(spec=mhtml.Resource)
    mock_resource2 = mocker.Mock(spec=mhtml.Resource)
    mock_resource2.headers = mhtml.ResourceHeader({'H2': 'V33'})
    mhtarc._set_resources([mock_resource, mock_resource2])

    # _get_resource_and_nr fails
    mock_method_getresnr1 = mocker.Mock(return_value=(None, None, False))
    mhtarc._get_resource_and_nr = mock_method_getresnr1
    assert mhtarc.move_resource(mocker.sentinel.nr_or_res,
                                mocker.sentinel.nr) is False
    mock_method_getresnr1.assert_called_once_with(mocker.sentinel.nr_or_res)

    # _get_resource_and_nr ok, same position
    pos = 1234
    mock_method_getresnr2 = mocker.Mock(return_value=(pos,
                                                      mocker.sentinel.res,
                                                      True))
    mhtarc._get_resource_and_nr = mock_method_getresnr2
    assert mhtarc.move_resource(mocker.sentinel.nr_or_res, pos) is True
    mock_method_getresnr2.assert_called_once_with(mocker.sentinel.nr_or_res)

    # _get_resource_and_nr ok, different position, insert fails
    pos2 = 4321
    mock_method_insert1 = mocker.Mock(return_value=False)
    mhtarc.insert_resource = mock_method_insert1
    assert mhtarc.move_resource(mocker.sentinel.nr_or_res, pos2) is False
    mock_method_insert1.assert_called_once_with(pos2, mocker.sentinel.res)

    # ret ok, different nrs, insert ok, remove
    mock_method_insert2 = mocker.Mock(return_value=True)
    mock_method_remove = mocker.Mock(return_value=mocker.sentinel.remove_ret)
    mhtarc.insert_resource = mock_method_insert2
    mhtarc.remove_resource = mock_method_remove
    assert mhtarc.move_resource(mocker.sentinel.nr_or_res, pos2) \
        is mocker.sentinel.remove_ret
    mock_method_insert2.assert_called_once_with(pos2, mocker.sentinel.res)
    mock_method_remove.assert_called_once_with(mocker.sentinel.res)
Example #14
0
def test_parse_part():
    # boundary is string (because from header)
    with pytest.raises(TypeError):
        mhtml.parse_part(b'', b'', 0)

    bndry = '---boundary---'
    part_bndry = bytes('--' + bndry + '\r\n', 'ascii')
    file_bndry = bytes('--' + bndry + '--\r\n', 'ascii')

    # this case should not happen, because there will always be a part when
    # the function is called?
    assert mhtml.parse_part(b'', bndry, 0) == \
        ((mhtml.ResourceHeader(), 0, -1, 0), -1)
    # simulate last part (end-of-parts boundary) (see the extra dashes)
    assert mhtml.parse_part(b'CH: CV\r\n\r\ncontent\r\n'
                            + file_bndry,
                            bndry, 0) == \
        ((mhtml.ResourceHeader([('CH', 'CV')]), 0, 10, 19), -1)
    # simulate more parts (end-of-part boundary)
    assert mhtml.parse_part(b'CH: CV\r\n\r\ncontent\r\n'
                            + part_bndry,
                            bndry, 0) == \
        ((mhtml.ResourceHeader([('CH', 'CV')]), 0, 10, 19), 37)
Example #15
0
def test_MHTMLArchive_change_resource_content(mocker):  # noqa: N802
    bndry = '---boundary---'
    bndry_part = bytes('--' + bndry + '\r\n', 'ascii')
    header = b'H: V\r\n\r\n\r\n'
    content1 = b'H1: V2\r\n\r\ncontent\r\n'
    content2_header = b'H2: V33\r\n\r\n'
    content2_content = b'123\r\n'
    content2_content_new = b'new_content_abc'
    content2 = content2_header + content2_content
    content = header \
        + bndry_part \
        + content1 \
        + bndry_part \
        + content2 \
        + bytes('--' + bndry + '--\r\n', 'ascii')

    mhtarc = mhtml.MHTMLArchive(content, mhtml.ResourceHeader(), len(header),
                                bndry)

    assert mhtarc.replace_content(0, content2_content_new) is False
    assert mhtarc.replace_content(None, content2_content_new) is False

    mock_resource = mocker.Mock(spec=mhtml.Resource)
    # resource to change
    mock_resource2 = mocker.Mock(spec=mhtml.Resource)
    offset = len(header) + len(bndry_part) + len(content1) + len(bndry_part)
    mock_resource2._offset_start = offset
    mock_resource2._offset_content = offset + len(content2_header)
    mock_resource2._offset_end = offset + len(content2)
    mhtarc._set_resources([mock_resource, mock_resource2])

    mock_method_get = mocker.Mock(return_value=(1, mock_resource2, True))
    mhtarc._get_resource_and_nr = mock_method_get
    mock_method_update = mocker.Mock()
    mhtarc._update_offsets = mock_method_update

    assert mhtarc.replace_content(mock_resource2, content2_content_new) is True
    mock_method_get.assert_called_once_with(mock_resource2)
    # difference between content, nr nach resource
    mock_method_update.assert_called_once_with(
        len(content2_content_new) - len(content2_content), 2)
    assert mock_resource2._offset_end == mock_resource2._offset_content \
        + len(content2_content_new)
    assert mhtarc.content == header \
        + bndry_part \
        + content1 \
        + bndry_part \
        + content2_header + content2_content_new \
        + bytes('--' + bndry + '--\r\n', 'ascii')
Example #16
0
def test_MHTMLArchive_remove_resource(mocker):  # noqa: N802
    mhtarc = mhtml.MHTMLArchive(b'content', mhtml.ResourceHeader(), 0,
                                '---boundary---')

    mock_resource = mocker.Mock(spec=mhtml.Resource)
    mock_resource.get_resource_range.return_value = (2, 5)
    mock_method = mocker.Mock()
    mhtarc._update_offsets = mock_method
    mhtarc._set_resources([mock_resource])

    assert mhtarc.remove_resource(0) is True
    assert mhtarc.remove_resource(0) is False

    assert mhtarc.content == b'cont'
    assert mhtarc.resources == []
    mock_resource.get_resource_range.assert_called_once_with(18)
    mock_method.assert_called_once_with(-3, 0)
Example #17
0
def test_MHTMLArchive_helpers(mocker):  # noqa: N802
    mhtarc = mhtml.MHTMLArchive(b'content', mhtml.ResourceHeader(), 0,
                                '---boundary---')

    # valid resource index
    assert mhtarc._is_valid_resource_index(None) is False
    assert mhtarc._is_valid_resource_index(3.4) is False
    assert mhtarc._is_valid_resource_index(-1) is False
    assert mhtarc._is_valid_resource_index(0) is False
    assert mhtarc._is_valid_resource_index(1) is False

    mock_resource = mocker.Mock(spec=mhtml.Resource)
    mock_resource2 = mocker.Mock(spec=mhtml.Resource)
    mhtarc._set_resources([mock_resource, mock_resource2])

    assert mhtarc._is_valid_resource_index(-1) is False
    assert mhtarc._is_valid_resource_index(0) is True
    assert mhtarc._is_valid_resource_index(1) is True
    assert mhtarc._is_valid_resource_index(2) is False
    assert mhtarc._is_valid_resource_index('1') is False

    # get resource nr
    mhtarc._set_resources([])
    assert mhtarc._resource_to_nr(mock_resource) is None
    mhtarc._set_resources([mock_resource, mock_resource2])
    assert mhtarc._resource_to_nr(mock_resource) == 0
    assert mhtarc._resource_to_nr(mock_resource2) == 1
    assert mhtarc._resource_to_nr(None) is None
    assert mhtarc._resource_to_nr(0) is None

    # get resource + nr
    mhtarc._set_resources([])
    assert mhtarc._get_resource_and_nr(None) == (None, None, False)
    assert mhtarc._get_resource_and_nr(mock_resource)[2] is False
    assert mhtarc._get_resource_and_nr(0)[2] is False
    mhtarc._set_resources([mock_resource])
    assert mhtarc._get_resource_and_nr(mock_resource) == \
        (0, mock_resource, True)
    assert mhtarc._get_resource_and_nr(mock_resource2)[2] is False
    assert mhtarc._get_resource_and_nr(1)[2] is False
    assert mhtarc._get_resource_and_nr(-1)[2] is False
    mhtarc._set_resources([mock_resource, mock_resource2])
    assert mhtarc._get_resource_and_nr(mock_resource2) == \
        (1, mock_resource2, True)
    assert mhtarc._get_resource_and_nr('1') == (None, None, False)
Example #18
0
def test_ResourceHeader_properties(mocker):  # noqa: N802
    rh = mhtml.ResourceHeader()
    rh['C'] = 'BbBb'

    # content type
    mock_method = mocker.patch('mhtml.get_content_type')
    mock_method.return_value = 'ab'
    assert rh.content_type == 'ab'
    mock_method.assert_called_once_with(rh)

    # encoding
    mock_get = mocker.Mock()
    mock_get.return_value = 1
    rh.get = mock_get
    assert rh.encoding == 1
    mock_get.assert_called_once_with('Content-Transfer-Encoding')

    # location
    mock_get = mocker.Mock()
    mock_get.return_value = None
    rh.get = mock_get
    assert rh.location is None
    assert mock_get.call_args_list == [
        mocker.call('Snapshot-Content-Location'),
        mocker.call('Content-Location')]

    def mock_get_sideeffect(name):
        if name == 'Snapshot-Content-Location':
            return 5
        return None  # pragma: no cover

    mock_get = mocker.Mock(side_effect=mock_get_sideeffect)
    rh.get = mock_get
    assert rh.location == 5

    def mock_get_sideeffect2(name):
        if name == 'Content-Location':
            return 6
        return None

    mock_get = mocker.Mock(side_effect=mock_get_sideeffect2)
    rh.get = mock_get
    assert rh.location == 6
Example #19
0
def test_MHTMLArchive_insert_resource_reslist_empty(mocker):  # noqa: N802
    bndry = '---boundary---'
    bndry_part = bytes('--' + bndry + '\r\n', 'ascii')
    header = b'H: V\r\n\r\n\r\n'
    content1 = b'H1: V2\r\n\r\ncontent\r\n'
    content2_header = b'H2: V33\r\n\r\n'
    content2_content = b'123\r\n'
    content2 = content2_header + content2_content
    content = header \
        + bndry_part \
        + content1 \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    mhtarc = mhtml.MHTMLArchive(content, mhtml.ResourceHeader(), len(header),
                                bndry)
    # existing resource in archive
    mock_resource = mocker.Mock(spec=mhtml.Resource)
    mock_resource.get_resource_range.return_value = (len(header), len(header) +
                                                     len(bndry_part) +
                                                     len(content1))
    mock_resource._offset_start = len(header) + len(bndry_part)
    mock_resource._offset_content = len(header) + len(bndry) + 10
    # resource to insert
    mock_resource2 = mocker.Mock(spec=mhtml.Resource)
    mock_resource2.headers = mhtml.ResourceHeader({'H2': 'V33'})
    mock_resource2.content_with_headers = content2
    mock_resource2._offset_start = 0
    mock_resource2._offset_content = len(content2_header)
    mhtarc._set_resources([mock_resource])

    # insert when empty
    content = header \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    mhtarc._content = bytearray(content)
    mhtarc._set_resources([])
    assert mhtarc.insert_resource(9001, mock_resource2) is True
    assert mhtarc.content == header \
        + bndry_part \
        + content2 \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    assert len(mhtarc.resources) == 1
    assert mhtarc.resources[0]._offset_start == \
        len(header) + len(bndry_part)
    assert mhtarc.resources[0]._offset_content == \
        len(header) + len(bndry_part) + len(content2_header)
    assert mhtarc.resources[0]._offset_end == \
        len(header) + len(bndry_part) + len(content2)
    assert mhtarc.resources[0].headers == mock_resource2.headers

    content = header \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    mhtarc._content = bytearray(content)
    mhtarc._set_resources([])
    assert mhtarc.insert_resource(0, mock_resource2) is True
    assert mhtarc.content == header \
        + bndry_part \
        + content2 \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    assert len(mhtarc.resources) == 1
    assert mhtarc.resources[0]._offset_start == \
        len(header) + len(bndry_part)
    assert mhtarc.resources[0]._offset_content == \
        len(header) + len(bndry_part) + len(content2_header)
    assert mhtarc.resources[0]._offset_end == \
        len(header) + len(bndry_part) + len(content2)

    # check that not called (not neccessary)
    mock_method = mocker.Mock()
    mhtarc._content = bytearray(content)
    mhtarc._set_resources([])
    mhtarc._update_offsets = mock_method

    assert mhtarc.insert_resource(0, mock_resource2) is True
    mock_method.assert_not_called()
Example #20
0
def test_MHTMLArchive_insert_resource_update_calls(mocker):  # noqa: N802
    bndry = '---boundary---'
    bndry_part = bytes('--' + bndry + '\r\n', 'ascii')
    header = b'H: V\r\n\r\n\r\n'
    content1 = b'H1: V2\r\n\r\ncontent\r\n'
    content2_header = b'H2: V33\r\n\r\n'
    content2_content = b'123\r\n'
    content2 = content2_header + content2_content
    content = header \
        + bndry_part \
        + content1 \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    mhtarc = mhtml.MHTMLArchive(content, mhtml.ResourceHeader(), len(header),
                                bndry)
    # existing resource in archive
    mock_resource = mocker.Mock(spec=mhtml.Resource)
    mock_resource.get_resource_range.return_value = (len(header), len(header) +
                                                     len(bndry_part) +
                                                     len(content1))
    mock_resource._offset_start = len(header) + len(bndry_part)
    mock_resource._offset_content = len(header) + len(bndry) + 10
    # resource to insert
    mock_resource2 = mocker.Mock(spec=mhtml.Resource)
    mock_resource2.headers = mhtml.ResourceHeader({'H2': 'V33'})
    mock_resource2.content_with_headers = content2
    mock_resource2._offset_start = 0
    mock_resource2._offset_content = len(content2_header)
    mhtarc._set_resources([mock_resource])

    # check that not called (not neccessary)
    mock_method1 = mocker.Mock()
    content = header \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    mhtarc._content = bytearray(content)
    mhtarc._set_resources([])
    mhtarc._update_offsets = mock_method1

    assert mhtarc.insert_resource(0, mock_resource2) is True
    mock_method1.assert_not_called()

    # check offset updates
    mock_method2 = mocker.Mock()
    content = header \
        + bndry_part \
        + content1 \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    mhtarc._content = bytearray(content)
    mhtarc._set_resources([mock_resource])
    mhtarc._update_offsets = mock_method2
    assert mhtarc.insert_resource(9001, mock_resource2) is True
    mock_method2.assert_not_called()

    mock_method3 = mocker.Mock()
    content = header \
        + bndry_part \
        + content1 \
        + bytes('--' + bndry + '--\r\n', 'ascii')
    mhtarc._content = bytearray(content)
    mhtarc._set_resources([mock_resource])
    mhtarc._update_offsets = mock_method3
    assert mhtarc.insert_resource(0, mock_resource2) is True
    mock_method3.assert_called_once_with(len(bndry_part) + len(content2), 1)

    # simply test that the resource parameter is given to the next method
    mock_method4 = mocker.Mock(return_value=4)
    mhtarc._set_resources([1, 2, 3])
    mhtarc.insert_resource = mock_method4
    assert mhtarc.append_resource('abc') == 4
    mock_method4.assert_called_once_with(3, 'abc')