import django.test from huey.contrib.djhuey import db_task import otree.constants test_client = django.test.Client() @db_task() def submit_expired_url(participant_code, url): from otree.models.participant import Participant # if the participant exists in the DB, # and they did not advance past the page yet # To reduce redundant server traffic, it's OK not to advance the page if the user already got to the next page # themselves, or via "advance slowest participants". # however, we must make sure that the user succeeded in loading the next page fully. # if the user made this page's POST but closed their browser before # the redirect to the next page's GET, then if the next page has a timeout, # it will not get scheduled, and then the auto-timeout chain would be broken. # so, instead of filtering by _index_in_pages (which is set in POST), # we filter by _current_form_page_url (which is set in GET, # AFTER the next page's timeout is scheduled.) if Participant.objects.filter( code=participant_code, _current_form_page_url=url ).exists(): test_client.post( url, data={otree.constants.timeout_happened: True}, follow=True ) @db_task() def ensure_pages_visited(participant_pks): """This is necessary when a wait page is followed by a timeout page. We can't guarantee the user's browser will properly continue to poll the wait page and get redirected, so after a grace period we load the page automatically, to kick off the expiration timer of the timeout page. """ from otree.models.participant import Participant # we used to filter by _index_in_pages, but that is not reliable, # because of the race condition described above. unvisited_participants = Participant.objects.filter(pk__in=participant_pks) for participant in unvisited_participants: # if the wait page is the first page, # then _current_form_page_url could be null. # in this case, use the start_url() instead, # because that will redirect to the current wait page. # (alternatively we could define _current_page_url or # current_wait_page_url) url = participant._url_i_should_be_on() test_client.get(url, follow=True)