0003-pricing-import-export-check-types-65459.patch
lingo/agendas/migrations/0003_check_type_group.py | ||
---|---|---|
1 |
import django.db.models.deletion |
|
2 |
from django.db import migrations, models |
|
3 | ||
4 | ||
5 |
class Migration(migrations.Migration): |
|
6 | ||
7 |
dependencies = [ |
|
8 |
('agendas', '0002_agenda'), |
|
9 |
] |
|
10 | ||
11 |
operations = [ |
|
12 |
migrations.AddField( |
|
13 |
model_name='agenda', |
|
14 |
name='check_type_group', |
|
15 |
field=models.ForeignKey( |
|
16 |
blank=True, |
|
17 |
null=True, |
|
18 |
on_delete=django.db.models.deletion.SET_NULL, |
|
19 |
to='agendas.CheckTypeGroup', |
|
20 |
verbose_name='Check type group', |
|
21 |
), |
|
22 |
), |
|
23 |
] |
lingo/agendas/models.py | ||
---|---|---|
28 | 28 |
slug = models.SlugField(_('Identifier'), max_length=160, unique=True) |
29 | 29 |
category_label = models.CharField(_('Category label'), max_length=150, null=True) |
30 | 30 |
category_slug = models.SlugField(_('Category identifier'), max_length=160, null=True) |
31 |
check_type_group = models.ForeignKey( |
|
32 |
'CheckTypeGroup', |
|
33 |
verbose_name=_('Check type group'), |
|
34 |
blank=True, |
|
35 |
null=True, |
|
36 |
on_delete=models.SET_NULL, |
|
37 |
) |
|
31 | 38 | |
32 | 39 |
def __str__(self): |
33 | 40 |
return self.label |
... | ... | |
45 | 52 |
return { |
46 | 53 |
'slug': self.slug, |
47 | 54 |
'pricings': [x.export_json() for x in self.agendapricing_set.all()], |
55 |
'check_type_group': self.check_type_group.slug if self.check_type_group else None, |
|
48 | 56 |
} |
49 | 57 | |
50 | 58 |
@classmethod |
... | ... | |
62 | 70 |
pricing_data['pricing'] = Pricing.objects.get(slug=pricing_data['pricing']) |
63 | 71 |
except Pricing.DoesNotExist: |
64 | 72 |
raise AgendaImportError(_('Missing "%s" pricing model') % pricing_data['pricing']) |
73 |
if data.get('check_type_group'): |
|
74 |
try: |
|
75 |
data['check_type_group'] = CheckTypeGroup.objects.get(slug=data['check_type_group']) |
|
76 |
except CheckTypeGroup.DoesNotExist: |
|
77 |
raise AgendaImportError(_('Missing "%s" check type group') % data['check_type_group']) |
|
78 | ||
79 |
agenda.check_type_group = data.get('check_type_group') |
|
80 |
agenda.save() |
|
65 | 81 | |
66 | 82 |
for pricing_data in pricings: |
67 | 83 |
pricing_data['agenda'] = agenda |
lingo/pricing/forms.py | ||
---|---|---|
25 | 25 | |
26 | 26 |
class ExportForm(forms.Form): |
27 | 27 |
agendas = forms.BooleanField(label=_('Agendas'), required=False, initial=True) |
28 |
check_type_groups = forms.BooleanField(label=_('Check type groups'), required=False, initial=True) |
|
28 | 29 |
pricing_categories = forms.BooleanField( |
29 | 30 |
label=_('Pricing criteria categories'), required=False, initial=True |
30 | 31 |
) |
lingo/pricing/templates/lingo/pricing/manager_agenda_detail.html | ||
---|---|---|
36 | 36 |
{% endif %} |
37 | 37 |
</div> |
38 | 38 |
</div> |
39 | ||
40 |
<div class="section"> |
|
41 |
<h3>{% trans "Booking check options" %} |
|
42 |
<a rel="popup" class="button" href="{% url 'lingo-manager-agenda-booking-check-settings' pk=object.pk %}">{% trans 'Configure' %}</a> |
|
43 |
</h3> |
|
44 |
<div> |
|
45 |
<ul> |
|
46 |
{% if agenda.check_type_group %} |
|
47 |
<li>{% trans "Check type group:" %} {{ agenda.check_type_group }} |
|
48 |
<ul> |
|
49 |
<li>{% trans "Absences:" %} |
|
50 |
<ul> |
|
51 |
{% for check_type in agenda.check_type_group.check_types.absences %} |
|
52 |
<li>{{ check_type }}</li> |
|
53 |
{% empty %} |
|
54 |
<li>({% trans "No absence check type defined" %})</li> |
|
55 |
{% endfor %} |
|
56 |
</ul> |
|
57 |
</li> |
|
58 |
<li>{% trans "Presences:" %} |
|
59 |
<ul> |
|
60 |
{% for check_type in agenda.check_type_group.check_types.presences %} |
|
61 |
<li>{{ check_type }}</li> |
|
62 |
{% empty %} |
|
63 |
<li>({% trans "No presence check type defined" %})</li> |
|
64 |
{% endfor %} |
|
65 |
</ul> |
|
66 |
</li> |
|
67 |
</ul> |
|
68 |
</li> |
|
69 |
{% else %} |
|
70 |
<li>{% trans "No check types configured for this agenda." %}</li> |
|
71 |
{% endif %} |
|
72 |
</ul> |
|
73 |
</div> |
|
74 |
</div> |
|
39 | 75 |
{% endblock %} |
lingo/pricing/templates/lingo/pricing/manager_agenda_form.html | ||
---|---|---|
1 |
{% extends "lingo/pricing/manager_agenda_detail.html" %} |
|
2 |
{% load i18n %} |
|
3 | ||
4 |
{% block breadcrumb %} |
|
5 |
{{ block.super }} |
|
6 |
<a href="{{ form_url }}">{{ title }}</a> |
|
7 |
{% endblock %} |
|
8 | ||
9 |
{% block appbar %} |
|
10 |
<h2>{{ title }}</h2> |
|
11 |
{% endblock %} |
|
12 | ||
13 |
{% block content %} |
|
14 |
<form method="post" enctype="multipart/form-data"> |
|
15 |
{% csrf_token %} |
|
16 |
{{ form.as_p }} |
|
17 |
<div class="buttons"> |
|
18 |
<button class="submit-button">{% trans "Save" %}</button> |
|
19 |
<a class="cancel" href="{% url 'lingo-manager-agenda-detail' agenda.pk %}">{% trans 'Cancel' %}</a> |
|
20 |
</div> |
|
21 |
</form> |
|
22 |
{% endblock %} |
lingo/pricing/urls.py | ||
---|---|---|
143 | 143 |
staff_member_required(views.agenda_export), |
144 | 144 |
name='lingo-manager-agenda-export', |
145 | 145 |
), |
146 |
url( |
|
147 |
r'^agenda/(?P<pk>\d+)/check-options/$', |
|
148 |
staff_member_required(views.agenda_booking_check_settings), |
|
149 |
name='lingo-manager-agenda-booking-check-settings', |
|
150 |
), |
|
146 | 151 |
url( |
147 | 152 |
r'^agenda/(?P<pk>\d+)/pricing/add/$', |
148 | 153 |
staff_member_required(views.agenda_pricing_add), |
lingo/pricing/utils.py | ||
---|---|---|
18 | 18 | |
19 | 19 |
from django.db import transaction |
20 | 20 | |
21 |
from lingo.agendas.models import Agenda |
|
21 |
from lingo.agendas.models import Agenda, CheckTypeGroup
|
|
22 | 22 |
from lingo.pricing.models import AgendaPricing, CriteriaCategory, Pricing |
23 | 23 | |
24 | 24 | |
25 | 25 |
def export_site( |
26 | 26 |
agendas=True, |
27 |
check_type_groups=True, |
|
27 | 28 |
pricing_categories=True, |
28 | 29 |
pricing_models=True, |
29 | 30 |
): |
... | ... | |
33 | 34 |
data['pricing_models'] = [x.export_json() for x in Pricing.objects.all()] |
34 | 35 |
if pricing_categories: |
35 | 36 |
data['pricing_categories'] = [x.export_json() for x in CriteriaCategory.objects.all()] |
37 |
if check_type_groups: |
|
38 |
data['check_type_groups'] = [x.export_json() for x in CheckTypeGroup.objects.all()] |
|
36 | 39 |
if agendas: |
37 | 40 |
data['agendas'] = [x.export_json() for x in Agenda.objects.all()] |
38 | 41 |
return data |
... | ... | |
40 | 43 | |
41 | 44 |
def import_site(data, if_empty=False, clean=False, overwrite=False): |
42 | 45 |
if if_empty and ( |
43 |
AgendaPricing.objects.exists() or CriteriaCategory.objects.exists() or Pricing.objects.exists() |
|
46 |
AgendaPricing.objects.exists() |
|
47 |
or CheckTypeGroup.objects.exists() |
|
48 |
or CriteriaCategory.objects.exists() |
|
49 |
or Pricing.objects.exists() |
|
44 | 50 |
): |
45 | 51 |
return |
46 | 52 | |
... | ... | |
48 | 54 |
AgendaPricing.objects.all().delete() |
49 | 55 |
CriteriaCategory.objects.all().delete() |
50 | 56 |
Pricing.objects.all().delete() |
57 |
CheckTypeGroup.objects.all().delete() |
|
51 | 58 | |
52 | 59 |
results = { |
53 | 60 |
key: collections.defaultdict(list) |
54 | 61 |
for key in [ |
55 | 62 |
'agendas', |
63 |
'check_type_groups', |
|
56 | 64 |
'pricing_categories', |
57 | 65 |
'pricing_models', |
58 | 66 |
] |
... | ... | |
62 | 70 |
for cls, key in ( |
63 | 71 |
(CriteriaCategory, 'pricing_categories'), |
64 | 72 |
(Pricing, 'pricing_models'), |
73 |
(CheckTypeGroup, 'check_type_groups'), |
|
65 | 74 |
(Agenda, 'agendas'), |
66 | 75 |
): |
67 | 76 |
objs = data.get(key, []) |
lingo/pricing/views.py | ||
---|---|---|
108 | 108 |
x, |
109 | 109 |
), |
110 | 110 |
}, |
111 |
'check_type_groups': { |
|
112 |
'create_noop': _('No check type group created.'), |
|
113 |
'create': lambda x: ungettext( |
|
114 |
'A check type group has been created.', |
|
115 |
'%(count)d check type groups have been created.', |
|
116 |
x, |
|
117 |
), |
|
118 |
'update_noop': _('No check type group updated.'), |
|
119 |
'update': lambda x: ungettext( |
|
120 |
'A check type group has been updated.', |
|
121 |
'%(count)d check type groups have been updated.', |
|
122 |
x, |
|
123 |
), |
|
124 |
}, |
|
111 | 125 |
'pricing_categories': { |
112 | 126 |
'create_noop': _('No pricing criteria category created.'), |
113 | 127 |
'create': lambda x: ungettext( |
... | ... | |
156 | 170 | |
157 | 171 |
obj_results['messages'] = "%s %s" % (message1, message2) |
158 | 172 | |
159 |
a_count, pc_count, pm_count = ( |
|
173 |
a_count, ct_count, pc_count, pm_count = (
|
|
160 | 174 |
len(results['agendas']['all']), |
175 |
len(results['check_type_groups']['all']), |
|
161 | 176 |
len(results['pricing_categories']['all']), |
162 | 177 |
len(results['pricing_models']['all']), |
163 | 178 |
) |
164 |
if (a_count, pc_count, pm_count) == (1, 0, 0):
|
|
179 |
if (a_count, ct_count, pc_count, pm_count) == (1, 0, 0, 0):
|
|
165 | 180 |
# only one agenda imported, redirect to agenda page |
166 | 181 |
return HttpResponseRedirect( |
167 | 182 |
reverse( |
... | ... | |
169 | 184 |
kwargs={'pk': results['agendas']['all'][0].pk}, |
170 | 185 |
) |
171 | 186 |
) |
172 |
if (a_count, pc_count, pm_count) == (0, 1, 0): |
|
187 |
if (a_count, ct_count, pc_count, pm_count) == (0, 1, 0, 0): |
|
188 |
# only one check type group imported, redirect to check type page |
|
189 |
return HttpResponseRedirect(reverse('lingo-manager-check-type-list')) |
|
190 |
if (a_count, ct_count, pc_count, pm_count) == (0, 0, 1, 0): |
|
173 | 191 |
# only one criteria category imported, redirect to criteria page |
174 | 192 |
return HttpResponseRedirect(reverse('lingo-manager-pricing-criteria-list')) |
175 |
if (a_count, pc_count, pm_count) == (0, 0, 1):
|
|
193 |
if (a_count, ct_count, pc_count, pm_count) == (0, 0, 0, 1):
|
|
176 | 194 |
# only one pricing imported, redirect to pricing page |
177 | 195 |
return HttpResponseRedirect( |
178 | 196 |
reverse( |
... | ... | |
185 | 203 |
messages.info(self.request, _('No data found.')) |
186 | 204 |
else: |
187 | 205 |
messages.info(self.request, results['agendas']['messages']) |
206 |
messages.info(self.request, results['check_type_groups']['messages']) |
|
188 | 207 |
messages.info(self.request, results['pricing_categories']['messages']) |
189 | 208 |
messages.info(self.request, results['pricing_models']['messages']) |
190 | 209 | |
... | ... | |
646 | 665 |
agenda_export = AgendaExport.as_view() |
647 | 666 | |
648 | 667 | |
668 |
class AgendaBookingCheckSettingsView(AgendaMixin, UpdateView): |
|
669 |
template_name = 'lingo/pricing/manager_agenda_form.html' |
|
670 |
model = Agenda |
|
671 |
fields = ['check_type_group'] |
|
672 | ||
673 |
def get_context_data(self, **kwargs): |
|
674 |
context = super().get_context_data(**kwargs) |
|
675 |
context['form_url'] = reverse('lingo-manager-agenda-booking-check-settings', args=[self.agenda.pk]) |
|
676 |
context['title'] = _("Configure booking check options") |
|
677 |
return context |
|
678 | ||
679 | ||
680 |
agenda_booking_check_settings = AgendaBookingCheckSettingsView.as_view() |
|
681 | ||
682 | ||
649 | 683 |
class AgendaPricingAddView(AgendaMixin, CreateView): |
650 | 684 |
template_name = 'lingo/pricing/manager_agenda_pricing_form.html' |
651 | 685 |
model = AgendaPricing |
... | ... | |
663 | 697 |
pk_url_kwarg = 'pricing_pk' |
664 | 698 |
template_name = 'lingo/pricing/manager_agenda_pricing_detail.html' |
665 | 699 | |
666 |
def set_agenda(self, **kwargs): |
|
667 |
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk')) |
|
668 | ||
669 | 700 |
def get_queryset(self): |
670 | 701 |
return AgendaPricing.objects.filter(agenda=self.agenda).prefetch_related( |
671 | 702 |
'pricing__criterias__category' |
... | ... | |
681 | 712 |
pk_url_kwarg = 'pricing_pk' |
682 | 713 |
form_class = AgendaPricingForm |
683 | 714 | |
684 |
def set_agenda(self, **kwargs): |
|
685 |
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk')) |
|
686 | ||
687 | 715 |
def get_queryset(self): |
688 | 716 |
return AgendaPricing.objects.filter(agenda=self.agenda) |
689 | 717 | |
... | ... | |
699 | 727 |
model = AgendaPricing |
700 | 728 |
pk_url_kwarg = 'pricing_pk' |
701 | 729 | |
702 |
def set_agenda(self, **kwargs): |
|
703 |
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk')) |
|
704 | ||
705 | 730 |
def get_queryset(self): |
706 | 731 |
return AgendaPricing.objects.filter(agenda=self.agenda) |
707 | 732 | |
... | ... | |
713 | 738 |
template_name = 'lingo/pricing/manager_agenda_pricing_matrix_form.html' |
714 | 739 | |
715 | 740 |
def set_agenda(self, **kwargs): |
716 |
self.agenda = get_object_or_404(Agenda, pk=kwargs.get('pk'))
|
|
741 |
super().set_agenda(**kwargs)
|
|
717 | 742 |
self.object = get_object_or_404( |
718 | 743 |
AgendaPricing.objects.filter(agenda=self.agenda), pk=kwargs['pricing_pk'] |
719 | 744 |
) |
tests/pricing/manager/test_agenda.py | ||
---|---|---|
3 | 3 | |
4 | 4 |
import pytest |
5 | 5 | |
6 |
from lingo.agendas.models import Agenda |
|
6 |
from lingo.agendas.models import Agenda, CheckTypeGroup
|
|
7 | 7 |
from lingo.pricing.models import AgendaPricing, Criteria, CriteriaCategory, Pricing |
8 | 8 |
from tests.utils import login |
9 | 9 | |
... | ... | |
698 | 698 | |
699 | 699 |
app = login(app) |
700 | 700 |
app.get('/manage/pricing/agenda/%s/pricing/%s/matrix/edit/' % (agenda.pk, agenda_pricing.pk), status=404) |
701 | ||
702 | ||
703 |
def test_edit_agenda_check_type_group(app, admin_user): |
|
704 |
agenda = Agenda.objects.create(label='Foo bar') |
|
705 |
group = CheckTypeGroup.objects.create(label='Foo bar') |
|
706 | ||
707 |
app = login(app) |
|
708 |
resp = app.get('/manage/pricing/agenda/%s/' % agenda.pk) |
|
709 |
assert 'No check types configured for this agenda.' in resp |
|
710 |
resp = resp.click(href='/manage/pricing/agenda/%s/check-options' % agenda.pk) |
|
711 |
resp.form['check_type_group'] = group.pk |
|
712 |
resp = resp.form.submit().follow() |
|
713 |
agenda.refresh_from_db() |
|
714 |
assert agenda.check_type_group == group |
|
715 |
assert 'Check type group: Foo bar' in resp |
tests/pricing/manager/test_import_export.py | ||
---|---|---|
4 | 4 |
import pytest |
5 | 5 |
from webtest import Upload |
6 | 6 | |
7 |
from lingo.agendas.models import Agenda |
|
7 |
from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
|
|
8 | 8 |
from lingo.pricing.models import Criteria, CriteriaCategory, Pricing |
9 | 9 |
from tests.utils import login |
10 | 10 | |
... | ... | |
24 | 24 |
site_json = json.loads(resp.text) |
25 | 25 |
assert site_json == { |
26 | 26 |
'agendas': [], |
27 |
'check_type_groups': [], |
|
27 | 28 |
'pricing_categories': [], |
28 | 29 |
'pricing_models': [], |
29 | 30 |
} |
... | ... | |
37 | 38 | |
38 | 39 |
resp = app.get('/manage/pricing/export/') |
39 | 40 |
resp.form['agendas'] = False |
41 |
resp.form['check_type_groups'] = False |
|
40 | 42 |
resp.form['pricing_categories'] = False |
41 | 43 |
resp.form['pricing_models'] = False |
42 | 44 |
resp = resp.form.submit() |
43 | 45 | |
44 | 46 |
site_json = json.loads(resp.text) |
45 | 47 |
assert 'agendas' not in site_json |
48 |
assert 'check_type_groups' not in site_json |
|
46 | 49 |
assert 'pricing_categories' not in site_json |
47 | 50 |
assert 'pricing_models' not in site_json |
48 | 51 | |
... | ... | |
233 | 236 |
resp = resp.follow() |
234 | 237 |
assert '2 agendas have been updated.' in resp.text |
235 | 238 |
assert Agenda.objects.count() == 2 |
239 | ||
240 | ||
241 |
@pytest.mark.freeze_time('2021-07-08') |
|
242 |
def test_import_check_type_group(app, admin_user): |
|
243 |
group = CheckTypeGroup.objects.create(label='Foo bar') |
|
244 |
CheckType.objects.create(label='Foo reason', group=group) |
|
245 |
CheckType.objects.create(label='Baz', group=group) |
|
246 | ||
247 |
app = login(app) |
|
248 |
resp = app.get('/manage/pricing/check-type/group/%s/export/' % group.id) |
|
249 |
assert resp.headers['content-type'] == 'application/json' |
|
250 |
assert ( |
|
251 |
resp.headers['content-disposition'] |
|
252 |
== 'attachment; filename="export_check_type_group_foo-bar_20210708.json"' |
|
253 |
) |
|
254 |
group_export = resp.text |
|
255 | ||
256 |
# existing group |
|
257 |
resp = app.get('/manage/pricing/', status=200) |
|
258 |
resp = resp.click('Import') |
|
259 |
resp.form['config_json'] = Upload('export.json', group_export.encode('utf-8'), 'application/json') |
|
260 |
resp = resp.form.submit() |
|
261 |
assert resp.location.endswith('/manage/pricing/check-types/') |
|
262 |
resp = resp.follow() |
|
263 |
assert 'No check type group created. A check type group has been updated.' not in resp.text |
|
264 |
assert CheckTypeGroup.objects.count() == 1 |
|
265 |
assert CheckType.objects.count() == 2 |
|
266 | ||
267 |
# new group |
|
268 |
CheckTypeGroup.objects.all().delete() |
|
269 |
resp = app.get('/manage/pricing/', status=200) |
|
270 |
resp = resp.click('Import') |
|
271 |
resp.form['config_json'] = Upload('export.json', group_export.encode('utf-8'), 'application/json') |
|
272 |
resp = resp.form.submit() |
|
273 |
assert resp.location.endswith('/manage/pricing/check-types/') |
|
274 |
resp = resp.follow() |
|
275 |
assert 'A check type group has been created. No check type group updated.' not in resp.text |
|
276 |
assert CheckTypeGroup.objects.count() == 1 |
|
277 |
assert CheckType.objects.count() == 2 |
|
278 | ||
279 |
# multiple groups |
|
280 |
groups = json.loads(group_export) |
|
281 |
groups['check_type_groups'].append(copy.copy(groups['check_type_groups'][0])) |
|
282 |
groups['check_type_groups'].append(copy.copy(groups['check_type_groups'][0])) |
|
283 |
groups['check_type_groups'][1]['label'] = 'Foo bar 2' |
|
284 |
groups['check_type_groups'][1]['slug'] = 'foo-bar-2' |
|
285 |
groups['check_type_groups'][2]['label'] = 'Foo bar 3' |
|
286 |
groups['check_type_groups'][2]['slug'] = 'foo-bar-3' |
|
287 | ||
288 |
resp = app.get('/manage/pricing/', status=200) |
|
289 |
resp = resp.click('Import') |
|
290 |
resp.form['config_json'] = Upload('export.json', json.dumps(groups).encode('utf-8'), 'application/json') |
|
291 |
resp = resp.form.submit() |
|
292 |
assert resp.location.endswith('/manage/pricing/') |
|
293 |
resp = resp.follow() |
|
294 |
assert '2 check type groups have been created. A check type group has been updated.' in resp.text |
|
295 |
assert CheckTypeGroup.objects.count() == 3 |
|
296 |
assert CheckType.objects.count() == 6 |
|
297 | ||
298 |
CheckTypeGroup.objects.all().delete() |
|
299 |
resp = app.get('/manage/pricing/', status=200) |
|
300 |
resp = resp.click('Import') |
|
301 |
resp.form['config_json'] = Upload('export.json', json.dumps(groups).encode('utf-8'), 'application/json') |
|
302 |
resp = resp.form.submit().follow() |
|
303 |
assert '3 check type groups have been created. No check type group updated.' in resp.text |
|
304 |
assert CheckTypeGroup.objects.count() == 3 |
|
305 |
assert CheckType.objects.count() == 6 |
tests/pricing/test_import_export.py | ||
---|---|---|
11 | 11 |
from django.core.management import call_command |
12 | 12 |
from django.utils.encoding import force_bytes |
13 | 13 | |
14 |
from lingo.agendas.models import Agenda |
|
14 |
from lingo.agendas.models import Agenda, CheckType, CheckTypeGroup
|
|
15 | 15 |
from lingo.pricing.models import AgendaPricing, Criteria, CriteriaCategory, Pricing, PricingCriteriaCategory |
16 | 16 |
from lingo.pricing.utils import import_site |
17 | 17 |
from lingo.utils.misc import AgendaImportError |
... | ... | |
159 | 159 |
assert agenda_pricing.date_end == datetime.date(year=2022, month=10, day=1) |
160 | 160 | |
161 | 161 | |
162 |
def test_import_export_agenda_with_check_types(app): |
|
163 |
group = CheckTypeGroup.objects.create(label='foo') |
|
164 |
agenda = Agenda.objects.create(label='Foo Bar', check_type_group=group) |
|
165 |
output = get_output_of_command('export_site') |
|
166 | ||
167 |
import_site(data={}, clean=True) |
|
168 |
assert CheckTypeGroup.objects.count() == 0 |
|
169 |
data = json.loads(output) |
|
170 |
del data['check_type_groups'] |
|
171 |
agenda.check_type_group = None |
|
172 |
agenda.save() |
|
173 | ||
174 |
with pytest.raises(AgendaImportError) as excinfo: |
|
175 |
import_site(data, overwrite=True) |
|
176 |
assert str(excinfo.value) == 'Missing "foo" check type group' |
|
177 | ||
178 |
CheckTypeGroup.objects.create(label='foobar') |
|
179 |
with pytest.raises(AgendaImportError) as excinfo: |
|
180 |
import_site(data, overwrite=True) |
|
181 |
assert str(excinfo.value) == 'Missing "foo" check type group' |
|
182 | ||
183 |
group = CheckTypeGroup.objects.create(label='foo') |
|
184 |
import_site(data, overwrite=True) |
|
185 |
agenda.refresh_from_db() |
|
186 |
assert agenda.check_type_group == group |
|
187 | ||
188 | ||
162 | 189 |
def test_import_export_pricing_criteria_category(app): |
163 | 190 |
output = get_output_of_command('export_site') |
164 | 191 |
payload = json.loads(output) |
... | ... | |
372 | 399 |
35, |
373 | 400 |
] |
374 | 401 |
assert set(pricing.criterias.all()) == {criteria1, criteria3} |
402 | ||
403 | ||
404 |
def test_import_export_check_type_group(app): |
|
405 |
output = get_output_of_command('export_site') |
|
406 |
payload = json.loads(output) |
|
407 |
assert len(payload['check_type_groups']) == 0 |
|
408 | ||
409 |
group = CheckTypeGroup.objects.create(label='Foo bar') |
|
410 |
CheckType.objects.create(label='Foo reason', group=group) |
|
411 |
CheckType.objects.create(label='Baz', group=group) |
|
412 | ||
413 |
output = get_output_of_command('export_site') |
|
414 |
payload = json.loads(output) |
|
415 |
assert len(payload['check_type_groups']) == 1 |
|
416 | ||
417 |
group.delete() |
|
418 |
assert not CheckTypeGroup.objects.exists() |
|
419 |
assert not CheckType.objects.exists() |
|
420 | ||
421 |
import_site(copy.deepcopy(payload)) |
|
422 |
assert CheckTypeGroup.objects.count() == 1 |
|
423 |
group = CheckTypeGroup.objects.first() |
|
424 |
assert group.label == 'Foo bar' |
|
425 |
assert group.slug == 'foo-bar' |
|
426 |
assert group.check_types.count() == 2 |
|
427 |
assert CheckType.objects.get(group=group, label='Foo reason', slug='foo-reason') |
|
428 |
assert CheckType.objects.get(group=group, label='Baz', slug='baz') |
|
429 | ||
430 |
# update |
|
431 |
update_payload = copy.deepcopy(payload) |
|
432 |
update_payload['check_type_groups'][0]['label'] = 'Foo bar Updated' |
|
433 |
import_site(update_payload) |
|
434 |
group.refresh_from_db() |
|
435 |
assert group.label == 'Foo bar Updated' |
|
436 | ||
437 |
# insert another group |
|
438 |
group.slug = 'foo-bar-updated' |
|
439 |
group.save() |
|
440 |
import_site(copy.deepcopy(payload)) |
|
441 |
assert CheckTypeGroup.objects.count() == 2 |
|
442 |
group = CheckTypeGroup.objects.latest('pk') |
|
443 |
assert group.label == 'Foo bar' |
|
444 |
assert group.slug == 'foo-bar' |
|
445 |
assert group.check_types.count() == 2 |
|
446 |
assert CheckType.objects.get(group=group, label='Foo reason', slug='foo-reason') |
|
447 |
assert CheckType.objects.get(group=group, label='Baz', slug='baz') |
|
448 | ||
449 |
# with overwrite |
|
450 |
CheckType.objects.create(group=group, label='Baz2') |
|
451 |
import_site(copy.deepcopy(payload), overwrite=True) |
|
452 |
assert CheckTypeGroup.objects.count() == 2 |
|
453 |
group = CheckTypeGroup.objects.latest('pk') |
|
454 |
assert group.label == 'Foo bar' |
|
455 |
assert group.slug == 'foo-bar' |
|
456 |
assert group.check_types.count() == 2 |
|
457 |
assert CheckType.objects.get(group=group, label='Foo reason', slug='foo-reason') |
|
458 |
assert CheckType.objects.get(group=group, label='Baz', slug='baz') |
|
375 |
- |