Persist raw data in browseable api when do POST

This commit is contained in:
Marcelo Galigniana 2020-10-15 17:38:04 -03:00
parent 59ae95b22f
commit 853e1052cb
5 changed files with 120 additions and 0 deletions

View File

@ -3,3 +3,4 @@ pytest>=6.2.0,<8.0
pytest-cov>=4.0.0,<5.0
pytest-django>=4.5.2,<5.0
importlib-metadata<5.0
selenium==4.7.2

View File

@ -1,3 +1,4 @@
$(document).ready(function() {
$('form').ajaxForm();
persistPostRawDataForm()
});

View File

@ -0,0 +1,22 @@
/**
* Preserve form's raw input after do POST
*/
function persistPostRawDataForm() {
var formContainerId = '#post-generic-content-form'
var $form = $(`${formContainerId} form`)
var $formInput = $(`${formContainerId} textarea`);
var localStorageKey = 'rawDataSubmitted'
var formAction = $form.attr('action')
$form.submit(function () {
var data = sessionStorage.getItem(localStorageKey)
data = data ? JSON.parse(data) : {}
data[formAction] = $formInput.val()
sessionStorage.setItem(localStorageKey, JSON.stringify(data))
});
if (sessionStorage.getItem(localStorageKey)) {
var data = JSON.parse(sessionStorage.getItem(localStorageKey))
$formInput.text(data[formAction])
};
}

View File

@ -295,6 +295,7 @@
</script>
<script src="{% static "rest_framework/js/jquery-3.5.1.min.js" %}"></script>
<script src="{% static "rest_framework/js/ajax-form.js" %}"></script>
<script src="{% static "rest_framework/js/store-data-form.js" %}"></script>
<script src="{% static "rest_framework/js/csrf.js" %}"></script>
<script src="{% static "rest_framework/js/bootstrap.min.js" %}"></script>
<script src="{% static "rest_framework/js/prettify-min.js" %}"></script>

View File

@ -1,8 +1,16 @@
from django.contrib.auth.models import User
from django.contrib.staticfiles.testing import StaticLiveServerTestCase
from django.test import TestCase, override_settings
from selenium.webdriver.common.by import By
from selenium.webdriver.firefox.webdriver import WebDriver
from rest_framework import serializers
from rest_framework.permissions import IsAuthenticated
from rest_framework.routers import SimpleRouter
from rest_framework.test import APIClient
from rest_framework.utils import json
from rest_framework.viewsets import ModelViewSet
from tests.models import BasicModel
from .views import BasicModelWithUsersViewSet, OrganizationPermissions
@ -99,3 +107,90 @@ class NoDropdownWithoutAuthTests(TestCase):
response = self.client.get('/')
content = response.content.decode()
assert '<li class="dropdown">' not in content
class BasicModelSerializer(serializers.ModelSerializer):
class Meta:
model = BasicModel
fields = "__all__"
class ResourceViewSet(ModelViewSet):
serializer_class = BasicModelSerializer
queryset = BasicModel.objects.all()
router = SimpleRouter()
router.register(r'resources', ResourceViewSet)
router.register(r'resources-2', ResourceViewSet)
urlpatterns = []
urlpatterns += router.urls
@override_settings(ROOT_URLCONF='tests.browsable_api.test_browsable_api')
class SeleniumTests(StaticLiveServerTestCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.selenium = WebDriver()
cls.selenium.implicitly_wait(10)
@classmethod
def tearDownClass(cls):
cls.selenium.quit()
super().tearDownClass()
def test_post_raw_data(self):
self.selenium.get('%s%s' % (self.live_server_url, '/resources'))
raw_tab = self.selenium.find_element(By.NAME, "raw-tab")
raw_tab.click()
# Raw data textarea is pre-populated with empty value.
text_input = self.selenium.find_element(By.ID, "id__content")
self.assertEqual(json.loads(text_input.text), {'text': ''})
# Do submit and the data will be presisted then.
text_input.clear()
json_data = json.dumps({"text": "text description"}, indent=4)
text_input.send_keys(json_data)
post_button = self.selenium.find_element(By.CSS_SELECTOR, '#post-generic-content-form div.form-actions button')
post_button.click()
text_input = self.selenium.find_element(By.ID, "id__content")
self.assertEqual(json.loads(text_input.text), {'text': 'text description'})
self.assertEqual(BasicModel.objects.last().text, 'text description')
# Moving to another resource view, the raw data will be clean.
self.selenium.get('%s%s' % (self.live_server_url, '/resources-2'))
text_input = self.selenium.find_element(By.ID, "id__content")
self.assertEqual(json.loads(text_input.text), {'text': ''})
# Do a second submit from the second view.
text_input.clear()
json_data = json.dumps({"text": "text description 2"}, indent=4)
text_input.send_keys(json_data)
post_button = self.selenium.find_element(By.CSS_SELECTOR, '#post-generic-content-form div.form-actions button')
post_button.click()
text_input = self.selenium.find_element(By.ID, "id__content")
self.assertEqual(json.loads(text_input.text), {'text': 'text description 2'})
self.assertEqual(BasicModel.objects.last().text, 'text description 2')
# Do a third submit, from the same view, with the previous data
# (which was pre-populated).
post_button = self.selenium.find_element(By.CSS_SELECTOR, '#post-generic-content-form div.form-actions button')
post_button.click()
self.assertEqual(BasicModel.objects.count(), 3)
self.assertEqual(BasicModel.objects.last().text, 'text description 2')
# Only two keys were stored.
session_storage_data = self.selenium.execute_script(
'return JSON.parse(sessionStorage.getItem("rawDataSubmitted"))'
)
self.assertEqual(
['/resources-2/', '/resources/'],
list(session_storage_data.keys())
)
self.assertEqual(
['{\n "text": "text description 2"\n}', '{\n "text": "text description"\n}'],
list(session_storage_data.values())
)