diff --git a/decide/census/export/README.md b/decide/census/export/README.md
new file mode 100644
index 0000000000..ed4bee0cb4
--- /dev/null
+++ b/decide/census/export/README.md
@@ -0,0 +1,4 @@
+Export Folder
+================================
+
+Este directorio incluirá todos los censos que exportes.
diff --git a/decide/census/templates/census_export.html b/decide/census/templates/census_export.html
new file mode 100644
index 0000000000..6fe6cb45af
--- /dev/null
+++ b/decide/census/templates/census_export.html
@@ -0,0 +1,62 @@
+{% extends "base.html" %}
+{% load i18n static %}
+
+{% block extrahead %}
+
+
+
+
+{% endblock %}
+
+
+{% block content %}
+
+
+
In this view you can manage the census by exporting the users participating in a voting
+
+
+
+
+
+
In this view you can manage the census by importing users participating in a voting
+
+
+
+
{% if remove %}
+ {% elif export %}
+
+ {% elif import %}
+
{% else %}
{% endif %}
diff --git a/decide/census/tests.py b/decide/census/tests.py
index 097b4fda89..6332a5e4b4 100644
--- a/decide/census/tests.py
+++ b/decide/census/tests.py
@@ -1,16 +1,26 @@
import random
+
+#Added AnonymousUser
from django.contrib.auth.models import User, AnonymousUser
+
+#Added RequestFactory to handle the request.user.is_staff check in the views
from django.test import RequestFactory
+#Added these Middleware to simulate the messages, since RequestFactory doesn't do it
+from django.contrib.messages.middleware import MessageMiddleware
+from django.contrib.sessions.middleware import SessionMiddleware
+
from rest_framework.test import APIClient
from .models import Census
+#Added the necessary models
from voting.models import Voting, Question, QuestionOption
from base import mods
from base.tests import BaseTestCase
-from .views import add_to_census, remove_from_census
+import os
+
+from .views import exporting_census, importing_census, add_to_census, remove_from_census
+import csv
-from django.contrib.messages.middleware import MessageMiddleware
-from django.contrib.sessions.middleware import SessionMiddleware
class CensusTestCase(BaseTestCase):
@@ -187,4 +197,119 @@ def test_delete_census_from_gui(self):
request.user = self.user
response = remove_from_census(request)
self.assertEqual(response.status_code, 200)
- self.assertEqual(existing_censuss, Census.objects.count())
\ No newline at end of file
+ self.assertEqual(existing_censuss, Census.objects.count())
+
+class CensusExportImport(BaseTestCase):
+ def setUp(self):
+ super().setUp()
+
+ self.q = Question(desc='test question')
+ self.q.save()
+ for i in range(5):
+ self.opt = QuestionOption(question=self.q, option='option {}'.format(i+1))
+ self.opt.save()
+ self.v = Voting(name='test voting', question=self.q)
+ self.v.save()
+
+ self.voter = User(username='test_user')
+ self.voter.save()
+
+ self.census = Census(voting_id=self.v.id, voter_id=self.voter.id)
+ self.census.save()
+
+ self.factory = RequestFactory()
+ self.sm = SessionMiddleware()
+ self.mm = MessageMiddleware()
+
+ def tearDown(self):
+ super().tearDown()
+ self.census = None
+
+ self.q = None
+ self.opt = None
+
+ if os.path.exists('./census/export/export_' + self.v.name + '.csv'):
+ os.remove('./census/export/export_' + self.v.name + '.csv')
+
+ if os.path.exists('./census/export/import_test.csv'):
+ os.remove('./census/export/import_test.csv')
+
+ self.v = None
+ self.voter = None
+ self.factory = None
+ self.sm = None
+ self.mm = None
+
+ self.file = None
+
+ def test_export_census(self):
+ self.user = AnonymousUser()
+ data = {'voting-select': self.v.id}
+ request = self.factory.post('/census/export/exporting_census/', data, format='json')
+ self.sm.process_request(request)
+ self.mm.process_request(request)
+ request.user = self.user
+ response = exporting_census(request)
+ self.assertEqual(response.status_code, 401)
+ self.assertFalse(os.path.exists('./census/export/export_' + self.v.name + '.csv'))
+
+ user_admin = User.objects.get(username="admin")
+ self.user = user_admin
+ data = {'voting-select': self.v.id}
+ request = self.factory.post('/census/export/exporting_census/', data, format='json')
+ self.sm.process_request(request)
+ self.mm.process_request(request)
+ request.user = self.user
+ response = exporting_census(request)
+ self.assertEqual(response.status_code, 302)
+ self.assertTrue(os.path.exists('./census/export/export_' + self.v.name + '.csv'))
+ with open('./census/export/export_' + self.v.name + '.csv', 'r') as csvfile:
+ self.assertEqual(2, len(csvfile.readlines()))
+
+
+ def generate_import_csv(self):
+ #Creates a csv file with a row containing the user admin
+ try:
+ user_admin = User.objects.get(username="admin")
+ self.file = open('./census/export/import_test.csv', 'w', encoding='UTF8')
+ wr = csv.writer(self.file)
+ header = ['username', 'first_name', 'last_name', 'email']
+ wr.writerow(header)
+ row = [user_admin.username,'','','']
+ wr.writerow(row)
+ finally:
+ self.file.close()
+
+ return self.file
+
+ def test_import_census(self):
+ #Gets the csv file with the user admin to import it into the census created in the set up method
+ import_csv = self.generate_import_csv()
+ file_path = import_csv.name
+
+ f = open(file_path, "r")
+
+ self.user = AnonymousUser()
+ data = {'voting-select': self.v.id, 'csv-file': f}
+ request = self.factory.post('/census/import/importing_census/', data, format='json')
+ self.sm.process_request(request)
+ self.mm.process_request(request)
+ request.user = self.user
+ response = importing_census(request)
+ self.assertEqual(response.status_code, 401)
+
+ f.close()
+ f = open(file_path, "r")
+
+ user_admin = User.objects.get(username="admin")
+ self.user = user_admin
+ data = {'voting-select': self.v.id, 'csv-file': f}
+ request = self.factory.post('/census/import/importing_census/', data, format='json')
+ self.sm.process_request(request)
+ self.mm.process_request(request)
+ request.user = self.user
+ response = importing_census(request)
+ self.assertEqual(response.status_code, 302)
+ self.assertTrue(Census.objects.all().filter(voting_id=self.v.id,voter_id=user_admin.id).exists())
+
+ f.close()
diff --git a/decide/census/urls.py b/decide/census/urls.py
index 41cc26e1d7..4c016b195a 100644
--- a/decide/census/urls.py
+++ b/decide/census/urls.py
@@ -8,5 +8,9 @@
path('add/', views.census_add, name='census_add'),
path('add/add_to_census', views.add_to_census),
path('remove/', views.census_remove, name='census_remove'),
- path('remove/remove_from_census', views.remove_from_census)
+ path('remove/remove_from_census', views.remove_from_census),
+ path('export/', views.export_census),
+ path('export/exporting_census/', views.exporting_census),
+ path('import/', views.import_census),
+ path('import/importing_census/', views.importing_census)
]
diff --git a/decide/census/views.py b/decide/census/views.py
index d8b5cff366..60125c3578 100644
--- a/decide/census/views.py
+++ b/decide/census/views.py
@@ -10,6 +10,7 @@
HTTP_409_CONFLICT as ST_409
)
from django.http import HttpResponse
+from django.http import HttpResponseRedirect
from django.template import loader
from voting.models import Voting
from django.contrib.auth.models import User
@@ -17,7 +18,7 @@
from base.perms import UserIsStaff
from .models import Census
-
+import csv
class CensusCreate(generics.ListCreateAPIView):
permission_classes = (UserIsStaff,)
@@ -71,7 +72,7 @@ def census_add(request):
template = loader.get_template("result_page.html")
messages.error(request, "You must be a staff member to access this page")
return HttpResponse(template.render({}, request), status=ST_401)
-
+
def add_to_census(request):
template = loader.get_template("result_page.html")
@@ -99,6 +100,7 @@ def add_to_census(request):
return HttpResponse(template.render({}, request), status=ST_401)
+
def census_remove(request):
if request.user.is_staff:
template = loader.get_template("census_remove.html")
@@ -139,5 +141,91 @@ def remove_from_census(request):
else:
messages.error(request, "You must be a staff member to access this page")
return HttpResponse(template.render({'remove': True}, request), status=ST_401)
+
+
+
+def export_census(request):
+ if request.user.is_staff:
+ template = loader.get_template("census_export.html")
+ votings = Voting.objects.all()
+ context = {
+ 'votings': votings,
+ }
+ return HttpResponse(template.render(context, request))
+ else:
+ template = loader.get_template("result_page.html")
+ messages.error(request, "You must be a staff member to access this page")
+ return HttpResponse(template.render({'export': True}, request), status=ST_401)
+
+
+
+def exporting_census(request):
+ if request.user.is_staff:
+ voting_id = request.POST['voting-select']
+ censuss_to_export = Census.objects.all().filter(voting_id=voting_id)
+ voting = Voting.objects.get(id=voting_id)
+
+ with open('./census/export/export_' + voting.name + '.csv', 'w', encoding='UTF8', newline='') as csvfile:
+ exportwriter = csv.writer(csvfile, delimiter=',')
+ header = ['username', 'first_name', 'last_name', 'email']
+ exportwriter.writerow(header)
+
+ for census in censuss_to_export:
+ voter = User.objects.get(id=census.voter_id)
+ row = [voter.username, voter.first_name, voter.last_name, voter.email]
+ exportwriter.writerow(row)
+
+
+
+ messages.success(request, "Census was exported correctly")
+ return HttpResponseRedirect('/census/export/')
+
+ else:
+ template = loader.get_template("result_page.html")
+ messages.error(request, "You must be a staff member to access this page")
+ return HttpResponse(template.render({'export': True}, request), status=ST_401)
+
+
+def import_census(request):
+ if request.user.is_staff:
+ template = loader.get_template("census_import.html")
+ votings = Voting.objects.all()
+ context = {
+ 'votings': votings,
+ }
+ return HttpResponse(template.render(context, request))
+ else:
+ template = loader.get_template("result_page.html")
+ messages.error(request, "You must be a staff member to access this page")
+ return HttpResponse(template.render({'export': True}, request), status=ST_401)
+
+
+
+def importing_census(request):
+ if request.user.is_staff:
+ voting_id = request.POST['voting-select']
+ csvfile = request.FILES['csv-file']
+
+ csvfile.readline()
+ lines = csvfile.readlines()
+
+ for line in lines:
+ fields = line.decode("utf-8").split(',')
+ voter_exists = User.objects.all().filter(username=fields[0].strip()).exists()
+ if voter_exists:
+ voter = User.objects.get(username=fields[0].strip())
+ already_exists = Census.objects.all().filter(voting_id=voting_id, voter_id=voter.id).exists()
+ if not already_exists:
+ census = Census(voting_id=voting_id,voter_id=voter.id)
+ census.save()
+
+
+ messages.success(request, "Census was imported correctly")
+ return HttpResponseRedirect('/census/import/')
+
+ else:
+ template = loader.get_template("result_page.html")
+ messages.error(request, "You must be a staff member to access this page")
+ return HttpResponse(template.render({'import': True}, request), status=ST_401)