Skip to content

Commit

Permalink
allow providing refresh token for tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Sam Schott committed Jan 8, 2021
1 parent 637cace commit c264cb7
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ jobs:
-d client_id=2jmbq42w7vof78h)
token=$(echo $auth_result | python -c "import sys, json; print(json.load(sys.stdin)['access_token'])")
echo "::add-mask::$token"
echo "DROPBOX_TOKEN=$token" >> $GITHUB_ENV
echo "DROPBOX_ACCESS_TOKEN=$token" >> $GITHUB_ENV
- name: Test with pytest
run: |
Expand Down
37 changes: 9 additions & 28 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ indexing and cleaning up sync events, and for particularly complex functions tha
prone to regressions.

The current test suite uses a Dropbox access token provided by the environment variable
`DROPBOX_TOKEN` to connect to a real account. The GitHub action which is running the
tests will set this environment variable for you with a temporary access token that
`DROPBOX_ACCESS_TOKEN` or a refresh token provided by `DROPBOX_REFRESH_TOKEN` to connect
to a real account. The GitHub action which is running the tests will set the
`DROPBOX_ACCESS_TOKEN` environment variable for you with a temporary access token that
expires after 4 hours. Tests are run on `ubuntu-latest` and `macos-latest` in parallel
on different accounts.

Expand All @@ -70,10 +71,10 @@ running tests to prevent them from interfering which each other by creating a fo
create and clean up a test config and to acquire a lock are provided in the
`tests/linked/conftest.py`.

If you run the tests locally, you will need to provide an access token for your own
Dropbox account. If your account is already linked with Maestral, it will have saved a
long-lived "refresh token" in your system keyring. You can access it manually or through
the Python API:
If you run the tests locally, you will need to provide a refresh or access token for
your own Dropbox account. If your account is already linked with Maestral, it will have
saved a long-lived "refresh token" in your system keyring. You can access it manually or
through the Python API:

```Python
from maestral.main import Maestral
Expand All @@ -82,25 +83,5 @@ m = Maestral()
print(m.client.auth.refresh_token)
```

This refresh token cannot be used to make API calls directly but should be used to
retrieve a short-lived access token. This can be done again through Python

```Python
m.client.dbx.refresh_access_token() # gets a short-lived auth token from server
print(m.client.dbx._oauth2_access_token) # prints the access token
```

or from the command line:

```shell
auth_result=$(curl https://api.dropbox.com/oauth2/token \
-d grant_type=refresh_token \
-d refresh_token=$REFRESH_TOKEN \
-d client_id=2jmbq42w7vof78h)
parse_response="import sys, json; print(json.load(sys.stdin)['access_token'])"
access_token=$(echo $auth_result | python3 -c "$parse_response")
```

You can then store the retrieved access token in the environment variable
`DROPBOX_TOKEN` to be automatically picked up by the tests.

You can then store the retrieved refresh token in the environment variable
`DROPBOX_REFRESH_TOKEN` to be automatically picked up by the tests.
20 changes: 16 additions & 4 deletions tests/linked/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,26 @@ def m():
m.log_level = logging.DEBUG

# link with given token
access_token = os.environ.get("DROPBOX_TOKEN", "")
m.client._init_sdk_with_token(access_token=access_token)
access_token = os.environ.get("DROPBOX_ACCESS_TOKEN")
refresh_token = os.environ.get("DROPBOX_REFRESH_TOKEN")

if access_token:
m.client._init_sdk_with_token(access_token=access_token)
m.client.auth._access_token = access_token
m.client.auth._token_access_type = "legacy"
elif refresh_token:
m.client._init_sdk_with_token(refresh_token=refresh_token)
m.client.auth._refresh_token = refresh_token
m.client.auth._token_access_type = "offline"
else:
raise RuntimeError(
"Either access token or refresh token must be given as environment "
"variable DROPBOX_ACCESS_TOKEN or DROPBOX_REFRESH_TOKEN."
)

# get corresponding Dropbox ID and store in keyring for other processes
res = m.client.get_account_info()
m.client.auth._account_id = res.account_id
m.client.auth._access_token = access_token
m.client.auth._token_access_type = "legacy"
m.client.auth.save_creds()

# set local Dropbox directory
Expand Down
7 changes: 7 additions & 0 deletions tests/linked/test_cli.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
# -*- coding: utf-8 -*-

import os

import pytest
from click.testing import CliRunner

from maestral.cli import main
from maestral.constants import IDLE, PAUSED, STOPPED, ERROR
from maestral.daemon import MaestralProxy


if not ("DROPBOX_ACCESS_TOKEN" in os.environ or "DROPBOX_REFRESH_TOKEN" in os.environ):
pytest.skip("Requires auth token", allow_module_level=True)


def wait_for_idle(m: MaestralProxy, minimum: int = 2):

while True:
Expand Down
2 changes: 1 addition & 1 deletion tests/linked/test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from .conftest import resources


if not os.environ.get("DROPBOX_TOKEN"):
if not ("DROPBOX_ACCESS_TOKEN" in os.environ or "DROPBOX_REFRESH_TOKEN" in os.environ):
pytest.skip("Requires auth token", allow_module_level=True)


Expand Down
2 changes: 1 addition & 1 deletion tests/linked/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from .conftest import wait_for_idle, resources


if not os.environ.get("DROPBOX_TOKEN"):
if not ("DROPBOX_ACCESS_TOKEN" in os.environ or "DROPBOX_REFRESH_TOKEN" in os.environ):
pytest.skip("Requires auth token", allow_module_level=True)


Expand Down
2 changes: 1 addition & 1 deletion tests/linked/test_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from .conftest import assert_synced, wait_for_idle, resources


if not os.environ.get("DROPBOX_TOKEN"):
if not ("DROPBOX_ACCESS_TOKEN" in os.environ or "DROPBOX_REFRESH_TOKEN" in os.environ):
pytest.skip("Requires auth token", allow_module_level=True)


Expand Down

0 comments on commit c264cb7

Please sign in to comment.