Skip to content

Commit

Permalink
Merge pull request #82 from unb-mds/task/search-api
Browse files Browse the repository at this point in the history
api(search): implementação do sistema de busca por matéria
  • Loading branch information
caio-felipee authored Nov 17, 2023
2 parents ec71a39 + ceb2ff9 commit f03986b
Show file tree
Hide file tree
Showing 9 changed files with 540 additions and 20 deletions.
15 changes: 15 additions & 0 deletions api/api/migrations/0002_auto_20231113_2029.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Generated by Django 4.2.5 on 2023-11-13 23:29

from django.db import migrations
from django.contrib.postgres.operations import UnaccentExtension


class Migration(migrations.Migration):

dependencies = [
('api', '0001_initial'),
]

operations = [
UnaccentExtension()
]
19 changes: 19 additions & 0 deletions api/api/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from rest_framework.serializers import ModelSerializer
from api.models import Department, Discipline, Class

class DepartmentSerializer(ModelSerializer):
class Meta:
model = Department
fields = '__all__'
class ClassSerializer(ModelSerializer):
class Meta:
model = Class
fields = '__all__'

class DisciplineSerializer(ModelSerializer):
department = DepartmentSerializer()
classes = ClassSerializer(many=True)

class Meta:
model = Discipline
fields = '__all__'
292 changes: 274 additions & 18 deletions api/api/tests.py
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
from django.test import TestCase
from .models import Department, Discipline,Class
from rest_framework.test import APITestCase
from .models import Department, Discipline, Class
from utils.db_handler import get_or_create_department, get_or_create_discipline, create_class
from .views import ERROR_MESSAGE
import json


class DisciplineModelsTest(TestCase):
def setUp(self):
self.department = Department.objects.create(
code = 'INF',
year = "2023",
period = "2"
code='INF',
year="2023",
period="2"
)

self.discipline = Discipline.objects.create(
name = 'Métodos de Desenvolvimento de Software',
code = 'MDS1010',
department = self.department
name='Métodos de Desenvolvimento de Software',
code='MDS1010',
department=self.department
)
self._class = Class.objects.create(
workload = 60,
teachers = ['Professor 1', 'Professor 2'],
classroom = 'MOCAP',
schedule = '46M34',
days = ['Quarta-Feira 10:00 às 11:50', 'Sexta-Feira 10:00 às 11:50'],
_class = "1",
discipline = self.discipline
workload=60,
teachers=['Professor 1', 'Professor 2'],
classroom='MOCAP',
schedule='46M34',
days=['Quarta-Feira 10:00 às 11:50', 'Sexta-Feira 10:00 às 11:50'],
_class="1",
discipline=self.discipline
)


def test_create_discipline(self):
self.assertEqual(self.discipline.name, 'Métodos de Desenvolvimento de Software')
self.assertEqual(self.discipline.name,
'Métodos de Desenvolvimento de Software')
self.assertEqual(self.discipline.code, 'MDS1010')
self.assertEqual(self.discipline.department, self.department)

Expand All @@ -35,7 +40,8 @@ def test_create_class(self):
self.assertEqual(self._class.teachers, ['Professor 1', 'Professor 2'])
self.assertEqual(self._class.classroom, 'MOCAP')
self.assertEqual(self._class.schedule, '46M34')
self.assertEqual(self._class.days, ['Quarta-Feira 10:00 às 11:50', 'Sexta-Feira 10:00 às 11:50'])
self.assertEqual(self._class.days, [
'Quarta-Feira 10:00 às 11:50', 'Sexta-Feira 10:00 às 11:50'])
self.assertEqual(self._class._class, "1")
self.assertEqual(self._class.discipline, self.discipline)

Expand All @@ -46,9 +52,259 @@ def test_create_department(self):

def test_str_method_of_discipline(self):
self.assertEqual(str(self.discipline), self.discipline.name)

def test_str_method_of_class(self):
self.assertEqual(str(self._class), self._class._class)

def test_str_method_of_department(self):
self.assertEqual(str(self.department), self.department.code)


class TestSearchAPI(APITestCase):
def setUp(self) -> None:
self.department = get_or_create_department(
code='518', year='2023', period='2')
self.discipline_1 = get_or_create_discipline(
name='CÁLCULO 1', code='MAT518', department=self.department)
self.discipline_2 = get_or_create_discipline(
name='CÁLCULO 2', code='MAT519', department=self.department)
self._class_1 = create_class(workload=60, teachers=['RICARDO FRAGELLI'], classroom='MOCAP', schedule='46M34',
days=['Quarta-Feira 10:00 às 11:50', 'Sexta-Feira 10:00 às 11:50'], _class="1", discipline=self.discipline_1)
self._class_2 = create_class(workload=60, teachers=['VINICIUS RISPOLI'], classroom='S1', schedule='24M34', days=[
'Segunda-Feira 10:00 às 11:50', 'Quarta-Feira 10:00 às 11:50'], _class="1", discipline=self.discipline_2)

