summaryrefslogtreecommitdiff
path: root/tests/test_auth_device.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test_auth_device.py')
-rw-r--r--tests/test_auth_device.py557
1 files changed, 284 insertions, 273 deletions
diff --git a/tests/test_auth_device.py b/tests/test_auth_device.py
index 8504ba7..5ec42f3 100644
--- a/tests/test_auth_device.py
+++ b/tests/test_auth_device.py
@@ -29,58 +29,113 @@ def test_create_noauth(client):
'message': 'invalid request signature'
}
-@pytest.mark.parametrize("args,code,errno,error,message", [
- ({ 'name': 'dev', 'availableCommands': {'a':1} },
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({ 'name': 'dev', 'availableCommands': {'a':1}, 'extra': 0 },
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({},
- 400, 108, 'Bad Request', 'missing parameter in request body'),
- ({ 'id': '00' * 16, 'name': 'dev' },
- 400, 108, 'Bad Request', 'missing parameter in request body'),
-])
-def test_create_invalid(account_or_rt, args, code, errno, error, message):
- with pytest.raises(ClientError) as e:
- account_or_rt.post_a("/account/device", args)
- assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
-
-def test_destroy_noauth(client, populate_devices):
- with pytest.raises(ClientError) as e:
- client.post_a("/account/device/destroy")
- assert e.value.details == {
- 'code': 401,
- 'errno': 109,
- 'error': 'Unauthorized',
- 'message': 'invalid request signature'
- }
- with pytest.raises(ClientError) as e:
- client.post_a("/account/device/destroy", {'id': populate_devices[0]['id']})
- assert e.value.details == {
- 'code': 401,
- 'errno': 109,
- 'error': 'Unauthorized',
- 'message': 'invalid request signature'
- }
-
-@pytest.mark.parametrize("args,code,errno,error,message", [
- ({ 'id': '00' },
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({ 'id': '00' * 16, 'extra': 0 },
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({ 'id': '00' * 16 },
- 400, 123, 'Bad Request', 'unknown device'),
-])
-def test_destroy_invalid(account_or_rt, args, code, errno, error, message):
- with pytest.raises(ClientError) as e:
- account_or_rt.post_a("/account/device/destroy", args)
- assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
+class TestBadCreate:
+ @pytest.mark.parametrize("args,code,errno,error,message", [
+ ({ 'name': 'dev', 'availableCommands': {'a':1} },
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({ 'name': 'dev', 'availableCommands': {'a':1}, 'extra': 0 },
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({},
+ 400, 108, 'Bad Request', 'missing parameter in request body'),
+ ({ 'id': '00' * 16, 'name': 'dev' },
+ 400, 108, 'Bad Request', 'missing parameter in request body'),
+ ])
+ def test_create_invalid(self, account_or_rt, args, code, errno, error, message):
+ with pytest.raises(ClientError) as e:
+ account_or_rt.post_a("/account/device", args)
+ assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
+
+class TestDestroyNoauth:
+ def test_destroy_noauth(self, client, populate_devices):
+ with pytest.raises(ClientError) as e:
+ client.post_a("/account/device/destroy")
+ assert e.value.details == {
+ 'code': 401,
+ 'errno': 109,
+ 'error': 'Unauthorized',
+ 'message': 'invalid request signature'
+ }
+ with pytest.raises(ClientError) as e:
+ client.post_a("/account/device/destroy", {'id': populate_devices[0]['id']})
+ assert e.value.details == {
+ 'code': 401,
+ 'errno': 109,
+ 'error': 'Unauthorized',
+ 'message': 'invalid request signature'
+ }
+
+class TestDestroyInvalid:
+ @pytest.mark.parametrize("args,code,errno,error,message", [
+ ({ 'id': '00' },
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({ 'id': '00' * 16, 'extra': 0 },
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({ 'id': '00' * 16 },
+ 400, 123, 'Bad Request', 'unknown device'),
+ ])
+ def test_destroy_invalid(self, account_or_rt, args, code, errno, error, message):
+ with pytest.raises(ClientError) as e:
+ account_or_rt.post_a("/account/device/destroy", args)
+ assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
def test_create_destroy(account_or_rt):
dev = account_or_rt.post_a("/account/device", device_data[0])
account_or_rt.post_a("/account/device/destroy", {'id': dev['id']})
-def test_create_unverified(unverified_account):
- unverified_account.post_a("/account/device", device_data[0])
+class TestUnverified:
+ def test_create_unverified(self, unverified_account):
+ unverified_account.post_a("/account/device", device_data[0])
+
+ def test_list_unverified(self, unverified_account):
+ with pytest.raises(ClientError) as e:
+ unverified_account.get_a("/account/devices")
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 138,
+ 'error': 'Bad Request',
+ 'message': 'unverified session'
+ }
+
+ def test_invoke_unverified(self, unverified_account):
+ body = {"target": "0" * 32, "command": "foo", "payload": {}, "ttl": 10}
+ with pytest.raises(ClientError) as e:
+ unverified_account.post_a("/account/devices/invoke_command", body)
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 138,
+ 'error': 'Bad Request',
+ 'message': 'unverified session'
+ }
+
+ def test_commands_unverified(self, unverified_account):
+ with pytest.raises(ClientError) as e:
+ unverified_account.get_a("/account/device/commands?index=1")
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 138,
+ 'error': 'Bad Request',
+ 'message': 'unverified session'
+ }
+
+ def test_attached_clients_unverified(self, unverified_account):
+ with pytest.raises(ClientError) as e:
+ unverified_account.get_a("/account/attached_clients")
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 138,
+ 'error': 'Bad Request',
+ 'message': 'unverified session'
+ }
+
+ def test_attached_client_destroy_unverified(self, unverified_account):
+ with pytest.raises(ClientError) as e:
+ unverified_account.post_a("/account/attached_client/destroy")
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 138,
+ 'error': 'Bad Request',
+ 'message': 'unverified session'
+ }
def test_list_noauth(client):
with pytest.raises(ClientError) as e:
@@ -92,19 +147,10 @@ def test_list_noauth(client):
'message': 'invalid request signature'
}
-def test_list_unverified(unverified_account):
- with pytest.raises(ClientError) as e:
- unverified_account.get_a("/account/devices")
- assert e.value.details == {
- 'code': 400,
- 'errno': 138,
- 'error': 'Bad Request',
- 'message': 'unverified session'
- }
-
-def test_list_none(account_or_rt):
- devs = account_or_rt.get_a("/account/devices")
- assert devs == []
+class TestListNone:
+ def test_list_none(self, account_or_rt):
+ devs = account_or_rt.get_a("/account/devices")
+ assert devs == []
@pytest.mark.usefixtures("populate_devices")
def test_list(account_or_rt):
@@ -157,76 +203,68 @@ def test_invoke_noauth(client):
'message': 'invalid request signature'
}
-def test_invoke_unverified(unverified_account):
- body = {"target": "0" * 32, "command": "foo", "payload": {}, "ttl": 10}
- with pytest.raises(ClientError) as e:
- unverified_account.post_a("/account/devices/invoke_command", body)
- assert e.value.details == {
- 'code': 400,
- 'errno': 138,
- 'error': 'Bad Request',
- 'message': 'unverified session'
- }
-
-@pytest.mark.parametrize("args,code,errno,error,message", [
- ({"target": "00", "command": "foo", "payload": {}, "ttl": 10},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({"target": "00" * 16, "command": "foo", "payload": {}, "ttl": 10, 'extra': 0},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({"target": "0" * 32, "command": "foo", "payload": {}, "ttl": 10},
- 400, 123, 'Bad Request', 'unknown device'),
-])
-def test_invoke_invalid(account_or_rt, args, code, errno, error, message):
- with pytest.raises(ClientError) as e:
- account_or_rt.post_a("/account/devices/invoke_command", args)
- assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
-
-def test_invoke_nocmd(account_or_rt, populate_devices):
- body = {"target": populate_devices[0]['id'], "command": "foo", "payload": {}, "ttl": 10}
- with pytest.raises(ClientError) as e:
- account_or_rt.post_a("/account/devices/invoke_command", body)
- assert e.value.details == {
- 'code': 400,
- 'errno': 157,
- 'error': 'Bad Request',
- 'message': 'unavailable device command'
- }
+class TestBadInvoke:
+ @pytest.mark.parametrize("args,code,errno,error,message", [
+ ({"target": "00", "command": "foo", "payload": {}, "ttl": 10},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({"target": "00" * 16, "command": "foo", "payload": {}, "ttl": 10, 'extra': 0},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({"target": "0" * 32, "command": "foo", "payload": {}, "ttl": 10},
+ 400, 123, 'Bad Request', 'unknown device'),
+ ])
+ def test_invoke_invalid(self, account_or_rt, args, code, errno, error, message):
+ with pytest.raises(ClientError) as e:
+ account_or_rt.post_a("/account/devices/invoke_command", args)
+ assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
+
+ def test_invoke_nocmd(self, account_or_rt, populate_devices):
+ body = {"target": populate_devices[0]['id'], "command": "foo", "payload": {}, "ttl": 10}
+ with pytest.raises(ClientError) as e:
+ account_or_rt.post_a("/account/devices/invoke_command", body)
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 157,
+ 'error': 'Bad Request',
+ 'message': 'unavailable device command'
+ }
+
+class TestInvokeOther:
+ def test_invoke_other_account(self, account_or_rt, account2):
+ dev = account2.post_a("/account/device", device_data[0])
+ body = {"target": dev['id'], "command": "foo", "payload": {}, "ttl": 10}
+ with pytest.raises(ClientError) as e:
+ account_or_rt.post_a("/account/devices/invoke_command", body)
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 123,
+ 'error': 'Bad Request',
+ 'message': 'unknown device'
+ }
+
+class TestInvoke:
+ @pytest.mark.parametrize("ttl", [None, 1, 60, 999999999])
+ @pytest.mark.parametrize("has_sender", [False, True])
+ def test_invoke(self, account_or_rt, login, ttl, has_sender):
+ sender = account_or_rt.post_a("/account/device", device_data[1])['id'] if has_sender else None
+ dev = login.post_a("/account/device", device_data[0])
+
+ body = {
+ "target": dev['id'],
+ "command": "a",
+ "payload": { "data": str(random.random()), },
+ "ttl": ttl,
+ }
+ resp = account_or_rt.post_a("/account/devices/invoke_command", body)
+ assert resp['enqueued']
+ assert not resp['notified']
+ assert resp['notifyError'] == "no push callback"
-def test_invoke_other_account(account_or_rt, account2):
- dev = account2.post_a("/account/device", device_data[0])
- body = {"target": dev['id'], "command": "foo", "payload": {}, "ttl": 10}
- with pytest.raises(ClientError) as e:
- account_or_rt.post_a("/account/devices/invoke_command", body)
- assert e.value.details == {
- 'code': 400,
- 'errno': 123,
- 'error': 'Bad Request',
- 'message': 'unknown device'
- }
-
-@pytest.mark.parametrize("ttl", [None, 1, 60, 999999999])
-@pytest.mark.parametrize("has_sender", [False, True])
-def test_invoke(account_or_rt, login, ttl, has_sender):
- sender = account_or_rt.post_a("/account/device", device_data[1])['id'] if has_sender else None
- dev = login.post_a("/account/device", device_data[0])
-
- body = {
- "target": dev['id'],
- "command": "a",
- "payload": { "data": str(random.random()), },
- "ttl": ttl,
- }
- resp = account_or_rt.post_a("/account/devices/invoke_command", body)
- assert resp['enqueued']
- assert not resp['notified']
- assert resp['notifyError'] == "no push callback"
-
- cmd = login.get_a("/account/device/commands?index=0&limit=11")
- assert cmd['last']
- assert len(cmd['messages']) == 1
- assert cmd['messages'][0]['data']['command'] == 'a'
- assert cmd['messages'][0]['data']['payload'] == body['payload']
- assert cmd['messages'][0]['data']['sender'] == sender
+ cmd = login.get_a("/account/device/commands?index=0&limit=11")
+ assert cmd['last']
+ assert len(cmd['messages']) == 1
+ assert cmd['messages'][0]['data']['command'] == 'a'
+ assert cmd['messages'][0]['data']['payload'] == body['payload']
+ assert cmd['messages'][0]['data']['sender'] == sender
def test_commands_noauth(client):
with pytest.raises(ClientError) as e:
@@ -238,65 +276,56 @@ def test_commands_noauth(client):
'message': 'invalid request signature'
}
-def test_commands_unverified(unverified_account):
- with pytest.raises(ClientError) as e:
- unverified_account.get_a("/account/device/commands?index=1")
- assert e.value.details == {
- 'code': 400,
- 'errno': 138,
- 'error': 'Bad Request',
- 'message': 'unverified session'
- }
-
-def test_commands_nodev(account_or_rt):
- with pytest.raises(ClientError) as e:
- account_or_rt.get_a("/account/device/commands?index=1")
- assert e.value.details == {
- 'code': 400,
- 'errno': 123,
- 'error': 'Bad Request',
- 'message': 'unknown device'
- }
-
-@pytest.mark.parametrize('n_cmds,offset,limit', [
- (1, 0, 0),
- (1, 0, 1),
- (1, 0, 100),
- (1, 1, 0),
- (1, 1, 1),
- (1, 1, 100),
- (2, 0, 0),
- (2, 0, 1),
- (2, 0, 100),
- (2, 1, 0),
- (2, 1, 1),
- (2, 1, 100),
- (101, 0, 100),
- (101, 10, 100),
-])
-def test_device_commands_list(account_or_rt, login, n_cmds, offset, limit):
- account_or_rt.post_a("/account/device", device_data[1])['id']
- dev = login.post_a("/account/device", device_data[0])
-
- bodies = [ {
- "target": dev['id'],
- "command": "a",
- "payload": { "data": str(i), },
- } for i in range(0, n_cmds) ]
-
- for b in bodies:
- resp = account_or_rt.post_a("/account/devices/invoke_command", b)
- assert resp['enqueued']
- assert not resp['notified']
- assert resp['notifyError'] == "no push callback"
-
- cmd = login.get_a("/account/device/commands", params={ "index": 0, "limit": 1 })
- assert cmd == login.get_a("/account/device/commands", params={ "index": 0, "limit": 1 })
-
- first_index = cmd['index']
- cmds = login.get_a("/account/device/commands", params={ "limit": limit, "index": first_index + offset })
- assert cmds['last'] == (offset + limit >= n_cmds)
- assert len(cmds['messages']) == min(max(n_cmds - offset, 0), limit)
+class TestDeviceCommands:
+ def test_commands_nodev(self, account_or_rt):
+ with pytest.raises(ClientError) as e:
+ account_or_rt.get_a("/account/device/commands?index=1")
+ assert e.value.details == {
+ 'code': 400,
+ 'errno': 123,
+ 'error': 'Bad Request',
+ 'message': 'unknown device'
+ }
+
+ @pytest.mark.parametrize('n_cmds,offset,limit', [
+ (1, 0, 0),
+ (1, 0, 1),
+ (1, 0, 100),
+ (1, 1, 0),
+ (1, 1, 1),
+ (1, 1, 100),
+ (2, 0, 0),
+ (2, 0, 1),
+ (2, 0, 100),
+ (2, 1, 0),
+ (2, 1, 1),
+ (2, 1, 100),
+ (101, 0, 100),
+ (101, 10, 100),
+ ])
+ def test_device_commands_list(self, account_or_rt, login, n_cmds, offset, limit):
+ account_or_rt.post_a("/account/device", device_data[1])['id']
+ dev = login.post_a("/account/device", device_data[0])
+
+ bodies = [ {
+ "target": dev['id'],
+ "command": "a",
+ "payload": { "data": str(i), },
+ } for i in range(0, n_cmds) ]
+
+ for b in bodies:
+ resp = account_or_rt.post_a("/account/devices/invoke_command", b)
+ assert resp['enqueued']
+ assert not resp['notified']
+ assert resp['notifyError'] == "no push callback"
+
+ cmd = login.get_a("/account/device/commands", params={ "index": 0, "limit": 1 })
+ assert cmd == login.get_a("/account/device/commands", params={ "index": 0, "limit": 1 })
+
+ first_index = cmd['index']
+ cmds = login.get_a("/account/device/commands", params={ "limit": limit, "index": first_index + offset })
+ assert cmds['last'] == (offset + limit >= n_cmds)
+ assert len(cmds['messages']) == min(max(n_cmds - offset, 0), limit)
def test_attached_clients_unauth(client):
with pytest.raises(ClientError) as e:
@@ -308,25 +337,26 @@ def test_attached_clients_unauth(client):
'message': 'invalid request signature'
}
-def test_attached_clients_unverified(unverified_account):
- with pytest.raises(ClientError) as e:
- unverified_account.get_a("/account/attached_clients")
- assert e.value.details == {
- 'code': 400,
- 'errno': 138,
- 'error': 'Bad Request',
- 'message': 'unverified session'
- }
-
-def test_attached_clients_badauth(refresh_token):
- with pytest.raises(ClientError) as e:
- refresh_token.get_a("/account/attached_clients")
- assert e.value.details == {
- 'code': 401,
- 'errno': 109,
- 'error': 'Unauthorized',
- 'message': 'invalid request signature'
- }
+class TestAttachedClientBadauth:
+ def test_attached_clients_badauth(self, refresh_token):
+ with pytest.raises(ClientError) as e:
+ refresh_token.get_a("/account/attached_clients")
+ assert e.value.details == {
+ 'code': 401,
+ 'errno': 109,
+ 'error': 'Unauthorized',
+ 'message': 'invalid request signature'
+ }
+
+ def test_attached_client_destroy_badauth(self, refresh_token):
+ with pytest.raises(ClientError) as e:
+ refresh_token.post_a("/account/attached_client/destroy")
+ assert e.value.details == {
+ 'code': 401,
+ 'errno': 109,
+ 'error': 'Unauthorized',
+ 'message': 'invalid request signature'
+ }
def test_attached_clients(account, refresh_token, push_server):
dev1 = Device(account, "dev1")
@@ -366,69 +396,50 @@ def test_attached_client_destroy_unauth(client):
'message': 'invalid request signature'
}
-def test_attached_client_destroy_unverified(unverified_account):
- with pytest.raises(ClientError) as e:
- unverified_account.post_a("/account/attached_client/destroy")
- assert e.value.details == {
- 'code': 400,
- 'errno': 138,
- 'error': 'Bad Request',
- 'message': 'unverified session'
- }
-
-def test_attached_client_destroy_badauth(refresh_token):
- with pytest.raises(ClientError) as e:
- refresh_token.post_a("/account/attached_client/destroy")
- assert e.value.details == {
- 'code': 401,
- 'errno': 109,
- 'error': 'Unauthorized',
- 'message': 'invalid request signature'
- }
-
-@pytest.mark.parametrize("args,code,errno,error,message", [
- ({"sessionTokenId": "0"},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({"refreshTokenId": "0"},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({"deviceId": "0"},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({"sessionTokenId": "00" * 16, 'extra': 0},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({"sessionTokenId": "00" * 16, 'refreshTokenId': "00" * 16},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({"sessionTokenId": "00" * 16, 'refreshTokenId': "00" * 16, 'deviceId': "00" * 16},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
- ({'refreshTokenId': "00" * 16, 'deviceId': "00" * 16},
- 400, 107, 'Bad Request', 'invalid parameter in request body'),
-])
-def test_attached_client_destroy_invalid(account, args, code, errno, error, message):
- with pytest.raises(ClientError) as e:
- account.post_a("/account/attached_client/destroy", args)
- assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
-
-@pytest.mark.parametrize("fn", [
- (lambda d: {'sessionTokenId': d['sessionTokenId']}),
- (lambda d: {'refreshTokenId': d['refreshTokenId']}),
- (lambda d: {'deviceId': d['deviceId']}),
-], ids=["session", "refresh", "device"])
-def test_attached_client_destroy(account, refresh_token, fn):
- Device(refresh_token, "dev2")
- devs = account.get_a("/account/attached_clients")
- account.post_a("/account/attached_client/destroy", fn(devs[0]))
- devs2 = account.get_a("/account/attached_clients")
- assert len(devs2) == len(devs) - 1
-
-def test_attached_client_destroy_push(account, refresh_token, push_server):
- dev = Device(account, "dev")
- dev2 = Device(refresh_token, "dev2")
- dev.update_pcb(push_server.good("4ed8d1d3-e756-4866-9169-aafe612eb1e9"))
- account.post_a("/account/attached_client/destroy", { 'deviceId': dev2.id })
- p = push_server.wait()
- assert p[0] == "/4ed8d1d3-e756-4866-9169-aafe612eb1e9"
- assert dev.decrypt(p[2]) == {
- 'command': 'fxaccounts:device_disconnected',
- 'data': {'id': dev2.id},
- 'version': 1
- }
- assert push_server.done()
+class TestAttachedClients:
+ @pytest.mark.parametrize("args,code,errno,error,message", [
+ ({"sessionTokenId": "0"},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({"refreshTokenId": "0"},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({"deviceId": "0"},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({"sessionTokenId": "00" * 16, 'extra': 0},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({"sessionTokenId": "00" * 16, 'refreshTokenId': "00" * 16},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({"sessionTokenId": "00" * 16, 'refreshTokenId': "00" * 16, 'deviceId': "00" * 16},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ({'refreshTokenId': "00" * 16, 'deviceId': "00" * 16},
+ 400, 107, 'Bad Request', 'invalid parameter in request body'),
+ ])
+ def test_attached_client_destroy_invalid(self, account, args, code, errno, error, message):
+ with pytest.raises(ClientError) as e:
+ account.post_a("/account/attached_client/destroy", args)
+ assert e.value.details == {'code': code, 'errno': errno, 'error': error, 'message': message}
+
+ @pytest.mark.parametrize("fn", [
+ (lambda d: {'sessionTokenId': d['sessionTokenId']}),
+ (lambda d: {'refreshTokenId': d['refreshTokenId']}),
+ (lambda d: {'deviceId': d['deviceId']}),
+ ], ids=["session", "refresh", "device"])
+ def test_attached_client_destroy(self, account, refresh_token, fn):
+ Device(refresh_token, "dev2")
+ devs = account.get_a("/account/attached_clients")
+ account.post_a("/account/attached_client/destroy", fn(devs[0]))
+ devs2 = account.get_a("/account/attached_clients")
+ assert len(devs2) == len(devs) - 1
+
+ def test_attached_client_destroy_push(self, account, refresh_token, push_server):
+ dev = Device(account, "dev")
+ dev2 = Device(refresh_token, "dev2")
+ dev.update_pcb(push_server.good("4ed8d1d3-e756-4866-9169-aafe612eb1e9"))
+ account.post_a("/account/attached_client/destroy", { 'deviceId': dev2.id })
+ p = push_server.wait()
+ assert p[0] == "/4ed8d1d3-e756-4866-9169-aafe612eb1e9"
+ assert dev.decrypt(p[2]) == {
+ 'command': 'fxaccounts:device_disconnected',
+ 'data': {'id': dev2.id},
+ 'version': 1
+ }
+ assert push_server.done()