5571 |
5571 |
assert resp.form['f1'].options == []
|
5572 |
5572 |
if pub.is_using_postgresql():
|
5573 |
5573 |
assert pub.loggederror_class.count() == 1
|
5574 |
5574 |
logged_error = pub.loggederror_class.select()[0]
|
5575 |
5575 |
assert logged_error.formdef_id == formdef.id
|
5576 |
5576 |
assert logged_error.summary == '[DATASOURCE] Unknown custom view "as-data-source" for CardDef "items"'
|
5577 |
5577 |
|
5578 |
5578 |
|
|
5579 |
def test_dynamic_item_field_from_custom_view_on_cards_lookup_by_key(pub):
|
|
5580 |
if not pub.is_using_postgresql():
|
|
5581 |
pytest.skip('this requires SQL')
|
|
5582 |
return
|
|
5583 |
|
|
5584 |
pub.role_class.wipe()
|
|
5585 |
pub.custom_view_class.wipe()
|
|
5586 |
|
|
5587 |
user = create_user(pub)
|
|
5588 |
role = pub.role_class(name='xxx')
|
|
5589 |
role.store()
|
|
5590 |
user.roles = [role.id]
|
|
5591 |
user.is_admin = True
|
|
5592 |
user.store()
|
|
5593 |
|
|
5594 |
formdef = create_formdef()
|
|
5595 |
formdef.data_class().wipe()
|
|
5596 |
|
|
5597 |
data_source = {
|
|
5598 |
'type': 'formula',
|
|
5599 |
'value': repr(
|
|
5600 |
[
|
|
5601 |
{'id': '0', 'text': 'foo'},
|
|
5602 |
{'id': '1', 'text': 'bar'},
|
|
5603 |
{'id': '2', 'text': 'baz'},
|
|
5604 |
]
|
|
5605 |
),
|
|
5606 |
}
|
|
5607 |
|
|
5608 |
CardDef.wipe()
|
|
5609 |
carddef = CardDef()
|
|
5610 |
carddef.name = 'items'
|
|
5611 |
carddef.digest_templates = {'default': '{{form_var_attr}}'}
|
|
5612 |
carddef.workflow_roles = {'_editor': user.roles[0]}
|
|
5613 |
carddef.fields = [
|
|
5614 |
fields.ItemField(id='0', type='item', label='item', data_source=data_source),
|
|
5615 |
fields.StringField(id='1', type='string', label='string', varname='attr'),
|
|
5616 |
]
|
|
5617 |
carddef.store()
|
|
5618 |
carddef.data_class().wipe()
|
|
5619 |
baz_ids = set()
|
|
5620 |
for key, value in enumerate(['foo', 'bar', 'baz']):
|
|
5621 |
for i in range(0, 10):
|
|
5622 |
carddata = carddef.data_class()()
|
|
5623 |
carddata.data = {
|
|
5624 |
'0': repr(key),
|
|
5625 |
'0_display': value,
|
|
5626 |
'1': 'attr%s%s' % (key, i),
|
|
5627 |
}
|
|
5628 |
carddata.just_created()
|
|
5629 |
carddata.store()
|
|
5630 |
if value == 'baz':
|
|
5631 |
baz_ids.add(str(carddata.id))
|
|
5632 |
|
|
5633 |
# create custom view
|
|
5634 |
app = login(get_app(pub), username='foo', password='foo')
|
|
5635 |
|
|
5636 |
resp = app.get('/backoffice/data/items/')
|
|
5637 |
if pub.is_using_postgresql():
|
|
5638 |
assert resp.text.count('<tr') == 21 # thead + 20 items (max per page)
|
|
5639 |
else:
|
|
5640 |
assert resp.text.count('<tr') == 31 # thead + all items
|
|
5641 |
resp.forms['listing-settings']['filter-0'].checked = True
|
|
5642 |
resp.forms['listing-settings']['filter-status'].checked = True
|
|
5643 |
resp = resp.forms['listing-settings'].submit()
|
|
5644 |
|
|
5645 |
resp.forms['listing-settings']['filter'].value = 'recorded'
|
|
5646 |
resp = resp.forms['listing-settings'].submit()
|
|
5647 |
|
|
5648 |
resp.forms['save-custom-view']['title'] = 'as data source'
|
|
5649 |
resp.forms['save-custom-view']['visibility'] = 'datasource'
|
|
5650 |
resp = resp.forms['save-custom-view'].submit().follow()
|
|
5651 |
|
|
5652 |
assert resp.forms['listing-settings']['filter-0-value'].attrs['data-allow-template']
|
|
5653 |
assert 'custom value' in [x[2] for x in resp.forms['listing-settings']['filter-0-value'].options]
|
|
5654 |
resp.forms['listing-settings']['filter-0-value'].force_value('{{ form_var_blah_raw }}')
|
|
5655 |
|
|
5656 |
resp = resp.forms['listing-settings'].submit()
|
|
5657 |
assert resp.forms['listing-settings']['filter-0-value'].value == '{{ form_var_blah_raw }}'
|
|
5658 |
assert resp.text.count('<tr') == 1 # thead only
|
|
5659 |
|
|
5660 |
# save custom view with filter
|
|
5661 |
resp = resp.forms['save-custom-view'].submit().follow()
|
|
5662 |
|
|
5663 |
custom_view = pub.custom_view_class.select()[0]
|
|
5664 |
|
|
5665 |
# use custom view as source
|
|
5666 |
ds = {'type': 'carddef:%s:%s' % (carddef.url_name, custom_view.slug)}
|
|
5667 |
formdef.fields = [
|
|
5668 |
fields.ItemField(id='0', type='item', label='item', varname='blah', data_source=data_source),
|
|
5669 |
fields.ItemField(id='1', label='string', type='item', data_source=ds, display_disabled_items=True),
|
|
5670 |
]
|
|
5671 |
formdef.store()
|
|
5672 |
|
|
5673 |
resp = get_app(pub).get('/test/')
|
|
5674 |
assert resp.form['f1'].options == [('', False, '---')]
|
|
5675 |
resp.form['f0'] = '2'
|
|
5676 |
live_resp = app.post('/test/live?modified_field_id=0', params=resp.form.submit_fields())
|
|
5677 |
assert len(live_resp.json['result']['1']['items']) == 10
|
|
5678 |
assert {x['id'] for x in live_resp.json['result']['1']['items']} == baz_ids
|
|
5679 |
|
|
5680 |
resp.form['f1'].options = []
|
|
5681 |
for item in live_resp.json['result']['1']['items']:
|
|
5682 |
# simulate javascript filling the <select>
|
|
5683 |
resp.form['f1'].options.append((item['id'], False, item['text']))
|
|
5684 |
|
|
5685 |
resp.form['f1'] = resp.form['f1'].options[0][0]
|
|
5686 |
resp = resp.form.submit('submit') # -> validation page
|
|
5687 |
resp = resp.form.submit('submit') # -> submit
|
|
5688 |
assert formdef.data_class().select()[0].data['1'] in baz_ids
|
|
5689 |
|
|
5690 |
# same in autocomplete mode
|
|
5691 |
formdef.fields[1].display_mode = 'autocomplete'
|
|
5692 |
formdef.store()
|
|
5693 |
app = get_app(pub)
|
|
5694 |
resp = app.get('/test/')
|
|
5695 |
# simulate select2 mode, with qommon.forms.js adding an extra hidden widget
|
|
5696 |
resp.form.fields['f1_display'] = Hidden(form=resp.form, tag='input', name='f1_display', pos=10)
|
|
5697 |
select2_url = resp.pyquery('select:last').attr['data-select2-url']
|
|
5698 |
resp_json = app.get(select2_url + '?q=')
|
|
5699 |
assert len(resp_json.json['data']) == 0
|
|
5700 |
resp.form['f0'] = '2'
|
|
5701 |
|
|
5702 |
live_resp = app.post('/test/live?modified_field_id=0', params=resp.form.submit_fields())
|
|
5703 |
new_select2_url = live_resp.json['result']['1']['source_url']
|
|
5704 |
resp_json = app.get(new_select2_url + '?q=')
|
|
5705 |
assert len(resp_json.json['data']) == 10
|
|
5706 |
assert {str(x['id']) for x in resp_json.json['data']} == baz_ids
|
|
5707 |
|
|
5708 |
resp.form['f1'].force_value(str(resp_json.json['data'][0]['id']))
|
|
5709 |
resp.form.fields['f1_display'].force_value(resp_json.json['data'][0]['text'])
|
|
5710 |
|
|
5711 |
resp = resp.form.submit('submit') # -> validation page
|
|
5712 |
resp = resp.form.submit('submit') # -> submit
|
|
5713 |
assert formdef.data_class().select()[0].data['1'] in baz_ids
|
|
5714 |
|
|
5715 |
|
|
5716 |
def test_dynamic_item_field_from_custom_view_on_cards_lookup_by_value(pub):
|
|
5717 |
if not pub.is_using_postgresql():
|
|
5718 |
pytest.skip('this requires SQL')
|
|
5719 |
return
|
|
5720 |
|
|
5721 |
pub.role_class.wipe()
|
|
5722 |
pub.custom_view_class.wipe()
|
|
5723 |
|
|
5724 |
user = create_user(pub)
|
|
5725 |
role = pub.role_class(name='xxx')
|
|
5726 |
role.store()
|
|
5727 |
user.roles = [role.id]
|
|
5728 |
user.is_admin = True
|
|
5729 |
user.store()
|
|
5730 |
|
|
5731 |
formdef = create_formdef()
|
|
5732 |
formdef.data_class().wipe()
|
|
5733 |
|
|
5734 |
data_source = {
|
|
5735 |
'type': 'formula',
|
|
5736 |
'value': repr(
|
|
5737 |
[
|
|
5738 |
{'id': '0', 'text': 'foo'},
|
|
5739 |
{'id': '1', 'text': 'bar'},
|
|
5740 |
{'id': '2', 'text': 'baz'},
|
|
5741 |
]
|
|
5742 |
),
|
|
5743 |
}
|
|
5744 |
|
|
5745 |
CardDef.wipe()
|
|
5746 |
carddef = CardDef()
|
|
5747 |
carddef.name = 'items'
|
|
5748 |
carddef.digest_templates = {'default': '{{form_var_attr}}'}
|
|
5749 |
carddef.workflow_roles = {'_editor': user.roles[0]}
|
|
5750 |
carddef.fields = [
|
|
5751 |
fields.ItemField(id='0', type='item', label='item', data_source=data_source),
|
|
5752 |
fields.StringField(id='1', type='string', label='string', varname='attr'),
|
|
5753 |
]
|
|
5754 |
carddef.store()
|
|
5755 |
carddef.data_class().wipe()
|
|
5756 |
baz_ids = set()
|
|
5757 |
for key, value in enumerate(['foo', 'bar', 'baz']):
|
|
5758 |
for i in range(0, 10):
|
|
5759 |
carddata = carddef.data_class()()
|
|
5760 |
carddata.data = {
|
|
5761 |
'0': repr(key),
|
|
5762 |
'0_display': value,
|
|
5763 |
'1': 'attr%s%s' % (key, i),
|
|
5764 |
}
|
|
5765 |
carddata.just_created()
|
|
5766 |
carddata.store()
|
|
5767 |
if value == 'baz':
|
|
5768 |
baz_ids.add(str(carddata.id))
|
|
5769 |
|
|
5770 |
# create custom view
|
|
5771 |
app = login(get_app(pub), username='foo', password='foo')
|
|
5772 |
|
|
5773 |
resp = app.get('/backoffice/data/items/')
|
|
5774 |
if pub.is_using_postgresql():
|
|
5775 |
assert resp.text.count('<tr') == 21 # thead + 20 items (max per page)
|
|
5776 |
else:
|
|
5777 |
assert resp.text.count('<tr') == 31 # thead + all items
|
|
5778 |
resp.forms['listing-settings']['filter-0'].checked = True
|
|
5779 |
resp.forms['listing-settings']['filter-status'].checked = True
|
|
5780 |
resp = resp.forms['listing-settings'].submit()
|
|
5781 |
|
|
5782 |
resp.forms['listing-settings']['filter'].value = 'recorded'
|
|
5783 |
resp = resp.forms['listing-settings'].submit()
|
|
5784 |
|
|
5785 |
resp.forms['save-custom-view']['title'] = 'as data source'
|
|
5786 |
resp.forms['save-custom-view']['visibility'] = 'datasource'
|
|
5787 |
resp = resp.forms['save-custom-view'].submit().follow()
|
|
5788 |
|
|
5789 |
assert resp.forms['listing-settings']['filter-0-value'].attrs['data-allow-template']
|
|
5790 |
assert 'custom value' in [x[2] for x in resp.forms['listing-settings']['filter-0-value'].options]
|
|
5791 |
resp.forms['listing-settings']['filter-0-value'].force_value('{{ form_var_blah }}')
|
|
5792 |
|
|
5793 |
resp = resp.forms['listing-settings'].submit()
|
|
5794 |
assert resp.forms['listing-settings']['filter-0-value'].value == '{{ form_var_blah }}'
|
|
5795 |
assert resp.text.count('<tr') == 1 # thead only
|
|
5796 |
|
|
5797 |
# save custom view with filter
|
|
5798 |
resp = resp.forms['save-custom-view'].submit().follow()
|
|
5799 |
|
|
5800 |
custom_view = pub.custom_view_class.select()[0]
|
|
5801 |
|
|
5802 |
# use custom view as source
|
|
5803 |
ds = {'type': 'carddef:%s:%s' % (carddef.url_name, custom_view.slug)}
|
|
5804 |
formdef.fields = [
|
|
5805 |
fields.ItemField(id='0', type='item', label='item', varname='blah', data_source=data_source),
|
|
5806 |
fields.ItemField(id='1', label='string', type='item', data_source=ds, display_disabled_items=True),
|
|
5807 |
]
|
|
5808 |
formdef.store()
|
|
5809 |
|
|
5810 |
resp = get_app(pub).get('/test/')
|
|
5811 |
assert resp.form['f1'].options == [('', False, '---')]
|
|
5812 |
resp.form['f0'] = 'baz' # I guess it should be something like f0_display
|
|
5813 |
live_resp = app.post('/test/live?modified_field_id=0', params=resp.form.submit_fields())
|
|
5814 |
assert len(live_resp.json['result']['1']['items']) == 10
|
|
5815 |
assert {x['id'] for x in live_resp.json['result']['1']['items']} == baz_ids
|
|
5816 |
|
|
5817 |
resp.form['f1'].options = []
|
|
5818 |
for item in live_resp.json['result']['1']['items']:
|
|
5819 |
# simulate javascript filling the <select>
|
|
5820 |
resp.form['f1'].options.append((item['id'], False, item['text']))
|
|
5821 |
|
|
5822 |
resp.form['f1'] = resp.form['f1'].options[0][0]
|
|
5823 |
resp = resp.form.submit('submit') # -> validation page
|
|
5824 |
resp = resp.form.submit('submit') # -> submit
|
|
5825 |
assert formdef.data_class().select()[0].data['1'] in baz_ids
|
|
5826 |
|
|
5827 |
# same in autocomplete mode
|
|
5828 |
formdef.fields[1].display_mode = 'autocomplete'
|
|
5829 |
formdef.store()
|
|
5830 |
app = get_app(pub)
|
|
5831 |
resp = app.get('/test/')
|
|
5832 |
# simulate select2 mode, with qommon.forms.js adding an extra hidden widget
|
|
5833 |
resp.form.fields['f1_display'] = Hidden(form=resp.form, tag='input', name='f1_display', pos=10)
|
|
5834 |
select2_url = resp.pyquery('select:last').attr['data-select2-url']
|
|
5835 |
resp_json = app.get(select2_url + '?q=')
|
|
5836 |
assert len(resp_json.json['data']) == 0
|
|
5837 |
resp.form['f0'] = 'baz' # I guess it should be something like f0_display
|
|
5838 |
|
|
5839 |
live_resp = app.post('/test/live?modified_field_id=0', params=resp.form.submit_fields())
|
|
5840 |
new_select2_url = live_resp.json['result']['1']['source_url']
|
|
5841 |
resp_json = app.get(new_select2_url + '?q=')
|
|
5842 |
assert len(resp_json.json['data']) == 10
|
|
5843 |
assert {str(x['id']) for x in resp_json.json['data']} == baz_ids
|
|
5844 |
|
|
5845 |
resp.form['f1'].force_value(str(resp_json.json['data'][0]['id']))
|
|
5846 |
resp.form.fields['f1_display'].force_value(resp_json.json['data'][0]['text'])
|
|
5847 |
|
|
5848 |
resp = resp.form.submit('submit') # -> validation page
|
|
5849 |
resp = resp.form.submit('submit') # -> submit
|
|
5850 |
assert formdef.data_class().select()[0].data['1'] in baz_ids
|
|
5851 |
|
|
5852 |
|
5579 |
5853 |
def test_item_field_from_cards_check_lazy_live(pub):
|
5580 |
5854 |
create_user(pub)
|
5581 |
5855 |
formdef = create_formdef()
|
5582 |
5856 |
formdef.data_class().wipe()
|
5583 |
5857 |
|
5584 |
5858 |
CardDef.wipe()
|
5585 |
5859 |
carddef = CardDef()
|
5586 |
5860 |
carddef.name = 'items'
|
5587 |
|
-
|