def test_with_complete_correct_search(self):
"""
Testa a busca por disciplinas com o nome completo e todos os parâmetros corretos
Testes:
- Status code (200 OK)
- Quantidade de disciplinas retornadas
- Código do departamento
- Nome da disciplina
- Professores da disciplina
"""
response_for_discipline_1 = self.client.get(
'/courses/?search=calculo+1&year=2023&period=2')
response_for_discipline_2 = self.client.get(
'/courses/?search=calculo+2&year=2023&period=2')
content_1 = json.loads(response_for_discipline_1.content)
content_2 = json.loads(response_for_discipline_2.content)

# Testes da disciplina 1
self.assertEqual(response_for_discipline_1.status_code, 200)
self.assertEqual(len(content_1), 1)
self.assertEqual(content_1[0]['department']
['code'], self.department.code)
self.assertEqual(content_1[0]['name'], self.discipline_1.name)
self.assertEqual(content_1[0]['classes'][0]
['teachers'], self._class_1.teachers)

# Testes da disciplina 2
self.assertEqual(response_for_discipline_2.status_code, 200)
self.assertEqual(len(content_2), 1)
self.assertEqual(content_2[0]['department']
['code'], self.department.code)
self.assertEqual(content_2[0]['name'], self.discipline_2.name)
self.assertEqual(content_2[0]['classes'][0]
['teachers'], self._class_2.teachers)

def test_with_incomplete_correct_search(self):
"""
Testa a busca por disciplinas com nome incompleto e todos os parâmetros corretos
Testes:
- Status code (200 OK)
- Quantidade de disciplinas retornadas
- Código do departamento
- Nome da disciplina
- Professores da disciplina
"""
response_for_disciplines = self.client.get(
'/courses/?search=calculo&year=2023&period=2')
content = json.loads(response_for_disciplines.content)

# Testes da disciplina 1
self.assertEqual(response_for_disciplines.status_code, 200)
self.assertEqual(len(content), 2)
self.assertEqual(content[0]['department']
['code'], self.department.code)
self.assertEqual(content[0]['name'], self.discipline_1.name)
self.assertEqual(content[0]['classes'][0]
['teachers'], self._class_1.teachers)
# Testes da disciplina 2
self.assertEqual(content[1]['department']
['code'], self.department.code)
self.assertEqual(content[1]['name'], self.discipline_2.name)
self.assertEqual(content[1]['classes'][0]
['teachers'], self._class_2.teachers)

def test_with_code_search(self):
"""
Testa a busca por disciplinas através do código da matéria
Testes:
- Status code (200 OK)
- Quantidade de disciplinas retornadas
"""

response_for_discipline_1 = self.client.get(
'/courses/?search=MAT518&year=2023&period=2')
response_for_discipline_2 = self.client.get(
'/courses/?search=MAT519&year=2023&period=2')
content_1 = json.loads(response_for_discipline_1.content)
content_2 = json.loads(response_for_discipline_2.content)

# Testes da disciplina 1
self.assertEqual(response_for_discipline_1.status_code, 200)
self.assertEqual(len(content_1), 1)

# Testes da disciplina 2
self.assertEqual(response_for_discipline_2.status_code, 200)
self.assertEqual(len(content_2), 1)

def test_with_code_search_spaced(self):
"""
Testa a busca por disciplinas através do código da matéria com espaços
Testes:
- Status code (200 OK)
- Quantidade de disciplinas retornadas
"""

response_for_discipline_1 = self.client.get(
'/courses/?search=MAT+518&year=2023&period=2')
response_for_discipline_2 = self.client.get(
'/courses/?search=MAT+519&year=2023&period=2')
content_1 = json.loads(response_for_discipline_1.content)
content_2 = json.loads(response_for_discipline_2.content)

# Testes da disciplina 1
self.assertEqual(response_for_discipline_1.status_code, 200)
self.assertEqual(len(content_1), 1)

# Testes da disciplina 2
self.assertEqual(response_for_discipline_2.status_code, 200)
self.assertEqual(len(content_2), 1)

