Skip to content

Commit

Permalink
[CE-114] Add test case for user management module
Browse files Browse the repository at this point in the history
Add run test case in Makefile check
Add test case for user management module

Change-Id: I5abbfcd6a849cb6f6ff64b5522c81b5228184a96
Signed-off-by: Haitao Yue <hightall@me.com>
  • Loading branch information
hightall committed Aug 19, 2017
1 parent b048138 commit ffa7404
Show file tree
Hide file tree
Showing 13 changed files with 205 additions and 12 deletions.
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,12 @@ all: check

check: ##@Code Check code format
tox
@$(MAKE) test-case
make start && sleep 10 && make stop

test-case: ##@Code Run test case for flask server
@$(MAKE) -C test/ all

clean: ##@Code Clean tox result
rm -rf .tox .cache *.egg-info
find . -name "*.pyc" -o -name "__pycache__" -exec rm -rf "{}" \;
Expand Down
7 changes: 5 additions & 2 deletions src/modules/user/management/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
logger.addHandler(log_handler)

user_create_fields = {
"status": fields.String
"status": fields.String,
"id": fields.String
}

user_create_parser = reqparse.RequestParser()
Expand Down Expand Up @@ -54,13 +55,15 @@ def post(self, **kwargs):
salt = app.config.get("SALT", b"")
password = bcrypt.hashpw(password.encode('utf8'), bytes(salt.encode()))
status = "OK"
user_id = ""

try:
user = User(username, password, is_admin=role == ADMIN,
role=role, active=active, balance=balance)
user.save()
user_id = user.id
except Exception as exc:
logger.error("exc %s", exc)
status = "FAIL"

return {"status": status}, 200
return {"status": status, "id": user_id}, 200
2 changes: 2 additions & 0 deletions src/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ mongoengine>=0.10.0,<=0.13.0
flask-login>=0.4.0,<=0.4.0
bcrypt>=3.0.0,<=3.1.0
flask-restful>=0.2.1,<=0.3.6
Flask-Testing>=0.5.0,<=0.6.2
Faker>=0.7.17,<=0.7.18
6 changes: 2 additions & 4 deletions src/resources/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ def save(self):
balance=self.balance,
isAdmin=self.isAdmin)
new_user.save()
self.id = new_user.id
self.id = str(new_user.id)
return self.id

def get_by_username(self, username):
Expand All @@ -59,7 +59,6 @@ def get_by_username_w_password(self, username):
dbUser = models.User.objects.get(username=username)

if dbUser:
logger.info("get user")
self.username = dbUser.username
self.active = dbUser.active
self.password = dbUser.password
Expand All @@ -68,10 +67,9 @@ def get_by_username_w_password(self, username):
self.balance = dbUser.balance
return self
else:
logger.info("not get user")
return None
except Exception as exc:
logger.info("get user exc %s", exc)
logger.error("get user exc %s", exc)
return None

