Project

General

Profile

0001-api-handle-submit-of-forms-with-date-file-and-map-fi.patch

Benjamin Dauvergne, 23 February 2016 03:46 PM

Download (6.49 KB)

View differences:

Subject: [PATCH] api: handle submit of forms with date, file and map fields
 (#10059)

 tests/test_api.py | 54 +++++++++++++++++++++++++++++++++++++++++-------------
 wcs/api.py        |  7 +++++++
 wcs/fields.py     | 25 +++++++++++++++++++++++++
 3 files changed, 73 insertions(+), 13 deletions(-)
tests/test_api.py
440 440
            data_source={'type': 'foobar'}),
441 441
        fields.ItemField(id='2', label='foobar2', varname='foobar2',
442 442
            data_source={'type': 'foobar_jsonp'}),
443
        fields.DateField(id='3', label='foobar3', varname='date'),
444
        fields.FileField(id='4', label='foobar4', varname='file'),
445
        fields.MapField(id='5', label='foobar5', varname='map'),
443 446
    ]
444 447
    formdef.store()
445 448
    data_class = formdef.data_class()
......
451 454
    signed_url = sign_url('http://example.net/api/formdefs/test/submit' +
452 455
            '?format=json&orig=coucou&email=%s' % urllib.quote(local_user.email), '1234')
453 456
    url = signed_url[len('http://example.net'):]
454
    resp = get_app(pub).post_json(url,
455
                                  {'data':
456
                                   {'foobar0': 'xxx',
457
                                    'foobar1': '1',
458
                                    'foobar1_structured': {
459
                                        'id': '1',
460
                                        'text': 'foo',
461
                                        'more': 'XXX',
462
                                    },
463
                                    'foobar2': 'bar',
464
                                    'foobar2_raw': '10',
465
                                   }
466
                                  })
457
    payload = {
458
        'data':
459
            {
460
                'foobar0': 'xxx',
461
                'foobar1': '1',
462
                'foobar1_structured': {
463
                    'id': '1',
464
                    'text': 'foo',
465
                    'more': 'XXX',
466
                },
467
                'foobar2': 'bar',
468
                'foobar2_raw': '10',
469
                'date': '1970-01-01',
470
                'file': {
471
                    'filename': 'test.txt',
472
                    'content': base64.b64encode('test'),
473
                },
474
                'map': {
475
                    'lat': 1.5,
476
                    'lon': 2.25,
477
                },
478
            }
479
    }
480
    resp = get_app(pub).post_json(url, payload)
467 481
    assert resp.json['err'] == 0
468 482
    assert data_class.get(resp.json['data']['id']).status == 'wf-new'
469 483
    assert data_class.get(resp.json['data']['id']).user_id == str(local_user.id)
......
473 487
    assert data_class.get(resp.json['data']['id']).data['1_structured'] == source[0]
474 488
    assert data_class.get(resp.json['data']['id']).data['2'] == '10'
475 489
    assert data_class.get(resp.json['data']['id']).data['2_display'] == 'bar'
490
    assert data_class.get(resp.json['data']['id']).data['3'] == time.struct_time((1970, 1, 1, 0, 0,
491
                                                                                 0, 3, 1, -1))
492

  
493
    assert data_class.get(resp.json['data']['id']).data['4'].orig_filename == 'test.txt'
494
    assert data_class.get(resp.json['data']['id']).data['4'].get_content() == 'test'
495
    assert data_class.get(resp.json['data']['id']).data['5'] == '1.5;2.25'
496
    # test bijectivity
497
    assert (formdef.fields[3].get_json_value(data_class.get(resp.json['data']['id']).data['3']) ==
498
            payload['data']['date'])
499
    for k in payload['data']['file']:
500
        data = data_class.get(resp.json['data']['id']).data['4']
501
        assert formdef.fields[4].get_json_value(data)[k] == payload['data']['file'][k]
502
    assert (formdef.fields[5].get_json_value(data_class.get(resp.json['data']['id']).data['5']) ==
503
            payload['data']['map'])
476 504

  
477 505
    data_class.wipe()
478 506

  
wcs/api.py
243 243
                data[field.id] = data.pop(field.varname)
244 244
            if field.store_structured_value and structured in data:
245 245
                data['%s_structured' % field.id] = data.pop(structured)
246
        # parse special fields
247
        for field in self.formdef.fields:
248
            if not hasattr(field, 'from_json_value'):
249
                continue
250
            if not field.id in data:
251
                continue
252
            data[field.id] = field.from_json_value(data[field.id])
246 253
        formdata.data = json_input['data']
247 254
        meta = json_input.get('meta') or {}
248 255
        if meta.get('backoffice-submission'):
wcs/fields.py
763 763
            'content': base64.b64encode(value.get_content())
764 764
        }
765 765

  
766
    def from_json_value(self, value):
767
        if 'filename' in value and 'content' in value:
768
            content = base64.b64decode(value['content'])
769
            content_type = value.get('content_type', 'application/octet-stream')
770
            if content_type.startswith('text/'):
771
                charset = 'utf-8'
772
            else:
773
                charset = None
774
            upload = PicklableUpload(value['filename'], content_type, charset)
775
            upload.receive([content])
776
            return upload
777
        return None
778

  
766 779
    def perform_more_widget_changes(self, form, kwargs, edit = True):
767 780
        if not edit:
768 781
            value = get_request().get_field(self.field_key)
......
915 928
        except TypeError:
916 929
            return ''
917 930

  
931
    def from_json_value(self, value):
932
        try:
933
            return time.strptime(value, '%Y-%m-%d')
934
        except (TypeError, ValueError):
935
            return None
936

  
918 937
register_field_class(DateField)
919 938

  
920 939

  
......
1756 1775
            return None
1757 1776
        return {'lat': lat, 'lon': lon}
1758 1777

  
1778
    def from_json_value(self, value):
1779
        if 'lat' in value and 'lon' in value:
1780
            return '%s;%s' % (float(value['lat']), float(value['lon']))
1781
        else:
1782
            return None
1783

  
1759 1784
register_field_class(MapField)
1760 1785

  
1761 1786

  
1762
-