kopia lustrzana https://github.com/wagtail/wagtail
				
				
				
			Add form data helpers
							rodzic
							
								
									0a634b0a42
								
							
						
					
					
						commit
						067c26f54d
					
				|  | @ -44,14 +44,21 @@ WagtailPageTests | |||
| 
 | ||||
|         .. code-block:: python | ||||
| 
 | ||||
|             from wagtail.tests.utils.form_data import nested_form_data, streamfield | ||||
| 
 | ||||
|             def test_can_create_content_page(self): | ||||
|                 # Get the HomePage | ||||
|                 root_page = HomePage.objects.get(pk=2) | ||||
| 
 | ||||
|                 # Assert that a ContentPage can be made here, with this POST data | ||||
|                 self.assertCanCreate(root_page, ContentPage, { | ||||
|                 self.assertCanCreate(root_page, ContentPage, nested_form_data({ | ||||
|                     'title': 'About us', | ||||
|                     'body': 'Lorem ipsum dolor sit amet') | ||||
|                     'body': streamfield([ | ||||
|                         ('text', 'Lorem ipsum dolor sit amet'), | ||||
|                     ]) | ||||
|                 })) | ||||
| 
 | ||||
|         See :ref:`form_data_test_helpers` for a set of functions useful for constructing POST data. | ||||
| 
 | ||||
|     .. automethod:: assertAllowedParentPageTypes | ||||
| 
 | ||||
|  | @ -79,3 +86,17 @@ WagtailPageTests | |||
|                 # A HomePage can have ContentPage and EventIndex children | ||||
|                 self.assertAllowedParentPageTypes( | ||||
|                     HomePage, {ContentPage, EventIndex}) | ||||
| 
 | ||||
| 
 | ||||
| .. _form_data_test_helpers: | ||||
| 
 | ||||
| Form data helpers | ||||
| ================= | ||||
| 
 | ||||
| .. automodule:: wagtail.tests.utils.form_data | ||||
| 
 | ||||
|    .. autofunction:: nested_form_data | ||||
| 
 | ||||
|    .. autofunction:: streamfield | ||||
| 
 | ||||
|    .. autofunction:: inline_formset | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ from wagtail.tests.testapp.models import ( | |||
|     BusinessChild, BusinessIndex, BusinessNowherePage, BusinessSubIndex, EventIndex, EventPage, | ||||
|     SimplePage, StreamPage) | ||||
| from wagtail.tests.utils import WagtailPageTests, WagtailTestUtils | ||||
| from wagtail.tests.utils.form_data import inline_formset, nested_form_data, streamfield | ||||
| 
 | ||||
| 
 | ||||
| class TestAssertTagInHTML(WagtailTestUtils, TestCase): | ||||
|  | @ -137,3 +138,60 @@ class TestWagtailPageTests(WagtailPageTests): | |||
|         self.assertAllowedParentPageTypes(BusinessIndex, all_but_business) | ||||
|         with self.assertRaises(AssertionError): | ||||
|             self.assertAllowedParentPageTypes(BusinessSubIndex, {BusinessSubIndex, BusinessIndex}) | ||||
| 
 | ||||
| 
 | ||||
| class TestFormDataHelpers(TestCase): | ||||
|     def test_nested_form_data(self): | ||||
|         result = nested_form_data({ | ||||
|             'foo': 'bar', | ||||
|             'parent': { | ||||
|                 'child': 'field', | ||||
|             }, | ||||
|         }) | ||||
|         self.assertEqual( | ||||
|             result, | ||||
|             {'foo': 'bar', 'parent-child': 'field'} | ||||
|         ) | ||||
| 
 | ||||
|     def test_streamfield(self): | ||||
|         result = nested_form_data({'content': streamfield([ | ||||
|             ('text', 'Hello, world'), | ||||
|             ('text', 'Goodbye, world'), | ||||
|         ])}) | ||||
| 
 | ||||
|         self.assertEqual( | ||||
|             result, | ||||
|             { | ||||
|                 'content-count': '2', | ||||
|                 'content-0-type': 'text', | ||||
|                 'content-0-value': 'Hello, world', | ||||
|                 'content-0-order': 0, | ||||
|                 'content-0-deleted': '', | ||||
|                 'content-1-type': 'text', | ||||
|                 'content-1-value': 'Goodbye, world', | ||||
|                 'content-1-order': 1, | ||||
|                 'content-1-deleted': '', | ||||
|             } | ||||
|         ) | ||||
| 
 | ||||
|     def test_inline_formset(self): | ||||
|         result = nested_form_data({'lines': inline_formset([ | ||||
|             {'text': 'Hello'}, | ||||
|             {'text': 'World'}, | ||||
|         ])}) | ||||
| 
 | ||||
|         self.assertEqual( | ||||
|             result, | ||||
|             { | ||||
|                 'lines-TOTAL_FORMS': '2', | ||||
|                 'lines-INITIAL_FORMS': '0', | ||||
|                 'lines-MIN_NUM_FORMS': '0', | ||||
|                 'lines-MAX_NUM_FORMS': '1000', | ||||
|                 'lines-0-text': 'Hello', | ||||
|                 'lines-0-ORDER': '0', | ||||
|                 'lines-0-DELETE': '', | ||||
|                 'lines-1-text': 'World', | ||||
|                 'lines-1-ORDER': '1', | ||||
|                 'lines-1-DELETE': '', | ||||
|             } | ||||
|         ) | ||||
|  |  | |||
|  | @ -0,0 +1,115 @@ | |||
| """ | ||||
| The ``assertCanCreate`` method requires page data to be passed in | ||||
| the same format that the page edit form would submit. For complex | ||||
| page types, it can be difficult to construct this data structure by hand; | ||||
| the ``wagtail.tests.utils.form_data`` module provides a set of helper | ||||
| functions to assist with this. | ||||
| """ | ||||
| 
 | ||||
| 
 | ||||
| def _nested_form_data(data): | ||||
|     if isinstance(data, dict): | ||||
|         items = data.items() | ||||
|     elif isinstance(data, list): | ||||
|         items = enumerate(data) | ||||
| 
 | ||||
|     for key, value in items: | ||||
|         key = str(key) | ||||
|         if isinstance(value, (dict, list)): | ||||
|             for child_keys, child_value in _nested_form_data(value): | ||||
|                 yield [key] + child_keys, child_value | ||||
|         else: | ||||
|             yield [key], value | ||||
| 
 | ||||
| 
 | ||||
| def nested_form_data(data): | ||||
|     """ | ||||
|     Translates a nested dict structure into a flat form data dict | ||||
|     with hyphen-separated keys. | ||||
| 
 | ||||
|     .. code-block:: python | ||||
| 
 | ||||
|         nested_form_data({ | ||||
|             'foo': 'bar', | ||||
|             'parent': { | ||||
|                 'child': 'field', | ||||
|             }, | ||||
|         }) | ||||
|         # Returns: {'foo': 'bar', 'parent-child': 'field'} | ||||
|     """ | ||||
|     return {'-'.join(key): value for key, value in _nested_form_data(data)} | ||||
| 
 | ||||
| 
 | ||||
| def streamfield(items): | ||||
|     """ | ||||
|     Takes a list of (block_type, value) tuples and turns it in to | ||||
|     StreamField form data. Use this within a :func:`nested_form_data` | ||||
|     call, with the field name as the key. | ||||
| 
 | ||||
|     .. code-block:: python | ||||
| 
 | ||||
|         nested_form_data({'content': streamfield([ | ||||
|             ('text', 'Hello, world'), | ||||
|         ])}) | ||||
|         # Returns: | ||||
|         # { | ||||
|         #     'content-count': '1', | ||||
|         #     'content-0-type': 'text', | ||||
|         #     'content-0-value': 'Hello, world', | ||||
|         #     'content-0-order': 0, | ||||
|         #     'content-0-deleted': '', | ||||
|         # } | ||||
|     """ | ||||
|     def to_block(index, item): | ||||
|         block, value = item | ||||
|         return {'type': block, 'value': value, 'deleted': '', 'order': index} | ||||
|     data_dict = {str(index): to_block(index, item) | ||||
|                  for index, item in enumerate(items)} | ||||
|     data_dict['count'] = str(len(data_dict)) | ||||
|     return data_dict | ||||
| 
 | ||||
| 
 | ||||
| def inline_formset(items, initial=0, min=0, max=1000): | ||||
|     """ | ||||
|     Takes a list of form data for an InlineFormset and translates | ||||
|     it in to valid POST data. Use this within a :func:`nested_form_data` | ||||
|     call, with the formset relation name as the key. | ||||
| 
 | ||||
|     .. code-block:: python | ||||
| 
 | ||||
|         nested_form_data({'lines': inline_formset([ | ||||
|             {'text': 'Hello'}, | ||||
|             {'text': 'World'}, | ||||
|         ])}) | ||||
|         # Returns: | ||||
|         # { | ||||
|         #     'lines-TOTAL_FORMS': '2', | ||||
|         #     'lines-INITIAL_FORMS': '0', | ||||
|         #     'lines-MIN_NUM_FORMS': '0', | ||||
|         #     'lines-MAX_NUM_FORMS': '1000', | ||||
|         #     'lines-0-text': 'Hello', | ||||
|         #     'lines-0-ORDER': '0', | ||||
|         #     'lines-0-DELETE': '', | ||||
|         #     'lines-1-text': 'World', | ||||
|         #     'lines-1-ORDER': '1', | ||||
|         #     'lines-1-DELETE': '', | ||||
|         # } | ||||
|     """ | ||||
|     def to_form(index, item): | ||||
|         defaults = { | ||||
|             'ORDER': str(index), | ||||
|             'DELETE': '', | ||||
|         } | ||||
|         defaults.update(item) | ||||
|         return defaults | ||||
| 
 | ||||
|     data_dict = {str(index): to_form(index, item) | ||||
|                  for index, item in enumerate(items)} | ||||
| 
 | ||||
|     data_dict.update({ | ||||
|         'TOTAL_FORMS': str(len(data_dict)), | ||||
|         'INITIAL_FORMS': str(initial), | ||||
|         'MIN_NUM_FORMS': str(min), | ||||
|         'MAX_NUM_FORMS': str(max), | ||||
|     }) | ||||
|     return data_dict | ||||
		Ładowanie…
	
		Reference in New Issue
	
	 Matt Westcott
						Matt Westcott