Skip to content

Commit 6920716

Browse files
authored
refactor(v3): add role slice (DEV-1010) (#2099)
* add sbt projects and dependencies * add role domain * add Role value objects + fix build * add LangString value object * add RoleIri value object + tests * update RoleId + LangString * add role test data + domain tests * add role repo implementation * add permission value object + update LangString * naming improvements * add interface placeholders * add RoleRepoMock * fix RoleRepoSpec name * add RoleHandler + tests * add RoleRepoLive + tests * update docs + cleanup * forgotten docs * review changes * fix merge issues
1 parent 5cec8ba commit 6920716

24 files changed

Lines changed: 1395 additions & 33 deletions

File tree

‎build.sbt‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,76 @@ lazy val valueObjects = project
242242
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework"))
243243
)
244244

245+
// Role projects
246+
247+
lazy val roleInterface = project
248+
.in(file("dsp-role/interface"))
249+
.settings(
250+
scalacOptions ++= Seq(
251+
"-feature",
252+
"-unchecked",
253+
"-deprecation",
254+
"-Yresolve-term-conflict:package",
255+
"-Ymacro-annotations"
256+
),
257+
name := "roleInterface",
258+
libraryDependencies ++= Dependencies.roleInterfaceLibraryDependencies,
259+
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework"))
260+
)
261+
.dependsOn(shared, roleHandler)
262+
263+
lazy val roleHandler = project
264+
.in(file("dsp-role/handler"))
265+
.settings(
266+
scalacOptions ++= Seq(
267+
"-feature",
268+
"-unchecked",
269+
"-deprecation",
270+
"-Yresolve-term-conflict:package",
271+
"-Ymacro-annotations"
272+
),
273+
name := "roleHandler",
274+
libraryDependencies ++= Dependencies.roleHandlerLibraryDependencies,
275+
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework"))
276+
)
277+
.dependsOn(
278+
shared,
279+
roleCore % "compile->compile;test->test",
280+
roleRepo % "test->test"
281+
)
282+
283+
lazy val roleRepo = project
284+
.in(file("dsp-role/repo"))
285+
.settings(
286+
scalacOptions ++= Seq(
287+
"-feature",
288+
"-unchecked",
289+
"-deprecation",
290+
"-Yresolve-term-conflict:package",
291+
"-Ymacro-annotations"
292+
),
293+
name := "roleRepo",
294+
libraryDependencies ++= Dependencies.roleRepoLibraryDependencies,
295+
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework"))
296+
)
297+
.dependsOn(shared, roleCore % "compile->compile;test->test")
298+
299+
lazy val roleCore = project
300+
.in(file("dsp-role/core"))
301+
.settings(
302+
scalacOptions ++= Seq(
303+
"-feature",
304+
"-unchecked",
305+
"-deprecation",
306+
"-Yresolve-term-conflict:package",
307+
"-Ymacro-annotations"
308+
),
309+
name := "roleCore",
310+
libraryDependencies ++= Dependencies.roleCoreLibraryDependencies,
311+
testFrameworks := Seq(new TestFramework("zio.test.sbt.ZTestFramework"))
312+
)
313+
.dependsOn(shared)
314+
245315
// User projects
246316

247317
lazy val userInterface = project
@@ -312,6 +382,8 @@ lazy val userCore = project
312382
)
313383
.dependsOn(shared)
314384

