def test_should_signup_new_user(self): response = self.rest.post('/api/v1/signup', USER) session = json.loads(response.content) JsonConverter.from_json(TypeCode.Map, response.content) assert session is not None assert session['id'] is not None assert session['user_name'] == USER['name']
def test_json_to_map(self): # Handling simple objects value = '{ "value1":123, "value2":234 }' result = JsonConverter.to_nullable_map(value) assert 123 == result["value1"] assert 234 == result["value2"] # Recursive conversion value = '{ "value1":123, "value2": { "value1": 111, "value2": 222 } }' result = JsonConverter.to_nullable_map(value) assert result != None assert 123 == result["value1"] assert result["value2"] != None assert isinstance(result["value2"], dict) # Handling arrays value = '{ "value1": [{ "value1": 111, "value2": 222 }] }' result = JsonConverter.to_nullable_map(value) assert result != None assert type(result["value1"]) == list resultElements = result["value1"] resultElement0 = resultElements[0] assert resultElement0 != None assert 111 == resultElement0["value1"] assert 222 == resultElement0["value2"]
def test_should_perform_invitation_operations(self): invitation1: InvitationV1 = None invitation2: InvitationV1 = None # Send one invitation response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + INVITATION1.site_id + '/invitations', JsonConverter.to_json(INVITATION1)) invitation = JsonConverter.from_json(TypeCode.Map, response.content) assert invitation['site_id'] == INVITATION1.site_id assert invitation['creator_id'] == INVITATION1.creator_id assert invitation['invitee_email'] == INVITATION1.invitee_email invitation1 = InvitationV1(**invitation) # Send another invitation response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + INVITATION2.site_id + '/invitations', JsonConverter.to_json(INVITATION2), ) invitation = JsonConverter.from_json(TypeCode.Map, response.content) assert invitation['site_id'] == INVITATION2.site_id assert invitation['creator_id'] == INVITATION2.creator_id assert invitation['invitee_email'] == INVITATION2.invitee_email invitation2 = InvitationV1(**invitation) # Get all invitations response = self.rest.get_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + INVITATION1.site_id + '/invitations') page = JsonConverter.from_json(TypeCode.Map, response.content) assert response.status_code == 200 assert page is not None and page != {} # assert len(page['data']) == 2 # Delete invitation response = self.rest.delete_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + invitation1.site_id + '/invitations/' + invitation1.id) assert response.status_code < 300 # Try to get delete invitation response = self.rest.get_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + invitation1.site_id + '/invitations/' + invitation1.id, ) assert response.status_code < 300 assert response.content == b''
def test_from_json(self): assert 123 == JsonConverter.from_json(TypeCode.Integer, '123') assert 'ABC' == JsonConverter.from_json(TypeCode.String, '"ABC"') filter = JsonConverter.from_json(None, '{"Key2": "ABC", "Key1": "123"}') assert isinstance(filter, dict) array = JsonConverter.from_json(TypeCode.Array, "[123,\"ABC\"]") assert len(array) == 2 date = DateTimeConverter.to_datetime("1975-04-08T00:00:00.000Z") json_date = JsonConverter.from_json(TypeCode.DateTime, "\"1975-04-08T00:00Z\"") assert date.timestamp() == json_date.timestamp()
def test_set_properties(self): obj = JsonConverter.to_map( "{ \"value1\": 123, \"value2\": { \"value21\": 111, \"value22\": 222 }, \"value3\": [ 444, " "{ \"value311\": 555 } ] } " ) values = AnyValueMap.from_tuples( "value1", "AAA", "value2", "BBB", "value3.1.value312", "CCC", "value3.3", "DDD", "value4.1", "EEE" ) RecursiveObjectWriter.set_properties(obj, values) values = RecursiveObjectReader.get_properties(obj) assert 8 == len(values) assert "AAA" == values["value1"] assert "BBB", values["value2"] assert 444 == values["value3.0"] assert 555 == values["value3.1.value311"] assert "CCC", values["value3.1.value312"] assert None is values["value3.2"] assert "DDD" == values["value3.3"] assert "EEE" == values["value4.1"]
def signup(self): try: signup_data = bottle.request.json if isinstance( bottle.request.json, dict) else JsonConverter.from_json( TypeCode.Map, bottle.request.json) account: AccountV1 = None invited: bool = False roles: List[str] = [] # Validate password first # Todo: complete implementation after validate password is added # Create account new_account = AccountV1(name=signup_data.get('name'), login=signup_data.get('login') or signup_data.get('email'), language=signup_data.get('language'), theme=signup_data.get('theme'), time_zone=signup_data.get('time_zone')) account = self.__accounts_client.create_account(None, new_account) # Create password for the account password = signup_data.get('password') self.__passwords_client.set_password(None, account.id, password) # Activate all pending invitations email = signup_data.get('email') invitations = self.__invitations_client.activate_invitations( None, email, account.id) if invitations: # Calculate user roles from activated invitations for invitation in invitations: # Was user invited with the same email? invited = invited or email == invitation.invitee_email if invitation.site_id: invitation.role = invitation.role or 'user' role = invitation.site_id + ':' + invitation.role roles.append(role) # Create email settings for the account new_email_settings = EmailSettingsV1(id=account.id, name=account.name, email=email, language=account.language) if self.__email_settings_client is not None: if invited: self.__email_settings_client.set_verified_settings( None, new_email_settings) else: self.__email_settings_client.set_settings( None, new_email_settings) return self.open_session(account, roles) except Exception as err: return self._send_error(err)
def create_site(self): try: data = bottle.request.json if isinstance(bottle.request.json, dict) else JsonConverter.from_json(TypeCode.Map, bottle.request.json) site: SiteV1 = SiteV1(**data) # Create a site site = self.__sites_client.create_site(None, site) # Assign permissions to the owner if self.__roles_client is not None and hasattr(bottle.request, 'user') and bottle.request.user.id is not None: self.__roles_client.grant_roles(None, bottle.request.user.id, [site.id + ':admin']) # Update current user session if hasattr(bottle.request, 'user') and hasattr(bottle.request, 'session_id'): user = bottle.request.user user.roles = user.roles or [] user.roles.append(site.id + ':admin') user.sites = user.sites or [] user.sites.append(site) self.__sessions_client.update_session_user(None, bottle.request.session_id, user) return self._send_result(site) except Exception as err: return self._send_error(err)
def create_beacon_x(self, site_id) -> Optional[str]: json_data = bottle.request.json if isinstance( bottle.request.json, dict) else JsonConverter.from_json( TypeCode.Map, bottle.request.json) beacon = BeaconV1(**json_data) result = self.__beacons_client.create_beacon(None, beacon) return self._send_result(result)
def test_should_notify_invitations(self): response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + INVITATION1.site_id + '/invitations/notify', JsonConverter.to_json(INVITATION3), ) assert response.status_code < 300 assert response.content == b''
def validate_beacon_udi_x(self, site_id) -> Optional[str]: params = dict(bottle.request.query.decode()) udi = params.get('udi') beacon = self.__beacons_client.get_beacon_by_udi(None, udi) if beacon: return JsonConverter.to_json(beacon) else: return ''
def update_beacon(self, site_id, beacon_id) -> Optional[str]: beacon = bottle.request.json if isinstance( bottle.request.json, dict) else JsonConverter.from_json( TypeCode.Map, bottle.request.json) beacon['id'] = beacon_id beacon = BeaconV1(**beacon) result = self.__beacons_client.update_beacon(None, beacon) return self._send_result(result)
def calculate_position_x(self, site_id) -> Optional[str]: params = bottle.request.json if isinstance( bottle.request.json, dict) else JsonConverter.from_json( TypeCode.Map, bottle.request.json) udis = params.get('udis') if isinstance(udis, str): udis = udis.split(',') result = self.__beacons_client.calculate_position(None, site_id, udis) return self._send_result(result)
def test_get_properties(self): obj = JsonConverter.to_map( "{ \"value1\": 123, \"value2\": { \"value21\": 111, \"value22\": 222 }, \"value3\": [ 444, " "{ \"value311\": 555 } ] } ") values = RecursiveObjectReader.get_properties(obj) assert 5 == len(values) assert 123 == values["value1"] assert 111 == values["value2.value21"] assert 222 == values["value2.value22"] assert 444 == values["value3.0"] assert 555 == values["value3.1.value311"]
def test_get_property_names(self): obj = JsonConverter.to_map( "{ \"value1\": 123, \"value2\": { \"value21\": 111, \"value22\": 222 }, \"value3\": [ 444, " "{ \"value311\": 555 } ] } ") names = RecursiveObjectReader.get_property_names(obj) assert 5 == len(names) assert "value1" in names assert "value2.value21" in names assert "value2.value22" in names assert "value3.0" in names assert "value3.1.value311" in names
def test_should_resend_invitations(self): invitation1: InvitationV1 = None # Send invitation response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + INVITATION1.site_id + '/invitations', JsonConverter.to_json(INVITATION1)) invitation = JsonConverter.from_json(TypeCode.Map, response.content) assert invitation['site_id'] == INVITATION1.site_id assert invitation['invitee_email'] == INVITATION1.invitee_email invitation1 = InvitationV1(**invitation) # Send another invitation response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + invitation1.site_id + '/invitations/' + invitation1.id + '/resend', {}) assert response.status_code < 300
def restore_session(self): try: session_id = dict(bottle.request.query.decode()).get('session_id') session = self.__sessions_client.get_session_by_id( None, session_id) # If session closed then return null if session and not session.active: session = None if session: return JsonConverter.to_json(session) else: return bottle.HTTPResponse(status=204) except Exception as err: return self._send_error(err)
def test_has_property(self): obj = JsonConverter.to_map( "{ \"value1\": 123, \"value2\": { \"value21\": 111, \"value22\": 222 }, \"value3\": [ 444, " "{ \"value311\": 555 } ] } ") has = RecursiveObjectReader.has_property(obj, "") assert False == has has = RecursiveObjectReader.has_property(obj, "value1") assert True == has has = RecursiveObjectReader.has_property(obj, "value2") assert True == has has = RecursiveObjectReader.has_property(obj, "value2.value21") assert True == has has = RecursiveObjectReader.has_property(obj, "value2.value31") assert False == has has = RecursiveObjectReader.has_property(obj, "value2.value21.value211") assert False == has has = RecursiveObjectReader.has_property(obj, "valueA.valueB.valueC") assert False == has has = RecursiveObjectReader.has_property(obj, "value3") assert True == has has = RecursiveObjectReader.has_property(obj, "value3.0") assert True == has has = RecursiveObjectReader.has_property(obj, "value3.0.value311") assert False == has has = RecursiveObjectReader.has_property(obj, "value3.1") assert True == has has = RecursiveObjectReader.has_property(obj, "value3.1.value311") assert True == has has = RecursiveObjectReader.has_property(obj, "value3.2") assert False == has
def test_get_property(self): obj = JsonConverter.to_map( "{ \"value1\": 123, \"value2\": { \"value21\": 111, \"value22\": 222 }, \"value3\": [ 444, " "{ \"value311\": 555 } ] } ") value = RecursiveObjectReader.get_property(obj, "") assert None == value value = RecursiveObjectReader.get_property(obj, "value1") assert 123 == value value = RecursiveObjectReader.get_property(obj, "value2") assert None != value value = RecursiveObjectReader.get_property(obj, "value2.value21") assert 111 == value value = RecursiveObjectReader.get_property(obj, "value2.value31") assert None == value value = RecursiveObjectReader.get_property(obj, "value2.value21.value211") assert None == value value = RecursiveObjectReader.get_property(obj, "valueA.valueB.valueC") assert None == value value = RecursiveObjectReader.get_property(obj, "value3") assert None != value value = RecursiveObjectReader.get_property(obj, "value3.0") assert 444 == value value = RecursiveObjectReader.get_property(obj, "value3.0.value311") assert None == value value = RecursiveObjectReader.get_property(obj, "value3.1") assert None != value value = RecursiveObjectReader.get_property(obj, "value3.1.value311") assert 555 == value value = RecursiveObjectReader.get_property(obj, "value3.2") assert None == value
def signin(self): json_data = bottle.request.json if isinstance( bottle.request.json, dict) else JsonConverter.from_json( TypeCode.Map, bottle.request.json) login = json_data.get('login') password = json_data.get('password') account: AccountV1 = None roles: List[str] = [] # Find user account try: account = self.__accounts_client.get_account_by_id_or_login( None, login) if account is None: raise BadRequestException( None, 'WRONG_LOGIN', 'Account ' + login + ' was not found').with_details( 'login', login) # Authenticate user result = self.__passwords_client.authenticate( None, account.id, password) # wrong password error is UNKNOWN when use http client if result is False: raise BadRequestException( None, 'WRONG_PASSWORD', 'Wrong password for account ' + login).with_details( 'login', login) # Retrieve user roles if self.__roles_client: roles = self.__roles_client.get_roles_by_id( None, account.id, ) else: roles = [] return self.open_session(account, roles) except Exception as err: return self._send_error(err)
def inner(): user = bottle.request.user if user is None: raise UnauthorizedException( None, 'NOT_SIGNED', 'User must be signed in to perform this operation' ).with_status(401) else: user_id = dict(bottle.request.query.decode()).get(user_id_param) or JsonConverter.to_json( bottle.request.json) if user_id is not None and user_id == user.user_id: return else: site_id = bottle.request.params.get(site_id_param) authorized = 'admin' in user.roles or site_id + ':admin' in user.roles if not authorized: raise UnauthorizedException( None, 'NOT_IN_SITE_ROLE', 'User must be site:admin to perform this operation' ).with_details('roles', ['admin']).with_status(403)
def test_to_json(self): assert JsonConverter.to_json(None) is None assert '123' == JsonConverter.to_json(123) assert "\"ABC\"" == JsonConverter.to_json('ABC') filter = {"Key1": 123, "Key2": "ABC"} json_filter = JsonConverter.to_json(filter) assert '{"Key1": 123, "Key2": "ABC"}' == json_filter array = [123, "ABC"] json_array = JsonConverter.to_json(array) assert '[123, "ABC"]' == json_array date = DateTimeConverter.to_datetime("1975-04-08T00:00:00.000Z") json_date = JsonConverter.to_json(date) assert "\"1975-04-08T00:00:00.000Z\"", json_date
def update_site(self, site_id): try: data = bottle.request.json if isinstance(bottle.request.json, dict) else JsonConverter.from_json(TypeCode.Map, bottle.request.json) data['id'] = site_id site: SiteV1 = SiteV1(**data) # Update site site = self.__sites_client.update_site(None, site) # Update current user session if hasattr(bottle.request, 'user') is not None and hasattr(bottle.request, 'session_id') is not None: user = bottle.request.user user.sites = user.sites or [] user.sites = list(filter(lambda x: x.id == site.id, user.sites)) user.sites.append(site) self.__sessions_client.update_session_user(None, bottle.request.session_id, user) return self._send_result(site) except Exception as err: self._send_error(err)
def open_session( self, account: AccountV1, roles: List[str], ): try: session: SessionV1 = None sites: List[SiteV1] = None passwordInfo: UserPasswordInfoV1 = None settings: ConfigParams = None # Retrieve sites for user site_roles = [] if not roles else list( filter(lambda x: x.find(':') > 0, roles)) site_ids = [] if not site_roles else list( map(lambda x: x[0:x.find(':')] if x.find(':') >= 0 else x, site_roles)) if len(site_ids) > 0: filter_params = FilterParams.from_tuples('ids', site_ids) page = self.__sites_client.get_sites(None, filter_params, None) sites = [] if page is None else page.data else: sites = [] password_info = self.__passwords_client.get_password_info( None, account.id) settings = self.__settings_client.get_section_by_id( None, account.id) # Open a new user session user = SessionUserV1( id=account.id, name=account.name, login=account.login, create_time=account.create_time, time_zone=account.time_zone, language=account.language, theme=account.theme, roles=roles, sites=list(map(lambda x: { 'id': x.id, 'name': x.name }, sites)), settings=settings, change_pwd_time=None if password_info is None else password_info.change_time, custom_hdr=account.custom_hdr, custom_dat=account.custom_dat) address = HttpRequestDetector.detect_address(bottle.request) client = HttpRequestDetector.detect_browser(bottle.request) platform = HttpRequestDetector.detect_platform(bottle.request) session = self.__sessions_client.open_session( None, account.id, account.name, address, client, user, None) return JsonConverter.to_json(session) except Exception as err: return self._send_error(err)
def test_should_perform_site_operations(self): site1: SiteV1 = SiteV1() site2: SiteV1 = SiteV1() # Create one site response = self.rest.post_as_user(TestUsers.AdminUserSessionId, '/api/v1/sites', JsonConverter.to_json(SITE1)) site = JsonConverter.from_json(TypeCode.Map, response.content) assert site['name'] == SITE1.name assert site['description'] == SITE1.description site1 = SiteV1(**site) # Create another site response = self.rest.post_as_user(TestUsers.AdminUserSessionId, '/api/v1/sites', JsonConverter.to_json(SITE2)) site = JsonConverter.from_json(TypeCode.Map, response.content) assert site['name'] == SITE2.name assert site['description'] == SITE2.description site2 = SiteV1(**site) # Get all sites response = self.rest.get_as_user(TestUsers.AdminUserSessionId, '/api/v1/sites') page = JsonConverter.from_json(TypeCode.Map, response.content) # Account for 1 test site assert len(page['data']) # Find site by code response = self.rest.get('/api/v1/sites/find_by_code?code=' + site1.code) site = JsonConverter.from_json(TypeCode.Map, response.content) assert site['id'] == site1.id # Validate site code response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/validate_code?code=' + site1.code, {}, ) assert response.content.decode('utf-8').replace('"', '') == site1.id # Generate code response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + site1.id + '/generate_code', {}, ) assert len(response.content.decode('utf-8')) > 0 # Update the site site1.description = 'Updated Content 1' site1.center = {'type': 'Point', 'coordinates': [32, -110]} site1.radius = 5 response = self.rest.put_as_user(TestUsers.AdminUserSessionId, '/api/v1/sites/' + site1.id, JsonConverter.to_json(site1)) site = JsonConverter.from_json(TypeCode.Map, response.content) assert site['description'] == 'Updated Content 1' assert site['name'] == site1.name assert site['radius'] == 5 assert site['center'] == {'type': 'Point', 'coordinates': [32, -110]} # Delete site response = self.rest.delete_as_user( TestUsers.AdminUserSessionId, '/api/v1/sites/' + site1.id, ) site = JsonConverter.from_json(TypeCode.Map, response.content) assert site['deleted'] is True # Try to get delete site response = self.rest.get_as_user(TestUsers.AdminUserSessionId, '/api/v1/sites/' + site1.id) site = JsonConverter.from_json(TypeCode.Map, response.content) assert site['deleted'] is True
def notify_invitation(self, site_id): json_data = bottle.request.json if isinstance(bottle.request.json, dict) else JsonConverter.from_json( TypeCode.Map, bottle.request.json) invitation = InvitationV1(**json_data) user = {} if not hasattr(bottle.request, 'user') else bottle.request.user invitation.create_time = datetime.datetime.now() invitation.creator_id = getattr(user, 'id', None) invitation.creator_name = getattr(user, 'name', None) result = self.__invitations_client.notify_invitation(None, invitation) return self._send_empty_result(result)
def test_beacons_operations(self): # Create one beacon response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + BEACON1.site_id + '/xbeacons', JsonConverter.to_json(BEACON1)) created_beacon = JsonConverter.from_json(TypeCode.Map, response.content) beacon1 = created_beacon assert response.status_code < 300 assert BEACON1.udi == created_beacon['udi'] assert BEACON1.id == created_beacon['id'] assert BEACON1.site_id == created_beacon['site_id'] assert created_beacon['center'] is not None # Create the second beacon response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + BEACON2.site_id + '/xbeacons', JsonConverter.to_json(BEACON2)) assert response.status_code < 300 created_beacon = JsonConverter.from_json(TypeCode.Map, response.content) assert BEACON2.udi == created_beacon['udi'] assert BEACON2.id == created_beacon['id'] assert BEACON2.site_id == created_beacon['site_id'] assert created_beacon['center'] is not None # Create yet another beacon response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + BEACON3.site_id + '/xbeacons', JsonConverter.to_json(BEACON3)) assert response.status_code < 300 created_beacon = JsonConverter.from_json(TypeCode.Map, response.content) assert BEACON3.udi == created_beacon['udi'] assert BEACON3.id == created_beacon['id'] assert BEACON3.site_id == created_beacon['site_id'] assert created_beacon['center'] is not None # Get all beacons response = self.rest.get_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + BEACON1.site_id + '/xbeacons', ) beacons = JsonConverter.from_json(TypeCode.Map, response.content) assert len(beacons['data']) == 2 # Calculate position for one beacon response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + BEACON1.site_id + '/xbeacons/calculate_position', { 'site_id': BEACON1.site_id, 'udis': [BEACON1.udi] }) calc_position = JsonConverter.from_json(TypeCode.Map, response.content) assert response.status_code < 300 assert calc_position['type'] == 'Point' assert len(calc_position['coordinates']) == 2 # Validate beacon udi response = self.rest.post_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + beacon1['site_id'] + '/xbeacons/validate_udi?udi=' + beacon1['udi'], {}, ) assert JsonConverter.from_json(TypeCode.Map, response.content)['id'] == beacon1['id'] # Update the beacon BEACON1.label = 'ABC' response = self.rest.put_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + beacon1['site_id'] + '/xbeacons/' + beacon1['id'], JsonConverter.to_json(BEACON1)) updated_beacon = JsonConverter.from_json(TypeCode.Map, response.content) beacon1 = updated_beacon assert response.status_code < 300 assert BEACON1.id == updated_beacon['id'] assert updated_beacon['label'] == 'ABC' # Delete the beacon response = self.rest.delete_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + beacon1['site_id'] + '/xbeacons/' + beacon1['id']) deleted_result = JsonConverter.from_json(TypeCode.Map, response.content) assert deleted_result['id'] == BEACON1.id # Try to get deleted beacon response = self.rest.get_as_user( TestUsers.AdminUserSessionId, '/api/v2/sites/' + beacon1['site_id'] + '/xbeacons/' + beacon1['id'], ) assert response.status_code == 204