Skip to content

Commit 77905a4

Browse files
authored
Merge pull request #538 from requests/docs-examples
Added secrets to actions to run test example
2 parents 45eca1a + 59f3d6a commit 77905a4

File tree

7 files changed

+132
-2
lines changed

7 files changed

+132
-2
lines changed

.github/workflows/run-tests.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ jobs:
3939
python -m pip install coveralls coverage-lcov toml
4040
- name: Execute tests with tox
4141
env:
42+
AUTH0_USERNAME: ${{ secrets.AUTH0_USERNAME }}
43+
AUTH0_PASSWORD: ${{ secrets.AUTH0_PASSWORD }}
44+
AUTH0_PKCE_CLIENT_ID: ${{ secrets.AUTH0_PKCE_CLIENT_ID }}
45+
AUTH0_DOMAIN: ${{ secrets.AUTH0_DOMAIN }}
4246
TOXENV: ${{ matrix.tox-env }}
4347
run: |
4448
tox

docs/contributing_examples.rst

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
======================
2+
Documentation examples
3+
======================
4+
5+
Examples found in documentation must be tested to be sure we have the appropriate
6+
coverage and be sure new releases are tested against regressions.
7+
8+
Also, it helps testing any changes in public Identity Providers.
9+
10+
Currently few tests are covered, and ``selenium`` package is used to interact with browser. Feel free to have a look at the base class in ``tests/examples/base.py`` to reuse utility specially crafted for testing samples in documentation.
11+
12+
Identity Providers available for tests
13+
======================================
14+
15+
Currently only an Auth0 test provider is available but new can be created on request. Following are the environment variables :
16+
17+
- Auth0 https://auth0.com/ :
18+
19+
- ``AUTH0_USERNAME``
20+
- ``AUTH0_PASSWORD``
21+
- ``AUTH0_DOMAIN``
22+
- ``AUTH0_PKCE_CLIENT_ID``
23+
24+
Guidelines to write samples
25+
===========================
26+
27+
Documentation
28+
^^^^^^^^^^^^^
29+
30+
In order to write a testable sample, like an easy copy/paste, it is recommended to separate the python code from the documentation as below :
31+
32+
.. code-block::
33+
34+
.. literalinclude:: xyz_foobar.py
35+
:language: python
36+
37+
Verify if formatting is correct by checking :
38+
39+
.. code-block:: bash
40+
41+
tox -e docs
42+
# output located in docs/_build/html/index.html
43+
44+
45+
Python example
46+
^^^^^^^^^^^^^^
47+
48+
It's recommended to write a python example with either predefined placeholder variables for environment setup properties (like identity provider tenants identifiers/secrets), and use ``input()`` when user interaction is required. Feel free to reuse an existing example like ``docs/examples/native_spa_pkce_auth0.py`` and its associated test.
49+
50+
Python tests
51+
^^^^^^^^^^^^
52+
53+
You can write new tests in ``tests/examples/test_*py`` and inherit of base classes found in ``tests/examples/base.py`` based on your needs.
54+
55+
Don't forget to skip python tests if you require an environment variables, also don't store any secrets or leak tenant informations in git.
56+
57+
Skip tests example as below:
58+
59+
.. code-block:: python
60+
61+
self.client_id = os.environ.get("AUTH0_PKCE_CLIENT_ID")
62+
self.idp_domain = os.environ.get("AUTH0_DOMAIN")
63+
64+
if not self.client_id or not self.idp_domain:
65+
self.skipTest("native auth0 is not configured properly")
66+
67+
68+
Then the sample can be copy paste into a python console
69+
70+
Environment variables
71+
^^^^^^^^^^^^^^^^^^^^^
72+
73+
Once referencing environment variables, you have to set them in the Github Actions. Any maintainers can do it, and it's the role of the maintainer to create a test tenant with test clients.
74+
75+
Example on how to set new env secrets with `GitHub CLI <https://cli.github.com/>`_:
76+
77+
.. code-block:: bash
78+
79+
gh secret set AUTH0_PASSWORD --body "secret"
80+
81+
82+
Helper Interfaces
83+
=================
84+
85+
.. autoclass:: tests.examples.Sample
86+
:members:
87+
88+
.. autoclass:: tests.examples.Browser
89+
:members:

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ Getting Started:
7777

