Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
82703d7
commit bd2d31e
Showing
30 changed files
with
1,561 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
70 changes: 70 additions & 0 deletions
70
dsp-project/core/src/main/scala/dsp/project/api/ProjectRepo.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package dsp.project.api | ||
|
||
import zio._ | ||
import zio.macros.accessible | ||
|
||
import dsp.project.domain._ | ||
import dsp.valueobjects.Project._ | ||
import dsp.valueobjects._ | ||
|
||
/** | ||
* The trait (interface) for the project repository. The project repository is responsible for storing and retrieving projects. | ||
* Needs to be used by the project repository implementations. | ||
*/ | ||
@accessible // with this annotation we don't have to write the companion object ourselves | ||
trait ProjectRepo { | ||
|
||
/** | ||
* Writes a project to the repository (used for both create and update). | ||
* If this fails (e.g. the triplestore is not available), it's a non-recovable error. That's why we need UIO. | ||
* When used, we should do it like: ...store(...).orDie | ||
* | ||
* @param project the project to write | ||
* @return The project ID | ||
*/ | ||
def storeProject(project: Project): UIO[ProjectId] | ||
|
||
/** | ||
* Gets all projects from the repository. | ||
* | ||
* @return a list of [[Project]] | ||
*/ | ||
def getProjects(): UIO[List[Project]] | ||
|
||
/** | ||
* Retrieves the project from the repository by ID. | ||
* | ||
* @param id the project's ID | ||
* @return an optional [[Project]] | ||
*/ | ||
def getProjectById(id: ProjectId): IO[Option[Nothing], Project] | ||
|
||
/** | ||
* Retrieves the project from the repository by ShortCode. | ||
* | ||
* @param shortCode ShortCode of the project. | ||
* @return an optional [[Project]]. | ||
*/ | ||
def getProjectByShortCode(shortCode: ShortCode): IO[Option[Nothing], Project] | ||
|
||
/** | ||
* Checks if a project ShortCode is available or if it already exists in the repo. | ||
* | ||
* @param shortCode ShortCode of the project. | ||
* @return Success of Unit if the ShortCode is available, Error of None if not. | ||
*/ | ||
def checkIfShortCodeIsAvailable(shortCode: ShortCode): IO[Option[Nothing], Unit] | ||
|
||
/** | ||
* Deletes a [[Project]] from the repository by its [[ProjectId]]. | ||
* | ||
* @param id the project ID | ||
* @return Project ID or None if not found | ||
*/ | ||
def deleteProject(id: ProjectId): IO[Option[Nothing], ProjectId] | ||
} |
67 changes: 67 additions & 0 deletions
67
dsp-project/core/src/main/scala/dsp/project/domain/ProjectDomain.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright © 2021 - 2022 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package dsp.project.domain | ||
|
||
import zio.prelude.Validation | ||
|
||
import dsp.errors.ValidationException | ||
import dsp.valueobjects.Project._ | ||
import dsp.valueobjects._ | ||
|
||
/** | ||
* Represents the project domain object. | ||
* | ||
* @param id the ID of the project | ||
* @param name the name of the project | ||
* @param description the description of the project | ||
*/ | ||
sealed abstract case class Project private ( | ||
id: ProjectId, | ||
name: Name, | ||
description: ProjectDescription | ||
// TODO-BL: [domain-model] missing status, shortname, selfjoin | ||
) extends Ordered[Project] { self => | ||
|
||
/** | ||
* Allows to sort collections of [[Project]]s. Sorting is done by the IRI. | ||
*/ | ||
def compare(that: Project): Int = self.id.iri.toString().compareTo(that.id.iri.toString()) | ||
|
||
/** | ||
* Updates the name of the project. | ||
* | ||
* @param name the new name | ||
* @return the updated Project or a ValidationException | ||
*/ | ||
def updateProjectName(name: Name): Validation[ValidationException, Project] = | ||
Project.make( | ||
id = self.id, | ||
name = name, | ||
description = self.description | ||
) | ||
|
||
/** | ||
* Updates the description of the project. | ||
* | ||
* @param description the new description | ||
* @return the updated Project or a ValidationException | ||
*/ | ||
def updateProjectDescription(description: ProjectDescription): Validation[ValidationException, Project] = | ||
Project.make( | ||
id = self.id, | ||
name = self.name, | ||
description = description | ||
) | ||
} | ||
object Project { | ||
def make( | ||
id: ProjectId, | ||
name: Name, | ||
description: ProjectDescription | ||
): Validation[ValidationException, Project] = | ||
Validation.succeed(new Project(id = id, name = name, description = description) {}) | ||
|
||
} |
96 changes: 96 additions & 0 deletions
96
dsp-project/core/src/test/scala/dsp/project/domain/ProjectDomainSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* Copyright © 2021 - 2022 Swiss National Data and Service Center for the Humanities and/or DaSCH Service Platform contributors. | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package dsp.project.domain | ||
|
||
import zio.test._ | ||
|
||
import dsp.valueobjects.Iri | ||
import dsp.valueobjects.Project._ | ||
import dsp.valueobjects.ProjectId | ||
import dsp.valueobjects.V2 | ||
|
||
/** | ||
* This spec is used to test [[dsp.project.domain.ProjectDomain]]. | ||
*/ | ||
object ProjectDomainSpec extends ZIOSpecDefault { | ||
|
||
private val shortCode = ShortCode.make("0001").fold(e => throw e.head, v => v) | ||
private val id = ProjectId.make(shortCode).fold(e => throw e.head, v => v) | ||
private val name = Name.make("proj").fold(e => throw e.head, v => v) | ||
private val description = ProjectDescription | ||
.make(Seq(V2.StringLiteralV2("A Project", Some("en")))) | ||
.fold(e => throw e.head, v => v) | ||
|
||
override def spec = | ||
suite("ProjectDomainSpec")( | ||
projectCreateTests, | ||
projectCompareTests, | ||
projectUpdateTests | ||
) | ||
|
||
val projectCreateTests = suite("create project")( | ||
test("create a project from valid input") { | ||
(for { | ||
project <- Project.make(id, name, description) | ||
} yield ( | ||
assertTrue(project.id == id) && | ||
assertTrue(project.name == name) && | ||
assertTrue(project.description == description) | ||
)).toZIO | ||
} | ||
) | ||
|
||
val projectCompareTests = suite("compare projects")( | ||
test("compare projects by IRI") { | ||
val iri1String = s"http://rdfh.ch/projects/d78c6cc8-0a18-4131-af72-4bb6cb688bed" | ||
val iri2String = s"http://rdfh.ch/projects/f4184d7a-caf7-4ab9-991e-d5da9eb7ec17" | ||
(for { | ||
iri1 <- Iri.ProjectIri.make(iri1String) | ||
iri2 <- Iri.ProjectIri.make(iri2String) | ||
id1 <- ProjectId.fromIri(iri1, shortCode) | ||
id2 <- ProjectId.fromIri(iri2, shortCode) | ||
project1 <- Project.make(id1, name, description) | ||
project2 <- Project.make(id2, name, description) | ||
listInitial = List(project1, project2) | ||
listSorted = listInitial.sorted | ||
listSortedInverse = listInitial.sortWith(_ > _) | ||
} yield ( | ||
assertTrue(listInitial == listSorted) && | ||
assertTrue(listInitial != listSortedInverse) && | ||
assertTrue(listInitial == listSortedInverse.reverse) | ||
)).toZIO | ||
} | ||
) | ||
|
||
val projectUpdateTests = suite("update project")( | ||
test("update a project name when provided a valid new name") { | ||
(for { | ||
newName <- Name.make("new project name") | ||
project <- Project.make(id, name, description) | ||
updatedProject <- project.updateProjectName(newName) | ||
} yield ( | ||
assertTrue(project.id == updatedProject.id) && | ||
assertTrue(project.name != updatedProject.name) && | ||
assertTrue(project.description == updatedProject.description) && | ||
assertTrue(project.name == name) && | ||
assertTrue(updatedProject.name == newName) | ||
)).toZIO | ||
}, | ||
test("update a project description when provided a valid new description") { | ||
(for { | ||
newDescription <- ProjectDescription.make(Seq(V2.StringLiteralV2("new project name", Some("en")))) | ||
project <- Project.make(id, name, description) | ||
updatedProject <- project.updateProjectDescription(newDescription) | ||
} yield ( | ||
assertTrue(project.id == updatedProject.id) && | ||
assertTrue(project.name == updatedProject.name) && | ||
assertTrue(project.description != updatedProject.description) && | ||
assertTrue(project.description == description) && | ||
assertTrue(updatedProject.description == newDescription) | ||
)).toZIO | ||
} | ||
) | ||
} |
Oops, something went wrong.