574 lines
20 KiB
Python
574 lines
20 KiB
Python
import unittest
|
|
import json
|
|
|
|
from flask import url_for
|
|
from endpoints.api import api
|
|
from app import app
|
|
from initdb import setup_database_for_testing, finished_database_for_testing
|
|
from specs import build_specs
|
|
from data import model
|
|
|
|
app.register_blueprint(api, url_prefix='/api')
|
|
|
|
NO_ACCESS_USER = 'freshuser'
|
|
READ_ACCESS_USER = 'reader'
|
|
ADMIN_ACCESS_USER = 'devtable'
|
|
ORGANIZATION = 'buynlarge'
|
|
|
|
NEW_USER_DETAILS = {
|
|
'username': 'bobby',
|
|
'password': 'password',
|
|
'email': 'bobby@tables.com',
|
|
}
|
|
|
|
class ApiTestCase(unittest.TestCase):
|
|
def setUp(self):
|
|
setup_database_for_testing(self)
|
|
self.app = app.test_client()
|
|
self.ctx = app.test_request_context()
|
|
self.ctx.__enter__()
|
|
|
|
def tearDown(self):
|
|
finished_database_for_testing(self)
|
|
self.ctx.__exit__(True, None, None)
|
|
|
|
def getJsonResponse(self, method_name, params={}):
|
|
rv = self.app.get(url_for(method_name, **params))
|
|
self.assertEquals(200, rv.status_code)
|
|
data = rv.data
|
|
parsed = json.loads(data)
|
|
return parsed
|
|
|
|
def postResponse(self, method_name, params={}, data={}, expected_code=200):
|
|
rv = self.app.post(url_for(method_name, **params), data=json.dumps(data),
|
|
headers={"Content-Type": "application/json"})
|
|
self.assertEquals(rv.status_code, expected_code)
|
|
return rv.data
|
|
|
|
def getResponse(self, method_name, params={}, expected_code=200):
|
|
rv = self.app.get(url_for(method_name, **params))
|
|
self.assertEquals(rv.status_code, expected_code)
|
|
return rv.data
|
|
|
|
def deleteResponse(self, method_name, params={}, expected_code=204):
|
|
rv = self.app.delete(url_for(method_name, **params))
|
|
self.assertEquals(rv.status_code, expected_code)
|
|
return rv.data
|
|
|
|
def postJsonResponse(self, method_name, params={}, data={}, expected_code=200):
|
|
rv = self.app.post(url_for(method_name, **params), data=json.dumps(data),
|
|
headers={"Content-Type": "application/json"})
|
|
|
|
if rv.status_code != expected_code:
|
|
print 'Mismatch data for method %s: %s' % (method_name, rv.data)
|
|
|
|
self.assertEquals(rv.status_code, expected_code)
|
|
data = rv.data
|
|
parsed = json.loads(data)
|
|
return parsed
|
|
|
|
def putJsonResponse(self, method_name, params={}, data={}, expected_code=200):
|
|
rv = self.app.put(url_for(method_name, **params), data=json.dumps(data),
|
|
headers={"Content-Type": "application/json"})
|
|
|
|
if rv.status_code != expected_code:
|
|
print 'Mismatch data for method %s: %s' % (method_name, rv.data)
|
|
|
|
self.assertEquals(rv.status_code, expected_code)
|
|
data = rv.data
|
|
parsed = json.loads(data)
|
|
return parsed
|
|
|
|
def login(self, username, password='password'):
|
|
return self.postJsonResponse('api.signin_user', data=dict(username=username, password=password))
|
|
|
|
class TestDiscovery(ApiTestCase):
|
|
def test_discovery(self):
|
|
""" Basic sanity check that discovery returns valid JSON in the expected format. """
|
|
json = self.getJsonResponse('api.discovery')
|
|
found = set([])
|
|
for method_info in json['endpoints']:
|
|
found.add(method_info['name'])
|
|
|
|
assert 'discovery' in found
|
|
|
|
class TestPlans(ApiTestCase):
|
|
def test_plans(self):
|
|
""" Basic sanity check that the plans are returned in the expected format. """
|
|
json = self.getJsonResponse('api.list_plans')
|
|
found = set([])
|
|
for method_info in json['plans']:
|
|
found.add(method_info['stripeId'])
|
|
|
|
assert 'free' in found
|
|
|
|
class TestLoggedInUser(ApiTestCase):
|
|
def test_guest(self):
|
|
json = self.getJsonResponse('api.get_logged_in_user')
|
|
assert json['anonymous'] == True
|
|
|
|
def test_user(self):
|
|
self.login(READ_ACCESS_USER)
|
|
json = self.getJsonResponse('api.get_logged_in_user')
|
|
assert json['anonymous'] == False
|
|
assert json['username'] == READ_ACCESS_USER
|
|
|
|
class TestGetUserPrivateCount(ApiTestCase):
|
|
def test_nonallowed(self):
|
|
self.login(READ_ACCESS_USER)
|
|
json = self.getJsonResponse('api.get_user_private_count')
|
|
assert json['privateCount'] == 0
|
|
assert json['reposAllowed'] == 0
|
|
|
|
def test_allowed(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
json = self.getJsonResponse('api.get_user_private_count')
|
|
assert json['privateCount'] == 6
|
|
assert json['reposAllowed'] == 125
|
|
|
|
class TestConvertToOrganization(ApiTestCase):
|
|
def test_sameadminuser(self):
|
|
self.login(READ_ACCESS_USER)
|
|
json = self.postJsonResponse('api.convert_user_to_organization',
|
|
data={'adminUser': READ_ACCESS_USER, 'adminPassword': 'password'},
|
|
expected_code=400)
|
|
|
|
self.assertEqual('The admin user is not valid', json['message'])
|
|
|
|
def test_invalidadminuser(self):
|
|
self.login(READ_ACCESS_USER)
|
|
json = self.postJsonResponse('api.convert_user_to_organization',
|
|
data={'adminUser': 'unknownuser', 'adminPassword': 'password'},
|
|
expected_code=400)
|
|
|
|
self.assertEqual('The admin user credentials are not valid', json['message'])
|
|
|
|
def test_invalidadminpassword(self):
|
|
self.login(READ_ACCESS_USER)
|
|
json = self.postJsonResponse('api.convert_user_to_organization',
|
|
data={'adminUser': ADMIN_ACCESS_USER, 'adminPassword': 'invalidpass'},
|
|
expected_code=400)
|
|
|
|
self.assertEqual('The admin user credentials are not valid', json['message'])
|
|
|
|
def test_convert(self):
|
|
self.login(READ_ACCESS_USER)
|
|
json = self.postJsonResponse('api.convert_user_to_organization',
|
|
data={'adminUser': ADMIN_ACCESS_USER,
|
|
'adminPassword': 'password',
|
|
'plan': 'free'})
|
|
|
|
self.assertEqual(True, json['success'])
|
|
|
|
# Verify the organization exists.
|
|
organization = model.get_organization(READ_ACCESS_USER)
|
|
assert organization is not None
|
|
|
|
# Verify the admin user is the org's admin.
|
|
self.login(ADMIN_ACCESS_USER)
|
|
json = self.getJsonResponse('api.get_organization', params=dict(orgname=READ_ACCESS_USER))
|
|
|
|
self.assertEquals(READ_ACCESS_USER, json['name'])
|
|
self.assertEquals(True, json['is_admin'])
|
|
|
|
|
|
class TestChangeUserDetails(ApiTestCase):
|
|
def test_changepassword(self):
|
|
self.login(READ_ACCESS_USER)
|
|
self.putJsonResponse('api.change_user_details', data=dict(password='newpasswordiscool'))
|
|
self.login(READ_ACCESS_USER, password='newpasswordiscool')
|
|
|
|
def test_changeinvoiceemail(self):
|
|
self.login(READ_ACCESS_USER)
|
|
|
|
json = self.putJsonResponse('api.change_user_details', data=dict(invoice_email=True))
|
|
self.assertEquals(True, json['invoice_email'])
|
|
|
|
json = self.putJsonResponse('api.change_user_details', data=dict(invoice_email=False))
|
|
self.assertEquals(False, json['invoice_email'])
|
|
|
|
|
|
class TestCreateNewUser(ApiTestCase):
|
|
def test_existingusername(self):
|
|
json = self.postJsonResponse('api.create_new_user',
|
|
data=dict(username=READ_ACCESS_USER,
|
|
password='password',
|
|
email='test@example.com'),
|
|
expected_code=400)
|
|
|
|
self.assertEquals('The username already exists', json['message'])
|
|
|
|
def test_createuser(self):
|
|
data = self.postResponse('api.create_new_user',
|
|
data=NEW_USER_DETAILS,
|
|
expected_code=201)
|
|
self.assertEquals('Created', data)
|
|
|
|
|
|
class TestSignout(ApiTestCase):
|
|
def test_signout(self):
|
|
self.login(READ_ACCESS_USER)
|
|
|
|
json = self.getJsonResponse('api.get_logged_in_user')
|
|
assert json['username'] == READ_ACCESS_USER
|
|
|
|
self.postResponse('api.logout')
|
|
|
|
json = self.getJsonResponse('api.get_logged_in_user')
|
|
assert json['anonymous'] == True
|
|
|
|
|
|
class TestGetMatchingEntities(ApiTestCase):
|
|
def test_notinorg(self):
|
|
self.login(NO_ACCESS_USER)
|
|
|
|
json = self.getJsonResponse('api.get_matching_entities',
|
|
params=dict(prefix='o', namespace=ORGANIZATION, includeTeams=True))
|
|
|
|
names = set([r['name'] for r in json['results']])
|
|
assert 'outsideorg' in names
|
|
assert not 'owners' in names
|
|
|
|
def test_inorg(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.getJsonResponse('api.get_matching_entities',
|
|
params=dict(prefix='o', namespace=ORGANIZATION, includeTeams=True))
|
|
|
|
names = set([r['name'] for r in json['results']])
|
|
assert 'outsideorg' in names
|
|
assert 'owners' in names
|
|
|
|
|
|
class TestCreateOrganization(ApiTestCase):
|
|
def test_existinguser(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.postJsonResponse('api.create_organization', data=dict(name=ADMIN_ACCESS_USER),
|
|
expected_code=400)
|
|
|
|
self.assertEquals('A user or organization with this name already exists', json['message'])
|
|
|
|
def test_existingorg(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.postJsonResponse('api.create_organization', data=dict(name=ORGANIZATION),
|
|
expected_code=400)
|
|
|
|
self.assertEquals('A user or organization with this name already exists', json['message'])
|
|
|
|
def test_createorg(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
data = self.postResponse('api.create_organization',
|
|
data=dict(name='neworg', email='test@example.com'),
|
|
expected_code=201)
|
|
|
|
self.assertEquals('Created', data)
|
|
|
|
# Ensure the org was created.
|
|
organization = model.get_organization('neworg')
|
|
assert organization is not None
|
|
|
|
# Verify the admin user is the org's admin.
|
|
json = self.getJsonResponse('api.get_organization', params=dict(orgname='neworg'))
|
|
self.assertEquals('neworg', json['name'])
|
|
self.assertEquals(True, json['is_admin'])
|
|
|
|
|
|
class TestGetOrganization(ApiTestCase):
|
|
def test_unknownorg(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
self.getResponse('api.get_organization', params=dict(orgname='notvalid'),
|
|
expected_code=403)
|
|
|
|
def test_cannotaccess(self):
|
|
self.login(NO_ACCESS_USER)
|
|
self.getResponse('api.get_organization', params=dict(orgname=ORGANIZATION),
|
|
expected_code=403)
|
|
|
|
def test_getorganization(self):
|
|
self.login(READ_ACCESS_USER)
|
|
json = self.getJsonResponse('api.get_organization', params=dict(orgname=ORGANIZATION))
|
|
|
|
self.assertEquals(ORGANIZATION, json['name'])
|
|
self.assertEquals(False, json['is_admin'])
|
|
|
|
def test_getorganization_asadmin(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
json = self.getJsonResponse('api.get_organization', params=dict(orgname=ORGANIZATION))
|
|
|
|
self.assertEquals(ORGANIZATION, json['name'])
|
|
self.assertEquals(True, json['is_admin'])
|
|
|
|
|
|
class TestChangeOrganizationDetails(ApiTestCase):
|
|
def test_changeinvoiceemail(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.putJsonResponse('api.change_organization_details',
|
|
params=dict(orgname=ORGANIZATION),
|
|
data=dict(invoice_email=True))
|
|
|
|
self.assertEquals(True, json['invoice_email'])
|
|
|
|
json = self.putJsonResponse('api.change_organization_details',
|
|
params=dict(orgname=ORGANIZATION),
|
|
data=dict(invoice_email=False))
|
|
self.assertEquals(False, json['invoice_email'])
|
|
|
|
|
|
def test_changemail(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.putJsonResponse('api.change_organization_details',
|
|
params=dict(orgname=ORGANIZATION),
|
|
data=dict(email='newemail@example.com'))
|
|
|
|
self.assertEquals('newemail@example.com', json['email'])
|
|
|
|
|
|
class TestGetOrganizationPrototypes(ApiTestCase):
|
|
def test_getprototypes(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
json = self.getJsonResponse('api.get_organization_prototype_permissions',
|
|
params=dict(orgname=ORGANIZATION))
|
|
|
|
assert len(json['prototypes']) > 0
|
|
|
|
|
|
class TestCreateOrganizationPrototypes(ApiTestCase):
|
|
def test_invaliduser(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.postJsonResponse('api.create_organization_prototype_permission',
|
|
params=dict(orgname=ORGANIZATION),
|
|
data=dict(activating_user={'name': 'unknownuser'},
|
|
role='read',
|
|
delegate={'kind': 'team', 'name': 'owners'}),
|
|
expected_code=400)
|
|
|
|
self.assertEquals('Unknown activating user', json['message'])
|
|
|
|
|
|
def test_missingdelegate(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.postJsonResponse('api.create_organization_prototype_permission',
|
|
params=dict(orgname=ORGANIZATION),
|
|
data=dict(role='read'),
|
|
expected_code=400)
|
|
|
|
self.assertEquals('Missing delegate user or team', json['message'])
|
|
|
|
def test_createprototype(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.postJsonResponse('api.create_organization_prototype_permission',
|
|
params=dict(orgname=ORGANIZATION),
|
|
data=dict(role='read', delegate={'kind': 'team', 'name': 'readers'}))
|
|
|
|
self.assertEquals('read', json['role'])
|
|
pid = json['id']
|
|
|
|
# Verify the prototype exists.
|
|
json = self.getJsonResponse('api.get_organization_prototype_permissions',
|
|
params=dict(orgname=ORGANIZATION))
|
|
|
|
ids = set([p['id'] for p in json['prototypes']])
|
|
assert pid in ids
|
|
|
|
|
|
class TestDeleteOrganizationPrototypes(ApiTestCase):
|
|
def test_deleteprototype(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
# Get the existing prototypes
|
|
json = self.getJsonResponse('api.get_organization_prototype_permissions',
|
|
params=dict(orgname=ORGANIZATION))
|
|
|
|
ids = [p['id'] for p in json['prototypes']]
|
|
pid = ids[0]
|
|
|
|
# Delete a prototype.
|
|
self.deleteResponse('api.delete_organization_prototype_permission',
|
|
params=dict(orgname=ORGANIZATION, prototypeid=pid))
|
|
|
|
# Verify the prototype no longer exists.
|
|
json = self.getJsonResponse('api.get_organization_prototype_permissions',
|
|
params=dict(orgname=ORGANIZATION))
|
|
|
|
newids = [p['id'] for p in json['prototypes']]
|
|
assert not pid in newids
|
|
|
|
|
|
class TestUpdateOrganizationPrototypes(ApiTestCase):
|
|
def test_updateprototype(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
# Get the existing prototypes
|
|
json = self.getJsonResponse('api.get_organization_prototype_permissions',
|
|
params=dict(orgname=ORGANIZATION))
|
|
|
|
ids = [p['id'] for p in json['prototypes']]
|
|
pid = ids[0]
|
|
|
|
# Update a prototype.
|
|
json = self.putJsonResponse('api.delete_organization_prototype_permission',
|
|
params=dict(orgname=ORGANIZATION, prototypeid=pid),
|
|
data=dict(role='admin'))
|
|
|
|
self.assertEquals('admin', json['role'])
|
|
|
|
|
|
|
|
class TestGetOrganiaztionMembers(ApiTestCase):
|
|
def test_getmembers(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.getJsonResponse('api.get_organization_members',
|
|
params=dict(orgname=ORGANIZATION))
|
|
|
|
assert ADMIN_ACCESS_USER in json['members']
|
|
assert READ_ACCESS_USER in json['members']
|
|
assert not NO_ACCESS_USER in json['members']
|
|
|
|
def test_getspecificmember(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.getJsonResponse('api.get_organization_member',
|
|
params=dict(orgname=ORGANIZATION, membername=ADMIN_ACCESS_USER))
|
|
|
|
self.assertEquals(ADMIN_ACCESS_USER, json['member']['name'])
|
|
self.assertEquals('user', json['member']['kind'])
|
|
|
|
assert 'owners' in json['member']['teams']
|
|
|
|
|
|
class TestGetOrganizationPrivateAllowed(ApiTestCase):
|
|
def test_existingorg(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.getJsonResponse('api.get_organization_private_allowed',
|
|
params=dict(orgname=ORGANIZATION))
|
|
|
|
self.assertEquals(True, json['privateAllowed'])
|
|
assert not 'reposAllowed' in json
|
|
|
|
|
|
def test_neworg(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
data = self.postResponse('api.create_organization',
|
|
data=dict(name='neworg', email='test@example.com'),
|
|
expected_code=201)
|
|
|
|
json = self.getJsonResponse('api.get_organization_private_allowed',
|
|
params=dict(orgname='neworg'))
|
|
|
|
self.assertEquals(False, json['privateAllowed'])
|
|
|
|
|
|
class TestUpdateOrganizationTeam(ApiTestCase):
|
|
def test_updateexisting(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
data = self.postJsonResponse('api.update_organization_team',
|
|
params=dict(orgname=ORGANIZATION, teamname='readers'),
|
|
data=dict(description = 'My cool team', role = 'creator'))
|
|
|
|
self.assertEquals('My cool team', data['description'])
|
|
self.assertEquals('creator', data['role'])
|
|
|
|
def test_attemptchangeroleonowners(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
self.postResponse('api.update_organization_team',
|
|
params=dict(orgname=ORGANIZATION, teamname='owners'),
|
|
data=dict(role = 'creator'),
|
|
expected_code=400)
|
|
|
|
def test_createnewteam(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
data = self.putJsonResponse('api.update_organization_team',
|
|
params=dict(orgname=ORGANIZATION, teamname='newteam'),
|
|
data=dict(description = 'My cool team', role = 'member'),
|
|
expected_code=201)
|
|
|
|
self.assertEquals('My cool team', data['description'])
|
|
self.assertEquals('member', data['role'])
|
|
|
|
# Verify the team was created.
|
|
json = self.getJsonResponse('api.get_organization', params=dict(orgname=ORGANIZATION))
|
|
assert 'newteam' in json['teams']
|
|
|
|
|
|
class TestDeleteOrganizationTeam(ApiTestCase):
|
|
def test_deleteteam(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
self.deleteResponse('api.delete_organization_team',
|
|
params=dict(orgname=ORGANIZATION, teamname='readers'))
|
|
|
|
# Make sure the team was deleted
|
|
json = self.getJsonResponse('api.get_organization', params=dict(orgname=ORGANIZATION))
|
|
assert not 'readers' in json['teams']
|
|
|
|
def test_attemptdeleteowners(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
self.deleteResponse('api.delete_organization_team',
|
|
params=dict(orgname=ORGANIZATION, teamname='owners'),
|
|
expected_code=400)
|
|
|
|
|
|
class TestGetOrganizationTeamMembers(ApiTestCase):
|
|
def test_invalidteam(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
self.getResponse('api.get_organization_team_members',
|
|
params=dict(orgname=ORGANIZATION, teamname='notvalid'),
|
|
expected_code=404)
|
|
|
|
def test_getmembers(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
json = self.getJsonResponse('api.get_organization_team_members',
|
|
params=dict(orgname=ORGANIZATION, teamname='readers'))
|
|
|
|
assert READ_ACCESS_USER in json['members']
|
|
|
|
|
|
class TestUpdateOrganizationTeamMember(ApiTestCase):
|
|
def test_addmember(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
self.postJsonResponse('api.update_organization_team_member',
|
|
params=dict(orgname=ORGANIZATION, teamname='readers', membername=NO_ACCESS_USER))
|
|
|
|
|
|
# Verify the user was added to the team.
|
|
json = self.getJsonResponse('api.get_organization_team_members',
|
|
params=dict(orgname=ORGANIZATION, teamname='readers'))
|
|
|
|
assert NO_ACCESS_USER in json['members']
|
|
|
|
|
|
class TestDeleteOrganizationTeamMember(ApiTestCase):
|
|
def test_deletemember(self):
|
|
self.login(ADMIN_ACCESS_USER)
|
|
|
|
self.deleteResponse('api.delete_organization_team_member',
|
|
params=dict(orgname=ORGANIZATION, teamname='readers', membername=READ_ACCESS_USER))
|
|
|
|
|
|
# Verify the user was removed from the team.
|
|
json = self.getJsonResponse('api.get_organization_team_members',
|
|
params=dict(orgname=ORGANIZATION, teamname='readers'))
|
|
|
|
assert not READ_ACCESS_USER in json['members']
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|