Skip to content

Commit

Permalink
Merge branch 'visualizer-luibelzan' into temporal
Browse files Browse the repository at this point in the history
  • Loading branch information
luibelzan authored Jan 6, 2022
2 parents 838aa1d + 47de106 commit d0ceb04
Show file tree
Hide file tree
Showing 30 changed files with 1,300 additions and 63 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,5 @@ ENV/
.mypy_cache/

.vagrant

requirements.txt
4 changes: 4 additions & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
% prepara el repositorio para su despliegue.
release: sh -c 'cd decide && python manage.py migrate'
% especifica el comando para lanzar Decide
web: sh -c 'cd decide && gunicorn decide.wsgi --log-file -'
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
[![Build Status](https://travis-ci.com/wadobo/decide.svg?branch=master)](https://travis-ci.com/wadobo/decide) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/94a85eaa0e974c71af6899ea3b0d27e0)](https://www.codacy.com/app/Wadobo/decide?utm_source=github.com&utm_medium=referral&utm_content=wadobo/decide&utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Coverage/94a85eaa0e974c71af6899ea3b0d27e0)](https://www.codacy.com/app/Wadobo/decide?utm_source=github.com&utm_medium=referral&utm_content=wadobo/decide&utm_campaign=Badge_Coverage)
[![Python application](https://github.com/Penyagolosa-3/Decide/actions/workflows/django.yml/badge.svg?branch=develop)](https://github.com/Penyagolosa-3/Decide/actions/workflows/django.yml)
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/06c453c2aba8409d8c5fbf354704fd65)](https://www.codacy.com/gh/Penyagolosa-3/Decide/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Penyagolosa-3/Decide&utm_campaign=Badge_Grade)
[![Codacy Badge](https://app.codacy.com/project/badge/Coverage/06c453c2aba8409d8c5fbf354704fd65)](https://www.codacy.com/gh/Penyagolosa-3/Decide/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Penyagolosa-3/Decide&utm_campaign=Badge_Coverage)

[![Python application](https://github.com/Decide-part-Penyagolosa/Decide/actions/workflows/django.yml/badge.svg?branch=deploy)](https://github.com/Decide-part-Penyagolosa/Decide/actions/workflows/django.yml)

Plataforma voto electrónico educativa
=====================================
Expand Down
4 changes: 1 addition & 3 deletions decide/authentication/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
from django.db import models

# Create your models here.
from django.db import models
10 changes: 10 additions & 0 deletions decide/authentication/templates/login.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{% load socialaccount %}
{% providers_media_js %}

<a class="fab fa-microsoft size_social text-info" aria-hidden="true" href="{% provider_login_url "microsoft" %}">microsoft</a>
<a class="fab fa-google size_social text-info" aria-hidden="true" href="{% provider_login_url "google" %}">Google</a>


{% if user.is_authenticated %}
estoy autenticado
{% endif %}
5 changes: 4 additions & 1 deletion decide/authentication/urls.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
from django.urls import include, path
from rest_framework.authtoken.views import obtain_auth_token
from django.views.generic import TemplateView
from django.contrib import admin

from .views import GetUserView, LogoutView, RegisterView


urlpatterns = [
path('login/', obtain_auth_token),
path('logout/', LogoutView.as_view()),
path('getuser/', GetUserView.as_view()),
path('register/', RegisterView.as_view()),
path('signin/',TemplateView.as_view(template_name="login.html")),
path('accounts/',include('allauth.urls')),
]
2 changes: 1 addition & 1 deletion decide/base/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def setUp(self):
user_noadmin.set_password('qwerty')
user_noadmin.save()

user_admin = User(username='admin', is_staff=True)
user_admin = User(username='admin', is_staff=True, is_superuser=True)
user_admin.set_password('qwerty')
user_admin.save()

Expand Down
24 changes: 24 additions & 0 deletions decide/booth/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Generated by Django 2.0 on 2021-12-17 23:56

from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

initial = True

dependencies = [
('voting', '0003_auto_20180605_0842'),
]

operations = [
migrations.CreateModel(
name='VotingCount',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('option', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='voting.QuestionOption')),
('voting', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='voting.Voting')),
],
),
]
19 changes: 19 additions & 0 deletions decide/booth/migrations/0002_votingcount_created_at.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 2.0 on 2021-12-20 16:50

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

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

operations = [
migrations.AddField(
model_name='votingcount',
name='created_at',
field=models.DateTimeField(default=django.utils.timezone.now),
),
]
8 changes: 8 additions & 0 deletions decide/booth/models.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
from django.db import models
from django.utils import timezone

from voting.models import Voting, QuestionOption

# Create your models here.

class VotingCount(models.Model):
voting = models.ForeignKey(Voting, on_delete=models.CASCADE)
option = models.ForeignKey(QuestionOption, on_delete=models.CASCADE)
created_at = models.DateTimeField(default=timezone.now)
9 changes: 9 additions & 0 deletions decide/booth/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from rest_framework import serializers

from .models import VotingCount


class VotingCountSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = VotingCount
fields = ('id', 'voting_id', 'option_id', 'created_at')
12 changes: 11 additions & 1 deletion decide/booth/templates/booth/booth.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<h1>[[ voting.id ]] - [[ voting.name ]]</h1>

<!-- Register -->

<b-form @submit="onSubmitLogin" v-if="signup">
<b-form-group label="{% trans "Username" %}" label-for="username">
<b-form-input
Expand Down Expand Up @@ -87,6 +88,9 @@ <h2>[[ voting.question.desc ]]</h2>

<script>
var voting = {{voting|safe}};

console.log('{% url "gateway" "authentication" "/login/" %}');

var app = new Vue({
delimiters: ['[[', ']]'],
el: '#app-booth',
Expand Down Expand Up @@ -193,13 +197,19 @@ <h2>[[ voting.question.desc ]]</h2>
voter: this.user.id,
token: this.token
}
this.postData("{% url "gateway" "store" "/" %}", data)
this.postData('{% url "gateway" "booth" "/votingCount/" %}', {
option: this.selected.toString(),
voting: data.voting
}).then(() => {
this.postData("{% url "gateway" "store" "/" %}", data)
.then(data => {
this.showAlert("success", '{% trans "Conglatulations. Your vote has been sent" %}');
})
.catch(error => {
this.showAlert("danger", '{% trans "Error: " %}' + error);
});
});
},
showAlert(lvl, msg) {
this.alertLvl = lvl;
Expand Down
77 changes: 76 additions & 1 deletion decide/booth/tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,78 @@
from django.test import TestCase

# Create your tests here.
from rest_framework.test import APIClient
from rest_framework.test import APITestCase

from base import mods

from voting.models import Voting, QuestionOption, Question

from .models import VotingCount

from django.utils import timezone

class BoothTestCase(APITestCase):

def setUp(self):
self.client = APIClient()
mods.mock_query(self.client)

question = Question(desc='qwerty')
question.save()

for i in range(5):
self.questionOption = QuestionOption(question=question, option='option {}'.format(i+1))
self.questionOption.save()

self.voting = Voting(name='test voting', question=question)
self.voting.save()

self.votingCount = VotingCount(voting=self.voting, option=self.questionOption)
self.votingCount.save()

def tearDown(self):
self.client = None

# Descripción: Añade una nueva votación a la tabla de Recuento de votaciones
# Entrada:
## option: id de la opción votada
## voting: id de la votación
# Salida: ninguna
def test_addVotingCount(self):
# Información que se debe insertar vía POST para una opción y votación
data = {
'option': self.questionOption.id,
'voting': self.voting.id
}

response = self.client.post('/booth/votingCount/', data, format='json')

# Si en el endpoint se recibe id de opción válido, e id de votación, la respuesta http debería ser 200
self.assertEqual(response.status_code, 200)

# Descripción: Prueba la recolección de recuentos de votos en vivo a través de endpoint
# Entrada:
## id: id de la votación
# Salida: Matriz con todos los votos realizados a una votación y su opción
def test_getVotingCount(self):
expected_result = [
{
'id': self.votingCount.id,
'voting_id': self.voting.id,
'option_id': self.questionOption.id
}
]

# Se solicita el recuento de votos a la url añadiendo el id de la votación
response = self.client.get('/booth/votingCount/'+str(self.voting.id)+'/', format='json')


# Si en el endpoint se recibe id de opción y de votación, la respuesta http debería ser 200
self.assertEqual(response.status_code, 200)

# Pasamos la respuesta a json y comparamos con la esperada
values = response.json()['votingCount']
for val in values:
val.pop('created_at')

self.assertEqual(values, expected_result)
7 changes: 5 additions & 2 deletions decide/booth/urls.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
from django.urls import path
from .views import BoothView

from .views import BoothView, BoothVotingCountView
from . import views

urlpatterns = [
path('<int:voting_id>/', BoothView.as_view()),
path('voting', views.votings),
path('voting', views.votings),
path('votingCount/', BoothVotingCountView.as_view()),
path('votingCount/<int:voting_id>/', BoothVotingCountView.as_view())
]
55 changes: 55 additions & 0 deletions decide/booth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,69 @@
from voting.models import Voting
from django.shortcuts import render, redirect

from rest_framework.views import APIView
from rest_framework.response import Response

from .models import VotingCount
from voting.models import Voting, QuestionOption
from census.models import Census
from store.models import Vote

from .serializers import VotingCountSerializer

from base import mods

class BoothVotingCountView(APIView):
# Descripción: endpoint que inserta un voto en el recuento de votos en vivo de una votación
# HTTP method: POST
# Entrada:
## option: id de la opción votada
## voting: id de la votación
# Salida: ninguna
def post(self, request):
for data in ['option', 'voting']:
if not data in request.data:
return Response({}, status=status.HTTP_400_BAD_REQUEST)

voting_id = int(request.data.get('voting'))

# Comprobamos que no exista una votación anterior del mismo usuario
votes = Vote.objects.filter(voting_id=voting_id, voter_id=request.user.id)

if len(votes)==0:
voting = Voting.objects.get(id=voting_id)
option = QuestionOption.objects.get(id=int(request.data.get('option')))

votingCount = VotingCount(voting = voting, option = option)
votingCount.save()
else:
print('El usuario ya ha votado antes. Omitiendo voto')

return Response({})

# Descripción: endpoint que devuelve el recuento de votos en vivo para una votación
# HTTP method: GET
# Entrada:
## id: id de la votación
# Salida: matriz con el fetch de los votos realizados a una votación
def get(self, request, voting_id):
votingCount = VotingCount.objects.filter(voting_id=voting_id)

census = Census.objects.filter(voting_id=voting_id)

votingCount.census = len(census)

return Response({'votingCount': VotingCountSerializer(votingCount, many=True).data, 'census': len(census)})


# TODO: check permissions and census
class BoothView(TemplateView):
template_name = 'booth/booth.html'

def post(self, request, *args, **kwargs):
print(self.request.POST)
return HttpResponse()

def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
vid = kwargs.get('voting_id', 0)
Expand Down
2 changes: 1 addition & 1 deletion decide/census/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Generated by Django 2.0 on 2018-04-08 17:16
# Generated by Django 2.0 on 2021-12-17 23:50

from django.db import migrations, models

Expand Down
Loading

0 comments on commit d0ceb04

Please sign in to comment.