示例#1
0
def test_edit_creation_date(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent() as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--date', '3000-05-30 15:03:01', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, creation_date=datetime(3000, 5, 30, 15, 3, 1))
示例#2
0
def test_metainfo_with_verbosity_level_two(capsys, nonstandard_torrent):
    run(['-i', nonstandard_torrent, '--metainfo', '--verbose', '--verbose'])
    cap = capsys.readouterr()
    assert cap.err == ''
    assert json.loads(cap.out) == {
        'created by': f'torf {torf.__version__}',
        'announce': 'https://foo.example.org',
        'foo': 'bar',
        'info': {
            'baz': [1, 2, 3],
            'private':
            1,
            'files': [{
                'length': 3,
                'path': ['dir', 'file3'],
                'sneaky': 'pete'
            }, {
                'length': 3,
                'path': ['file1']
            }, {
                'length': 3,
                'path': ['file2']
            }],
            'name':
            'content',
            'piece length':
            16384,
            'pieces':
            'YscFPSkTuTXkBSgIyyaqj/HVRXU='
        }
    }
示例#3
0
def test_replace_webseeds(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(webseeds=['http://webseed1', 'http://webseed2']) as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--nowebseed', '--webseed', 'http://webseed10', '--webseed', 'http://webseed20', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, webseeds=['http://webseed10', 'http://webseed20'])
示例#4
0
def test_json_with_magnet_uri(capsys, regex):
    magnet = (
        'magnet:?xt=urn:btih:e167b1fbb42ea72f051f4f50432703308efb8fd1&dn=My+Torrent&xl=142631'
        '&tr=https%3A%2F%2Flocalhost%3A123%2Fannounce&&tr=https%3A%2F%2Flocalhost%3A456%2Fannounce'
    )
    run(['-i', magnet, '--json'])
    cap = capsys.readouterr()
    assert cap.err == ''
    assert json.loads(cap.out) == {
        "Error": [
            'https://localhost:123/file?info_hash=%E1g%B1%FB%B4.%A7/%05%1FOPC%27%030%8E%FB%8F%D1: Connection refused',
            'https://localhost:456/file?info_hash=%E1g%B1%FB%B4.%A7/%05%1FOPC%27%030%8E%FB%8F%D1: Connection refused'
        ],
        'Name':
        'My Torrent',
        'Size':
        142631,
        'Trackers':
        ['https://localhost:123/announce', 'https://localhost:456/announce'],
        'Piece Size':
        16384,
        'Piece Count':
        9,
        'File Count':
        1,
        'Files': ['My Torrent']
    }
示例#5
0
def test_metainfo_with_verbosity_level_zero(capsys, nonstandard_torrent):
    run(['-i', nonstandard_torrent, '--metainfo'])
    cap = capsys.readouterr()
    assert cap.err == ''
    assert json.loads(cap.out) == {
        'created by': f'torf {torf.__version__}',
        'announce': 'https://foo.example.org',
        'info': {
            'name':
            'content',
            'piece length':
            16384,
            'private':
            1,
            'files': [{
                'length': 3,
                'path': ['dir', 'file3']
            }, {
                'length': 3,
                'path': ['file1']
            }, {
                'length': 3,
                'path': ['file2']
            }]
        }
    }
示例#6
0
def test_content_path_doesnt_exist(capsys, human_readable, hr_enabled):
    with human_readable(hr_enabled):
        with patch('sys.exit') as mock_exit:
            run(['/path/doesnt/exist'])
    mock_exit.assert_called_once_with(err.Code.READ)
    cap = capsys.readouterr()
    assert cap.err == f'{_vars.__appname__}: /path/doesnt/exist: No such file or directory\n'
示例#7
0
def test_add_private(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(private=False) as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--private', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, private=True)
示例#8
0
def test_edit_comment(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(comment='A comment') as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--comment', 'A different comment', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, comment='A different comment')
示例#9
0
def test_remove_creator(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(created_by='The creator') as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--nocreator', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, created_by=None)
示例#10
0
def test_file_tree_and_file_count(capsys, create_torrent, human_readable, tmp_path, clear_ansi, regex):
    root = tmp_path / 'root'
    (root / 'subdir1' / 'subdir1.0' / 'subdir1.0.0').mkdir(parents=True)
    (root / 'subdir2').mkdir(parents=True)
    (root / 'subdir1' / 'file1').write_text('data')
    (root / 'subdir1' / 'subdir1.0' / 'file2').write_text('data')
    (root / 'subdir1' / 'subdir1.0' / 'subdir1.0.0' / 'file3').write_text('data')
    (root / 'subdir2' / 'file4').write_text('data')

    with create_torrent(path=str(root)) as torrent_file:
        with human_readable(True):
            run(['-i', torrent_file])
            cap = capsys.readouterr()
            assert clear_ansi(cap.out) == regex(r'^\s*File Count  4$', flags=re.MULTILINE)
            assert clear_ansi(cap.out) == regex(r'^(\s*)      Files  root\n'
                                                r'\1             ├─subdir1\n'
                                                r'\1             │ ├─file1 \[4 B\]\n'
                                                r'\1             │ └─subdir1.0\n'
                                                r'\1             │   ├─file2 \[4 B\]\n'
                                                r'\1             │   └─subdir1.0.0\n'
                                                r'\1             │     └─file3 \[4 B\]\n'
                                                r'\1             └─subdir2\n'
                                                r'\1               └─file4 \[4 B\]$', flags=re.MULTILINE)
            assert cap.err == ''

        with human_readable(False):
            run(['-i', torrent_file])
            cap = capsys.readouterr()
            assert cap.out == regex(r'^File Count\t4$', flags=re.MULTILINE)
            exp_files = '\t'.join(('root/subdir1/file1',
                                   'root/subdir1/subdir1.0/file2',
                                   'root/subdir1/subdir1.0/subdir1.0.0/file3',
                                   'root/subdir2/file4'))
            assert cap.out == regex(rf'^Files\t{exp_files}$', flags=re.MULTILINE)
            assert cap.err == ''
示例#11
0
def test_no_changes(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent() as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new)
示例#12
0
def test_nonexisting_input(capsys):
    nonexisting_path = '/no/such/file'
    with patch('sys.exit') as mock_exit:
        run(['-i', nonexisting_path, '-o', 'out.torrent'])
    mock_exit.assert_called_once_with(err.Code.READ)
    cap = capsys.readouterr()
    assert cap.err == f'{_vars.__appname__}: {nonexisting_path}: No such file or directory\n'
示例#13
0
def test_illegal_configfile_arguments(capsys, cfgfile, mock_content,
                                      mock_create_mode):
    for arg in ('config', 'profile'):
        cfgfile.write_text(
            textwrap.dedent(f'''
        [foo]
        {arg} = foo
        '''))

        with patch('sys.exit') as mock_exit:
            run(['--config', str(cfgfile), str(mock_content)])
        mock_exit.assert_called_once_with(err.Code.CONFIG)
        cap = capsys.readouterr()
        assert cap.err == f'{_vars.__appname__}: {cfgfile}: Not allowed in config file: {arg}\n'
        assert mock_create_mode.call_args is None

    for arg in ('noconfig', 'help', 'version'):
        cfgfile.write_text(
            textwrap.dedent(f'''
        [foo]
        {arg}
        '''))
        with patch('sys.exit') as mock_exit:
            run(['--config', str(cfgfile), str(mock_content)])
        mock_exit.assert_called_once_with(err.Code.CONFIG)
        cap = capsys.readouterr()
        assert cap.err == f'{_vars.__appname__}: {cfgfile}: Not allowed in config file: {arg}\n'
        assert mock_create_mode.call_args is None
示例#14
0
def test_replace_trackers(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(trackers=['http://tracker1', 'http://tracker2']) as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--notracker', '--tracker', 'http://tracker10', '--tracker', 'http://tracker20', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, trackers=[['http://tracker10'], ['http://tracker20']])
示例#15
0
def test_remove_source(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(source='the source') as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--nosource', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, source=None)
示例#16
0
def test_metainfo_with_unreadable_torrent(capsys):
    with patch('sys.exit') as mock_exit:
        run(['-i', 'no/such/path.torrent', '--metainfo'])
    mock_exit.assert_called_once_with(err.Code.READ)
    cap = capsys.readouterr()
    assert cap.err == f'{_vars.__appname__}: no/such/path.torrent: No such file or directory\n'
    assert json.loads(cap.out) == {}
示例#17
0
def test_unwritable_output(capsys, create_torrent):
    unwritable_path = '/out.torrent'
    with create_torrent() as infile:
        with patch('sys.exit') as mock_exit:
            run(['-i', infile, '-o', unwritable_path])
        mock_exit.assert_called_once_with(err.Code.WRITE)
        cap = capsys.readouterr()
        assert cap.err == f'{_vars.__appname__}: {unwritable_path}: Permission denied\n'
示例#18
0
def test_custom_configfile(tmp_path, mock_content, mock_create_mode):
    cfgfile = tmp_path / 'special_config'
    cfgfile.write_text(textwrap.dedent('''
    comment = asdf
    '''))
    run(['--config', str(cfgfile), str(mock_content)])
    cfg = mock_create_mode.call_args[0][1]
    assert cfg['comment'] == 'asdf'
示例#19
0
def test_json_contains_cli_errors(capsys):
    with patch('sys.exit') as mock_exit:
        run(['--foo', '--json'])
    mock_exit.assert_called_once_with(err.Code.CLI)
    cap = capsys.readouterr()
    assert cap.err == ''
    j = json.loads(cap.out)
    assert j['Error'] == ['Unrecognized arguments: --foo']
示例#20
0
def test_add_xseed(create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(randomize_infohash=False) as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--xseed', '-o', outfile])
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, randomize_infohash=True)
        assert orig.infohash != new.infohash
示例#21
0
def test_reading_invalid_magnet(capsys):
    magnet = 'magnet:?xt=urn:btih:e167b1fbb42ea72f051f4f50432703308efb8fd1&xl=not_an_int'
    with patch('sys.exit') as mock_exit:
        run(['-i', magnet])
    mock_exit.assert_called_once_with(err.Code.READ)
    cap = capsys.readouterr()
    assert cap.err == f'{_vars.__appname__}: not_an_int: Invalid exact length ("xl")\n'
    assert cap.out == ''
示例#22
0
def test_version(capsys):
    with patch('sys.exit') as mock_exit:
        run(['--version'])
    mock_exit.assert_not_called()
    cap = capsys.readouterr()
    from torfcli._config import VERSION_TEXT
    assert cap.out == VERSION_TEXT + '\n'
    assert cap.err == ''
示例#23
0
def test_adding_to_list_via_cli(cfgfile, mock_content, mock_create_mode):
    cfgfile.write_text(textwrap.dedent('''
    tracker = https://foo
    tracker = https://bar
    '''))
    run([str(mock_content), '--tracker', 'https://baz'])
    cfg = mock_create_mode.call_args[0][1]
    assert cfg['tracker'] == ['https://foo', 'https://bar', 'https://baz']
示例#24
0
def test_reading_valid_torrent_data_from_stdin(capsys, monkeypatch, clear_ansi, create_torrent, regex):
    with create_torrent(name='Foo', comment='Bar.') as torrent_file:
        monkeypatch.setattr(sys, 'stdin', open(torrent_file, 'rb'))
        run(['-i', '-'])
    cap = capsys.readouterr()
    assert clear_ansi(cap.out) == regex(r'^Name\tFoo$', flags=re.MULTILINE)
    assert clear_ansi(cap.out) == regex(r'^Comment\tBar.$', flags=re.MULTILINE)
    assert cap.err == ''
示例#25
0
def test_no_arguments(capsys):
    with patch('sys.exit') as mock_exit:
        run([])
    mock_exit.assert_called_once_with(_errors.Code.CLI)
    cap = capsys.readouterr()
    assert cap.out == ''
    assert cap.err == (f'{_vars.__appname__}: Not sure what to do '
                       f'(see USAGE in `{_vars.__appname__} -h`)\n')
示例#26
0
def test_metainfo_when_creating_torrent(capsys, mock_content):
    run([str(mock_content), '--metainfo', '-vv'])
    cap = capsys.readouterr()
    assert cap.err == ''
    j = json.loads(cap.out)
    assert 'info' in j
    assert 'name' in j['info']
    assert 'pieces' in j['info']
示例#27
0
def test_invalid_creation_date(capsys, create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent() as infile:
        with patch('sys.exit') as mock_exit:
            run(['-i', infile, '--date', 'foo', '-o', outfile])
        mock_exit.assert_called_once_with(err.Code.CLI)
        cap = capsys.readouterr()
        assert cap.err == f'{_vars.__appname__}: foo: Invalid date\n'
        assert not os.path.exists(outfile)
示例#28
0
def test_invalid_webseed_url(capsys, create_torrent, tmp_path, assert_torrents_equal):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(webseeds=['http://webseed1', 'http://webseed2']) as infile:
        with patch('sys.exit') as mock_exit:
            run(['-i', infile, '--webseed', 'not a url', '-o', outfile])
        mock_exit.assert_called_once_with(err.Code.CLI)
        cap = capsys.readouterr()
        assert cap.err == f'{_vars.__appname__}: not a url: Invalid URL\n'
        assert not os.path.exists(outfile)
示例#29
0
def test_add_private_and_remove_all_trackers(create_torrent, tmp_path, assert_torrents_equal, capsys):
    outfile = str(tmp_path / 'out.torrent')
    with create_torrent(private=False) as infile:
        orig = torf.Torrent.read(infile)
        run(['-i', infile, '--private', '--notracker', '-o', outfile])
        cap = capsys.readouterr()
        assert cap.err == f'{_vars.__appname__}: WARNING: Torrent is private and has no trackers\n'
        new = torf.Torrent.read(outfile)
        assert_torrents_equal(orig, new, private=True, trackers=())
示例#30
0
def test_json_contains_sigint(capsys, mock_create_mode, mock_content):
    mock_create_mode.side_effect = KeyboardInterrupt()
    with patch('sys.exit') as mock_exit:
        run([str(mock_content), '--json'])
    mock_exit.assert_called_once_with(err.Code.ABORTED)
    cap = capsys.readouterr()
    assert cap.err == ''
    j = json.loads(cap.out)
    assert j['Error'] == ['Aborted']