def get_by_id(self, id):
Expand Down
6 changes: 3 additions & 3 deletions src/themes/basic/static/js/routes/stat.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Copyright IBM Corp, All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
/** Copyright IBM Corp, All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

Vue.component('chart', VueECharts)
Expand Down
6 changes: 3 additions & 3 deletions src/themes/basic/static/js/routes/users.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Copyright IBM Corp, All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
/** Copyright IBM Corp, All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

Vue.prototype.unixMoment = function (time) {
Expand Down
3 changes: 3 additions & 0 deletions test/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
COMPOSE_PROJECT_NAME=dashboard-test
STATIC_FOLDER=themes/basic/static
TEMPLATE_FOLDER=themes/basic/templates
8 changes: 8 additions & 0 deletions test/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright IBM Corp, All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
test:
docker-compose up --abort-on-container-exit

all: test
5 changes: 5 additions & 0 deletions test/cases/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# Copyright IBM Corp, All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
23 changes: 23 additions & 0 deletions test/cases/run.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

# Copyright IBM Corp, All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
import sys
import unittest
from test_user_management import UserManagementTestCase


def suite():
suit = unittest.TestSuite()
suit.addTest(unittest.makeSuite(UserManagementTestCase))

return suit


def run():
result = unittest.TextTestRunner(verbosity=2).run(suite())


if __name__ == '__main__':
run()
98 changes: 98 additions & 0 deletions test/cases/test_user_management.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@

# Copyright IBM Corp, All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
import unittest
from flask_testing import TestCase
import sys
import os
import logging
import json
from faker import Factory
fake = Factory.create()

sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'src'))
from dashboard import app
from common import log_handler, LOG_LEVEL
from resources.models import COMMON_USER

logger = logging.getLogger(__name__)
logger.setLevel(LOG_LEVEL)
logger.addHandler(log_handler)


class UserManagementTestCase(TestCase):
def create_app(self):
app.config['TESTING'] = True
app.config['LOGIN_DISABLED'] = False
return app

def _login(self, username, password):
return self.client.post('/api/auth/login',
data=dict(
username=username,
password=password
),
follow_redirects=True)

def test_server_is_up_and_running(self):
response = self.client.get("/login")
self.assert200(response)

def test_login_required(self):
response = self.client.get("/")
self.assertRedirects(response, "/login")

def test_valid_login(self):
response = self._login("admin", "pass")
response = response.data.decode("utf-8")
response = json.loads(response)
self.assertEqual(response.get("status", ""), "OK")

def test_list_user(self):
self._login("admin", "pass")
raw_response = self.client.get("/api/user/list")
response = raw_response.data.decode("utf-8")
response = json.loads(response)
users = response.get("users", {}).get("result", [])
self.assertTrue(len(users) >= 1)

def test_create_update_delete_user(self):
self._login("admin", "pass")
user_name = fake.user_name()
password = fake.password()
raw_response = self.client.post("/api/user/create",
data=dict(
username=user_name,
password=password,
active=True,
role=COMMON_USER
))
response = raw_response.data.decode("utf-8")
response = json.loads(response)
user_id = response.get("id", "")
self.assertTrue(user_id != "")

response = self._login(user_name, password)
response = response.data.decode("utf-8")
response = json.loads(response)
self.assertEqual(response.get("status", ""), "OK")

self._login("admin", "pass")

new_user_name = fake.user_name()
response = self.client.put("/api/user/update/%s" % user_id,
data=dict(
username=new_user_name,
active=True,
role=COMMON_USER
))
response = response.data.decode("utf-8")
response = json.loads(response)
self.assertEqual(response.get("status", ""), "OK")

response = self.client.delete("/api/user/delete/%s" % user_id)
response = response.data.decode("utf-8")
response = json.loads(response)
self.assertEqual(response.get("status", ""), "OK")
44 changes: 44 additions & 0 deletions test/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# This compose file will deploy the services, and bootup a mongo server.

# Copyright IBM Corp., All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#
# Local `/opt/cello/mongo` will be used for the db storage.
# dashboard: dashboard service of cello, listen on 8080
# app: app service of cello, listen on 80
# nginx: front end
# mongo: mongo db

version: '2'
services:
# cello dashboard service
dashboard:
build:
context: ../src
dockerfile: Dockerfile-dashboard
image: cello-dashboard
container_name: dashboard-test
hostname: cello-dashboard
environment:
- MONGO_URL=mongodb://mongo:27017
- MONGO_DB=dev
- DEBUG=False # in debug mode, service will auto-restart
- LOG_LEVEL=INFO # what level log will be output
- STATIC_FOLDER=$STATIC_FOLDER
- TEMPLATE_FOLDER=$TEMPLATE_FOLDER
expose:
- "8080"
volumes: # This should be removed in product env
- ../src:/src
- ./:/test
command: bash -c "python /test/cases/run.py"

# mongo database, may use others in future
mongo:
image: mongo:3.2
hostname: mongo
container_name: mongo-test
mem_limit: 2048m
environment:
- NO_USED=0
5 changes: 5 additions & 0 deletions test/unit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

# Copyright IBM Corp, All Rights Reserved.
#
# SPDX-License-Identifier: Apache-2.0
#

0 comments on commit ffa7404

Please sign in to comment.