def fetch():
    name = request.args.get('name')

    query = District.query()
    if name:
        query = District.query(District.slug == name.lower())

    districts = query.order(-District.ts_created).fetch()

    return {
        'districts': [d.to_dict() for d in districts]
    }
Пример #2
0
    def execute(self):
        filter = self.command.filter
        user = self.command.sms.user

        if RETRIEVE_ALL_DISTRICT not in user.permissions:
            logging.info('{} - User {} does not have permission {}'.format(
                self.command.sms.key.id(), user.key.id(), RETRIEVE_ALL_DISTRICT))
            return _('Command not allowed')

        district_name = self.command.district
        slug = district_name.lower()
        district = District.query(District.slug == slug).get()

        if not district:
            logging.info('{} - District {} is unknown'.format(
                self.command.sms.key.id(), district_name))
            return _('District {} is unknown').format(district_name)

        query = Farm.query(ndb.AND(Farm.action == filter,
                                   Farm.district_id == district.key.id()))
        crops = query.order(-Farm.ts_updated).fetch()

        if not crops:
            return _('{} data is none').format(_(filter))

        response = _('Total {} in {}:').format(_(filter), district.name)
        for crop in crops:
            response += '\n{} {}'.format(_(crop.crop_name).title(),
                                         crop.quantity)
        return response
    def execute(self):
        filter = self.command.filter
        user = self.command.sms.user

        if RETRIEVE_ALL_DISTRICT not in user.permissions:
            logging.info('{} - User {} does not have permission {}'.format(
                self.command.sms.key.id(), user.key.id(),
                RETRIEVE_ALL_DISTRICT))
            return _('Command not allowed')

        district_name = self.command.district
        slug = district_name.lower()
        district = District.query(District.slug == slug).get()

        if not district:
            logging.info('{} - District {} is unknown'.format(
                self.command.sms.key.id(), district_name))
            return _('District {} is unknown').format(district_name)

        query = Farm.query(
            ndb.AND(Farm.action == filter,
                    Farm.district_id == district.key.id()))
        crops = query.order(-Farm.ts_updated).fetch()

        if not crops:
            return _('{} data is none').format(_(filter))

        response = _('Total {} in {}:').format(_(filter), district.name)
        for crop in crops:
            response += '\n{} {}'.format(
                _(crop.crop_name).title(), crop.quantity)
        return response
Пример #4
0
    def execute(self):
        user = self.command.sms.user
        words = self.command.msg.split()
        message = self.command.msg
        farmers = None
        district = None

        for i in range(self.MULTI_DISTRICT_LIMIT):
            if district:
                message = ' '.join(words[i - 1:])
                break
            district_name = ' '.join(words[:i])
            slug = district_name.lower()
            district = District.query(District.slug == slug).get()

        if BROADCAST_ALL in user.permissions:
            # district must be specified
            if self.command.district != EVERYONE and not district:
                logging.info('{} - District {} is unknown'.format(
                    self.command.sms.id, words[0]))
                return _('District {} is unknown').format(words[0])

            if self.command.district == EVERYONE:
                farmers = User.query(User.role == User.ROLE_FARMER).fetch()

            if district:
                farmers = User.query(
                    ndb.AND(User.role == User.ROLE_FARMER,
                            User.district_id == district.key.id())).fetch()

        elif BROADCAST_OWN_DISTRICT in user.permissions:
            if self.command.district == EVERYONE:
                words.insert(0, EVERYONE)

            # own district is not specified but valid
            if not district or \
                    (district and district.key.id() != user.district_id):
                message = ' '.join(words)

            farmers = User.query(
                ndb.AND(User.role == User.ROLE_FARMER,
                        User.district_id == user.district_id)).fetch()

        else:
            return _('Command not allowed')

        phone_numbers = [farmer.phone_number for farmer in farmers]

        if phone_numbers:
            taskqueue.add(queue_name=self.QUEUE_NAME,
                          url=self.QUEUE_URL,
                          payload=json.dumps({
                              'task': {
                                  'phone_numbers': phone_numbers,
                                  'message': message
                              }
                          }))
            return _('Message delivered')
        return _('Message delivery failed')
    def setUp(self):
        self.ADMIN = 'admin'
        self.APIKEY = '123456789'

        self.app = app.test_client()

        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

        self.district = District(id='district_id',
                                 name='Sulawesi',
                                 slug='sulawesi')
        self.district.put()

        self.config = Config(admin_username=self.ADMIN,
                             admin_apikey=self.APIKEY)
        self.config.put()

        ndb.get_context().clear_cache()
