Exemplo n.º 1
0
 def test_choose_activity_with_unconfigured_engine(self, mock_choose_activity_by_engine):
     """
     Test sequence is deleted if after creating first activity is not chosen for any reason.
     """
     choose_activity(sequence=self.vpal_sequence)
     sequence_is_exists = Sequence.objects.filter(group=self.vpal_group)
     self.assertFalse(sequence_is_exists)
Exemplo n.º 2
0
 def test_choose_activity_from_completed_collection(self, mock_choose_activity_by_engine):
     """
     Test sequence becomes completed if at least one sequence_item exists and there no new activity chosen.
     """
     sequence_item = SequenceItem.objects.create(sequence=self.vpal_sequence, activity=self.activity)
     choose_activity(sequence_item=sequence_item)
     completed_sequence = Sequence.objects.filter(group=self.vpal_group).first()
     self.assertEqual(completed_sequence, self.vpal_sequence)
     self.assertTrue(completed_sequence.completed)
Exemplo n.º 3
0
def learner_flow(request, lti_consumer, tool_provider, collection_slug=None, group_slug=None, unique_marker=''):
    """
    Define logic flow for Learner.
    """
    if not collection_slug:
        return stub_page(request)

    collection, collection_group, engine = get_collection_collectiongroup_engine(collection_slug, group_slug)

    lti_user, created = LtiUser.objects.get_or_create(
        user_id=request.POST['user_id'],
        lti_consumer=lti_consumer,
        defaults={'course_id': request.POST['context_id']}
    )
    log.debug("LTI user {}: user_id='{}'".format('created' if created else 'picked', lti_user.user_id))

    sequence, created = Sequence.objects.get_or_create(
        lti_user=lti_user,
        collection=collection,
        group=collection_group,
        suffix=unique_marker,
    )

    # Update sequence metadata with lti parameters required by the engine
    sequence.fulfil_sequence_metadata(engine.lti_params, tool_provider.launch_params)

    strict_forward = collection.strict_forward
    request.session['Lti_sequence'] = sequence.id
    request.session['Lti_strict_forward'] = strict_forward

    if sequence.completed:
        log.debug("Sequence {} is already completed".format(sequence.id))
        return redirect(reverse('module:sequence-complete', kwargs={'pk': sequence.id}))

    if created:
        log.debug("Sequence {} was created".format(sequence))
        start_activity = module_utils.choose_activity(sequence_item=None, sequence=sequence)
        if not start_activity:
            log.warning('Instructor configured empty Collection.')
            return stub_page(
                request,
                title="Warning",
                message="Cannot get the first question to start.",
                tip="Please try again later"
            )
        sequence_item = create_sequence_item(
            request, sequence, start_activity, tool_provider, lti_consumer
        )
    else:
        sequence_item = find_last_sequence_item(sequence, strict_forward)
    sequence_item_id = sequence_item.id if sequence_item else None
    if not sequence_item_id:
        return stub_page(
            request,
            title="Warning",
            message="Cannot find sequence item to start from.",
            tip="Ask help from the site admins."
        )

    return redirect(reverse('module:sequence-item', kwargs={'pk': sequence_item_id}))
Exemplo n.º 4
0
def sequence_item_next(request, pk):
    try:
        next_forbidden, last_item, sequence_item = _check_next_forbidden(pk)
    except SequenceItem.DoesNotExist:
        log.exception("SequenceItem which supposed to exist can't be found!")
        return render(
            request,
            template_name="bridge_lti/announcement.html",
            context={
                'title': 'Something went wrong...',
                'message':
                'Internal problem was occurred, please, inform course personal about your experience.',
                'tip': "ERROR: next sequence item can't be proposed",
            })
    if next_forbidden:
        return redirect("{}?forbidden=true".format(
            reverse('module:sequence-item', kwargs={'pk': sequence_item.id})))

    next_sequence_item = SequenceItem.objects.filter(
        sequence=sequence_item.sequence,
        position=sequence_item.position + 1).first()

    log.debug("Picked next sequence item is: {}".format(next_sequence_item))

    if not next_sequence_item or next_sequence_item.position == last_item:
        activity = utils.choose_activity(sequence_item)
        update_activity = request.session.pop('Lti_update_activity', None)
        if next_sequence_item is None:
            sequence = sequence_item.sequence
            policy = sequence.collection_order.grading_policy.policy_instance(
                sequence=sequence)
            policy.send_grade()
            if not activity:
                if sequence.completed:
                    return redirect(
                        reverse('module:sequence-complete',
                                kwargs={'pk': sequence_item.sequence_id}))
                return stub_page(
                    request,
                    title="Warning",
                    message="Cannot get next activity from the engine.",
                    tip="Try again later or connect with the instructor.")

            next_sequence_item = SequenceItem.objects.create(
                sequence=sequence_item.sequence,
                activity=activity,
                position=sequence_item.position + 1)
        elif update_activity:
            log.debug(
                'Bridge updates activity in the un-submitted SequenceItem')
            if activity:
                next_sequence_item.activity = activity
                next_sequence_item.save()
    return redirect(
        reverse('module:sequence-item', kwargs={'pk': next_sequence_item.id}))
