def test_list_view_current_version(self):
     make_disclaimer_content(disclaimer_terms='Foo')
     make_disclaimer_content(disclaimer_terms='Bar')
     latest = make_disclaimer_content(disclaimer_terms='Foobar')
     assert DisclaimerContent.current() == latest
     resp = self.client.get(self.list_url)
     assert resp.context_data["current_version"] == latest.version
Beispiel #2
0
    def test_disclaimer_health_questionnaire_required_fields(self):
        make_disclaimer_content(
            form=[
                    {
                        'type': 'text',
                        'required': False,
                        'label': 'Say something',
                        'name': 'text-1',
                        'subtype': 'text'
                    },
                    {
                        'type': 'text',
                        'required': True,
                        'label': 'What is your favourite colour?',
                        'name': 'text-2',
                        'choices': ["red", "green", "blue"],
                        'subtype': 'text'
                    }
                ],
            version=None  # make sure it's the latest
        )
        self.login(self.student_user)
        url = reverse('accounts:disclaimer_form', args=(self.student_user.id,))
        # form data only has response for qn 0 (not required)
        resp = self.client.post(url, {**self.form_data})
        assert resp.status_code == 200
        form = resp.context_data["form"]
        assert form.errors == {"health_questionnaire_responses": ["Please fill in all required fields."]}

        form_data = {**self.form_data}
        del form_data["health_questionnaire_responses_0"]
        form_data["health_questionnaire_responses_1"] = "red"
        resp = self.client.post(url, {**form_data})
        assert resp.status_code == 302
Beispiel #3
0
 def test_disclaimer_health_questionnaire(self):
     # Make new disclaimer version with questionnaire - this should be the new current version
     make_disclaimer_content(
         form=[
                 {
                     'type': 'text',
                     'required': False,
                     'label': 'Say something',
                     'name': 'text-1',
                     'subtype': 'text'
                 },
                 {
                     'type': 'text',
                     'required': True,
                     'label': 'What is your favourite colour?',
                     'name': 'text-2',
                     'choices': ["red", "green", "blue"],
                     'subtype': 'text'
                 }
             ],
         version=None
     )
     self.login(self.student_user)
     url = reverse('accounts:disclaimer_form', args=(self.student_user.id,))
     resp = self.client.get(url)
     form = resp.context_data["form"]
     # disclaimer content questionnaire fields have been translated into form fields
     questionnaire_fields = form.fields['health_questionnaire_responses'].fields
     assert questionnaire_fields[0].label == "Say something"
     # text field initial is set to "-"
     assert questionnaire_fields[0].initial == "-"
     assert questionnaire_fields[1].label == "What is your favourite colour?"
Beispiel #4
0
 def test_new_online_disclaimer_with_current_version_is_active(self):
     disclaimer_content = make_disclaimer_content(
         version=None
     )  # ensure version is incremented from any existing ones
     disclaimer = make_online_disclaimer(user=self.student_user,
                                         version=disclaimer_content.version)
     assert disclaimer.is_active
     make_disclaimer_content(version=None)
     assert disclaimer.is_active is False
Beispiel #5
0
    def test_disclaimer_content_first_version(self):
        DisclaimerContent.objects.all().delete()
        assert DisclaimerContent.objects.exists() is False
        assert DisclaimerContent.current_version() == 0

        content = make_disclaimer_content()
        assert content.version == 1.0

        content1 = make_disclaimer_content()
        assert content1.version == 2.0
 def test_add_disclaimer_content_no_content_change(self):
     make_disclaimer_content(disclaimer_terms='test', version=None)
     resp = self.client.post(
         reverse("studioadmin:add_disclaimer_content"), {
             **self.form_default, "disclaimer_terms": "test",
             "publish": "Publish"
         })
     assert resp.context_data["form"].errors == {
         "__all__": [
             'No changes made from previous version; new version must update disclaimer content'
         ]
     }
 def test_edit_published_version_with_existing_draft(self):
     published_disclaimer_content = make_disclaimer_content(
         is_draft=False, disclaimer_terms="Foo", version=None)
     draft_disclaimer_content = make_disclaimer_content(
         is_draft=True, disclaimer_terms="Bar", version=None)
     url = reverse("studioadmin:edit_disclaimer_content",
                   args=(published_disclaimer_content.version, ))
     resp = self.client.get(url)
     # redirect to latest draft view
     assert resp.status_code == 302
     assert resp.url == reverse("studioadmin:edit_disclaimer_content",
                                args=(draft_disclaimer_content.version, ))
