Пример #1
0
    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware',
                        return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = batch.RestaurantCollection()
        self.api.add_route('/batch/restaurants', self.resource)
        self.srmock = testing.StartResponseMock()

        restaurants = [{
            'name': 'a',
            'description': 'desc A',
            'email': '*****@*****.**',
            'address': 'tokyo',
        }, {
            'name': 'b',
            'description': 'desc B',
            'email': '*****@*****.**',
            'address': 'kyoto',
        }]
        self.restaurants = []
        for r in restaurants:
            rest = Restaurant(**r)
            rest.save()
            self.restaurants.append(rest)
Пример #2
0
    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware', return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = menu.Collection()
        self.api.add_route('/restaurants', self.resource)
        self.srmock = testing.StartResponseMock()
        self.restaurants = [
            Restaurant(name='a', description='a', email='*****@*****.**',
                       address='Roppongi Hills, Mori Tower, Minato-ku, Tokyo',
                       geolocation=[139.729183, 35.660429]),  # exactly at Roppongi Hills Mori Tower
            Restaurant(name='z', description='z', email='*****@*****.**',
                       address='Nishi-Azabu, Minato-ku, Tokyo',
                       geolocation=[139.727553, 35.659599]),  # slightly away from Roppongi
        ]
        for r in self.restaurants:
            r.save()

        self.menus = [
            Menu(name='curry chicken', price=550, currency='JPY', images=[], tags=['chicken', 'curry'], restaurant=self.restaurants[0]),
            Menu(name='keema curry', price=700, currency='JPY', images=[], tags=['indian', 'curry'], restaurant=self.restaurants[0]),
            Menu(name='tempura don', price=600, currency='JPY', images=[], tags=['japanese', 'fried'], restaurant=self.restaurants[1]),
            Menu(name='chahan set', price=900, currency='JPY', images=[], tags=['fried', 'rice'], restaurant=self.restaurants[1]),
            Menu(name='yakisoba', price=400, currency='JPY', images=[], tags=['noodles'], restaurant=self.restaurants[1])
        ]
        for m in self.menus:
            m.save()
Пример #3
0
    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware', return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = restaurant.Item()
        self.api.add_route('/restaurants/{id}', self.resource)
        self.srmock = testing.StartResponseMock()

        restaurants = [
            {
                'name': 'a',
                'description': 'desc A',
                'email': '*****@*****.**',
                'address': 'tokyo',
            },
            {
                'name': 'b',
                'description': 'desc B',
                'email': '*****@*****.**',
                'address': 'kyoto',
            }
        ]
        self.restaurants = []
        for r in restaurants:
            rest = Restaurant(**r)
            rest.save()
            self.restaurants.append(rest)
Пример #4
0
    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware', return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = menu.Collection()
        self.api.add_route('/restaurants', self.resource)
        self.srmock = testing.StartResponseMock()
        self.restaurant = Restaurant(name='a', description='a', email='*****@*****.**',
                                     address='Roppongi Hills, Mori Tower, Minato-ku, Tokyo',
                                     geolocation=[139.729183, 35.660429])
        self.restaurant.save()
Пример #5
0
class TestRatingWithSetup(testing.TestBase):
    def setup_common_resources_DB(self):
        self.restaurant = Restaurant(name='a',
                                     description='desc',
                                     email='*****@*****.**',
                                     address='Asakusa, Taito-ku, Tokyo',
                                     geolocation=[139.79843, 35.712074])
        self.restaurant.save()
        self.menus = [
            Menu(name='menu1',
                 price=200,
                 currency='JPY',
                 rating_total=4,
                 rating_count=1,
                 images=[],
                 tags=['chicken'],
                 restaurant=self.restaurant),
            Menu(name='menu2',
                 price=450,
                 currency='JPY',
                 rating_total=7,
                 rating_count=2,
                 images=[],
                 tags=['beef'],
                 restaurant=self.restaurant),
        ]
        for menu in self.menus:
            menu.save()
        self.users = [
            User(first_name='Clarke',
                 last_name='Kent',
                 display_name='Superman',
                 email='*****@*****.**',
                 role=1),
            User(first_name='Bruce',
                 last_name='Wayne',
                 display_name='Batman',
                 email='*****@*****.**',
                 role=9),
        ]
        for user in self.users:
            user.save()

    def tearDownDB(self):
        Restaurant.objects.delete()
        Menu.objects.delete()
        User.objects.delete()
        MenuRating.objects.delete()
