def test_add_existing_collaboration_to_meal_fails(self): ''' No new pending collaboration object should be created if the specified user is already a collaborator on the meal. Test steps: - create a meal - add an existing collaborator to the meal - send a patch request attempting to add the same collaborator to the meal - check that there is no new pending collaboration for that collaborator/meal combination ''' client = APIClient() meal_data = MealSerializer.get_meal_data(self.new_meal_data) collaborators_data = MealSerializer.get_collaborators( self.new_meal_data) meal = Meal(**meal_data) meal.save() meal.collaborators.set(collaborators_data) meal_id = meal.pk meal_owner = meal.owner.username user = User.objects.get(username=meal_owner) client.force_authenticate(user=user) url = "/meals/%d/" % meal_id client.patch(url, {"collaborators": [2]}, format="json") collaborator = User.objects.get(id=2) new_collaboration_exists = collaborator.new_shared_meals.filter( meal=meal).exists() self.assertFalse(new_collaboration_exists)
def test_update_ingredients_replaces_ingredients_list(self): ''' When a meal's ingredients are updated, the old ingredients list should be entirely replaced by the new one. Test steps: - create a meal with ingredients - send a request to update that meal's ingredients - check that the meal db object's incredients list reflects the update list. ''' new_meal_data = { "name": "test meal", "taste": 1, "difficulty": 1, "last_used": "2018-01-01", "used_count": 22, "notes": "test notes", "ingredients": ["sugar", "spice", "everything nice"] } new_meal = Meal(**new_meal_data) new_meal.save() meal_id = new_meal.pk updated_ingredients = {"ingredients": ["lemon", "lime"]} user = new_meal.owner client = APIClient() client.force_authenticate(user=user) url = "/meals/%d/" % meal_id client.patch(url, updated_ingredients, format="json") new_meal.refresh_from_db() self.assertListEqual(updated_ingredients["ingredients"], new_meal.ingredients)
def test_add_collaboration_to_existing_meal(self): ''' Add collaborators to an existing meal. The collaborators should result in new pending collaborations being created. Test steps: - create a meal - send a patch request to add a collaborator to that meal - check that a new pending collaboration object exists for the collaborator/meal combination ''' client = APIClient() data = { k: v for k, v in self.new_meal_data.items() if k != "collaborators" } meal = Meal(**data) meal.save() meal_id = meal.pk meal_owner = meal.owner.username user = User.objects.get(username=meal_owner) client.force_authenticate(user=user) url = "/meals/%d/" % meal_id client.patch(url, {"collaborators": [1]}, format="json") collaborator = User.objects.get(id=1) self.assertIsNotNone( PendingCollaboration.objects.get(collaborator=collaborator, meal=meal))
def test_filter_existing_collaborations_returns_true_if_no_collaboration_exists(self): new_meal = Meal(**self.new_meal_data) new_meal.save() collaborator = User.objects.get(id=self.pending_collaborators_data[0]) include_in_list = MealSerializer.filter_existing_collaborations(collaborator, new_meal) self.assertTrue(include_in_list)
def test_user_new_shared_meals(self): ''' Given a user, it should be possible to retrieve all of the pending meals other people have shared with the user by accessing the new_shared_meals property. Test steps: - create a new meal - send a patch request to add a collaborator to that meal - check that a new pending collaboration object for that meal is present on the collaborator's new_shared_meals property. ''' client = APIClient() data = { k: v for k, v in self.new_meal_data.items() if k != "collaborators" } meal = Meal(**data) meal.save() meal_id = meal.pk meal_owner = meal.owner.username user = User.objects.get(username=meal_owner) client.force_authenticate(user=user) url = "/meals/%d/" % meal_id client.patch(url, {"collaborators": [1]}, format="json") collaborator = User.objects.get(id=1) new_collaboration_exists = collaborator.new_shared_meals.filter( meal=meal).exists() self.assertTrue(new_collaboration_exists)
def form_valid(self, form): for date, data in form.cleaned_data['data'].items(): try: meal = self.object.meal_set.get(date=date) except Meal.DoesNotExist: meal = Meal(person=self.object, date=date) meal.data = trim_meals_data(data) meal.save() return redirect(self.object.get_absolute_url())
def test_filter_existing_collaborations_returns_false_if_collaboration_exists(self): new_meal = Meal(**self.new_meal_data) new_meal.save() owner = User.objects.get(id=4) for collaborator in self.pending_collaborators_data: user = User.objects.get(id=collaborator) PendingCollaboration(meal=new_meal, collaborator=user, owner=owner).save() new_meal.collaborators.set(self.existing_collaborators_data) collaborator = User.objects.get(id=self.existing_collaborators_data[0]) self.assertFalse(MealSerializer.filter_existing_collaborations(collaborator, new_meal))
def create(self, validated_data): collaborators = self.get_collaborators(validated_data) new_meal = self.get_meal_data(validated_data) meal = Meal(**new_meal) meal.save() pending_collaborations = self.create_pending_collaborations( collaborators, meal) for collaboration in pending_collaborations: collaboration.save() return meal
def add_meal(request, meal_option_id): form = MealForm(request.POST) meal_option = get_object_or_404(MealOption, pk=meal_option_id) # meal = get_object_or_404(Meal, pk=meal_option_id) if 'special' in request.POST: special = request.POST['special'] if special == 'on': special = True else: special = False if form.is_valid(): new_meal = Meal(name=request.POST['name'].lower(), user=request.user, meal_option=meal_option, special=special) new_meal.save() return redirect('meals:edit_meals')
def test_create_pending_collaborations(self): user = User() user.save() collaborators = (pipe | list | (filter, lambda x: user is x) | list | (lambda col: col[0:2]))(User.objects.all()) meal = Meal(name="test", taste=1, owner=user, difficulty=5) meal.save() pending_collaborations = MealSerializer.create_pending_collaborations(collaborators, meal) for collaboration in pending_collaborations: with self.subTest(collaboration=collaboration): self.assertEqual(collaboration, meal)
def test_delete_meal_succeeds(self): ''' An authenticated meal owner should be able to delete a meal. Test steps: - create a meal - send a request to delete the meal - check that response indicates success - check that the meal does not still exist in the db ''' client = APIClient() new_meal = Meal(**self.new_meal_data) new_meal.save() pk = new_meal.pk url = "/meals/%d/" % pk client.force_authenticate(user=new_meal.owner) response = client.delete(url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) self.assertFalse(Meal.objects.filter(pk=pk).exists())
def test_delete_meal_fails_if_not_owner(self): ''' An user authenticated as someone other than the meal owner should not be able to delete a meal. Test steps: - create a meal - authenticate as not the owner - send a request to delete the meal - check that response indicates failure - check that the meal still exists in the db ''' client = APIClient() new_meal = Meal(owner=User.objects.get(pk=2), **self.new_meal_data) new_meal.save() pk = new_meal.pk url = "/meals/%d/" % pk client.force_authenticate(user=User.objects.get(pk=1)) response = client.delete(url) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) self.assertTrue(Meal.objects.filter(pk=pk).exists())
def test_delete_meal_fails_if_not_logged_in(self): ''' An unauthenticated user should not be able to delete a meal. Test steps: - create a meal - send a request to delete the meal - check that response indicates failure - check that the meal still exists in the db ''' factory = APIRequestFactory() new_meal = Meal(**self.new_meal_data) new_meal.save() pk = new_meal.pk url = "/meals/%d/" % pk request = factory.delete(url) view = MealDetail.as_view() response = view(request) self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED) self.assertTrue(Meal.objects.filter(pk=pk).exists())
def post(self, request, *args, **kwargs): meal = Meal() mealname = request.POST.get('meal_name') if mealname: meal.name = mealname mealtype = request.POST.get('meal_type') if mealtype: meal.kind = mealtype mealstarts = request.POST.get('meal_starts') if mealstarts: meal.starts = mealstarts mealends = request.POST.get('meal_ends') if mealends: meal.ends = mealends mealtimes = request.POST.get('meal_times') if mealtimes: meal.times = mealtimes mealopened = request.POST.get('meal_opened') if mealopened: meal.opened = (mealopened == 'opened') meal.save() messages.success(self.request, 'Meal added!') return redirect('meals_list')
def generate_meal(): users = SystemUser.objects.all() for user in users: current_month = datetime.datetime.now().month current_year = datetime.datetime.now().year date_list = calendar.monthcalendar(current_year, current_month) dates = list(filter(lambda num: num != 0, combine(date_list))) for date in dates: meal = Meal( member=user, meal_date=datetime.date(current_year, current_month, date), breakfast=random.choice([0, 0.5, 1]), lunch=random.choice([0, 1, 2]), dinner=random.choice([0, 1, 2]), ) meal.save() meal_pk = str(meal.pk).zfill(4) meal.code = 'M-{0}'.format(meal_pk) meal.save() print('Meal generated successfully.')
class MealsAPITest(APITestCase): """ Functional tests of the REST functionality of meals API. """ def setUp(self): self.sample_meal_info = { "eater": "John", "name": "Burger", "description": "great!", "calories": 300, "meal_time": "2015-06-25T05:37:45.331352Z", } admin_group = Group(name="Admin") admin_group.save() self.admin_group = admin_group self.sample_password = "******" self.sample_user_credentials = { "email": "*****@*****.**", "username": "******", "password": self.sample_password, "calorie_target": 3500, } self.sample_admin_credentials = {'email': "*****@*****.**", 'username': "******", 'password': self.sample_password} self.sample_user = Account.objects.create_user(**self.sample_user_credentials) self.sample_admin = Account.objects.create_superuser(**self.sample_admin_credentials) self.sample_meal_info_2 = { "eater": self.sample_user, "name": "Pizza", "description": "good!", "calories": 200, "meal_time": "2015-06-25T05:37:45.331352Z", } self.sample_meal = Meal(**self.sample_meal_info_2) self.sample_meal.save() self.sample_meal_info_3 = { "eater": self.sample_admin, "name": "Burrito", "description": "good!", "calories": 200, "meal_time": "2015-07-25T05:37:45.331352Z", } self.sample_admin_meal = Meal(**self.sample_meal_info_3) self.sample_admin_meal.save() def test_logged_out_user_cannot_create_meal(self): url = reverse("meals-list") response = self.client.post(url, self.sample_meal_info) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_logged_out_user_cannot_see_meal(self): url = reverse("meals-detail", args=(1,)) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_logged_out_user_cannot_update_meal(self): url = reverse("meals-detail", args=(1,)) response = self.client.put(url, self.sample_meal_info) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_logged_out_user_cannot_delete_meal(self): url = reverse("meals-detail", args=(1,)) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_create_meal_from_valid_data(self): url = reverse("meals-list") self.client.login(username=self.sample_user.username, password=self.sample_password) response = self.client.post(url, self.sample_meal_info) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.content, '{"id":3,"eater":{"id":1,"email":"*****@*****.**","username":"******","calorie_target":2000,"is_admin":false},"name":"Burger","description":"great!","calories":300,"meal_time":"2015-06-25T05:37:45.331352Z"}') def test_create_meal_from_invalid_data(self): invalid_meal = { "name": 500, "meal_time": 500, "calories": "beans" } url = reverse("meals-list") self.client.login(username=self.sample_user.username, password=self.sample_password) response = self.client.post(url, invalid_meal) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_update_meal_with_valid_data(self): self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-detail", args=(1,)) response = self.client.put(url, self.sample_meal_info) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.content, '{"id":1,"eater":{"id":1,"email":"*****@*****.**","username":"******","calorie_target":2000,"is_admin":false},"name":"Burger","description":"great!","calories":300,"meal_time":"2015-06-25T05:37:45.331352Z"}') def test_update_meal_with_invalid_data(self): invalid_meal = { "name": 500, "meal_time": 500, "calories": "beans" } self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-detail", args=(1,)) response = self.client.put(url, invalid_meal) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) def test_can_view_own_meal_detail(self): self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-detail", args=(1,)) response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.content, '{"id":1,"eater":{"id":1,"email":"*****@*****.**","username":"******","calorie_target":2000,"is_admin":false},"name":"Pizza","description":"good!","calories":200,"meal_time":"2015-06-25T05:37:45.331352Z"}') def test_delete_meal(self): self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-detail", args=(1,)) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) def test_non_admin_can_only_create_own_meal(self): friends_meal = { "eater": self.sample_admin, "name": "Pizza", "description": "good!", "calories": 200, "meal_time": "2015-06-25T05:37:45.331352Z", } url = reverse("meals-list") self.client.login(username=self.sample_user.username, password=self.sample_password) response = self.client.post(url, friends_meal) self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(response.content, '{"id":3,"eater":{"id":1,"email":"*****@*****.**","username":"******","calorie_target":2000,"is_admin":false},"name":"Pizza","description":"good!","calories":200,"meal_time":"2015-06-25T05:37:45.331352Z"}') def test_non_admin_can_only_edit_own_meal(self): self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-detail", args=(2,)) response = self.client.put(url, self.sample_meal_info) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_non_admin_can_only_delete_own_meal(self): self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-detail", args=(2,)) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND) def test_admin_can_edit_any_meal(self): self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-detail", args=(1,)) response = self.client.put(url, self.sample_meal_info) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(response.content, '{"id":1,"eater":{"id":1,"email":"*****@*****.**","username":"******","calorie_target":2000,"is_admin":false},"name":"Burger","description":"great!","calories":300,"meal_time":"2015-06-25T05:37:45.331352Z"}') def test_admin_can_delete_any_meal(self): self.client.login(username=self.sample_admin.username, password=self.sample_password) url = reverse("meals-detail", args=(1,)) response = self.client.delete(url) self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) def test_admin_sees_all_meals(self): self.client.login(username=self.sample_admin.username, password=self.sample_password) url = reverse("meals-list") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 2) def test_non_admin_sees_only_own_meals(self): self.client.login(username=self.sample_user.username, password=self.sample_password) url = reverse("meals-list") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(len(response.data), 1) def test_logged_out_user_sees_no_meals(self): url = reverse("meals-list") response = self.client.get(url) self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) def test_meals_ordered_by_meal_time(self): self.client.login(username=self.sample_admin.username, password=self.sample_password) url = reverse("meals-list") response = self.client.get(url) self.assertEqual(response.data[0]["name"], "Burrito")