def test_with_bad_url_search_missing_year(self):
"""
Testa a busca por disciplinas sem os parâmetros de ano, como None e como string vazia
Testes:
- Status code (400 BAD REQUEST)
- Quantidade de resposta no JSON
- Mensagem de erro
"""
response_1 = self.client.get(
'/courses/?search=calculo&')
response_2 = self.client.get(
'/courses/?search=calculo&year=&period=2')
content_1 = json.loads(response_1.content)
content_2 = json.loads(response_2.content)

# Testes com ano None
self.assertEqual(response_1.status_code, 400)
self.assertEqual(len(content_1), 1)
self.assertEqual(content_1['errors'], ERROR_MESSAGE)

# Testes com ano string vazia
self.assertEqual(response_2.status_code, 400)
self.assertEqual(len(content_2), 1)
self.assertEqual(content_2['errors'], ERROR_MESSAGE)

def test_with_bad_url_search_missing_period(self):
"""
Testa a busca por disciplinas sem os parâmetros de período, como None e como string vazia
Testes:
- Status code (400 BAD REQUEST)
- Quantidade de resposta no JSON
- Mensagem de erro
"""
response_1 = self.client.get(
'/courses/?search=calculo&year=2023')
response_2 = self.client.get(
'/courses/?search=calculo&year=2023&period=')
content_1 = json.loads(response_1.content)
content_2 = json.loads(response_2.content)

# Testes com período None
self.assertEqual(response_1.status_code, 400)
self.assertEqual(len(content_1), 1)
self.assertEqual(content_1['errors'], ERROR_MESSAGE)

# Testes com período string vazia
self.assertEqual(response_2.status_code, 400)
self.assertEqual(len(content_2), 1)
self.assertEqual(content_2['errors'], ERROR_MESSAGE)

def test_with_bad_url_search_missing_name(self):
"""
Testa a busca por disciplinas sem os parâmetros de nome, como None e como string vazia
Testes:
- Status code (400 BAD REQUEST)
- Quantidade de resposta no JSON
- Mensagem de erro
"""
response_1 = self.client.get(
'/courses/?year=2023&period=2')
response_2 = self.client.get(
'/courses/?search=&year=2023&period=2')
content_1 = json.loads(response_1.content)
content_2 = json.loads(response_2.content)

# Testes com nome None
self.assertEqual(response_1.status_code, 400)
self.assertEqual(len(content_1), 1)
self.assertEqual(content_1['errors'], ERROR_MESSAGE)

# Testes com nome string vazia
self.assertEqual(response_2.status_code, 400)
self.assertEqual(len(content_2), 1)
self.assertEqual(content_2['errors'], ERROR_MESSAGE)

def test_with_bad_url_search_missing_all_parameters(self):
"""
Testa a busca por disciplinas sem nenhum parâmetro, como None e como string vazia
Testes:
- Status code (400 BAD REQUEST)
- Quantidade de resposta no JSON
- Mensagem de erro
"""
response_1 = self.client.get('/courses/')
response_2 = self.client.get('/courses/?search=&year=&period=')
content_1 = json.loads(response_1.content)
content_2 = json.loads(response_2.content)

# Testes com todos os parâmetros None
self.assertEqual(response_1.status_code, 400)
self.assertEqual(len(content_1), 1)
self.assertEqual(content_1['errors'], ERROR_MESSAGE)

# Testes com todos os parâmetros string vazia
self.assertEqual(response_2.status_code, 400)
self.assertEqual(len(content_2), 1)
self.assertEqual(content_2['errors'], ERROR_MESSAGE)

def test_with_only_spaces(self):
"""
Testa a busca por disciplinas com apenas espaços nos parâmetros
Testes:
- Status code (400 BAD REQUEST)
"""

response_1 = self.client.get('/courses/?search= &year=2023&period=2')
response_2 = self.client.get('/courses/?search=calculo&year= &period=2')
response_3 = self.client.get('/courses/?search=calculo&year=2023&period= ')
content_1 = json.loads(response_1.content)
content_2 = json.loads(response_2.content)
content_3 = json.loads(response_3.content)

self.assertEqual(response_1.status_code, 400)
self.assertEqual(len(content_1), 1)
self.assertEqual(content_1['errors'], ERROR_MESSAGE)

self.assertEqual(response_2.status_code, 400)
self.assertEqual(len(content_2), 1)
self.assertEqual(content_2['errors'], ERROR_MESSAGE)

self.assertEqual(response_3.status_code, 400)
self.assertEqual(len(content_3), 1)
self.assertEqual(content_3['errors'], ERROR_MESSAGE)
8 changes: 8 additions & 0 deletions api/api/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from django.urls import path
from api import views

app_name = 'api'

urlpatterns = [
path('', views.Search.as_view(), name="search")
]
Loading

0 comments on commit f03986b

Please sign in to comment.