예제 #1
0
def test_user_upload_to_display_set_without_interface(client, settings):
    # Override the celery settings
    settings.task_eager_propagates = (True, )
    settings.task_always_eager = (True, )

    user = UserFactory()
    rs = ReaderStudyFactory(use_display_sets=False)
    rs.add_editor(user=user)
    ci = ComponentInterface.objects.filter(slug="generic-overlay").get()
    civ = ComponentInterfaceValueFactory(interface=ci)
    ds = DisplaySetFactory(reader_study=rs)
    ds.values.add(civ)
    assert ds.values.count() == 1

    upload = create_upload_from_file(
        file_path=Path(__file__).parent / "resources" / "image10x10x10.mha",
        creator=user,
    )
    with capture_on_commit_callbacks(execute=True):
        response = get_view_for_user(
            viewname="api:upload-session-list",
            user=user,
            client=client,
            method=client.post,
            content_type="application/json",
            data={
                "uploads": [upload.api_url],
                "display_set": ds.pk
            },
            HTTP_X_FORWARDED_PROTO="https",
        )

    assert response.status_code == 400
    assert ("An interface needs to be defined to upload to a display set."
            in response.json()["non_field_errors"])
예제 #2
0
def test_assert_modification_allowed():
    rs = ReaderStudyFactory(use_display_sets=False)
    ci = ComponentInterfaceFactory(
        kind=InterfaceKind.InterfaceKindChoices.BOOL)
    civ = ComponentInterfaceValueFactory(interface=ci, value=True)
    ds = DisplaySetFactory(reader_study=rs)
    ds.values.add(civ)

    del ds.is_editable

    civ2 = ComponentInterfaceValueFactory(interface=ci, value=True)
    ds.values.remove(civ)
    ds.values.add(civ2)

    assert ds.values.count() == 1
    assert ds.values.first() == civ2

    q = QuestionFactory(reader_study=rs)
    AnswerFactory(question=q, display_set=ds)

    del ds.is_editable

    with pytest.raises(ValidationError):
        with transaction.atomic():
            ds.values.remove(civ2)

    assert ds.values.count() == 1
    assert ds.values.first() == civ2
예제 #3
0
def test_reader_study_add_ground_truth_ds(client, settings):
    settings.task_eager_propagates = (True,)
    settings.task_always_eager = (True,)

    rs = ReaderStudyFactory(use_display_sets=True)
    QuestionFactory(
        reader_study=rs,
        question_text="bar",
        answer_type=Question.AnswerType.SINGLE_LINE_TEXT,
    )

    civ = ComponentInterfaceValueFactory(image=ImageFactory())
    ds = DisplaySetFactory(reader_study=rs)
    ds.values.add(civ)

    editor = UserFactory()
    rs.editors_group.user_set.add(editor)

    gt = io.StringIO()
    fake_writer = csv.writer(gt)
    fake_writer.writerows([["images", "foo"], [str(ds.pk), "bar"]])
    gt.seek(0)

    response = get_view_for_user(
        viewname="reader-studies:add-ground-truth",
        client=client,
        method=client.post,
        reverse_kwargs={"slug": rs.slug},
        data={"ground_truth": gt},
        follow=True,
        user=editor,
    )

    assert response.status_code == 200
예제 #4
0
def test_display_set_order():
    rs = ReaderStudyFactory(use_display_sets=False)
    ds = DisplaySetFactory(reader_study=rs)
    assert ds.order == 10

    ds = DisplaySetFactory(reader_study=rs)
    assert ds.order == 20

    ds.order = 15
    ds.save()

    ds = DisplaySetFactory(reader_study=rs)
    assert ds.order == 20
예제 #5
0
def test_changing_reader_study_updates_permissions():
    ds = DisplaySetFactory()
    im = ImageFactory()
    civ = ComponentInterfaceValueFactory(image=im)

    with capture_on_commit_callbacks(execute=True):
        ds.values.set([civ])

    assert get_groups_with_set_perms(im) == {
        ds.reader_study.editors_group: {"view_image"},
        ds.reader_study.readers_group: {"view_image"},
    }

    rs = ReaderStudyFactory(use_display_sets=False)

    ds.reader_study = rs

    with capture_on_commit_callbacks(execute=True):
        ds.save()

    assert get_groups_with_set_perms(im) == {
        rs.editors_group: {"view_image"},
        rs.readers_group: {"view_image"},
    }
