From 260f72f118b5549e56933672216bb13e8cbf339a Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 11:37:15 -0400 Subject: [PATCH 01/15] Add: Initial tests and configuration files --- .github/workflows/release.yml | 14 +++++++++ .github/workflows/test.yml | 28 ++++++++++++++++++ .python-version | 2 +- Makefile | 4 +++ __pycache__/__init__.cpython-310.pyc | Bin 0 -> 143 bytes .../conftest.cpython-310-pytest-7.1.3.pyc | Bin 0 -> 701 bytes conftest.py | 18 +++++++++++ .../lib/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 156 bytes firmware/lib/__pycache__/pin.cpython-310.pyc | Bin 0 -> 549 bytes .../lib/__pycache__/scout.cpython-310.pyc | Bin 0 -> 4231 bytes .../lib/__pycache__/utils.cpython-310.pyc | Bin 0 -> 985 bytes firmware/lib/connection.py | 2 +- firmware/lib/scout.py | 4 +-- firmware/lib/webpage.py | 2 +- pytest.ini | 2 ++ test-requirements.txt | 2 ++ tests/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 149 bytes .../test_scout.cpython-310-pytest-7.1.3.pyc | Bin 0 -> 878 bytes tests/test_scout.py | 23 ++++++++++++++ 19 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/test.yml create mode 100644 Makefile create mode 100644 __pycache__/__init__.cpython-310.pyc create mode 100644 __pycache__/conftest.cpython-310-pytest-7.1.3.pyc create mode 100644 conftest.py create mode 100644 firmware/lib/__pycache__/__init__.cpython-310.pyc create mode 100644 firmware/lib/__pycache__/pin.cpython-310.pyc create mode 100644 firmware/lib/__pycache__/scout.cpython-310.pyc create mode 100644 firmware/lib/__pycache__/utils.cpython-310.pyc create mode 100644 pytest.ini create mode 100644 test-requirements.txt create mode 100644 tests/__pycache__/__init__.cpython-310.pyc create mode 100644 tests/__pycache__/test_scout.cpython-310-pytest-7.1.3.pyc create mode 100644 tests/test_scout.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b352a66..fbe7967 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,11 @@ name: Release +on: + workflow_run: + workflows: ["Test"] + branches: [main] + types: + - completed + on: push: branches: @@ -21,6 +28,13 @@ jobs: pyenv install micropython-1.19.1 pyenv local micropython-1.19.1 micropython -m upip install -r requirements.txt -p 'firmware/' + - name: Run unittests + run: | + pyenv install 3.10.7 + pyenv local 3.10.7 + pip install -r test-requirements.txt + pytest + - name: Archive Release uses: thedoctor0/zip-release@main with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..3cc0a7e --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,28 @@ +name: Test +on: + push + +jobs: + release: + name: Release + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 0 + - name: Install micropython dependencies + run: | + git clone https://github.com/pyenv/pyenv.git ~/.pyenv + export PYENV_ROOT="$HOME/.pyenv" + command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH" + eval "$(pyenv init -)" + pyenv install micropython-1.19.1 + pyenv local micropython-1.19.1 + micropython -m upip install -r requirements.txt -p 'firmware/' + - name: Run unittests + run: | + pyenv install 3.10.7 + pyenv local 3.10.7 + pip install -r test-requirements.txt + pytest \ No newline at end of file diff --git a/.python-version b/.python-version index 6f80e59..1281604 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -micropython-1.19.1 +3.10.7 diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..efba37e --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +install_test_requirements: + pip install -r test-requirements.txt + + diff --git a/__pycache__/__init__.cpython-310.pyc b/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c7d7f90975688e904230a2686249abbb3a3089ce GIT binary patch literal 143 zcmd1j<>g`kf~P(f$sqbMh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vAKO;XkRX?{l zIU}*4ATc>3wMgG3Ke;qFHLs*t-zhPvGB`QEv_wBXJ~J<~BtBlRpz;=nO>TZlX-=vg M$gE-}Ai=@_03{_KyZ`_I literal 0 HcmV?d00001 diff --git a/__pycache__/conftest.cpython-310-pytest-7.1.3.pyc b/__pycache__/conftest.cpython-310-pytest-7.1.3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e4eec7a1616751c5527035e68a2fca5190db3216 GIT binary patch literal 701 zcmZXRy>8nu5P(ThmMB&BR21!+EsF)TO9!Jc+5*{(0$B3G?}x|ZeMjl#GAAe>zJILWQbHbm@LU)MTU_=5l_H8Bh@innEsF>x zZ7dda&LkoUnN*~~a>0YmM0Q0~q}V-C>==n0UO{rCDn3$CKn{h>A%*02sTLaoJa`Fu zS@2Tyir~c??0-!z`5$BIDP1mQtJQe$ej(-ESRLk!S^NhxV|iTTFHLa; zcuoo$c3j#bVbg(FjJH;IA{!0djfiCh8@0V$Ies%XhoR}LE4KY4pQ3lNp8|hnEtsLv z-P*uU(+uFUr!AMB_Hr!t$7N+4vy*jk=*Lg(T%_%c6c1AmCPP-F3sc(j^PVSid^2Z1 Y`Tt_ypt_(ue50j~L@@c;k- literal 0 HcmV?d00001 diff --git a/conftest.py b/conftest.py new file mode 100644 index 0000000..07d33b3 --- /dev/null +++ b/conftest.py @@ -0,0 +1,18 @@ +# conftest.py +import sys +import json +import requests +import os + +class Pin: + def __init__(): + pass + +machine = type(sys)('machine') +machine.Pin = Pin + + +sys.modules['ujson'] = json +sys.modules['urequests'] = requests +sys.modules['uos'] = os +sys.modules['machine'] = machine \ No newline at end of file diff --git a/firmware/lib/__pycache__/__init__.cpython-310.pyc b/firmware/lib/__pycache__/__init__.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf2ebe46027f553a9a7ad071cc98c0a3ec8d238f GIT binary patch literal 156 zcmd1j<>g`k0`Fk$WDxxrL?8o3AjbiSi&=m~3PUi1CZpd;2{RgxZ%INPS)rBNW?-*ed{u_Eq}lk7x02{$onuIyNt!& z{CYZFPG&#ikO@wEg}-X7)n$MC9Sq5;8>dDkRxNj@0e!07t`F#;IUr*82tuzL7L+k7 gRllOY%MhCvn&|ZOXP5djZYm1S8$e@QOMDq2t0 zWF2i;F3T0P6}c+c&@RaeYYjRUwLtB?y@;cgO`IdYe?TUOy-axx5--RZP z%-QWGqqNKC@DfkYT|D|4$b?O-z}mM!!JY6^i;RZhtlhLTuM_Gh7^z<7br0g6RM8-- z#e+Bvrmsz&2_5wwDhHFDS*ncY<*n91(vMnw-8~40!?1f0sn)%uJL*S+RJZPgog;&+ z^)OcbC!va3y|~lT1a^CPlzBm5mIx>=v}0!i~|)t8bvxay5^!T^h0k`D33;pVVEA|Jx*>RvWGE>B5hO&WEqd9H^Ekz$JUs5 zHNKLowqV*W=`{V3ZZrKFc$x5H0q5D0-LeWj1>X2`yKtc0R@hF~8OwwW)9{R|I$jO- zrjx_Xof^b4^TKW#KaSHQb%lghh%7?S%Ek;d)m8KwzX-rzXXE7@{H%WgI9YTC{2pEq zWfXP%loSx^IuvmxLb5H3;6oY2;US+mjG67J$-(=}=B!4;uOlLo-s32rTwlj9T?MH!fqxZ7SmERK z+zgANT}lwsAK8KIVS@Aq7zC+ZIM3)O`RAOpCd*(CigxB2b##*(XJ%p$_9MI)kj7Q( zn5OXOoMNV*_V)!ZDuVtUJVgL2MN!(^Z%Gqt+RDqE2L0UqO70h?42*%i)T;rXUw z^RGRJ|3l0oeHLa5xs^OUwbBc63#`P?qrHe+-p(A|i=yEfQ*S}&%)SVHao?$LLFgBF zUeMf>GR8~Aexq4li$FCX-sJ7^QabAQk8YAFwE8waD)Rq@xX3C-%Eb4tsrx;U@k+kX zdDp^fglD?5Uwj`gq_0F2NbxzRB%AN^iG7Ncl;Qw1-m!x8=@ zN__`AES4`fK8m`Dl96oOi^E~08h4E#($^-I$ef{y2kBX!Z|4Hu?1e?kWfe>tNHfcC zG4=(eXu&GRy;I%JMP93$`X0ssvw9!x&YmJwRg(yXjQSCg3oBQRF2&j(lE5~|c&%_8 zDOz;Cc2zxRQP}iSi;9^=ogCf&1#X3Oo(K5H8NiJk;6;Jgf}ENr^BzW#j0gMr4n0RvOXmi zb2fIsAPb`8)bEcyI@zC^oOsMWu?E)!vf$Bs4Cfv4A@(%w-qe0dZ{oy}f=bc+{jb)5 zJ;7^mpAnK;XQgMA}B<0bUR2?fKcO>Dj&fG<2YnJbJV)X$`!`H5?{gWsHoH(h%A(m1cG9~n0W#wwN6mq zpYYT^5vMTvDL=)n3st_DaJ4>xK~Z9o!EDt^-IEfIArxEEMyV-KWV$C_T0X2yVB}5Q z3OB6@RnP8o`*7)$?N0lv^Zl~)oaenwuRUJg-frortD;nIAL?Y_*KU8j_lE}`-S=+ueh9iVlrt zP0?M=-^3y+j!=Gvqx2wn9IBYCul@325)T5pb7VZxnTxul`$T5$XoxaB$^dfgSq12gI++nmYhKWvb4(FiMyR@K_Uu{hFNC@%*xxTpU1y7q&?C%iPbWT$7#9whP zz7ci>o~*#bR3q1M%fZ*Lg|h+9jA_<08yCM^$MR?jO#KPd_|AyHtNX;;qeQD6;!2R; t9>xPjQL1hep%6CVl9z;+?C{LHm1maU&~DIlSE$l9FJiB5d*RyZe*md}g0TPq literal 0 HcmV?d00001 diff --git a/firmware/lib/__pycache__/utils.cpython-310.pyc b/firmware/lib/__pycache__/utils.cpython-310.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3889643ea9104c0b414825e1e8dfaf857413fe2e GIT binary patch literal 985 zcmZ8g!EV$r5cN3DHoNT>sDP>h?nFXFTsWW#v1Ng-gtn+@wIY`&8=G!WwprOptD^K& zIP(Qa-6Ox0E2sWKFJ;CpRg0||&x{>=-kV9$?RFTBbnRvOi!=6zoSOq<>3nAqmqNO@Ie|9h3i?X%}BVUk@h5R0UI$PLkOyNheAN{UWWVYQHqWMlwDM)1oSa zFPWYmCRzn~HV&#X%gyuIQM0O5sWWw;?49vJqO)Y2DG`xVNYuqhXO@*^fcO zDb%*Pe(*ImrzR4^a|krG(AfnJpEs_Vg`kf?GZo$sqbMh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6v4KO;XkRX?{l zIU}*4ATc>3wMgG3Ke;qFHLs*t-zhPvGB`QEv_!uowHU~ckI&4@EQycTE2zB1VUwGm RQks)$2Qsmk2}rOo0002JA{hVx literal 0 HcmV?d00001 diff --git a/tests/__pycache__/test_scout.cpython-310-pytest-7.1.3.pyc b/tests/__pycache__/test_scout.cpython-310-pytest-7.1.3.pyc new file mode 100644 index 0000000000000000000000000000000000000000..961f3a7c2aee5082abea2f95c8865c6ef02ace30 GIT binary patch literal 878 zcmZWnJ&zMH5ViMvH(7ML>Nrs%q?J%2I)o590d<-y5N=k^+Q*vPFKn-(pzDI@5PyK; zQeMaJaZANtpn$SdzFlqx5V*AHyqBbV6^Zh1iQ<7rDV-{@i_bJJE%EApMlXvh&fC9AfG3t_MNIhL) z4DVp{9`^1$i&*>x!RhIJoa|$UFHw>H1}tb%U=t2hSG9F6tA5m<&l|CvDeKM@?^sC( zQA+-40_4{T00QMW$>I{rVw|EOkZqTjAF!Q#aWdv3Ig|r7vQq`hi zl6Qq~LRX9Aq7%B@=glcqic3h)rs1qy30>b|a? Date: Sat, 1 Oct 2022 11:38:10 -0400 Subject: [PATCH 02/15] Update gitignore --- .gitignore | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 162 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a46808c..5ad35e2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,163 @@ env.json -secrets.json \ No newline at end of file +secrets.json + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ From f78cda452024e6d3e8a0cf7e68949c459c3c0ae0 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 11:39:28 -0400 Subject: [PATCH 03/15] Remove pycache files --- __pycache__/__init__.cpython-310.pyc | Bin 143 -> 0 bytes .../conftest.cpython-310-pytest-7.1.3.pyc | Bin 701 -> 0 bytes .../lib/__pycache__/__init__.cpython-310.pyc | Bin 156 -> 0 bytes firmware/lib/__pycache__/pin.cpython-310.pyc | Bin 549 -> 0 bytes firmware/lib/__pycache__/scout.cpython-310.pyc | Bin 4231 -> 0 bytes firmware/lib/__pycache__/utils.cpython-310.pyc | Bin 985 -> 0 bytes tests/__pycache__/__init__.cpython-310.pyc | Bin 149 -> 0 bytes .../test_scout.cpython-310-pytest-7.1.3.pyc | Bin 878 -> 0 bytes 8 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 __pycache__/__init__.cpython-310.pyc delete mode 100644 __pycache__/conftest.cpython-310-pytest-7.1.3.pyc delete mode 100644 firmware/lib/__pycache__/__init__.cpython-310.pyc delete mode 100644 firmware/lib/__pycache__/pin.cpython-310.pyc delete mode 100644 firmware/lib/__pycache__/scout.cpython-310.pyc delete mode 100644 firmware/lib/__pycache__/utils.cpython-310.pyc delete mode 100644 tests/__pycache__/__init__.cpython-310.pyc delete mode 100644 tests/__pycache__/test_scout.cpython-310-pytest-7.1.3.pyc diff --git a/__pycache__/__init__.cpython-310.pyc b/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index c7d7f90975688e904230a2686249abbb3a3089ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 143 zcmd1j<>g`kf~P(f$sqbMh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6vAKO;XkRX?{l zIU}*4ATc>3wMgG3Ke;qFHLs*t-zhPvGB`QEv_wBXJ~J<~BtBlRpz;=nO>TZlX-=vg M$gE-}Ai=@_03{_KyZ`_I diff --git a/__pycache__/conftest.cpython-310-pytest-7.1.3.pyc b/__pycache__/conftest.cpython-310-pytest-7.1.3.pyc deleted file mode 100644 index e4eec7a1616751c5527035e68a2fca5190db3216..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 701 zcmZXRy>8nu5P(ThmMB&BR21!+EsF)TO9!Jc+5*{(0$B3G?}x|ZeMjl#GAAe>zJILWQbHbm@LU)MTU_=5l_H8Bh@innEsF>x zZ7dda&LkoUnN*~~a>0YmM0Q0~q}V-C>==n0UO{rCDn3$CKn{h>A%*02sTLaoJa`Fu zS@2Tyir~c??0-!z`5$BIDP1mQtJQe$ej(-ESRLk!S^NhxV|iTTFHLa; zcuoo$c3j#bVbg(FjJH;IA{!0djfiCh8@0V$Ies%XhoR}LE4KY4pQ3lNp8|hnEtsLv z-P*uU(+uFUr!AMB_Hr!t$7N+4vy*jk=*Lg(T%_%c6c1AmCPP-F3sc(j^PVSid^2Z1 Y`Tt_ypt_(ue50j~L@@c;k- diff --git a/firmware/lib/__pycache__/__init__.cpython-310.pyc b/firmware/lib/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index bf2ebe46027f553a9a7ad071cc98c0a3ec8d238f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmd1j<>g`k0`Fk$WDxxrL?8o3AjbiSi&=m~3PUi1CZpd;2{RgxZ%INPS)rBNW?-*ed{u_Eq}lk7x02{$onuIyNt!& z{CYZFPG&#ikO@wEg}-X7)n$MC9Sq5;8>dDkRxNj@0e!07t`F#;IUr*82tuzL7L+k7 gRllOY%MhCvn&|ZOXP5djZYm1S8$e@QOMDq2t0 zWF2i;F3T0P6}c+c&@RaeYYjRUwLtB?y@;cgO`IdYe?TUOy-axx5--RZP z%-QWGqqNKC@DfkYT|D|4$b?O-z}mM!!JY6^i;RZhtlhLTuM_Gh7^z<7br0g6RM8-- z#e+Bvrmsz&2_5wwDhHFDS*ncY<*n91(vMnw-8~40!?1f0sn)%uJL*S+RJZPgog;&+ z^)OcbC!va3y|~lT1a^CPlzBm5mIx>=v}0!i~|)t8bvxay5^!T^h0k`D33;pVVEA|Jx*>RvWGE>B5hO&WEqd9H^Ekz$JUs5 zHNKLowqV*W=`{V3ZZrKFc$x5H0q5D0-LeWj1>X2`yKtc0R@hF~8OwwW)9{R|I$jO- zrjx_Xof^b4^TKW#KaSHQb%lghh%7?S%Ek;d)m8KwzX-rzXXE7@{H%WgI9YTC{2pEq zWfXP%loSx^IuvmxLb5H3;6oY2;US+mjG67J$-(=}=B!4;uOlLo-s32rTwlj9T?MH!fqxZ7SmERK z+zgANT}lwsAK8KIVS@Aq7zC+ZIM3)O`RAOpCd*(CigxB2b##*(XJ%p$_9MI)kj7Q( zn5OXOoMNV*_V)!ZDuVtUJVgL2MN!(^Z%Gqt+RDqE2L0UqO70h?42*%i)T;rXUw z^RGRJ|3l0oeHLa5xs^OUwbBc63#`P?qrHe+-p(A|i=yEfQ*S}&%)SVHao?$LLFgBF zUeMf>GR8~Aexq4li$FCX-sJ7^QabAQk8YAFwE8waD)Rq@xX3C-%Eb4tsrx;U@k+kX zdDp^fglD?5Uwj`gq_0F2NbxzRB%AN^iG7Ncl;Qw1-m!x8=@ zN__`AES4`fK8m`Dl96oOi^E~08h4E#($^-I$ef{y2kBX!Z|4Hu?1e?kWfe>tNHfcC zG4=(eXu&GRy;I%JMP93$`X0ssvw9!x&YmJwRg(yXjQSCg3oBQRF2&j(lE5~|c&%_8 zDOz;Cc2zxRQP}iSi;9^=ogCf&1#X3Oo(K5H8NiJk;6;Jgf}ENr^BzW#j0gMr4n0RvOXmi zb2fIsAPb`8)bEcyI@zC^oOsMWu?E)!vf$Bs4Cfv4A@(%w-qe0dZ{oy}f=bc+{jb)5 zJ;7^mpAnK;XQgMA}B<0bUR2?fKcO>Dj&fG<2YnJbJV)X$`!`H5?{gWsHoH(h%A(m1cG9~n0W#wwN6mq zpYYT^5vMTvDL=)n3st_DaJ4>xK~Z9o!EDt^-IEfIArxEEMyV-KWV$C_T0X2yVB}5Q z3OB6@RnP8o`*7)$?N0lv^Zl~)oaenwuRUJg-frortD;nIAL?Y_*KU8j_lE}`-S=+ueh9iVlrt zP0?M=-^3y+j!=Gvqx2wn9IBYCul@325)T5pb7VZxnTxul`$T5$XoxaB$^dfgSq12gI++nmYhKWvb4(FiMyR@K_Uu{hFNC@%*xxTpU1y7q&?C%iPbWT$7#9whP zz7ci>o~*#bR3q1M%fZ*Lg|h+9jA_<08yCM^$MR?jO#KPd_|AyHtNX;;qeQD6;!2R; t9>xPjQL1hep%6CVl9z;+?C{LHm1maU&~DIlSE$l9FJiB5d*RyZe*md}g0TPq diff --git a/firmware/lib/__pycache__/utils.cpython-310.pyc b/firmware/lib/__pycache__/utils.cpython-310.pyc deleted file mode 100644 index 3889643ea9104c0b414825e1e8dfaf857413fe2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 985 zcmZ8g!EV$r5cN3DHoNT>sDP>h?nFXFTsWW#v1Ng-gtn+@wIY`&8=G!WwprOptD^K& zIP(Qa-6Ox0E2sWKFJ;CpRg0||&x{>=-kV9$?RFTBbnRvOi!=6zoSOq<>3nAqmqNO@Ie|9h3i?X%}BVUk@h5R0UI$PLkOyNheAN{UWWVYQHqWMlwDM)1oSa zFPWYmCRzn~HV&#X%gyuIQM0O5sWWw;?49vJqO)Y2DG`xVNYuqhXO@*^fcO zDb%*Pe(*ImrzR4^a|krG(AfnJpEs_Vg`kf?GZo$sqbMh(HF6K#l_t7qb9~6oz01O-8?!3`HPe1o6v4KO;XkRX?{l zIU}*4ATc>3wMgG3Ke;qFHLs*t-zhPvGB`QEv_!uowHU~ckI&4@EQycTE2zB1VUwGm RQks)$2Qsmk2}rOo0002JA{hVx diff --git a/tests/__pycache__/test_scout.cpython-310-pytest-7.1.3.pyc b/tests/__pycache__/test_scout.cpython-310-pytest-7.1.3.pyc deleted file mode 100644 index 961f3a7c2aee5082abea2f95c8865c6ef02ace30..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 878 zcmZWnJ&zMH5ViMvH(7ML>Nrs%q?J%2I)o590d<-y5N=k^+Q*vPFKn-(pzDI@5PyK; zQeMaJaZANtpn$SdzFlqx5V*AHyqBbV6^Zh1iQ<7rDV-{@i_bJJE%EApMlXvh&fC9AfG3t_MNIhL) z4DVp{9`^1$i&*>x!RhIJoa|$UFHw>H1}tb%U=t2hSG9F6tA5m<&l|CvDeKM@?^sC( zQA+-40_4{T00QMW$>I{rVw|EOkZqTjAF!Q#aWdv3Ig|r7vQq`hi zl6Qq~LRX9Aq7%B@=glcqic3h)rs1qy30>b|a? Date: Sat, 1 Oct 2022 11:41:35 -0400 Subject: [PATCH 04/15] Fix workflow --- .github/workflows/release.yml | 7 ------- .github/workflows/test.yml | 4 +--- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fbe7967..a086eba 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,13 +28,6 @@ jobs: pyenv install micropython-1.19.1 pyenv local micropython-1.19.1 micropython -m upip install -r requirements.txt -p 'firmware/' - - name: Run unittests - run: | - pyenv install 3.10.7 - pyenv local 3.10.7 - pip install -r test-requirements.txt - pytest - - name: Archive Release uses: thedoctor0/zip-release@main with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3cc0a7e..a3c251e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,7 +11,7 @@ jobs: uses: actions/checkout@v2 with: fetch-depth: 0 - - name: Install micropython dependencies + - name: Install dependencies and run tests run: | git clone https://github.com/pyenv/pyenv.git ~/.pyenv export PYENV_ROOT="$HOME/.pyenv" @@ -20,8 +20,6 @@ jobs: pyenv install micropython-1.19.1 pyenv local micropython-1.19.1 micropython -m upip install -r requirements.txt -p 'firmware/' - - name: Run unittests - run: | pyenv install 3.10.7 pyenv local 3.10.7 pip install -r test-requirements.txt From f1f5a53080c5c5fc28a1c785d64ca051f21fd10c Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 11:42:19 -0400 Subject: [PATCH 05/15] Fix Workflow job name --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a3c251e..e86625a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ on: jobs: release: - name: Release + name: Unit Test runs-on: ubuntu-latest steps: - name: Checkout From 000ab0dfdae5e8553ec6e640780d943ae3f50548 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 11:47:05 -0400 Subject: [PATCH 06/15] Fix: Use python setup stage --- .github/workflows/test.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e86625a..1cb0c39 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,7 +20,10 @@ jobs: pyenv install micropython-1.19.1 pyenv local micropython-1.19.1 micropython -m upip install -r requirements.txt -p 'firmware/' - pyenv install 3.10.7 - pyenv local 3.10.7 + - name: Setup Python 3.10 + - uses: actions/setup-python@v4 + with: + python-version: '3.10' + run: | pip install -r test-requirements.txt pytest \ No newline at end of file From 91f215822553ff2c45f42450845ad0f4aec78cca Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 11:49:39 -0400 Subject: [PATCH 07/15] Fix issues with test workflow --- .github/workflows/test.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1cb0c39..fe0a947 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,9 +21,11 @@ jobs: pyenv local micropython-1.19.1 micropython -m upip install -r requirements.txt -p 'firmware/' - name: Setup Python 3.10 - - uses: actions/setup-python@v4 + uses: actions/setup-python@v4 with: python-version: '3.10' - run: | - pip install -r test-requirements.txt - pytest \ No newline at end of file + - name: Install dependencies + run: pip install -r test-requirements.txt + - name: Run tests + run: pytest + From fcf81a8599d0638b0ad2d6ed6523133619c172eb Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 11:50:30 -0400 Subject: [PATCH 08/15] Fix redundant on in workflow --- .github/workflows/release.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a086eba..0cc8af6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,11 +5,6 @@ on: branches: [main] types: - completed - -on: - push: - branches: - - main jobs: release: name: Release From 593c125d66910b248bea51b1f936f2ff8be07f50 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 12:12:50 -0400 Subject: [PATCH 09/15] Fix: Make Pico connection more generalized --- firmware/lib/connection.py | 4 ++-- firmware/main.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/lib/connection.py b/firmware/lib/connection.py index a46b33c..5b1b5b6 100644 --- a/firmware/lib/connection.py +++ b/firmware/lib/connection.py @@ -15,9 +15,9 @@ def wireless_client_setup(): return wlan @staticmethod - def access_point_wifi_setup(): + def access_point_wifi_setup(essid, password): ap = network.WLAN(network.AP_IF) - ap.config(essid="BabyScout", password="BabyBuddy") + ap.config(essid=essid, password=password) ap.active(True) print(ap.status()) print(ap) diff --git a/firmware/main.py b/firmware/main.py index 93885c4..8037e1b 100644 --- a/firmware/main.py +++ b/firmware/main.py @@ -80,7 +80,7 @@ def ensure_connection(): ap_mode = True if ap_mode: print("No matching wifi, falling back to webpage based setup.") - ap = pico_connection.access_point_wifi_setup() + ap = pico_connection.access_point_wifi_setup("BabyScout", "BabyBuddy") ip = ap.ifconfig()[0] app = WebRouter(ip, 80, default_route, "webpages/static") app.route("/config")(config_route)() From 4710dfb65fdf3119c6f160e411ca04dfdcc9ac36 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 13:02:09 -0400 Subject: [PATCH 10/15] Add more tests --- Makefile | 4 ++- firmware/secrets.json.placeholder | 2 +- test-requirements.txt | 4 ++- tests/resources/fake_auth.json | 11 +++++++ tests/resources/fake_false_auth.json | 10 +++++++ tests/test_scout.py | 1 + tests/test_template.py | 27 +++++++++++++++++ tests/test_utils.py | 45 ++++++++++++++++++++++++++++ 8 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 tests/resources/fake_auth.json create mode 100644 tests/resources/fake_false_auth.json create mode 100644 tests/test_template.py create mode 100644 tests/test_utils.py diff --git a/Makefile b/Makefile index efba37e..9a49cbf 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ install_test_requirements: pip install -r test-requirements.txt - +run_tests: + pytest --cov=firmware/lib + coverage report --fail-under=80 diff --git a/firmware/secrets.json.placeholder b/firmware/secrets.json.placeholder index 6e339e3..fad08d6 100644 --- a/firmware/secrets.json.placeholder +++ b/firmware/secrets.json.placeholder @@ -1,6 +1,6 @@ { "SSIDS_PASSWORD": { - "MYSSID": "MYPASSWORD + "MYSSID": "MYPASSWORD" }, "BASE_URL": "http://baby.example.com/api/", "AUTHORIZATION": { diff --git a/test-requirements.txt b/test-requirements.txt index 16d3b77..025d717 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -1,2 +1,4 @@ pytest -requests \ No newline at end of file +requests +pytest-cov +coverage \ No newline at end of file diff --git a/tests/resources/fake_auth.json b/tests/resources/fake_auth.json new file mode 100644 index 0000000..fad08d6 --- /dev/null +++ b/tests/resources/fake_auth.json @@ -0,0 +1,11 @@ +{ + "SSIDS_PASSWORD": { + "MYSSID": "MYPASSWORD" + }, + "BASE_URL": "http://baby.example.com/api/", + "AUTHORIZATION": { + "CF-Access-Client-Id": "my cloudfront tunnel id", + "CF-Access-Client-Secret": "my cloudfront tunnel secret", + "Authorization": "Token my baby buddy token " + } +} \ No newline at end of file diff --git a/tests/resources/fake_false_auth.json b/tests/resources/fake_false_auth.json new file mode 100644 index 0000000..cd9b7b1 --- /dev/null +++ b/tests/resources/fake_false_auth.json @@ -0,0 +1,10 @@ +{ + "SSIDS_PASSWORD": { + "MYSSID": "MYPASSWORD" + }, + "AUTHORIZATION": { + "CF-Access-Client-Id": "my cloudfront tunnel id", + "CF-Access-Client-Secret": "my cloudfront tunnel secret", + "Authorization": "Token my baby buddy token " + } +} \ No newline at end of file diff --git a/tests/test_scout.py b/tests/test_scout.py index 75b2b76..6efb16b 100644 --- a/tests/test_scout.py +++ b/tests/test_scout.py @@ -2,6 +2,7 @@ from lib.scout import Scout with patch('lib.scout.send_api_request') as mock_api: + scout = Scout("fake_url") @patch('lib.scout.send_api_request') diff --git a/tests/test_template.py b/tests/test_template.py new file mode 100644 index 0000000..8b05657 --- /dev/null +++ b/tests/test_template.py @@ -0,0 +1,27 @@ +from lib.template import render_template + +template = """ + + + + test + + + {{ test }} + + +""" + +def test_render_template(): + rendered_template = render_template(template, {"test": "replaced!"}) + assert rendered_template == """ + + + + test + + + replaced! + + +""" \ No newline at end of file diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..9ff01a7 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,45 @@ +from lib.utils import retrieve_auth_variables, auth_variables_valid, get_base_path, join_path +import os + +fake_auth = { + "SSIDS_PASSWORD": { + "MYSSID": "MYPASSWORD" + }, + "BASE_URL": "http://baby.example.com/api/", + "AUTHORIZATION": { + "CF-Access-Client-Id": "my cloudfront tunnel id", + "CF-Access-Client-Secret": "my cloudfront tunnel secret", + "Authorization": "Token my baby buddy token " + } +} + +def test_retrieve_auth_variables(): + auth = retrieve_auth_variables(f"{os.getcwd()}/tests/resources/fake_auth.json") + assert auth == fake_auth + +def test_failed_retrieve_auth_variables(): + auth = retrieve_auth_variables(f"{os.getcwd()}/tests/resources/fake.json") + assert auth == None + +def test_auth_variables_valid(): + auth = retrieve_auth_variables(f"{os.getcwd()}/tests/resources/fake_auth.json") + valid = auth_variables_valid(auth) + assert valid == True + +def test_auth_variables_invalid(): + auth = retrieve_auth_variables(f"{os.getcwd()}/tests/resources/fake_auth.json") + valid = auth_variables_valid(None) + assert valid == False + +def test_auth_variables_invalid_wrong(): + auth = retrieve_auth_variables(f"{os.getcwd()}/tests/fake_false_auth.json") + valid = auth_variables_valid(None) + assert valid == False + +def test_get_base_path(): + path = get_base_path("test/best/rest") + assert path == "test/best" + +def test_join_path(): + path = join_path("test", "rest") + assert path == "test/rest" \ No newline at end of file From ded99dbbf0127af55c4762b0523497e3b52678ef Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 13:04:17 -0400 Subject: [PATCH 11/15] Add coverage failure --- .github/workflows/test.yml | 2 +- Makefile | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fe0a947..1f46ce7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,5 +27,5 @@ jobs: - name: Install dependencies run: pip install -r test-requirements.txt - name: Run tests - run: pytest + run: make run_tests diff --git a/Makefile b/Makefile index 9a49cbf..fa46902 100644 --- a/Makefile +++ b/Makefile @@ -3,4 +3,5 @@ install_test_requirements: run_tests: pytest --cov=firmware/lib + coverage xml coverage report --fail-under=80 From 43742875019bdfb167c03eaec463982b4b53aad7 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 17:00:28 -0400 Subject: [PATCH 12/15] Move Pico Connection to own library, add to requirements.txt --- conftest.py | 1 - firmware/lib/connection.py | 59 -------------------------------------- firmware/main.py | 2 +- requirements.txt | 3 +- tests/test_connection.py | 2 ++ tests/test_utils.py | 4 +-- 6 files changed, 7 insertions(+), 64 deletions(-) delete mode 100644 firmware/lib/connection.py create mode 100644 tests/test_connection.py diff --git a/conftest.py b/conftest.py index 07d33b3..a4f315d 100644 --- a/conftest.py +++ b/conftest.py @@ -11,7 +11,6 @@ def __init__(): machine = type(sys)('machine') machine.Pin = Pin - sys.modules['ujson'] = json sys.modules['urequests'] = requests sys.modules['uos'] = os diff --git a/firmware/lib/connection.py b/firmware/lib/connection.py deleted file mode 100644 index 5b1b5b6..0000000 --- a/firmware/lib/connection.py +++ /dev/null @@ -1,59 +0,0 @@ -import network -from lib.pin import onboard_led -import time - - -class PicoConnection: - def __init__(self): - self.wlan = self.wireless_client_setup() - self.nearby_access_points = self.scan_access_points() - - @staticmethod - def wireless_client_setup(): - wlan = network.WLAN(network.STA_IF) - wlan.active(True) - return wlan - - @staticmethod - def access_point_wifi_setup(essid, password): - ap = network.WLAN(network.AP_IF) - ap.config(essid=essid, password=password) - ap.active(True) - print(ap.status()) - print(ap) - return ap - - def connect_to_access_point(self, ssid, password): - # Attempt to connect to WIFI - if ssid not in self.nearby_access_points: - return False - self.wlan.active(True) - self.wlan.connect(ssid, password) - print(f"Attempting to connect to {ssid}") - while not self.wlan.isconnected(): - onboard_led() - time.sleep(0.5) - onboard_led() - time.sleep(0.5) - print("WLAN Connected") - return True - - def scan_access_points(self): - nearby_access_point_list = [] - nearby_access_points = self.wlan.scan() - for ssid in nearby_access_points: - nearby_access_point_list.append(ssid[0].decode("utf-8")) - self.wlan.active(False) - while "" in nearby_access_point_list: - nearby_access_point_list.remove("") - print(nearby_access_point_list) - return nearby_access_point_list - - def access_point_nearby(self, configured_ssids): - matching_ssids = [] - for ssid in configured_ssids: - if ssid in self.nearby_access_points: - matching_ssids.append(ssid) - if matching_ssids: - return matching_ssids[0] - return None diff --git a/firmware/main.py b/firmware/main.py index 8037e1b..f067b10 100644 --- a/firmware/main.py +++ b/firmware/main.py @@ -3,7 +3,7 @@ import uos as os import _thread from lib.utils import retrieve_auth_variables, join_path, auth_variables_valid -from lib.connection import PicoConnection +from picoconnection import PicoConnection from lib.webpage import config_route, default_route from lib.scout import connect_to_baby_buddy from picowebrouter import WebRouter diff --git a/requirements.txt b/requirements.txt index 5a7a4cd..84420b2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1 +1,2 @@ -micropython-picowebrouter==0.0.2 \ No newline at end of file +micropython-picowebrouter==0.0.2 +micropython-picoconnection==0.0.0 \ No newline at end of file diff --git a/tests/test_connection.py b/tests/test_connection.py new file mode 100644 index 0000000..19c235d --- /dev/null +++ b/tests/test_connection.py @@ -0,0 +1,2 @@ +from lib.connection import PicoConnection + diff --git a/tests/test_utils.py b/tests/test_utils.py index 9ff01a7..3847299 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -32,8 +32,8 @@ def test_auth_variables_invalid(): assert valid == False def test_auth_variables_invalid_wrong(): - auth = retrieve_auth_variables(f"{os.getcwd()}/tests/fake_false_auth.json") - valid = auth_variables_valid(None) + auth = retrieve_auth_variables(f"{os.getcwd()}/tests/resources/fake_false_auth.json") + valid = auth_variables_valid(auth) assert valid == False def test_get_base_path(): From bdeaceffd9015f7846969a6d024c8426c349c15f Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 17:03:35 -0400 Subject: [PATCH 13/15] Remove test_connection --- tests/test_connection.py | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 tests/test_connection.py diff --git a/tests/test_connection.py b/tests/test_connection.py deleted file mode 100644 index 19c235d..0000000 --- a/tests/test_connection.py +++ /dev/null @@ -1,2 +0,0 @@ -from lib.connection import PicoConnection - From 17c26a4c27b51dca6e8450f7a7fee302a31ef406 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 17:46:21 -0400 Subject: [PATCH 14/15] 100% Unit tests on scout.py --- firmware/lib/scout.py | 6 --- tests/test_scout.py | 97 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 92 insertions(+), 11 deletions(-) diff --git a/firmware/lib/scout.py b/firmware/lib/scout.py index 9413a51..da8d69e 100644 --- a/firmware/lib/scout.py +++ b/firmware/lib/scout.py @@ -2,8 +2,6 @@ import urequests as requests import ujson as json import uos as os -from lib.pin import onboard_led -import time class Scout: @@ -112,10 +110,6 @@ def connect_to_baby_buddy(base_url): baby_buddy_reachable = True except OSError: print("Failed to connect to BabyBuddy") - onboard_led() - time.sleep(1) - onboard_led() - onboard_led(0) print("Connected to BabyBuddy") return baby_buddy diff --git a/tests/test_scout.py b/tests/test_scout.py index 6efb16b..4c839ef 100644 --- a/tests/test_scout.py +++ b/tests/test_scout.py @@ -1,8 +1,7 @@ from unittest.mock import patch -from lib.scout import Scout +from lib.scout import Scout, connect_to_baby_buddy, send_api_request with patch('lib.scout.send_api_request') as mock_api: - scout = Scout("fake_url") @patch('lib.scout.send_api_request') @@ -12,13 +11,101 @@ def test_init_scout_children(mock_api_request): mock_api_request.assert_called_with("fake_url", "children") @patch('lib.scout.send_api_request') -def test_init_scout_children(mock_api_request): +def test_bottle_feed(mock_api_request): # Test Initializing Scout class scout.bottle_feed(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) @patch('lib.scout.send_api_request') -def test_init_scout_children(mock_api_request): +def test_right_breast(mock_api_request): # Test Initializing Scout class - scout.bottle_feed(0) + scout.right_breast(0) + mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) + +@patch('lib.scout.send_api_request') +def test_left_breast(mock_api_request): + # Test Initializing Scout class + scout.left_breast(0) mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) + +@patch('lib.scout.send_api_request') +def test_both_breasts(mock_api_request): + # Test Initializing Scout class + scout.breast_feed(0) + mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'feedings'}) + +@patch('lib.scout.send_api_request') +def test_wet_solid_diaper(mock_api_request): + # Test Initializing Scout class + scout.wet_solid_diaper(0) + mock_api_request.assert_called_with('fake_url', 'changes', data={'wet': True, 'solid': True, 'child': 0}) + +@patch('lib.scout.send_api_request') +def test_solid_diaper(mock_api_request): + # Test Initializing Scout class + scout.solid_diaper(0) + mock_api_request.assert_called_with('fake_url', 'changes', data={'wet': False, 'solid': True, 'child': 0}) + +@patch('lib.scout.send_api_request') +def test_wet_diaper(mock_api_request): + # Test Initializing Scout class + scout.wet_diaper(0) + mock_api_request.assert_called_with('fake_url', 'changes', data={'wet': True, 'solid': False, 'child': 0}) + + +@patch('lib.scout.send_api_request') +def test_conect_to_baby_buddy(mock_api_request): + mock_api_request.side_effect = [OSError("test"), {"results": [{"id": 1}]}] + # Test Initializing Scout class + scout = connect_to_baby_buddy('fake_url') + mock_api_request.assert_called_with('fake_url', 'children') + +@patch('lib.scout.utils.retrieve_auth_variables') +@patch('lib.scout.requests') +def test_get_send_api_request(mock_request, mock_utils): + class FakeRequest: + def __init__(self): + self.content = '{"test": "test"}' + fake = FakeRequest() + mock_request.get.side_effect = [fake] + mock_utils.side_effect = [{"AUTHORIZATION": {"test": "test"}}, {"AUTHORIZATION": {"test": "test"}}] + request = send_api_request("test", "best", {"test": "test"}) + assert request == {'test': 'test'} + +@patch('lib.scout.utils.retrieve_auth_variables') +@patch('lib.scout.requests') +def test_post_send_api_request(mock_request, mock_utils): + class FakeRequest: + def __init__(self): + self.content = '{"test": "test"}' + fake = FakeRequest() + mock_request.post.side_effect = [fake] + mock_utils.side_effect = [{"AUTHORIZATION": {"test": "test"}}, {"AUTHORIZATION": {"test": "test"}}] + request = send_api_request("test", "best", {"headers": "headers"}, {"data": "data"}) + assert request == {'test': 'test'} + +@patch('lib.scout.send_api_request') +def test_sleep(mock_api_request): + # Test Initializing Scout class + scout.sleep(0) + mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'sleep'}) + +@patch('lib.scout.send_api_request') +def test_tummy_time(mock_api_request): + # Test Initializing Scout class + scout.tummy_time(0) + mock_api_request.assert_called_with('fake_url', path='timers', data={'child': 0, 'name': 'tummy-times'}) + +@patch('lib.scout.send_api_request') +def test_get_timers(mock_api_request): + mock_api_request.side_effect = [{"results": [{"name": "sleep", "child": 0, "active": True}]}] + # Test Initializing Scout class + timer = scout.get_timer(0, "sleep") + assert timer == {'active': True, 'child': 0, 'name': 'sleep'} + +@patch('lib.scout.send_api_request') +def test_resolve_timers_current_timer(mock_api_request): + mock_api_request.side_effect = [{"results": [{"name": "sleep", "child": 0, "active": True, "id": 0}]}, None] + # Test Initializing Scout class + timer = scout.resolve_timers(0, "sleep", {"timer": 0}) + assert timer == None \ No newline at end of file From 2792d61fba9df6a629d7b8456c7c68a803d259b6 Mon Sep 17 00:00:00 2001 From: Michael Schappacher Date: Sat, 1 Oct 2022 18:12:34 -0400 Subject: [PATCH 15/15] Pass 80% coverage requirement --- tests/resources/test.html | 9 +++++++++ tests/test_webpage.py | 24 ++++++++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/resources/test.html create mode 100644 tests/test_webpage.py diff --git a/tests/resources/test.html b/tests/resources/test.html new file mode 100644 index 0000000..6c4b6c1 --- /dev/null +++ b/tests/resources/test.html @@ -0,0 +1,9 @@ + + + + test + + + {{ test }} + + \ No newline at end of file diff --git a/tests/test_webpage.py b/tests/test_webpage.py new file mode 100644 index 0000000..4812955 --- /dev/null +++ b/tests/test_webpage.py @@ -0,0 +1,24 @@ +from unittest.mock import patch +from lib.webpage import load_webpage, default_route +import os + + +def test_load_webpage(): + webpage = load_webpage(f"{os.getcwd()}/tests/resources/test.html") + assert webpage == """ + + + test + + + {{ test }} + + """ + +@patch("lib.webpage.template.render_template") +@patch("lib.webpage.load_webpage") +def test_default_route(mock_webpage, render_template): + webpage = default_route() + mock_webpage.assert_called_with('webpages/default.html') + +