began testing, added CI
This commit is contained in:
parent
71a59b526e
commit
0614860c63
46
.github/workflows/ci.yml
vendored
Normal file
46
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
name: Tests
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
python-version: [3.8]
|
||||
poetry-version: [1.1.4]
|
||||
# node: [ '10', '12' ]
|
||||
os: [ubuntu-20.04, ubuntu-18.04, macos-latest, windows-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2 # get source
|
||||
|
||||
- name: Install Python 3
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install Poetry # PYTHON dependency management
|
||||
uses: abatilo/actions-poetry@v2.1.0
|
||||
with:
|
||||
poetry-version: ${{ matrix.poetry-version }}
|
||||
|
||||
- name: Install Dependencies # PYTHON install dependencies
|
||||
run: poetry install
|
||||
|
||||
# - name: Setup node # JS setup
|
||||
# uses: actions/setup-node@v2
|
||||
# with:
|
||||
# node-version: ${{ matrix.node }}
|
||||
|
||||
# - name: Install Node Packages # JS install
|
||||
# run: npm ci
|
||||
|
||||
- name: Set up Cloud SDK
|
||||
uses: google-github-actions/setup-gcloud@master
|
||||
with:
|
||||
project_id: ${{ secrets.GCP_PROJECT_ID }}
|
||||
service_account_key: ${{ secrets.GCP_SA_KEY }}
|
||||
export_default_credentials: true
|
||||
|
||||
- name: Run Tests # test script
|
||||
run: poetry run python -m unittest discover -s tests
|
@ -1,6 +1,8 @@
|
||||
[Music Tools](https://music.sarsoo.xyz)
|
||||
==================
|
||||
|
||||
![Python Tests](https://github.com/sarsoo/music-tools/workflows/Tests/badge.svg)
|
||||
|
||||
Set of utility tools for Spotify and Last.fm.
|
||||
Built on my other libraries for Spotify ([spotframework](https://github.com/Sarsoo/spotframework)), Last.fm ([fmframework](https://github.com/Sarsoo/pyfmframework)) and interfacing utility tools for the two ([spotfm](https://github.com/Sarsoo/pyfmframework)). Currently running on a suite of Google Cloud Platform services. An iOS client is currently under development [here](https://github.com/Sarsoo/Music-Tools-iOS).
|
||||
|
||||
|
6
admin.py
6
admin.py
@ -3,6 +3,7 @@ import shutil
|
||||
import os
|
||||
from pathlib import Path
|
||||
import sys
|
||||
import subprocess
|
||||
from cmd import Cmd
|
||||
|
||||
stage_dir = '.music-tools'
|
||||
@ -187,6 +188,11 @@ class Admin(Cmd):
|
||||
with open('requirements.txt', 'w') as f:
|
||||
f.write("\n".join(filtered))
|
||||
|
||||
def test():
|
||||
os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = 'service.json'
|
||||
subprocess.run(
|
||||
['python', '-u', '-m', 'unittest', 'discover', "-s", "tests"]
|
||||
)
|
||||
|
||||
if __name__ == '__main__':
|
||||
console = Admin()
|
||||
|
51
poetry.lock
generated
51
poetry.lock
generated
@ -122,8 +122,10 @@ requests = "^2.24.0"
|
||||
image = []
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "../fmframework"
|
||||
type = "git"
|
||||
url = "https://github.com/Sarsoo/pyfmframework.git"
|
||||
reference = "master"
|
||||
resolved_reference = "bf111d06cb4ffc9dbe0b57fbf83a3c236365c2ad"
|
||||
|
||||
[[package]]
|
||||
name = "google-api-core"
|
||||
@ -149,7 +151,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "google-auth"
|
||||
version = "1.24.0"
|
||||
version = "1.25.0"
|
||||
description = "Google Authentication Library"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -166,7 +168,7 @@ aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)"]
|
||||
|
||||
[[package]]
|
||||
name = "google-cloud-core"
|
||||
version = "1.5.0"
|
||||
version = "1.6.0"
|
||||
description = "Google Cloud API client core library"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -174,6 +176,7 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*"
|
||||
|
||||
[package.dependencies]
|
||||
google-api-core = ">=1.21.0,<2.0.0dev"
|
||||
google-auth = ">=1.24.0,<2.0dev"
|
||||
six = ">=1.12.0"
|
||||
|
||||
[package.extras]
|
||||
@ -301,7 +304,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
|
||||
|
||||
[[package]]
|
||||
name = "jinja2"
|
||||
version = "2.11.2"
|
||||
version = "2.11.3"
|
||||
description = "A very fast and expressive template engine."
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -384,7 +387,7 @@ toml = ">=0.7.1"
|
||||
|
||||
[[package]]
|
||||
name = "pytz"
|
||||
version = "2020.5"
|
||||
version = "2021.1"
|
||||
description = "World timezone definitions, modern and historical"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -445,16 +448,18 @@ python-versions = "^3.8"
|
||||
develop = false
|
||||
|
||||
[package.dependencies]
|
||||
fmframework = "1.0.0"
|
||||
spotframework = "1.0.0"
|
||||
fmframework = "branch master"
|
||||
spotframework = "branch master"
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "../spotfm"
|
||||
type = "git"
|
||||
url = "https://github.com/Sarsoo/spotfm.git"
|
||||
reference = "master"
|
||||
resolved_reference = "4713e82819b110358ec94af7a5f9919d1aca3614"
|
||||
|
||||
[[package]]
|
||||
name = "spotframework"
|
||||
version = "1.0.0"
|
||||
version = "1.0.1"
|
||||
description = "Spotify HTTP wrapper library"
|
||||
category = "main"
|
||||
optional = false
|
||||
@ -467,8 +472,10 @@ requests = "^2.24.0"
|
||||
tabulate = "^0.8.7"
|
||||
|
||||
[package.source]
|
||||
type = "directory"
|
||||
url = "../spotframework"
|
||||
type = "git"
|
||||
url = "https://github.com/Sarsoo/spotframework.git"
|
||||
reference = "master"
|
||||
resolved_reference = "ac8944764f1ff3c3db40b4bc7a8897a482db9434"
|
||||
|
||||
[[package]]
|
||||
name = "tabulate"
|
||||
@ -525,7 +532,7 @@ python-versions = "*"
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.8"
|
||||
content-hash = "bee9f68f62a9a9f5f4d7ee11e6687acb09e8aee69956ca4767b5f25f71a94bb6"
|
||||
content-hash = "943b58ae3ae110c4c990bab3fa72b73b0f8a172905246839c2fe481c73919067"
|
||||
|
||||
[metadata.files]
|
||||
astroid = [
|
||||
@ -573,12 +580,12 @@ google-api-core = [
|
||||
{file = "google_api_core-1.25.1-py2.py3-none-any.whl", hash = "sha256:292dd636ed381098d24b7093ccb826b2278a12d886a3fc982084069aa24a8fbb"},
|
||||
]
|
||||
google-auth = [
|
||||
{file = "google-auth-1.24.0.tar.gz", hash = "sha256:0b0e026b412a0ad096e753907559e4bdb180d9ba9f68dd9036164db4fdc4ad2e"},
|
||||
{file = "google_auth-1.24.0-py2.py3-none-any.whl", hash = "sha256:ce752cc51c31f479dbf9928435ef4b07514b20261b021c7383bee4bda646acb8"},
|
||||
{file = "google-auth-1.25.0.tar.gz", hash = "sha256:514e39f4190ca972200ba33876da5a8857c5665f2b4ccc36c8b8ee21228aae80"},
|
||||
{file = "google_auth-1.25.0-py2.py3-none-any.whl", hash = "sha256:008e23ed080674f69f9d2d7d80db4c2591b9bb307d136cea7b3bc129771d211d"},
|
||||
]
|
||||
google-cloud-core = [
|
||||
{file = "google-cloud-core-1.5.0.tar.gz", hash = "sha256:1277a015f8eeb014c48f2ec094ed5368358318f1146cf49e8de389962dc19106"},
|
||||
{file = "google_cloud_core-1.5.0-py2.py3-none-any.whl", hash = "sha256:99a8a15f406f53f2b11bda1f45f952a9cdfbdbba8abf40c75651019d800879f5"},
|
||||
{file = "google-cloud-core-1.6.0.tar.gz", hash = "sha256:c6abb18527545379fc82efc4de75ce9a3772ccad2fc645adace593ba097cbb02"},
|
||||
{file = "google_cloud_core-1.6.0-py2.py3-none-any.whl", hash = "sha256:40d9c2da2d03549b5ac3dcccf289d4f15e6d1210044c6381ce45c92913e62904"},
|
||||
]
|
||||
google-cloud-firestore = [
|
||||
{file = "google-cloud-firestore-1.9.0.tar.gz", hash = "sha256:d8a56919a3a32c7271d1253542ec24cb13f384a726fed354fdeb2a2269f25d1c"},
|
||||
@ -664,8 +671,8 @@ itsdangerous = [
|
||||
{file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"},
|
||||
]
|
||||
jinja2 = [
|
||||
{file = "Jinja2-2.11.2-py2.py3-none-any.whl", hash = "sha256:f0a4641d3cf955324a89c04f3d94663aa4d638abe8f733ecd3582848e1c37035"},
|
||||
{file = "Jinja2-2.11.2.tar.gz", hash = "sha256:89aab215427ef59c34ad58735269eb58b1a5808103067f7bb9d5836c651b3bb0"},
|
||||
{file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"},
|
||||
{file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"},
|
||||
]
|
||||
lazy-object-proxy = [
|
||||
{file = "lazy-object-proxy-1.4.3.tar.gz", hash = "sha256:f3900e8a5de27447acbf900b4750b0ddfd7ec1ea7fbaf11dfa911141bc522af0"},
|
||||
@ -784,8 +791,8 @@ pylint = [
|
||||
{file = "pylint-2.5.3.tar.gz", hash = "sha256:7dd78437f2d8d019717dbf287772d0b2dbdfd13fc016aa7faa08d67bccc46adc"},
|
||||
]
|
||||
pytz = [
|
||||
{file = "pytz-2020.5-py2.py3-none-any.whl", hash = "sha256:16962c5fb8db4a8f63a26646d8886e9d769b6c511543557bc84e9569fb9a9cb4"},
|
||||
{file = "pytz-2020.5.tar.gz", hash = "sha256:180befebb1927b16f6b57101720075a984c019ac16b1b7575673bea42c6c3da5"},
|
||||
{file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"},
|
||||
{file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"},
|
||||
]
|
||||
requests = [
|
||||
{file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"},
|
||||
|
@ -12,6 +12,7 @@ packages = [
|
||||
|
||||
[tool.poetry.scripts]
|
||||
backend-dev = 'music.music:start'
|
||||
test = 'admin:test'
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.8"
|
||||
@ -23,9 +24,9 @@ google-cloud-pubsub = "^1.6.0"
|
||||
google-cloud-tasks = "^1.5.0"
|
||||
requests = "^2.24.0"
|
||||
|
||||
spotframework = { path = "../spotframework" }
|
||||
fmframework = { path = "../fmframework" }
|
||||
spotfm = { path = "../spotfm" }
|
||||
spotframework = { git = "https://github.com/Sarsoo/spotframework.git" }
|
||||
fmframework = { git = "https://github.com/Sarsoo/pyfmframework.git" }
|
||||
spotfm = { git = "https://github.com/Sarsoo/spotfm.git" }
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pylint = "2.5.3"
|
||||
|
97
tests/test_api.py
Normal file
97
tests/test_api.py
Normal file
@ -0,0 +1,97 @@
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
import flask
|
||||
|
||||
from music.music import create_app
|
||||
import music.model.playlist
|
||||
|
||||
class TestAPI(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.app = create_app()
|
||||
self.app.testing = True
|
||||
self.test_app = self.app.test_client()
|
||||
|
||||
### ROOT ###
|
||||
|
||||
def test_root_route_without_login(self):
|
||||
response = self.test_app.get('/')
|
||||
self.assertTrue(199 < response.status_code <= 299)
|
||||
|
||||
def test_root_route_with_login(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'test'
|
||||
response = self.test_app.get('/')
|
||||
self.assertTrue(299 < response.status_code <= 399)
|
||||
|
||||
def test_app_route_redirects_without_login(self):
|
||||
response = self.test_app.get('/app')
|
||||
self.assertTrue(299 < response.status_code <= 399)
|
||||
|
||||
def test_app_route_with_login(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'test'
|
||||
response = self.test_app.get('/app')
|
||||
self.assertTrue(199 < response.status_code <= 299)
|
||||
|
||||
### PLAYLISTS ###
|
||||
|
||||
def test_all_playlists_route(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'andy'
|
||||
response = self.test_app.get('/api/playlists')
|
||||
|
||||
self.assertTrue(199 < response.status_code <= 299)
|
||||
self.assertIsNotNone(response.get_json())
|
||||
self.assertTrue(len(response.get_json()['playlists']) > 0)
|
||||
|
||||
def test_playlist_get(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'andy'
|
||||
response = self.test_app.get('/api/playlist?name=RAP')
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_playlist_get_no_param(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'andy'
|
||||
response = self.test_app.get('/api/playlist')
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_playlist_get_wrong_param(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'andy'
|
||||
response = self.test_app.get('/api/playlist?name=playlist_name')
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
#TODO: patch fireo so can test delete
|
||||
|
||||
def test_playlist_delete_no_param(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'andy'
|
||||
response = self.test_app.delete('/api/playlist')
|
||||
|
||||
self.assertEqual(response.status_code, 400)
|
||||
|
||||
def test_playlist_delete_wrong_param(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'andy'
|
||||
response = self.test_app.delete('/api/playlist?name=playlist_name')
|
||||
|
||||
self.assertEqual(response.status_code, 404)
|
||||
|
||||
### USERS ###
|
||||
def test_user_get(self):
|
||||
with self.test_app.session_transaction() as sess:
|
||||
sess['username'] = 'andy'
|
||||
response = self.test_app.get('/api/user')
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIsNotNone(response.get_json())
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
192
tests/test_decorators.py
Normal file
192
tests/test_decorators.py
Normal file
@ -0,0 +1,192 @@
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import Mock
|
||||
|
||||
import flask
|
||||
|
||||
from music.music import create_app
|
||||
from music.api.decorators import is_logged_in, admin_required, spotify_link_required, lastfm_username_required, check_dict, validate_json
|
||||
|
||||
class TestDecorators(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.app = create_app()
|
||||
self.app.testing = True
|
||||
self.test_app = self.app.test_client()
|
||||
|
||||
### LOGGED IN ###
|
||||
|
||||
def test_is_logged_in_default_session(self):
|
||||
with self.app.test_request_context('/'):
|
||||
self.assertFalse('username' in flask.session)
|
||||
self.assertFalse(is_logged_in())
|
||||
|
||||
def test_is_logged_in(self):
|
||||
with self.app.test_request_context('/'):
|
||||
flask.session['username'] = 'test'
|
||||
self.assertTrue('username' in flask.session)
|
||||
self.assertTrue(is_logged_in())
|
||||
|
||||
### ADMIN ###
|
||||
|
||||
def test_admin_required(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
func.return_value = 5 # a known value to test for
|
||||
wrapped = admin_required(func)
|
||||
|
||||
user_mock = Mock()
|
||||
user_mock.type = 'admin'
|
||||
resp = wrapped(user=user_mock)
|
||||
|
||||
self.assertEqual(resp, 5)
|
||||
|
||||
def test_admin_required_no_user(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
wrapped = admin_required(func)
|
||||
|
||||
resp = wrapped()
|
||||
|
||||
self.assertEqual(resp[1], 401)
|
||||
|
||||
def test_admin_required_not_permitted(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
wrapped = admin_required(func)
|
||||
|
||||
user_mock = Mock()
|
||||
user_mock.type = 'user'
|
||||
resp = wrapped(user=user_mock)
|
||||
|
||||
self.assertEqual(resp[1], 401)
|
||||
|
||||
### SPOTIFY ###
|
||||
|
||||
def test_spotify_required(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
func.return_value = 5 # a known value to test for
|
||||
wrapped = spotify_link_required(func)
|
||||
|
||||
user_mock = Mock()
|
||||
user_mock.spotify_linked = True
|
||||
resp = wrapped(user=user_mock)
|
||||
|
||||
self.assertEqual(resp, 5)
|
||||
|
||||
def test_spotify_required_no_user(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
wrapped = spotify_link_required(func)
|
||||
|
||||
resp = wrapped()
|
||||
|
||||
self.assertEqual(resp[1], 401)
|
||||
|
||||
def test_spotify_required_not_linked(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
wrapped = spotify_link_required(func)
|
||||
|
||||
user_mock = Mock()
|
||||
user_mock.spotify_linked = False
|
||||
resp = wrapped(user=user_mock)
|
||||
|
||||
self.assertEqual(resp[1], 401)
|
||||
|
||||
### LAST.FM ###
|
||||
|
||||
def test_lastfm_required(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
func.return_value = 5 # a known value to test for
|
||||
wrapped = lastfm_username_required(func)
|
||||
|
||||
user_mock = Mock()
|
||||
user_mock.lastfm_username = 'test_username'
|
||||
resp = wrapped(user=user_mock)
|
||||
|
||||
self.assertEqual(resp, 5)
|
||||
|
||||
def test_lastfm_required_no_user(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
wrapped = lastfm_username_required(func)
|
||||
|
||||
resp = wrapped()
|
||||
|
||||
self.assertEqual(resp[1], 401)
|
||||
|
||||
def test_lastfm_required_zero_length(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
wrapped = lastfm_username_required(func)
|
||||
|
||||
user_mock = Mock()
|
||||
user_mock.lastfm_username = ''
|
||||
resp = wrapped(user=user_mock)
|
||||
|
||||
self.assertEqual(resp[1], 401)
|
||||
|
||||
### CHECK_DICT ###
|
||||
|
||||
def test_check_dict(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
func.return_value = 5 # a known value to test for
|
||||
|
||||
resp = check_dict(
|
||||
request_params=["test1", "test2", "test3"],
|
||||
expected_args=["test1", "test2", "test3"],
|
||||
func=func,
|
||||
args=[],
|
||||
kwargs={}
|
||||
)
|
||||
|
||||
self.assertEqual(resp, 5)
|
||||
|
||||
def test_check_dict_missing_required(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
func.return_value = 5 # a known value to test for
|
||||
|
||||
resp = check_dict(
|
||||
request_params=["test1", "test2"],
|
||||
expected_args=["test1", "test2", "test3"],
|
||||
func=func,
|
||||
args=[],
|
||||
kwargs={}
|
||||
)
|
||||
|
||||
self.assertEqual(resp[1], 400)
|
||||
|
||||
def test_check_dict_tuples(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
func.return_value = 5 # a known value to test for
|
||||
|
||||
resp = check_dict(
|
||||
request_params={"test1": 'hello world', "test2": 10, "test3": True},
|
||||
expected_args=[("test1", str), ("test2", int), ("test3", bool)],
|
||||
func=func,
|
||||
args=[],
|
||||
kwargs={}
|
||||
)
|
||||
|
||||
self.assertEqual(resp, 5)
|
||||
|
||||
def test_check_dict_tuples_wrong_type(self):
|
||||
with self.app.test_request_context('/'):
|
||||
func = Mock()
|
||||
func.return_value = 5 # a known value to test for
|
||||
|
||||
resp = check_dict(
|
||||
request_params={"test1": 'hello world', "test2": "hello world", "test3": True},
|
||||
expected_args=[("test1", str), ("test2", int), ("test3", bool)],
|
||||
func=func,
|
||||
args=[],
|
||||
kwargs={}
|
||||
)
|
||||
|
||||
self.assertEqual(resp[1], 400)
|
21
tests/test_model.py
Normal file
21
tests/test_model.py
Normal file
@ -0,0 +1,21 @@
|
||||
import unittest
|
||||
|
||||
from music.model.user import User
|
||||
|
||||
class TestUser(unittest.TestCase):
|
||||
|
||||
def test_fetch_all(self):
|
||||
users = User.collection.fetch()
|
||||
self.assertIsNotNone(users)
|
||||
self.assertTrue(len([i for i in users]) > 0)
|
||||
|
||||
def test_to_dict(self):
|
||||
users = [i for i in User.collection.fetch()]
|
||||
self.assertIsInstance(users[0].to_dict(), dict)
|
||||
|
||||
def test_to_dict_filtered_keys(self):
|
||||
users = [i for i in User.collection.fetch()]
|
||||
|
||||
for user in users:
|
||||
for key in ['password', 'access_token', 'refresh_token', 'token_expiry', 'id', 'key']:
|
||||
self.assertNotIn(key, user.to_dict())
|
Loading…
Reference in New Issue
Block a user