Skip to content

Commit

Permalink
Merge pull request #24 from rdmorganiser/import_export
Browse files Browse the repository at this point in the history
Import export
  • Loading branch information
jochenklar committed Feb 4, 2017
2 parents f63c3fa + 26ed248 commit 327ad82
Show file tree
Hide file tree
Showing 181 changed files with 7,627 additions and 4,177 deletions.
1 change: 1 addition & 0 deletions .coveragerc
Expand Up @@ -7,6 +7,7 @@ omit =
rdmo/settings/*
apps/core/management/commands/*
env/*
*/migrations/*
exclude_lines =
raise Exception
except ImportError:
1 change: 0 additions & 1 deletion apps/accounts/testing/__init__.py

This file was deleted.

77 changes: 0 additions & 77 deletions apps/accounts/testing/factories.py

This file was deleted.

28 changes: 16 additions & 12 deletions apps/accounts/testing/tests.py → apps/accounts/tests.py
@@ -1,22 +1,27 @@
import re

from django.contrib.auth.models import User
from django.test import TestCase
from django.core import mail
from django.core.urlresolvers import reverse
from django.utils import translation
from django.core.urlresolvers import reverse
from django.core import mail

from apps.core.testing.mixins import TestModelStringMixin

from .factories import *

class AccountsTestCase(TestCase):

class ProfileTests(TestModelStringMixin, TestCase):
fixtures = (
'auth.json',
'accounts.json'
)


class ProfileTests(TestModelStringMixin, AccountsTestCase):

def setUp(self):
translation.activate('en')
AdditionalTextFieldFactory()
AdditionalTextareaFieldFactory()
self.instance = UserFactory()
self.instances = User.objects.all()

def test_get_profile_update(self):
"""
Expand Down Expand Up @@ -124,19 +129,18 @@ def test_post_profile_update_next2(self):
self.assertRedirects(response, reverse('home'), target_status_code=302)


class AdditionalFieldTests(TestModelStringMixin, TestCase):
class AdditionalFieldTests(TestModelStringMixin, AccountsTestCase):

def setUp(self):
translation.activate('en')
self.instance = AdditionalTextFieldFactory()
self.instances = User.objects.all()


class PasswordTests(TestCase):
class PasswordTests(AccountsTestCase):

def setUp(self):
UserFactory()

translation.activate('en')
self.instances = User.objects.all()

def test_password_change_get(self):
"""
Expand Down
9 changes: 7 additions & 2 deletions apps/conditions/admin.py
@@ -1,5 +1,10 @@
from django.contrib import admin

from .models import *
from .models import Condition

admin.site.register(Condition)

class ConditionAdmin(admin.ModelAdmin):
readonly_fields = ('uri', )


admin.site.register(Condition, ConditionAdmin)
30 changes: 30 additions & 0 deletions apps/conditions/migrations/0010_refactoring.py
@@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2017-01-25 13:48
from __future__ import unicode_literals

from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
('conditions', '0009_options'),
('options', '0006_refactoring'),
]

operations = [
migrations.AlterModelOptions(
name='condition',
options={'ordering': ('key',), 'verbose_name': 'Condition', 'verbose_name_plural': 'Conditions'},
),
migrations.RenameField(
model_name='condition',
old_name='description',
new_name='comment',
),
migrations.RenameField(
model_name='condition',
old_name='title',
new_name='key',
),
]
60 changes: 60 additions & 0 deletions apps/conditions/migrations/0011_refactoring.py
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.9 on 2017-01-25 13:56
from __future__ import unicode_literals

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


class Migration(migrations.Migration):

dependencies = [
('conditions', '0010_refactoring'),
]

operations = [
migrations.AlterModelOptions(
name='condition',
options={'ordering': ('uri',), 'verbose_name': 'Condition', 'verbose_name_plural': 'Conditions'},
),
migrations.AddField(
model_name='condition',
name='uri',
field=models.URLField(blank=True, help_text='The Uniform Resource Identifier of this option set (auto-generated).', max_length=640, null=True, verbose_name='URI'),
),
migrations.AddField(
model_name='condition',
name='uri_prefix',
field=models.URLField(blank=True, help_text='The prefix for the URI of this condition.', max_length=256, null=True, verbose_name='URI Prefix'),
),
migrations.AlterField(
model_name='condition',
name='comment',
field=models.TextField(blank=True, help_text='Additional information about this condition.', null=True, verbose_name='Comment'),
),
migrations.AlterField(
model_name='condition',
name='key',
field=models.SlugField(blank=True, help_text='The internal identifier of this condition. The URI will be generated from this key.', max_length=128, null=True, verbose_name='Key'),
),
migrations.AlterField(
model_name='condition',
name='relation',
field=models.CharField(choices=[('eq', 'is equal to (==)'), ('neq', 'is not equal to (!=)'), ('contains', 'contains'), ('gt', 'is greater than (>)'), ('gte', 'is greater than or equal (>=)'), ('lt', 'is lesser than (<)'), ('lte', 'is lesser than or equal (<=)'), ('empty', 'is empty'), ('notempty', 'is not empty')], help_text='Relation this condition is using.', max_length=8, verbose_name='Relation'),
),
migrations.AlterField(
model_name='condition',
name='source',
field=models.ForeignKey(blank=True, db_constraint=False, help_text='Attribute this condition is evaluating.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='domain.Attribute', verbose_name='Source'),
),
migrations.AlterField(
model_name='condition',
name='target_option',
field=models.ForeignKey(blank=True, db_constraint=False, help_text='Option this condition is checking against.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='+', to='options.Option', verbose_name='Target (Option)'),
),
migrations.AlterField(
model_name='condition',
name='target_text',
field=models.CharField(blank=True, help_text='Raw text value this condition is checking against.', max_length=256, null=True, verbose_name='Target (Text)'),
),
]
73 changes: 58 additions & 15 deletions apps/conditions/models.py
@@ -1,10 +1,13 @@
from __future__ import unicode_literals

from django.db import models
from django.core.validators import RegexValidator
from django.utils.encoding import python_2_unicode_compatible
from django.utils.translation import ugettext_lazy as _

from apps.core.utils import get_uri_prefix

from .validators import ConditionUniqueKeyValidator


@python_2_unicode_compatible
class Condition(models.Model):
Expand All @@ -30,28 +33,61 @@ class Condition(models.Model):
(RELATION_NOT_EMPTY, 'is not empty'),
)

title = models.CharField(max_length=256, validators=[
RegexValidator('^[a-zA-z0-9_]*$', _('Only letters, numbers, or underscores are allowed.'))
])
description = models.TextField(blank=True, null=True)

source = models.ForeignKey('domain.Attribute', db_constraint=False, blank=True, null=True, on_delete=models.SET_NULL, related_name='+')
relation = models.CharField(max_length=8, choices=RELATION_CHOICES)

target_text = models.CharField(max_length=256, blank=True, null=True)
target_option = models.ForeignKey('options.Option', db_constraint=False, blank=True, null=True, on_delete=models.SET_NULL, related_name='+')
uri = models.URLField(
max_length=640, blank=True, null=True,
verbose_name=_('URI'),
help_text=_('The Uniform Resource Identifier of this option set (auto-generated).')
)
uri_prefix = models.URLField(
max_length=256, blank=True, null=True,
verbose_name=_('URI Prefix'),
help_text=_('The prefix for the URI of this condition.')
)
key = models.SlugField(
max_length=128, blank=True, null=True,
verbose_name=_('Key'),
help_text=_('The internal identifier of this condition. The URI will be generated from this key.')
)
comment = models.TextField(
blank=True, null=True,
verbose_name=_('Comment'),
help_text=_('Additional information about this condition.')
)
source = models.ForeignKey(
'domain.Attribute', db_constraint=False, blank=True, null=True, on_delete=models.SET_NULL, related_name='+',
verbose_name=_('Source'),
help_text=_('Attribute this condition is evaluating.')
)
relation = models.CharField(
max_length=8, choices=RELATION_CHOICES,
verbose_name=_('Relation'),
help_text=_('Relation this condition is using.')
)
target_text = models.CharField(
max_length=256, blank=True, null=True,
verbose_name=_('Target (Text)'),
help_text=_('Raw text value this condition is checking against.')
)
target_option = models.ForeignKey(
'options.Option', db_constraint=False, blank=True, null=True, on_delete=models.SET_NULL, related_name='+',
verbose_name=_('Target (Option)'),
help_text=_('Option this condition is checking against.')
)

class Meta:
ordering = ('title', )
ordering = ('uri', )
verbose_name = _('Condition')
verbose_name_plural = _('Conditions')

def __str__(self):
return self.title
return self.uri or self.key

def clean(self):
ConditionUniqueKeyValidator(self).validate()

@property
def source_label(self):
return self.source.label
def source_path(self):
return self.source.path

@property
def relation_label(self):
Expand All @@ -64,6 +100,13 @@ def target_label(self):
else:
return self.target_text

def save(self, *args, **kwargs):
self.uri = self.build_uri()
super(Condition, self).save(*args, **kwargs)

def build_uri(self):
return get_uri_prefix(self) + '/conditions/' + self.key

def resolve(self, project, snapshot=None):
# get the values for the given project, the given snapshot and the condition's attribute
values = project.values.filter(snapshot=snapshot).filter(attribute=self.source)
Expand Down
24 changes: 24 additions & 0 deletions apps/conditions/renderers.py
@@ -0,0 +1,24 @@
from apps.core.renderers import BaseXMLRenderer


class XMLRenderer(BaseXMLRenderer):

def render_document(self, xml, conditions):
xml.startElement('conditions', {
'xmlns:dc': "http://purl.org/dc/elements/1.1/"
})

for condition in conditions:
self.render_condition(xml, condition)

xml.endElement('conditions')

def render_condition(self, xml, condition):
xml.startElement('condition', {})
self.render_text_element(xml, 'dc:uri', {}, condition["uri"])
self.render_text_element(xml, 'dc:comment', {}, condition["comment"])
self.render_text_element(xml, 'source', {'dc:uri': condition["source"]}, None)
self.render_text_element(xml, 'relation', {}, condition["relation"])
self.render_text_element(xml, 'target_text', {}, condition["target_text"])
self.render_text_element(xml, 'target_option', {'dc:uri': condition["target_option"]}, None)
xml.endElement('condition')

0 comments on commit 327ad82

Please sign in to comment.