def insert():
    name = request.form.get('name')
    slug = name.lower()

    existing = District.query(District.slug == slug).fetch()
    if existing:
        abort(400, 'district {} is already registered'.format(name))

    new = District(id=District.id(), name=name, slug=slug)
    new.put()
    return new.to_dict()
Пример #7
0
    def setUp(self):
        self.testbed = testbed.Testbed()
        self.testbed.activate()

        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

        District(id='d1', name='Sumatra', slug='sumatra').put()
        Farm(action='plant', district_id='d1', crop_name='potato', quantity=10).put()
        Farm(action='sell', district_id='d1', crop_name='potato', quantity=1).put()
        Farm(action='sell', district_id='d1', crop_name='carrot', quantity=2).put()

        self.user = User(id='u1', role=User.ROLE_FARMER, district_id='d1')
    def setUp(self):
        self.testbed = testbed.Testbed()
        self.testbed.activate()

        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()
        self.testbed.init_taskqueue_stub(root_path='.')
        self.taskqueue_stub = self.testbed.get_stub(
            testbed.TASKQUEUE_SERVICE_NAME)

        User(role='farmer',
             phone_number='+111',
             first_name='Kat',
             district_id='d1').put()
        User(role='farmer',
             phone_number='+222',
             first_name='Ayu',
             district_id='d1').put()
        User(role='farmer',
             phone_number='+333',
             first_name='Budi',
             district_id='d2').put()
        User(role='farmer',
             phone_number='+444',
             first_name='Anto',
             district_id='d3').put()

        District(id='d1', name='Lompoko', slug='lompoko').put()
        District(id='d2', name='Jawa Barat', slug='jawa barat').put()
        District(id='d3',
                 name='Nusa Tenggara Barat',
                 slug='nusa tenggara barat').put()

        self.user_hb = User(role=User.ROLE_HUTAN_BIRU, district_id='d0')
        self.user_leader = User(role=User.ROLE_DISTRICT_LEADER,
                                district_id='d2')
    def setUp(self):
        self.app = app.test_client()

        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()
        self.testbed.init_taskqueue_stub(root_path='.')

        self.user = User(role='district_leader',
                         phone_number='6072809193',
                         first_name='Kat',
                         district_id='sum123')
        self.user.put()

        District(id='sum123', name='Sumatra', slug='sumatra').put()
        Config(id='test', twilio_phone_number='+321').put()
Пример #10
0
    def setUp(self):
        self.ADMIN = 'admin'
        self.APIKEY = '123456789'

        self.app = app.test_client()

        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

        self.district = District(id='district_id',
                                 name='Sulawesi',
                                 slug='sulawesi')
        self.district.put()

        self.config = Config(admin_username=self.ADMIN,
                             admin_apikey=self.APIKEY)
        self.config.put()

        ndb.get_context().clear_cache()
Пример #11
0
def insert():
    role = request.form.get('role')
    district_id = request.form.get('district_id', None)

    if role == User.ROLE_FARMER or role == User.ROLE_DISTRICT_LEADER:
        if not district_id:
            abort(400, 'district_id is required')

        district = District.get_by_id(district_id)
        if not district:
            abort(400, '{} is an invalid district_id'.format(district_id))

    new = User(id=User.id(),
               role=role,
               district_id=district_id,
               phone_number=request.form.get('phone_number'),
               first_name=request.form.get('first_name'),
               last_name=request.form.get('last_name', None))

    new.put()
    return new.to_dict()
