diff --git a/.gitignore b/.gitignore index b823e313b4..970c89f17b 100644 --- a/.gitignore +++ b/.gitignore @@ -24,7 +24,7 @@ wheels/ *.egg-info/ .installed.cfg *.egg - +decide-enviroment/ # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. @@ -45,6 +45,8 @@ nosetests.xml coverage.xml *.cover .hypothesis/ +loadtest/gen_census.py +loadtest/locustfile.py # Translations *.mo diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..e191e8ed8c --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Python: Django", + "type": "python", + "request": "launch", + "program": "${workspaceFolder}/decide/manage.py", + "args": [ + "runserver", + "0.0.0.0:8000" + ], + "django": true, + "justMyCode": false, + } + ] +} \ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000000..f53429927d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,84 @@ +pipeline { + agent { docker { image 'python:3.7.2' } } + + stages { + stage('Build Master') { + when { + branch 'master' + } + steps { + sh ''' + pip install -r requirements.txt + + cd decide + ./manage.py test -v 2 + ''' + } + } + + stage('Deploy Master') { + when { + branch 'master' + } + steps { + /* Llamamos a Heroku y a darle caña */ + } + } + + stage('Build Develop') { + when { + branch 'develop' + } + steps { + sh ''' + pip install -r requirements.txt + + cd decide + ./manage.py test -v 2 + ''' + } + } + + stage('Build G1') { + when { + branch 'G1' + } + steps { + sh ''' + pip install -r requirements.txt + + cd decide + ./manage.py test authentication -v 2 + ''' + } + } + + stage('Build G2') { + when { + branch 'G2' + } + steps { + sh ''' + pip install -r requirements.txt + + cd decide + ./manage.py test booth -v 2 + ''' + } + } + + stage('Build G3') { + when { + branch 'G3' + } + steps { + sh ''' + pip install -r requirements.txt + + cd decide + ./manage.py test voting -v 2 + ''' + } + } + } +} diff --git a/Procfile b/Procfile new file mode 100644 index 0000000000..818fef7fe3 --- /dev/null +++ b/Procfile @@ -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 -' diff --git a/README.md b/README.md index 83d0a57e27..3cbb53640d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ [![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) - +Prueba de commit 7 Plataforma voto electrónico educativa -===================================== El objetivo de este proyecto es implementar una plataforma de voto electrónico seguro, que cumpla una serie de garantías básicas, como la diff --git a/decide/decide/settings.py b/decide/decide/settings.py index 1d22b67324..399527ea8a 100644 --- a/decide/decide/settings.py +++ b/decide/decide/settings.py @@ -1,11 +1,8 @@ """ Django settings for decide project. - Generated by 'django-admin startproject' using Django 2.0. - For more information on this file, see https://docs.djangoproject.com/en/2.0/topics/settings/ - For the full list of settings and their values, see https://docs.djangoproject.com/en/2.0/ref/settings/ """ @@ -179,4 +176,6 @@ vars()[k] = v + INSTALLED_APPS = INSTALLED_APPS + MODULES + diff --git a/decide/local_settings.example.py b/decide/local_settings.example.py deleted file mode 100644 index 41db563a5a..0000000000 --- a/decide/local_settings.example.py +++ /dev/null @@ -1,41 +0,0 @@ -ALLOWED_HOSTS = ["*"] - -# Modules in use, commented modules that you won't use -MODULES = [ - 'authentication', - 'base', - 'booth', - 'census', - 'mixnet', - 'postproc', - 'store', - 'visualizer', - 'voting', -] - -APIS = { - 'authentication': 'http://10.5.0.1:8000', - 'base': 'http://10.5.0.1:8000', - 'booth': 'http://10.5.0.1:8000', - 'census': 'http://10.5.0.1:8000', - 'mixnet': 'http://10.5.0.1:8000', - 'postproc': 'http://10.5.0.1:8000', - 'store': 'http://10.5.0.1:8000', - 'visualizer': 'http://10.5.0.1:8000', - 'voting': 'http://10.5.0.1:8000', -} - -BASEURL = 'http://10.5.0.1:8000' - -DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql', - 'NAME': 'postgres', - 'USER': 'postgres', - 'HOST': 'db', - 'PORT': '5432', - } -} - -# number of bits for the key, all auths should use the same number of bits -KEYBITS = 256 diff --git a/decide/postproc/tests.py b/decide/postproc/tests.py index 1a6a27e86c..2a48f0bd41 100644 --- a/decide/postproc/tests.py +++ b/decide/postproc/tests.py @@ -15,6 +15,7 @@ def setUp(self): def tearDown(self): self.client = None + def test_identity(self): data = { 'type': 'IDENTITY', @@ -42,3 +43,302 @@ def test_identity(self): values = response.json() self.assertEqual(values, expected_result) + + + +#test de la función de postproc Bipartisanship, +#comprueba que las dos opciones mayoritarias obtienen 25 y 15 escaños cada una + def test_bipartitanship(self): + data = { + 'type': 'BIPARTISHANSHIP', + 'numEscanyos': 40, + 'options': [ + { 'option': 'Option 1', 'number': 1, 'votes': 50 }, + { 'option': 'Option 2', 'number': 2, 'votes': 0 }, + { 'option': 'Option 3', 'number': 3, 'votes': 30 }, + { 'option': 'Option 4', 'number': 4, 'votes': 20 }, + ] + } + + expected_result = [ + { 'option': 'Option 1', 'number': 1, 'votes': 50, 'postproc': 25 }, + { 'option': 'Option 3', 'number': 3, 'votes': 30, 'postproc': 15 }, + { 'option': 'Option 4', 'number': 4, 'votes': 20, 'postproc': 0 }, + { 'option': 'Option 2', 'number': 2, 'votes': 0, 'postproc': 0 }, + ] + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + def test_hamilton(self): + data = { + 'type': 'HAMILTON', + 'options': [ + {'option':'A','number':1,'votes': 100000}, + {'option':'B', 'number':2,'votes': 80000}, + {'option':'C', 'number':3,'votes': 30000}, + {'option':'D', 'number':4,'votes': 20000} + ], 'numEscanyos': 10 + + } + + expected_result = [ + {'option':'A','number':1,'votes': 100000, 'postproc': 4}, + {'option':'B', 'number':2,'votes': 80000, 'postproc': 4}, + {'option':'C', 'number':3,'votes': 30000, 'postproc': 1}, + {'option':'D', 'number':4,'votes': 20000, 'postproc': 1} + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + + + def testHuntington(self): + data = { + 'type': 'HUNTINGTONHILL', + 'options': [ + {'option':'A','number':1,'votes': 95000}, + {'option':'B', 'number':2,'votes': 75000}, + {'option':'C', 'number':3,'votes': 25000}, + {'option':'D', 'number':4,'votes': 15000} + ], 'numEscanyos': 8 + + } + + expected_result = [ + {'option':'A','number':1,'votes': 95000,'postproc':4}, + {'option':'B', 'number':2,'votes': 75000,'postproc':3}, + {'option':'C', 'number':3,'votes': 25000,'postproc':1}, + {'option':'D', 'number':4,'votes': 15000,'postproc':0} +] + response = self.client.post('/postproc/', data, format='json') + + self.assertEqual(response.status_code, 200) + values = response.json() + + + self.assertEqual(values, expected_result) + + + def testDHont1(self): #Fácil de comprobar manualmente + data = { + 'type': 'DHONT', + 'options': [ + {'option':'Option 1','number':1,'votes': 12000}, + {'option':'Option 2','number':2,'votes': 140000}, + {'option':'Option 3','number':3,'votes': 110000}, + {'option':'Option 4','number':4,'votes': 205000}, + {'option':'Option 5','number':5,'votes': 150000}, + {'option':'Option 6','number':6,'votes': 16000} + ], + 'numEscanyos': 10 + } + + expected_result = [ + {'option':'Option 1','number':1,'votes': 12000, 'postproc': 0}, + {'option':'Option 2','number':2,'votes': 140000, 'postproc': 2}, + {'option':'Option 3','number':3,'votes': 110000, 'postproc': 2}, + {'option':'Option 4','number':4,'votes': 205000, 'postproc': 4}, + {'option':'Option 5','number':5,'votes': 150000, 'postproc': 2}, + {'option':'Option 6','number':6,'votes': 16000, 'postproc': 0} + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + + def testDHont2(self): #Votos muy igualados + data = { + 'type': 'DHONT', + 'options': [ + {'option':'Option 1','number':1,'votes': 65000}, + {'option':'Option 2','number':2,'votes': 60000}, + {'option':'Option 3','number':3,'votes': 50000}, + {'option':'Option 4','number':4,'votes': 55000}, + {'option':'Option 5','number':5,'votes': 62000}, + {'option':'Option 6','number':6,'votes': 57000}, + ], + 'numEscanyos': 10 + } + + expected_result = [ + {'option':'Option 1','number':1,'votes': 65000,'postproc': 2}, + {'option':'Option 2','number':2,'votes': 60000,'postproc': 2}, + {'option':'Option 3','number':3,'votes': 50000,'postproc': 1}, + {'option':'Option 4','number':4,'votes': 55000,'postproc': 1}, + {'option':'Option 5','number':5,'votes': 62000,'postproc': 2}, + {'option':'Option 6','number':6,'votes': 57000,'postproc': 2}, + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + + def testDHont3(self): #Votos muy desiguales + data = { + 'type': 'DHONT', + 'options': [ + {'option':'Option 1','number':1,'votes': 65000}, + {'option':'Option 2','number':2,'votes': 30000}, + {'option':'Option 3','number':3,'votes': 1500}, + {'option':'Option 4','number':4,'votes': 4500}, + {'option':'Option 5','number':5,'votes': 2000}, + ], + 'numEscanyos': 100 + } + + expected_result = [ + {'option':'Option 1','number':1,'votes': 65000,'postproc': 65}, + {'option':'Option 2','number':2,'votes': 30000,'postproc': 29}, + {'option':'Option 3','number':3,'votes': 1500,'postproc': 1}, + {'option':'Option 4','number':4,'votes': 4500,'postproc': 4}, + {'option':'Option 5','number':5,'votes': 2000,'postproc': 1}, + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + + def testDHont4(self): #Votos iguales + data = { + 'type': 'DHONT', + 'options': [ + {'option':'Option 1','number':1,'votes': 50000}, + {'option':'Option 2','number':2,'votes': 50000}, + {'option':'Option 3','number':3,'votes': 50000} + ], + 'numEscanyos': 300 + } + + expected_result = [ + {'option':'Option 1','number':1,'votes': 50000,'postproc': 100}, + {'option':'Option 2','number':2,'votes': 50000,'postproc': 100}, + {'option':'Option 3','number':3,'votes': 50000,'postproc': 100} + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + + def testDHont5(self): #Votos muy elevados + data = { + 'type': 'DHONT', + 'options': [ + {'option':'Option 1','number':1,'votes': 150150150150150}, + {'option':'Option 2','number':2,'votes': 300300300300300}, + {'option':'Option 3','number':3,'votes': 200200200200200} + ], + 'numEscanyos': 100 + } + + expected_result = [ + {'option':'Option 1','number':1,'votes': 150150150150150,'postproc': 23}, + {'option':'Option 2','number':2,'votes': 300300300300300,'postproc': 46}, + {'option':'Option 3','number':3,'votes': 200200200200200,'postproc': 31} + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + + def testDHont6(self): #Escaños elevados + data = { + 'type': 'DHONT', + 'options': [ + {'option':'Option 1','number':1,'votes': 15000}, + {'option':'Option 2','number':2,'votes': 75000}, + {'option':'Option 3','number':3,'votes': 10000}, + {'option':'Option 4','number':4,'votes': 5000}, + {'option':'Option 5','number':5,'votes': 2500}, + ], + 'numEscanyos': 900 + } + + expected_result = [ + {'option':'Option 1','number':1,'votes': 15000,'postproc': 126}, + {'option':'Option 2','number':2,'votes': 75000,'postproc': 630}, + {'option':'Option 3','number':3,'votes': 10000,'postproc': 83}, + {'option':'Option 4','number':4,'votes': 5000,'postproc': 41}, + {'option':'Option 5','number':5,'votes': 2500,'postproc': 20} + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + def test_imperiali(self): + data={ + 'type':'IMPERIALI', + 'options':[ + {'option':'A', 'number':1, 'votes':391.000}, + {'option':'B', 'number':2, 'votes':311.000}, + {'option':'C', 'number':2, 'votes':184.000}, + {'option':'D', 'number':4, 'votes':73.000}, + {'option':'E', 'number':5, 'votes':27.000}, + {'option':'F', 'number':6, 'votes':12.000}, + {'option':'G', 'number':7, 'votes':2.000}, + ], 'numEscanyos':21 + } + + expected_result=[ + {'option':'A', 'number':1, 'votes':391.000, 'postproc':9}, + {'option':'B', 'number':2, 'votes':311.000, 'postproc':7}, + {'option':'C', 'number':2, 'votes':184.000, 'postproc':4}, + {'option':'D', 'number':4, 'votes':73.000, 'postproc':1}, + {'option':'E', 'number':5, 'votes':27.000, 'postproc':0}, + {'option':'F', 'number':6, 'votes':12.000, 'postproc':0}, + {'option':'G', 'number':7, 'votes':2.000, 'postproc':0}, + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + + values = response.json() + self.assertEqual(values, expected_result) + + + def test_saintelague3(self): + data = { + 'type': 'SAINTELAGUE', + 'numEscanyos': 4, + 'options': [ + { 'option': 'Option 1', 'number': 1, 'votes': 1200 },{ 'option': 'Option 2', 'number': 2, 'votes': 700 }, + { 'option': 'Option 3', 'number': 3, 'votes': 650 },{ 'option': 'Option 4', 'number': 4, 'votes': 400 }, + { 'option': 'Option 5', 'number': 5, 'votes': 200 }, + ] + } + + expected_result = [ + { 'option': 'Option 1', 'number': 1, 'votes': 1200, 'postproc': 2 }, + { 'option': 'Option 2', 'number': 2, 'votes': 700, 'postproc': 1 },{ 'option': 'Option 3', 'number': 3, 'votes': 650, 'postproc': 1 }, + { 'option': 'Option 4', 'number': 4, 'votes': 400, 'postproc': 0 },{ 'option': 'Option 5', 'number': 5, 'votes': 200, 'postproc': 0 } + ] + + response = self.client.post('/postproc/', data, format='json') + self.assertEqual(response.status_code, 200) + values = response.json() + self.assertEqual(values, expected_result) + diff --git a/decide/postproc/views.py b/decide/postproc/views.py index f4c5de1e5f..40b9385b69 100644 --- a/decide/postproc/views.py +++ b/decide/postproc/views.py @@ -1,5 +1,8 @@ +from django.db import models from rest_framework.views import APIView from rest_framework.response import Response +import math +#import numpy as np class PostProcView(APIView): @@ -15,10 +18,240 @@ def identity(self, options): out.sort(key=lambda x: -x['postproc']) return Response(out) + + + def hamilton(self, options, numEscanyos): + #Definimos votos totales y el numero de escanyos asignados + votos = 0 + numEscanyosAsignados=0 + #Hacemos recuento de votos totales y le añadimos a cada opción otro valor llamado postproc en el que almacenaremos el numero de escanyos que le asignamos + for option in options: + option['postproc']=0 + votos += option['votes'] + #Creamos una lista vacia para introducir el resto de cada partido al anyadir los escanyos + lista=[] + if votos>0 and numEscanyos>0: + participantes = len(options) + #Recorremos las opciones y al atributo postproc que habiamos creado anteriormente le asignamos un numero de escanyos mediante + #el siguiente calculo: (NumVotosPartido*NumEscanyos)//VotosTotales. El resultado sera una division exacta + #A su vez rellenamos la lista vacia con un diccionario en el que ponemos el nombre de la opcion y el resto de la division + #Tambien vamos incrementando el numero de escanyos asignados + for option in options: + option['postproc']=(option['votes']*numEscanyos)//votos + lista.append({'number':option['number'],'votes':(option['votes']*numEscanyos)%votos}) + numEscanyosAsignados+=(option['votes']*numEscanyos)//votos + + + lista.sort(key=lambda o: o['votes'],reverse=True) + for option in lista: + i = option['number']-1 + if(numEscanyosAsignados 0 and numEscanyos > 0: + + limit = votosTotales/numEscanyos + + #Vamos a aplicar la regla rounding + rounding = limit*0.001 + lower = limit-rounding + upper = limit+rounding + + numEscanyosAsig = 0 + + while(numEscanyosAsig != numEscanyos): + + #si llegamos a aplicar rounding rule y no llegamos al numero igual de escanos, + #reseteamos de nuevo el numero de escanos asig y empezamos de nuevo + ##si no se cumple la regla reseteamos cero + + numEscanyosAsig = 0 + + for x in options: + + if(x['votes'] mediaG): + x['postproc']=(lQ+1) + else: + x['postproc']=lQ + + numEscanyosAsig += x['postproc'] + + #Rounding Rule: + + + #For a quota q, let L denote it's lower quota, U its upper quota, and G the + #geometric mean of L and U. If then round q down to L, otherwise + #round q up to U. + + if(numEscanyosAsig < numEscanyos): + + limit = lower + lower = limit-rounding + upper = limit+rounding + + else: + limit = upper + lower = limit-rounding + upper = limit+rounding + else: + for x in options: + x.update({'postproc' : 0}) + return Response(options) + + return Response(options) + + + def imperiali(self, options,numEscanyos): + votosTotales = 0 + + for i in options: + votosTotales= votosTotales+ i['votes'] + + if votosTotales>0 and numEscanyos>0: + + q=round(votosTotales/(numEscanyos+2),0) + + escanyosAsigandos=0 + for i in options: + votos= i['votes'] + escanyos=math.floor(votos/q) + i.update({'postproc': escanyos}) + escanyosAsigandos=escanyosAsigandos+i['postproc'] + + #Mientras queden escaños libre + + while(escanyosAsigandos
-

