1
1
"""Library tests."""
2
+ import json
3
+ from requests import Session , Response
2
4
3
5
from pyicloud import base
4
6
from pyicloud .exceptions import PyiCloudFailedLoginException
5
7
from pyicloud .services .findmyiphone import FindMyiPhoneServiceManager , AppleDevice
6
8
9
+ from .const import (
10
+ AUTHENTICATED_USER ,
11
+ REQUIRES_2SA_USER ,
12
+ VALID_USERS ,
13
+ VALID_PASSWORD ,
14
+ )
15
+ from .const_login import (
16
+ LOGIN_WORKING ,
17
+ LOGIN_2SA ,
18
+ TRUSTED_DEVICES ,
19
+ TRUSTED_DEVICE_1 ,
20
+ VERIFICATION_CODE_OK ,
21
+ VERIFICATION_CODE_KO ,
22
+ )
23
+ from .const_account import ACCOUNT_DEVICES_WORKING
24
+ from .const_findmyiphone import FMI_FMLY_WORKING
25
+
26
+
27
+ class ResponseMock (Response ):
28
+ """Mocked Response."""
29
+
30
+ def __init__ (self , result , status_code = 200 ):
31
+ Response .__init__ (self )
32
+ self .result = result
33
+ self .status_code = status_code
34
+
35
+ @property
36
+ def text (self ):
37
+ return json .dumps (self .result )
38
+
39
+
40
+ class PyiCloudSessionMock (base .PyiCloudSession ):
41
+ """Mocked PyiCloudSession."""
42
+
43
+ def request (self , method , url , ** kwargs ):
44
+ data = json .loads (kwargs .get ("data" , "{}" ))
45
+
46
+ # Login
47
+ if self .service .SETUP_ENDPOINT in url :
48
+ if "login" in url and method == "POST" :
49
+ if (
50
+ data .get ("apple_id" ) not in VALID_USERS
51
+ or data .get ("password" ) != VALID_PASSWORD
52
+ ):
53
+ self ._raise_error (None , "Unknown reason" )
54
+ if (
55
+ data .get ("apple_id" ) == REQUIRES_2SA_USER
56
+ and data .get ("password" ) == VALID_PASSWORD
57
+ ):
58
+ return ResponseMock (LOGIN_2SA )
59
+ return ResponseMock (LOGIN_WORKING )
60
+
61
+ if "listDevices" in url and method == "GET" :
62
+ return ResponseMock (TRUSTED_DEVICES )
63
+
64
+ if "sendVerificationCode" in url and method == "POST" :
65
+ if data == TRUSTED_DEVICE_1 :
66
+ return ResponseMock (VERIFICATION_CODE_OK )
67
+ return ResponseMock (VERIFICATION_CODE_KO )
68
+
69
+ if "validateVerificationCode" in url and method == "POST" :
70
+ TRUSTED_DEVICE_1 .update ({"verificationCode" : "0" , "trustBrowser" : True })
71
+ if data == TRUSTED_DEVICE_1 :
72
+ self .service .user ["apple_id" ] = AUTHENTICATED_USER
73
+ return ResponseMock (VERIFICATION_CODE_OK )
74
+ self ._raise_error (None , "FOUND_CODE" )
7
75
8
- AUTHENTICATED_USER = "authenticated_user"
9
- REQUIRES_2SA_USER = "requires_2sa_user"
10
- VALID_USERS = [AUTHENTICATED_USER , REQUIRES_2SA_USER ]
76
+ # Account
77
+ if "device/getDevices" in url and method == "GET" :
78
+ return ResponseMock (ACCOUNT_DEVICES_WORKING )
79
+
80
+ # Find My iPhone
81
+ if "fmi" in url and method == "POST" :
82
+ return ResponseMock (FMI_FMLY_WORKING )
83
+
84
+ return None
11
85
12
86
13
87
class PyiCloudServiceMock (base .PyiCloudService ):
@@ -22,174 +96,7 @@ def __init__(
22
96
client_id = None ,
23
97
with_family = True ,
24
98
):
99
+ base .PyiCloudSession = PyiCloudSessionMock
25
100
base .PyiCloudService .__init__ (
26
101
self , apple_id , password , cookie_directory , verify , client_id , with_family
27
102
)
28
- base .FindMyiPhoneServiceManager = FindMyiPhoneServiceManagerMock
29
-
30
- def authenticate (self ):
31
- if (
32
- not self .user .get ("apple_id" )
33
- or self .user .get ("apple_id" ) not in VALID_USERS
34
- ):
35
- raise PyiCloudFailedLoginException (
36
- "Invalid email/password combination." , None
37
- )
38
- if not self .user .get ("password" ) or self .user .get ("password" ) != "valid_pass" :
39
- raise PyiCloudFailedLoginException (
40
- "Invalid email/password combination." , None
41
- )
42
-
43
- self .params .update ({"dsid" : "ID" })
44
- self ._webservices = {
45
- "account" : {"url" : "account_url" ,},
46
- "findme" : {"url" : "findme_url" ,},
47
- "calendar" : {"url" : "calendar_url" ,},
48
- "contacts" : {"url" : "contacts_url" ,},
49
- "reminders" : {"url" : "reminders_url" ,},
50
- }
51
-
52
- @property
53
- def requires_2sa (self ):
54
- return self .user ["apple_id" ] is REQUIRES_2SA_USER
55
-
56
- @property
57
- def trusted_devices (self ):
58
- return [
59
- {
60
- "deviceType" : "SMS" ,
61
- "areaCode" : "" ,
62
- "phoneNumber" : "*******58" ,
63
- "deviceId" : "1" ,
64
- }
65
- ]
66
-
67
- def send_verification_code (self , device ):
68
- return device
69
-
70
- def validate_verification_code (self , device , code ):
71
- if not device or code != 0 :
72
- self .user ["apple_id" ] = AUTHENTICATED_USER
73
- self .authenticate ()
74
- return not self .requires_2sa
75
-
76
-
77
- IPHONE_DEVICE_ID = "X1x/X&x="
78
- IPHONE_DEVICE = AppleDevice (
79
- {
80
- "msg" : {
81
- "strobe" : False ,
82
- "userText" : False ,
83
- "playSound" : True ,
84
- "vibrate" : True ,
85
- "createTimestamp" : 1568031021347 ,
86
- "statusCode" : "200" ,
87
- },
88
- "canWipeAfterLock" : True ,
89
- "baUUID" : "" ,
90
- "wipeInProgress" : False ,
91
- "lostModeEnabled" : False ,
92
- "activationLocked" : True ,
93
- "passcodeLength" : 6 ,
94
- "deviceStatus" : "200" ,
95
- "deviceColor" : "1-6-0" ,
96
- "features" : {
97
- "MSG" : True ,
98
- "LOC" : True ,
99
- "LLC" : False ,
100
- "CLK" : False ,
101
- "TEU" : True ,
102
- "LMG" : False ,
103
- "SND" : True ,
104
- "CLT" : False ,
105
- "LKL" : False ,
106
- "SVP" : False ,
107
- "LST" : True ,
108
- "LKM" : False ,
109
- "WMG" : True ,
110
- "SPN" : False ,
111
- "XRM" : False ,
112
- "PIN" : False ,
113
- "LCK" : True ,
114
- "REM" : False ,
115
- "MCS" : False ,
116
- "CWP" : False ,
117
- "KEY" : False ,
118
- "KPD" : False ,
119
- "WIP" : True ,
120
- },
121
- "lowPowerMode" : True ,
122
- "rawDeviceModel" : "iPhone11,8" ,
123
- "id" : IPHONE_DEVICE_ID ,
124
- "remoteLock" : None ,
125
- "isLocating" : True ,
126
- "modelDisplayName" : "iPhone" ,
127
- "lostTimestamp" : "" ,
128
- "batteryLevel" : 0.47999998927116394 ,
129
- "mesg" : None ,
130
- "locationEnabled" : True ,
131
- "lockedTimestamp" : None ,
132
- "locFoundEnabled" : False ,
133
- "snd" : {"createTimestamp" : 1568031021347 , "statusCode" : "200" },
134
- "fmlyShare" : False ,
135
- "lostDevice" : {
136
- "stopLostMode" : False ,
137
- "emailUpdates" : False ,
138
- "userText" : True ,
139
- "sound" : False ,
140
- "ownerNbr" : "" ,
141
- "text" : "" ,
142
- "createTimestamp" : 1558383841233 ,
143
- "statusCode" : "2204" ,
144
- },
145
- "lostModeCapable" : True ,
146
- "wipedTimestamp" : None ,
147
- "deviceDisplayName" : "iPhone XR" ,
148
- "prsId" : None ,
149
- "audioChannels" : [],
150
- "locationCapable" : True ,
151
- "batteryStatus" : "NotCharging" ,
152
- "trackingInfo" : None ,
153
- "name" : "Quentin's iPhone" ,
154
- "isMac" : False ,
155
- "thisDevice" : False ,
156
- "deviceClass" : "iPhone" ,
157
- "location" : {
158
- "isOld" : False ,
159
- "isInaccurate" : False ,
160
- "altitude" : 0.0 ,
161
- "positionType" : "GPS" ,
162
- "latitude" : 46.012345678 ,
163
- "floorLevel" : 0 ,
164
- "horizontalAccuracy" : 12.012345678 ,
165
- "locationType" : "" ,
166
- "timeStamp" : 1568827039692 ,
167
- "locationFinished" : False ,
168
- "verticalAccuracy" : 0.0 ,
169
- "longitude" : 5.012345678 ,
170
- },
171
- "deviceModel" : "iphoneXR-1-6-0" ,
172
- "maxMsgChar" : 160 ,
173
- "darkWake" : False ,
174
- "remoteWipe" : None ,
175
- },
176
- None ,
177
- None ,
178
- None ,
179
- )
180
-
181
- DEVICES = {
182
- IPHONE_DEVICE_ID : IPHONE_DEVICE ,
183
- }
184
-
185
-
186
- class FindMyiPhoneServiceManagerMock (FindMyiPhoneServiceManager ):
187
- """Mocked FindMyiPhoneServiceManager."""
188
-
189
- def __init__ (self , service_root , session , params , with_family = False ):
190
- FindMyiPhoneServiceManager .__init__ (
191
- self , service_root , session , params , with_family
192
- )
193
-
194
- def refresh_client (self ):
195
- self ._devices = DEVICES
0 commit comments