def insert():
    role = request.form.get('role')
    district_id = request.form.get('district_id', None)

    if role == User.ROLE_FARMER or role == User.ROLE_DISTRICT_LEADER:
        if not district_id:
            abort(400, 'district_id is required')

        district = District.get_by_id(district_id)
        if not district:
            abort(400, '{} is an invalid district_id'.format(district_id))

    new = User(id=User.id(),
               role=role,
               district_id=district_id,
               phone_number=request.form.get('phone_number'),
               first_name=request.form.get('first_name'),
               last_name=request.form.get('last_name', None))

    new.put()
    return new.to_dict()
class UserTest(unittest.TestCase):
    def setUp(self):
        self.ADMIN = 'admin'
        self.APIKEY = '123456789'

        self.app = app.test_client()

        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

        self.district = District(id='district_id',
                                 name='Sulawesi',
                                 slug='sulawesi')
        self.district.put()

        self.config = Config(admin_username=self.ADMIN,
                             admin_apikey=self.APIKEY)
        self.config.put()

        ndb.get_context().clear_cache()

    def tearDown(self):
        self.testbed.deactivate()

    def headers(self, username=None, apikey=None):
        username = username or self.ADMIN
        apikey = apikey or self.APIKEY

        return {
            'Authorization':
            'Basic ' + b64encode("{}:{}".format(username, apikey))
        }

    def insert(self, **kwargs):
        headers = self.headers()
        return self.app.post('/v1/users', data=kwargs, headers=headers)

    def retrieve(self, user_id):
        headers = self.headers()
        return self.app.get('/v1/users/{}'.format(user_id), headers=headers)

    def fetch(self, **kwargs):
        headers = self.headers()
        return self.app.get('/v1/users', query_string=kwargs, headers=headers)

    def insert_without_auth(self, **kwargs):
        return self.app.post('/v1/users', data=kwargs)

    def retrieve_without_auth(self, user_id):
        return self.app.get('/v1/users/{}'.format(user_id))

    def fetch_without_auth(self, **kwargs):
        return self.app.get('/v1/users', query_string=kwargs)

    def insert_with_invalid_admin(self, **kwargs):
        headers = self.headers(username='******')
        return self.app.post('/v1/users', data=kwargs, headers=headers)

    def retrieve_with_invalid_admin(self, user_id):
        headers = self.headers(username='******')
        return self.app.get('/v1/users/{}'.format(user_id), headers=headers)

    def fetch_with_invalid_admin(self, **kwargs):
        headers = self.headers(username='******')
        return self.app.get('/v1/users', query_string=kwargs, headers=headers)

    def insert_with_invalid_apikey(self, **kwargs):
        headers = self.headers('admin', '663377')
        return self.app.post('/v1/users', data=kwargs, headers=headers)

    def retrieve_with_invalid_apikey(self, user_id):
        headers = self.headers('admin', '663377')
        return self.app.get('/v1/users/{}'.format(user_id), headers=headers)

    def fetch_with_invalid_apikey(self, **kwargs):
        headers = self.headers('admin', '663377')
        return self.app.get('/v1/users', query_string=kwargs, headers=headers)

    def test_insert_user(self):
        res = self.insert(role='farmer',
                          phone_number='1234567',
                          first_name='Kat',
                          last_name='Leigh',
                          district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual('farmer', data['role'])
        self.assertEqual('1234567', data['phone_number'])
        self.assertEqual('Kat', data['first_name'])
        self.assertEqual('Leigh', data['last_name'])
        self.assertEqual('district_id', data['district_id'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_insert_without_district(self):
        res = self.insert(role='farmer',
                          phone_number='1234567',
                          first_name='Kat',
                          last_name='Leigh')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('district_id is required', data['error'])

    def test_insert_with_non_existent_district(self):
        res = self.insert(role='farmer',
                          phone_number='1234567',
                          first_name='Kat',
                          last_name='Leigh',
                          district_id='Dsomerandomid')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('Dsomerandomid is an invalid district_id',
                         data['error'])

    def test_insert_without_optional_param(self):
        res = self.insert(role='hutan_biru',
                          phone_number='1234567',
                          first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual('hutan_biru', data['role'])
        self.assertEqual('1234567', data['phone_number'])
        self.assertEqual('Kat', data['first_name'])
        self.assertEqual(None, data['last_name'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_insert_without_role(self):
        res = self.insert(phone_number='1234567', first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('role is required', data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_insert_without_phone(self):
        res = self.insert(role='farmer', first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('phone_number is required', data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_insert_without_name(self):
        res = self.insert(role='farmer', phone_number='1234567')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('first_name is required', data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_insert_with_undefined_roles(self):
        res = self.insert(role='teacher',
                          phone_number='1234567',
                          first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertTrue('teacher is an invalid role' in data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_with_different_roles(self):
        self.insert(role='farmer',
                    phone_number='1234567',
                    first_name='Kat',
                    last_name='Leigh',
                    district_id=self.district.key.id())

        self.insert(role='hutan_biru',
                    phone_number='1234567',
                    first_name='Kat',
                    last_name='Leigh')

        self.assertEqual(2, len(User.query().fetch()))

    def test_insert_and_retrieve(self):
        req = self.insert(role='hutan_biru',
                          phone_number='321',
                          first_name='Kat',
                          last_name='Leigh')

        data = json.loads(req.data)

        get = self.retrieve(data['id'])
        res = json.loads(get.data)

        self.assertEqual(data['id'], res['id'])
        self.assertEqual(data['role'], res['role'])
        self.assertEqual(data['phone_number'], res['phone_number'])
        self.assertEqual(data['first_name'], res['first_name'])
        self.assertEqual(data['last_name'], res['last_name'])
        self.assertEqual(data['ts_created'], res['ts_created'])
        self.assertEqual(data['ts_updated'], res['ts_updated'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_insert_and_retrieve_without_last_name(self):
        req = self.insert(role='hutan_biru',
                          phone_number='321',
                          first_name='Kat')

        data = json.loads(req.data)

        get = self.retrieve(data['id'])
        res = json.loads(get.data)

        self.assertEqual(data['id'], res['id'])
        self.assertEqual(data['role'], res['role'])
        self.assertEqual(data['phone_number'], res['phone_number'])
        self.assertEqual(data['first_name'], res['first_name'])
        self.assertEqual(None, res['last_name'])
        self.assertEqual(None, data['last_name'])
        self.assertEqual(data['ts_created'], res['ts_created'])
        self.assertEqual(data['ts_updated'], res['ts_updated'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_retrieve_empty_db(self):
        res = self.retrieve('123')
        data = json.loads(res.data)

        self.assertEqual(404, res.status_code)
        self.assertEqual('The uri "/v1/users/123" was not found',
                         data['error'])

    def test_fetch_empty_db(self):
        res = self.fetch()
        data = json.loads(res.data)

        self.assertEqual(200, res.status_code)
        self.assertEqual(0, len(data['users']))

    def test_fetch_with_phone_number(self):
        self.insert(role='farmer',
                    phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())
        self.insert(role='hutan_biru', phone_number='321', first_name='Kat')

        res = self.fetch(phone_number='123')
        data = json.loads(res.data)

        r = data['users']

        self.assertEqual(200, res.status_code)
        self.assertEqual(1, len(r))
        self.assertEqual('123', r[0]['phone_number'])
        self.assertEqual('Erika', r[0]['first_name'])
        self.assertEqual('farmer', r[0]['role'])

    def test_fetch_without_phone_number(self):
        self.insert(role='hutan_biru', phone_number='321', first_name='Kat')
        self.insert(role='farmer',
                    phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch()
        data = json.loads(res.data)

        r = data['users']

        self.assertEqual(200, res.status_code)
        self.assertEqual(2, len(r))
        self.assertEqual('123', r[0]['phone_number'])
        self.assertEqual('Erika', r[0]['first_name'])
        self.assertEqual('farmer', r[0]['role'])
        self.assertEqual('district_id', r[0]['district_id'])
        self.assertEqual('321', r[1]['phone_number'])
        self.assertEqual('Kat', r[1]['first_name'])
        self.assertEqual('hutan_biru', r[1]['role'])

    def test_insert_without_auth(self):
        res = self.insert_without_auth(role='farmer',
                                       phone_number='1234567',
                                       first_name='Kat',
                                       last_name='Leigh',
                                       district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

        self.assertEqual(0, len(User.query().fetch()))

    def test_retrieve_without_auth(self):
        req = self.insert(role='hutan_biru',
                          phone_number='321',
                          first_name='Kat',
                          last_name='Leigh')

        data = json.loads(req.data)

        res = self.retrieve_without_auth(data['id'])
        r = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', r['error'])

    def test_fetch_without_auth(self):
        self.insert(role='farmer',
                    phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch_without_auth(phone_number='123')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

    def test_insert_with_invalid_admin(self):
        res = self.insert_with_invalid_admin(
            role='farmer',
            phone_number='1234567',
            first_name='Kat',
            district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

        self.assertEqual(0, len(User.query().fetch()))

    def test_retrieve_with_invalid_admin(self):
        req = self.insert(role='hutan_biru',
                          phone_number='321',
                          first_name='Kat',
                          last_name='Leigh')

        data = json.loads(req.data)

        res = self.retrieve_with_invalid_admin(data['id'])
        r = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', r['error'])

    def test_fetch_with_invalid_admin(self):
        self.insert(role='farmer',
                    phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch_with_invalid_admin(phone_number='123')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

    def test_insert_with_invalid_apikey(self):
        res = self.insert_with_invalid_apikey(
            role='farmer',
            phone_number='1234567',
            first_name='Kat',
            district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

        self.assertEqual(0, len(User.query().fetch()))

    def test_retrieve_with_invalid_apikey(self):
        req = self.insert(role='hutan_biru',
                          phone_number='321',
                          first_name='Kat',
                          last_name='Leigh')

        data = json.loads(req.data)

        res = self.retrieve_with_invalid_apikey(data['id'])
        r = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', r['error'])

    def test_fetch_with_invalid_apikey(self):
        self.insert(role='farmer',
                    phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch_with_invalid_apikey(phone_number='123')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])
def retrieve(district_id):
    district = District.get_by_id(district_id)
    if not district:
        abort(404, 'this resource does not exist')

    return district.to_dict()
Пример #15
0
class UserTest(unittest.TestCase):

    def setUp(self):
        self.ADMIN = 'admin'
        self.APIKEY = '123456789'

        self.app = app.test_client()

        self.testbed = testbed.Testbed()
        self.testbed.activate()
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()

        self.district = District(id='district_id',
                                 name='Sulawesi',
                                 slug='sulawesi')
        self.district.put()

        self.config = Config(admin_username=self.ADMIN,
                             admin_apikey=self.APIKEY)
        self.config.put()

        ndb.get_context().clear_cache()

    def tearDown(self):
        self.testbed.deactivate()

    def headers(self, username=None, apikey=None):
        username = username or self.ADMIN
        apikey = apikey or self.APIKEY

        return {
            'Authorization':
                'Basic ' + b64encode("{}:{}".format(username, apikey))
        }

    def insert(self, **kwargs):
        headers = self.headers()
        return self.app.post('/v1/users', data=kwargs, headers=headers)

    def retrieve(self, user_id):
        headers = self.headers()
        return self.app.get('/v1/users/{}'.format(user_id), headers=headers)

    def fetch(self, **kwargs):
        headers = self.headers()
        return self.app.get('/v1/users', query_string=kwargs, headers=headers)

    def insert_without_auth(self, **kwargs):
        return self.app.post('/v1/users', data=kwargs)

    def retrieve_without_auth(self, user_id):
        return self.app.get('/v1/users/{}'.format(user_id))

    def fetch_without_auth(self, **kwargs):
        return self.app.get('/v1/users', query_string=kwargs)

    def insert_with_invalid_admin(self, **kwargs):
        headers = self.headers(username='******')
        return self.app.post('/v1/users', data=kwargs, headers=headers)

    def retrieve_with_invalid_admin(self, user_id):
        headers = self.headers(username='******')
        return self.app.get('/v1/users/{}'.format(user_id), headers=headers)

    def fetch_with_invalid_admin(self, **kwargs):
        headers = self.headers(username='******')
        return self.app.get('/v1/users', query_string=kwargs, headers=headers)

    def insert_with_invalid_apikey(self, **kwargs):
        headers = self.headers('admin', '663377')
        return self.app.post('/v1/users', data=kwargs, headers=headers)

    def retrieve_with_invalid_apikey(self, user_id):
        headers = self.headers('admin', '663377')
        return self.app.get('/v1/users/{}'.format(user_id), headers=headers)

    def fetch_with_invalid_apikey(self, **kwargs):
        headers = self.headers('admin', '663377')
        return self.app.get('/v1/users', query_string=kwargs, headers=headers)

    def test_insert_user(self):
        res = self.insert(role='farmer', phone_number='1234567',
                          first_name='Kat', last_name='Leigh',
                          district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual('farmer', data['role'])
        self.assertEqual('1234567', data['phone_number'])
        self.assertEqual('Kat', data['first_name'])
        self.assertEqual('Leigh', data['last_name'])
        self.assertEqual('district_id', data['district_id'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_insert_without_district(self):
        res = self.insert(role='farmer', phone_number='1234567',
                          first_name='Kat', last_name='Leigh')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('district_id is required', data['error'])

    def test_insert_with_non_existent_district(self):
        res = self.insert(role='farmer', phone_number='1234567',
                          first_name='Kat', last_name='Leigh',
                          district_id='Dsomerandomid')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('Dsomerandomid is an invalid district_id', data['error'])

    def test_insert_without_optional_param(self):
        res = self.insert(role='hutan_biru', phone_number='1234567',
                          first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual('hutan_biru', data['role'])
        self.assertEqual('1234567', data['phone_number'])
        self.assertEqual('Kat', data['first_name'])
        self.assertEqual(None, data['last_name'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_insert_without_role(self):
        res = self.insert(phone_number='1234567', first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('role is required', data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_insert_without_phone(self):
        res = self.insert(role='farmer', first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('phone_number is required', data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_insert_without_name(self):
        res = self.insert(role='farmer', phone_number='1234567')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('first_name is required', data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_insert_with_undefined_roles(self):
        res = self.insert(role='teacher', phone_number='1234567',
                          first_name='Kat')

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertTrue('teacher is an invalid role' in data['error'])
        self.assertEqual(0, len(User.query().fetch()))

    def test_with_different_roles(self):
        self.insert(role='farmer', phone_number='1234567',
                    first_name='Kat', last_name='Leigh',
                    district_id=self.district.key.id())

        self.insert(role='hutan_biru', phone_number='1234567',
                    first_name='Kat', last_name='Leigh')

        self.assertEqual(2, len(User.query().fetch()))

    def test_insert_and_retrieve(self):
        req = self.insert(role='hutan_biru', phone_number='321',
                          first_name='Kat', last_name='Leigh')

        data = json.loads(req.data)

        get = self.retrieve(data['id'])
        res = json.loads(get.data)

        self.assertEqual(data['id'], res['id'])
        self.assertEqual(data['role'], res['role'])
        self.assertEqual(data['phone_number'], res['phone_number'])
        self.assertEqual(data['first_name'], res['first_name'])
        self.assertEqual(data['last_name'], res['last_name'])
        self.assertEqual(data['ts_created'], res['ts_created'])
        self.assertEqual(data['ts_updated'], res['ts_updated'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_insert_and_retrieve_without_last_name(self):
        req = self.insert(role='hutan_biru', phone_number='321',
                          first_name='Kat')

        data = json.loads(req.data)

        get = self.retrieve(data['id'])
        res = json.loads(get.data)

        self.assertEqual(data['id'], res['id'])
        self.assertEqual(data['role'], res['role'])
        self.assertEqual(data['phone_number'], res['phone_number'])
        self.assertEqual(data['first_name'], res['first_name'])
        self.assertEqual(None, res['last_name'])
        self.assertEqual(None, data['last_name'])
        self.assertEqual(data['ts_created'], res['ts_created'])
        self.assertEqual(data['ts_updated'], res['ts_updated'])

        self.assertEqual(1, len(User.query().fetch()))

    def test_retrieve_empty_db(self):
        res = self.retrieve('123')
        data = json.loads(res.data)

        self.assertEqual(404, res.status_code)
        self.assertEqual('The uri "/v1/users/123" was not found', data['error'])

    def test_fetch_empty_db(self):
        res = self.fetch()
        data = json.loads(res.data)

        self.assertEqual(200, res.status_code)
        self.assertEqual(0, len(data['users']))

    def test_fetch_with_phone_number(self):
        self.insert(role='farmer', phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())
        self.insert(role='hutan_biru', phone_number='321',
                    first_name='Kat')

        res = self.fetch(phone_number='123')
        data = json.loads(res.data)

        r = data['users']

        self.assertEqual(200, res.status_code)
        self.assertEqual(1, len(r))
        self.assertEqual('123', r[0]['phone_number'])
        self.assertEqual('Erika', r[0]['first_name'])
        self.assertEqual('farmer', r[0]['role'])

    def test_fetch_without_phone_number(self):
        self.insert(role='hutan_biru', phone_number='321',
                    first_name='Kat')
        self.insert(role='farmer', phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch()
        data = json.loads(res.data)

        r = data['users']

        self.assertEqual(200, res.status_code)
        self.assertEqual(2, len(r))
        self.assertEqual('123', r[0]['phone_number'])
        self.assertEqual('Erika', r[0]['first_name'])
        self.assertEqual('farmer', r[0]['role'])
        self.assertEqual('district_id', r[0]['district_id'])
        self.assertEqual('321', r[1]['phone_number'])
        self.assertEqual('Kat', r[1]['first_name'])
        self.assertEqual('hutan_biru', r[1]['role'])

    def test_insert_without_auth(self):
        res = self.insert_without_auth(role='farmer', phone_number='1234567',
                                       first_name='Kat', last_name='Leigh',
                                       district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

        self.assertEqual(0, len(User.query().fetch()))

    def test_retrieve_without_auth(self):
        req = self.insert(role='hutan_biru', phone_number='321',
                          first_name='Kat', last_name='Leigh')

        data = json.loads(req.data)

        res = self.retrieve_without_auth(data['id'])
        r = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', r['error'])

    def test_fetch_without_auth(self):
        self.insert(role='farmer', phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch_without_auth(phone_number='123')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

    def test_insert_with_invalid_admin(self):
        res = self.insert_with_invalid_admin(role='farmer',
                                             phone_number='1234567',
                                             first_name='Kat',
                                             district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

        self.assertEqual(0, len(User.query().fetch()))

    def test_retrieve_with_invalid_admin(self):
        req = self.insert(role='hutan_biru', phone_number='321',
                          first_name='Kat', last_name='Leigh')

        data = json.loads(req.data)

        res = self.retrieve_with_invalid_admin(data['id'])
        r = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', r['error'])

    def test_fetch_with_invalid_admin(self):
        self.insert(role='farmer', phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch_with_invalid_admin(phone_number='123')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

    def test_insert_with_invalid_apikey(self):
        res = self.insert_with_invalid_apikey(role='farmer',
                                              phone_number='1234567',
                                              first_name='Kat',
                                              district_id=self.district.key.id())

        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])

        self.assertEqual(0, len(User.query().fetch()))

    def test_retrieve_with_invalid_apikey(self):
        req = self.insert(role='hutan_biru', phone_number='321',
                          first_name='Kat', last_name='Leigh')

        data = json.loads(req.data)

        res = self.retrieve_with_invalid_apikey(data['id'])
        r = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', r['error'])

    def test_fetch_with_invalid_apikey(self):
        self.insert(role='farmer', phone_number='123',
                    first_name='Erika',
                    district_id=self.district.key.id())

        res = self.fetch_with_invalid_apikey(phone_number='123')
        data = json.loads(res.data)

        self.assertEqual(400, res.status_code)
        self.assertEqual('unauthorized access', data['error'])