Updated unittest code so that we can create 100% valid projects.

This means also creating a user and groups so that the references are
valid.
This commit is contained in:
2016-09-08 12:03:17 +02:00
parent 4313284dab
commit 68666f0650
3 changed files with 92 additions and 18 deletions

View File

@@ -1,5 +1,7 @@
# -*- encoding: utf-8 -*- # -*- encoding: utf-8 -*-
from __future__ import absolute_import
import base64 import base64
import copy import copy
import json import json
@@ -26,8 +28,8 @@ import pymongo.collection
from flask.testing import FlaskClient from flask.testing import FlaskClient
import responses import responses
from pillar.tests.common_test_data import EXAMPLE_PROJECT, EXAMPLE_FILE
import pillar import pillar
from . import common_test_data as ctd
# from six: # from six:
PY3 = sys.version_info[0] == 3 PY3 = sys.version_info[0] == 3
@@ -44,11 +46,10 @@ TEST_EMAIL_USER = 'koro'
TEST_EMAIL_ADDRESS = '%s@testing.blender.org' % TEST_EMAIL_USER TEST_EMAIL_ADDRESS = '%s@testing.blender.org' % TEST_EMAIL_USER
TEST_FULL_NAME = u'врач Сергей' TEST_FULL_NAME = u'врач Сергей'
TEST_SUBCLIENT_TOKEN = 'my-subclient-token-for-pillar' TEST_SUBCLIENT_TOKEN = 'my-subclient-token-for-pillar'
BLENDER_ID_TEST_USERID = 1896
BLENDER_ID_USER_RESPONSE = {'status': 'success', BLENDER_ID_USER_RESPONSE = {'status': 'success',
'user': {'email': TEST_EMAIL_ADDRESS, 'user': {'email': TEST_EMAIL_ADDRESS,
'full_name': TEST_FULL_NAME, 'full_name': TEST_FULL_NAME,
'id': BLENDER_ID_TEST_USERID}, 'id': ctd.BLENDER_ID_TEST_USERID},
'token_expires': 'Mon, 1 Jan 2018 01:02:03 GMT'} 'token_expires': 'Mon, 1 Jan 2018 01:02:03 GMT'}
@@ -105,7 +106,7 @@ class AbstractPillarTest(TestMinimal):
files_collection = self.app.data.driver.db['files'] files_collection = self.app.data.driver.db['files']
assert isinstance(files_collection, pymongo.collection.Collection) assert isinstance(files_collection, pymongo.collection.Collection)
file = copy.deepcopy(EXAMPLE_FILE) file = copy.deepcopy(ctd.EXAMPLE_FILE)
if file_overrides is not None: if file_overrides is not None:
file.update(file_overrides) file.update(file_overrides)
if '_id' in file and file['_id'] is None: if '_id' in file and file['_id'] is None:
@@ -120,13 +121,24 @@ class AbstractPillarTest(TestMinimal):
return file_id, from_db return file_id, from_db
def ensure_project_exists(self, project_overrides=None): def ensure_project_exists(self, project_overrides=None):
self.ensure_group_exists(ctd.EXAMPLE_ADMIN_GROUP_ID, 'project admin')
self.ensure_group_exists(ctd.EXAMPLE_PROJECT_READONLY_GROUP_ID, 'r/o group')
self.ensure_group_exists(ctd.EXAMPLE_PROJECT_READONLY_GROUP2_ID, 'r/o group 2')
self.ensure_user_exists(ctd.EXAMPLE_PROJECT_OWNER_ID,
'proj-owner',
[ctd.EXAMPLE_ADMIN_GROUP_ID])
with self.app.test_request_context(): with self.app.test_request_context():
projects_collection = self.app.data.driver.db['projects'] projects_collection = self.app.data.driver.db['projects']
assert isinstance(projects_collection, pymongo.collection.Collection) assert isinstance(projects_collection, pymongo.collection.Collection)
project = copy.deepcopy(EXAMPLE_PROJECT) project = copy.deepcopy(ctd.EXAMPLE_PROJECT)
if project_overrides is not None: if project_overrides is not None:
project.update(project_overrides) for key, value in project_overrides.items():
if value is None:
project.pop(key, None)
else:
project[key] = value
found = projects_collection.find_one(project['_id']) found = projects_collection.find_one(project['_id'])
if found is None: if found is None:
@@ -135,6 +147,37 @@ class AbstractPillarTest(TestMinimal):
return found['_id'], found return found['_id'], found
def ensure_user_exists(self, user_id, name, group_ids=()):
user = copy.deepcopy(ctd.EXAMPLE_USER)
user['groups'] = list(group_ids)
user['full_name'] = name
user['_id'] = ObjectId(user_id)
with self.app.test_request_context():
users_coll = self.app.data.driver.db['users']
assert isinstance(users_coll, pymongo.collection.Collection)
found = users_coll.find_one(user_id)
if found:
return
result = users_coll.insert_one(user)
assert result.inserted_id
def ensure_group_exists(self, group_id, name):
group_id = ObjectId(group_id)
with self.app.test_request_context():
groups_coll = self.app.data.driver.db['groups']
assert isinstance(groups_coll, pymongo.collection.Collection)
found = groups_coll.find_one(group_id)
if found:
return
result = groups_coll.insert_one({'_id': group_id, 'name': name})
assert result.inserted_id
def create_user(self, user_id='cafef00dc379cf10c4aaceaf', roles=('subscriber',), def create_user(self, user_id='cafef00dc379cf10c4aaceaf', roles=('subscriber',),
groups=None): groups=None):
from pillar.api.utils.authentication import make_unique_username from pillar.api.utils.authentication import make_unique_username
@@ -152,7 +195,7 @@ class AbstractPillarTest(TestMinimal):
'roles': list(roles), 'roles': list(roles),
'settings': {'email_communications': 1}, 'settings': {'email_communications': 1},
'auth': [{'token': '', 'auth': [{'token': '',
'user_id': unicode(BLENDER_ID_TEST_USERID), 'user_id': unicode(ctd.BLENDER_ID_TEST_USERID),
'provider': 'blender-id'}], 'provider': 'blender-id'}],
'full_name': u'คนรักของผัดไทย', 'full_name': u'คนรักของผัดไทย',
'email': TEST_EMAIL_ADDRESS 'email': TEST_EMAIL_ADDRESS
@@ -335,3 +378,16 @@ class AbstractPillarTest(TestMinimal):
def patch(self, *args, **kwargs): def patch(self, *args, **kwargs):
return self.client_request('PATCH', *args, **kwargs) return self.client_request('PATCH', *args, **kwargs)
def mongo_to_sdk(data):
"""Transforms a MongoDB dict to a dict suitable to give to the PillarSDK.
Not efficient, as it converts to JSON and back again. Only use in unittests.
"""
import pillar.api.utils
import json
as_json = pillar.api.utils.dumps(data)
return json.loads(as_json)