Beispiel #8
0
    def test_disclaimer_required(self):
        """
        test that page redirects if there is no user logged in
        """
        url = reverse("booking:disclaimer_required", args=(self.student_user.id,))
        resp = self.client.get(url)
        assert resp.status_code == 200
        assert resp.context['has_expired_disclaimer'] is False
        assert resp.context['disclaimer_user'] == self.student_user

        self.make_disclaimer(self.student_user)
        make_disclaimer_content(version=None)
        resp = self.client.get(url)
        assert resp.status_code == 200
        assert resp.context['has_expired_disclaimer'] is True
Beispiel #9
0
    def test_cannot_update_terms_after_first_save(self):
        disclaimer_content = make_disclaimer_content(
            disclaimer_terms="foo",
            version=None  # ensure version is incremented from any existing ones
        )

        with self.assertRaises(ValueError):
            disclaimer_content.disclaimer_terms = 'foo1'
            disclaimer_content.save()
 def test_edit_draft_version(self):
     DisclaimerContent.objects.all().delete()
     disclaimer_content = make_disclaimer_content(is_draft=True,
                                                  disclaimer_terms="Foo",
                                                  version=None)
     url = reverse("studioadmin:edit_disclaimer_content",
                   args=(disclaimer_content.version, ))
     resp = self.client.get(url)
     # no previous version to reset to
     assert "Reset to latest published version" not in resp.rendered_content
     assert resp.context_data["disclaimer_content"] == disclaimer_content
 def test_add_new_with_existing_draft(self):
     draft_disclaimer_content = make_disclaimer_content(
         is_draft=True, disclaimer_terms="Bar", version=None)
     resp = self.client.get(reverse("studioadmin:add_disclaimer_content"))
     # redirect to latest draft view
     assert resp.status_code == 302
     assert resp.url == reverse("studioadmin:edit_disclaimer_content",
                                args=(draft_disclaimer_content.version, ))
     resp = self.client.get(reverse("studioadmin:add_disclaimer_content"),
                            follow=True)
     assert "Cannot add a new version while a draft already exists. Editing latest draft version" in resp.rendered_content
 def test_edit_disclaimer_content_unknown_action(self):
     draft_disclaimer_content = make_disclaimer_content(
         is_draft=True, disclaimer_terms="Bar", version=None)
     url = reverse("studioadmin:edit_disclaimer_content",
                   args=(draft_disclaimer_content.version, ))
     with pytest.raises(ValidationError):
         self.client.post(
             url, {
                 **self.form_default, "disclaimer_terms": "test",
                 "foo": "Foo",
                 "version": draft_disclaimer_content.version
             })
 def test_edit_disclaimer_content_form_invalid(self):
     published_disclaimer_content = make_disclaimer_content(
         is_draft=False, disclaimer_terms="Foo", version=None)
     draft_disclaimer_content = make_disclaimer_content(
         is_draft=True, disclaimer_terms="Bar", version=None)
     url = reverse("studioadmin:edit_disclaimer_content",
                   args=(draft_disclaimer_content.version, ))
     resp = self.client.post(
         url, {
             **self.form_default, "disclaimer_terms": "Foo",
             "form": json.dumps(published_disclaimer_content.form),
             "version": draft_disclaimer_content.version,
             "save_draft": "Save as draft"
         })
     assert resp.status_code == 200
     assert resp.context_data["form_errors"] == {
         "__all__": [
             "No changes made from previous version; new version must update disclaimer content"
         ]
     }
     draft_disclaimer_content.refresh_from_db()
    def test_edit_published_version(self):
        disclaimer_content = make_disclaimer_content(is_draft=False,
                                                     disclaimer_terms="Foo",
                                                     version=None)
        url = reverse("studioadmin:edit_disclaimer_content",
                      args=(disclaimer_content.version, ))
        resp = self.client.get(url)
        # No other draft versions, redirect to list view
        assert resp.status_code == 302
        assert resp.url == reverse("studioadmin:disclaimer_contents")

        resp = self.client.get(url, follow=True)
        assert "Published disclaimer versions cannot be edited; make a new version if updates are required." in resp.rendered_content
