2020-03-24 12:08:27 +01:00
|
|
|
"""Cmdline tests."""
|
|
|
|
import os
|
|
|
|
import pickle
|
|
|
|
from unittest import TestCase
|
2022-02-16 20:00:29 +01:00
|
|
|
from unittest.mock import patch
|
2020-03-24 12:08:27 +01:00
|
|
|
|
2022-02-16 21:16:10 +01:00
|
|
|
import pytest
|
|
|
|
from pyicloud import cmdline
|
|
|
|
|
|
|
|
from . import PyiCloudServiceMock
|
|
|
|
from .const import AUTHENTICATED_USER, REQUIRES_2FA_USER, VALID_2FA_CODE, VALID_PASSWORD
|
|
|
|
from .const_findmyiphone import FMI_FAMILY_WORKING
|
|
|
|
|
2020-03-24 14:54:43 +01:00
|
|
|
|
2020-03-24 12:08:27 +01:00
|
|
|
class TestCmdline(TestCase):
|
|
|
|
"""Cmdline test cases."""
|
2020-03-24 14:54:43 +01:00
|
|
|
|
2020-03-24 12:08:27 +01:00
|
|
|
main = None
|
|
|
|
|
|
|
|
def setUp(self):
|
2022-02-16 21:16:10 +01:00
|
|
|
"""Set up tests."""
|
2020-03-24 12:08:27 +01:00
|
|
|
cmdline.PyiCloudService = PyiCloudServiceMock
|
|
|
|
self.main = cmdline.main
|
|
|
|
|
|
|
|
def test_no_arg(self):
|
|
|
|
"""Test no args."""
|
|
|
|
with pytest.raises(SystemExit, match="2"):
|
|
|
|
self.main()
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit, match="2"):
|
|
|
|
self.main(None)
|
|
|
|
|
|
|
|
with pytest.raises(SystemExit, match="2"):
|
|
|
|
self.main([])
|
|
|
|
|
|
|
|
def test_help(self):
|
|
|
|
"""Test the help command."""
|
|
|
|
with pytest.raises(SystemExit, match="0"):
|
2020-03-24 14:54:43 +01:00
|
|
|
self.main(["--help"])
|
2020-03-24 12:08:27 +01:00
|
|
|
|
|
|
|
def test_username(self):
|
|
|
|
"""Test the username command."""
|
|
|
|
# No username supplied
|
|
|
|
with pytest.raises(SystemExit, match="2"):
|
2020-03-24 14:54:43 +01:00
|
|
|
self.main(["--username"])
|
2020-03-24 12:08:27 +01:00
|
|
|
|
2020-04-03 18:50:12 +02:00
|
|
|
@patch("keyring.get_password", return_value=None)
|
2020-03-24 12:08:27 +01:00
|
|
|
@patch("getpass.getpass")
|
2020-04-03 18:50:12 +02:00
|
|
|
def test_username_password_invalid(
|
|
|
|
self, mock_getpass, mock_get_password
|
|
|
|
): # pylint: disable=unused-argument
|
2020-03-24 12:08:27 +01:00
|
|
|
"""Test username and password commands."""
|
|
|
|
# No password supplied
|
|
|
|
mock_getpass.return_value = None
|
|
|
|
with pytest.raises(SystemExit, match="2"):
|
2020-03-24 14:54:43 +01:00
|
|
|
self.main(["--username", "invalid_user"])
|
2020-03-24 12:08:27 +01:00
|
|
|
|
|
|
|
# Bad username or password
|
|
|
|
mock_getpass.return_value = "invalid_pass"
|
2020-03-24 14:54:43 +01:00
|
|
|
with pytest.raises(
|
|
|
|
RuntimeError, match="Bad username or password for invalid_user"
|
|
|
|
):
|
|
|
|
self.main(["--username", "invalid_user"])
|
2020-03-24 12:08:27 +01:00
|
|
|
|
|
|
|
# We should not use getpass for this one, but we reset the password at login fail
|
2020-03-24 14:54:43 +01:00
|
|
|
with pytest.raises(
|
|
|
|
RuntimeError, match="Bad username or password for invalid_user"
|
|
|
|
):
|
|
|
|
self.main(["--username", "invalid_user", "--password", "invalid_pass"])
|
2020-03-24 12:08:27 +01:00
|
|
|
|
2020-04-03 18:50:12 +02:00
|
|
|
@patch("keyring.get_password", return_value=None)
|
2020-03-24 14:54:43 +01:00
|
|
|
@patch("pyicloud.cmdline.input")
|
2020-10-29 17:51:08 +01:00
|
|
|
def test_username_password_requires_2fa(
|
2020-04-03 18:50:12 +02:00
|
|
|
self, mock_input, mock_get_password
|
|
|
|
): # pylint: disable=unused-argument
|
2020-03-24 12:08:27 +01:00
|
|
|
"""Test username and password commands."""
|
|
|
|
# Valid connection for the first time
|
2020-10-29 17:51:08 +01:00
|
|
|
mock_input.return_value = VALID_2FA_CODE
|
2020-03-24 12:08:27 +01:00
|
|
|
with pytest.raises(SystemExit, match="0"):
|
2020-03-24 14:54:43 +01:00
|
|
|
# fmt: off
|
2020-03-24 12:08:27 +01:00
|
|
|
self.main([
|
2020-10-29 17:51:08 +01:00
|
|
|
'--username', REQUIRES_2FA_USER,
|
2020-04-03 18:50:12 +02:00
|
|
|
'--password', VALID_PASSWORD,
|
2020-03-24 12:08:27 +01:00
|
|
|
'--non-interactive',
|
|
|
|
])
|
2020-03-24 14:54:43 +01:00
|
|
|
# fmt: on
|
2020-03-24 12:08:27 +01:00
|
|
|
|
2020-04-03 18:50:12 +02:00
|
|
|
@patch("keyring.get_password", return_value=None)
|
|
|
|
def test_device_outputfile(
|
|
|
|
self, mock_get_password
|
|
|
|
): # pylint: disable=unused-argument
|
2020-03-24 12:08:27 +01:00
|
|
|
"""Test the outputfile command."""
|
|
|
|
with pytest.raises(SystemExit, match="0"):
|
2020-03-24 14:54:43 +01:00
|
|
|
# fmt: off
|
2020-03-24 12:08:27 +01:00
|
|
|
self.main([
|
|
|
|
'--username', AUTHENTICATED_USER,
|
2020-04-03 18:50:12 +02:00
|
|
|
'--password', VALID_PASSWORD,
|
2020-03-24 12:08:27 +01:00
|
|
|
'--non-interactive',
|
|
|
|
'--outputfile'
|
|
|
|
])
|
2020-03-24 14:54:43 +01:00
|
|
|
# fmt: on
|
2020-03-24 12:08:27 +01:00
|
|
|
|
2020-04-04 00:48:32 +02:00
|
|
|
devices = FMI_FAMILY_WORKING.get("content")
|
2020-04-03 18:50:12 +02:00
|
|
|
for device in devices:
|
|
|
|
file_name = device.get("name").strip().lower() + ".fmip_snapshot"
|
2020-03-24 12:08:27 +01:00
|
|
|
|
|
|
|
pickle_file = open(file_name, "rb")
|
|
|
|
assert pickle_file
|
|
|
|
|
|
|
|
contents = []
|
|
|
|
with pickle_file as opened_file:
|
|
|
|
while True:
|
|
|
|
try:
|
|
|
|
contents.append(pickle.load(opened_file))
|
|
|
|
except EOFError:
|
|
|
|
break
|
2020-04-03 18:50:12 +02:00
|
|
|
assert contents == [device]
|
2020-03-24 12:08:27 +01:00
|
|
|
|
|
|
|
pickle_file.close()
|
|
|
|
os.remove(file_name)
|