Пример #6
0
    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware',
                        return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = restaurant.Item()
        self.api.add_route('/restaurants/{id}', self.resource)
        self.srmock = testing.StartResponseMock()
        self.restaurant = None
        rst = Restaurant(name='a',
                         description='desc',
                         email='*****@*****.**',
                         address='Asakusa, Taito-ku, Tokyo',
                         geolocation=[139.79843, 35.712074])

        self.restaurant = rst.save()
Пример #7
0
    def setUp(self):
        self.restaurant = Restaurant(
            **{
                'name': 'a',
                'description': 'desc',
                'email': '*****@*****.**',
                'address': 'Asakusa, Taito-ku, Tokyo',
                'geolocation': [139.79843, 35.712074]
            })

        self.menus = [
            {
                'name': 'menu1',
                'price': 200,
                'currency': 'JPY',
                'rating_total': 0.0,
                'rating_count': 0,
                'images': [],
                'tags': ['chicken'],
                'restaurant': self.restaurant
            },
            {
                'name': 'menu2',
                'price': 450,
                'currency': 'JPY',
                'rating_total': 7.0,
                'rating_count': 2,
                'images': [],
                'tags': ['curry'],
                'restaurant': self.restaurant
            },
        ]
Пример #8
0
    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware', return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = restaurant.Item()
        self.api.add_route('/restaurants/{id}', self.resource)
        self.srmock = testing.StartResponseMock()
        self.restaurant = None
        rst = Restaurant(
            name='a',
            description='desc',
            email='*****@*****.**',
            address='Asakusa, Taito-ku, Tokyo',
            geolocation=[139.79843, 35.712074]
        )

        self.restaurant = rst.save()
Пример #9
0
    def test_init(self):

        for r in self.restaurants:
            attributes = r['dict']
            restaurant = Restaurant(**attributes)

            for property, value in attributes.iteritems():
                self.assertEquals(getattr(restaurant, property), value)
Пример #10
0
    def on_post(self, req, res):
        # save restaurants, and menus (if any)
        data = req.params.get('body')  # restaurant data
        menu_data = data.pop('menus')

        # save to DB
        restaurant = Restaurant(**data)
        restaurant.save()
        menus = []
        for mdata in menu_data:
            mdata.update({'restaurant': restaurant})
            menus.append(Menu(**mdata))  # extract info meant for menus

        Menu.objects.insert(menus)

        # return Restaurant (no menus)
        restaurant = Restaurant.objects.get(id=restaurant.id)
        res.body = restaurant
        res.body = reformat_geolocations_point_field_to_map(res.body, 'geolocation')
Пример #11
0
class TestMenuCollectionPost(testing.TestBase):

    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware', return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = menu.Collection()
        self.api.add_route('/restaurants', self.resource)
        self.srmock = testing.StartResponseMock()
        self.restaurant = Restaurant(name='a', description='a', email='*****@*****.**',
                                     address='Roppongi Hills, Mori Tower, Minato-ku, Tokyo',
                                     geolocation=[139.729183, 35.660429])
        self.restaurant.save()

    def tearDown(self):
        Restaurant.objects(id__in=[self.restaurant.id]).delete()
        Menu.objects().delete()

    def test_on_post(self):
        tests = [
            {
                'data': json.dumps({
                    "name": "menu1",
                    "price": 100.00,
                    "currency": 'JPY',
                    "images": ["http://kfc.com/1.jpg"],
                    "tags": [],
                    "restaurant_id": str(self.restaurant.id)}),
                'expected': {
                    "name": "menu1"
                }
            }
        ]
        for t in tests:
            res = self.simulate_request('/restaurants',
                                        body=t['data'],
                                        method='POST',
                                        headers={'Content-Type': 'application/json'})

            self.assertTrue(isinstance(res, list))
            body = json.loads(res[0])
            self.assertTrue(isinstance(body, dict))
            self.assertDictContainsSubset(t['expected'], body)