View File

@@ -3,8 +3,11 @@ import datetime
from bson import tz_util, ObjectId from bson import tz_util, ObjectId
EXAMPLE_ADMIN_GROUP_ID = ObjectId('5596e975ea893b269af85c0e') EXAMPLE_ADMIN_GROUP_ID = ObjectId('5596e975ea893b269af85c0e')
EXAMPLE_PROJECT_READONLY_GROUP_ID = ObjectId('5596e975ea893b269af85c0f')
EXAMPLE_PROJECT_READONLY_GROUP2_ID = ObjectId('564733b56dcaf85da2faee8a')
EXAMPLE_PROJECT_ID = ObjectId('5672beecc0261b2005ed1a33') EXAMPLE_PROJECT_ID = ObjectId('5672beecc0261b2005ed1a33')
EXAMPLE_PROJECT_OWNER_ID = ObjectId('552b066b41acdf5dec4436f2')
EXAMPLE_FILE = {u'_id': ObjectId('5672e2c1c379cf0007b31995'), EXAMPLE_FILE = {u'_id': ObjectId('5672e2c1c379cf0007b31995'),
u'_updated': datetime.datetime(2016, 3, 25, 10, 28, 24, tzinfo=tz_util.utc), u'_updated': datetime.datetime(2016, 3, 25, 10, 28, 24, tzinfo=tz_util.utc),
@@ -45,7 +48,7 @@ EXAMPLE_PROJECT = {
u'category': u'assets', u'category': u'assets',
u'description': u'Welcome to this curated collection of Blender Institute textures and image resources. This collection is an on-going project, as with each project we create a number of textures based on our own resources (photographs, scans, etc.) or made completely from scratch. At the moment you can find all the textures from the past Open Projects that were deemed re-usable. \r\n\r\nPeople who have contributed to these textures:\r\n\r\nAndrea Weikert, Andy Goralczyk, Basse Salmela, Ben Dansie, Campbell Barton, Enrico Valenza, Ian Hubert, Kjartan Tysdal, Manu J\xe4rvinen, Massimiliana Pulieso, Matt Ebb, Pablo Vazquez, Rob Tuytel, Roland Hess, Sarah Feldlaufer, S\xf6nke M\xe4ter', u'description': u'Welcome to this curated collection of Blender Institute textures and image resources. This collection is an on-going project, as with each project we create a number of textures based on our own resources (photographs, scans, etc.) or made completely from scratch. At the moment you can find all the textures from the past Open Projects that were deemed re-usable. \r\n\r\nPeople who have contributed to these textures:\r\n\r\nAndrea Weikert, Andy Goralczyk, Basse Salmela, Ben Dansie, Campbell Barton, Enrico Valenza, Ian Hubert, Kjartan Tysdal, Manu J\xe4rvinen, Massimiliana Pulieso, Matt Ebb, Pablo Vazquez, Rob Tuytel, Roland Hess, Sarah Feldlaufer, S\xf6nke M\xe4ter',
u'is_private': False, u'is_private': False,
u'name': u'Textures', u'name': u'Unittest project',
u'node_types': [{u'description': u'Group for texture node type', u'node_types': [{u'description': u'Group for texture node type',
u'dyn_schema': {u'order': {u'type': u'integer'}, u'dyn_schema': {u'order': {u'type': u'integer'},
u'status': {u'allowed': [u'published', u'pending'], u'status': {u'allowed': [u'published', u'pending'],
@@ -114,9 +117,9 @@ EXAMPLE_PROJECT = {
u'parent': [u'group', u'project'], u'parent': [u'group', u'project'],
u'permissions': {u'groups': [{u'group': EXAMPLE_ADMIN_GROUP_ID, u'permissions': {u'groups': [{u'group': EXAMPLE_ADMIN_GROUP_ID,
u'methods': [u'GET', u'PUT', u'POST']}, u'methods': [u'GET', u'PUT', u'POST']},
{u'group': ObjectId('5596e975ea893b269af85c0f'), {u'group': EXAMPLE_PROJECT_READONLY_GROUP_ID,
u'methods': [u'GET']}, u'methods': [u'GET']},
{u'group': ObjectId('564733b56dcaf85da2faee8a'), {u'group': EXAMPLE_PROJECT_READONLY_GROUP2_ID,
u'methods': [u'GET']}], u'methods': [u'GET']}],
u'users': [], u'users': [],
u'world': []}}, u'world': []}},
@@ -232,8 +235,6 @@ EXAMPLE_PROJECT = {
u'nodes_blog': [], u'nodes_blog': [],
u'nodes_featured': [], u'nodes_featured': [],
u'nodes_latest': [], u'nodes_latest': [],
u'organization': ObjectId('55a99fb43004867fb9934f01'),
u'owners': {u'groups': [], u'users': []},
u'permissions': {u'groups': [{u'group': EXAMPLE_ADMIN_GROUP_ID, u'permissions': {u'groups': [{u'group': EXAMPLE_ADMIN_GROUP_ID,
u'methods': [u'GET', u'POST', u'PUT', u'DELETE']}], u'methods': [u'GET', u'POST', u'PUT', u'DELETE']}],
u'users': [], u'users': [],
@@ -243,7 +244,7 @@ EXAMPLE_PROJECT = {
u'status': u'published', u'status': u'published',
u'summary': u'Texture collection from all Blender Institute open projects.', u'summary': u'Texture collection from all Blender Institute open projects.',
u'url': u'textures', u'url': u'textures',
u'user': ObjectId('552b066b41acdf5dec4436f2')} u'user': EXAMPLE_PROJECT_OWNER_ID}
EXAMPLE_NODE = { EXAMPLE_NODE = {
u'_id': ObjectId('572761099837730efe8e120d'), u'_id': ObjectId('572761099837730efe8e120d'),
@@ -262,3 +263,19 @@ EXAMPLE_NODE = {
u'_created': datetime.datetime(2016, 5, 2, 14, 19, 37, 0, tzinfo=tz_util.utc), u'_created': datetime.datetime(2016, 5, 2, 14, 19, 37, 0, tzinfo=tz_util.utc),
u'_etag': u'6b8589b42c880e3626f43f3e82a5c5b946742687' u'_etag': u'6b8589b42c880e3626f43f3e82a5c5b946742687'
} }
BLENDER_ID_TEST_USERID = 1533
EXAMPLE_USER = {'_id': EXAMPLE_PROJECT_OWNER_ID,
'username': 'sybren+unittests@blender.studio',
'groups': [],
'auth': [{
'provider': 'blender-id',
'token': '',
'user_id': str(BLENDER_ID_TEST_USERID),
}],
'full_name': 'sybren+unittest@blender.studio',
'settings': {'email_communications': 1},
'_updated': datetime.datetime(2016, 8, 5, 18, 19, 29),
'_etag': '25a6a90781bf27333218fbbf33b3e8d53e37b1cb',
'_created': datetime.datetime(2016, 8, 5, 18, 19, 29),
'email': 'sybren+unittests@blender.studio'}

View File

@@ -5,8 +5,9 @@ import json
import responses import responses
from bson import ObjectId from bson import ObjectId
from flask import g from flask import g
from pillar.tests import (AbstractPillarTest, TEST_EMAIL_ADDRESS, BLENDER_ID_TEST_USERID, from pillar.tests import (AbstractPillarTest, TEST_EMAIL_ADDRESS,
TEST_SUBCLIENT_TOKEN, TEST_EMAIL_USER, TEST_FULL_NAME) TEST_SUBCLIENT_TOKEN, TEST_EMAIL_USER, TEST_FULL_NAME)
from pillar.tests import common_test_data as ctd
class BlenderIdSubclientTest(AbstractPillarTest): class BlenderIdSubclientTest(AbstractPillarTest):
@@ -22,7 +23,7 @@ class BlenderIdSubclientTest(AbstractPillarTest):
json={'status': 'success', json={'status': 'success',
'user': {'email': TEST_EMAIL_ADDRESS, 'user': {'email': TEST_EMAIL_ADDRESS,
'full_name': None, 'full_name': None,
'id': BLENDER_ID_TEST_USERID}, 'id': ctd.BLENDER_ID_TEST_USERID},
'token_expires': 'Mon, 1 Jan 2218 01:02:03 GMT'}, 'token_expires': 'Mon, 1 Jan 2218 01:02:03 GMT'},
status=200) status=200)
@@ -35,7 +36,7 @@ class BlenderIdSubclientTest(AbstractPillarTest):
# Make sure the user exists in our database. # Make sure the user exists in our database.
from pillar.api.utils.authentication import create_new_user from pillar.api.utils.authentication import create_new_user
with self.app.test_request_context(): with self.app.test_request_context():
create_new_user(TEST_EMAIL_ADDRESS, 'apekoppie', BLENDER_ID_TEST_USERID) create_new_user(TEST_EMAIL_ADDRESS, 'apekoppie', ctd.BLENDER_ID_TEST_USERID)
self._common_user_test(200, expected_full_name='apekoppie') self._common_user_test(200, expected_full_name='apekoppie')
@@ -80,7 +81,7 @@ class BlenderIdSubclientTest(AbstractPillarTest):
subclient_id = self.app.config['BLENDER_ID_SUBCLIENT_ID'] subclient_id = self.app.config['BLENDER_ID_SUBCLIENT_ID']
resp = self.client.post('/api/blender_id/store_scst', resp = self.client.post('/api/blender_id/store_scst',
data={'user_id': BLENDER_ID_TEST_USERID, data={'user_id': ctd.BLENDER_ID_TEST_USERID,
'subclient_id': subclient_id, 'subclient_id': subclient_id,
'token': scst}) 'token': scst})
self.assertEqual(expected_status_code, resp.status_code, resp.data) self.assertEqual(expected_status_code, resp.status_code, resp.data)
@@ -97,7 +98,7 @@ class BlenderIdSubclientTest(AbstractPillarTest):
self.assertEqual(TEST_EMAIL_ADDRESS, db_user['email']) self.assertEqual(TEST_EMAIL_ADDRESS, db_user['email'])
self.assertEqual(expected_full_name, db_user['full_name']) self.assertEqual(expected_full_name, db_user['full_name'])
# self.assertEqual(TEST_SUBCLIENT_TOKEN, db_user['auth'][0]['token']) # self.assertEqual(TEST_SUBCLIENT_TOKEN, db_user['auth'][0]['token'])
self.assertEqual(str(BLENDER_ID_TEST_USERID), db_user['auth'][0]['user_id']) self.assertEqual(str(ctd.BLENDER_ID_TEST_USERID), db_user['auth'][0]['user_id'])
self.assertEqual('blender-id', db_user['auth'][0]['provider']) self.assertEqual('blender-id', db_user['auth'][0]['provider'])
# Check that the token was succesfully stored. # Check that the token was succesfully stored.