385+
// Shared project
386+
315387
lazy val shared = project
316388
.in(file("dsp-shared"))
317389
.settings(
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright © 2021 - 2022 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dsp.role.api
7+
8+
import dsp.role.domain.Role
9+
import dsp.valueobjects.Id.RoleId
10+
import zio._
11+
import zio.macros.accessible
12+
13+
/**
14+
* The trait (interface) for the role repository.
15+
* The role repository is responsible for storing and retrieving roles.
16+
* Needs to be used by the role repository implementations.
17+
*/
18+
@accessible
19+
trait RoleRepo {
20+
21+
/**
22+
* Writes a role into the repository, while both creating or updating a role.
23+
*
24+
* @param r the [[Role]] to write
25+
* @return the [[RoleId]]
26+
*/
27+
def storeRole(role: Role): UIO[RoleId]
28+
29+
/**
30+
* Gets all roles from the repository.
31+
*
32+
* @return a list of [[Role]]
33+
*/
34+
def getRoles(): UIO[List[Role]]
35+
36+
/**
37+
* Retrieves a role from the repository.
38+
*
39+
* @param id the role's ID
40+
* @return the [[Role]] if found
41+
*/
42+
def getRoleById(id: RoleId): IO[Option[Nothing], Role]
43+
44+
// should the role name be unique like username???
45+
46+
/**
47+
* Deletes the [[Role]] from the repository by its [[RoleId]]
48+
*
49+
* @param id the role ID
50+
* @return the [[RoleId]] of the deleted role, if found
51+
*/
52+
def deleteRole(id: RoleId): IO[Option[Nothing], RoleId]
53+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
* Copyright © 2021 - 2022 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dsp.role.domain
7+
8+
import dsp.errors.BadRequestException
9+
import dsp.valueobjects.Id.RoleId
10+
import dsp.valueobjects.Id.UserId
11+
import dsp.valueobjects.Permission
12+
import dsp.valueobjects.Role._
13+
import zio.prelude.Validation
14+
15+
case class RoleUser(
16+
id: UserId
17+
)
18+
19+
/**
20+
* Role's domain entity.
21+
*
22+
* @param id the role's ID
23+
* @param name the role's name
24+
* @param description the role's description
25+
* @param users the role's users
26+
* @param permission the role's permission
27+
*/
28+
sealed abstract case class Role private (
29+
id: RoleId,
30+
name: LangString,
31+
description: LangString,
32+
users: List[RoleUser], // how to reperesnt the user here?
33+
permission: Permission
34+
) extends Ordered[Role] { self =>
35+
36+
/**
37+
* Allows to compare the [[Role]] instances.
38+
*
39+
* @param that [[Role]] to compare
40+
* @return [[Boolean]] value
41+
*/
42+
def compare(that: Role): Int = self.id.iri.toString().compareTo(that.id.iri.toString())
43+
44+
/**
45+
* Updates the role's name with new value.
46+
*
47+
* @param newValue new role's name to update
48+
* @return updated [[Role]]
49+
*/
50+
def updateName(newValue: LangString): Validation[BadRequestException, Role] =
51+
Role.make(
52+
self.id,
53+
newValue,
54+
self.description,
55+
self.users,
56+
self.permission
57+
)
58+
59+
/**
60+
* Updates the role's description with new value.
61+
*
62+
* @param newValue new role's description to update
63+
* @return updated [[Role]]
64+
*/
65+
def updateDescription(newValue: LangString): Validation[BadRequestException, Role] =
66+
Role.make(
67+
self.id,
68+
self.name,
69+
newValue,
70+
self.users,
71+
self.permission
72+
)
73+
74+
/**
75+
* Updates the role's users with new value.
76+
*
77+
* @param newValue new role's users to update
78+
* @return updated [[Role]]
79+
*/
80+
def updateUsers(newValue: List[RoleUser]): Validation[BadRequestException, Role] =
81+
Role.make(
82+
self.id,
83+
self.name,
84+
self.description,
85+
newValue,
86+
self.permission
87+
)
88+
89+
/**
90+
* Updates the role's permission with new value.
91+
*
92+
* @param newValue new role's permission to update
93+
* @return updated [[Role]]
94+
*/
95+
def updatePermission(newValue: Permission): Validation[BadRequestException, Role] =
96+
Role.make(
97+
self.id,
98+
self.name,
99+
self.description,
100+
self.users,
101+
newValue
102+
)
103+
}
104+
105+
object Role {
106+
def make(
107+
id: RoleId,
108+
name: LangString,
109+
description: LangString,
110+
users: List[RoleUser],
111+
permission: Permission
112+
): Validation[BadRequestException, Role] =
113+
Validation.succeed(
114+
new Role(
115+
id,
116+
name,
117+
description,
118+
users,
119+
permission
120+
) {}
121+
)
122+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/*
2+
* Copyright © 2021 - 2022 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dsp.role.api
7+
8+
/**
9+
* To be implemented...
10+
*/
11+
object placeholder {}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* Copyright © 2021 - 2022 Data and Service Center for the Humanities and/or DaSCH Service Platform contributors.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package dsp.role.domain
7+
8+
import dsp.role.sharedtestdata.RoleTestData
9+
import dsp.valueobjects.Id
10+
import dsp.valueobjects.Permission
11+
import dsp.valueobjects.Role._
12+
import zio.test._
13+
14+
/**
15+
* This spec is used to test [[RoleDomain]].
16+
*/
17+
object RoleDomainSpec extends ZIOSpecDefault {
18+
def spec = (compareRolesTest + createRoleTest + updateRoleTest)
19+
20+
private val compareRolesTest = suite("compareRoles")(
21+
test("compare two roles") {
22+
val role = RoleTestData.role1
23+
val equalRole = RoleTestData.role1
24+
val nonEqualRole = RoleTestData.role2
25+
26+
assertTrue(role == equalRole) &&
27+
assertTrue(role != nonEqualRole)
28+
}
29+
)
30+
31+
private val createRoleTest = suite("createRole")(
32+
test("create a role") {
33+
(
34+
for {
35+
id <- RoleTestData.id1
36+
name <- RoleTestData.name1
37+
description <- RoleTestData.description1
38+
users = RoleTestData.users1
39+
permission <- RoleTestData.permission1
40+
41+
role <- Role.make(
42+
id,
43+
name,
44+
description,
45+
users = users,
46+
permission
47+
)
48+
} yield assertTrue(role.id == id) &&
49+
assertTrue(role.name == name) &&
50+
assertTrue(role.description == description) &&
51+
assertTrue(role.users == users) &&
52+
assertTrue(role.permission == permission)
53+
).toZIO
54+
}
55+
)
56+
57+
private val updateRoleTest = suite("updateRole")(
58+
test("update the name") {
59+
(
60+
for {
61+
role <- RoleTestData.role1
62+
newValue <- LangString.make("newRoleName", "en")
63+
updatedRole <- role.updateName(newValue)
64+
} yield assertTrue(updatedRole.name == newValue) &&
65+
assertTrue(updatedRole.name != role.name) &&
66+
assertTrue(updatedRole.description == role.description) &&
67+
assertTrue(updatedRole.users == role.users) &&
68+
assertTrue(updatedRole.permission == role.permission)
69+
).toZIO
70+
},
71+
test("update the description") {
72+
(
73+
for {
74+
role <- RoleTestData.role1
75+
newValue <- LangString.make("New Role Description", "en")
76+
updatedRole <- role.updateDescription(newValue)
77+
} yield assertTrue(updatedRole.name == role.name) &&
78+
assertTrue(updatedRole.description == newValue) &&
79+
assertTrue(updatedRole.description != role.description) &&
80+
assertTrue(updatedRole.users == role.users) &&
81+
assertTrue(updatedRole.permission == role.permission)
82+
).toZIO
83+
},
84+
test("update the users") {
85+
(
86+
for {
87+
role <- RoleTestData.role1
88+
newValue = List(RoleUser(Id.UserId.make().fold(e => throw e.head, v => v)))
89+
updatedRole <- role.updateUsers(newValue)
90+
} yield assertTrue(updatedRole.name == role.name) &&
91+
assertTrue(updatedRole.description == role.description) &&
92+
assertTrue(updatedRole.users == newValue) &&
93+
assertTrue(updatedRole.users != role.users) &&
94+
assertTrue(updatedRole.permission == role.permission)
95+
).toZIO
96+
},
97+
test("update the permission") {
98+
(
99+
for {
100+
role <- RoleTestData.role1
101+
newValue <- Permission.make(Permission.Create)
102+
updatedRole <- role.updatePermission(newValue)
103+
} yield assertTrue(updatedRole.name == role.name) &&
104+
assertTrue(updatedRole.description == role.description) &&
105+
assertTrue(updatedRole.users == role.users) &&
106+
assertTrue(updatedRole.permission == newValue) &&
107+
assertTrue(updatedRole.permission != role.permission)
108+
).toZIO
109+
}
110+
)
111+
}

0 commit comments

Comments
 (0)