Skip to content

Commit

Permalink
refactor: Migrate /admin/files to tapir (DEV-3189) (#2995)
Browse files Browse the repository at this point in the history
  • Loading branch information
seakayone authored Jan 18, 2024
1 parent 1ea69a4 commit 78ff954
Show file tree
Hide file tree
Showing 20 changed files with 351 additions and 334 deletions.
14 changes: 9 additions & 5 deletions integration/src/test/scala/org/knora/sipi/SipiIT.scala
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,8 @@ object SipiIT extends ZIOSpecDefault {
"when getting the file, " +
"then Sipi responds with Ok"
) {
val dspApiResponse = SipiFileInfoGetResponseADM(permissionCode = 2, restrictedViewSettings = None)
val dspApiResponse =
PermissionCodeAndProjectRestrictedViewSettings(permissionCode = 2, restrictedViewSettings = None)
val dspApiPermissionPath = s"/admin/files/$prefix/$imageTestfile"
for {
server <- MockDspApiServer.resetAndStubGetResponse(dspApiPermissionPath, 200, dspApiResponse)
Expand All @@ -177,7 +178,8 @@ object SipiIT extends ZIOSpecDefault {
"when getting the file, " +
"then Sipi responds with Unauthorized"
) {
val dspApiResponse = SipiFileInfoGetResponseADM(permissionCode = 0, restrictedViewSettings = None)
val dspApiResponse =
PermissionCodeAndProjectRestrictedViewSettings(permissionCode = 0, restrictedViewSettings = None)
val dspApiPermissionPath = s"/admin/files/$prefix/$imageTestfile"
for {
server <- MockDspApiServer.resetAndStubGetResponse(dspApiPermissionPath, 200, dspApiResponse)
Expand Down Expand Up @@ -225,7 +227,8 @@ object SipiIT extends ZIOSpecDefault {
"when getting the file, " +
"Sipi responds with Ok"
) {
val dspApiResponse = SipiFileInfoGetResponseADM(permissionCode = 2, restrictedViewSettings = None)
val dspApiResponse =
PermissionCodeAndProjectRestrictedViewSettings(permissionCode = 2, restrictedViewSettings = None)
val dspApiPermissionPath = s"/admin/files/$prefix/$imageTestfile"
for {
server <- MockDspApiServer.resetAndStubGetResponse(dspApiPermissionPath, 200, dspApiResponse)
Expand All @@ -240,7 +243,8 @@ object SipiIT extends ZIOSpecDefault {
"when getting the file, " +
"Sipi responds with Unauthorized"
) {
val dspApiResponse = SipiFileInfoGetResponseADM(permissionCode = 0, restrictedViewSettings = None)
val dspApiResponse =
PermissionCodeAndProjectRestrictedViewSettings(permissionCode = 0, restrictedViewSettings = None)
val dspApiPermissionPath = s"/admin/files/$prefix/$imageTestfile"
for {
server <- MockDspApiServer.resetAndStubGetResponse(dspApiPermissionPath, 200, dspApiResponse)
Expand Down Expand Up @@ -321,7 +325,7 @@ object MockDspApiServer {
identifier: String,
permissionCode: Int
): URIO[WireMockServer, WireMockServer] = {
val dspApiResponse = SipiFileInfoGetResponseADM(permissionCode, restrictedViewSettings = None)
val dspApiResponse = PermissionCodeAndProjectRestrictedViewSettings(permissionCode, restrictedViewSettings = None)
val dspApiPermissionPath = s"/admin/files/$prefix/$identifier"
MockDspApiServer.resetAndStubGetResponse(dspApiPermissionPath, 200, dspApiResponse)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ object LayersTest {
with ConstructResponseUtilV2
with ConstructTransformer
with DspIngestClient
with FilesEndpoints
with FilesEndpointsHandler
with GravsearchTypeInspectionRunner
with GroupsResponderADM
with HttpServer
Expand Down Expand Up @@ -129,7 +131,7 @@ object LayersTest {
with RestResourceInfoService
with SearchApiRoutes
with SearchResponderV2
with SipiResponderADM
with AssetPermissionResponder
with StandoffResponderV2
with StandoffTagUtilV2
with State
Expand All @@ -156,6 +158,8 @@ object LayersTest {
ConstructResponseUtilV2Live.layer,
ConstructTransformer.layer,
DspIngestClientLive.layer,
FilesEndpoints.layer,
FilesEndpointsHandler.layer,
GravsearchTypeInspectionRunner.layer,
GroupsEndpoints.layer,
GroupsEndpointsHandler.layer,
Expand Down Expand Up @@ -205,7 +209,7 @@ object LayersTest {
SearchApiRoutes.layer,
SearchEndpoints.layer,
SearchResponderV2Live.layer,
SipiResponderADMLive.layer,
AssetPermissionResponder.layer,
StandoffResponderV2Live.layer,
StandoffTagUtilV2Live.layer,
State.layer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,32 @@

package org.knora.webapi.e2e.admin

import org.apache.pekko
import org.apache.pekko.http.scaladsl.model.*
import org.apache.pekko.http.scaladsl.model.headers.BasicHttpCredentials
import org.apache.pekko.http.scaladsl.unmarshalling.Unmarshal

import scala.concurrent.Await
import scala.concurrent.duration.*

import org.knora.webapi.E2ESpec
import org.knora.webapi.messages.admin.responder.sipimessages.SipiFileInfoGetResponseADM
import org.knora.webapi.messages.admin.responder.sipimessages.PermissionCodeAndProjectRestrictedViewSettings
import org.knora.webapi.messages.admin.responder.sipimessages.SipiResponderResponseADMJsonProtocol.*
import org.knora.webapi.messages.store.triplestoremessages.RdfDataObject
import org.knora.webapi.messages.store.triplestoremessages.TriplestoreJsonProtocol
import org.knora.webapi.routing.Authenticator
import org.knora.webapi.routing.UnsafeZioRun
import org.knora.webapi.sharedtestdata.SharedTestDataADM2

import pekko.http.scaladsl.model.*
import pekko.http.scaladsl.unmarshalling.Unmarshal

/**
* End-to-End (E2E) test specification for Sipi access.
*
* This spec tests the 'admin/files'.
*/
class FilesADME2ESpec extends E2ESpec with TriplestoreJsonProtocol {
class AdminFilesE2ESpec extends E2ESpec with TriplestoreJsonProtocol {

private val anythingAdminEmail = SharedTestDataADM2.anythingAdminUser.userData.email.get
private val anythingAdminEmailEnc = java.net.URLEncoder.encode(anythingAdminEmail, "utf-8")
private val normalUserEmail = SharedTestDataADM2.normalUser.userData.email.get
private val normalUserEmailEnc = java.net.URLEncoder.encode(normalUserEmail, "utf-8")
private val testPass = java.net.URLEncoder.encode("test", "utf-8")
private val anythingAdminEmail = SharedTestDataADM2.anythingAdminUser.userData.email.get
private val normalUserEmail = SharedTestDataADM2.normalUser.userData.email.get
private val testPass = "test"

val KnoraAuthenticationCookieName = UnsafeZioRun.runOrThrow(Authenticator.calculateCookieName())

Expand All @@ -48,54 +45,56 @@ class FilesADME2ESpec extends E2ESpec with TriplestoreJsonProtocol {

"return CR (8) permission code" in {
/* anything image */
val request = Get(
baseApiUrl + s"/admin/files/0001/B1D0OkEgfFp-Cew2Seur7Wi.jp2?email=$anythingAdminEmailEnc&password=$testPass"
)
val request = Get(baseApiUrl + s"/admin/files/0001/B1D0OkEgfFp-Cew2Seur7Wi.jp2") ~>
addCredentials(BasicHttpCredentials(anythingAdminEmail, testPass))
val response: HttpResponse = singleAwaitingRequest(request)

// println(response.toString)

assert(response.status == StatusCodes.OK)

val fr: SipiFileInfoGetResponseADM =
Await.result(Unmarshal(response.entity).to[SipiFileInfoGetResponseADM], 1.seconds)
val fr: PermissionCodeAndProjectRestrictedViewSettings =
Await.result(Unmarshal(response.entity).to[PermissionCodeAndProjectRestrictedViewSettings], 1.seconds)

(fr.permissionCode === 8) should be(true)
fr.permissionCode shouldEqual 8
}

"return RV (1) permission code" in {
/* anything image */
val request =
Get(baseApiUrl + s"/admin/files/0001/B1D0OkEgfFp-Cew2Seur7Wi.jp2?email=$normalUserEmailEnc&password=$testPass")
Get(baseApiUrl + s"/admin/files/0001/B1D0OkEgfFp-Cew2Seur7Wi.jp2") ~>
addCredentials(BasicHttpCredentials(normalUserEmail, testPass))
val response: HttpResponse = singleAwaitingRequest(request)

// println(response.toString)

assert(response.status == StatusCodes.OK)

val fr: SipiFileInfoGetResponseADM =
Await.result(Unmarshal(response.entity).to[SipiFileInfoGetResponseADM], 1.seconds)
val fr: PermissionCodeAndProjectRestrictedViewSettings =
Await.result(Unmarshal(response.entity).to[PermissionCodeAndProjectRestrictedViewSettings], 1.seconds)

(fr.permissionCode === 1) should be(true)
}

"return 404 Not Found if a file value is in a deleted resource" in {
val request =
Get(baseApiUrl + s"/admin/files/0001/9hxmmrWh0a7-CnRCq0650ro.jpx?email=$normalUserEmailEnc&password=$testPass")
Get(baseApiUrl + s"/admin/files/0001/9hxmmrWh0a7-CnRCq0650ro.jpx") ~>
addCredentials(BasicHttpCredentials(normalUserEmail, testPass))
val response: HttpResponse = singleAwaitingRequest(request)

assert(response.status == StatusCodes.NotFound)
}

"return permissions for a previous version of a file value" in {
val request =
Get(baseApiUrl + s"/admin/files/0001/QxFMm5wlRlatStw9ft3iZA.jp2?email=$normalUserEmailEnc&password=$testPass")
Get(baseApiUrl + s"/admin/files/0001/QxFMm5wlRlatStw9ft3iZA.jp2") ~>
addCredentials(BasicHttpCredentials(normalUserEmail, testPass))
val response: HttpResponse = singleAwaitingRequest(request)

assert(response.status == StatusCodes.OK)

val fr: SipiFileInfoGetResponseADM =
Await.result(Unmarshal(response.entity).to[SipiFileInfoGetResponseADM], 1.seconds)
val fr: PermissionCodeAndProjectRestrictedViewSettings =
Await.result(Unmarshal(response.entity).to[PermissionCodeAndProjectRestrictedViewSettings], 1.seconds)

(fr.permissionCode === 1) should be(true)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@ package org.knora.webapi.responders.admin

import org.apache.pekko.testkit.*

import scala.concurrent.duration.*

import org.knora.webapi.*
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectIdentifierADM.ShortcodeIdentifier
import org.knora.webapi.messages.admin.responder.projectsmessages.ProjectRestrictedViewSettingsADM
import org.knora.webapi.messages.admin.responder.sipimessages.*
import org.knora.webapi.messages.store.triplestoremessages.RdfDataObject
import org.knora.webapi.routing.UnsafeZioRun
import org.knora.webapi.sharedtestdata.SharedTestDataADM
import org.knora.webapi.slice.admin.domain.model.KnoraProject.Shortcode

/**
* Tests [[SipiResponderADM]].
* Tests [[AssetPermissionResponder]].
*/
class SipiResponderADMSpec extends CoreSpec with ImplicitSender {
class AssetPermissionResponderSpec extends CoreSpec with ImplicitSender {

override lazy val rdfDataObjects = List(
RdfDataObject(
Expand All @@ -28,35 +27,33 @@ class SipiResponderADMSpec extends CoreSpec with ImplicitSender {
)
)

// The default timeout for receiving reply messages from actors.
override implicit val timeout: FiniteDuration = 20.seconds

"The Sipi responder" should {
"return details of a full quality file value" in {
// http://localhost:3333/v1/files/http%3A%2F%2Frdfh.ch%2F8a0b1e75%2Freps%2F7e4ba672
appActor ! SipiFileInfoGetRequestADM(
projectID = Shortcode.unsafeFrom("0803"),
filename = "incunabula_0000003328.jp2",
requestingUser = SharedTestDataADM.incunabulaMemberUser
val actual = UnsafeZioRun.runOrThrow(
AssetPermissionResponder.getFileInfoForSipiADM(
ShortcodeIdentifier.unsafeFrom("0803"),
"incunabula_0000003328.jp2",
SharedTestDataADM.incunabulaMemberUser
)
)

expectMsg(timeout, SipiFileInfoGetResponseADM(permissionCode = 6, None))
actual shouldEqual PermissionCodeAndProjectRestrictedViewSettings(permissionCode = 6, None)
}

"return details of a restricted view file value" in {
// http://localhost:3333/v1/files/http%3A%2F%2Frdfh.ch%2F8a0b1e75%2Freps%2F7e4ba672
appActor ! SipiFileInfoGetRequestADM(
projectID = Shortcode.unsafeFrom("0803"),
filename = "incunabula_0000003328.jp2",
requestingUser = SharedTestDataADM.anonymousUser
val actual = UnsafeZioRun.runOrThrow(
AssetPermissionResponder.getFileInfoForSipiADM(
ShortcodeIdentifier.unsafeFrom("0803"),
"incunabula_0000003328.jp2",
SharedTestDataADM.anonymousUser
)
)

expectMsg(
timeout,
SipiFileInfoGetResponseADM(
permissionCode = 1,
Some(ProjectRestrictedViewSettingsADM(size = Some("!512,512"), watermark = Some("path_to_image")))
)
actual shouldEqual PermissionCodeAndProjectRestrictedViewSettings(
permissionCode = 1,
Some(ProjectRestrictedViewSettingsADM(size = Some("!512,512"), watermark = Some("path_to_image")))
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,14 +31,13 @@ import org.knora.webapi.slice.admin.api.model.ProjectsEndpointsRequests.ProjectC
import org.knora.webapi.slice.admin.api.model.ProjectsEndpointsRequests.ProjectUpdateRequest
import org.knora.webapi.slice.admin.domain.model.KnoraProject.*
import org.knora.webapi.util.MutableTestIri
import org.knora.webapi.util.ZioScalaTestUtil.assertFailsWithA

/**
* This spec is used to test the messages received by the [[ProjectsResponderADM]] actor.
*/
class ProjectsResponderADMSpec extends CoreSpec with ImplicitSender {

private val rootUser = SharedTestDataADM.rootUser

private val notExistingProjectButValidProjectIri = "http://rdfh.ch/projects/notexisting"

"The ProjectsResponderADM" when {
Expand Down Expand Up @@ -105,59 +104,68 @@ class ProjectsResponderADMSpec extends CoreSpec with ImplicitSender {
val expectedResult = ProjectRestrictedViewSettingsADM(size = Some("!512,512"), watermark = Some("path_to_image"))

"return restricted view settings using project IRI" in {
appActor ! ProjectRestrictedViewSettingsGetADM(
identifier = IriIdentifier
.fromString(SharedTestDataADM.imagesProject.id)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
val actual = UnsafeZioRun.runOrThrow(
ProjectsResponderADM.projectRestrictedViewSettingsGetADM(
IriIdentifier
.fromString(SharedTestDataADM.imagesProject.id)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
)
)
expectMsg(Some(expectedResult))
actual shouldEqual Some(expectedResult)
}

"return restricted view settings using project SHORTNAME" in {
appActor ! ProjectRestrictedViewSettingsGetADM(
identifier = ShortnameIdentifier
.fromString(SharedTestDataADM.imagesProject.shortname)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
val actual = UnsafeZioRun.runOrThrow(
ProjectsResponderADM.projectRestrictedViewSettingsGetADM(
ShortnameIdentifier
.fromString(SharedTestDataADM.imagesProject.shortname)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
)
)
expectMsg(Some(expectedResult))
actual shouldEqual Some(expectedResult)
}

"return restricted view settings using project SHORTCODE" in {
appActor ! ProjectRestrictedViewSettingsGetADM(
identifier = ShortcodeIdentifier
.fromString(SharedTestDataADM.imagesProject.shortcode)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
val actual = UnsafeZioRun.runOrThrow(
ProjectsResponderADM.projectRestrictedViewSettingsGetADM(
ShortcodeIdentifier.unsafeFrom(SharedTestDataADM.imagesProject.shortcode)
)
)
expectMsg(Some(expectedResult))
actual shouldEqual Some(expectedResult)
}

"return 'NotFoundException' when the project IRI is unknown" in {
appActor ! ProjectRestrictedViewSettingsGetRequestADM(
identifier = IriIdentifier
.fromString(notExistingProjectButValidProjectIri)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
val exit = UnsafeZioRun.run(
ProjectsResponderADM.projectRestrictedViewSettingsGetRequestADM(
IriIdentifier
.fromString(notExistingProjectButValidProjectIri)
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
)
)
expectMsg(Failure(NotFoundException(s"Project '$notExistingProjectButValidProjectIri' not found.")))
assertFailsWithA[NotFoundException](exit, s"Project '$notExistingProjectButValidProjectIri' not found.")
}

"return 'NotFoundException' when the project SHORTCODE is unknown" in {
appActor ! ProjectRestrictedViewSettingsGetRequestADM(
identifier = ShortcodeIdentifier
.fromString("9999")
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
val exit = UnsafeZioRun.run(
ProjectsResponderADM.projectRestrictedViewSettingsGetRequestADM(
ShortcodeIdentifier
.fromString("9999")
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
)
)
expectMsg(Failure(NotFoundException(s"Project '9999' not found.")))
assertFailsWithA[NotFoundException](exit, s"Project '9999' not found.")
}

"return 'NotFoundException' when the project SHORTNAME is unknown" in {
appActor ! ProjectRestrictedViewSettingsGetRequestADM(
identifier = ShortnameIdentifier
.fromString("wrongshortname")
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
val exit = UnsafeZioRun.run(
ProjectsResponderADM.projectRestrictedViewSettingsGetRequestADM(
ShortnameIdentifier
.fromString("wrongshortname")
.getOrElseWith(e => throw BadRequestException(e.head.getMessage))
)
)
expectMsg(Failure(NotFoundException(s"Project 'wrongshortname' not found.")))
assertFailsWithA[NotFoundException](exit, s"Project 'wrongshortname' not found.")
}

}

"used to modify project information" should {
Expand Down
Loading

0 comments on commit 78ff954

Please sign in to comment.