Beispiel #15
0
    def test_can_update_and_make_draft_published(self):
        content = make_disclaimer_content(is_draft=True,
                                          disclaimer_terms="first versin")
        first_issue_date = content.issue_date

        content.disclaimer_terms = "second version"
        content.is_draft = False
        content.save()
        assert first_issue_date < content.issue_date

        with self.assertRaises(ValueError):
            content.disclaimer_terms = "third version"
            content.save()
 def test_reset_draft(self):
     published_disclaimer_content = make_disclaimer_content(
         is_draft=False, disclaimer_terms="Foo", version=None)
     draft_disclaimer_content = make_disclaimer_content(
         is_draft=True, disclaimer_terms="Bar", version=None)
     url = reverse("studioadmin:edit_disclaimer_content",
                   args=(draft_disclaimer_content.version, ))
     resp = self.client.get(url)
     assert "Reset to latest published version" in resp.rendered_content
     resp = self.client.post(
         url, {
             **self.form_default,
             "reset": "Reset to latest published version",
             "disclaimer_terms": draft_disclaimer_content.disclaimer_terms,
             "form": json.dumps(draft_disclaimer_content.form),
             "version": draft_disclaimer_content.version,
         })
     draft_disclaimer_content.refresh_from_db()
     assert draft_disclaimer_content.disclaimer_terms == published_disclaimer_content.disclaimer_terms
     # redirects back to edit page again
     assert resp.status_code == 302
     assert resp.url == reverse("studioadmin:edit_disclaimer_content",
                                args=(draft_disclaimer_content.version, ))
Beispiel #17
0
    def test_cannot_change_existing_published_disclaimer_version(self):
        content = make_disclaimer_content(disclaimer_terms="first version",
                                          version=4,
                                          is_draft=True)
        content.version = 3.8
        content.save()

        assert content.version == 3.8
        content.is_draft = False
        content.save()

        with pytest.raises(ValueError):
            content.version = 4
            content.save()
 def test_edit_disclaimer_content_save_as_draft(self):
     draft_disclaimer_content = make_disclaimer_content(
         is_draft=True, disclaimer_terms="Bar", version=None)
     url = reverse("studioadmin:edit_disclaimer_content",
                   args=(draft_disclaimer_content.version, ))
     self.client.post(
         url, {
             **self.form_default, "disclaimer_terms": "test",
             "save_draft": "Save as draft",
             "version": draft_disclaimer_content.version
         })
     draft_disclaimer_content.refresh_from_db()
     assert draft_disclaimer_content.is_draft is True
     assert DisclaimerContent.current_version() == 0
Beispiel #19
0
 def setUp(self):
     self.create_users()
     self.content = make_disclaimer_content(
         form=[{"label": "test", "type": "text"}]
     )
     self.form_data = {
         "date_of_birth": '01-Jan-1990', 'address': '1 test st',
         'postcode': 'TEST1', 'home_phone': '123445', 'mobile_phone': '124566',
         'emergency_contact_name': 'test1',
         'emergency_contact_relationship': 'mother',
         'emergency_contact_phone': '4547',
         'terms_accepted': True,
         'health_questionnaire_responses_0': ["foo"],
         'password': '******'
     }
Beispiel #20
0
    def test_can_edit_draft_disclaimer_content(self):
        content = make_disclaimer_content(is_draft=True)
        first_issue_date = content.issue_date

        content.disclaimer_terms = "second version"
        content.save()
        assert first_issue_date < content.issue_date

        assert content.disclaimer_terms == "second version"
        content.is_draft = False
        content.save()

        with pytest.raises(ValueError):
            content.disclaimer_terms = "third version"
            content.save()
 def test_publish_draft(self):
     draft_disclaimer_content = make_disclaimer_content(
         is_draft=True, disclaimer_terms="Bar", version=None)
     url = reverse("studioadmin:edit_disclaimer_content",
                   args=(draft_disclaimer_content.version, ))
     self.client.post(
         url, {
             **self.form_default,
             "publish": "Publish",
             "disclaimer_terms": draft_disclaimer_content.disclaimer_terms,
             "form": json.dumps(draft_disclaimer_content.form),
             "version": draft_disclaimer_content.version,
         })
     draft_disclaimer_content.refresh_from_db()
     assert draft_disclaimer_content.is_draft is False
     assert DisclaimerContent.current() == draft_disclaimer_content
Beispiel #22
0
 def test_event_list_booked_events_no_disclaimer(self):
     make_disclaimer_content()
     resp = self.client.get(self.adult_url)
     assert "Complete a disclaimer" in resp.rendered_content
Beispiel #23
0
 def test_status(self):
     disclaimer_content = make_disclaimer_content()
     assert disclaimer_content.status == "published"
     disclaimer_content_draft = make_disclaimer_content(is_draft=True)
     assert disclaimer_content_draft.status == "draft"
