Test rework + add account & fmi device test (#266)
* Rework tests * Add account test * Add Find My iPhone devices test * Remove logger * Working with Python 3.4 * Make test working in more setups @patch("keyring.get_password", return_value=None) * Fix Python 2.7 ASCII * Pylint * Self reviewed
This commit is contained in:
parent
d510b14570
commit
91ac1d956e
9 changed files with 1868 additions and 194 deletions
|
@ -56,9 +56,9 @@ class PyiCloudSession(Session):
|
||||||
|
|
||||||
def __init__(self, service):
|
def __init__(self, service):
|
||||||
self.service = service
|
self.service = service
|
||||||
super(PyiCloudSession, self).__init__()
|
Session.__init__(self)
|
||||||
|
|
||||||
def request(self, *args, **kwargs): # pylint: disable=arguments-differ
|
def request(self, method, url, **kwargs): # pylint: disable=arguments-differ
|
||||||
|
|
||||||
# Charge logging to the right service endpoint
|
# Charge logging to the right service endpoint
|
||||||
callee = inspect.stack()[2]
|
callee = inspect.stack()[2]
|
||||||
|
@ -67,10 +67,10 @@ class PyiCloudSession(Session):
|
||||||
if self.service.password_filter not in request_logger.filters:
|
if self.service.password_filter not in request_logger.filters:
|
||||||
request_logger.addFilter(self.service.password_filter)
|
request_logger.addFilter(self.service.password_filter)
|
||||||
|
|
||||||
request_logger.debug("%s %s %s", args[0], args[1], kwargs.get("data", ""))
|
request_logger.debug("%s %s %s", method, url, kwargs.get("data", ""))
|
||||||
|
|
||||||
kwargs.pop("retried", None)
|
kwargs.pop("retried", None)
|
||||||
response = super(PyiCloudSession, self).request(*args, **kwargs)
|
response = super(PyiCloudSession, self).request(method, url, **kwargs)
|
||||||
|
|
||||||
content_type = response.headers.get("Content-Type", "").split(";")[0]
|
content_type = response.headers.get("Content-Type", "").split(";")[0]
|
||||||
json_mimetypes = ["application/json", "text/json"]
|
json_mimetypes = ["application/json", "text/json"]
|
||||||
|
@ -82,7 +82,7 @@ class PyiCloudSession(Session):
|
||||||
)
|
)
|
||||||
request_logger.warn(api_error)
|
request_logger.warn(api_error)
|
||||||
kwargs["retried"] = True
|
kwargs["retried"] = True
|
||||||
return self.request(*args, **kwargs)
|
return self.request(method, url, **kwargs)
|
||||||
self._raise_error(response.status_code, response.reason)
|
self._raise_error(response.status_code, response.reason)
|
||||||
|
|
||||||
if content_type not in json_mimetypes:
|
if content_type not in json_mimetypes:
|
||||||
|
@ -150,6 +150,9 @@ class PyiCloudService(object):
|
||||||
pyicloud.iphone.location()
|
pyicloud.iphone.location()
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
HOME_ENDPOINT = "https://www.icloud.com"
|
||||||
|
SETUP_ENDPOINT = "https://setup.icloud.com/setup/ws/1"
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
apple_id,
|
apple_id,
|
||||||
|
@ -170,10 +173,7 @@ class PyiCloudService(object):
|
||||||
self.password_filter = PyiCloudPasswordFilter(password)
|
self.password_filter = PyiCloudPasswordFilter(password)
|
||||||
LOGGER.addFilter(self.password_filter)
|
LOGGER.addFilter(self.password_filter)
|
||||||
|
|
||||||
self._home_endpoint = "https://www.icloud.com"
|
self._base_login_url = "%s/login" % self.SETUP_ENDPOINT
|
||||||
self._setup_endpoint = "https://setup.icloud.com/setup/ws/1"
|
|
||||||
|
|
||||||
self._base_login_url = "%s/login" % self._setup_endpoint
|
|
||||||
|
|
||||||
if cookie_directory:
|
if cookie_directory:
|
||||||
self._cookie_directory = os.path.expanduser(
|
self._cookie_directory = os.path.expanduser(
|
||||||
|
@ -186,8 +186,8 @@ class PyiCloudService(object):
|
||||||
self.session.verify = verify
|
self.session.verify = verify
|
||||||
self.session.headers.update(
|
self.session.headers.update(
|
||||||
{
|
{
|
||||||
"Origin": self._home_endpoint,
|
"Origin": self.HOME_ENDPOINT,
|
||||||
"Referer": "%s/" % self._home_endpoint,
|
"Referer": "%s/" % self.HOME_ENDPOINT,
|
||||||
"User-Agent": "Opera/9.52 (X11; Linux i686; U; en)",
|
"User-Agent": "Opera/9.52 (X11; Linux i686; U; en)",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -270,7 +270,7 @@ class PyiCloudService(object):
|
||||||
def trusted_devices(self):
|
def trusted_devices(self):
|
||||||
"""Returns devices trusted for two-step authentication."""
|
"""Returns devices trusted for two-step authentication."""
|
||||||
request = self.session.get(
|
request = self.session.get(
|
||||||
"%s/listDevices" % self._setup_endpoint, params=self.params
|
"%s/listDevices" % self.SETUP_ENDPOINT, params=self.params
|
||||||
)
|
)
|
||||||
return request.json().get("devices")
|
return request.json().get("devices")
|
||||||
|
|
||||||
|
@ -278,7 +278,7 @@ class PyiCloudService(object):
|
||||||
"""Requests that a verification code is sent to the given device."""
|
"""Requests that a verification code is sent to the given device."""
|
||||||
data = json.dumps(device)
|
data = json.dumps(device)
|
||||||
request = self.session.post(
|
request = self.session.post(
|
||||||
"%s/sendVerificationCode" % self._setup_endpoint,
|
"%s/sendVerificationCode" % self.SETUP_ENDPOINT,
|
||||||
params=self.params,
|
params=self.params,
|
||||||
data=data,
|
data=data,
|
||||||
)
|
)
|
||||||
|
@ -291,7 +291,7 @@ class PyiCloudService(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.session.post(
|
self.session.post(
|
||||||
"%s/validateVerificationCode" % self._setup_endpoint,
|
"%s/validateVerificationCode" % self.SETUP_ENDPOINT,
|
||||||
params=self.params,
|
params=self.params,
|
||||||
data=data,
|
data=data,
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,13 +1,87 @@
|
||||||
"""Library tests."""
|
"""Library tests."""
|
||||||
|
import json
|
||||||
|
from requests import Session, Response
|
||||||
|
|
||||||
from pyicloud import base
|
from pyicloud import base
|
||||||
from pyicloud.exceptions import PyiCloudFailedLoginException
|
from pyicloud.exceptions import PyiCloudFailedLoginException
|
||||||
from pyicloud.services.findmyiphone import FindMyiPhoneServiceManager, AppleDevice
|
from pyicloud.services.findmyiphone import FindMyiPhoneServiceManager, AppleDevice
|
||||||
|
|
||||||
|
from .const import (
|
||||||
|
AUTHENTICATED_USER,
|
||||||
|
REQUIRES_2SA_USER,
|
||||||
|
VALID_USERS,
|
||||||
|
VALID_PASSWORD,
|
||||||
|
)
|
||||||
|
from .const_login import (
|
||||||
|
LOGIN_WORKING,
|
||||||
|
LOGIN_2SA,
|
||||||
|
TRUSTED_DEVICES,
|
||||||
|
TRUSTED_DEVICE_1,
|
||||||
|
VERIFICATION_CODE_OK,
|
||||||
|
VERIFICATION_CODE_KO,
|
||||||
|
)
|
||||||
|
from .const_account import ACCOUNT_DEVICES_WORKING
|
||||||
|
from .const_findmyiphone import FMI_FMLY_WORKING
|
||||||
|
|
||||||
AUTHENTICATED_USER = "authenticated_user"
|
|
||||||
REQUIRES_2SA_USER = "requires_2sa_user"
|
class ResponseMock(Response):
|
||||||
VALID_USERS = [AUTHENTICATED_USER, REQUIRES_2SA_USER]
|
"""Mocked Response."""
|
||||||
|
|
||||||
|
def __init__(self, result, status_code=200):
|
||||||
|
Response.__init__(self)
|
||||||
|
self.result = result
|
||||||
|
self.status_code = status_code
|
||||||
|
|
||||||
|
@property
|
||||||
|
def text(self):
|
||||||
|
return json.dumps(self.result)
|
||||||
|
|
||||||
|
|
||||||
|
class PyiCloudSessionMock(base.PyiCloudSession):
|
||||||
|
"""Mocked PyiCloudSession."""
|
||||||
|
|
||||||
|
def request(self, method, url, **kwargs):
|
||||||
|
data = json.loads(kwargs.get("data", "{}"))
|
||||||
|
|
||||||
|
# Login
|
||||||
|
if self.service.SETUP_ENDPOINT in url:
|
||||||
|
if "login" in url and method == "POST":
|
||||||
|
if (
|
||||||
|
data.get("apple_id") not in VALID_USERS
|
||||||
|
or data.get("password") != VALID_PASSWORD
|
||||||
|
):
|
||||||
|
self._raise_error(None, "Unknown reason")
|
||||||
|
if (
|
||||||
|
data.get("apple_id") == REQUIRES_2SA_USER
|
||||||
|
and data.get("password") == VALID_PASSWORD
|
||||||
|
):
|
||||||
|
return ResponseMock(LOGIN_2SA)
|
||||||
|
return ResponseMock(LOGIN_WORKING)
|
||||||
|
|
||||||
|
if "listDevices" in url and method == "GET":
|
||||||
|
return ResponseMock(TRUSTED_DEVICES)
|
||||||
|
|
||||||
|
if "sendVerificationCode" in url and method == "POST":
|
||||||
|
if data == TRUSTED_DEVICE_1:
|
||||||
|
return ResponseMock(VERIFICATION_CODE_OK)
|
||||||
|
return ResponseMock(VERIFICATION_CODE_KO)
|
||||||
|
|
||||||
|
if "validateVerificationCode" in url and method == "POST":
|
||||||
|
TRUSTED_DEVICE_1.update({"verificationCode": "0", "trustBrowser": True})
|
||||||
|
if data == TRUSTED_DEVICE_1:
|
||||||
|
self.service.user["apple_id"] = AUTHENTICATED_USER
|
||||||
|
return ResponseMock(VERIFICATION_CODE_OK)
|
||||||
|
self._raise_error(None, "FOUND_CODE")
|
||||||
|
|
||||||
|
# Account
|
||||||
|
if "device/getDevices" in url and method == "GET":
|
||||||
|
return ResponseMock(ACCOUNT_DEVICES_WORKING)
|
||||||
|
|
||||||
|
# Find My iPhone
|
||||||
|
if "fmi" in url and method == "POST":
|
||||||
|
return ResponseMock(FMI_FMLY_WORKING)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class PyiCloudServiceMock(base.PyiCloudService):
|
class PyiCloudServiceMock(base.PyiCloudService):
|
||||||
|
@ -22,174 +96,7 @@ class PyiCloudServiceMock(base.PyiCloudService):
|
||||||
client_id=None,
|
client_id=None,
|
||||||
with_family=True,
|
with_family=True,
|
||||||
):
|
):
|
||||||
|
base.PyiCloudSession = PyiCloudSessionMock
|
||||||
base.PyiCloudService.__init__(
|
base.PyiCloudService.__init__(
|
||||||
self, apple_id, password, cookie_directory, verify, client_id, with_family
|
self, apple_id, password, cookie_directory, verify, client_id, with_family
|
||||||
)
|
)
|
||||||
base.FindMyiPhoneServiceManager = FindMyiPhoneServiceManagerMock
|
|
||||||
|
|
||||||
def authenticate(self):
|
|
||||||
if (
|
|
||||||
not self.user.get("apple_id")
|
|
||||||
or self.user.get("apple_id") not in VALID_USERS
|
|
||||||
):
|
|
||||||
raise PyiCloudFailedLoginException(
|
|
||||||
"Invalid email/password combination.", None
|
|
||||||
)
|
|
||||||
if not self.user.get("password") or self.user.get("password") != "valid_pass":
|
|
||||||
raise PyiCloudFailedLoginException(
|
|
||||||
"Invalid email/password combination.", None
|
|
||||||
)
|
|
||||||
|
|
||||||
self.params.update({"dsid": "ID"})
|
|
||||||
self._webservices = {
|
|
||||||
"account": {"url": "account_url",},
|
|
||||||
"findme": {"url": "findme_url",},
|
|
||||||
"calendar": {"url": "calendar_url",},
|
|
||||||
"contacts": {"url": "contacts_url",},
|
|
||||||
"reminders": {"url": "reminders_url",},
|
|
||||||
}
|
|
||||||
|
|
||||||
@property
|
|
||||||
def requires_2sa(self):
|
|
||||||
return self.user["apple_id"] is REQUIRES_2SA_USER
|
|
||||||
|
|
||||||
@property
|
|
||||||
def trusted_devices(self):
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
"deviceType": "SMS",
|
|
||||||
"areaCode": "",
|
|
||||||
"phoneNumber": "*******58",
|
|
||||||
"deviceId": "1",
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
def send_verification_code(self, device):
|
|
||||||
return device
|
|
||||||
|
|
||||||
def validate_verification_code(self, device, code):
|
|
||||||
if not device or code != 0:
|
|
||||||
self.user["apple_id"] = AUTHENTICATED_USER
|
|
||||||
self.authenticate()
|
|
||||||
return not self.requires_2sa
|
|
||||||
|
|
||||||
|
|
||||||
IPHONE_DEVICE_ID = "X1x/X&x="
|
|
||||||
IPHONE_DEVICE = AppleDevice(
|
|
||||||
{
|
|
||||||
"msg": {
|
|
||||||
"strobe": False,
|
|
||||||
"userText": False,
|
|
||||||
"playSound": True,
|
|
||||||
"vibrate": True,
|
|
||||||
"createTimestamp": 1568031021347,
|
|
||||||
"statusCode": "200",
|
|
||||||
},
|
|
||||||
"canWipeAfterLock": True,
|
|
||||||
"baUUID": "",
|
|
||||||
"wipeInProgress": False,
|
|
||||||
"lostModeEnabled": False,
|
|
||||||
"activationLocked": True,
|
|
||||||
"passcodeLength": 6,
|
|
||||||
"deviceStatus": "200",
|
|
||||||
"deviceColor": "1-6-0",
|
|
||||||
"features": {
|
|
||||||
"MSG": True,
|
|
||||||
"LOC": True,
|
|
||||||
"LLC": False,
|
|
||||||
"CLK": False,
|
|
||||||
"TEU": True,
|
|
||||||
"LMG": False,
|
|
||||||
"SND": True,
|
|
||||||
"CLT": False,
|
|
||||||
"LKL": False,
|
|
||||||
"SVP": False,
|
|
||||||
"LST": True,
|
|
||||||
"LKM": False,
|
|
||||||
"WMG": True,
|
|
||||||
"SPN": False,
|
|
||||||
"XRM": False,
|
|
||||||
"PIN": False,
|
|
||||||
"LCK": True,
|
|
||||||
"REM": False,
|
|
||||||
"MCS": False,
|
|
||||||
"CWP": False,
|
|
||||||
"KEY": False,
|
|
||||||
"KPD": False,
|
|
||||||
"WIP": True,
|
|
||||||
},
|
|
||||||
"lowPowerMode": True,
|
|
||||||
"rawDeviceModel": "iPhone11,8",
|
|
||||||
"id": IPHONE_DEVICE_ID,
|
|
||||||
"remoteLock": None,
|
|
||||||
"isLocating": True,
|
|
||||||
"modelDisplayName": "iPhone",
|
|
||||||
"lostTimestamp": "",
|
|
||||||
"batteryLevel": 0.47999998927116394,
|
|
||||||
"mesg": None,
|
|
||||||
"locationEnabled": True,
|
|
||||||
"lockedTimestamp": None,
|
|
||||||
"locFoundEnabled": False,
|
|
||||||
"snd": {"createTimestamp": 1568031021347, "statusCode": "200"},
|
|
||||||
"fmlyShare": False,
|
|
||||||
"lostDevice": {
|
|
||||||
"stopLostMode": False,
|
|
||||||
"emailUpdates": False,
|
|
||||||
"userText": True,
|
|
||||||
"sound": False,
|
|
||||||
"ownerNbr": "",
|
|
||||||
"text": "",
|
|
||||||
"createTimestamp": 1558383841233,
|
|
||||||
"statusCode": "2204",
|
|
||||||
},
|
|
||||||
"lostModeCapable": True,
|
|
||||||
"wipedTimestamp": None,
|
|
||||||
"deviceDisplayName": "iPhone XR",
|
|
||||||
"prsId": None,
|
|
||||||
"audioChannels": [],
|
|
||||||
"locationCapable": True,
|
|
||||||
"batteryStatus": "NotCharging",
|
|
||||||
"trackingInfo": None,
|
|
||||||
"name": "Quentin's iPhone",
|
|
||||||
"isMac": False,
|
|
||||||
"thisDevice": False,
|
|
||||||
"deviceClass": "iPhone",
|
|
||||||
"location": {
|
|
||||||
"isOld": False,
|
|
||||||
"isInaccurate": False,
|
|
||||||
"altitude": 0.0,
|
|
||||||
"positionType": "GPS",
|
|
||||||
"latitude": 46.012345678,
|
|
||||||
"floorLevel": 0,
|
|
||||||
"horizontalAccuracy": 12.012345678,
|
|
||||||
"locationType": "",
|
|
||||||
"timeStamp": 1568827039692,
|
|
||||||
"locationFinished": False,
|
|
||||||
"verticalAccuracy": 0.0,
|
|
||||||
"longitude": 5.012345678,
|
|
||||||
},
|
|
||||||
"deviceModel": "iphoneXR-1-6-0",
|
|
||||||
"maxMsgChar": 160,
|
|
||||||
"darkWake": False,
|
|
||||||
"remoteWipe": None,
|
|
||||||
},
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
|
|
||||||
DEVICES = {
|
|
||||||
IPHONE_DEVICE_ID: IPHONE_DEVICE,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class FindMyiPhoneServiceManagerMock(FindMyiPhoneServiceManager):
|
|
||||||
"""Mocked FindMyiPhoneServiceManager."""
|
|
||||||
|
|
||||||
def __init__(self, service_root, session, params, with_family=False):
|
|
||||||
FindMyiPhoneServiceManager.__init__(
|
|
||||||
self, service_root, session, params, with_family
|
|
||||||
)
|
|
||||||
|
|
||||||
def refresh_client(self):
|
|
||||||
self._devices = DEVICES
|
|
||||||
|
|
10
tests/const.py
Normal file
10
tests/const.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
"""Test constants."""
|
||||||
|
from .const_login import PRIMARY_EMAIL, APPLE_ID_EMAIL, ICLOUD_ID_EMAIL
|
||||||
|
|
||||||
|
# Base
|
||||||
|
AUTHENTICATED_USER = PRIMARY_EMAIL
|
||||||
|
REQUIRES_2SA_USER = "requires_2sa_user"
|
||||||
|
VALID_USERS = [AUTHENTICATED_USER, REQUIRES_2SA_USER, APPLE_ID_EMAIL, ICLOUD_ID_EMAIL]
|
||||||
|
VALID_PASSWORD = "valid_password"
|
||||||
|
|
||||||
|
CLIENT_ID = "client_id"
|
77
tests/const_account.py
Normal file
77
tests/const_account.py
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Account test constants."""
|
||||||
|
from .const_login import FIRST_NAME
|
||||||
|
|
||||||
|
# Fakers
|
||||||
|
PAYMENT_METHOD_ID_1 = "PAYMENT_METHOD_ID_1"
|
||||||
|
PAYMENT_METHOD_ID_2 = "PAYMENT_METHOD_ID_2"
|
||||||
|
PAYMENT_METHOD_ID_3 = "PAYMENT_METHOD_ID_3"
|
||||||
|
PAYMENT_METHOD_ID_4 = "PAYMENT_METHOD_ID_4"
|
||||||
|
|
||||||
|
# Data
|
||||||
|
ACCOUNT_DEVICES_WORKING = {
|
||||||
|
"devices": [
|
||||||
|
{
|
||||||
|
"serialNumber": "●●●●●●●NG123",
|
||||||
|
"osVersion": "OSX;10.15.3",
|
||||||
|
"modelLargePhotoURL2x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/MacBookPro/MacBookPro15,1-spacegray/online-infobox__2x.png",
|
||||||
|
"modelLargePhotoURL1x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/MacBookPro/MacBookPro15,1-spacegray/online-infobox.png",
|
||||||
|
"paymentMethods": [PAYMENT_METHOD_ID_3],
|
||||||
|
"name": "MacBook Pro de " + FIRST_NAME,
|
||||||
|
"imei": "",
|
||||||
|
"model": "MacBookPro15,1",
|
||||||
|
"udid": "MacBookPro15,1" + FIRST_NAME,
|
||||||
|
"modelSmallPhotoURL2x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/MacBookPro/MacBookPro15,1-spacegray/online-sourcelist__2x.png",
|
||||||
|
"modelSmallPhotoURL1x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/MacBookPro/MacBookPro15,1-spacegray/online-sourcelist.png",
|
||||||
|
"modelDisplayName": 'MacBook Pro 15"',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"serialNumber": "●●●●●●●UX123",
|
||||||
|
"osVersion": "iOS;13.3",
|
||||||
|
"modelLargePhotoURL2x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/iPhone/iPhone12,1-1-6-0/online-infobox__2x.png",
|
||||||
|
"modelLargePhotoURL1x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/iPhone/iPhone12,1-1-6-0/online-infobox.png",
|
||||||
|
"paymentMethods": [
|
||||||
|
PAYMENT_METHOD_ID_4,
|
||||||
|
PAYMENT_METHOD_ID_2,
|
||||||
|
PAYMENT_METHOD_ID_1,
|
||||||
|
],
|
||||||
|
"name": "iPhone de " + FIRST_NAME,
|
||||||
|
"imei": "●●●●●●●●●●12345",
|
||||||
|
"model": "iPhone12,1",
|
||||||
|
"udid": "iPhone12,1" + FIRST_NAME,
|
||||||
|
"modelSmallPhotoURL2x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/iPhone/iPhone12,1-1-6-0/online-sourcelist__2x.png",
|
||||||
|
"modelSmallPhotoURL1x": "https://statici.icloud.com/fmipmobile/deviceImages-4.0/iPhone/iPhone12,1-1-6-0/online-sourcelist.png",
|
||||||
|
"modelDisplayName": "iPhone 11",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
"paymentMethods": [
|
||||||
|
{
|
||||||
|
"lastFourDigits": "333",
|
||||||
|
"balanceStatus": "NOTAPPLICABLE",
|
||||||
|
"suspensionReason": "ACTIVE",
|
||||||
|
"id": PAYMENT_METHOD_ID_3,
|
||||||
|
"type": "Boursorama Banque",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lastFourDigits": "444",
|
||||||
|
"balanceStatus": "NOTAPPLICABLE",
|
||||||
|
"suspensionReason": "ACTIVE",
|
||||||
|
"id": PAYMENT_METHOD_ID_4,
|
||||||
|
"type": "Carte Crédit Agricole",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lastFourDigits": "2222",
|
||||||
|
"balanceStatus": "NOTAPPLICABLE",
|
||||||
|
"suspensionReason": "ACTIVE",
|
||||||
|
"id": PAYMENT_METHOD_ID_2,
|
||||||
|
"type": "Lydia",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lastFourDigits": "111",
|
||||||
|
"balanceStatus": "NOTAPPLICABLE",
|
||||||
|
"suspensionReason": "ACTIVE",
|
||||||
|
"id": PAYMENT_METHOD_ID_1,
|
||||||
|
"type": "Boursorama Banque",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
1136
tests/const_findmyiphone.py
Normal file
1136
tests/const_findmyiphone.py
Normal file
File diff suppressed because it is too large
Load diff
413
tests/const_login.py
Normal file
413
tests/const_login.py
Normal file
|
@ -0,0 +1,413 @@
|
||||||
|
"""Login test constants."""
|
||||||
|
|
||||||
|
# Base
|
||||||
|
FIRST_NAME = "Quentin"
|
||||||
|
LAST_NAME = "TARANTINO"
|
||||||
|
FULL_NAME = FIRST_NAME + " " + LAST_NAME
|
||||||
|
|
||||||
|
PERSON_ID = (FIRST_NAME + LAST_NAME).lower()
|
||||||
|
NOTIFICATION_ID = "12345678-1234-1234-1234-123456789012" + PERSON_ID
|
||||||
|
A_DS_ID = "123456-12-12345678-1234-1234-1234-123456789012" + PERSON_ID
|
||||||
|
WIDGET_KEY = "widget_key" + PERSON_ID
|
||||||
|
|
||||||
|
PRIMARY_EMAIL = PERSON_ID + "@hotmail.fr"
|
||||||
|
APPLE_ID_EMAIL = PERSON_ID + "@me.com"
|
||||||
|
ICLOUD_ID_EMAIL = PERSON_ID + "@icloud.com"
|
||||||
|
|
||||||
|
|
||||||
|
# Data
|
||||||
|
LOGIN_WORKING = {
|
||||||
|
"dsInfo": {
|
||||||
|
"lastName": LAST_NAME,
|
||||||
|
"iCDPEnabled": False,
|
||||||
|
"tantorMigrated": True,
|
||||||
|
"dsid": PERSON_ID,
|
||||||
|
"hsaEnabled": True,
|
||||||
|
"ironcadeMigrated": True,
|
||||||
|
"locale": "fr-fr_FR",
|
||||||
|
"brZoneConsolidated": False,
|
||||||
|
"isManagedAppleID": False,
|
||||||
|
"gilligan-invited": "true",
|
||||||
|
"appleIdAliases": [APPLE_ID_EMAIL, ICLOUD_ID_EMAIL],
|
||||||
|
"hsaVersion": 2,
|
||||||
|
"isPaidDeveloper": False,
|
||||||
|
"countryCode": "FRA",
|
||||||
|
"notificationId": NOTIFICATION_ID,
|
||||||
|
"primaryEmailVerified": True,
|
||||||
|
"aDsID": A_DS_ID,
|
||||||
|
"locked": False,
|
||||||
|
"hasICloudQualifyingDevice": True,
|
||||||
|
"primaryEmail": PRIMARY_EMAIL,
|
||||||
|
"appleIdEntries": [
|
||||||
|
{"isPrimary": True, "type": "EMAIL", "value": PRIMARY_EMAIL},
|
||||||
|
{"type": "EMAIL", "value": APPLE_ID_EMAIL},
|
||||||
|
{"type": "EMAIL", "value": ICLOUD_ID_EMAIL},
|
||||||
|
],
|
||||||
|
"gilligan-enabled": "true",
|
||||||
|
"fullName": FULL_NAME,
|
||||||
|
"languageCode": "fr-fr",
|
||||||
|
"appleId": PRIMARY_EMAIL,
|
||||||
|
"firstName": FIRST_NAME,
|
||||||
|
"iCloudAppleIdAlias": ICLOUD_ID_EMAIL,
|
||||||
|
"notesMigrated": True,
|
||||||
|
"hasPaymentInfo": False,
|
||||||
|
"pcsDeleted": False,
|
||||||
|
"appleIdAlias": APPLE_ID_EMAIL,
|
||||||
|
"brMigrated": True,
|
||||||
|
"statusCode": 2,
|
||||||
|
"familyEligible": True,
|
||||||
|
},
|
||||||
|
"hasMinimumDeviceForPhotosWeb": True,
|
||||||
|
"iCDPEnabled": False,
|
||||||
|
"webservices": {
|
||||||
|
"reminders": {
|
||||||
|
"url": "https://p31-remindersws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"notes": {"url": "https://p38-notesws.icloud.com:443", "status": "active"},
|
||||||
|
"mail": {"url": "https://p38-mailws.icloud.com:443", "status": "active"},
|
||||||
|
"ckdatabasews": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-ckdatabasews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"photosupload": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-uploadphotosws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"photos": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"uploadUrl": "https://p31-uploadphotosws.icloud.com:443",
|
||||||
|
"url": "https://p31-photosws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"drivews": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-drivews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"uploadimagews": {
|
||||||
|
"url": "https://p31-uploadimagews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"schoolwork": {},
|
||||||
|
"cksharews": {"url": "https://p31-ckshare.icloud.com:443", "status": "active"},
|
||||||
|
"findme": {"url": "https://p31-fmipweb.icloud.com:443", "status": "active"},
|
||||||
|
"ckdeviceservice": {"url": "https://p31-ckdevice.icloud.com:443"},
|
||||||
|
"iworkthumbnailws": {
|
||||||
|
"url": "https://p31-iworkthumbnailws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"url": "https://p31-calendarws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"docws": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-docws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"url": "https://p31-settingsws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"ubiquity": {
|
||||||
|
"url": "https://p31-ubiquityws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"streams": {"url": "https://p31-streams.icloud.com:443", "status": "active"},
|
||||||
|
"keyvalue": {
|
||||||
|
"url": "https://p31-keyvalueservice.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"archivews": {
|
||||||
|
"url": "https://p31-archivews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"push": {"url": "https://p31-pushws.icloud.com:443", "status": "active"},
|
||||||
|
"iwmb": {"url": "https://p31-iwmb.icloud.com:443", "status": "active"},
|
||||||
|
"iworkexportws": {
|
||||||
|
"url": "https://p31-iworkexportws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"geows": {"url": "https://p31-geows.icloud.com:443", "status": "active"},
|
||||||
|
"account": {
|
||||||
|
"iCloudEnv": {"shortId": "p", "vipSuffix": "prod"},
|
||||||
|
"url": "https://p31-setup.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"fmf": {"url": "https://p31-fmfweb.icloud.com:443", "status": "active"},
|
||||||
|
"contacts": {
|
||||||
|
"url": "https://p31-contactsws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"pcsEnabled": True,
|
||||||
|
"configBag": {
|
||||||
|
"urls": {
|
||||||
|
"accountCreateUI": "https://appleid.apple.com/widget/account/?widgetKey="
|
||||||
|
+ WIDGET_KEY
|
||||||
|
+ "#!create",
|
||||||
|
"accountLoginUI": "https://idmsa.apple.com/appleauth/auth/signin?widgetKey="
|
||||||
|
+ WIDGET_KEY,
|
||||||
|
"accountLogin": "https://setup.icloud.com/setup/ws/1/accountLogin",
|
||||||
|
"accountRepairUI": "https://appleid.apple.com/widget/account/?widgetKey="
|
||||||
|
+ WIDGET_KEY
|
||||||
|
+ "#!repair",
|
||||||
|
"downloadICloudTerms": "https://setup.icloud.com/setup/ws/1/downloadLiteTerms",
|
||||||
|
"repairDone": "https://setup.icloud.com/setup/ws/1/repairDone",
|
||||||
|
"accountAuthorizeUI": "https://idmsa.apple.com/appleauth/auth/authorize/signin?client_id="
|
||||||
|
+ WIDGET_KEY,
|
||||||
|
"vettingUrlForEmail": "https://id.apple.com/IDMSEmailVetting/vetShareEmail",
|
||||||
|
"accountCreate": "https://setup.icloud.com/setup/ws/1/createLiteAccount",
|
||||||
|
"getICloudTerms": "https://setup.icloud.com/setup/ws/1/getTerms",
|
||||||
|
"vettingUrlForPhone": "https://id.apple.com/IDMSEmailVetting/vetSharePhone",
|
||||||
|
},
|
||||||
|
"accountCreateEnabled": "true",
|
||||||
|
},
|
||||||
|
"hsaTrustedBrowser": True,
|
||||||
|
"appsOrder": [
|
||||||
|
"mail",
|
||||||
|
"contacts",
|
||||||
|
"calendar",
|
||||||
|
"photos",
|
||||||
|
"iclouddrive",
|
||||||
|
"notes3",
|
||||||
|
"reminders",
|
||||||
|
"pages",
|
||||||
|
"numbers",
|
||||||
|
"keynote",
|
||||||
|
"newspublisher",
|
||||||
|
"fmf",
|
||||||
|
"find",
|
||||||
|
"settings",
|
||||||
|
],
|
||||||
|
"version": 2,
|
||||||
|
"isExtendedLogin": False,
|
||||||
|
"pcsServiceIdentitiesIncluded": True,
|
||||||
|
"hsaChallengeRequired": False,
|
||||||
|
"requestInfo": {"country": "FR", "timeZone": "GMT+1", "region": "IDF"},
|
||||||
|
"pcsDeleted": False,
|
||||||
|
"iCloudInfo": {"SafariBookmarksHasMigratedToCloudKit": True},
|
||||||
|
"apps": {
|
||||||
|
"calendar": {},
|
||||||
|
"reminders": {},
|
||||||
|
"keynote": {"isQualifiedForBeta": True},
|
||||||
|
"settings": {"canLaunchWithOneFactor": True},
|
||||||
|
"mail": {},
|
||||||
|
"numbers": {"isQualifiedForBeta": True},
|
||||||
|
"photos": {},
|
||||||
|
"pages": {"isQualifiedForBeta": True},
|
||||||
|
"notes3": {},
|
||||||
|
"find": {"canLaunchWithOneFactor": True},
|
||||||
|
"iclouddrive": {},
|
||||||
|
"newspublisher": {"isHidden": True},
|
||||||
|
"fmf": {},
|
||||||
|
"contacts": {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup data
|
||||||
|
LOGIN_2SA = {
|
||||||
|
"dsInfo": {
|
||||||
|
"lastName": LAST_NAME,
|
||||||
|
"iCDPEnabled": False,
|
||||||
|
"tantorMigrated": True,
|
||||||
|
"dsid": PERSON_ID,
|
||||||
|
"hsaEnabled": True,
|
||||||
|
"ironcadeMigrated": True,
|
||||||
|
"locale": "fr-fr_FR",
|
||||||
|
"brZoneConsolidated": False,
|
||||||
|
"isManagedAppleID": False,
|
||||||
|
"gilligan-invited": "true",
|
||||||
|
"appleIdAliases": [APPLE_ID_EMAIL, ICLOUD_ID_EMAIL],
|
||||||
|
"hsaVersion": 2,
|
||||||
|
"isPaidDeveloper": False,
|
||||||
|
"countryCode": "FRA",
|
||||||
|
"notificationId": NOTIFICATION_ID,
|
||||||
|
"primaryEmailVerified": True,
|
||||||
|
"aDsID": A_DS_ID,
|
||||||
|
"locked": False,
|
||||||
|
"hasICloudQualifyingDevice": True,
|
||||||
|
"primaryEmail": PRIMARY_EMAIL,
|
||||||
|
"appleIdEntries": [
|
||||||
|
{"isPrimary": True, "type": "EMAIL", "value": PRIMARY_EMAIL},
|
||||||
|
{"type": "EMAIL", "value": APPLE_ID_EMAIL},
|
||||||
|
{"type": "EMAIL", "value": ICLOUD_ID_EMAIL},
|
||||||
|
],
|
||||||
|
"gilligan-enabled": "true",
|
||||||
|
"fullName": FULL_NAME,
|
||||||
|
"languageCode": "fr-fr",
|
||||||
|
"appleId": PRIMARY_EMAIL,
|
||||||
|
"firstName": FIRST_NAME,
|
||||||
|
"iCloudAppleIdAlias": ICLOUD_ID_EMAIL,
|
||||||
|
"notesMigrated": True,
|
||||||
|
"hasPaymentInfo": True,
|
||||||
|
"pcsDeleted": False,
|
||||||
|
"appleIdAlias": APPLE_ID_EMAIL,
|
||||||
|
"brMigrated": True,
|
||||||
|
"statusCode": 2,
|
||||||
|
"familyEligible": True,
|
||||||
|
},
|
||||||
|
"hasMinimumDeviceForPhotosWeb": True,
|
||||||
|
"iCDPEnabled": False,
|
||||||
|
"webservices": {
|
||||||
|
"reminders": {
|
||||||
|
"url": "https://p31-remindersws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"notes": {"url": "https://p38-notesws.icloud.com:443", "status": "active"},
|
||||||
|
"mail": {"url": "https://p38-mailws.icloud.com:443", "status": "active"},
|
||||||
|
"ckdatabasews": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-ckdatabasews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"photosupload": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-uploadphotosws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"photos": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"uploadUrl": "https://p31-uploadphotosws.icloud.com:443",
|
||||||
|
"url": "https://p31-photosws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"drivews": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-drivews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"uploadimagews": {
|
||||||
|
"url": "https://p31-uploadimagews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"schoolwork": {},
|
||||||
|
"cksharews": {"url": "https://p31-ckshare.icloud.com:443", "status": "active"},
|
||||||
|
"findme": {"url": "https://p31-fmipweb.icloud.com:443", "status": "active"},
|
||||||
|
"ckdeviceservice": {"url": "https://p31-ckdevice.icloud.com:443"},
|
||||||
|
"iworkthumbnailws": {
|
||||||
|
"url": "https://p31-iworkthumbnailws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"calendar": {
|
||||||
|
"url": "https://p31-calendarws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"docws": {
|
||||||
|
"pcsRequired": True,
|
||||||
|
"url": "https://p31-docws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"url": "https://p31-settingsws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"ubiquity": {
|
||||||
|
"url": "https://p31-ubiquityws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"streams": {"url": "https://p31-streams.icloud.com:443", "status": "active"},
|
||||||
|
"keyvalue": {
|
||||||
|
"url": "https://p31-keyvalueservice.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"archivews": {
|
||||||
|
"url": "https://p31-archivews.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"push": {"url": "https://p31-pushws.icloud.com:443", "status": "active"},
|
||||||
|
"iwmb": {"url": "https://p31-iwmb.icloud.com:443", "status": "active"},
|
||||||
|
"iworkexportws": {
|
||||||
|
"url": "https://p31-iworkexportws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"geows": {"url": "https://p31-geows.icloud.com:443", "status": "active"},
|
||||||
|
"account": {
|
||||||
|
"iCloudEnv": {"shortId": "p", "vipSuffix": "prod"},
|
||||||
|
"url": "https://p31-setup.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
"fmf": {"url": "https://p31-fmfweb.icloud.com:443", "status": "active"},
|
||||||
|
"contacts": {
|
||||||
|
"url": "https://p31-contactsws.icloud.com:443",
|
||||||
|
"status": "active",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"pcsEnabled": True,
|
||||||
|
"configBag": {
|
||||||
|
"urls": {
|
||||||
|
"accountCreateUI": "https://appleid.apple.com/widget/account/?widgetKey="
|
||||||
|
+ WIDGET_KEY
|
||||||
|
+ "#!create",
|
||||||
|
"accountLoginUI": "https://idmsa.apple.com/appleauth/auth/signin?widgetKey="
|
||||||
|
+ WIDGET_KEY,
|
||||||
|
"accountLogin": "https://setup.icloud.com/setup/ws/1/accountLogin",
|
||||||
|
"accountRepairUI": "https://appleid.apple.com/widget/account/?widgetKey="
|
||||||
|
+ WIDGET_KEY
|
||||||
|
+ "#!repair",
|
||||||
|
"downloadICloudTerms": "https://setup.icloud.com/setup/ws/1/downloadLiteTerms",
|
||||||
|
"repairDone": "https://setup.icloud.com/setup/ws/1/repairDone",
|
||||||
|
"accountAuthorizeUI": "https://idmsa.apple.com/appleauth/auth/authorize/signin?client_id="
|
||||||
|
+ WIDGET_KEY,
|
||||||
|
"vettingUrlForEmail": "https://id.apple.com/IDMSEmailVetting/vetShareEmail",
|
||||||
|
"accountCreate": "https://setup.icloud.com/setup/ws/1/createLiteAccount",
|
||||||
|
"getICloudTerms": "https://setup.icloud.com/setup/ws/1/getTerms",
|
||||||
|
"vettingUrlForPhone": "https://id.apple.com/IDMSEmailVetting/vetSharePhone",
|
||||||
|
},
|
||||||
|
"accountCreateEnabled": "true",
|
||||||
|
},
|
||||||
|
"hsaTrustedBrowser": False,
|
||||||
|
"appsOrder": [
|
||||||
|
"mail",
|
||||||
|
"contacts",
|
||||||
|
"calendar",
|
||||||
|
"photos",
|
||||||
|
"iclouddrive",
|
||||||
|
"notes3",
|
||||||
|
"reminders",
|
||||||
|
"pages",
|
||||||
|
"numbers",
|
||||||
|
"keynote",
|
||||||
|
"newspublisher",
|
||||||
|
"fmf",
|
||||||
|
"find",
|
||||||
|
"settings",
|
||||||
|
],
|
||||||
|
"version": 2,
|
||||||
|
"isExtendedLogin": False,
|
||||||
|
"pcsServiceIdentitiesIncluded": False,
|
||||||
|
"hsaChallengeRequired": True,
|
||||||
|
"requestInfo": {"country": "FR", "timeZone": "GMT+1", "region": "IDF"},
|
||||||
|
"pcsDeleted": False,
|
||||||
|
"iCloudInfo": {"SafariBookmarksHasMigratedToCloudKit": True},
|
||||||
|
"apps": {
|
||||||
|
"calendar": {},
|
||||||
|
"reminders": {},
|
||||||
|
"keynote": {"isQualifiedForBeta": True},
|
||||||
|
"settings": {"canLaunchWithOneFactor": True},
|
||||||
|
"mail": {},
|
||||||
|
"numbers": {"isQualifiedForBeta": True},
|
||||||
|
"photos": {},
|
||||||
|
"pages": {"isQualifiedForBeta": True},
|
||||||
|
"notes3": {},
|
||||||
|
"find": {"canLaunchWithOneFactor": True},
|
||||||
|
"iclouddrive": {},
|
||||||
|
"newspublisher": {"isHidden": True},
|
||||||
|
"fmf": {},
|
||||||
|
"contacts": {},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
TRUSTED_DEVICE_1 = {
|
||||||
|
"deviceType": "SMS",
|
||||||
|
"areaCode": "",
|
||||||
|
"phoneNumber": "*******58",
|
||||||
|
"deviceId": "1",
|
||||||
|
}
|
||||||
|
TRUSTED_DEVICES = {"devices": [TRUSTED_DEVICE_1]}
|
||||||
|
|
||||||
|
VERIFICATION_CODE_OK = {"success": True}
|
||||||
|
VERIFICATION_CODE_KO = {"success": False}
|
33
tests/test_account.py
Normal file
33
tests/test_account.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
"""Account service tests."""
|
||||||
|
from unittest import TestCase
|
||||||
|
from . import PyiCloudServiceMock
|
||||||
|
from .const import AUTHENTICATED_USER, VALID_PASSWORD
|
||||||
|
|
||||||
|
|
||||||
|
class AccountServiceTest(TestCase):
|
||||||
|
""""Account service tests"""
|
||||||
|
|
||||||
|
service = None
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.service = PyiCloudServiceMock(AUTHENTICATED_USER, VALID_PASSWORD).account
|
||||||
|
|
||||||
|
def test_devices(self):
|
||||||
|
"""Tests devices."""
|
||||||
|
assert len(self.service.devices) == 2
|
||||||
|
|
||||||
|
for device in self.service.devices:
|
||||||
|
assert device.name
|
||||||
|
assert device.model
|
||||||
|
assert device.udid
|
||||||
|
assert device["serialNumber"]
|
||||||
|
assert device["osVersion"]
|
||||||
|
assert device["modelLargePhotoURL2x"]
|
||||||
|
assert device["modelLargePhotoURL1x"]
|
||||||
|
assert device["paymentMethods"]
|
||||||
|
assert device["name"]
|
||||||
|
assert device["model"]
|
||||||
|
assert device["udid"]
|
||||||
|
assert device["modelSmallPhotoURL2x"]
|
||||||
|
assert device["modelSmallPhotoURL1x"]
|
||||||
|
assert device["modelDisplayName"]
|
|
@ -1,6 +1,8 @@
|
||||||
"""Cmdline tests."""
|
"""Cmdline tests."""
|
||||||
from pyicloud import cmdline
|
from pyicloud import cmdline
|
||||||
from . import PyiCloudServiceMock, AUTHENTICATED_USER, REQUIRES_2SA_USER, DEVICES
|
from . import PyiCloudServiceMock
|
||||||
|
from .const import AUTHENTICATED_USER, REQUIRES_2SA_USER, VALID_PASSWORD
|
||||||
|
from .const_findmyiphone import FMI_FMLY_WORKING
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
@ -45,8 +47,11 @@ class TestCmdline(TestCase):
|
||||||
with pytest.raises(SystemExit, match="2"):
|
with pytest.raises(SystemExit, match="2"):
|
||||||
self.main(["--username"])
|
self.main(["--username"])
|
||||||
|
|
||||||
|
@patch("keyring.get_password", return_value=None)
|
||||||
@patch("getpass.getpass")
|
@patch("getpass.getpass")
|
||||||
def test_username_password_invalid(self, mock_getpass):
|
def test_username_password_invalid(
|
||||||
|
self, mock_getpass, mock_get_password
|
||||||
|
): # pylint: disable=unused-argument
|
||||||
"""Test username and password commands."""
|
"""Test username and password commands."""
|
||||||
# No password supplied
|
# No password supplied
|
||||||
mock_getpass.return_value = None
|
mock_getpass.return_value = None
|
||||||
|
@ -66,8 +71,11 @@ class TestCmdline(TestCase):
|
||||||
):
|
):
|
||||||
self.main(["--username", "invalid_user", "--password", "invalid_pass"])
|
self.main(["--username", "invalid_user", "--password", "invalid_pass"])
|
||||||
|
|
||||||
|
@patch("keyring.get_password", return_value=None)
|
||||||
@patch("pyicloud.cmdline.input")
|
@patch("pyicloud.cmdline.input")
|
||||||
def test_username_password_requires_2sa(self, mock_input):
|
def test_username_password_requires_2sa(
|
||||||
|
self, mock_input, mock_get_password
|
||||||
|
): # pylint: disable=unused-argument
|
||||||
"""Test username and password commands."""
|
"""Test username and password commands."""
|
||||||
# Valid connection for the first time
|
# Valid connection for the first time
|
||||||
mock_input.return_value = "0"
|
mock_input.return_value = "0"
|
||||||
|
@ -75,25 +83,29 @@ class TestCmdline(TestCase):
|
||||||
# fmt: off
|
# fmt: off
|
||||||
self.main([
|
self.main([
|
||||||
'--username', REQUIRES_2SA_USER,
|
'--username', REQUIRES_2SA_USER,
|
||||||
'--password', 'valid_pass',
|
'--password', VALID_PASSWORD,
|
||||||
'--non-interactive',
|
'--non-interactive',
|
||||||
])
|
])
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
def test_device_outputfile(self):
|
@patch("keyring.get_password", return_value=None)
|
||||||
|
def test_device_outputfile(
|
||||||
|
self, mock_get_password
|
||||||
|
): # pylint: disable=unused-argument
|
||||||
"""Test the outputfile command."""
|
"""Test the outputfile command."""
|
||||||
with pytest.raises(SystemExit, match="0"):
|
with pytest.raises(SystemExit, match="0"):
|
||||||
# fmt: off
|
# fmt: off
|
||||||
self.main([
|
self.main([
|
||||||
'--username', AUTHENTICATED_USER,
|
'--username', AUTHENTICATED_USER,
|
||||||
'--password', 'valid_pass',
|
'--password', VALID_PASSWORD,
|
||||||
'--non-interactive',
|
'--non-interactive',
|
||||||
'--outputfile'
|
'--outputfile'
|
||||||
])
|
])
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
for key in DEVICES:
|
devices = FMI_FMLY_WORKING.get("content")
|
||||||
file_name = DEVICES[key].content["name"].strip().lower() + ".fmip_snapshot"
|
for device in devices:
|
||||||
|
file_name = device.get("name").strip().lower() + ".fmip_snapshot"
|
||||||
|
|
||||||
pickle_file = open(file_name, "rb")
|
pickle_file = open(file_name, "rb")
|
||||||
assert pickle_file
|
assert pickle_file
|
||||||
|
@ -105,7 +117,7 @@ class TestCmdline(TestCase):
|
||||||
contents.append(pickle.load(opened_file))
|
contents.append(pickle.load(opened_file))
|
||||||
except EOFError:
|
except EOFError:
|
||||||
break
|
break
|
||||||
assert contents == [DEVICES[key].content]
|
assert contents == [device]
|
||||||
|
|
||||||
pickle_file.close()
|
pickle_file.close()
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
|
|
86
tests/test_findmyiphone.py
Normal file
86
tests/test_findmyiphone.py
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
"""Find My iPhone service tests."""
|
||||||
|
from unittest import TestCase
|
||||||
|
from . import PyiCloudServiceMock
|
||||||
|
from .const import AUTHENTICATED_USER, VALID_PASSWORD
|
||||||
|
|
||||||
|
|
||||||
|
class FindMyiPhoneServiceTest(TestCase):
|
||||||
|
""""Find My iPhone service tests"""
|
||||||
|
|
||||||
|
service = None
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.service = PyiCloudServiceMock(AUTHENTICATED_USER, VALID_PASSWORD)
|
||||||
|
|
||||||
|
def test_devices(self):
|
||||||
|
"""Tests devices."""
|
||||||
|
assert len(list(self.service.devices)) == 13
|
||||||
|
|
||||||
|
for device in self.service.devices:
|
||||||
|
assert device["canWipeAfterLock"] is not None
|
||||||
|
assert device["baUUID"] is not None
|
||||||
|
assert device["wipeInProgress"] is not None
|
||||||
|
assert device["lostModeEnabled"] is not None
|
||||||
|
assert device["activationLocked"] is not None
|
||||||
|
assert device["passcodeLength"] is not None
|
||||||
|
assert device["deviceStatus"] is not None
|
||||||
|
assert device["features"] is not None
|
||||||
|
assert device["lowPowerMode"] is not None
|
||||||
|
assert device["rawDeviceModel"] is not None
|
||||||
|
assert device["id"] is not None
|
||||||
|
assert device["isLocating"] is not None
|
||||||
|
assert device["modelDisplayName"] is not None
|
||||||
|
assert device["lostTimestamp"] is not None
|
||||||
|
assert device["batteryLevel"] is not None
|
||||||
|
assert device["locationEnabled"] is not None
|
||||||
|
assert device["locFoundEnabled"] is not None
|
||||||
|
assert device["fmlyShare"] is not None
|
||||||
|
assert device["lostModeCapable"] is not None
|
||||||
|
assert device["wipedTimestamp"] is None
|
||||||
|
assert device["deviceDisplayName"] is not None
|
||||||
|
assert device["audioChannels"] is not None
|
||||||
|
assert device["locationCapable"] is not None
|
||||||
|
assert device["batteryStatus"] is not None
|
||||||
|
assert device["trackingInfo"] is None
|
||||||
|
assert device["name"] is not None
|
||||||
|
assert device["isMac"] is not None
|
||||||
|
assert device["thisDevice"] is not None
|
||||||
|
assert device["deviceClass"] is not None
|
||||||
|
assert device["deviceModel"] is not None
|
||||||
|
assert device["maxMsgChar"] is not None
|
||||||
|
assert device["darkWake"] is not None
|
||||||
|
assert device["remoteWipe"] is None
|
||||||
|
|
||||||
|
assert device.data["canWipeAfterLock"] is not None
|
||||||
|
assert device.data["baUUID"] is not None
|
||||||
|
assert device.data["wipeInProgress"] is not None
|
||||||
|
assert device.data["lostModeEnabled"] is not None
|
||||||
|
assert device.data["activationLocked"] is not None
|
||||||
|
assert device.data["passcodeLength"] is not None
|
||||||
|
assert device.data["deviceStatus"] is not None
|
||||||
|
assert device.data["features"] is not None
|
||||||
|
assert device.data["lowPowerMode"] is not None
|
||||||
|
assert device.data["rawDeviceModel"] is not None
|
||||||
|
assert device.data["id"] is not None
|
||||||
|
assert device.data["isLocating"] is not None
|
||||||
|
assert device.data["modelDisplayName"] is not None
|
||||||
|
assert device.data["lostTimestamp"] is not None
|
||||||
|
assert device.data["batteryLevel"] is not None
|
||||||
|
assert device.data["locationEnabled"] is not None
|
||||||
|
assert device.data["locFoundEnabled"] is not None
|
||||||
|
assert device.data["fmlyShare"] is not None
|
||||||
|
assert device.data["lostModeCapable"] is not None
|
||||||
|
assert device.data["wipedTimestamp"] is None
|
||||||
|
assert device.data["deviceDisplayName"] is not None
|
||||||
|
assert device.data["audioChannels"] is not None
|
||||||
|
assert device.data["locationCapable"] is not None
|
||||||
|
assert device.data["batteryStatus"] is not None
|
||||||
|
assert device.data["trackingInfo"] is None
|
||||||
|
assert device.data["name"] is not None
|
||||||
|
assert device.data["isMac"] is not None
|
||||||
|
assert device.data["thisDevice"] is not None
|
||||||
|
assert device.data["deviceClass"] is not None
|
||||||
|
assert device.data["deviceModel"] is not None
|
||||||
|
assert device.data["maxMsgChar"] is not None
|
||||||
|
assert device.data["darkWake"] is not None
|
||||||
|
assert device.data["remoteWipe"] is None
|
Loading…
Reference in a new issue