[[ voting.id ]] - [[ voting.name ]]

+

[[ voting.id ]] - [[ voting.name ]]

Votación no comenzada

Votación en curso

@@ -28,15 +28,21 @@

Resultados:

Opción - Puntuación + Escaños Votos + Método de conteo [[opt.option]] [[opt.postproc]] + + + [[opt.votes]] + [[opt.tipo]] + diff --git a/decide/voting/migrations/0004_voting_tipo.py b/decide/voting/migrations/0004_voting_tipo.py new file mode 100644 index 0000000000..d94f1c6f05 --- /dev/null +++ b/decide/voting/migrations/0004_voting_tipo.py @@ -0,0 +1,19 @@ +# Generated by Django 2.0 on 2021-12-01 20:27 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('voting', '0003_auto_20180605_0842'), + ] + + operations = [ + migrations.AddField( + model_name='voting', + name='tipo', + + field=models.CharField(choices=[('IDENTITY', 'IDENTITY'), ('HUNTINGTONHILL', 'HUNTINGTONHILL'), ('HAMILTON','HAMILTON'), ('BIPARTITANSHIP', 'BIPARTITANSHIP'),("IMPERIALI", "IMPERIALI")], default='IDENTITY', max_length=20, verbose_name='Count method'), + ), + ] diff --git a/decide/voting/migrations/0005_auto_20220103_1037.py b/decide/voting/migrations/0005_auto_20220103_1037.py new file mode 100644 index 0000000000..9b4f9a3f33 --- /dev/null +++ b/decide/voting/migrations/0005_auto_20220103_1037.py @@ -0,0 +1,23 @@ +# Generated by Django 2.0 on 2022-01-03 10:37 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('voting', '0004_voting_tipo'), + ] + + operations = [ + migrations.AddField( + model_name='voting', + name='numEscanyos', + field=models.PositiveIntegerField(blank=True, default=0, null=True, verbose_name='Seats'), + ), + migrations.AlterField( + model_name='voting', + name='tipo', + field=models.CharField(choices=[('IDENTITY', 'IDENTITY'), ('HUNTINGTONHILL', 'HUNTINGTONHILL'), ('DHONT', 'DHONT'), ('HAMILTON', 'HAMILTON'), ('BIPARTISHANSHIP', 'BIPARTISHANSHIP'), ('IMPERIALI', 'IMPERIALI'), ('SAINTELAGUE', 'SAINTELAGUE')], default='IDENTITY', max_length=20, verbose_name='Count method'), + ), + ] diff --git a/decide/voting/models.py b/decide/voting/models.py index a10ab2bcb6..fde1c82d7e 100644 --- a/decide/voting/models.py +++ b/decide/voting/models.py @@ -36,6 +36,10 @@ class Voting(models.Model): start_date = models.DateTimeField(blank=True, null=True) end_date = models.DateTimeField(blank=True, null=True) + tipo_votacion = [("IDENTITY", "IDENTITY"),("HUNTINGTONHILL", "HUNTINGTONHILL"),("DHONT","DHONT"), ('HAMILTON', 'HAMILTON'),("BIPARTISHANSHIP", "BIPARTISHANSHIP"),("IMPERIALI", "IMPERIALI"),("SAINTELAGUE","SAINTELAGUE")] + tipo = models.CharField(choices=tipo_votacion, max_length=20, default="IDENTITY", verbose_name='Count method') + numEscanyos = models.PositiveIntegerField(blank=True, null=True, default=0, verbose_name='Seats') + pub_key = models.OneToOneField(Key, related_name='voting', blank=True, null=True, on_delete=models.SET_NULL) auths = models.ManyToManyField(Auth, related_name='votings') @@ -111,9 +115,10 @@ def do_postproc(self): 'option': opt.option, 'number': opt.number, 'votes': votes + }) - data = { 'type': 'IDENTITY', 'options': opts } + data = { 'type': self.tipo, 'options': opts , 'numEscanyos': self.numEscanyos } postp = mods.post('postproc', json=data) self.postproc = postp diff --git a/decide/voting/tests.py b/decide/voting/tests.py index 063c52e1cc..5ac58daf1b 100644 --- a/decide/voting/tests.py +++ b/decide/voting/tests.py @@ -208,3 +208,16 @@ def test_update_voting(self): response = self.client.put('/voting/{}/'.format(voting.pk), data, format='json') self.assertEqual(response.status_code, 400) self.assertEqual(response.json(), 'Voting already tallied') + + data = { + 'name': 'Example', + 'desc': 'Description example', + 'tipo': 'HUNTINGTONHILL', + 'numEscanos': '10', + 'question': 'I am a ', + 'question_opt': ['cow', 'cat', 'fish'] + } + + response = self.client.post('/voting/', data, format='json') + self.assertEqual(response.status_code, 201) + \ No newline at end of file diff --git a/decide/voting/views.py b/decide/voting/views.py index 2f2227edc9..220f528240 100644 --- a/decide/voting/views.py +++ b/decide/voting/views.py @@ -29,7 +29,7 @@ def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): self.permission_classes = (UserIsStaff,) self.check_permissions(request) - for data in ['name', 'desc', 'question', 'question_opt']: + for data in ['name', 'desc', 'question', 'question_opt','tipo', 'numEscanyos']: if not data in request.data: return Response({}, status=status.HTTP_400_BAD_REQUEST) diff --git "a/documentation/Gu\303\255a para la Instalaci\303\263n de entorno de CI_CD en Rasperry Pi - Wiki de EGC.pdf" "b/documentation/Gu\303\255a para la Instalaci\303\263n de entorno de CI_CD en Rasperry Pi - Wiki de EGC.pdf" new file mode 100644 index 0000000000..eda778c82e Binary files /dev/null and "b/documentation/Gu\303\255a para la Instalaci\303\263n de entorno de CI_CD en Rasperry Pi - Wiki de EGC.pdf" differ diff --git a/loadtest/gen_census.py b/loadtest/gen_census.py index 64f5705604..be287e4cc1 100644 --- a/loadtest/gen_census.py +++ b/loadtest/gen_census.py @@ -3,9 +3,9 @@ HOST = "http://localhost:8000" -USER = "admin" -PASS = "admin" -VOTING = 1 +USER = "joszamama" +PASS = "decidepass" +VOTING = 2 def create_voters(filename): diff --git a/loadtest/locustfile.py b/loadtest/locustfile.py index 85cae8ee99..ea43844cec 100644 --- a/loadtest/locustfile.py +++ b/loadtest/locustfile.py @@ -12,7 +12,7 @@ HOST = "http://localhost:8000" -VOTING = 1 +VOTING = 2 class DefVisualizer(TaskSet): diff --git a/local_settings.py b/local_settings.py new file mode 100644 index 0000000000..03b9086637 --- /dev/null +++ b/local_settings.py @@ -0,0 +1,25 @@ +ALLOWED_HOSTS = ["*"]# Modules in use, commented modules that you won't use +MODULES = [ 'authentication', 'base', 'booth', 'census', 'mixnet', 'postproc', 'store', 'visualizer', +'voting',] +APIS = { +'authentication': 'http://localhost:8000', +'base': 'http://localhost:8000', +'booth': 'http://localhost:8000', +'census': 'http://localhost:8000', +'mixnet': 'http://localhost:8000', +'postproc': 'http://localhost:8000', +'store': 'http://localhost:8000', +'visualizer': 'http://localhost:8000', +'voting': 'http://localhost:8000', +} +BASEURL = 'http://localhost:8000' +DATABASES = { +'default': { +'ENGINE': 'django.db.backends.postgresql', +'NAME': 'decide', +'USER': 'decide', +'PASSWORD': 'decide', +'HOST': 'localhost', +'PORT': '5432', }} + +KEYBITS = 256 diff --git a/requirements.txt b/requirements.txt index d5860a1eb4..26dd1b7cdf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,8 +4,8 @@ djangorestframework==3.7.7 django-cors-headers==2.1.0 requests==2.18.4 django-filter==1.1.0 -psycopg2==2.7.4 +psycopg2==2.8.4 django-rest-swagger==2.2.0 coverage==4.5.2 django-nose==1.4.6 -jsonnet==0.12.1 +jsonnet==0.12.1 \ No newline at end of file diff --git a/runtime.txt b/runtime.txt new file mode 100644 index 0000000000..d9c98d7999 --- /dev/null +++ b/runtime.txt @@ -0,0 +1 @@ +python-3.7.12