Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pivotal ID # 174316468: Project Refresh AccNo Template Validation #257

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ internal class ProjectSubmitTest(tempFolder: TemporaryFolder) : BaseIntegrationT
assertThat(webClient.submitSingle(aProject, SubmissionFormat.TSV)).isSuccessful()
assertThatExceptionOfType(WebClientException::class.java)
.isThrownBy { webClient.submitSingle(anotherProject, SubmissionFormat.TSV) }
.withMessageContaining("There is a project already using the accNo template S-APRJ")
.withMessageContaining("There is a project already using the accNo template 'S-APRJ'")
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package ac.uk.ebi.biostd.submission.exceptions

class ProjectAlreadyExistingException(project: String) : RuntimeException("The project $project already exists")
class ProjectAlreadyExistingException(project: String) : RuntimeException("The project '$project' already exists")

class ProjectAccNoTemplateAlreadyExistsException(
pattern: String
) : RuntimeException("There is a project already using the accNo template $pattern")
) : RuntimeException("There is a project already using the accNo template '$pattern'")

class ProjectInvalidAccNoPatternException(message: String) : RuntimeException(message)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,38 @@ class ProjectInfoService(
private val accNoUtil: AccNoPatternUtil,
private val privilegesService: IUserPrivilegesService
) {
@Suppress("ThrowsCount")
fun process(request: ProjectRequest): ProjectResponse? {
if (request.subType != "Project") return null
val (submitter, subType, template, accNo) = request

val submitter = request.submitter
val template = request.accNoTemplate
val accNo = request.accNo
if (subType != "Project") return null

val isNew = queryService.isNew(accNo)
require(privilegesService.canSubmitProjects(submitter)) { throw UserCanNotSubmitProjectsException(submitter) }
require(template != null) { throw ProjectInvalidAccNoPatternException(ACC_NO_TEMPLATE_REQUIRED) }
require(accNoUtil.isPattern(template)) { throw ProjectInvalidAccNoPatternException(ACC_NO_TEMPLATE_INVALID) }
require(queryService.isNew(accNo).not() || context.accessTagExists(accNo).not()) {
throw ProjectAlreadyExistingException(accNo)
}
validatePattern(template)

val accNoPattern = accNoUtil.getPattern(template!!)
validateProject(isNew, accNo, accNoPattern)
persist(isNew, accNo, accNoPattern)

return ProjectResponse(request.accNo)
}

val accNoPattern = accNoUtil.getPattern(template)
require(context.sequenceAccNoPatternExists(accNoPattern).not()) {
private fun validateProject(isNew: Boolean, accNo: String, accNoPattern: String) {
if (isNew && context.accessTagExists(accNo)) throw ProjectAlreadyExistingException(accNo)
if (isNew && context.sequenceAccNoPatternExists(accNoPattern))
throw ProjectAccNoTemplateAlreadyExistsException(accNoPattern)
}
}

context.createAccNoPatternSequence(accNoPattern)
context.saveAccessTag(accNo)
private fun validatePattern(template: String?) {
require(template != null) { throw ProjectInvalidAccNoPatternException(ACC_NO_TEMPLATE_REQUIRED) }
require(accNoUtil.isPattern(template)) { throw ProjectInvalidAccNoPatternException(ACC_NO_TEMPLATE_INVALID) }
}

return ProjectResponse(request.accNo)
private fun persist(isNew: Boolean, accNo: String, accNoPattern: String) {
if (isNew) {
context.saveAccessTag(accNo)
context.createAccNoPatternSequence(accNoPattern)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package ac.uk.ebi.biostd.submission.service

import ac.uk.ebi.biostd.persistence.integration.PersistenceContext
import ac.uk.ebi.biostd.persistence.integration.SubmissionQueryService
import ac.uk.ebi.biostd.submission.exceptions.ProjectAccNoTemplateAlreadyExistsException
import ac.uk.ebi.biostd.submission.exceptions.ProjectAlreadyExistingException
import ac.uk.ebi.biostd.submission.exceptions.ProjectInvalidAccNoPatternException
import ac.uk.ebi.biostd.submission.exceptions.UserCanNotSubmitProjectsException
import ac.uk.ebi.biostd.submission.util.AccNoPatternUtil
import ebi.ac.uk.security.integration.components.IUserPrivilegesService
import io.mockk.clearAllMocks
import io.mockk.every
import io.mockk.impl.annotations.MockK
import io.mockk.junit5.MockKExtension
import io.mockk.verify
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.AfterEach
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import org.junit.jupiter.api.extension.ExtendWith
import kotlin.test.assertNotNull
import kotlin.test.assertNull

@ExtendWith(MockKExtension::class)
class ProjectInfoServiceTest(
@MockK private val context: PersistenceContext,
@MockK private val queryService: SubmissionQueryService,
@MockK private val accNoUtil: AccNoPatternUtil,
@MockK private val privilegesService: IUserPrivilegesService
) {
private val testInstance = ProjectInfoService(context, queryService, accNoUtil, privilegesService)

@AfterEach
fun afterEach() = clearAllMocks()

@BeforeEach
fun beforeEach() {
initContext()
initAccNoUtil()
every { queryService.isNew("TheProject") } returns true
every { privilegesService.canSubmitProjects("user@test.org") } returns true
}

@Test
fun process() {
val request = ProjectRequest("user@test.org", "Project", "!{S-PRJ}", "TheProject")
val response = testInstance.process(request)

assertNotNull(response)
assertThat(response.accessTag).isEqualTo("TheProject")
verify(exactly = 1) { context.saveAccessTag("TheProject") }
verify(exactly = 1) { context.createAccNoPatternSequence("S-PRJ") }
}

@Test
fun `non project`() {
val request = ProjectRequest("user@test.org", "Study", "!{S-PRJ}", "TheProject")
assertNull(testInstance.process(request))
}

@Test
fun `user cant submit projects`() {
every { privilegesService.canSubmitProjects("user@test.org") } returns false

val request = ProjectRequest("user@test.org", "Project", "!{S-PRJ}", "TheProject")
val exception = assertThrows<UserCanNotSubmitProjectsException> { testInstance.process(request) }

assertThat(exception.message).isEqualTo("The user user@test.org is not allowed to submit projects")
}

@Test
fun `no template`() {
val request = ProjectRequest("user@test.org", "Project", null, "TheProject")
val exception = assertThrows<ProjectInvalidAccNoPatternException> { testInstance.process(request) }

assertThat(exception.message).isEqualTo(ACC_NO_TEMPLATE_REQUIRED)
}

@Test
fun `invalid pattern`() {
every { accNoUtil.getPattern("Invalid") } returns ""
every { accNoUtil.isPattern("Invalid") } returns false

val request = ProjectRequest("user@test.org", "Project", "Invalid", "TheProject")
val exception = assertThrows<ProjectInvalidAccNoPatternException> { testInstance.process(request) }
assertThat(exception.message).isEqualTo(ACC_NO_TEMPLATE_INVALID)
}

@Test
fun `already existing project`() {
every { context.accessTagExists("TheProject") } returns true

val request = ProjectRequest("user@test.org", "Project", "!{S-PRJ}", "TheProject")
val exception = assertThrows<ProjectAlreadyExistingException> { testInstance.process(request) }

assertThat(exception.message).isEqualTo("The project 'TheProject' already exists")
}

@Test
fun `pattern accNo already in use`() {
every { context.sequenceAccNoPatternExists("S-PRJ") } returns true

val request = ProjectRequest("user@test.org", "Project", "!{S-PRJ}", "TheProject")
val exception = assertThrows<ProjectAccNoTemplateAlreadyExistsException> { testInstance.process(request) }

assertThat(exception.message).isEqualTo("There is a project already using the accNo template 'S-PRJ'")
}

private fun initContext() {
every { context.saveAccessTag("TheProject") } answers { nothing }
every { context.accessTagExists("TheProject") } returns false
every { context.sequenceAccNoPatternExists("S-PRJ") } returns false
every { context.createAccNoPatternSequence("S-PRJ") } answers { nothing }
}

private fun initAccNoUtil() {
every { accNoUtil.getPattern("!{S-PRJ}") } returns "S-PRJ"
every { accNoUtil.isPattern("!{S-PRJ}") } returns true
}
}