diff --git a/.github/workflows/core.yml b/.github/workflows/core.yml
index c84a97d7..c2e9547c 100644
--- a/.github/workflows/core.yml
+++ b/.github/workflows/core.yml
@@ -28,8 +28,9 @@ jobs:
tox -e lint
- name: Integration Tests
env:
- PLATFORMIO_TEST_ACCOUNT_LOGIN: ${{ secrets.PLATFORMIO_TEST_ACCOUNT_LOGIN }}
- PLATFORMIO_TEST_ACCOUNT_PASSWORD: ${{ secrets.PLATFORMIO_TEST_ACCOUNT_PASSWORD }}
+ TEST_EMAIL_LOGIN: ${{ secrets.TEST_EMAIL_LOGIN }}
+ TEST_EMAIL_PASSWORD: ${{ secrets.TEST_EMAIL_PASSWORD }}
+ TEST_EMAIL_POP3_SERVER: ${{ secrets.TEST_EMAIL_POP3_SERVER }}
run: |
tox -e testcore
diff --git a/platformio/clients/account.py b/platformio/clients/account.py
index 9534777d..31e34f78 100644
--- a/platformio/clients/account.py
+++ b/platformio/clients/account.py
@@ -189,11 +189,14 @@ class AccountClient(RESTClient): # pylint:disable=too-many-public-methods
app.set_state_item("account", account)
return result
- def create_org(self, orgname, email, display_name):
+ def destroy_account(self):
+ return self.send_auth_request("delete", "/v1/account")
+
+ def create_org(self, orgname, email, displayname):
return self.send_auth_request(
"post",
"/v1/orgs",
- data={"orgname": orgname, "email": email, "displayname": display_name},
+ data={"orgname": orgname, "email": email, "displayname": displayname},
)
def get_org(self, orgname):
@@ -207,6 +210,9 @@ class AccountClient(RESTClient): # pylint:disable=too-many-public-methods
"put", "/v1/orgs/%s" % orgname, data={k: v for k, v in data.items() if v}
)
+ def destroy_org(self, orgname):
+ return self.send_auth_request("delete", "/v1/orgs/%s" % orgname,)
+
def add_org_owner(self, orgname, username):
return self.send_auth_request(
"post", "/v1/orgs/%s/owners" % orgname, data={"username": username},
diff --git a/platformio/commands/account.py b/platformio/commands/account.py
index c254dbee..3a1492ec 100644
--- a/platformio/commands/account.py
+++ b/platformio/commands/account.py
@@ -178,6 +178,23 @@ def account_update(current_password, **kwargs):
return click.secho("Please re-login.", fg="yellow")
+@cli.command("destroy", short_help="Destroy account")
+def account_destroy():
+ client = AccountClient()
+ click.confirm(
+ "Are you sure you want to delete the %s user account?\n"
+ "Warning! All linked data will be permanently removed and can not be restored."
+ % client.get_account_info().get("profile").get("username"),
+ abort=True,
+ )
+ client.destroy_account()
+ try:
+ client.logout()
+ except AccountNotAuthorized:
+ pass
+ return click.secho("User account has been destroyed.", fg="green",)
+
+
@cli.command("show", short_help="PIO Account information")
@click.option("--offline", is_flag=True)
@click.option("--json-output", is_flag=True)
diff --git a/platformio/commands/org.py b/platformio/commands/org.py
index 7d62120f..a7e0f1e9 100644
--- a/platformio/commands/org.py
+++ b/platformio/commands/org.py
@@ -39,10 +39,10 @@ def validate_orgname(value):
@click.option(
"--email", callback=lambda _, __, value: validate_email(value) if value else value
)
-@click.option("--display-name",)
-def org_create(orgname, email, display_name):
+@click.option("--displayname",)
+def org_create(orgname, email, displayname):
client = AccountClient()
- client.create_org(orgname, email, display_name)
+ client.create_org(orgname, email, displayname)
return click.secho(
"The organization %s has been successfully created." % orgname, fg="green",
)
@@ -82,7 +82,7 @@ def org_list(json_output):
"--new-orgname", callback=lambda _, __, value: validate_orgname(value),
)
@click.option("--email")
-@click.option("--display-name",)
+@click.option("--displayname",)
def org_update(orgname, **kwargs):
client = AccountClient()
org = client.get_org(orgname)
@@ -107,6 +107,20 @@ def org_update(orgname, **kwargs):
)
+@cli.command("destroy", short_help="Destroy organization")
+@click.argument("orgname")
+def account_destroy(orgname):
+ client = AccountClient()
+ click.confirm(
+ "Are you sure you want to delete the %s organization account?\n"
+ "Warning! All linked data will be permanently removed and can not be restored."
+ % orgname,
+ abort=True,
+ )
+ client.destroy_org(orgname)
+ return click.secho("Organization %s has been destroyed." % orgname, fg="green",)
+
+
@cli.command("add", short_help="Add a new owner to organization")
@click.argument("orgname",)
@click.argument("username",)
diff --git a/tests/commands/test_account.py b/tests/commands/test_account.py
index 1be778eb..221b724a 100644
--- a/tests/commands/test_account.py
+++ b/tests/commands/test_account.py
@@ -17,34 +17,29 @@ import os
import time
import pytest
+import requests
from platformio.commands.account import cli as cmd_account
-
-pytestmark = pytest.mark.skipif(
- not (
- os.environ.get("PLATFORMIO_TEST_ACCOUNT_LOGIN")
- and os.environ.get("PLATFORMIO_TEST_ACCOUNT_PASSWORD")
- ),
- reason="requires PLATFORMIO_TEST_ACCOUNT_LOGIN, PLATFORMIO_TEST_ACCOUNT_PASSWORD environ variables",
-)
+from platformio.commands.package import cli as cmd_package
+from platformio.downloader import FileDownloader
+from platformio.unpacker import FileUnpacker
-@pytest.fixture(scope="session")
-def credentials():
- return {
- "login": os.environ["PLATFORMIO_TEST_ACCOUNT_LOGIN"],
- "password": os.environ["PLATFORMIO_TEST_ACCOUNT_PASSWORD"],
- }
-
-
-def test_account_register_with_already_exists_username(
- clirunner, credentials, isolated_pio_home
+@pytest.mark.skipif(
+ not os.environ.get("TEST_EMAIL_LOGIN"),
+ reason="requires TEST_EMAIL_LOGIN, TEST_EMAIL_PASSWORD environ variables",
+) # pylint:disable=too-many-arguments
+def test_account(
+ clirunner, validate_cliresult, receive_email, isolated_pio_home, tmpdir_factory
):
- username = credentials["login"]
- email = "test@test.com"
- if "@" in credentials["login"]:
- username = "Testusername"
- email = credentials["login"]
+ username = "test-piocore-%s" % str(int(time.time() * 1000))
+ splited_email = os.environ.get("TEST_EMAIL_LOGIN").split("@")
+ email = "%s+%s@%s" % (splited_email[0], username, splited_email[1])
+ firstname = "Test"
+ lastname = "User"
+ password = "Qwerty123!"
+
+ # pio account register
result = clirunner.invoke(
cmd_account,
[
@@ -54,345 +49,33 @@ def test_account_register_with_already_exists_username(
"-e",
email,
"-p",
- credentials["password"],
+ password,
"--firstname",
- "First",
+ firstname,
"--lastname",
- "Last",
+ lastname,
],
)
- assert result.exit_code > 0
- assert result.exception
- assert "User with same username already exists" in str(
- result.exception
- ) or "User with same email already exists" in str(result.exception)
+ validate_cliresult(result)
+ # email verification
+ result = receive_email(email)
+ link = (
+ result.split("Click on the link below to start this process.")[1]
+ .split("This link will expire within 12 hours.")[0]
+ .strip()
+ )
+ session = requests.Session()
+ result = session.get(link).text
+ link = result.split(' 0
- assert result.exception
- assert "Invalid user credentials" in str(result.exception)
-
-
-def test_account_login(clirunner, credentials, validate_cliresult, isolated_pio_home):
+ # pio account login
+ result = clirunner.invoke(cmd_account, ["login", "-u", username, "-p", password],)
+ validate_cliresult(result)
try:
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
- assert "Successfully logged in!" in result.output
-
- with open(str(isolated_pio_home.join("appstate.json"))) as fp:
- appstate = json.load(fp)
- assert appstate.get("account")
- assert appstate.get("account").get("email")
- assert appstate.get("account").get("username")
- assert appstate.get("account").get("auth")
- assert appstate.get("account").get("auth").get("access_token")
- assert appstate.get("account").get("auth").get("access_token_expire")
- assert appstate.get("account").get("auth").get("refresh_token")
-
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- assert result.exit_code > 0
- assert result.exception
- assert "You are already authorized with" in str(result.exception)
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-def test_account_logout(clirunner, credentials, validate_cliresult, isolated_pio_home):
- try:
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(cmd_account, ["logout"])
- validate_cliresult(result)
- assert "Successfully logged out" in result.output
-
- result = clirunner.invoke(cmd_account, ["logout"])
- assert result.exit_code > 0
- assert result.exception
- assert "You are not authorized! Please log in to PIO Account" in str(
- result.exception
- )
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-@pytest.mark.skip_ci
-def test_account_password_change_with_invalid_old_password(
- clirunner, credentials, validate_cliresult
-):
- try:
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_account,
- ["password", "--old-password", "test", "--new-password", "test"],
- )
- assert result.exit_code > 0
- assert result.exception
- assert (
- "Invalid request data for new_password -> "
- "'Password must contain at least 8 "
- "characters including a number and a lowercase letter'"
- in str(result.exception)
- )
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-def test_account_password_change_with_invalid_new_password_format(
- clirunner, credentials, validate_cliresult
-):
- try:
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_account,
- [
- "password",
- "--old-password",
- credentials["password"],
- "--new-password",
- "test",
- ],
- )
- assert result.exit_code > 0
- assert result.exception
- assert (
- "Invalid request data for new_password -> "
- "'Password must contain at least 8 characters"
- " including a number and a lowercase letter'" in str(result.exception)
- )
-
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-@pytest.mark.skip_ci
-def test_account_password_change(
- clirunner, credentials, validate_cliresult, isolated_pio_home
-):
- try:
- result = clirunner.invoke(
- cmd_account,
- [
- "password",
- "--old-password",
- credentials["password"],
- "--new-password",
- "Testpassword123",
- ],
- )
- assert result.exit_code > 0
- assert result.exception
- assert "You are not authorized! Please log in to PIO Account" in str(
- result.exception
- )
-
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_account,
- [
- "password",
- "--old-password",
- credentials["password"],
- "--new-password",
- "Testpassword123",
- ],
- )
- validate_cliresult(result)
- assert "Password successfully changed!" in result.output
-
- result = clirunner.invoke(cmd_account, ["logout"])
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_account, ["login", "-u", credentials["login"], "-p", "Testpassword123"],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_account,
- [
- "password",
- "--old-password",
- "Testpassword123",
- "--new-password",
- credentials["password"],
- ],
- )
- validate_cliresult(result)
- assert "Password successfully changed!" in result.output
-
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-@pytest.mark.skip_ci
-def test_account_token_with_invalid_password(
- clirunner, credentials, validate_cliresult
-):
- try:
- result = clirunner.invoke(
- cmd_account, ["token", "--password", credentials["password"],],
- )
- assert result.exit_code > 0
- assert result.exception
- assert "You are not authorized! Please log in to PIO Account" in str(
- result.exception
- )
-
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(cmd_account, ["token", "--password", "test",],)
- assert result.exit_code > 0
- assert result.exception
- assert "Invalid user password" in str(result.exception)
-
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-def test_account_token(clirunner, credentials, validate_cliresult, isolated_pio_home):
- try:
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_account, ["token", "--password", credentials["password"],],
- )
- validate_cliresult(result)
- assert "Personal Authentication Token:" in result.output
- token = result.output.strip().split(": ")[-1]
-
- result = clirunner.invoke(
- cmd_account,
- ["token", "--password", credentials["password"], "--json-output"],
- )
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert json_result
- assert json_result.get("status") == "success"
- assert json_result.get("result") == token
- token = json_result.get("result")
-
- clirunner.invoke(cmd_account, ["logout"])
-
- result = clirunner.invoke(
- cmd_account, ["token", "--password", credentials["password"],],
- )
- assert result.exit_code > 0
- assert result.exception
- assert "You are not authorized! Please log in to PIO Account" in str(
- result.exception
- )
-
- os.environ["PLATFORMIO_AUTH_TOKEN"] = token
-
- result = clirunner.invoke(
- cmd_account,
- ["token", "--password", credentials["password"], "--json-output"],
- )
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert json_result
- assert json_result.get("status") == "success"
- assert json_result.get("result") == token
-
- os.environ.pop("PLATFORMIO_AUTH_TOKEN")
-
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-@pytest.mark.skip_ci
-def test_account_token_with_refreshing(
- clirunner, credentials, validate_cliresult, isolated_pio_home
-):
- try:
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_account,
- ["token", "--password", credentials["password"], "--json-output"],
- )
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert json_result
- assert json_result.get("status") == "success"
- assert json_result.get("result")
- token = json_result.get("result")
-
- result = clirunner.invoke(
- cmd_account,
- [
- "token",
- "--password",
- credentials["password"],
- "--json-output",
- "--regenerate",
- ],
- )
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert json_result
- assert json_result.get("status") == "success"
- assert json_result.get("result")
- assert token != json_result.get("result")
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-def test_account_summary(clirunner, credentials, validate_cliresult, isolated_pio_home):
- try:
- result = clirunner.invoke(cmd_account, ["show"],)
- assert result.exit_code > 0
- assert result.exception
- assert "You are not authorized! Please log in to PIO Account" in str(
- result.exception
- )
-
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
+ # pio account summary
result = clirunner.invoke(cmd_account, ["show", "--json-output", "--offline"])
validate_cliresult(result)
json_result = json.loads(result.output.strip())
@@ -405,9 +88,8 @@ def test_account_summary(clirunner, credentials, validate_cliresult, isolated_pi
result = clirunner.invoke(cmd_account, ["show"])
validate_cliresult(result)
- assert credentials["login"] in result.output
- assert "Community" in result.output
- assert "100 Concurrent Remote Agents" in result.output
+ assert username in result.output
+ # assert "100 Concurrent Remote Agents" in result.output
result = clirunner.invoke(cmd_account, ["show", "--json-output"])
validate_cliresult(result)
@@ -416,9 +98,9 @@ def test_account_summary(clirunner, credentials, validate_cliresult, isolated_pi
assert json_result.get("profile")
assert json_result.get("profile").get("username")
assert json_result.get("profile").get("email")
- assert credentials["login"] == json_result.get("profile").get(
+ assert username == json_result.get("profile").get(
"username"
- ) or credentials["login"] == json_result.get("profile").get("email")
+ ) or username == json_result.get("profile").get("email")
assert json_result.get("profile").get("firstname")
assert json_result.get("profile").get("lastname")
assert json_result.get("packages")
@@ -433,147 +115,121 @@ def test_account_summary(clirunner, credentials, validate_cliresult, isolated_pi
assert json_result.get("profile")
assert json_result.get("profile").get("username")
assert json_result.get("profile").get("email")
- assert credentials["login"] == json_result.get("profile").get(
+ assert username == json_result.get("profile").get(
"username"
- ) or credentials["login"] == json_result.get("profile").get("email")
+ ) or username == json_result.get("profile").get("email")
assert json_result.get("profile").get("firstname")
assert json_result.get("profile").get("lastname")
assert json_result.get("packages")
assert json_result.get("packages")[0].get("name")
assert json_result.get("packages")[0].get("path")
assert json_result.get("subscriptions") is not None
- finally:
+
+ # pio account token
+ result = clirunner.invoke(cmd_account, ["token", "--password", password,],)
+ validate_cliresult(result)
+ assert "Personal Authentication Token:" in result.output
+ token = result.output.strip().split(": ")[-1]
+
+ result = clirunner.invoke(
+ cmd_account, ["token", "--password", password, "--json-output"],
+ )
+ validate_cliresult(result)
+ json_result = json.loads(result.output.strip())
+ assert json_result
+ assert json_result.get("status") == "success"
+ assert json_result.get("result") == token
+ token = json_result.get("result")
+
clirunner.invoke(cmd_account, ["logout"])
-
-@pytest.mark.skip_ci
-def test_account_profile_update_with_invalid_password(
- clirunner, credentials, validate_cliresult
-):
- try:
- result = clirunner.invoke(
- cmd_account, ["update", "--current-password", credentials["password"]],
- )
+ result = clirunner.invoke(cmd_account, ["token", "--password", password,],)
assert result.exit_code > 0
assert result.exception
assert "You are not authorized! Please log in to PIO Account" in str(
result.exception
)
+ os.environ["PLATFORMIO_AUTH_TOKEN"] = token
+
result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
+ cmd_account, ["token", "--password", password, "--json-output"],
+ )
+ validate_cliresult(result)
+ json_result = json.loads(result.output.strip())
+ assert json_result
+ assert json_result.get("status") == "success"
+ assert json_result.get("result") == token
+
+ os.environ.pop("PLATFORMIO_AUTH_TOKEN")
+
+ result = clirunner.invoke(
+ cmd_account, ["login", "-u", username, "-p", password],
)
validate_cliresult(result)
- firstname = "First " + str(int(time.time() * 1000))
-
+ # pio account password
+ new_password = "Testpassword123"
result = clirunner.invoke(
cmd_account,
- ["update", "--current-password", "test", "--firstname", firstname],
+ ["password", "--old-password", password, "--new-password", new_password,],
)
- assert result.exit_code > 0
- assert result.exception
- assert "Invalid user password" in str(result.exception)
- finally:
+ validate_cliresult(result)
+ assert "Password successfully changed!" in result.output
+
clirunner.invoke(cmd_account, ["logout"])
-
-@pytest.mark.skip_ci
-def test_account_profile_update_only_firstname_and_lastname(
- clirunner, credentials, validate_cliresult, isolated_pio_home
-):
- try:
result = clirunner.invoke(
- cmd_account, ["update", "--current-password", credentials["password"]],
- )
- assert result.exit_code > 0
- assert result.exception
- assert "You are not authorized! Please log in to PIO Account" in str(
- result.exception
- )
-
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
+ cmd_account, ["login", "-u", username, "-p", new_password],
)
validate_cliresult(result)
+ result = clirunner.invoke(
+ cmd_account,
+ ["password", "--old-password", new_password, "--new-password", password,],
+ )
+ validate_cliresult(result)
+
+ # pio account update
firstname = "First " + str(int(time.time() * 1000))
lastname = "Last" + str(int(time.time() * 1000))
- result = clirunner.invoke(
- cmd_account,
- [
- "update",
- "--current-password",
- credentials["password"],
- "--firstname",
- firstname,
- "--lastname",
- lastname,
- ],
- )
- validate_cliresult(result)
- assert "Profile successfully updated!" in result.output
-
- result = clirunner.invoke(cmd_account, ["show", "--json-output"])
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert json_result.get("profile").get("firstname") == firstname
- assert json_result.get("profile").get("lastname") == lastname
-
- finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-@pytest.mark.skip_ci
-def test_account_profile_update(
- clirunner, credentials, validate_cliresult, isolated_pio_home
-):
- try:
- result = clirunner.invoke(
- cmd_account, ["update", "--current-password", credentials["password"]],
- )
- assert result.exit_code > 0
- assert result.exception
- assert "You are not authorized! Please log in to PIO Account" in str(
- result.exception
- )
-
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(cmd_account, ["show", "--json-output"])
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
-
- firstname = "First " + str(int(time.time() * 1000))
- lastname = "Last" + str(int(time.time() * 1000))
-
- old_username = json_result.get("profile").get("username")
new_username = "username" + str(int(time.time() * 1000))[-5:]
-
+ new_email = "%s+new-%s@%s" % (splited_email[0], username, splited_email[1])
result = clirunner.invoke(
cmd_account,
[
"update",
"--current-password",
- credentials["password"],
+ password,
"--firstname",
firstname,
"--lastname",
lastname,
"--username",
new_username,
+ "--email",
+ new_email,
],
)
validate_cliresult(result)
assert "Profile successfully updated!" in result.output
- assert "Please re-login." in result.output
+ assert (
+ "Please check your mail to verify your new email address and re-login. "
+ in result.output
+ )
+
+ result = receive_email(new_email)
+ link = (
+ result.split("Click on the link below to start this process.")[1]
+ .split("This link will expire within 12 hours.")[0]
+ .strip()
+ )
+ session = requests.Session()
+ result = session.get(link).text
+ link = result.split(' 0
@@ -583,27 +239,39 @@ def test_account_profile_update(
)
result = clirunner.invoke(
- cmd_account, ["login", "-u", new_username, "-p", credentials["password"]],
+ cmd_account, ["login", "-u", new_username, "-p", password],
)
validate_cliresult(result)
- result = clirunner.invoke(
- cmd_account,
- [
- "update",
- "--current-password",
- credentials["password"],
- "--username",
- old_username,
- ],
- )
- validate_cliresult(result)
- assert "Profile successfully updated!" in result.output
- assert "Please re-login." in result.output
+ # pio account destroy with linked resource
- result = clirunner.invoke(
- cmd_account, ["login", "-u", old_username, "-p", credentials["password"]],
+ package_url = "https://github.com/bblanchon/ArduinoJson/archive/v6.11.0.tar.gz"
+
+ tmp_dir = tmpdir_factory.mktemp("package")
+ fd = FileDownloader(package_url, str(tmp_dir))
+ pkg_dir = tmp_dir.mkdir("raw_package")
+ fd.start(with_progress=False, silent=True)
+ with FileUnpacker(fd.get_filepath()) as unpacker:
+ unpacker.unpack(str(pkg_dir), with_progress=False, silent=True)
+
+ result = clirunner.invoke(cmd_package, ["publish", str(pkg_dir)],)
+ validate_cliresult(result)
+ try:
+ result = receive_email(new_email)
+ assert "Congrats" in result
+ assert "was published" in result
+ except: # pylint:disable=bare-except
+ pass
+
+ result = clirunner.invoke(cmd_account, ["destroy"], "y")
+ assert result.exit_code != 0
+ assert (
+ "We can not destroy the %s account due to 1 linked resources from registry"
+ % username
)
+
+ result = clirunner.invoke(cmd_package, ["unpublish", "ArduinoJson"],)
validate_cliresult(result)
finally:
- clirunner.invoke(cmd_account, ["logout"])
+ result = clirunner.invoke(cmd_account, ["destroy"], "y")
+ validate_cliresult(result)
diff --git a/tests/commands/test_orgs.py b/tests/commands/test_orgs.py
index 4650caaf..3af38e83 100644
--- a/tests/commands/test_orgs.py
+++ b/tests/commands/test_orgs.py
@@ -14,142 +14,150 @@
import json
import os
+import time
import pytest
+import requests
from platformio.commands.account import cli as cmd_account
from platformio.commands.org import cli as cmd_org
-pytestmark = pytest.mark.skipif(
- not (
- os.environ.get("PLATFORMIO_TEST_ACCOUNT_LOGIN")
- and os.environ.get("PLATFORMIO_TEST_ACCOUNT_PASSWORD")
- ),
- reason="requires PLATFORMIO_TEST_ACCOUNT_LOGIN, PLATFORMIO_TEST_ACCOUNT_PASSWORD environ variables",
-)
+@pytest.mark.skipif(
+ not os.environ.get("TEST_EMAIL_LOGIN"),
+ reason="requires TEST_EMAIL_LOGIN, TEST_EMAIL_PASSWORD environ variables",
+) # pylint:disable=too-many-arguments
+def test_org(clirunner, validate_cliresult, receive_email, isolated_pio_home):
+ username = "test-piocore-%s" % str(int(time.time() * 1000))
+ splited_email = os.environ.get("TEST_EMAIL_LOGIN").split("@")
+ email = "%s+%s@%s" % (splited_email[0], username, splited_email[1])
+ firstname = "Test"
+ lastname = "User"
+ password = "Qwerty123!"
-@pytest.fixture(scope="session")
-def credentials():
- return {
- "login": os.environ["PLATFORMIO_TEST_ACCOUNT_LOGIN"],
- "password": os.environ["PLATFORMIO_TEST_ACCOUNT_PASSWORD"],
- }
+ # pio account register
+ result = clirunner.invoke(
+ cmd_account,
+ [
+ "register",
+ "-u",
+ username,
+ "-e",
+ email,
+ "-p",
+ password,
+ "--firstname",
+ firstname,
+ "--lastname",
+ lastname,
+ ],
+ )
+ validate_cliresult(result)
+ # email verification
+ result = receive_email(email)
+ link = (
+ result.split("Click on the link below to start this process.")[1]
+ .split("This link will expire within 12 hours.")[0]
+ .strip()
+ )
+ session = requests.Session()
+ result = session.get(link).text
+ link = result.split('= 3
- check = False
- for org in json_result:
- assert "orgname" in org
- orgname = org["orgname"]
- assert "displayname" in org
- assert "email" in org
- assert "owners" in org
- for owner in org.get("owners"):
- assert "username" in owner
- check = owner["username"] == credentials["login"] if not check else True
- assert "firstname" in owner
- assert "lastname" in owner
- assert check
+ assert json_result == [
+ {
+ "orgname": new_orgname,
+ "displayname": new_display_name,
+ "email": email,
+ "owners": [
+ {"username": username, "firstname": firstname, "lastname": lastname}
+ ],
+ }
+ ]
- result = clirunner.invoke(cmd_org, ["add", orgname, "ivankravets"],)
+ result = clirunner.invoke(
+ cmd_org,
+ [
+ "update",
+ new_orgname,
+ "--new-orgname",
+ orgname,
+ "--displayname",
+ display_name,
+ ],
+ )
validate_cliresult(result)
-
- result = clirunner.invoke(cmd_org, ["list", "--json-output"],)
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert len(json_result) >= 3
- check = False
- for item in json_result:
- if item["orgname"] != orgname:
- continue
- for owner in item.get("owners"):
- check = owner["username"] == "ivankravets" if not check else True
- assert check
-
- result = clirunner.invoke(cmd_org, ["remove", orgname, "ivankravets"],)
- validate_cliresult(result)
-
- result = clirunner.invoke(cmd_org, ["list", "--json-output"],)
- validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert len(json_result) >= 3
- check = False
- for item in json_result:
- if item["orgname"] != orgname:
- continue
- for owner in item.get("owners"):
- check = owner["username"] == "ivankravets" if not check else True
- assert not check
finally:
- clirunner.invoke(cmd_account, ["logout"])
-
-
-@pytest.mark.skip
-def test_org_update(clirunner, credentials, validate_cliresult, isolated_pio_home):
- try:
- result = clirunner.invoke(
- cmd_account,
- ["login", "-u", credentials["login"], "-p", credentials["password"]],
- )
+ result = clirunner.invoke(cmd_org, ["destroy", orgname], "y")
validate_cliresult(result)
- assert "Successfully logged in!" in result.output
-
- result = clirunner.invoke(cmd_org, ["list", "--json-output"],)
+ result = clirunner.invoke(cmd_account, ["destroy"], "y")
validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- assert len(json_result) >= 3
- org = json_result[0]
- assert "orgname" in org
- assert "displayname" in org
- assert "email" in org
- assert "owners" in org
-
- old_orgname = org["orgname"]
- if len(old_orgname) > 10:
- new_orgname = "neworg" + org["orgname"][6:]
-
- result = clirunner.invoke(
- cmd_org, ["update", old_orgname, "--new-orgname", new_orgname],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(
- cmd_org, ["update", new_orgname, "--new-orgname", old_orgname],
- )
- validate_cliresult(result)
-
- result = clirunner.invoke(cmd_org, ["list", "--json-output"],)
- validate_cliresult(result)
- assert json.loads(result.output.strip()) == json_result
- finally:
- clirunner.invoke(cmd_account, ["logout"])
diff --git a/tests/commands/test_teams.py b/tests/commands/test_teams.py
index 13e30ce0..92d5226d 100644
--- a/tests/commands/test_teams.py
+++ b/tests/commands/test_teams.py
@@ -17,123 +17,128 @@ import os
import time
import pytest
+import requests
from platformio.commands.account import cli as cmd_account
from platformio.commands.org import cli as cmd_org
from platformio.commands.team import cli as cmd_team
-pytestmark = pytest.mark.skipif(
- not (
- os.environ.get("PLATFORMIO_TEST_ACCOUNT_LOGIN")
- and os.environ.get("PLATFORMIO_TEST_ACCOUNT_PASSWORD")
- ),
- reason="requires PLATFORMIO_TEST_ACCOUNT_LOGIN, PLATFORMIO_TEST_ACCOUNT_PASSWORD environ variables",
-)
+@pytest.mark.skipif(
+ not os.environ.get("TEST_EMAIL_LOGIN"),
+ reason="requires TEST_EMAIL_LOGIN, TEST_EMAIL_PASSWORD environ variables",
+) # pylint:disable=too-many-arguments
+def test_teams(clirunner, validate_cliresult, receive_email, isolated_pio_home):
+ username = "test-piocore-%s" % str(int(time.time() * 1000))
+ splited_email = os.environ.get("TEST_EMAIL_LOGIN").split("@")
+ email = "%s+%s@%s" % (splited_email[0], username, splited_email[1])
+ firstname = "Test"
+ lastname = "User"
+ password = "Qwerty123!"
-@pytest.fixture(scope="session")
-def credentials():
- return {
- "login": os.environ["PLATFORMIO_TEST_ACCOUNT_LOGIN"],
- "password": os.environ["PLATFORMIO_TEST_ACCOUNT_PASSWORD"],
- }
+ # pio account register
+ result = clirunner.invoke(
+ cmd_account,
+ [
+ "register",
+ "-u",
+ username,
+ "-e",
+ email,
+ "-p",
+ password,
+ "--firstname",
+ firstname,
+ "--lastname",
+ lastname,
+ ],
+ )
+ validate_cliresult(result)
+ # email verification
+ result = receive_email(email)
+ link = (
+ result.split("Click on the link below to start this process.")[1]
+ .split("This link will expire within 12 hours.")[0]
+ .strip()
+ )
+ session = requests.Session()
+ result = session.get(link).text
+ link = result.split('= 3
- orgname = json_result[0].get("orgname")
-
+ # pio team create
result = clirunner.invoke(
cmd_team,
[
"create",
"%s:%s" % (orgname, teamname),
"--description",
- "team for CI test",
+ team_description,
],
)
validate_cliresult(result)
+ # pio team list
result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result)
json_result = json.loads(result.output.strip())
- assert len(json_result) >= 1
- check = False
- for team in json_result:
- assert team["id"]
- assert team["name"]
- if team["name"] == teamname:
- check = True
- assert "description" in team
- assert "members" in team
- assert check
+ for item in json_result:
+ del item["id"]
+ assert json_result == [
+ {"name": teamname, "description": team_description, "members": []}
+ ]
+ # pio team add (member)
result = clirunner.invoke(
- cmd_team, ["add", "%s:%s" % (orgname, teamname), credentials["login"]],
+ cmd_team, ["add", "%s:%s" % (orgname, teamname), second_username],
)
validate_cliresult(result)
result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result)
- json_result = json.loads(result.output.strip())
- check = False
- for team in json_result:
- assert team["id"]
- assert team["name"]
- assert "description" in team
- assert "members" in team
- if (
- len(team["members"]) > 0
- and team["members"][0]["username"] == credentials["login"]
- ):
- check = True
- assert check
+ assert second_username in result.output
+ # pio team remove (member)
result = clirunner.invoke(
- cmd_team, ["remove", "%s:%s" % (orgname, teamname), credentials["login"]],
+ cmd_team, ["remove", "%s:%s" % (orgname, teamname), second_username],
)
validate_cliresult(result)
result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result)
+ assert second_username not in result.output
+ # pio team update
+ new_teamname = "new-" + str(int(time.time() * 1000))
+ newteam_description = "Updated Description"
result = clirunner.invoke(
cmd_team,
[
"update",
"%s:%s" % (orgname, teamname),
+ "--name",
+ new_teamname,
"--description",
- "Updated Description",
+ newteam_description,
],
)
validate_cliresult(result)
@@ -141,18 +146,30 @@ def test_teams(clirunner, credentials, validate_cliresult, isolated_pio_home):
result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result)
json_result = json.loads(result.output.strip())
- assert len(json_result) >= 1
- check = False
- for team in json_result:
- assert team["id"]
- assert team["name"]
- assert "description" in team
- if team.get("description") == "Updated Description":
- check = True
- assert "members" in team
- assert check
- finally:
- clirunner.invoke(
- cmd_team, ["destroy", "%s:%s" % (orgname, teamname),],
+ for item in json_result:
+ del item["id"]
+ assert json_result == [
+ {"name": new_teamname, "description": newteam_description, "members": []}
+ ]
+
+ result = clirunner.invoke(
+ cmd_team,
+ [
+ "update",
+ "%s:%s" % (orgname, new_teamname),
+ "--name",
+ teamname,
+ "--description",
+ team_description,
+ ],
)
- clirunner.invoke(cmd_account, ["logout"])
+ validate_cliresult(result)
+ finally:
+ result = clirunner.invoke(
+ cmd_team, ["destroy", "%s:%s" % (orgname, teamname)], "y"
+ )
+ validate_cliresult(result)
+ result = clirunner.invoke(cmd_org, ["destroy", orgname], "y")
+ validate_cliresult(result)
+ result = clirunner.invoke(cmd_account, ["destroy"], "y")
+ validate_cliresult(result)
diff --git a/tests/conftest.py b/tests/conftest.py
index f0529146..4b2259ac 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import email
import os
+import poplib
+import time
import pytest
from click.testing import CliRunner
@@ -53,3 +56,43 @@ def isolated_pio_home(request, tmpdir_factory):
@pytest.fixture(scope="function")
def without_internet(monkeypatch):
monkeypatch.setattr(util, "_internet_on", lambda: False)
+
+
+@pytest.fixture
+def receive_email(): # pylint:disable=redefined-outer-name, too-many-locals
+ def _receive_email(from_who):
+ test_email = os.environ.get("TEST_EMAIL_LOGIN")
+ test_password = os.environ.get("TEST_EMAIL_PASSWORD")
+ pop_server = os.environ.get("TEST_EMAIL_POP3_SERVER") or "pop.gmail.com"
+ if "gmail" in pop_server:
+ test_email = "recent:" + test_email
+
+ def get_body(msg):
+ if msg.is_multipart():
+ return get_body(msg.get_payload(0))
+ return msg.get_payload(None, True)
+
+ result = None
+ start_time = time.time()
+ while not result:
+ time.sleep(5)
+ server = poplib.POP3_SSL(pop_server)
+ server.user(test_email)
+ server.pass_(test_password)
+ _, mails, _ = server.list()
+ for index, _ in enumerate(mails):
+ _, lines, _ = server.retr(index + 1)
+ msg_content = b"\n".join(lines)
+ msg = email.message_from_string(
+ msg_content.decode("ASCII", errors="surrogateescape")
+ )
+ if from_who not in msg.get("To"):
+ continue
+ server.dele(index + 1)
+ result = get_body(msg).decode()
+ if time.time() - start_time > 60:
+ break
+ server.quit()
+ return result
+
+ return _receive_email