async def test_get_torrents_by_filter(self): self.daemon.response = rsrc.response_torrents( { 'id': 1, 'name': 'Foo' }, { 'id': 2, 'name': 'Bar' }, { 'id': 3, 'name': 'Boo' }, ) response = await self.api.torrents(torrents=TorrentFilter('name=Foo')) self.assertEqual(response.success, True) self.assert_torrentkeys_equal('id', response.torrents, 1) self.assert_torrentkeys_equal('name', response.torrents, 'Foo') response = await self.api.torrents(torrents=TorrentFilter('name~oo')) self.assertEqual(response.success, True) self.assert_torrentkeys_equal('id', response.torrents, 1, 3) self.assert_torrentkeys_equal('name', response.torrents, 'Foo', 'Boo') response = await self.api.torrents(torrents=TorrentFilter('name=Nope')) self.assertEqual(response.success, False) self.assertEqual(response.torrents, ()) self.assertIn('Nope', str(response.msgs[0]))
def test_AND_operator(self): ftlist = TorrentFilter('name~f&public').apply(tlist) self.assertEqual(getids(ftlist), {1, 3}) ftlist = TorrentFilter('name~f&public&!complete').apply(tlist) self.assertEqual(getids(ftlist), {3}) ftlist = TorrentFilter('name~f&!complete&private&stopped').apply(tlist) self.assertEqual(getids(ftlist), {4})
def test_AND_OR_operator(self): ftlist = TorrentFilter('!stopped&complete|name=foof').apply(tlist) self.assertEqual(getids(ftlist), {1, 4}) ftlist = TorrentFilter('name~foo|active&private').apply(tlist) self.assertEqual(getids(ftlist), {1, 2, 4}) ftlist = TorrentFilter('name~f&seeding|!complete&downloading|' 'connections&!downloading|id=4').apply(tlist) self.assertEqual(getids(ftlist), {1, 2, 3, 4})
def test_needed_keys(self): f1 = TorrentFilter('public') self.assertEqual(set(f1.needed_keys), set(['private'])) f2 = TorrentFilter('complete') self.assertEqual(set((f1 + f2).needed_keys), set(['private', '%downloaded'])) f3 = TorrentFilter('!private|active') self.assertEqual( set((f1 + f2 + f3).needed_keys), set(['private', '%downloaded', 'peers-connected', 'status']))
def test_parser(self): for s in ('&', '|', '&idle', '|idle'): with self.assertRaisesRegex(ValueError, "can't start with operator"): TorrentFilter(s) for s in ('idle&', 'idle|'): with self.assertRaisesRegex(ValueError, "can't end with operator"): TorrentFilter(s) for s in ('idle||private', 'idle&&private', 'idle&|private', 'idle|&private', 'idle||private&name~foo|name~bar', 'name~foo|name~bar&idle|&private|name~baz'): with self.assertRaisesRegex( ValueError, "Consecutive operators: 'idle[&|]{2}private'"): TorrentFilter(s) TorrentFilter()
def test_OR_operator(self): ftlist = TorrentFilter('name~f|public').apply(tlist) self.assertEqual(getids(ftlist), {1, 3, 4}) ftlist = TorrentFilter('name~f|public|!complete').apply(tlist) self.assertEqual(getids(ftlist), {1, 2, 3, 4}) ftlist = TorrentFilter('%downloaded<30|%downloaded>90').apply(tlist) self.assertEqual(getids(ftlist), {1, 2, 3}) ftlist = TorrentFilter('%downloaded<30|seeding').apply(tlist) self.assertEqual(getids(ftlist), {1, 2}) ftlist = TorrentFilter('seeding|%downloaded<30 |' 'connections=1|path~/different/').apply(tlist) self.assertEqual(getids(ftlist), {1, 2, 3, 4})
async def test_disable_rate_limit(self): self.daemon.response = rsrc.response_torrents( {'id': 1, 'name': 'Foo', 'uploadLimit': 100, 'uploadLimited': True}, {'id': 2, 'name': 'Bar', 'uploadLimit': 200, 'uploadLimited': True}, ) response = await self.api.set_rate_limit_up(TorrentFilter('id=1|id=2'), False) self.assert_request({'method': 'torrent-set', 'arguments': {'ids': [1, 2], 'uploadLimited': False}})
def __init__(self, tfilter, *keys): self.keys = keys if isinstance(tfilter, str): self.tfilter = TorrentFilter(tfilter) self.keys_needed = tuple(set(self.keys + self.tfilter.needed_keys)) else: self.tfilter = tfilter self.keys_needed = self.keys self.callback = FakeCallback()
async def test_rpc_method_without_kwargs(self): response = await self.api._torrent_action( torrents=TorrentFilter('id=4|id=3'), method=self.mock_method, keys=('id', )) self.assertEqual(self.mock_method_args, (3, )) self.assertEqual(self.mock_method_kwargs, {}) self.assertEqual(response.success, True) self.assert_torrentkeys_equal('id', response.torrents, 3) self.assert_torrentkeys_equal('name', response.torrents, 'Boo')
async def test_rpc_method_with_kwargs(self): response = await self.api._torrent_action( torrents=TorrentFilter('name~B'), method=self.mock_method, method_args={'foo': 'bar'}, ) self.assertEqual(self.mock_method_args, (2,3)) self.assertEqual(self.mock_method_kwargs, {'foo': 'bar'}) self.assertEqual(response.success, True) self.assert_torrentkeys_equal('id', response.torrents, 2, 3) self.assert_torrentkeys_equal('name', response.torrents, 'Bar', 'Boo')
async def test_no_torrents_found(self): response = await self.api._torrent_action( torrents=TorrentFilter('id=4'), method=self.mock_method, keys=('id')) self.assertEqual(self.mock_method_args, None) self.assertEqual(self.mock_method_kwargs, None) self.assertEqual(response.success, False) self.assertEqual(response.torrents, ()) self.assertIn('id', str(response.msgs[0])) self.assertIn('4', str(response.msgs[0]))
async def test_set_relative_rate_limit_when_enabled(self): self.daemon.response = rsrc.response_torrents( {'id': 1, 'name': 'Foo', 'uploadLimit': 100, 'uploadLimited': True}, {'id': 2, 'name': 'Bar', 'uploadLimit': 200, 'uploadLimited': True}, ) response = await self.api.adjust_rate_limit_up(TorrentFilter('id=1|id=2'), -50e3) self.assert_request({'method': 'torrent-set', 'arguments': {'ids': [1], 'uploadLimited': True, 'uploadLimit': 50}}) self.assert_request({'method': 'torrent-set', 'arguments': {'ids': [2], 'uploadLimited': True, 'uploadLimit': 150}})
async def test_combining_requests(self): await self.rp.start() self.assertEqual(self.rp.running, True) await self.advance(0) self.assert_api_request(calls=1, tfilter=None, keys='ALL') foo = Subscriber('name~foo', 'name', 'rate-down') self.rp.register('foo', foo.callback, keys=foo.keys, tfilter=foo.tfilter) await self.advance(self.rp.interval) self.assert_api_request(calls=2, tfilter=foo.tfilter, keys=foo.keys_needed) bar = Subscriber('name~bar', 'name', 'rate-up') self.rp.register('bar', bar.callback, keys=bar.keys, tfilter=bar.tfilter) await self.advance(self.rp.interval) self.assert_api_request(calls=3, tfilter=(foo + bar).tfilter, keys=(foo + bar).keys_needed) baz = Subscriber('idle', 'id', 'status', 'size-total') self.rp.register('baz', baz.callback, keys=baz.keys, tfilter=baz.tfilter) await self.advance(self.rp.interval) self.assert_api_request(calls=4, tfilter=(foo + bar + baz).tfilter, keys=(foo + bar + baz).keys_needed) # no filter for f in (None, TorrentFilter('all')): thelot = Subscriber(f, 'name', 'rate-up') self.rp.register('all', thelot.callback, keys=thelot.keys, tfilter=thelot.tfilter) await self.advance(self.rp.interval) self.assert_api_request(tfilter=None, keys=(foo + bar + baz + thelot).keys_needed) self.rp.remove('all') await self.advance(self.rp.interval) self.assert_api_request(tfilter=(foo + bar + baz).tfilter, keys=(foo + bar + baz).keys_needed) await self.rp.stop()
def test_combining_filters(self): f1 = TorrentFilter('name=foo') f2 = TorrentFilter('active') f3 = f1 + f2 self.assertEqual(f3, TorrentFilter('name=foo|active')) f1 = TorrentFilter('name~foo&private|path~/other/') f2 = TorrentFilter('active&private|public&!complete') f3 = f1 + f2 self.assertEqual(str(f3), ('~foo&private|path~/other/|' 'active&private|public&!complete')) f1 = TorrentFilter('public&active') f2 = TorrentFilter('active&public') self.assertEqual(str(f1 + f2), 'public&active') f3 = TorrentFilter('complete') self.assertEqual(str(f1 + f2 + f3), 'public&active|complete') self.assertEqual(str(f3 + f2 + f1), 'complete|active&public')
def test_no_filters(self): ftlist = TorrentFilter().apply(tlist) self.assertEqual(getids(ftlist), {1, 2, 3, 4})
def test_combining_any_filter_with_all_is_all(self): f = TorrentFilter('active') + TorrentFilter('all') self.assertEqual(f, TorrentFilter('all')) f = TorrentFilter('active') + TorrentFilter('private') self.assertEqual(f, TorrentFilter('active|private'))
def test_multiple_implied_name_filters(self): self.assertEqual(str(TorrentFilter('foo|bar')), '~foo|~bar')
def test_equality(self): self.assertEqual(TorrentFilter('idle&private'), TorrentFilter('idle&private')) self.assertEqual(TorrentFilter('idle&private'), TorrentFilter('private&idle')) self.assertEqual(TorrentFilter('idle|private'), TorrentFilter('private|idle')) self.assertNotEqual(TorrentFilter('idle|private'), TorrentFilter('idle&private')) self.assertEqual(TorrentFilter('idle|private&stopped'), TorrentFilter('stopped&private|idle')) self.assertNotEqual(TorrentFilter('idle|private&stopped'), TorrentFilter('private|idle&stopped')) self.assertEqual(TorrentFilter('idle|private&stopped|name~foo'), TorrentFilter('stopped&private|name~foo|idle')) self.assertNotEqual(TorrentFilter('idle|private&stopped|name~foo'), TorrentFilter('stopped&private|idle')) self.assertEqual(TorrentFilter('idle&active|private&stopped|name~foo'), TorrentFilter('stopped&private|name~foo|idle&active')) self.assertNotEqual( TorrentFilter('idle&active|private&stopped|name~foo'), TorrentFilter('stopped&private|name~foo|idle'))
def test_sequence_argument(self): f1 = TorrentFilter(['foo', 'bar']) f2 = TorrentFilter('foo|bar') self.assertEqual(f1, f2)
def test_any_allfilter_means_no_filters(self): f = TorrentFilter('name~f|all&public') self.assertEqual(f._filterchains, ())