Beispiel #24
0
    def test_button_display_course_event(self):
        # With a course event, check that the button displays as expected for:
        # - no disclaimer
        # - not booked (with and without available course blocks)
        # - booked and open
        # - cancelled (with and without available course blocks)
        # - no-show (with and without available course blocks)
        # - course full and booked
        # - course full and cancelled/no-show
        # - event cancelled
        # - on waiting list
        def _element_from_response_by_id(element_id):
            response = self.client.get(self.adult_url)
            soup = BeautifulSoup(response.rendered_content, features="html.parser")
            return soup.find(id=element_id)

        Event.objects.all().delete()
        self.course.number_of_events = 1
        self.course.save()
        event = baker.make_recipe("booking.future_event", event_type=self.aerial_event_type, course=self.course)
        make_disclaimer_content(version=None)

        self.login(self.student_user)
        resp = self.client.get(self.adult_url)
        assert len(sum(list(resp.context_data['events_by_date'].values()), [])) == 1
        assert "Complete a disclaimer" in resp.rendered_content

        # not booked, has disclaimer
        self.make_disclaimer(self.student_user)
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Payment plan required" in book_button.text

        # cancelled, no block
        booking = baker.make(Booking, user=self.student_user, event=event, status="CANCELLED")
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Payment plan required" in book_button.text
        booking.delete()

        # not booked with valid block
        block = baker.make_recipe(
            "booking.course_block", block_config__event_type=self.aerial_event_type,
            block_config__size=1, user=self.student_user, paid=True
        )
        book_button = _element_from_response_by_id(f"book_{event.id}")
        for fragment in ["NOT BOOKED", "Payment plan available", "Course details"]:
            assert fragment in book_button.text

        # cancelled, with block
        booking = baker.make(Booking, user=self.student_user, event=event, status="CANCELLED")
        book_button = _element_from_response_by_id(f"book_{event.id}")
        for fragment in ["NOT BOOKED", "Payment plan available", "Course details"]:
            assert fragment in book_button.text

        # no-show, with block
        booking.status = "OPEN"
        booking.no_show = True
        booking.save()
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Rebook" in book_button.text
        booking.delete()

        # event full
        baker.make(Booking, event=event, _quantity=event.max_participants)
        waiting_list_button = _element_from_response_by_id(f"waiting_list_button_{event.id}")
        assert "Join waiting list" in waiting_list_button.text

        # event full, on waiting list
        baker.make(WaitingListUser, event=event, user=self.student_user)
        waiting_list_button = _element_from_response_by_id(f"waiting_list_button_{event.id}")
        assert "Leave waiting list" in waiting_list_button.text

        # event full, has booking
        Booking.objects.all().delete()
        baker.make(Booking, user=self.student_user, event=event, block=block)
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Cancel" in book_button.text
Beispiel #25
0
    def test_button_display_dropin_event(self):

        def _element_from_response_by_id(element_id):
            response = self.client.get(self.adult_url)
            soup = BeautifulSoup(response.rendered_content, features="html.parser")
            return soup.find(id=element_id)

        Event.objects.all().delete()
        event = baker.make_recipe("booking.future_event", event_type=self.aerial_event_type)
        make_disclaimer_content(version=None)

        self.login(self.student_user)
        resp = self.client.get(self.adult_url)
        assert len(sum(list(resp.context_data['events_by_date'].values()), [])) == 1
        assert "Complete a disclaimer" in resp.rendered_content

        # not booked, has disclaimer
        self.make_disclaimer(self.student_user)
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Payment plan required" in book_button.text

        # cancelled, no block
        booking = baker.make(Booking, user=self.student_user, event=event, status="CANCELLED")
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Payment plan required" in book_button.text
        booking.delete()

        # not booked with valid block
        block = baker.make_recipe(
            "booking.dropin_block", block_config__event_type=self.aerial_event_type,
            block_config__size=10, user=self.student_user, paid=True
        )
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Book Drop-in" in book_button.text

        # cancelled, with block available
        booking = baker.make(Booking, user=self.student_user, event=event, status="CANCELLED")
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Rebook Drop-in" in book_button.text

        # no-show, with block
        booking.status = "OPEN"
        booking.block = block
        booking.no_show = True
        booking.save()
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Rebook Drop-in" in book_button.text
        booking.delete()

        # event full
        baker.make(Booking, event=event, _quantity=event.max_participants)
        waiting_list_button = _element_from_response_by_id(f"waiting_list_button_{event.id}")
        assert "Join waiting list" in waiting_list_button.text

        # event full, on waiting list
        baker.make(WaitingListUser, event=event, user=self.student_user)
        waiting_list_button = _element_from_response_by_id(f"waiting_list_button_{event.id}")
        assert "Leave waiting list" in waiting_list_button.text

        # event full, has booking
        event.max_participants += 1
        event.save()
        baker.make(Booking, user=self.student_user, event=event, block=block)
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Cancel" in book_button.text
Beispiel #26
0
    def test_button_display_course_event(self):
        # With a course event, check that the button displays as expected for:
        # - no disclaimer
        # - not booked (with and without available course blocks)
        # - booked and open
        # - cancelled (with and without available course blocks)
        # - no-show (with and without available course blocks)
        # - course full and booked
        # - course full and cancelled/no-show
        # - event cancelled
        # - on waiting list
        def _element_from_response_by_id(element_id):
            response = self.client.get(self.url)
            soup = BeautifulSoup(response.rendered_content, features="html.parser")
            return soup.find(id=element_id)

        Event.objects.all().delete()
        self.course.number_of_events = 1
        self.course.save()
        event = baker.make_recipe("booking.future_event", event_type=self.aerial_event_type, course=self.course)
        make_disclaimer_content(version=None)

        self.login(self.student_user)
        resp = self.client.get(self.url)
        assert len(sum(list(resp.context_data['events_by_date'].values()), [])) == 1
        assert "Complete a disclaimer" in resp.rendered_content

        # not booked, has disclaimer. Booking button for individual events not shown
        self.make_disclaimer(self.student_user)
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert book_button is None
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "You need a payment plan to book this course" in course_book_button.text

        # cancelled, no block.  Booking button for individual events not shown
        booking = baker.make(Booking, user=self.student_user, event=event, status="CANCELLED")
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert book_button is None
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "You need a payment plan to book this course" in course_book_button.text
        booking.delete()

        # not booked with valid block
        block = baker.make_recipe(
            "booking.course_block", block_config__event_type=self.aerial_event_type,
            block_config__size=1, user=self.student_user, paid=True
        )
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert book_button is None
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "Book Course" in course_book_button.text

        # cancelled, with block
        booking = baker.make(Booking, user=self.student_user, event=event, status="CANCELLED")
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert book_button is None
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "Book Course" in course_book_button.text

        # no-show, with block
        booking.status = "OPEN"
        booking.no_show = True
        booking.save()
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Rebook" in book_button.text
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "Student User is attending this course" in course_book_button.text
        booking.delete()

        # event full
        baker.make(Booking, event=event, _quantity=event.max_participants)
        waiting_list_button = _element_from_response_by_id(f"waiting_list_button_{event.id}")
        assert waiting_list_button is None
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "This course is now full" in course_book_button.text

        # event full, on waiting list
        baker.make(WaitingListUser, event=event, user=self.student_user)
        waiting_list_button = _element_from_response_by_id(f"waiting_list_button_{event.id}")
        assert waiting_list_button is None
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "This course is now full" in course_book_button.text

        # event full, has booking
        Booking.objects.all().delete()
        baker.make(Booking, user=self.student_user, event=event, block=block)
        book_button = _element_from_response_by_id(f"book_{event.id}")
        assert "Cancel" in book_button.text
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "Student User is attending this course" in course_book_button.text

        Booking.objects.all().delete()
        self.course.number_of_events = 2
        self.course.save()
        baker.make_recipe("booking.past_event", course=self.course, event_type=self.aerial_event_type)
        assert self.course.has_started
        assert self.course.allow_partial_booking is False

        # Course started, partial booking not allowed
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert course_book_button is None
        resp = self.client.get(self.url)
        assert "NOTE: This course has started" in resp.rendered_content

        self.course.allow_partial_booking = True
        self.course.save()
        # Course started, partial booking allowed, has partial block
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "Book Course" in course_book_button.text

        # Course started, partial booking allowed, no block
        block.delete()
        course_book_button = _element_from_response_by_id(f"book_course_{self.course.id}")
        assert "You need a payment plan to book this course" in course_book_button.text
        assert "1 class course block" in course_book_button.text
Beispiel #27
0
 def setUp(self):
     self.create_users()
     self.content = make_disclaimer_content(version=5.0)
Beispiel #28
0
 def test_str(self):
     disclaimer_content = make_disclaimer_content()
     assert str(
         disclaimer_content
     ) == f'Disclaimer Content - Version {disclaimer_content.version} (published)'
Beispiel #29
0
 def test_new_version_must_have_new_terms(self):
     make_disclaimer_content(disclaimer_terms="foo", version=None)
     with pytest.raises(ValidationError) as e:
         make_disclaimer_content(disclaimer_terms="foo", version=None)
         assert str(e) == "No changes made to content; not saved"
 def test_detail_view(self):
     policy = make_disclaimer_content(disclaimer_terms='Foo', version=4.1)
     resp = self.client.get(
         reverse("studioadmin:disclaimer_content", args=(policy.version, )))
     assert resp.status_code == 200