How can I test the functionality of a rendered flask template? - unit-testing

I've got a flask application which renders an html page as a response to one of my endpoints (using jinja2 and render_template()). That html page has a form, which upon submission runs the form field values through some javascript functions which transforms the data and then makes 1 or more api calls to a different endpoint on my flask application.
I'd like to test the functionality of the javascript on that rendered html page. ie, given a certain input to the form fields on that page, ensure that the resulting requests contain the correct payloads.
Is that something that can be done for a flask application? All I've been able to find so far are ways to test the initially rendered html output, but that's not really helpful for me. I want to be able to update values in the form fields and then trigger a form submission and assert the results.

Related

Is there a way in django to update the same page with the response without totally rendering it?

Is there a way in django to update the same page with the response without totally rendering it. I am trying to create a code editor to test. But when I am returning the results my contents are removed. I understand it is because I am rendering the page . I need the contents to retain. How can I do it using redirect? I am including the render statement I used and a screenshot of how it looks here:
Steps:
Handle post request
Program execution code
Save the result in a variable called "message". Then I used
return render(request, 'editor.html', {'message': message})
I want to redirect the message to the same page without rendering a new page.
[Before submission][1]
[After submission][2]
[1]: https://i.stack.imgur.com/BxoLU.png
[2]: https://i.stack.imgur.com/uiEOU.png
Any help will be appreciated. Thank you.
it is possible. using ajax in front-end and render or render_to_string in back-end(Django). using ajax you're able to call a url (with/without data you want to send), then in the views.py you can do anything needed and return render(request,'template.html, context). then in ajax you have success: function (res) { $('#id_of_element').append(res)}. this function in ajax will append the recived response which is a rendered HTML template to the target element.
For that, you have to switch to a different web software paradigm called "single page application", which implies that both, backend and frontend, are functional software components on their own, instead of having a "dumb" HTML frontend that only displays what the backend renders.
In a regular web application, the front end is served from a backend with all the information that is going to display. In a Single Page Application, the front end is served by a server independent of the backend server, and the frontend and backend interact through an API served by the backend.
With this architecture, the frontend component is responsible for requesting and providing data from and to the backend, as well as for displaying the data and getting user's interaction, and the mean for interchanging data with the backend is called an ajax, that is an asynchronous request.
The only language accepted by web browsers is javascript, but there are many frameworks and second level languages that can render a javascript application, like React, Angular, Vue, and many others.

How to build conversational form with django?

I am trying to build a conversational form with Django.
It will be used in landing page. The form questions will be loaded one by one as user answers them. And there will be some greeting and "human-way" responses to user input (such as "wow! you did a good choice!" after user selects one of the choices from form). The experience and look of the app will be like a real-time chat but user can only select one of the choices from form or upload a file/image.
1. Which technology is better to use for it? I am planning to do it with Fetch.
2. Since I want it to work without page reloading, how do I need to load Django forms through Fetch? Do I need to pass elements of it with JSON and construct it in client-side or can I just pass it as an html with {{form.as_p}} and display it in HTML?
Does these options make difference in matter of security?
I do not know anything about Fetch, but anyway I think it must be constructed clientside, but at first I would simply display the form in a template to get the ids of its fields and then use it in clientside code.
What about security - you'll need to pass the csrf token via your form.

Does Django render JS on server side?

I know that Django has default config of SSR (server-side rendering) but all the articles I have gone through mention that the Django-forms are rendered on server side and then sent to the browser. No specific information on the use case when javascript is mixed in the template.
I want to know if I use jquery tables in my Django template. Does that still render on server side? If yes then how does it render Javascript/jquery on the server-side?
I'd be glad if someone corrects me if my question itself has invalid argument.
JavaScript is for browsers so it doesn't matter if you write it in your template or add a link to it. The only way to render JS on the server-side is to actually have an engine doing that for you which Django doesn't.
What Django's template engine does is it will render the template based on the tags and HTML you provided and sends a valid HTML to the user containing the js code or js files alongside CSS and then browser runs those js and CSS codes and renders the final webpage.

Add other elements than fields in Django forms

I'm using Django to set up a website, where users can add spatial informations associated with ecological datasets. I'm using leafletjs to display pins on the map, where datasets have been sampled.
The solution I have now, is to have users write lat/lon as fields. On the other hand, there is an example on the leaflet website where clicking on the map will display the coordinates, and that is much more user friendly. So I'd like to have this + a javascript to fill the lat/lon position, in the form rendered by Django.
Is there any chance I can put that in a Django form, or must I write the form in HTML?
In this case, I would use an AJAX form to post entries in the back end, and upon submission recall the entries and write it out as JSON. Django has native functionality for all of this.
Here is a recent SO example: How to submit form without refreshing page using Django, Ajax, jQuery?

Cross-domain redirect to a partially filled form on Django web application

I have an HTML form in my Django web application (NOT implemented using Django forms) that does POST request.
Now I want to implement a feature so that other web apps, not necessarily django, from different domains, can send some data to my application and get redirected to the web page with this form, partially filled with that data (the data can be JSON).
Besides redirecting, after the user clicks submit on my form, I would also want to send a message to the other server with some short text information.
I am not sure what is the best way to implement this. REST interface like Piston?
Could you give me some general directions I should follow?
You should create a view that handles the POST data from the form and the external web apps.
You should be able to check whether the data you are getting in the view is coming from your site or another by checking request.META['HTTP_REFERER'].
If it is from your site, you can just handle the form as you usually would.
However if it is from an external site, you would instead render the template with the form in it. You can put the information you got from the external site into the context, so you can pre-fill the form in the template.
You should also include a flag in the form to say that this was from an external site, something like:
<input type="hidden" name="external_site_url" value="{{ external_site_url }}">
After that form is submitted, you can check for the existence of external_site_url. If it exists you can then send the message to the other server.
Note, because you want other apps to use your view, you'll have to disable CSRF protection on the view (https://docs.djangoproject.com/en/dev/ref/contrib/csrf/#csrf-protection-should-be-disabled-for-just-a-few-views).
Also, by allowing other apps to use your view, you are opening yourself up to a lot of possible attacks. Be very careful with input validation and only give the view the ability to do the things it really needs -- you don't want an external app to be able to delete entries in your database for example.