def test_one(self):
        input_dict = {'first_outer_key' : 'whatever',
                'second_outer_key' : {
                    'first_inner_key' : 'whatever'
                }}

        new_dict = utils.convert_dict(input_dict, utils.underscore_to_camel)
        self.assertIn('firstOuterKey', new_dict)
        self.assertIn('secondOuterKey', new_dict)
        self.assertIn('firstInnerKey',new_dict['secondOuterKey'])

        old_dict = utils.convert_dict(new_dict, utils.camel_to_underscore)
        self.assertIn('first_outer_key' , old_dict)
        self.assertIn('second_outer_key' , old_dict)
        self.assertIn('first_inner_key' , old_dict['second_outer_key'])
    def post(self):
        try:
            room_dict = json.loads(self.request.body)

            # Need to get the URL encoded data from utf8. Note that json encoded data appears to already be decoded.

            # Convert camel case keys to underscore (standard python) keys
            room_dict = utils.convert_dict(room_dict, utils.camel_to_underscore)

            chat_room_name_as_written = room_dict['chat_room_name_as_written']
            chat_room_name_normalized = chat_room_name_as_written.lower()
            room_dict['chat_room_name_normalized'] = chat_room_name_normalized


            # Make sure that the room name is valid before continuing.
            # These errors should be rare since these values are
            # already formatted to be within bounds and characters checked by the client-side javascript.
            # Only if the user has somehow bypassed the javascript checks should we receive values that don't
            # conform to the constraints that we have placed.
            if not constants.valid_chat_room_name_regex_compiled.match(chat_room_name_as_written):
                raise Exception('Room name regexp did not match')
            if len(chat_room_name_as_written) > constants.room_max_chars or len(chat_room_name_as_written) < constants.room_min_chars:
                raise Exception('Room name length of %s is out of range' % len(chat_room_name_as_written))

            response_dict = {}
            user_id = int(room_dict['user_id'])

            assert self.session.user_id == user_id

            # If this is a new room, then the room_creator_user_key will be stored in the room
            # object as the "creator" of the room
            room_creator_user_key = ndb.Key('UserModel', user_id)
            chat_room_obj = ChatRoomModel.create_or_get_room(chat_room_name_normalized, room_dict,
                                                            room_creator_user_key)

            response_dict['chatRoomNameNormalized'] = chat_room_name_normalized
            response_dict['chatRoomId'] = chat_room_obj.key.id()
            response_dict['statusString'] = 'roomJoined'

            http_helpers.set_http_ok_json_response(self.response, response_dict)

        except:
            # Unknown exception - provide feedback to the user to indicate that the room was not created or entered into
            err_status = 'ErrorUnableToCreateOrEnterRoom'
            # log this error for further analysis
            status_reporting.log_call_stack_and_traceback(logging.error, extra_info = err_status)
            http_helpers.set_http_ok_json_response(self.response, {'statusString': err_status})