Exemplo n.º 5
0
 def test_choose_activity(self):
     try:
         # test if 2 activities has the same launch url but has different collections
         # this method should return only one activity, filtered by sequence.collection
         chosen_activity = choose_activity(sequence=self.sequence)
     except MultipleObjectsReturned as e:
         log.error(Activity.ojbects.all().values('collection', 'source_launch_url'))
         self.fail(e)
     expected_activity = Activity.objects.get(
         collection=self.sequence.collection, source_launch_url=f"{self.source_launch_url}5"
     )
     self.assertEqual(chosen_activity, expected_activity)
Exemplo n.º 6
0
def demo_collection(request, collection_order_slug):
    """
    View for the demonstration and testing of the adaptivity behaviour.
    """
    __, collection_order = get_engine_and_collection_order(
        collection_order_slug)

    lti_lms_platform = LtiLmsPlatform.objects.first()
    test_lti_user, created = LtiUser.objects.get_or_create(
        user_id=DEMO_USER,
        lti_lms_platform=lti_lms_platform,
    )

    test_sequence, created = Sequence.objects.get_or_create(
        lti_user=test_lti_user, collection_order=collection_order)

    strict_forward = collection_order.strict_forward
    request.session['Lti_sequence'] = test_sequence.id
    request.session['Lti_strict_forward'] = strict_forward

    back_url = request.GET.get('back_url', '')

    context = {
        'sequence_pk': test_sequence.id,
        'back_url': back_url,
        'forbidden': request.GET.get('forbidden', ''),
    }

    if created or not test_sequence.items.exists():
        suffix = int(datetime.datetime.now().timestamp())
        cache.set(settings.TEST_SEQUENCE_SUFFIX, suffix)
        test_sequence.suffix = suffix
        test_sequence.save()
        log.debug("Sequence {} was created".format(test_sequence))
        start_activity = utils.choose_activity(sequence=test_sequence)
        if not start_activity:
            log.warning('Instructor configured empty Collection.')
            return stub_page(
                request,
                title="Warning",
                message="Cannot get the first question to start.",
                tip="Please try again later",
                demo=True,
                sequence=test_sequence,
                back_url=back_url,
            )
        sequence_item = SequenceItem.objects.create(sequence=test_sequence,
                                                    activity=start_activity,
                                                    position=1)
        next_forbidden, _, _ = _check_next_forbidden(sequence_item.id)
        context.update({"forbidden": next_forbidden})
    else:
        s_item_id = request.GET.get(
            'sequence_item_id') or test_sequence.items.last().id
        log.debug(f'SequienceItem id: {s_item_id}')
        next_forbidden, last_item, sequence_item = _check_next_forbidden(
            s_item_id)
        position = int(request.GET.get('position') or 1)
        if not (next_forbidden and position > sequence_item.position):
            update_activity = request.session.pop('Lti_update_activity', None)
            sequence_item, sequence_complete, stub = utils.select_next_sequence_item(
                sequence_item,
                update_activity,
                last_item,
                position,
            )
            next_forbidden, _, _ = _check_next_forbidden(sequence_item.id)
            context.update({"forbidden": next_forbidden})

            if sequence_complete:
                context.update({
                    'sequence_items': test_sequence.items.all(),
                    'demo': True,
                    'sequence_item': sequence_item
                })
                return render(request,
                              template_name='module/sequence_complete.html',
                              context=context)
            elif stub:
                return stub_page(
                    request,
                    title="Warning",
                    message="Cannot get next activity from the engine.",
                    tip="Try again later or connect with the instructor.",
                    demo=True,
                    sequence=test_sequence,
                    back_url=back_url,
                )

    context.update({
        'sequence_item': sequence_item,
        'sequence_items': test_sequence.items.all(),
        'demo': True,
        'position': sequence_item.position + 1
    })
    return render(request,
                  template_name="module/sequence_item.html",
                  context=context)