예제 #6
0
def test_display_set_permissions_signal(client, reverse):
    ds1, ds2 = DisplaySetFactory.create_batch(2)
    im1, im2, im3, im4 = ImageFactory.create_batch(4)

    civ1, civ2, civ3, civ4 = (
        ComponentInterfaceValueFactory(image=im1),
        ComponentInterfaceValueFactory(image=im2),
        ComponentInterfaceValueFactory(image=im3),
        ComponentInterfaceValueFactory(image=im4),
    )

    with capture_on_commit_callbacks(execute=True):
        if reverse:
            for civ in [civ1, civ2, civ3, civ4]:
                civ.display_sets.add(ds1, ds2)
            for civ in [civ3, civ4]:
                civ.display_sets.remove(ds1, ds2)
            for civ in [civ1, civ2]:
                civ.display_sets.remove(ds2)
        else:
            # Test that adding images works
            ds1.values.add(civ1, civ2, civ3, civ4)
            # Test that removing images works
            ds1.values.remove(civ3, civ4)

    assert get_groups_with_set_perms(im1) == {
        ds1.reader_study.editors_group: {"view_image"},
        ds1.reader_study.readers_group: {"view_image"},
    }
    assert get_groups_with_set_perms(im2) == {
        ds1.reader_study.editors_group: {"view_image"},
        ds1.reader_study.readers_group: {"view_image"},
    }
    assert get_groups_with_set_perms(im3) == {}
    assert get_groups_with_set_perms(im4) == {}

    # Test clearing
    with capture_on_commit_callbacks(execute=True):
        if reverse:
            civ1.display_sets.clear()
            civ2.display_sets.clear()
        else:
            ds1.values.clear()

    assert get_groups_with_set_perms(im1) == {}
    assert get_groups_with_set_perms(im2) == {}
예제 #7
0
def test_display_set_description():
    rs = ReaderStudyFactory()
    reader = UserFactory()
    rs.add_reader(reader)
    images = [ImageFactory() for _ in range(6)]
    ci = ComponentInterface.objects.get(slug="generic-medical-image")
    result = {}
    for image in images:
        ds = DisplaySetFactory(reader_study=rs)
        result[ds.pk] = f"<p>{str(image.pk)}</p>"
        civ = ComponentInterfaceValueFactory(interface=ci, image=image)
        ds.values.add(civ)

    rs.case_text = {im.name: str(im.pk) for im in images}
    rs.case_text["no_image"] = "not an image"
    rs.save()

    for ds in rs.display_sets.all():
        assert ds.description == result[ds.pk]
예제 #8
0
def test_deleting_display_set_removes_permissions():
    ds1, ds2 = DisplaySetFactory.create_batch(2)
    im = ImageFactory()
    civ = ComponentInterfaceValueFactory(image=im)

    with capture_on_commit_callbacks(execute=True):
        ds1.values.set([civ])
        ds2.values.set([civ])

    assert get_groups_with_set_perms(im) == {
        ds1.reader_study.editors_group: {"view_image"},
        ds1.reader_study.readers_group: {"view_image"},
        ds2.reader_study.editors_group: {"view_image"},
        ds2.reader_study.readers_group: {"view_image"},
    }

    with capture_on_commit_callbacks(execute=True):
        ds1.delete()

    assert get_groups_with_set_perms(im) == {
        ds2.reader_study.editors_group: {"view_image"},
        ds2.reader_study.readers_group: {"view_image"},
    }
예제 #9
0
def test_reader_study_display_set_list(client):
    user = UserFactory()
    rs = ReaderStudyFactory(use_display_sets=True)
    rs.add_editor(user)

    civ = ComponentInterfaceValueFactory(image=ImageFactory())
    ds = DisplaySetFactory(reader_study=rs)
    ds.values.add(civ)

    response = get_view_for_user(
        viewname="reader-studies:display_sets",
        reverse_kwargs={"slug": rs.slug},
        client=client,
        user=user,
    )

    assert response.status_code == 200

    response = get_view_for_user(
        viewname="reader-studies:display_sets",
        reverse_kwargs={"slug": rs.slug},
        client=client,
        user=user,
        method=client.get,
        follow=True,
        data={
            "length": 10,
            "draw": 1,
            "order[0][dir]": "desc",
            "order[0][column]": 0,
        },
        **{"HTTP_X_REQUESTED_WITH": "XMLHttpRequest"},
    )

    resp = response.json()
    assert str(ds.pk) in resp["data"][0][0]
