def setUp(self): user = User.objects.create( username="******", email="*****@*****.**", is_staff=True ) user.set_password("top_secret") user.save() self.assertTrue(self.client.login(username="******", password="******")) campaign = create_campaign(published=True) project = create_project(campaign=campaign, published=True) item = create_item(project=project, published=True) asset = create_asset( item=item, title="TestAsset", description="Asset Description", download_url=DOWNLOAD_URL, media_type=MediaType.IMAGE, sequence=1, ) # add a Transcription object transcription1 = Transcription( asset=asset, user=user, text="Sample", submitted=datetime.now(), accepted=datetime.now(), ) transcription1.full_clean() transcription1.save()
def test_transcription_double_review(self): asset = create_asset() anon = get_anonymous_user() t1 = Transcription(asset=asset, user=anon, text="test", submitted=now()) t1.full_clean() t1.save() self.login_user() resp = self.client.post(reverse("review-transcription", args=(t1.pk, )), data={"action": "accept"}) data = self.assertValidJSON(resp, expected_status=200) resp = self.client.post(reverse("review-transcription", args=(t1.pk, )), data={"action": "reject"}) data = self.assertValidJSON(resp, expected_status=400) self.assertIn("error", data) self.assertEqual("This transcription has already been reviewed", data["error"])
def test_transcription_review(self): asset = create_asset() anon = get_anonymous_user() t1 = Transcription(asset=asset, user=anon, text="test", submitted=now()) t1.full_clean() t1.save() self.login_user() resp = self.client.post(reverse("review-transcription", args=(t1.pk, )), data={"action": "foobar"}) data = self.assertValidJSON(resp, expected_status=400) self.assertIn("error", data) self.assertEqual( 1, Transcription.objects.filter(pk=t1.pk, accepted__isnull=True).count()) resp = self.client.post(reverse("review-transcription", args=(t1.pk, )), data={"action": "accept"}) data = self.assertValidJSON(resp, expected_status=200) self.assertEqual( 1, Transcription.objects.filter(pk=t1.pk, accepted__isnull=False).count())
def save_transcription(request, *, asset_pk): asset = get_object_or_404(Asset, pk=asset_pk) if request.user.is_anonymous: user = get_anonymous_user() else: user = request.user # Check whether this transcription text contains any URLs # If so, ask the user to correct the transcription by removing the URLs transcription_text = request.POST["text"] url_match = re.search(URL_REGEX, transcription_text) if url_match: return JsonResponse( { "error": "It looks like your text contains URLs. " "Please remove the URLs and try again." }, status=400, ) supersedes_pk = request.POST.get("supersedes") if not supersedes_pk: superseded = None if asset.transcription_set.filter(supersedes=None).exists(): return JsonResponse( {"error": "An open transcription already exists"}, status=409) else: if asset.transcription_set.filter(supersedes=supersedes_pk).exists(): return JsonResponse( {"error": "This transcription has been superseded"}, status=409) try: superseded = asset.transcription_set.get(pk=supersedes_pk) except Transcription.DoesNotExist: return JsonResponse({"error": "Invalid supersedes value"}, status=400) transcription = Transcription(asset=asset, user=user, supersedes=superseded, text=transcription_text) transcription.full_clean() transcription.save() return JsonResponse( { "id": transcription.pk, "submissionUrl": reverse("submit-transcription", args=(transcription.pk, )), }, status=201, )
def test_bagit_export(self): """ Test the http GET on route /campaigns/exportBagit/<campaignname>/ """ self.login_user() campaign = create_campaign(published=True) project = create_project(campaign=campaign, published=True) item = create_item(project=project, published=True) asset = create_asset( item=item, title="TestAsset", description="Asset Description", media_url="1.jpg", media_type=MediaType.IMAGE, sequence=1, ) # add a Transcription object transcription1 = Transcription(asset=asset, user=self.user, text="Sample") transcription1.full_clean() transcription1.save() item_dir = os.path.join(settings.MEDIA_ROOT, campaign.slug, project.slug, item.item_id, asset.slug) asset_file = ContentFile(b"Not a real JPEG") default_storage.save(os.path.join(item_dir, f"{asset.sequence}.jpg"), asset_file) response = self.client.get( reverse("transcriptions:export-bagit", args=(campaign.slug, ))) self.assertEqual(response.status_code, 200) self.assertEquals( response.get("Content-Disposition"), "attachment; filename=%s.zip" % campaign.slug, ) f = io.BytesIO(response.content) zipped_file = zipfile.ZipFile(f, "r") self.assertIn("bagit.txt", zipped_file.namelist()) self.assertIn("bag-info.txt", zipped_file.namelist()) self.assertIn( "data/test-project/testitem0123456789/testasset/1.jpg", zipped_file.namelist(), )
def test_stale_transcription_submission(self): asset = create_asset() anon = get_anonymous_user() t1 = Transcription(asset=asset, user=anon, text="test") t1.full_clean() t1.save() t2 = Transcription(asset=asset, user=anon, text="test", supersedes=t1) t2.full_clean() t2.save() resp = self.client.post(reverse("submit-transcription", args=(t1.pk, ))) data = self.assertValidJSON(resp, expected_status=400) self.assertIn("error", data)
def test_transcription_disallow_self_review(self): asset = create_asset() self.login_user() t1 = Transcription(asset=asset, user=self.user, text="test", submitted=now()) t1.full_clean() t1.save() resp = self.client.post(reverse("review-transcription", args=(t1.pk, )), data={"action": "accept"}) data = self.assertValidJSON(resp, expected_status=400) self.assertIn("error", data) self.assertEqual("You cannot accept your own transcription", data["error"])
def test_transcription_allow_self_reject(self): asset = create_asset() self.login_user() t1 = Transcription(asset=asset, user=self.user, text="test", submitted=now()) t1.full_clean() t1.save() resp = self.client.post(reverse("review-transcription", args=(t1.pk, )), data={"action": "reject"}) self.assertValidJSON(resp, expected_status=200) self.assertEqual( Asset.objects.get(pk=asset.pk).transcription_status, TranscriptionStatus.IN_PROGRESS, ) self.assertEqual( Transcription.objects.get(pk=t1.pk).reviewed_by, self.user)
def save_transcription(request, *, asset_pk): asset = get_object_or_404(Asset, pk=asset_pk) if request.user.is_anonymous: user = get_anonymous_user() else: user = request.user supersedes_pk = request.POST.get("supersedes") if not supersedes_pk: superseded = None if asset.transcription_set.filter(supersedes=None).exists(): return JsonResponse( {"error": "An open transcription already exists"}, status=409 ) else: if asset.transcription_set.filter(supersedes=supersedes_pk).exists(): return JsonResponse( {"error": "This transcription has been superseded"}, status=409 ) try: superseded = asset.transcription_set.get(pk=supersedes_pk) except Transcription.DoesNotExist: return JsonResponse({"error": "Invalid supersedes value"}, status=400) transcription = Transcription( asset=asset, user=user, supersedes=superseded, text=request.POST["text"] ) transcription.full_clean() transcription.save() return JsonResponse( { "id": transcription.pk, "submissionUrl": reverse("submit-transcription", args=(transcription.pk,)), }, status=201, )
def test_anonymous_transcription_submission(self): asset = create_asset() anon = get_anonymous_user() transcription = Transcription(asset=asset, user=anon, text="previous entry") transcription.full_clean() transcription.save() resp = self.client.post( reverse("submit-transcription", args=(transcription.pk, ))) data = self.assertValidJSON(resp, expected_status=401) self.assertIn("key", data) self.assertIn("image", data) self.assertFalse( Transcription.objects.filter(submitted__isnull=False).exists()) self.completeCaptcha(data["key"]) self.client.post( reverse("submit-transcription", args=(transcription.pk, ))) self.assertTrue( Transcription.objects.filter(submitted__isnull=False).exists())
def test_transcription_review_asset_status_updates(self): """ Confirm that the Asset.transcription_status field is correctly updated throughout the review process """ asset = create_asset() anon = get_anonymous_user() # We should see NOT_STARTED only when no transcription records exist: self.assertEqual(asset.transcription_set.count(), 0) self.assertEqual( Asset.objects.get(pk=asset.pk).transcription_status, TranscriptionStatus.NOT_STARTED, ) t1 = Transcription(asset=asset, user=anon, text="test", submitted=now()) t1.full_clean() t1.save() self.assertEqual( Asset.objects.get(pk=asset.pk).transcription_status, TranscriptionStatus.SUBMITTED, ) # “Login” so we can review the anonymous transcription: self.login_user() self.assertEqual( 1, Transcription.objects.filter(pk=t1.pk, accepted__isnull=True).count()) resp = self.client.post(reverse("review-transcription", args=(t1.pk, )), data={"action": "reject"}) self.assertValidJSON(resp, expected_status=200) # After rejecting a transcription, the asset status should be reset to # in-progress: self.assertEqual( 1, Transcription.objects.filter(pk=t1.pk, accepted__isnull=True, rejected__isnull=False).count(), ) self.assertEqual( Asset.objects.get(pk=asset.pk).transcription_status, TranscriptionStatus.IN_PROGRESS, ) # We'll simulate a second attempt: t2 = Transcription(asset=asset, user=anon, text="test", submitted=now(), supersedes=t1) t2.full_clean() t2.save() self.assertEqual( Asset.objects.get(pk=asset.pk).transcription_status, TranscriptionStatus.SUBMITTED, ) resp = self.client.post(reverse("review-transcription", args=(t2.pk, )), data={"action": "accept"}) self.assertValidJSON(resp, expected_status=200) self.assertEqual( 1, Transcription.objects.filter(pk=t2.pk, accepted__isnull=False).count()) self.assertEqual( Asset.objects.get(pk=asset.pk).transcription_status, TranscriptionStatus.COMPLETED, )