def test_all_projectlinks(): c = ChallengeFactory(hidden=False) hidden = ChallengeFactory(hidden=True) template = Template('{% load all_projectlinks from grandchallenge_tags %}' '{% all_projectlinks %}') rendered = template.render(Context({})) assert c.short_name in rendered assert hidden.short_name not in rendered
def test_challenge_list(client): c = ChallengeFactory(hidden=False) hidden = ChallengeFactory(hidden=True) response = get_view_for_user(client=client, viewname="challenges:list") assert c.short_name in response.rendered_content assert hidden.short_name not in response.rendered_content
def challenge_set(): """ Creates a challenge with creator, 2 participants, and non participant. To use this you must mark the test with @pytest.mark.django_db """ ChallengeSet = namedtuple( 'ChallengeSet', [ 'challenge', 'creator', 'admin', 'participant', 'participant1', 'non_participant', ], ) creator = UserFactory() challenge = ChallengeFactory(creator=creator) admin = UserFactory() challenge.add_admin(admin) participant = UserFactory() challenge.add_participant(participant) participant1 = UserFactory() challenge.add_participant(participant1) non_participant = UserFactory() try: Challenge.objects.get(short_name=settings.MAIN_PROJECT_NAME) except ObjectDoesNotExist: ChallengeFactory(short_name=settings.MAIN_PROJECT_NAME) return ChallengeSet( challenge, creator, admin, participant, participant1, non_participant )
def test_non_posters_notified(group): p = UserFactory() u = UserFactory() c = ChallengeFactory() c.add_admin(user=p) add_method = getattr(c, f"add_{group}") add_method(user=u) TopicFactory(forum=c.forum, poster=p, type=Topic.TOPIC_ANNOUNCE) assert u.user_profile.has_unread_notifications is True assert p.user_profile.has_unread_notifications is False
def test_notification_for_new_admin_only(): user = UserFactory() admin = UserFactory() challenge = ChallengeFactory(creator=admin) # clear existing notifications for easier testing below Notification.objects.all().delete() # add user as admin to challenge challenge.add_admin(user) assert Notification.objects.count() == 1 assert Notification.objects.get().user == user assert Notification.objects.get().user != admin
def test_challenge_card_status( client, phase1_submission_limit, phase1_submissions_open, phase1_submissions_close, phase2_submission_limit, phase2_submissions_open, phase2_submissions_close, expected_status, phase_in_status, ): ch = ChallengeFactory(hidden=False) phase1 = ch.phase_set.first() phase2 = PhaseFactory(challenge=ch) u = UserFactory() phase1.submission_limit = phase1_submission_limit phase1.submissions_open_at = phase1_submissions_open phase1.submissions_close_at = phase1_submissions_close phase2.submission_limit = phase2_submission_limit phase2.submissions_open_at = phase2_submissions_open phase2.submissions_close_at = phase2_submissions_close phase1.save() phase2.save() response = get_view_for_user( client=client, viewname="challenges:list", user=u ) if phase_in_status: title = ch.phase_set.order_by("created").all()[phase_in_status].title assert f"{expected_status} for {title}" in response.rendered_content else: assert expected_status in response.rendered_content
def test_imageset_add_images(client, settings): # Override the celery settings settings.task_eager_propagates = (True, ) settings.task_always_eager = (True, ) settings.broker_url = ("memory://", ) settings.backend = "memory" user = UserFactory(is_staff=True) client.login(username=user.username, password=SUPER_SECURE_TEST_PASSWORD) challenge = ChallengeFactory() imageset = ImageSet.objects.get(challenge=challenge, phase=ImageSet.TRAINING) assert len(imageset.images.all()) == 0 images = ["image10x10x10.zraw", "image10x10x10.mhd"] session, uploaded_images = create_raw_upload_image_session( images, imageset=imageset) response = client.get(imageset.get_absolute_url()) assert "image10x10x10.mhd" in response.rendered_content assert str(session.pk) in response.rendered_content imageset.refresh_from_db() assert len(imageset.images.all()) == 1
def test_phase_filtered_views(self, client): c = ChallengeFactory(hidden=False) p1, p2 = PhaseFactory.create_batch(2, challenge=c) e1 = EvaluationFactory( method__phase=p1, submission__phase=p1, rank=1, status=Evaluation.SUCCESS, ) _ = EvaluationFactory( method__phase=p2, submission__phase=p2, rank=1, status=Evaluation.SUCCESS, ) response = get_view_for_user( client=client, viewname="evaluation:leaderboard", reverse_kwargs={ "challenge_short_name": e1.submission.phase.challenge.short_name, "slug": e1.submission.phase.slug, }, ) assert response.status_code == 200 assert {e1.pk} == {o.pk for o in response.context[-1]["object_list"]}
def test_url_conf_set( settings, rf, subdomain, expected_subdomain, expected_challenge, expected_url_conf, ): """Subdomains should have the correct url_conf attached""" settings.ALLOWED_HOSTS = [f".{SITE_DOMAIN}"] c = ChallengeFactory(short_name="c") if subdomain is not None: host = f"{subdomain}.{SITE_DOMAIN}" else: host = SITE_DOMAIN request = CurrentSiteMiddleware(lambda x: x)(rf.get("/", HTTP_HOST=host)) request = subdomain_middleware(lambda x: x)(request) request = challenge_subdomain_middleware(lambda x: x)(request) request = subdomain_urlconf_middleware(lambda x: x)(request) assert request.subdomain == expected_subdomain assert request.urlconf == expected_url_conf if expected_challenge: assert request.challenge == c else: assert request.challenge is None
def test_null_results(settings): # Override the celery settings settings.task_eager_propagates = (True, ) settings.task_always_eager = (True, ) challenge = ChallengeFactory() with mute_signals(post_save): user1 = UserFactory() queryset = ( ResultFactory( job__submission__challenge=challenge, metrics={"a": 0.6}, job__submission__creator=user1, ), ResultFactory( job__submission__challenge=challenge, metrics={"a": None}, job__submission__creator=user1, ), ) challenge.evaluation_config.score_jsonpath = "a" challenge.evaluation_config.result_display_choice = Config.ALL challenge.evaluation_config.save() expected_ranks = [1, 0] assert_ranks(queryset, expected_ranks)
def test_archive_challenge(): challenge = ChallengeFactory.create() # Check that the is_archived flag is set to true when the archive function is called challenge.archive() assert challenge.is_archived is True
def test_save_challenge(): challenge = ChallengeFactory.create() # Check that on saving a challenge in_progress is set to False by default challenge.save() assert challenge.in_progress is False
def test_annotationset_creation(client, settings): # Override the celery settings settings.task_eager_propagates = (True, ) settings.task_always_eager = (True, ) user = UserFactory(is_staff=True) client.login(username=user.username, password=SUPER_SECURE_TEST_PASSWORD) imageset = ChallengeFactory().imageset_set.get(phase=ImageSet.TRAINING) url = reverse( "datasets:annotationset-create", kwargs={ "challenge_short_name": imageset.challenge.short_name, "base_pk": imageset.pk, }, ) url, kwargs = get_http_host(url=url, kwargs={}) response = client.get(url, **kwargs) assert response.status_code == 200 response = client.post(url, data={"kind": AnnotationSet.GROUNDTRUTH}, **kwargs) assert response.status_code == 302 annotationset = AnnotationSet.objects.get(base=imageset, kind=AnnotationSet.GROUNDTRUTH) assert len(annotationset.images.all()) == 0 assert annotationset.creator == user assert response.url == reverse( "datasets:annotationset-add-images", kwargs={ "challenge_short_name": annotationset.base.challenge.short_name, "pk": annotationset.pk, }, ) images = ["image10x10x10.zraw", "image10x10x10.mhd"] session, uploaded_images = create_raw_upload_image_session( images, annotationset=annotationset, linked_task=add_images_to_annotationset, ) url, kwargs = get_http_host(url=annotationset.get_absolute_url(), kwargs={}) response = client.get(url, **kwargs) assert "image10x10x10.mhd" in response.rendered_content assert str(session.pk) in response.rendered_content annotationset.refresh_from_db() assert len(annotationset.images.all()) == 1
def test_unique_dataset_phase(client): challenge = ChallengeFactory() with pytest.raises(ValidationError): ImageSet.objects.create(challenge=challenge, phase=ImageSet.TRAINING) with pytest.raises(ValidationError): ImageSet.objects.create(challenge=challenge, phase=ImageSet.TESTING)
def setUp(self): self.factory = RequestFactory() self.user = UserFactory.create() self.challenge = ChallengeFactory.create(user=self.user) self.score_card = AnxietyScoreCard.objects.create( challenge=self.challenge, anxiety_at_0_min='9', anxiety_at_120_min='2')
def test_permissions_mixin( rf: RequestFactory, admin_user, mocker, ChallengeSet ): # admin_user is a superuser, not a challenge admin creator = ChallengeSet.creator challenge = ChallengeSet.challenge participant = ChallengeSet.participant non_participant = ChallengeSet.non_participant # Messages need to be mocked when using request factory mock_messages = mocker.patch( "grandchallenge.core.permissions.mixins.messages" ).start() mock_messages.INFO = "INFO" assert_status(200, admin_user, AdminOnlyView, challenge, rf) assert_status(200, creator, AdminOnlyView, challenge, rf) assert_status(403, participant, AdminOnlyView, challenge, rf) assert_status(403, non_participant, AdminOnlyView, challenge, rf) assert_redirect( settings.LOGIN_URL, AnonymousUser(), AdminOnlyView, challenge, rf ) assert_status(200, admin_user, ParticipantOrAdminOnlyView, challenge, rf) assert_status(200, creator, ParticipantOrAdminOnlyView, challenge, rf) assert_status(200, participant, ParticipantOrAdminOnlyView, challenge, rf) assert_status( 403, non_participant, ParticipantOrAdminOnlyView, challenge, rf ) assert_redirect( settings.LOGIN_URL, AnonymousUser(), ParticipantOrAdminOnlyView, challenge, rf, ) # Make a 2nd challenge and make sure that the admins and participants # here cannot see the first creator2 = UserFactory() challenge2 = ChallengeFactory(creator=creator2) participant2 = UserFactory() challenge2.add_participant(participant2) assert_status(403, creator2, AdminOnlyView, challenge, rf) assert_status(403, participant2, AdminOnlyView, challenge, rf) assert_status(403, creator2, ParticipantOrAdminOnlyView, challenge, rf) assert_status(403, participant2, ParticipantOrAdminOnlyView, challenge, rf)
def test_imageset_creation(): assert ImageSet.objects.all().count() == 0 challenge = ChallengeFactory() assert ImageSet.objects.all().count() == 2 assert len(challenge.imageset_set.all()) == 2 assert len(challenge.imageset_set.filter(phase=ImageSet.TRAINING)) == 1 assert len(challenge.imageset_set.filter(phase=ImageSet.TESTING)) == 1
def test_group_deletion_reverse(group): challenge = ChallengeFactory() participants_group = challenge.participants_group admins_group = challenge.admins_group assert participants_group assert admins_group getattr(challenge, group).delete() with pytest.raises(ObjectDoesNotExist): participants_group.refresh_from_db() with pytest.raises(ObjectDoesNotExist): admins_group.refresh_from_db() with pytest.raises(ObjectDoesNotExist): challenge.refresh_from_db()
def test_imageset_creation(): initial_count = 2 # Automatically created assert ImageSet.objects.all().count() == initial_count challenge = ChallengeFactory() assert ImageSet.objects.all().count() == 2 + initial_count assert len(challenge.imageset_set.all()) == 2 assert len(challenge.imageset_set.filter(phase=ImageSet.TRAINING)) == 1 assert len(challenge.imageset_set.filter(phase=ImageSet.TESTING)) == 1
def test_default_interfaces_created(): c = ChallengeFactory() assert {i.kind for i in c.evaluation_config.inputs.all() } == {InterfaceKindChoices.CSV} assert {o.kind for o in c.evaluation_config.outputs.all()} == { InterfaceKindChoices.JSON, }
def test_group_deletion_reverse(group): challenge = ChallengeFactory() participants_group = challenge.participants_group admins_group = challenge.admins_group assert participants_group assert admins_group with pytest.raises(ProtectedError): getattr(challenge, group).delete()
def test_allusers_statistics(): c = ChallengeFactory(short_name=str(uuid.uuid4())) p = PageFactory(challenge=c) template = Template( '{% load allusers_statistics from grandchallenge_tags %}' '{% allusers_statistics %}') context = Context() context.page = p rendered = template.render(context) assert "['Country', '#Participants']" in rendered
def test_allusers_statistics(): c = ChallengeFactory(short_name=str(uuid.uuid4())) p = PageFactory(challenge=c) template = Template( "{% load allusers_statistics from grandchallenge_tags %}" "{% allusers_statistics %}") context = Context({"currentpage": p}) rendered = template.render(context) assert '["Country", "#Participants"]' in rendered assert "data-geochart" in rendered
def test_submission_conversion(capsys, submission_file, settings): # Override the celery settings settings.task_eager_propagates = (True,) settings.task_always_eager = (True,) challenge = ChallengeFactory() test_set = challenge.imageset_set.get(phase=ImageSet.TESTING) with mute_signals(post_save): submission = SubmissionFactory( file__from_path=submission_file, challenge=challenge ) call_command("convertsubmissions", challenge.short_name) _, err = capsys.readouterr() assert err == "" annotation_set = AnnotationSet.objects.all()[0] assert annotation_set.submission == submission assert annotation_set.base == test_set images = annotation_set.images.all() assert len(images) == 1 assert images[0].name == "image10x10x10.mhd" with mute_signals(post_save): submission = SubmissionFactory( file__from_path=Path(__file__).parent.parent / "evaluation_tests" / "resources" / "submission.csv", challenge=challenge, ) call_command("convertsubmissions", challenge.short_name) _, err = capsys.readouterr() assert err == "" annotation_set = AnnotationSet.objects.all()[1] assert annotation_set.submission == submission assert annotation_set.base == test_set labels = annotation_set.labels assert len(labels) == 10 assert labels[0]["class"] == 0
def test_upload_file(client, test_file, expected_response): submission_file = os.path.join( os.path.split(__file__)[0], 'resources', test_file) # Get the users token user = UserFactory() challenge = ChallengeFactory() token_url = reverse('api:obtain-auth-token') response = client.post(token_url, { 'username': user.username, 'password': '******' }) token = response.data['token'] submission_url = reverse('api:submission-list') # Upload with token authorisation with open(submission_file, 'rb') as f: response = client.post( submission_url, { 'file': f, 'challenge': challenge.short_name }, format='multipart', HTTP_AUTHORIZATION='Token ' + token, ) assert response.status_code == expected_response # Upload with session authorisation client.login(username=user.username, password='******') with open(submission_file, 'rb') as f: response = client.post( submission_url, { 'file': f, 'challenge': challenge.short_name }, format='multipart', ) assert response.status_code == expected_response submissions = Submission.objects.all() if expected_response == 201: assert len(submissions) == 2 else: assert len(submissions) == 0 # We should not be able to download submissions for submission in Submission.objects.all(): response = client.get(submission.file.url) assert response.status_code == 403 # Cleanup for submission in submissions: filepath = submission.file.name submission.file.delete() try: os.removedirs(settings.MEDIA_ROOT + os.path.split(filepath)[0]) except OSError: pass
def test_get_latest_initial_anxiety_level_with_score_card(): challenge = ChallengeFactory.create() AnxietyScoreCard.objects.create(challenge=challenge, anxiety_at_0_min='9', anxiety_at_120_min='2') AnxietyScoreCard.objects.create(challenge=challenge, anxiety_at_0_min='6', anxiety_at_120_min='1') # Check that when getting the initial anxiety level, the most recent is returned assert challenge.get_latest_initial_anxiety_level() == '6'
def test_project_statistics(): c = ChallengeFactory(short_name=str(uuid.uuid4())) p = PageFactory(challenge=c) template = Template( "{% load project_statistics from grandchallenge_tags %}" "{% project_statistics %}" ) context = Context() context.page = p rendered = template.render(context) assert "Number of users: 0" in rendered assert "['Country', '#Participants']" in rendered
def test_accept_challenge_request(client, challenge_reviewer, type_1_challenge_request): _ = ChallengeFactory(short_name=type_1_challenge_request.short_name) form = ChallengeRequestUpdateForm( data={ "status": type_1_challenge_request.ChallengeRequestStatusChoices.ACCEPTED }, instance=type_1_challenge_request, ) assert not form.is_valid() assert ( f"There already is a challenge with short name: {type_1_challenge_request.short_name}" in str(form.errors))
def test_image_browser(rf: RequestFactory): c = ChallengeFactory(short_name='testproj-image-browser') p = PageFactory(challenge=c) template = Template('{% load image_browser from grandchallenge_tags %}' '{% image_browser path:public_html ' 'config:public_html/promise12_viewer_config_new.js %}') context = RequestContext(request=rf.get( '/results/?id=CBA&folder=20120627202920_304_CBA_Results')) context.page = p context.update({'site': c}) rendered = template.render(context) assert "pageError" not in rendered assert "Error rendering Visualization" not in rendered assert "20120627202920_304_CBA_Results" in rendered assert "Results viewer" in rendered
def test_group_deletion(): challenge = ChallengeFactory() participants_group = challenge.participants_group admins_group = challenge.admins_group assert participants_group assert admins_group Challenge.objects.filter(pk__in=[challenge.pk]).delete() with pytest.raises(ObjectDoesNotExist): participants_group.refresh_from_db() with pytest.raises(ObjectDoesNotExist): admins_group.refresh_from_db()
def generate_challenge_set(): creator = UserFactory() challenge = ChallengeFactory(creator=creator) admin = UserFactory() challenge.add_admin(admin) participant = UserFactory() challenge.add_participant(participant) participant1 = UserFactory() challenge.add_participant(participant1) non_participant = UserFactory() try: Challenge.objects.get(short_name=settings.MAIN_PROJECT_NAME) except ObjectDoesNotExist: ChallengeFactory(short_name=settings.MAIN_PROJECT_NAME) return ChallengeSet( challenge=challenge, creator=creator, admin=admin, participant=participant, participant1=participant1, non_participant=non_participant, )