Skip to content
Snippets Groups Projects
Commit 4e1d985a authored by Ben Adida's avatar Ben Adida
Browse files

added tinyhash to migration, fixed jsonfield to be dumpdata compatible, added...

added tinyhash to migration, fixed jsonfield to be dumpdata compatible, added quarantine support and tests for legacy data support
parent 420e05bc
No related branches found
No related tags found
No related merge requests found
......@@ -25,34 +25,45 @@ class JSONField(models.TextField):
def to_python(self, value):
"""Convert our string value to JSON after we load it from the DB"""
if value == "":
# must handle the case where the value is already ready
if self.json_type:
if isinstance(value, self.json_type):
return value
else:
if isinstance(value, dict) or isinstance(value, list):
return value
if value == "" or value == None:
return None
try:
if isinstance(value, basestring):
parsed_value = json.loads(value)
if self.json_type and parsed_value:
parsed_value = self.json_type.fromJSONDict(parsed_value)
return parsed_value
except ValueError:
pass
return value
# we should never look up by JSON field anyways.
# def get_prep_lookup(self, lookup_type, value)
def get_db_prep_save(self, value):
def get_prep_value(self, value):
"""Convert our JSON object to a string before we save"""
if isinstance(value, basestring):
return value
if value == "" or value == None:
if value == None:
return None
if value and (self.json_type or hasattr(value, 'toJSONDict')):
value = value.toJSONDict()
if self.json_type or hasattr(value,'toJSONDict'):
the_dict = value.toJSONDict()
else:
the_dict = value
return json.dumps(the_dict, cls=DjangoJSONEncoder)
# if isinstance(value, dict):
value = json.dumps(value, cls=DjangoJSONEncoder)
return super(JSONField, self).get_db_prep_save(value)
def value_to_string(self, obj):
value = self._get_val_from_obj(obj)
return self.get_db_prep_value(value)
##
## for schema migration, we have to tell South about JSONField
......
This diff is collapsed.
{}
\ No newline at end of file
......@@ -25,6 +25,11 @@ class Migration(DataMigration):
v.save()
# also, update tinyhash for all votes
for cv in orm.CastVote.objects.all():
cv.set_tinyhash()
cv.save()
def backwards(self, orm):
"Write your backwards methods here."
......
# encoding: utf-8
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Election.complaint_period_ends_at'
db.add_column('helios_election', 'complaint_period_ends_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True), keep_default=False)
# Adding field 'CastVote.quarantined_p'
db.add_column('helios_castvote', 'quarantined_p', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False)
# Adding field 'CastVote.released_from_quarantine_at'
db.add_column('helios_castvote', 'released_from_quarantine_at', self.gf('django.db.models.fields.DateTimeField')(null=True), keep_default=False)
def backwards(self, orm):
# Deleting field 'Election.complaint_period_ends_at'
db.delete_column('helios_election', 'complaint_period_ends_at')
# Deleting field 'CastVote.quarantined_p'
db.delete_column('helios_castvote', 'quarantined_p')
# Deleting field 'CastVote.released_from_quarantine_at'
db.delete_column('helios_castvote', 'released_from_quarantine_at')
models = {
'auth.user': {
'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'},
'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'info': ('auth.jsonfield.JSONField', [], {}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}),
'token': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'helios.auditedballot': {
'Meta': {'object_name': 'AuditedBallot'},
'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'raw_vote': ('django.db.models.fields.TextField', [], {}),
'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
'helios.castvote': {
'Meta': {'object_name': 'CastVote'},
'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'vote': ('auth.jsonfield.JSONField', [], {}),
'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}),
'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"})
},
'helios.election': {
'Meta': {'object_name': 'Election'},
'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}),
'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'datatype': ('django.db.models.fields.CharField', [], {'default': "'2011/01/election'", 'max_length': '250'}),
'description': ('django.db.models.fields.TextField', [], {}),
'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}),
'eligibility': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'encrypted_tally': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}),
'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'private_key': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'public_key': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'questions': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'result': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'result_proof': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'})
},
'helios.electionlog': {
'Meta': {'object_name': 'ElectionLog'},
'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'log': ('django.db.models.fields.CharField', [], {'max_length': '500'})
},
'helios.trustee': {
'Meta': {'object_name': 'Trustee'},
'decryption_factors': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'decryption_proofs': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}),
'pok': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'public_key': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'secret_key': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
'helios.voter': {
'Meta': {'object_name': 'Voter'},
'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
'vote': ('auth.jsonfield.JSONField', [], {'null': 'True'}),
'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}),
'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}),
'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}),
'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'})
},
'helios.voterfile': {
'Meta': {'object_name': 'VoterFile'},
'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'})
}
}
complete_apps = ['helios']
......@@ -738,7 +738,7 @@ class CastVote(models.Model, electionalgs.CastVote):
cast_at = models.DateTimeField(auto_now_add=True)
# some ballots can be quarantined (this is not the same thing as provisional)
quarantined_p = modelsBooleanField(default=False, null=False)
quarantined_p = models.BooleanField(default=False, null=False)
released_from_quarantine_at = models.DateTimeField(auto_now_add=False, null=True)
# when is the vote verified?
......
......@@ -217,6 +217,20 @@ class CastVoteModelTests(TestCase):
## Black box tests
##
class LegacyElectionBlackboxTests(TestCase):
fixtures = ['legacy-data.json']
EXPECTED_OUTPUT_FILE = 'helios/fixtures/legacy-election-expected.json'
def setUp(self):
self.election = models.Election.objects.all()[0]
def test_legacy_format(self):
response = self.client.get("/helios/elections/%s" % self.election.uuid, follow=False)
expected = open(self.EXPECTED_OUTPUT_FILE)
self.assertEquals(response.content, expected.read())
expected.close()
class ElectionBlackboxTests(TestCase):
fixtures = ['users.json', 'election.json']
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment