Add account and org destroy commands. Fix tests (#3552)

* Add account and org destroy commands. Fix tests

* fix tests

* fix

* fix texts
This commit is contained in:
ShahRustam
2020-06-09 15:50:37 +03:00
committed by GitHub
parent 78546e9246
commit a5547491ed
8 changed files with 454 additions and 680 deletions

View File

@ -28,8 +28,9 @@ jobs:
tox -e lint tox -e lint
- name: Integration Tests - name: Integration Tests
env: env:
PLATFORMIO_TEST_ACCOUNT_LOGIN: ${{ secrets.PLATFORMIO_TEST_ACCOUNT_LOGIN }} TEST_EMAIL_LOGIN: ${{ secrets.TEST_EMAIL_LOGIN }}
PLATFORMIO_TEST_ACCOUNT_PASSWORD: ${{ secrets.PLATFORMIO_TEST_ACCOUNT_PASSWORD }} TEST_EMAIL_PASSWORD: ${{ secrets.TEST_EMAIL_PASSWORD }}
TEST_EMAIL_POP3_SERVER: ${{ secrets.TEST_EMAIL_POP3_SERVER }}
run: | run: |
tox -e testcore tox -e testcore

View File

@ -189,11 +189,14 @@ class AccountClient(RESTClient): # pylint:disable=too-many-public-methods
app.set_state_item("account", account) app.set_state_item("account", account)
return result 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( return self.send_auth_request(
"post", "post",
"/v1/orgs", "/v1/orgs",
data={"orgname": orgname, "email": email, "displayname": display_name}, data={"orgname": orgname, "email": email, "displayname": displayname},
) )
def get_org(self, orgname): 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} "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): def add_org_owner(self, orgname, username):
return self.send_auth_request( return self.send_auth_request(
"post", "/v1/orgs/%s/owners" % orgname, data={"username": username}, "post", "/v1/orgs/%s/owners" % orgname, data={"username": username},

View File

@ -178,6 +178,23 @@ def account_update(current_password, **kwargs):
return click.secho("Please re-login.", fg="yellow") 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") @cli.command("show", short_help="PIO Account information")
@click.option("--offline", is_flag=True) @click.option("--offline", is_flag=True)
@click.option("--json-output", is_flag=True) @click.option("--json-output", is_flag=True)

View File

@ -39,10 +39,10 @@ def validate_orgname(value):
@click.option( @click.option(
"--email", callback=lambda _, __, value: validate_email(value) if value else value "--email", callback=lambda _, __, value: validate_email(value) if value else value
) )
@click.option("--display-name",) @click.option("--displayname",)
def org_create(orgname, email, display_name): def org_create(orgname, email, displayname):
client = AccountClient() client = AccountClient()
client.create_org(orgname, email, display_name) client.create_org(orgname, email, displayname)
return click.secho( return click.secho(
"The organization %s has been successfully created." % orgname, fg="green", "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), "--new-orgname", callback=lambda _, __, value: validate_orgname(value),
) )
@click.option("--email") @click.option("--email")
@click.option("--display-name",) @click.option("--displayname",)
def org_update(orgname, **kwargs): def org_update(orgname, **kwargs):
client = AccountClient() client = AccountClient()
org = client.get_org(orgname) 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") @cli.command("add", short_help="Add a new owner to organization")
@click.argument("orgname",) @click.argument("orgname",)
@click.argument("username",) @click.argument("username",)

View File

@ -17,34 +17,29 @@ import os
import time import time
import pytest import pytest
import requests
from platformio.commands.account import cli as cmd_account from platformio.commands.account import cli as cmd_account
from platformio.commands.package import cli as cmd_package
pytestmark = pytest.mark.skipif( from platformio.downloader import FileDownloader
not ( from platformio.unpacker import FileUnpacker
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.fixture(scope="session") @pytest.mark.skipif(
def credentials(): not os.environ.get("TEST_EMAIL_LOGIN"),
return { reason="requires TEST_EMAIL_LOGIN, TEST_EMAIL_PASSWORD environ variables",
"login": os.environ["PLATFORMIO_TEST_ACCOUNT_LOGIN"], ) # pylint:disable=too-many-arguments
"password": os.environ["PLATFORMIO_TEST_ACCOUNT_PASSWORD"], def test_account(
} clirunner, validate_cliresult, receive_email, isolated_pio_home, tmpdir_factory
def test_account_register_with_already_exists_username(
clirunner, credentials, isolated_pio_home
): ):
username = credentials["login"] username = "test-piocore-%s" % str(int(time.time() * 1000))
email = "test@test.com" splited_email = os.environ.get("TEST_EMAIL_LOGIN").split("@")
if "@" in credentials["login"]: email = "%s+%s@%s" % (splited_email[0], username, splited_email[1])
username = "Testusername" firstname = "Test"
email = credentials["login"] lastname = "User"
password = "Qwerty123!"
# pio account register
result = clirunner.invoke( result = clirunner.invoke(
cmd_account, cmd_account,
[ [
@ -54,345 +49,33 @@ def test_account_register_with_already_exists_username(
"-e", "-e",
email, email,
"-p", "-p",
credentials["password"], password,
"--firstname", "--firstname",
"First", firstname,
"--lastname", "--lastname",
"Last", lastname,
], ],
) )
assert result.exit_code > 0 validate_cliresult(result)
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)
# 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('<a href="')[1].split('"', 1)[0]
link = link.replace("&amp;", "&")
session.get(link)
@pytest.mark.skip_ci # pio account login
def test_account_login_with_invalid_creds(clirunner, credentials, isolated_pio_home): result = clirunner.invoke(cmd_account, ["login", "-u", username, "-p", password],)
result = clirunner.invoke(cmd_account, ["login", "-u", "123", "-p", "123"]) validate_cliresult(result)
assert result.exit_code > 0
assert result.exception
assert "Invalid user credentials" in str(result.exception)
def test_account_login(clirunner, credentials, validate_cliresult, isolated_pio_home):
try: try:
result = clirunner.invoke( # pio account summary
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)
result = clirunner.invoke(cmd_account, ["show", "--json-output", "--offline"]) result = clirunner.invoke(cmd_account, ["show", "--json-output", "--offline"])
validate_cliresult(result) validate_cliresult(result)
json_result = json.loads(result.output.strip()) 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"]) result = clirunner.invoke(cmd_account, ["show"])
validate_cliresult(result) validate_cliresult(result)
assert credentials["login"] in result.output assert username in result.output
assert "Community" in result.output # assert "100 Concurrent Remote Agents" in result.output
assert "100 Concurrent Remote Agents" in result.output
result = clirunner.invoke(cmd_account, ["show", "--json-output"]) result = clirunner.invoke(cmd_account, ["show", "--json-output"])
validate_cliresult(result) 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")
assert json_result.get("profile").get("username") assert json_result.get("profile").get("username")
assert json_result.get("profile").get("email") assert json_result.get("profile").get("email")
assert credentials["login"] == json_result.get("profile").get( assert username == json_result.get("profile").get(
"username" "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("firstname")
assert json_result.get("profile").get("lastname") assert json_result.get("profile").get("lastname")
assert json_result.get("packages") 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")
assert json_result.get("profile").get("username") assert json_result.get("profile").get("username")
assert json_result.get("profile").get("email") assert json_result.get("profile").get("email")
assert credentials["login"] == json_result.get("profile").get( assert username == json_result.get("profile").get(
"username" "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("firstname")
assert json_result.get("profile").get("lastname") assert json_result.get("profile").get("lastname")
assert json_result.get("packages") assert json_result.get("packages")
assert json_result.get("packages")[0].get("name") assert json_result.get("packages")[0].get("name")
assert json_result.get("packages")[0].get("path") assert json_result.get("packages")[0].get("path")
assert json_result.get("subscriptions") is not None 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"]) clirunner.invoke(cmd_account, ["logout"])
result = clirunner.invoke(cmd_account, ["token", "--password", password,],)
@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"]],
)
assert result.exit_code > 0 assert result.exit_code > 0
assert result.exception assert result.exception
assert "You are not authorized! Please log in to PIO Account" in str( assert "You are not authorized! Please log in to PIO Account" in str(
result.exception result.exception
) )
os.environ["PLATFORMIO_AUTH_TOKEN"] = token
result = clirunner.invoke( result = clirunner.invoke(
cmd_account, cmd_account, ["token", "--password", password, "--json-output"],
["login", "-u", credentials["login"], "-p", credentials["password"]], )
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) validate_cliresult(result)
firstname = "First " + str(int(time.time() * 1000)) # pio account password
new_password = "Testpassword123"
result = clirunner.invoke( result = clirunner.invoke(
cmd_account, cmd_account,
["update", "--current-password", "test", "--firstname", firstname], ["password", "--old-password", password, "--new-password", new_password,],
) )
assert result.exit_code > 0 validate_cliresult(result)
assert result.exception assert "Password successfully changed!" in result.output
assert "Invalid user password" in str(result.exception)
finally:
clirunner.invoke(cmd_account, ["logout"]) 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( result = clirunner.invoke(
cmd_account, ["update", "--current-password", credentials["password"]], cmd_account, ["login", "-u", username, "-p", new_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) 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)) firstname = "First " + str(int(time.time() * 1000))
lastname = "Last" + 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_username = "username" + str(int(time.time() * 1000))[-5:]
new_email = "%s+new-%s@%s" % (splited_email[0], username, splited_email[1])
result = clirunner.invoke( result = clirunner.invoke(
cmd_account, cmd_account,
[ [
"update", "update",
"--current-password", "--current-password",
credentials["password"], password,
"--firstname", "--firstname",
firstname, firstname,
"--lastname", "--lastname",
lastname, lastname,
"--username", "--username",
new_username, new_username,
"--email",
new_email,
], ],
) )
validate_cliresult(result) validate_cliresult(result)
assert "Profile successfully updated!" in result.output 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('<a href="')[1].split('"', 1)[0]
link = link.replace("&amp;", "&")
session.get(link)
result = clirunner.invoke(cmd_account, ["show"],) result = clirunner.invoke(cmd_account, ["show"],)
assert result.exit_code > 0 assert result.exit_code > 0
@ -583,27 +239,39 @@ def test_account_profile_update(
) )
result = clirunner.invoke( result = clirunner.invoke(
cmd_account, ["login", "-u", new_username, "-p", credentials["password"]], cmd_account, ["login", "-u", new_username, "-p", password],
) )
validate_cliresult(result) validate_cliresult(result)
result = clirunner.invoke( # pio account destroy with linked resource
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
result = clirunner.invoke( package_url = "https://github.com/bblanchon/ArduinoJson/archive/v6.11.0.tar.gz"
cmd_account, ["login", "-u", old_username, "-p", credentials["password"]],
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) validate_cliresult(result)
finally: finally:
clirunner.invoke(cmd_account, ["logout"]) result = clirunner.invoke(cmd_account, ["destroy"], "y")
validate_cliresult(result)

View File

@ -14,142 +14,150 @@
import json import json
import os import os
import time
import pytest import pytest
import requests
from platformio.commands.account import cli as cmd_account from platformio.commands.account import cli as cmd_account
from platformio.commands.org import cli as cmd_org 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") # pio account register
def credentials(): result = clirunner.invoke(
return { cmd_account,
"login": os.environ["PLATFORMIO_TEST_ACCOUNT_LOGIN"], [
"password": os.environ["PLATFORMIO_TEST_ACCOUNT_PASSWORD"], "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('<a href="')[1].split('"', 1)[0]
link = link.replace("&amp;", "&")
session.get(link)
def test_orgs(clirunner, credentials, validate_cliresult, isolated_pio_home): # pio account login
result = clirunner.invoke(cmd_account, ["login", "-u", username, "-p", password],)
validate_cliresult(result)
orgname = "testorg-piocore-%s" % str(int(time.time() * 1000))
display_name = "Test Org for PIO Core"
second_username = "ivankravets"
try: try:
# pio org create
result = clirunner.invoke( result = clirunner.invoke(
cmd_account, cmd_org,
["login", "-u", credentials["login"], "-p", credentials["password"]], ["create", "--email", email, "--displayname", display_name, orgname],
) )
validate_cliresult(result) validate_cliresult(result)
assert "Successfully logged in!" in result.output
result = clirunner.invoke(cmd_org, ["list", "--json-output"],) # pio org list
result = clirunner.invoke(cmd_org, ["list", "--json-output"])
validate_cliresult(result) validate_cliresult(result)
json_result = json.loads(result.output.strip()) json_result = json.loads(result.output.strip())
if len(json_result) < 3: assert json_result == [
for i in range(3 - len(json_result)): {
result = clirunner.invoke( "orgname": orgname,
cmd_org, "displayname": display_name,
[ "email": email,
"create", "owners": [
"%s-%s" % (i, credentials["login"]), {"username": username, "firstname": firstname, "lastname": lastname}
"--email", ],
"test@test.com", }
"--display-name", ]
"TEST ORG %s" % i,
], # pio org add (owner)
) result = clirunner.invoke(cmd_org, ["add", orgname, second_username])
validate_cliresult(result) validate_cliresult(result)
result = clirunner.invoke(cmd_org, ["list", "--json-output"],)
result = clirunner.invoke(cmd_org, ["list", "--json-output"])
validate_cliresult(result)
assert second_username in result.output
# pio org remove (owner)
result = clirunner.invoke(cmd_org, ["remove", orgname, second_username])
validate_cliresult(result)
result = clirunner.invoke(cmd_org, ["list", "--json-output"])
validate_cliresult(result)
assert second_username not in result.output
# pio org update
new_orgname = "neworg-piocore-%s" % str(int(time.time() * 1000))
new_display_name = "Test Org for PIO Core"
result = clirunner.invoke(
cmd_org,
[
"update",
orgname,
"--new-orgname",
new_orgname,
"--displayname",
new_display_name,
],
)
validate_cliresult(result)
result = clirunner.invoke(cmd_org, ["list", "--json-output"])
validate_cliresult(result) validate_cliresult(result)
json_result = json.loads(result.output.strip()) json_result = json.loads(result.output.strip())
assert len(json_result) >= 3 assert json_result == [
check = False {
for org in json_result: "orgname": new_orgname,
assert "orgname" in org "displayname": new_display_name,
orgname = org["orgname"] "email": email,
assert "displayname" in org "owners": [
assert "email" in org {"username": username, "firstname": firstname, "lastname": lastname}
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
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) 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: finally:
clirunner.invoke(cmd_account, ["logout"]) result = clirunner.invoke(cmd_org, ["destroy", orgname], "y")
@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"]],
)
validate_cliresult(result) validate_cliresult(result)
assert "Successfully logged in!" in result.output result = clirunner.invoke(cmd_account, ["destroy"], "y")
result = clirunner.invoke(cmd_org, ["list", "--json-output"],)
validate_cliresult(result) 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"])

View File

@ -17,123 +17,128 @@ import os
import time import time
import pytest import pytest
import requests
from platformio.commands.account import cli as cmd_account from platformio.commands.account import cli as cmd_account
from platformio.commands.org import cli as cmd_org from platformio.commands.org import cli as cmd_org
from platformio.commands.team import cli as cmd_team 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") # pio account register
def credentials(): result = clirunner.invoke(
return { cmd_account,
"login": os.environ["PLATFORMIO_TEST_ACCOUNT_LOGIN"], [
"password": os.environ["PLATFORMIO_TEST_ACCOUNT_PASSWORD"], "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('<a href="')[1].split('"', 1)[0]
link = link.replace("&amp;", "&")
session.get(link)
# pio account login
result = clirunner.invoke(cmd_account, ["login", "-u", username, "-p", password],)
validate_cliresult(result)
orgname = "testorg-piocore-%s" % str(int(time.time() * 1000))
display_name = "Test Org for PIO Core"
# pio org create
result = clirunner.invoke(
cmd_org, ["create", "--email", email, "--displayname", display_name, orgname]
)
validate_cliresult(result)
def test_teams(clirunner, credentials, validate_cliresult, isolated_pio_home):
orgname = ""
teamname = "test-" + str(int(time.time() * 1000)) teamname = "test-" + str(int(time.time() * 1000))
team_description = "team for CI test"
second_username = "ivankravets"
try: try:
result = clirunner.invoke( # pio team create
cmd_account,
["login", "-u", credentials["login"], "-p", credentials["password"]],
)
validate_cliresult(result)
assert "Successfully logged in!" in result.output
result = clirunner.invoke(cmd_org, ["list", "--json-output"],)
validate_cliresult(result)
json_result = json.loads(result.output.strip())
if len(json_result) < 3:
for i in range(3 - len(json_result)):
result = clirunner.invoke(
cmd_org,
[
"create",
"%s-%s" % (i, credentials["login"]),
"--email",
"test@test.com",
"--display-name",
"TEST ORG %s" % i,
],
)
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
orgname = json_result[0].get("orgname")
result = clirunner.invoke( result = clirunner.invoke(
cmd_team, cmd_team,
[ [
"create", "create",
"%s:%s" % (orgname, teamname), "%s:%s" % (orgname, teamname),
"--description", "--description",
"team for CI test", team_description,
], ],
) )
validate_cliresult(result) validate_cliresult(result)
# pio team list
result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],) result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result) validate_cliresult(result)
json_result = json.loads(result.output.strip()) json_result = json.loads(result.output.strip())
assert len(json_result) >= 1 for item in json_result:
check = False del item["id"]
for team in json_result: assert json_result == [
assert team["id"] {"name": teamname, "description": team_description, "members": []}
assert team["name"] ]
if team["name"] == teamname:
check = True
assert "description" in team
assert "members" in team
assert check
# pio team add (member)
result = clirunner.invoke( result = clirunner.invoke(
cmd_team, ["add", "%s:%s" % (orgname, teamname), credentials["login"]], cmd_team, ["add", "%s:%s" % (orgname, teamname), second_username],
) )
validate_cliresult(result) validate_cliresult(result)
result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],) result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result) validate_cliresult(result)
json_result = json.loads(result.output.strip()) assert second_username in result.output
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
# pio team remove (member)
result = clirunner.invoke( result = clirunner.invoke(
cmd_team, ["remove", "%s:%s" % (orgname, teamname), credentials["login"]], cmd_team, ["remove", "%s:%s" % (orgname, teamname), second_username],
) )
validate_cliresult(result) validate_cliresult(result)
result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],) result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result) 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( result = clirunner.invoke(
cmd_team, cmd_team,
[ [
"update", "update",
"%s:%s" % (orgname, teamname), "%s:%s" % (orgname, teamname),
"--name",
new_teamname,
"--description", "--description",
"Updated Description", newteam_description,
], ],
) )
validate_cliresult(result) 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"],) result = clirunner.invoke(cmd_team, ["list", "%s" % orgname, "--json-output"],)
validate_cliresult(result) validate_cliresult(result)
json_result = json.loads(result.output.strip()) json_result = json.loads(result.output.strip())
assert len(json_result) >= 1 for item in json_result:
check = False del item["id"]
for team in json_result: assert json_result == [
assert team["id"] {"name": new_teamname, "description": newteam_description, "members": []}
assert team["name"] ]
assert "description" in team
if team.get("description") == "Updated Description": result = clirunner.invoke(
check = True cmd_team,
assert "members" in team [
assert check "update",
finally: "%s:%s" % (orgname, new_teamname),
clirunner.invoke( "--name",
cmd_team, ["destroy", "%s:%s" % (orgname, teamname),], 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)

View File

@ -12,7 +12,10 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
import email
import os import os
import poplib
import time
import pytest import pytest
from click.testing import CliRunner from click.testing import CliRunner
@ -53,3 +56,43 @@ def isolated_pio_home(request, tmpdir_factory):
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def without_internet(monkeypatch): def without_internet(monkeypatch):
monkeypatch.setattr(util, "_internet_on", lambda: False) 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