Пример #12
0
    def on_get(self, req, res):
        query_params = req.params.get('query')

        try:
            # get pagination limits
            start = int(query_params.pop('start', 0))
            limit = int(query_params.pop('limit', constants.PAGE_LIMIT))
            end = start + limit

        except ValueError as e:
            raise HTTPBadRequest(title='Invalid Value',
                                 description='Invalid arguments in URL query:\n{}'.format(e.message))
        # custom filters
        # temp dict for updating query filters
        updated_params = {}

        for item in ['name', 'description']:
            if item in query_params:
                item_val = query_params.pop(item)
                updated_params['{}__icontains'.format(item)] = item_val

        try:
            if 'geolocation' in query_params:
                geolocation_val = query_params.pop('geolocation')
                geolocation_val = map(float, geolocation_val.split(',')[:2])
                max_distance = int(query_params.pop('maxDistance', constants.MAX_DISTANCE_SEARCH))

                # we deal with geolocation query in raw instead due to mongoengine bugs
                # see https://github.com/MongoEngine/mongoengine/issues/795
                # dated: 3/1/2015

                updated_params['__raw__'] = {
                    'geolocation': {
                        '$near': {
                            '$geometry': {
                                'type': 'Point',
                                'coordinates': geolocation_val
                            },
                            '$maxDistance': max_distance
                        },
                    }
                }

        except Exception:
            raise HTTPBadRequest('Invalid Value', 'geolocation supplied is invalid: {}'.format(geolocation_val))

        query_params.update(updated_params)  # update modified params for filtering

        restaurants = Restaurant.objects(**query_params)[start:end]
        for r in restaurants:
            reformat_geolocations_point_field_to_map(r, 'geolocation')

        res.body = {'items': restaurants, 'count': len(restaurants)}
Пример #13
0
    def setUp(self):
        with mock.patch('snakebite.JWTAuthMiddleware',
                        return_value=get_mock_auth_middleware()):
            self.api = get_test_snakebite().app

        self.resource = restaurant.Collection()
        self.api.add_route('/restaurants', self.resource)
        self.srmock = testing.StartResponseMock()
        self.restaurants = [
            Restaurant(name='a',
                       description='desc',
                       email='*****@*****.**',
                       address='Asakusa, Taito-ku, Tokyo',
                       geolocation=[139.79843, 35.712074]),
            Restaurant(name='b',
                       description='description',
                       email='*****@*****.**',
                       address='Roppongi, Minato-ku, Tokyo',
                       geolocation=[139.731443, 35.662836])
        ]
        for r in self.restaurants:
            r.save()
Пример #14
0
class TestRatingWithSetup(testing.TestBase):

    def setup_common_resources_DB(self):
        self.restaurant = Restaurant(name='a', description='desc', email='*****@*****.**',
                                     address='Asakusa, Taito-ku, Tokyo', geolocation=[139.79843, 35.712074])
        self.restaurant.save()
        self.menus = [
            Menu(name='menu1', price=200, currency='JPY', rating_total=4, rating_count=1, images=[], tags=['chicken'], restaurant=self.restaurant),
            Menu(name='menu2', price=450, currency='JPY', rating_total=7, rating_count=2, images=[], tags=['beef'], restaurant=self.restaurant),
        ]
        for menu in self.menus:
            menu.save()
        self.users = [
            User(first_name='Clarke', last_name='Kent', display_name='Superman', email='*****@*****.**', role=1),
            User(first_name='Bruce', last_name='Wayne', display_name='Batman', email='*****@*****.**', role=9),
        ]
        for user in self.users:
            user.save()

    def tearDownDB(self):
        Restaurant.objects.delete()
        Menu.objects.delete()
        User.objects.delete()
        MenuRating.objects.delete()
Пример #15
0
 def test_remove(self):
     Restaurant.objects(name__in=['a', 'b']).delete()
     self.assertEquals(len(Restaurant.objects), 0)
Пример #16
0
 def test_save(self):
     for i, r in enumerate(self.restaurants):
         attributes = r['dict']
         restaurant = Restaurant(**attributes)
         restaurant.save()
         self.assertEquals(len(Restaurant.objects), i + 1)