7878
api
7979
contributing
80+
contributing_examples
8081

8182

8283

tests/examples/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from .base import Sample
2+
from .base import Browser

tests/examples/base.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ def replaceVariables(self, filein ,fileout, vars):
3535
fout.write(line)
3636

3737
def run_sample(self, filepath, variables):
38+
"""
39+
Execute python sample as a background process.
40+
41+
:param filepath: Name of the python sample present in docs examples folder.
42+
:type filepath: string
43+
:param variables: Key Names/Values to replace in the python script before being run
44+
:type variables: dict
45+
"""
3846
inpath = os.path.join(cwd, "..", "..", "docs", "examples", filepath)
3947
outpath = os.path.join(cwd, "tmp_{}".format(filepath))
4048
self.replaceVariables(inpath, outpath, variables)
@@ -48,10 +56,21 @@ def run_sample(self, filepath, variables):
4856
)
4957

5058
def write(self, string):
59+
"""
60+
Write string into standard input. Useful to fill an answer to ``input()``
61+
62+
:param string: string to write
63+
"""
5164
self.proc.stdin.write(string)
5265
self.proc.stdin.flush()
5366

5467
def wait_for_pattern(self, pattern):
68+
"""
69+
Wait until the background process is writing ``pattern`` in standard output.
70+
71+
:param pattern: search for this string before returning.
72+
:type pattern: string
73+
"""
5574
try:
5675
while True:
5776
line = self.proc.stdout.readline()
@@ -62,6 +81,9 @@ def wait_for_pattern(self, pattern):
6281
self.assertTrue(False, "timeout when looking for output")
6382

6483
def wait_for_end(self):
84+
"""
85+
Wait until the background process ends. Timeout after 10sec.
86+
"""
6587
try:
6688
outs, err = self.proc.communicate(timeout=10)
6789
self.outputs += filter(lambda x: x != '', outs.split('\n'))
@@ -88,6 +110,16 @@ def tearDown(self):
88110
self.driver.quit()
89111

90112
def authorize_auth0(self, authorize_url, expected_redirect_uri):
113+
"""
114+
Start browser based on an Auth0 authorize url, and log user with user and password.
115+
Returns once login journey ends with a redirection to ``expected_redirect_uri``.
116+
Note this is for Auth0 login dialog specifically.
117+
118+
:param authorize_url: Full Authorize URL of Identity Provider
119+
:type authorize_url: string
120+
:param expected_redirect_uri: Expected ``redirect_uri``. Used only to check end of the authorize journey.
121+
:type expected_redirect_uri: string
122+
"""
91123
self.driver.get(authorize_url)
92124
username = self.driver.find_element(By.ID, "username")
93125
password = self.driver.find_element(By.ID, "password")

tests/examples/test_native_spa_pkce_auth0.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import os
22
import unittest
33

4-
from . import base
4+
from . import Sample
5+
from . import Browser
56

6-
class TestNativeAuth0Test(base.Sample, base.Browser, unittest.TestCase):
7+
class TestNativeAuth0Test(Sample, Browser, unittest.TestCase):
78
def setUp(self):
89
super().setUp()
910
self.client_id = os.environ.get("AUTH0_PKCE_CLIENT_ID")

tox.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ basepython=python3.11
1717
skipsdist=True
1818
deps=
1919
-r{toxinidir}/docs/requirements.txt
20+
-r{toxinidir}/requirements-test.txt
2021
changedir=docs
2122
allowlist_externals=make
2223
commands=make clean html

0 commit comments

Comments
 (0)