Fix API so that the correct users are unsubscribed
This commit is contained in:
parent
723db8efac
commit
434c444333
2 changed files with 45 additions and 20 deletions
|
@ -72,6 +72,15 @@ class SchleuderApi:
|
||||||
subs.append(sub)
|
subs.append(sub)
|
||||||
return subs
|
return subs
|
||||||
|
|
||||||
|
def get_subscriber(self, email: str, schleuder: 'SchleuderList') -> 'SchleuderSubscriber':
|
||||||
|
response = self.__request('subscriptions.json', list_id=schleuder.id)
|
||||||
|
for r in response:
|
||||||
|
if r['email'] != email:
|
||||||
|
continue
|
||||||
|
key = self.get_key(r['fingerprint'], schleuder)
|
||||||
|
return SchleuderSubscriber.from_api(key, **r)
|
||||||
|
raise KeyError(f'{email} is not subscribed to {schleuder.name}')
|
||||||
|
|
||||||
def subscribe(self, sub: 'SchleuderSubscriber', schleuder: 'SchleuderList'):
|
def subscribe(self, sub: 'SchleuderSubscriber', schleuder: 'SchleuderList'):
|
||||||
if self._dry_run:
|
if self._dry_run:
|
||||||
return
|
return
|
||||||
|
@ -81,16 +90,18 @@ class SchleuderApi:
|
||||||
})
|
})
|
||||||
self.__request('subscriptions.json', list_id=schleuder.id, data=data, method='POST')
|
self.__request('subscriptions.json', list_id=schleuder.id, data=data, method='POST')
|
||||||
|
|
||||||
def unsubscribe(self, sub: 'SchleuderSubscriber'):
|
def unsubscribe(self, sub: 'SchleuderSubscriber', schleuder: 'SchleuderList'):
|
||||||
|
listsub = self.get_subscriber(sub.email, schleuder)
|
||||||
if self._dry_run:
|
if self._dry_run:
|
||||||
return
|
return
|
||||||
self.__request('subscriptions/{}.json', fmt=[sub.id], method='DELETE')
|
self.__request('subscriptions/{}.json', fmt=[listsub.id], method='DELETE')
|
||||||
|
|
||||||
def update_fingerprint(self, sub: 'SchleuderSubscriber'):
|
def update_fingerprint(self, sub: 'SchleuderSubscriber', schleuder: 'SchleuderList'):
|
||||||
|
listsub = self.get_subscriber(sub.email, schleuder)
|
||||||
if self._dry_run:
|
if self._dry_run:
|
||||||
return
|
return
|
||||||
data = json.dumps({'fingerprint': sub.key.fingerprint})
|
data = json.dumps({'fingerprint': sub.key.fingerprint})
|
||||||
self.__request('subscriptions/{}.json', fmt=[sub.id], data=data, method='PATCH')
|
self.__request('subscriptions/{}.json', fmt=[listsub.id], data=data, method='PATCH')
|
||||||
|
|
||||||
# Key Management
|
# Key Management
|
||||||
|
|
||||||
|
|
|
@ -102,11 +102,13 @@ class TestSchleuderApi(unittest.TestCase):
|
||||||
|
|
||||||
def read():
|
def read():
|
||||||
url = mock.call_args_list[-1][0][0].get_full_url()
|
url = mock.call_args_list[-1][0][0].get_full_url()
|
||||||
if 'lists.json' in url:
|
if '/lists' in url:
|
||||||
return _LIST_RESPONSE.encode()
|
return _LIST_RESPONSE.encode()
|
||||||
if 'subscriptions.json' in url:
|
if '/subscriptions' in url:
|
||||||
return _SUBSCRIBER_RESPONSE.encode()
|
return _SUBSCRIBER_RESPONSE.encode()
|
||||||
|
if '/keys' in url:
|
||||||
return _KEY_RESPONSE.encode()
|
return _KEY_RESPONSE.encode()
|
||||||
|
return b'null'
|
||||||
m.read = read
|
m.read = read
|
||||||
m.__enter__.return_value = m
|
m.__enter__.return_value = m
|
||||||
mock.return_value = m
|
mock.return_value = m
|
||||||
|
@ -145,6 +147,18 @@ class TestSchleuderApi(unittest.TestCase):
|
||||||
self.assertIn('-----BEGIN PGP PUBLIC KEY BLOCK-----', subs[0].key.blob)
|
self.assertIn('-----BEGIN PGP PUBLIC KEY BLOCK-----', subs[0].key.blob)
|
||||||
self.assertEqual(42, subs[0].key.schleuder)
|
self.assertEqual(42, subs[0].key.schleuder)
|
||||||
|
|
||||||
|
@patch('urllib.request.urlopen')
|
||||||
|
def test_get_subscriber(self, mock):
|
||||||
|
api = self._mock_api(mock)
|
||||||
|
sub = api.get_subscriber('foo@example.org', SchleuderList(42, '', ''))
|
||||||
|
self.assertEqual(23, sub.id)
|
||||||
|
self.assertEqual('foo@example.org', sub.email)
|
||||||
|
self.assertEqual('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', sub.key.fingerprint)
|
||||||
|
self.assertEqual(42, sub.key.schleuder)
|
||||||
|
self.assertEqual(42, sub.schleuder)
|
||||||
|
with self.assertRaises(KeyError):
|
||||||
|
api.get_subscriber('bar@example.org', SchleuderList(42, '', ''))
|
||||||
|
|
||||||
@patch('urllib.request.urlopen')
|
@patch('urllib.request.urlopen')
|
||||||
def test_subscribe(self, mock):
|
def test_subscribe(self, mock):
|
||||||
api = self._mock_api(mock)
|
api = self._mock_api(mock)
|
||||||
|
@ -153,8 +167,8 @@ class TestSchleuderApi(unittest.TestCase):
|
||||||
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
||||||
api.subscribe(sub, SchleuderList(42, '', ''))
|
api.subscribe(sub, SchleuderList(42, '', ''))
|
||||||
self.assertEqual('https://localhost:4443/subscriptions.json?list_id=42',
|
self.assertEqual('https://localhost:4443/subscriptions.json?list_id=42',
|
||||||
mock.call_args_list[0][0][0].get_full_url())
|
mock.call_args_list[-1][0][0].get_full_url())
|
||||||
self.assertEqual('POST', mock.call_args_list[0][0][0].method)
|
self.assertEqual('POST', mock.call_args_list[-1][0][0].method)
|
||||||
# todo assert request payload
|
# todo assert request payload
|
||||||
|
|
||||||
@patch('urllib.request.urlopen')
|
@patch('urllib.request.urlopen')
|
||||||
|
@ -163,10 +177,10 @@ class TestSchleuderApi(unittest.TestCase):
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
key = SchleuderKey('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', 'foo@example.org', 'verylongpgpkeyblock', 42)
|
key = SchleuderKey('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', 'foo@example.org', 'verylongpgpkeyblock', 42)
|
||||||
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
||||||
api.unsubscribe(sub)
|
api.unsubscribe(sub, SchleuderList(42, '', ''))
|
||||||
self.assertEqual('https://localhost:4443/subscriptions/23.json',
|
self.assertEqual('https://localhost:4443/subscriptions/23.json',
|
||||||
mock.call_args_list[0][0][0].get_full_url())
|
mock.call_args_list[-1][0][0].get_full_url())
|
||||||
self.assertEqual('DELETE', mock.call_args_list[0][0][0].method)
|
self.assertEqual('DELETE', mock.call_args_list[-1][0][0].method)
|
||||||
# todo assert request payload
|
# todo assert request payload
|
||||||
|
|
||||||
@patch('urllib.request.urlopen')
|
@patch('urllib.request.urlopen')
|
||||||
|
@ -175,10 +189,10 @@ class TestSchleuderApi(unittest.TestCase):
|
||||||
now = datetime.utcnow()
|
now = datetime.utcnow()
|
||||||
key = SchleuderKey('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', 'foo@example.org', 'verylongpgpkeyblock', 42)
|
key = SchleuderKey('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', 'foo@example.org', 'verylongpgpkeyblock', 42)
|
||||||
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
||||||
api.update_fingerprint(sub)
|
api.update_fingerprint(sub, SchleuderList(42, '', ''))
|
||||||
self.assertEqual('https://localhost:4443/subscriptions/23.json',
|
self.assertEqual('https://localhost:4443/subscriptions/23.json',
|
||||||
mock.call_args_list[0][0][0].get_full_url())
|
mock.call_args_list[-1][0][0].get_full_url())
|
||||||
self.assertEqual('PATCH', mock.call_args_list[0][0][0].method)
|
self.assertEqual('PATCH', mock.call_args_list[-1][0][0].method)
|
||||||
# todo assert request payload
|
# todo assert request payload
|
||||||
|
|
||||||
@patch('urllib.request.urlopen')
|
@patch('urllib.request.urlopen')
|
||||||
|
@ -220,15 +234,15 @@ class TestSchleuderApi(unittest.TestCase):
|
||||||
key = SchleuderKey('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', 'foo@example.org', 'verylongpgpkeyblock', 42)
|
key = SchleuderKey('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', 'foo@example.org', 'verylongpgpkeyblock', 42)
|
||||||
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
sub = SchleuderSubscriber(23, 'foo@example.org', key, 42, now)
|
||||||
sch = SchleuderList(42, '', '')
|
sch = SchleuderList(42, '', '')
|
||||||
# create, update, delete should be no-ops
|
# create, update, delete should be no-ops; 2 requests for retrieving the subscriptions in unsub & update
|
||||||
api.subscribe(sub, sch)
|
api.subscribe(sub, sch)
|
||||||
api.unsubscribe(sub)
|
api.unsubscribe(sub, sch)
|
||||||
api.update_fingerprint(sub)
|
api.update_fingerprint(sub, sch)
|
||||||
api.post_key(key, SchleuderList(42, '', ''))
|
api.post_key(key, SchleuderList(42, '', ''))
|
||||||
api.delete_key(key, SchleuderList(42, '', ''))
|
api.delete_key(key, SchleuderList(42, '', ''))
|
||||||
self.assertEqual(0, len(mock.call_args_list))
|
self.assertGreater(3, len(mock.call_args_list))
|
||||||
# only reads should execute
|
# only reads should execute
|
||||||
api.get_lists()
|
api.get_lists()
|
||||||
api.get_subscribers(sch)
|
api.get_subscribers(sch)
|
||||||
api.get_key('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', sch)
|
api.get_key('2FBBC0DF97FDBF1E4B704EEDE39EF4FAC420BEB6', sch)
|
||||||
self.assertLess(0, len(mock.call_args_list))
|
self.assertLess(2, len(mock.call_args_list))
|
||||||
|
|
Loading…
Reference in a new issue