Пример #17
0
    def on_get(self, req, res):
        query_params = req.params.get('query')

        try:
            # get pagination limits
            start = int(query_params.pop('start', 0))
            limit = int(query_params.pop('limit', constants.PAGE_LIMIT))
            end = start + limit

        except ValueError as e:
            raise HTTPBadRequest(title='Invalid Value',
                                 description='Invalid arguments in URL query:\n{}'.format(e.message))

        # custom filters
        # temp dict for updating query filters
        updated_params = {}

        for item in ['name']:
            if item in query_params:
                item_val = query_params.pop(item)
                updated_params['{}__icontains'.format(item)] = item_val

        # skip updating query_params for filters on list fields like tags,
        # since mongoengine filters directly by finding any Menu that has tags of that value
        # e.g., GET /menu?tags=chicken returns all restaurants having 'chicken' tag

        for item in ['price', 'rating']:
            if item in query_params:
                range = query_params.pop(item)
                r_min, r_max = min_max(range, type='float')
                updated_params['{}__gte'.format(item)] = r_min
                updated_params['{}__lte'.format(item)] = r_max

        # for convenience, we allow users to search for menus by their restaurant's geolocation too
        if 'geolocation' in query_params:
            try:
                geolocation_val = query_params.pop('geolocation')
                geolocation_val = map(float, geolocation_val.split(',')[:2])
                max_distance = int(query_params.pop('maxDistance', constants.MAX_DISTANCE_SEARCH))

                # we deal with geolocation query in raw instead due to mongoengine bugs
                # see https://github.com/MongoEngine/mongoengine/issues/795
                # dated: 3/1/2015

                restaurant_query_params = {
                    '__raw__': {
                        'geolocation': {
                            '$near': {
                                '$geometry': {
                                    'type': 'Point',
                                    'coordinates': geolocation_val
                                },
                                '$maxDistance': max_distance
                            },
                        }
                    }
                }
                # return list of restaurants satisfying geolocation requirements
                restaurants = Restaurant.objects(**restaurant_query_params)

                # we found nearby restaurants, filter menus further to menus from these restaurants only
                updated_params['__raw__'] = {
                    "restaurant.$id": {
                        "$in": [r.id for r in restaurants]
                    }
                }

            except Exception:
                raise HTTPBadRequest('Invalid Value', 'geolocation supplied is invalid: {}'.format(geolocation_val))

        query_params.update(updated_params)  # update modified params for filtering
        menus = Menu.objects(**query_params)[start:end]

        res.body = {'items': menus, 'count': len(menus)}
Пример #18
0
 def tearDown(self):
     Restaurant.objects(id__in=[self.restaurant.id]).delete()
     Menu.objects().delete()
Пример #19
0
    def on_get(self, req, res):
        query_params = req.params.get('query')

        try:
            # get pagination limits
            start = int(query_params.pop('start', 0))
            limit = int(query_params.pop('limit', constants.PAGE_LIMIT))
            end = start + limit

        except ValueError as e:
            raise HTTPBadRequest(
                title='Invalid Value',
                description='Invalid arguments in URL query:\n{}'.format(
                    e.message))

        # custom filters
        # temp dict for updating query filters
        updated_params = {}

        for item in ['name']:
            if item in query_params:
                item_val = query_params.pop(item)
                updated_params['{}__icontains'.format(item)] = item_val

        # skip updating query_params for filters on list fields like tags,
        # since mongoengine filters directly by finding any Menu that has tags of that value
        # e.g., GET /menu?tags=chicken returns all restaurants having 'chicken' tag

        for item in ['price', 'rating']:
            if item in query_params:
                range = query_params.pop(item)
                r_min, r_max = min_max(range, type='float')
                updated_params['{}__gte'.format(item)] = r_min
                updated_params['{}__lte'.format(item)] = r_max

        # for convenience, we allow users to search for menus by their restaurant's geolocation too
        if 'geolocation' in query_params:
            try:
                geolocation_val = query_params.pop('geolocation')
                geolocation_val = map(float, geolocation_val.split(',')[:2])
                max_distance = int(
                    query_params.pop('maxDistance',
                                     constants.MAX_DISTANCE_SEARCH))

                # we deal with geolocation query in raw instead due to mongoengine bugs
                # see https://github.com/MongoEngine/mongoengine/issues/795
                # dated: 3/1/2015

                restaurant_query_params = {
                    '__raw__': {
                        'geolocation': {
                            '$near': {
                                '$geometry': {
                                    'type': 'Point',
                                    'coordinates': geolocation_val
                                },
                                '$maxDistance': max_distance
                            },
                        }
                    }
                }
                # return list of restaurants satisfying geolocation requirements
                restaurants = Restaurant.objects(**restaurant_query_params)

                # we found nearby restaurants, filter menus further to menus from these restaurants only
                updated_params['__raw__'] = {
                    "restaurant.$id": {
                        "$in": [r.id for r in restaurants]
                    }
                }

            except Exception:
                raise HTTPBadRequest(
                    'Invalid Value',
                    'geolocation supplied is invalid: {}'.format(
                        geolocation_val))

        query_params.update(
            updated_params)  # update modified params for filtering
        menus = Menu.objects(**query_params)[start:end]

        res.body = {'items': menus, 'count': len(menus)}
Пример #20
0
 def tearDown(self):
     Restaurant.objects(id__in=[r.id for r in self.restaurants]).delete()
Пример #21
0
 def tearDown(self):
     Restaurant.objects(id__in=[r.id for r in self.restaurants]).delete()