From 3e2bed982cf45edfea95a92efdee91084a20133a Mon Sep 17 00:00:00 2001 From: Muhammad At Thoriq <muhammad.at@ui.ac.id> Date: Sun, 6 Oct 2019 03:30:36 +0700 Subject: [PATCH] Merge branch 'master' into '1606918484-03' # Conflicts: # kape/urls.py --- core/migrations/0015_merge_20191005_2038.py | 16 ++++ core/migrations/0017_merge_20191006_0134.py | 16 ++++ core/models/vacancies.py | 1 + core/serializers/vacancies.py | 2 +- core/tests/test_vacancies.py | 93 +++++++++++++++++++++ core/views/vacancies.py | 20 +++++ kape/urls.py | 3 +- 7 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 core/migrations/0015_merge_20191005_2038.py create mode 100644 core/migrations/0017_merge_20191006_0134.py diff --git a/core/migrations/0015_merge_20191005_2038.py b/core/migrations/0015_merge_20191005_2038.py new file mode 100644 index 00000000..d4afc1b8 --- /dev/null +++ b/core/migrations/0015_merge_20191005_2038.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2019-10-05 13:38 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0014_feedback'), + ('core', '0014_company_category'), + ] + + operations = [ + ] diff --git a/core/migrations/0017_merge_20191006_0134.py b/core/migrations/0017_merge_20191006_0134.py new file mode 100644 index 00000000..d41f21a8 --- /dev/null +++ b/core/migrations/0017_merge_20191006_0134.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.10.5 on 2019-10-05 18:34 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0015_merge_20191005_2038'), + ('core', '0016_merge_20191005_2235'), + ] + + operations = [ + ] diff --git a/core/models/vacancies.py b/core/models/vacancies.py index f2b5dc49..8968e626 100644 --- a/core/models/vacancies.py +++ b/core/models/vacancies.py @@ -23,6 +23,7 @@ class Application(models.Model): BOOKMARKED = 2 REJECTED = 3 ACCEPTED = 4 + ABORTED = 5 cover_letter = models.TextField(null=True, blank=True) student = models.ForeignKey(Student, on_delete=models.CASCADE) diff --git a/core/serializers/vacancies.py b/core/serializers/vacancies.py index 313f2064..a2bd2e4f 100644 --- a/core/serializers/vacancies.py +++ b/core/serializers/vacancies.py @@ -61,7 +61,7 @@ class ApplicationStatusSerializer(serializers.ModelSerializer): class SupervisorStudentApplicationSerializer(serializers.ModelSerializer): def to_representation(self, instance): - status_map = ["new", "read", "bookmarked", "rejected", "accepted" ] + status_map = ["new", "read", "bookmarked", "rejected", "accepted","aborted" ] return { 'name' : instance.student.full_name, 'npm' : instance.student.npm, diff --git a/core/tests/test_vacancies.py b/core/tests/test_vacancies.py index d8c654f6..f6ab7938 100644 --- a/core/tests/test_vacancies.py +++ b/core/tests/test_vacancies.py @@ -1,6 +1,7 @@ from datetime import datetime from django.utils import timezone +import json import requests_mock from django.contrib.auth.models import User from rest_framework import status @@ -434,3 +435,95 @@ class SupervisorApprovalTests(APITestCase): response = self.client.patch(url, format='json') self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) self.assertEqual(new_vacancy.verified, False) + +class AcceptOneOfferTests(APITestCase): + + def generateObject(self): + new_user = User.objects.create_user('dummy.company', 'dummy.company@company.com', 'lalala123') + new_company = Company.objects.create(user=new_user, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_user2 = User.objects.create_user('dummy.company2', 'dummy.company2@company.com', 'lalala123') + new_company2 = Company.objects.create(user=new_user2, description="lalala", status=Company.VERIFIED, logo=None, + address=None) + + new_vacancy = Vacancy.objects.create(company=new_company, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_vacancy2 = Vacancy.objects.create(company=new_company2, verified=True, open_time=datetime.fromtimestamp(0), + description="lalala", close_time=datetime.today()) + + new_user3 = User.objects.create_user('dummy.student', 'dummy.student@company.com', 'lalala123') + new_student = Student.objects.create(user=new_user3, npm=1234123412) + + return new_user3, new_vacancy, new_vacancy2, new_student + + def test_number_of_content_response_object_given_id_auth(self): + + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + status_response = [] + for app in body: + status_response.append(app['status']) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) >= 2) + self.assertFalse(len(body) == 0) + self.assertTrue('new' in status_response) + self.assertTrue('aborted' in status_response) + + def test_student_not_exist_given_auth(self): + new_user3,new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + user4 = User.objects.create_user('student_user_4', 'student_user_4@company.com', 'lalala123') + other_student = Student.objects.create(user=user4, npm=1098765432) + + Application.objects.create(student=other_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=other_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_200_OK) + self.assertTrue(len(body) == 0) + + def test_type_error_if_input_null(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + self.client.force_authenticate(new_user3) + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + None + '/vacancy/' + str(new_vacancy.pk) + '/' + + with self.assertRaises(TypeError): + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + None + '/' + + def test_if_requester_is_not_authenticated(self): + new_user3, new_vacancy, new_vacancy2, new_student = self.generateObject() + + Application.objects.create(student=new_student, vacancy=new_vacancy, cover_letter="asdasdasd") + Application.objects.create(student=new_student, vacancy=new_vacancy2, cover_letter="asdasdasd") + + url = '/api/acceptoffer/' + str(new_student.pk) + '/vacancy/' + str(new_vacancy.pk) + '/' + + response = self.client.patch(url, format='json') + body = json.loads(response.content) + + self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN) diff --git a/core/views/vacancies.py b/core/views/vacancies.py index 56165caa..2f805138 100644 --- a/core/views/vacancies.py +++ b/core/views/vacancies.py @@ -350,3 +350,23 @@ class BookmarkedVacancyByStudentViewSet(viewsets.GenericViewSet): student.bookmarked_vacancies.remove(vacancy) return Response( self.serializer_class(student.bookmarked_vacancies, many=True, context={'request': request}).data) + +class AcceptOfferByStudentViewSet(MultiSerializerViewSetMixin, viewsets.GenericViewSet): + queryset = Application.objects.all() + permission_classes = [IsAdminOrStudent] + + def partial_update(self, request, student_id, pk=None): + """ + Get list of a student {student_id}'s cancel offered vacancies + --- + """ + student = get_object_or_404(Student.objects.all().order_by('-updated'), pk=student_id) + apps = Application.objects.filter(student=student) + + for a in apps: + if a.vacancy_id != int(pk): + serializer = ApplicationStatusSerializer(a, data={'status': 5}, partial=True) + if serializer.is_valid(): + serializer.save() + + return Response(SupervisorStudentApplicationSerializer(apps, many=True, context={'request': request}).data) \ No newline at end of file diff --git a/kape/urls.py b/kape/urls.py index 5ae9c078..ade154c6 100755 --- a/kape/urls.py +++ b/kape/urls.py @@ -25,7 +25,7 @@ from core import apps from core.views.accounts import StudentViewSet, CompanyViewSet, SupervisorViewSet, UserViewSet, LoginViewSet, \ CompanyRegisterViewSet from core.views.vacancies import VacancyViewSet, BookmarkedVacancyByStudentViewSet, StudentApplicationViewSet, \ - CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet + CompanyApplicationViewSet, CompanyVacanciesViewSet, ApplicationViewSet, AcceptOfferByStudentViewSet from core.views.feedbacks import FeedbackViewSet schema_view = get_swagger_view() @@ -40,6 +40,7 @@ router.register(r'vacancies', VacancyViewSet) router.register(r'applications', ApplicationViewSet) router.register(r'feedbacks', FeedbackViewSet) # router.register(r'students/(?P<student_id>\d+)/profile', StudentProfileViewSet) +router.register(r'acceptoffer/(?P<student_id>\d+)/vacancy', AcceptOfferByStudentViewSet) router.register(r'students/(?P<student_id>\d+)/bookmarked-vacancies', BookmarkedVacancyByStudentViewSet, base_name='bookmarked-vacancy-list') router.register(r'students/(?P<student_id>\d+)/applied-vacancies', StudentApplicationViewSet, -- GitLab