예제 #10
0
def test_progress_for_user(settings, use_display_sets):  # noqa: C901
    settings.task_eager_propagates = (True, )
    settings.task_always_eager = (True, )

    rs = ReaderStudyFactory(use_display_sets=use_display_sets)
    im1, im2 = ImageFactory(name="im1"), ImageFactory(name="im2")
    q1, q2, q3 = [
        QuestionFactory(reader_study=rs),
        QuestionFactory(reader_study=rs),
        QuestionFactory(reader_study=rs),
    ]

    reader = UserFactory()
    rs.add_reader(reader)

    question_perc = 100 / 6

    assert rs.get_progress_for_user(reader) == {
        "diff": 0.0,
        "hangings": 0.0,
        "questions": 0.0,
    }

    if use_display_sets:
        ci = ComponentInterface.objects.get(slug="generic-medical-image")
        civ1 = ComponentInterfaceValueFactory(image=im1, interface=ci)
        civ2 = ComponentInterfaceValueFactory(image=im2, interface=ci)
        ds1, ds2 = DisplaySetFactory(reader_study=rs), DisplaySetFactory(
            reader_study=rs)
        ds1.values.add(civ1)
        ds2.values.add(civ2)

    else:
        rs.images.set([im1, im2])
        rs.hanging_list = [{"main": im1.name}, {"main": im2.name}]
        rs.save()

    progress = rs.get_progress_for_user(reader)
    assert progress["hangings"] == 0
    assert progress["questions"] == 0

    a11 = AnswerFactory(question=q1, answer="foo", creator=reader)
    if use_display_sets:
        a11.display_set = ds1
        a11.save()
    else:
        a11.images.add(im1)

    progress = rs.get_progress_for_user(reader)
    assert progress["hangings"] == 0
    assert progress["questions"] == pytest.approx(question_perc)

    a21 = AnswerFactory(question=q1, answer="foo", creator=reader)
    if use_display_sets:
        a21.display_set = ds2
        a21.save()
    else:
        a21.images.add(im2)

    progress = rs.get_progress_for_user(reader)
    assert progress["hangings"] == 0
    assert progress["questions"] == pytest.approx(question_perc * 2)

    a12 = AnswerFactory(question=q2, answer="foo", creator=reader)
    a13 = AnswerFactory(question=q3, answer="foo", creator=reader)
    if use_display_sets:
        a12.display_set = ds1
        a12.save()
        a13.display_set = ds1
        a13.save()
    else:
        a12.images.add(im1)
        a13.images.add(im1)

    progress = rs.get_progress_for_user(reader)
    assert progress["hangings"] == 50
    assert progress["questions"] == pytest.approx(question_perc * 4)

    editor = UserFactory()
    rs.add_reader(editor)
    rs.add_editor(editor)

    for q in [q1, q2, q3]:
        if use_display_sets:
            for ds in [ds1, ds2]:
                a = AnswerFactory(
                    question=q,
                    answer="foo",
                    creator=editor,
                    is_ground_truth=True,
                    display_set=ds,
                )
        else:
            for im in [im1, im2]:
                a = AnswerFactory(
                    question=q,
                    answer="foo",
                    creator=editor,
                    is_ground_truth=True,
                )
                a.images.add(im)

    progress = rs.get_progress_for_user(editor)
    assert progress["hangings"] == 0
    assert progress["questions"] == 0

    for q in [q1, q2, q3]:
        if use_display_sets:
            for ds in [ds1, ds2]:
                a = AnswerFactory(
                    question=q,
                    answer="foo",
                    creator=editor,
                    is_ground_truth=False,
                    display_set=ds,
                )
        else:
            for im in [im1, im2]:
                a = AnswerFactory(
                    question=q,
                    answer="foo",
                    creator=editor,
                    is_ground_truth=False,
                )
                a.images.add(im)

    progress = rs.get_progress_for_user(editor)
    assert progress["hangings"] == 100.0
    assert progress["questions"] == 100.0