#55 Can be assign a role to members of my Workgroup

Remove Owner on Workgroup (use role MASTER instead)
"find_citizen_by_id" not return user anymore, use "find_citizen_by_id_with_user" instead
This commit is contained in:
2020-06-01 13:44:25 +02:00
parent 8ff6fcc970
commit 7874f5cec4
49 changed files with 331 additions and 217 deletions

View File

@@ -130,7 +130,7 @@ fun Application.module(env: Env = PROD) {
decode { values, _ -> decode { values, _ ->
val id = values.singleOrNull()?.let { UUID.fromString(it) } val id = values.singleOrNull()?.let { UUID.fromString(it) }
?: throw InternalError("Cannot convert $values to UUID") ?: throw InternalError("Cannot convert $values to UUID")
get<RepositoryCitizen>().findById(id, true) ?: throw NotFoundException("Citizen $values not found") get<RepositoryCitizen>().findById(id) ?: throw NotFoundException("Citizen $values not found")
} }
} }

View File

@@ -21,7 +21,12 @@ class Citizen(
) : CitizenFull, ) : CitizenFull,
CitizenBasic(id, name, email, birthday, voteAnonymous, followAnonymous, user), CitizenBasic(id, name, email, birthday, voteAnonymous, followAnonymous, user),
EntityCreatedAt by EntityCreatedAtImp() { EntityCreatedAt by EntityCreatedAtImp() {
var workgroups: List<WorkgroupSimple<CitizenRef>> = emptyList() var workgroups: List<WorkgroupAndRoles> = emptyList()
class WorkgroupAndRoles(
val roles: List<String>,
val workgroup: WorkgroupSimple<CitizenRef>
)
} }
open class CitizenBasic( open class CitizenBasic(

View File

@@ -1,5 +1,8 @@
package fr.dcproject.entity package fr.dcproject.entity
import fr.dcproject.entity.WorkgroupWithMembersI.Member
import fr.dcproject.entity.WorkgroupWithMembersI.Member.Role
import fr.postgresjson.entity.EntityI
import fr.postgresjson.entity.immutable.* import fr.postgresjson.entity.immutable.*
import fr.postgresjson.entity.mutable.EntityDeletedAt import fr.postgresjson.entity.mutable.EntityDeletedAt
import fr.postgresjson.entity.mutable.EntityDeletedAtImp import fr.postgresjson.entity.mutable.EntityDeletedAtImp
@@ -11,9 +14,8 @@ class Workgroup(
description: String, description: String,
logo: String? = null, logo: String? = null,
anonymous: Boolean = true, anonymous: Boolean = true,
owner: CitizenBasic,
createdBy: CitizenBasic, createdBy: CitizenBasic,
override var members: List<CitizenBasic> = emptyList() override var members: List<Member<CitizenBasic>> = emptyList()
) : WorkgroupWithAuthI<CitizenBasic>, ) : WorkgroupWithAuthI<CitizenBasic>,
WorkgroupSimple<CitizenBasic>( WorkgroupSimple<CitizenBasic>(
id, id,
@@ -21,7 +23,6 @@ class Workgroup(
description, description,
logo, logo,
anonymous, anonymous,
owner,
createdBy createdBy
), ),
EntityCreatedAt by EntityCreatedAtImp(), EntityCreatedAt by EntityCreatedAtImp(),
@@ -33,7 +34,6 @@ open class WorkgroupSimple<Z : CitizenRef>(
var description: String, var description: String,
var logo: String? = null, var logo: String? = null,
var anonymous: Boolean = true, var anonymous: Boolean = true,
var owner: Z,
createdBy: Z createdBy: Z
) : WorkgroupRef(id), ) : WorkgroupRef(id),
EntityCreatedBy<Z> by EntityCreatedByImp(createdBy), EntityCreatedBy<Z> by EntityCreatedByImp(createdBy),
@@ -45,19 +45,51 @@ open class WorkgroupRef(
interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, EntityCreatedBy<Z>, EntityDeletedAt { interface WorkgroupWithAuthI<Z : CitizenWithUserI> : WorkgroupWithMembersI<Z>, EntityCreatedBy<Z>, EntityDeletedAt {
val anonymous: Boolean val anonymous: Boolean
val owner: Z
fun isMember(user: UserI): Boolean = fun isMember(user: UserI): Boolean = members.isMember(user)
members.map { it.user.id }.contains(user.id) || owner.user.id == user.id fun isMember(citizen: CitizenWithUserI): Boolean = members.isMember(citizen)
fun isMember(citizen: CitizenWithUserI): Boolean = fun hasRole(expectedRole: Role, user: UserI): Boolean = members.hasRole(expectedRole, user)
isMember(citizen.user) fun hasRole(expectedRole: Role, citizen: CitizenI): Boolean = members.hasRole(expectedRole, citizen)
fun getRoles(user: UserI): List<Role> = members.getRoles(user)
fun getRoles(citizen: CitizenI): List<Role> = members.getRoles(citizen)
} }
interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI { interface WorkgroupWithMembersI<Z : CitizenI> : WorkgroupI {
var members: List<Z> var members: List<Member<Z>>
class Member<C : CitizenI> (
val citizen: C,
val roles: List<Role> = emptyList()
) : EntityI {
enum class Role {
MASTER,
MANAGER,
EDITOR,
REPORTER
}
}
} }
fun List<CitizenI>.asCitizen(citizen: CitizenI): Boolean = this.map { it.id }.contains(citizen.id) fun List<CitizenI>.hasCitizen(citizen: CitizenI): Boolean = this.map { it.id }.contains(citizen.id)
fun <Z : CitizenWithUserI> List<Member<Z>>.isMember(user: UserI): Boolean =
map { it.citizen.user.id }.contains(user.id)
fun <Z : CitizenI> List<Member<Z>>.isMember(citizen: CitizenI): Boolean =
map { it.citizen.id }.contains(citizen.id)
fun <Z : CitizenI> List<Member<Z>>.hasRole(expectedRole: Role, citizen: CitizenI): Boolean =
any { member -> member.citizen.id == citizen.id && member.roles.any { it == expectedRole } }
fun <Z : CitizenWithUserI> List<Member<Z>>.hasRole(expectedRole: Role, user: UserI): Boolean =
any { member -> member.citizen.user.id == user.id && member.roles.any { it == expectedRole } }
fun <Z : CitizenWithUserI> List<Member<Z>>.getRoles(user: UserI): List<Role> =
firstOrNull { it.citizen.user.id == user.id }?.roles ?: emptyList()
fun <Z : CitizenWithUserI> List<Member<Z>>.getRoles(citizen: CitizenI): List<Role> =
firstOrNull { it.citizen.id == citizen.id }?.roles ?: emptyList()
interface WorkgroupI : UuidEntityI interface WorkgroupI : UuidEntityI

View File

@@ -12,29 +12,21 @@ import java.util.*
import fr.dcproject.entity.Citizen as CitizenEntity import fr.dcproject.entity.Citizen as CitizenEntity
class Citizen(override var requester: Requester) : RepositoryI { class Citizen(override var requester: Requester) : RepositoryI {
fun findById(id: UUID, withUser: Boolean = false): CitizenEntity? { fun findById(id: UUID): CitizenEntity? = requester
return requester .getFunction("find_citizen_by_id_with_user_and_workgroups")
.getFunction(if (withUser) "find_citizen_by_id_with_user" else "find_citizen_by_id")
.selectOne("id" to id) .selectOne("id" to id)
}
fun findByUser(user: UserI): CitizenEntity? { fun findByUser(user: UserI): CitizenEntity? = requester
return requester
.getFunction("find_citizen_by_user_id") .getFunction("find_citizen_by_user_id")
.selectOne("user_id" to user.id) .selectOne("user_id" to user.id)
}
fun findByUsername(unsername: String): CitizenEntity? { fun findByUsername(unsername: String): CitizenEntity? = requester
return requester
.getFunction("find_citizen_by_username") .getFunction("find_citizen_by_username")
.selectOne("username" to unsername) .selectOne("username" to unsername)
}
fun findByEmail(email: String): CitizenEntity? { fun findByEmail(email: String): CitizenEntity? = requester
return requester
.getFunction("find_citizen_by_email") .getFunction("find_citizen_by_email")
.selectOne("email" to email) .selectOne("email" to email)
}
fun find( fun find(
page: Int = 1, page: Int = 1,
@@ -42,8 +34,7 @@ class Citizen(override var requester: Requester) : RepositoryI {
sort: String? = null, sort: String? = null,
direction: Direction? = null, direction: Direction? = null,
search: String? = null search: String? = null
): Paginated<CitizenBasic> { ): Paginated<CitizenBasic> = requester
return requester
.getFunction("find_citizens") .getFunction("find_citizens")
.select( .select(
page, limit, page, limit,
@@ -51,17 +42,12 @@ class Citizen(override var requester: Requester) : RepositoryI {
"direction" to direction, "direction" to direction,
"search" to search "search" to search
) )
}
fun upsert(citizen: CitizenFull): CitizenEntity? { fun upsert(citizen: CitizenFull): CitizenEntity? = requester
return requester
.getFunction("upsert_citizen") .getFunction("upsert_citizen")
.selectOne("resource" to citizen) .selectOne("resource" to citizen)
}
fun insertWithUser(citizen: CitizenFull): CitizenEntity? { fun insertWithUser(citizen: CitizenFull): CitizenEntity? = requester
return requester
.getFunction("insert_citizen_with_user") .getFunction("insert_citizen_with_user")
.selectOne("resource" to citizen) .selectOne("resource" to citizen)
} }
}

View File

@@ -1,6 +1,7 @@
package fr.dcproject.repository package fr.dcproject.repository
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.entity.WorkgroupWithMembersI.Member
import fr.postgresjson.connexion.Paginated import fr.postgresjson.connexion.Paginated
import fr.postgresjson.connexion.Requester import fr.postgresjson.connexion.Requester
import fr.postgresjson.entity.Parameter import fr.postgresjson.entity.Parameter
@@ -44,36 +45,43 @@ class Workgroup(override var requester: Requester) : RepositoryI {
.getFunction("delete_workgroup") .getFunction("delete_workgroup")
.perform("id" to workgroup.id) .perform("id" to workgroup.id)
fun addMember(workgroup: WorkgroupI, member: CitizenI): List<CitizenBasic> = fun addMember(workgroup: WorkgroupI, member: Member<CitizenI>): Member<CitizenBasic>? =
addMembers(workgroup, listOf(member)) addMember(workgroup, member.citizen, member.roles)
fun addMembers(workgroup: WorkgroupI, members: List<CitizenI>): List<CitizenBasic> = requester fun addMember(workgroup: WorkgroupI, citizen: CitizenI, roles: List<Member.Role>): Member<CitizenBasic>? = requester
.getFunction("add_workgroup_member")
.selectOne(
"id" to workgroup.id,
"members" to Member(citizen, roles).serialize()
)
fun <Z : CitizenI> addMembers(workgroup: WorkgroupI, members: List<Member<Z>>): List<Member<CitizenBasic>> = requester
.getFunction("add_workgroup_members") .getFunction("add_workgroup_members")
.select( .select(
"id" to workgroup.id, "id" to workgroup.id,
"resource" to members.serialize() "members" to members.serialize()
) )
fun removeMember(workgroup: WorkgroupI, memberToDelete: CitizenI): List<CitizenBasic> = fun <Z : CitizenI> removeMember(workgroup: WorkgroupI, memberToDelete: Member<Z>): List<Member<CitizenBasic>> =
removeMembers(workgroup, listOf(memberToDelete)) removeMembers(workgroup, listOf(memberToDelete))
fun removeMembers(workgroup: WorkgroupI, membersToDelete: List<CitizenI>): List<CitizenBasic> = requester fun <Z : CitizenI> removeMembers(workgroup: WorkgroupI, membersToDelete: List<Member<Z>>): List<Member<CitizenBasic>> = requester
.getFunction("remove_workgroup_members") .getFunction("remove_workgroup_members")
.select( .select(
"id" to workgroup.id, "id" to workgroup.id,
"resource" to membersToDelete "members" to membersToDelete
) )
fun updateMembers(workgroup: WorkgroupI, members: List<CitizenI>): List<CitizenBasic> = requester fun <Z : CitizenI> updateMembers(workgroup: WorkgroupI, members: List<Member<Z>>): List<Member<CitizenBasic>> = requester
.getFunction("update_workgroup_members") .getFunction("update_workgroup_members")
.select( .select(
"id" to workgroup.id, "id" to workgroup.id,
"resource" to members "members" to members
) )
fun <W : WorkgroupWithMembersI<CitizenI>> updateMembers(workgroup: W): W { fun <W : WorkgroupWithMembersI<Z>, Z : CitizenI> updateMembers(workgroup: W): W {
updateMembers(workgroup, workgroup.members).let { updateMembers(workgroup, workgroup.members).let {
workgroup.members = it workgroup.members = it as List<Member<Z>>
} }
return workgroup return workgroup

View File

@@ -3,6 +3,8 @@ package fr.dcproject.routes
import fr.dcproject.citizen import fr.dcproject.citizen
import fr.dcproject.entity.CitizenRef import fr.dcproject.entity.CitizenRef
import fr.dcproject.entity.WorkgroupSimple import fr.dcproject.entity.WorkgroupSimple
import fr.dcproject.entity.WorkgroupWithMembersI.Member
import fr.dcproject.entity.WorkgroupWithMembersI.Member.Role
import fr.dcproject.repository.Workgroup.Filter import fr.dcproject.repository.Workgroup.Filter
import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW import fr.dcproject.security.voter.WorkgroupVoter.Action.VIEW
import fr.dcproject.security.voter.WorkgroupVoter.Action.CREATE import fr.dcproject.security.voter.WorkgroupVoter.Action.CREATE
@@ -54,8 +56,7 @@ object WorkgroupsPaths {
val name: String, val name: String,
val description: String, val description: String,
val logo: String?, val logo: String?,
val anonymous: Boolean?, val anonymous: Boolean?
val owner: UUID?
) )
suspend fun getNewWorkgroup(call: ApplicationCall): WorkgroupSimple<CitizenRef> = call.receive<Body>().run { suspend fun getNewWorkgroup(call: ApplicationCall): WorkgroupSimple<CitizenRef> = call.receive<Body>().run {
@@ -65,7 +66,6 @@ object WorkgroupsPaths {
description, description,
logo, logo,
anonymous ?: true, anonymous ?: true,
owner?.let { CitizenRef(it) } ?: call.citizen,
call.citizen call.citizen
) )
} }
@@ -77,8 +77,7 @@ object WorkgroupsPaths {
val name: String?, val name: String?,
val description: String?, val description: String?,
val logo: String?, val logo: String?,
val anonymous: Boolean?, val anonymous: Boolean?
val owner: UUID?
) )
suspend fun updateWorkgroup(call: ApplicationCall): Unit = call.receive<Body>().run { suspend fun updateWorkgroup(call: ApplicationCall): Unit = call.receive<Body>().run {
@@ -98,13 +97,19 @@ object WorkgroupsMembersPaths {
@Location("/workgroups/{workgroup}/members") @Location("/workgroups/{workgroup}/members")
class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) { class WorkgroupsMembersRequest(val workgroup: WorkgroupEntity) {
class Body : MutableList<Body.Item> by mutableListOf() { class Body : MutableList<Body.Item> by mutableListOf() {
class Item(id: String) { class Item(id: String, roles: List<String>) {
val id = id.toUUID() val citizen = CitizenRef(id.toUUID())
val roles: List<Role> = roles.map {
Role.valueOf(it)
}
} }
} }
suspend fun getMembers(call: ApplicationCall): List<CitizenRef> = call.receive<Body>().map { suspend fun getMembers(call: ApplicationCall): List<Member<CitizenRef>> = call.receive<Body>().map {
CitizenRef(it.id) Member(
citizen = it.citizen,
roles = it.roles
)
} }
} }
} }

View File

@@ -1,7 +1,7 @@
package fr.dcproject.security.voter package fr.dcproject.security.voter
import fr.dcproject.citizenOrNull
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.entity.WorkgroupWithMembersI.Member.Role
import fr.dcproject.user import fr.dcproject.user
import fr.ktorVoter.ActionI import fr.ktorVoter.ActionI
import fr.ktorVoter.Vote import fr.ktorVoter.Vote
@@ -46,11 +46,11 @@ class WorkgroupVoter : Voter {
} }
if (subject is WorkgroupWithAuthI<*>) { if (subject is WorkgroupWithAuthI<*>) {
if (action == Action.DELETE && user is UserI && subject.owner.user.id == user.id) { if (action == Action.DELETE && user is UserI && subject.hasRole(Role.MASTER, user)) {
return Vote.GRANTED return Vote.GRANTED
} }
if (action == Action.UPDATE && user is UserI && subject.owner.user.id == user.id) { if (action == Action.UPDATE && user is UserI && subject.hasRole(Role.MASTER, user)) {
return Vote.GRANTED return Vote.GRANTED
} }
@@ -61,32 +61,29 @@ class WorkgroupVoter : Voter {
} }
if (action == ActionMembers.ADD) { if (action == ActionMembers.ADD) {
val citizen = call.citizenOrNull
// TODO create ROLES // TODO create ROLES
return Vote.isGranted { return Vote.isGranted {
citizen != null && user is UserI &&
subject is WorkgroupWithMembersI<*> && subject is WorkgroupWithAuthI<*> &&
subject.members.asCitizen(citizen) subject.hasRole(Role.MASTER, user)
} }
} }
if (action == ActionMembers.UPDATE) { if (action == ActionMembers.UPDATE) {
val citizen = call.citizenOrNull
// TODO create ROLES // TODO create ROLES
return Vote.isGranted { return Vote.isGranted {
citizen != null && user is UserI &&
subject is WorkgroupWithMembersI<*> && subject is WorkgroupWithAuthI<*> &&
subject.members.asCitizen(citizen) subject.hasRole(Role.MASTER, user)
} }
} }
if (action == ActionMembers.REMOVE) { if (action == ActionMembers.REMOVE) {
val citizen = call.citizenOrNull
// TODO create ROLES // TODO create ROLES
return Vote.isGranted { return Vote.isGranted {
citizen != null && user is UserI &&
subject is WorkgroupWithMembersI<*> && subject is WorkgroupWithAuthI<*> &&
subject.members.asCitizen(citizen) subject.hasRole(Role.MASTER, user)
} }
} }

View File

@@ -1708,8 +1708,6 @@ components:
anonymous: anonymous:
type: boolean type: boolean
example: false example: false
owner:
$ref: '#/components/schemas/CitizenResponse'
- $ref: '#/components/schemas/CreatedBy' - $ref: '#/components/schemas/CreatedBy'
- $ref: '#/components/schemas/DeletedAt' - $ref: '#/components/schemas/DeletedAt'
Workgroup: Workgroup:
@@ -1719,11 +1717,30 @@ components:
- type: object - type: object
properties: properties:
members: members:
type: array $ref: '#/components/schemas/Members'
items:
$ref: '#/components/schemas/CitizenResponse'
- $ref: '#/components/schemas/CreatedAt' - $ref: '#/components/schemas/CreatedAt'
- $ref: '#/components/schemas/UpdatedAt' - $ref: '#/components/schemas/UpdatedAt'
Members:
description: members of workgroup
type: array
items:
$ref: '#/components/schemas/Member'
Member:
description: Member of workgroup
type: object
properties:
citizen:
$ref: '#/components/schemas/CitizenResponse'
roles:
type: array
items:
type: string
enum:
- MASTER
- MANAGER
- EDITOR
- REPORTER
example: MASTER

View File

@@ -2,27 +2,40 @@ do
$$ $$
declare declare
citizen_count int = (select count(*) from citizen); citizen_count int = (select count(*) from citizen);
_roles text[] = $roles$
{
"MANAGER", "EDITOR", "REPORTER"
}
$roles$;
begin begin
delete from citizen_in_workgroup; delete from citizen_in_workgroup;
delete from workgroup; delete from workgroup;
insert into workgroup (id, created_by_id, name, description, anonymous, owner_id) insert into workgroup (id, created_by_id, name, description, anonymous)
select select
uuid_in(md5('workgroup'||rn::text)::cstring), uuid_in(md5('workgroup'||rn::text)::cstring),
z.id, z.id,
'name' || rn, 'name' || rn,
'description' || rn, 'description' || rn,
rn % 3 = 1, rn % 3 = 1
z.id
from (select *, row_number() over () rn from citizen) z; from (select *, row_number() over () rn from citizen) z;
insert into citizen_in_workgroup (citizen_id, workgroup_id) insert into citizen_in_workgroup (citizen_id, workgroup_id, roles)
select select
z.id, z.id,
w.id w.id,
'{MASTER}'
from (select *, row_number() over ()+5 % citizen_count rn from citizen) z from (select *, row_number() over ()+5 % citizen_count rn from citizen) z
join (select *, row_number() over () rn from workgroup) w using (rn); join (select *, row_number() over () rn from workgroup) w using (rn);
insert into citizen_in_workgroup (citizen_id, workgroup_id, roles)
select
z.id,
w.id,
_roles[(row_number() over () % 3)+1:(row_number() over () % 3)+1]
from (select *, row_number() over ()+10 % citizen_count rn from citizen) z
join (select *, row_number() over () rn from workgroup) w using (rn);
raise notice 'workgroup fixtures done'; raise notice 'workgroup fixtures done';
end; end;
$$; $$;

View File

@@ -7,7 +7,7 @@ begin
from ( from (
select select
a.*, a.*,
find_citizen_by_id(a.created_by_id) as created_by, find_citizen_by_id_with_user(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup, find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes, count_vote(a.id) as votes,
count_opinion(a.id) as opinions count_opinion(a.id) as opinions

View File

@@ -21,7 +21,7 @@ begin
from ( from (
select select
a.*, a.*,
find_citizen_by_id(a.created_by_id) as created_by, find_citizen_by_id_with_user(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup, find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes, count_vote(a.id) as votes,
count_opinion(a.id) as opinions, count_opinion(a.id) as opinions,

View File

@@ -14,7 +14,7 @@ begin
from ( from (
select select
a.*, a.*,
find_citizen_by_id(a.created_by_id) as created_by, find_citizen_by_id_with_user(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup, find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes count_vote(a.id) as votes
from article as a from article as a

View File

@@ -7,7 +7,7 @@ begin
from ( from (
select select
a.*, a.*,
find_citizen_by_id(a.created_by_id) as created_by, find_citizen_by_id_with_user(a.created_by_id) as created_by,
find_workgroup_by_id(a.workgroup_id) as workgroup, find_workgroup_by_id(a.workgroup_id) as workgroup,
count_vote(a.id) as votes count_vote(a.id) as votes
into resource into resource

View File

@@ -6,9 +6,7 @@ begin
select to_json(t) into resource select to_json(t) into resource
from ( from (
select select
z.*, z.*
find_user_by_id(z.user_id) as "user",
array_agg(find_workgroup_by_id_simple(ciw.workgroup_id)) as "workgroups"
from citizen as z from citizen as z
left join citizen_in_workgroup ciw on z.id = ciw.citizen_id left join citizen_in_workgroup ciw on z.id = ciw.citizen_id
where z.id = _id where z.id = _id

View File

@@ -7,8 +7,7 @@ begin
from ( from (
select select
z.*, z.*,
find_user_by_id(z.user_id) as "user", find_user_by_id(z.user_id) as "user"
array_agg(find_workgroup_by_id_simple(ciw.workgroup_id)) as "workgroups"
from citizen as z from citizen as z
left join citizen_in_workgroup ciw on z.id = ciw.citizen_id left join citizen_in_workgroup ciw on z.id = ciw.citizen_id
where z.id = _id where z.id = _id

View File

@@ -0,0 +1,22 @@
create or replace function find_citizen_by_id_with_user_and_workgroups(in id uuid, out resource json) language plpgsql as
$$
declare
_id alias for id;
begin
select to_json(t) into resource
from (
select
z.*,
find_user_by_id(z.user_id) as "user",
case when ciw.workgroup_id is null then '{}' else array_agg(json_build_object(
'roles', ciw.roles,
'workgroup', find_workgroup_by_id_simple(ciw.workgroup_id)
)) end as "workgroups"
from citizen as z
left join citizen_in_workgroup ciw on z.id = ciw.citizen_id
where z.id = _id
group by z.id, ciw.workgroup_id
) as t;
end;
$$;

View File

@@ -23,7 +23,7 @@ begin
email = excluded.email email = excluded.email
returning id into new_id; returning id into new_id;
select find_citizen_by_id(new_id) into resource; select find_citizen_by_id_with_user(new_id) into resource;
end; end;
$$; $$;

View File

@@ -10,7 +10,7 @@ begin
select select
com.*, com.*,
find_reference_by_id(com.target_id, com.target_reference) as target, find_reference_by_id(com.target_id, com.target_reference) as target,
find_citizen_by_id(com.created_by_id) as created_by, find_citizen_by_id_with_user(com.created_by_id) as created_by,
count_vote(com.id) as votes count_vote(com.id) as votes
from "comment" as com from "comment" as com
where id = _id where id = _id

View File

@@ -21,7 +21,7 @@ begin
select select
com.*, com.*,
find_reference_by_id(com.target_id, _reference) as target, find_reference_by_id(com.target_id, _reference) as target,
find_citizen_by_id(com.created_by_id) as created_by, find_citizen_by_id_with_user(com.created_by_id) as created_by,
count_vote(com.id) as votes count_vote(com.id) as votes
from "comment" as com from "comment" as com

View File

@@ -14,7 +14,7 @@ begin
com.*, com.*,
(select count(*) from "comment" c2 where c2.parents_ids @> array[com.id]) as children_count, (select count(*) from "comment" c2 where c2.parents_ids @> array[com.id]) as children_count,
find_reference_by_id(com.target_id, com.target_reference) as target, find_reference_by_id(com.target_id, com.target_reference) as target,
find_citizen_by_id(com.created_by_id) as created_by, find_citizen_by_id_with_user(com.created_by_id) as created_by,
count_vote(com.id) as votes count_vote(com.id) as votes
from "comment" as com from "comment" as com
where parent_id = _parent_id where parent_id = _parent_id

View File

@@ -15,7 +15,7 @@ begin
com.*, com.*,
(select count(c2) from "comment" c2 where c2.parent_comment_id = com.id) as children_count, (select count(c2) from "comment" c2 where c2.parent_comment_id = com.id) as children_count,
find_reference_by_id(com.target_id, com.target_reference) as target, find_reference_by_id(com.target_id, com.target_reference) as target,
find_citizen_by_id(com.created_by_id) as created_by, find_citizen_by_id_with_user(com.created_by_id) as created_by,
count_vote(com.id) as votes count_vote(com.id) as votes
from "comment" as com from "comment" as com
where com.parent_id = _target_id where com.parent_id = _target_id

View File

@@ -7,7 +7,7 @@ begin
from ( from (
select select
c.*, c.*,
find_citizen_by_id(c.created_by_id) as created_by, find_citizen_by_id_with_user(c.created_by_id) as created_by,
find_constitution_titles_by_id(c.id) as titles find_constitution_titles_by_id(c.id) as titles
into resource into resource
from constitution as c from constitution as c

View File

@@ -14,7 +14,7 @@ begin
from ( from (
select select
c.*, c.*,
find_citizen_by_id(c.created_by_id) as created_by, find_citizen_by_id_with_user(c.created_by_id) as created_by,
find_constitution_titles_by_id(c.id) as titles, find_constitution_titles_by_id(c.id) as titles,
zdb.score(c.ctid) _score zdb.score(c.ctid) _score
from constitution as c from constitution as c

View File

@@ -19,7 +19,7 @@ begin
select select
f.*, f.*,
json_build_object('id', f.target_id, 'reference', f.target_reference) as target, json_build_object('id', f.target_id, 'reference', f.target_reference) as target,
find_citizen_by_id(f.created_by_id) as created_by find_citizen_by_id_with_user(f.created_by_id) as created_by
from follow as f from follow as f
where f.created_by_id = _citizen_id where f.created_by_id = _citizen_id
and array[f.target_id] <@ _target_ids and array[f.target_id] <@ _target_ids
@@ -32,7 +32,7 @@ begin
select select
f.*, f.*,
json_build_object('id', f.target_id, 'reference', f.target_reference) as target, json_build_object('id', f.target_id, 'reference', f.target_reference) as target,
find_citizen_by_id(f.created_by_id) as created_by find_citizen_by_id_with_user(f.created_by_id) as created_by
from follow as f from follow as f
where f.created_by_id = _citizen_id where f.created_by_id = _citizen_id
and f.target_id = _target_id and f.target_id = _target_id

View File

@@ -13,7 +13,7 @@ begin
select select
f.*, f.*,
find_article_by_id(f.target_id) as target, find_article_by_id(f.target_id) as target,
find_citizen_by_id(f.created_by_id) as created_by find_citizen_by_id_with_user(f.created_by_id) as created_by
from follow as f from follow as f
where created_by_id = _created_by_id where created_by_id = _created_by_id
order by created_at desc, order by created_at desc,

View File

@@ -13,7 +13,7 @@ begin
select select
f.*, f.*,
json_build_object('id', f.target_id) as target, json_build_object('id', f.target_id) as target,
find_citizen_by_id(f.created_by_id) as created_by find_citizen_by_id_with_user(f.created_by_id) as created_by
from follow as f from follow as f
where created_by_id = _created_by_id where created_by_id = _created_by_id
order by created_at desc, order by created_at desc,

View File

@@ -13,7 +13,7 @@ begin
select select
f.*, f.*,
find_constitution_by_id(f.target_id) as target, find_constitution_by_id(f.target_id) as target,
find_citizen_by_id(f.created_by_id) as created_by find_citizen_by_id_with_user(f.created_by_id) as created_by
from follow as f from follow as f
where created_by_id = _created_by_id where created_by_id = _created_by_id
order by created_at desc, order by created_at desc,

View File

@@ -19,7 +19,7 @@ begin
select select
o.*, o.*,
find_reference_by_id(o.target_id, o.target_reference) as target, find_reference_by_id(o.target_id, o.target_reference) as target,
find_citizen_by_id(o.created_by_id) as created_by, find_citizen_by_id_with_user(o.created_by_id) as created_by,
to_json(ol) as choice to_json(ol) as choice
from opinion as o from opinion as o
join opinion_choice ol on o.choice_id = ol.id join opinion_choice ol on o.choice_id = ol.id

View File

@@ -12,7 +12,7 @@ begin
select select
o.*, o.*,
find_reference_by_id(o.target_id, o.target_reference) as target, find_reference_by_id(o.target_id, o.target_reference) as target,
find_citizen_by_id(o.created_by_id) as created_by, find_citizen_by_id_with_user(o.created_by_id) as created_by,
to_json(ol) as choice to_json(ol) as choice
from opinion as o from opinion as o
join opinion_choice ol on o.choice_id = ol.id join opinion_choice ol on o.choice_id = ol.id

View File

@@ -10,7 +10,7 @@ begin
select select
o.*, o.*,
find_reference_by_id(o.target_id, o.target_reference) as target, find_reference_by_id(o.target_id, o.target_reference) as target,
find_citizen_by_id(o.created_by_id) as created_by, find_citizen_by_id_with_user(o.created_by_id) as created_by,
to_json(ol) as choice to_json(ol) as choice
from opinion as o from opinion as o
join opinion_choice ol on o.choice_id = ol.id join opinion_choice ol on o.choice_id = ol.id

View File

@@ -10,7 +10,7 @@ begin
select select
o.*, o.*,
find_reference_by_id(o.target_id, o.target_reference) as target, find_reference_by_id(o.target_id, o.target_reference) as target,
find_citizen_by_id(o.created_by_id) as created_by, find_citizen_by_id_with_user(o.created_by_id) as created_by,
to_json(ol) as choice to_json(ol) as choice
from "opinion" as o from "opinion" as o
join opinion_choice ol on o.choice_id = ol.id join opinion_choice ol on o.choice_id = ol.id

View File

@@ -13,7 +13,7 @@ begin
select select
o.*, o.*,
find_reference_by_id(o.target_id, o.target_reference) as target, find_reference_by_id(o.target_id, o.target_reference) as target,
find_citizen_by_id(o.created_by_id) as created_by, find_citizen_by_id_with_user(o.created_by_id) as created_by,
to_json(ol) as choice to_json(ol) as choice
from "opinion" as o from "opinion" as o
join opinion_choice ol on o.choice_id = ol.id join opinion_choice ol on o.choice_id = ol.id

View File

@@ -13,7 +13,7 @@ begin
select select
v.*, v.*,
find_reference_by_id(v.target_id, v.target_reference) as target, find_reference_by_id(v.target_id, v.target_reference) as target,
find_citizen_by_id(v.created_by_id) as created_by find_citizen_by_id_with_user(v.created_by_id) as created_by
from vote as v from vote as v

View File

@@ -21,7 +21,7 @@ begin
select select
v.*, v.*,
find_reference_by_id(v.target_id, _reference) as target, find_reference_by_id(v.target_id, _reference) as target,
find_citizen_by_id(v.created_by_id) as created_by find_citizen_by_id_with_user(v.created_by_id) as created_by
from vote as v from vote as v

View File

@@ -0,0 +1,13 @@
create or replace function add_workgroup_member(in _id uuid, inout member json)
language plpgsql as
$$
begin
insert into citizen_in_workgroup (workgroup_id, citizen_id, roles)
values (
_id,
(member#>>'{citizen, id}')::uuid,
(select array_agg(t) from json_array_elements_text(member#>'{roles}') t)
)
on conflict do nothing;
end;
$$;

View File

@@ -1,16 +1,11 @@
create or replace function add_workgroup_members(in _id uuid, inout resource json) create or replace function add_workgroup_members(in _id uuid, inout members json)
language plpgsql as language plpgsql as
$$ $$
begin begin
insert into citizen_in_workgroup (citizen_id, workgroup_id) perform add_workgroup_member(_id, b)
select from json_array_elements(members) b;
(z->>'id')::uuid,
_id::uuid
from json_array_elements(resource) z
where (z->>'id') is not null
on conflict do nothing;
select find_workgroup_members(_id) into resource; select find_workgroup_members(_id) into members;
end; end;
$$; $$;

View File

@@ -7,8 +7,7 @@ begin
from ( from (
select select
w.*, w.*,
find_citizen_by_id(w.created_by_id) as created_by, find_citizen_by_id_with_user(w.created_by_id) as created_by,
find_citizen_by_id(w.owner_id) as owner,
find_workgroup_members(w.id) as members find_workgroup_members(w.id) as members
into resource into resource
from workgroup as w from workgroup as w

View File

@@ -7,8 +7,7 @@ begin
from ( from (
select select
w.*, w.*,
json_build_object('id', w.created_by_id) as created_by, json_build_object('id', w.created_by_id) as created_by
json_build_object('id', w.owner_id) as owner
into resource into resource
from workgroup as w from workgroup as w
join citizen_in_workgroup ciw on w.id = ciw.workgroup_id join citizen_in_workgroup ciw on w.id = ciw.workgroup_id

View File

@@ -4,8 +4,9 @@ begin
select json_agg(t) into resource select json_agg(t) into resource
from ( from (
select select
z.*, w.id as id,
find_user_by_id(z.user_id) as "user" find_citizen_by_id_with_user(z.id) as citizen,
ciw.roles as roles
from citizen_in_workgroup as ciw from citizen_in_workgroup as ciw
join workgroup as w on ciw.workgroup_id = w.id join workgroup as w on ciw.workgroup_id = w.id
join citizen z on z.id = ciw.citizen_id join citizen z on z.id = ciw.citizen_id

View File

@@ -21,8 +21,7 @@ begin
from ( from (
select select
w.*, w.*,
find_citizen_by_id(w.created_by_id) as created_by, find_citizen_by_id_with_user(w.created_by_id) as created_by,
find_citizen_by_id(w.owner_id) as owner,
zdb.score(w.ctid) _score zdb.score(w.ctid) _score
from workgroup as w from workgroup as w
where deleted_at is null where deleted_at is null

View File

@@ -1,4 +1,4 @@
create or replace function remove_workgroup_members(in _id uuid, inout resource json) create or replace function remove_workgroup_members(in _id uuid, inout members json)
language plpgsql as language plpgsql as
$$ $$
begin begin
@@ -6,11 +6,11 @@ begin
where workgroup_id = _id where workgroup_id = _id
and citizen_id in ( and citizen_id in (
select select
(z->>'id')::uuid (b#>>'{citizen, id}')::uuid
from json_array_elements(resource) z from json_array_elements(members) b
); );
select find_workgroup_members(_id) into resource; select find_workgroup_members(_id) into members;
end end
$$; $$;

View File

@@ -1,25 +1,20 @@
create or replace function update_workgroup_members(in _id uuid, inout resource json) create or replace function update_workgroup_members(in _id uuid, inout members json)
language plpgsql as language plpgsql as
$$ $$
begin begin
insert into citizen_in_workgroup (citizen_id, workgroup_id) perform add_workgroup_member(_id, b)
select from json_array_elements(members) b;
(z->>'id')::uuid,
_id::uuid
from json_array_elements(resource) z
where (z->>'id') is not null
on conflict do nothing;
delete from citizen_in_workgroup delete from citizen_in_workgroup
where workgroup_id = _id where workgroup_id = _id
and citizen_id not in( and citizen_id not in(
select select
(z->>'id')::uuid (b#>>'{citizen, id}')::uuid
from json_array_elements(resource) z from json_array_elements(members) b
where (z->>'id') is not null where (b#>>'{citizen, id}')::uuid is not null
); );
select find_workgroup_members(_id) into resource; select find_workgroup_members(_id) into members;
end; end;
$$; $$;

View File

@@ -4,28 +4,27 @@ $$
declare declare
new_id uuid = coalesce((resource->>'id')::uuid, uuid_generate_v4()); new_id uuid = coalesce((resource->>'id')::uuid, uuid_generate_v4());
begin begin
insert into workgroup (id, created_by_id, name, description, anonymous, logo, owner_id) insert into workgroup (id, created_by_id, name, description, anonymous, logo)
select select
new_id, new_id,
(resource#>>'{created_by, id}')::uuid, (resource#>>'{created_by, id}')::uuid,
name, name,
description, description,
anonymous, anonymous,
logo, logo
(resource#>>'{owner, id}')::uuid
from json_populate_record(null::workgroup, resource) from json_populate_record(null::workgroup, resource)
on conflict (id) do update set on conflict (id) do update set
name = excluded.name, name = excluded.name,
description = excluded.description, description = excluded.description,
anonymous = excluded.anonymous, anonymous = excluded.anonymous,
logo = excluded.logo, logo = excluded.logo;
owner_id = excluded.owner_id;
-- insert into citizen_in_workgroup (citizen_id, workgroup_id) insert into citizen_in_workgroup (workgroup_id, citizen_id, roles)
-- select select
-- (resource->>'id')::uuid, new_id::uuid,
-- new_id::uuid (resource#>>'{created_by, id}')::uuid,
-- from json_populate_recordset(null::workgroup, resource->'members'); '{MASTER}'
from json_populate_recordset(null::workgroup, resource->'members');
select find_workgroup_by_id(new_id) into resource; select find_workgroup_by_id(new_id) into resource;
end; end;

View File

@@ -32,14 +32,14 @@ create table workgroup
name varchar(128) not null, name varchar(128) not null,
description text null, description text null,
anonymous boolean default false not null, anonymous boolean default false not null,
logo text null, logo text null
owner_id uuid not null references citizen (id)
); );
create table citizen_in_workgroup create table citizen_in_workgroup
( (
citizen_id uuid not null references citizen (id), citizen_id uuid not null references citizen (id),
workgroup_id uuid not null references workgroup (id), workgroup_id uuid not null references workgroup (id),
roles text[] not null,
created_at timestamptz default now() not null, created_at timestamptz default now() not null,
primary key (citizen_id, workgroup_id) primary key (citizen_id, workgroup_id)
); );

View File

@@ -1,6 +1,7 @@
package feature package feature
import fr.dcproject.entity.* import fr.dcproject.entity.*
import fr.dcproject.entity.WorkgroupWithMembersI.Member
import fr.dcproject.utils.toUUID import fr.dcproject.utils.toUUID
import io.cucumber.datatable.DataTable import io.cucumber.datatable.DataTable
import io.cucumber.java8.En import io.cucumber.java8.En
@@ -16,7 +17,10 @@ class WorkgroupSteps : En, KoinTest {
init { init {
When("I have members in workgroup {string}:") { workgroupId: String, members: DataTable -> When("I have members in workgroup {string}:") { workgroupId: String, members: DataTable ->
val membersRefs = members.asList() val membersRefs = members.asList()
.map { CitizenRef(it.toUUID()) } .map { Member(
citizen = CitizenRef(it.toUUID()),
roles = listOf(Member.Role.MASTER)
) }
get<WorkgroupRepository>().addMembers(WorkgroupRef(workgroupId.toUUID()), membersRefs) get<WorkgroupRepository>().addMembers(WorkgroupRef(workgroupId.toUUID()), membersRefs)
} }
@@ -42,16 +46,11 @@ class WorkgroupSteps : En, KoinTest {
} }
} }
val owner = data["owner"]?.let {
get<CitizenRepository>().findByUsername(it.toLowerCase().replace(' ', '-'))
} ?: creator
val workgroup = WorkgroupSimple<CitizenRef>( val workgroup = WorkgroupSimple<CitizenRef>(
id = UUID.fromString(data["id"] ?: UUID.randomUUID().toString()), id = UUID.fromString(data["id"] ?: UUID.randomUUID().toString()),
name = data["name"] ?: "Les Incoruptible", name = data["name"] ?: "Les Incoruptible",
description = data["description"] ?: "La vie est notre jeux", description = data["description"] ?: "La vie est notre jeux",
createdBy = creator, createdBy = creator,
owner = owner,
anonymous = (data["anonymous"] ?: false) == true anonymous = (data["anonymous"] ?: false) == true
) )

View File

@@ -55,15 +55,15 @@ internal class WorkgroupVoterTest {
createdBy = tesla, createdBy = tesla,
description = "Super desc", description = "Super desc",
name = "super name", name = "super name",
owner = tesla, anonymous = false,
anonymous = false members = listOf(WorkgroupWithMembersI.Member(tesla, listOf(WorkgroupWithMembersI.Member.Role.MASTER)))
) )
private val workgroupAnon = WorkgroupEntity( private val workgroupAnon = WorkgroupEntity(
createdBy = tesla, createdBy = tesla,
description = "Super desc", description = "Super desc",
name = "super name", name = "super name",
owner = tesla, members = listOf(WorkgroupWithMembersI.Member(tesla, listOf(WorkgroupWithMembersI.Member.Role.MASTER))),
anonymous = true anonymous = true
) )

View File

@@ -3,15 +3,21 @@ Feature: Workgroup
Scenario: Can get one workgroup Scenario: Can get one workgroup
Given I have citizen Stephen Hawking Given I have citizen Stephen Hawking
And I have citizen Sadi Carnot with ID "be3b0926-8628-4426-804a-75188a6eb315"
And I have citizen Joseph Fourier with ID "d9671eca-abaf-4b67-9230-3ece700c1ddb"
And I am authenticated as Stephen Hawking And I am authenticated as Stephen Hawking
And I have workgroup: And I have workgroup:
| id | ab469134-bf14-4856-b093-ae1aa990f977 | | id | ab469134-bf14-4856-b093-ae1aa990f977 |
| name | Les Mousquets | | name | Les Mousquets |
And I have members in workgroup "ab469134-bf14-4856-b093-ae1aa990f977":
| be3b0926-8628-4426-804a-75188a6eb315 |
| d9671eca-abaf-4b67-9230-3ece700c1ddb |
When I send a GET request to "/workgroups/ab469134-bf14-4856-b093-ae1aa990f977" When I send a GET request to "/workgroups/ab469134-bf14-4856-b093-ae1aa990f977"
Then the response status code should be 200 Then the response status code should be 200
And the JSON should contain: And the response should contain object:
| id | ab469134-bf14-4856-b093-ae1aa990f977 | | $.id | ab469134-bf14-4856-b093-ae1aa990f977 |
| name | Les Mousquets | | $.name | Les Mousquets |
| $.members[0].first_name | Sadi |
Scenario: Can create a workgroup Scenario: Can create a workgroup
Given I have citizen Werner Heisenberg Given I have citizen Werner Heisenberg
@@ -60,12 +66,17 @@ Feature: Workgroup
And I have workgroup: And I have workgroup:
| id | b0ea1922-3bc6-44e2-aa7c-40158998cfbb | | id | b0ea1922-3bc6-44e2-aa7c-40158998cfbb |
| name | Les bonobos | | name | Les bonobos |
| owner | Blaise Pascal |
When I send a POST request to "/workgroups/b0ea1922-3bc6-44e2-aa7c-40158998cfbb/members" with body: When I send a POST request to "/workgroups/b0ea1922-3bc6-44e2-aa7c-40158998cfbb/members" with body:
""" """
[ [
{"id":"6d883fe7-5fc0-4a50-8858-72230673eba4"}, {
{"id":"b5bac515-45d4-4aeb-9b6d-2627a0bbc419"} "id":"6d883fe7-5fc0-4a50-8858-72230673eba4",
"roles": ["MASTER"]
},
{
"id":"b5bac515-45d4-4aeb-9b6d-2627a0bbc419",
"roles": ["MASTER"]
}
] ]
""" """
Then the response status code should be 201 Then the response status code should be 201
@@ -78,19 +89,21 @@ Feature: Workgroup
And I have workgroup: And I have workgroup:
| id | b6c975df-dd44-4e99-adc1-f605746b0e11 | | id | b6c975df-dd44-4e99-adc1-f605746b0e11 |
| name | Les Tacos | | name | Les Tacos |
| owner | Heinrich Hertz |
And I have members in workgroup "b6c975df-dd44-4e99-adc1-f605746b0e11": And I have members in workgroup "b6c975df-dd44-4e99-adc1-f605746b0e11":
| 87909ba3-2069-431c-9924-219fd8411cf2 | | 87909ba3-2069-431c-9924-219fd8411cf2 |
| 1baf48bb-02bc-4d8f-ac86-33335354f5e7 | | 1baf48bb-02bc-4d8f-ac86-33335354f5e7 |
When I send a DELETE request to "/workgroups/b6c975df-dd44-4e99-adc1-f605746b0e11/members" with body: When I send a DELETE request to "/workgroups/b6c975df-dd44-4e99-adc1-f605746b0e11/members" with body:
""" """
[ [
{"id":"87909ba3-2069-431c-9924-219fd8411cf2"} {
"id":"87909ba3-2069-431c-9924-219fd8411cf2",
"roles": ["MASTER"]
}
] ]
""" """
Then the response status code should be 200 Then the response status code should be 200
And the response should contain object: And the response should contain object:
| $.[0]id | 1baf48bb-02bc-4d8f-ac86-33335354f5e7 | | $.[0]citizen.id | 1baf48bb-02bc-4d8f-ac86-33335354f5e7 |
And the JSON should have 1 items And the JSON should have 1 items
Scenario: Can update members on workgroup Scenario: Can update members on workgroup
@@ -102,19 +115,24 @@ Feature: Workgroup
And I have workgroup: And I have workgroup:
| id | 784fe6bc-7635-4ae2-b080-3a4743b998bf | | id | 784fe6bc-7635-4ae2-b080-3a4743b998bf |
| name | Les Tacos | | name | Les Tacos |
| owner | Leon Foucault |
And I have members in workgroup "784fe6bc-7635-4ae2-b080-3a4743b998bf": And I have members in workgroup "784fe6bc-7635-4ae2-b080-3a4743b998bf":
| be3b0926-8628-4426-804a-75188a6eb315 | | be3b0926-8628-4426-804a-75188a6eb315 |
| d9671eca-abaf-4b67-9230-3ece700c1ddb | | d9671eca-abaf-4b67-9230-3ece700c1ddb |
When I send a PUT request to "/workgroups/784fe6bc-7635-4ae2-b080-3a4743b998bf/members" with body: When I send a PUT request to "/workgroups/784fe6bc-7635-4ae2-b080-3a4743b998bf/members" with body:
""" """
[ [
{"id":"be3b0926-8628-4426-804a-75188a6eb315"}, {
{"id":"b49e20c1-8393-45d6-a6a0-3fa5c71cbdc1"} "id":"be3b0926-8628-4426-804a-75188a6eb315",
"roles": ["MASTER"]
},
{
"id":"b49e20c1-8393-45d6-a6a0-3fa5c71cbdc1",
"roles": ["MASTER"]
}
] ]
""" """
Then the response status code should be 200 Then the response status code should be 200
And the response should contain object: And the response should contain object:
| $.[0]id | be3b0926-8628-4426-804a-75188a6eb315 | | $.[0]citizen.id | be3b0926-8628-4426-804a-75188a6eb315 |
| $.[1]id | b49e20c1-8393-45d6-a6a0-3fa5c71cbdc1 | | $.[1]citizen.id | b49e20c1-8393-45d6-a6a0-3fa5c71cbdc1 |
And the JSON should have 2 items And the JSON should have 2 items

View File

@@ -19,7 +19,6 @@ begin
end if; end if;
created_workgroup := jsonb_set(created_workgroup::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json; created_workgroup := jsonb_set(created_workgroup::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
created_workgroup := jsonb_set(created_workgroup::jsonb, '{owner}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
assert created_workgroup#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup#>>'{created_by, id}', _citizen_id::text); assert created_workgroup#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup#>>'{created_by, id}', _citizen_id::text);
-- upsert workgroup -- upsert workgroup

View File

@@ -16,9 +16,9 @@ declare
}'; }';
selected_workgroup json; selected_workgroup json;
members json; members json;
selected_citizen json;
begin begin
created_workgroup := jsonb_set(created_workgroup::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json; created_workgroup := jsonb_set(created_workgroup::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
created_workgroup := jsonb_set(created_workgroup::jsonb, '{owner}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
assert created_workgroup#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup#>>'{created_by, id}', _citizen_id::text); assert created_workgroup#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup#>>'{created_by, id}', _citizen_id::text);
-- upsert workgroup -- upsert workgroup
@@ -28,7 +28,6 @@ begin
-- insert another workgroup -- insert another workgroup
created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json; created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{owner}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json;
assert created_workgroup_2#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup_2#>>'{created_by, id}', _citizen_id::text); assert created_workgroup_2#>>'{created_by, id}' = _citizen_id::text, format('citizenId in workgroup must be the same as citizen, %s != %s', created_workgroup_2#>>'{created_by, id}', _citizen_id::text);
select upsert_workgroup(created_workgroup_2) into created_workgroup_2; select upsert_workgroup(created_workgroup_2) into created_workgroup_2;
@@ -47,44 +46,61 @@ begin
-- add -- add
select m into members from add_workgroup_members((created_workgroup->>'id')::uuid, json_build_array( select m into members from add_workgroup_members((created_workgroup->>'id')::uuid, json_build_array(
json_build_object('id', _citizen_id2), json_build_object('citizen', json_build_object('id', _citizen_id2), 'roles', '{MASTER}'::text[]),
json_build_object('id', _citizen_id3) json_build_object('citizen', json_build_object('id', _citizen_id3), 'roles', '{MASTER}'::text[])
)) m; )) m;
assert json_array_length(members) = 2, 'The members count must be equal to 2'; assert json_array_length(members) = 2, 'The members count must be equal to 2';
assert members::jsonb @> jsonb_build_array(jsonb_build_object('id', _citizen_id3)), assert (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'id', (created_workgroup->>'id'),
'citizen', jsonb_build_object('id', _citizen_id3),
'roles', jsonb_build_array('MASTER')
)),
'Members must contain citizen3'; 'Members must contain citizen3';
-- Check if "find_citizen_by_id" retrun workgroups of citizen -- Check if "find_citizen_by_id" retrun citizen
assert (select find_citizen_by_id(_citizen_id2)#>>'{workgroups, 0, id}') = (created_workgroup->>'id'), 'find_citizen_by_id must return workgroups'; assert (select find_citizen_by_id(_citizen_id2)#>>'{id}')::uuid = _citizen_id2, 'find_citizen_by_id must return citizen';
-- Check if "find_citizen_by_id_with_user_and_workgroups" retrun workgroups of citizen
select find_citizen_by_id_with_user_and_workgroups(_citizen_id3) into selected_citizen;
assert selected_citizen#>>'{workgroups, 0, roles, 0}' = 'MASTER', format('workgroup must have MASTER role, %s', selected_citizen#>>'{workgroups, 0, roles, 0}');
-- update -- update
select m into members from update_workgroup_members((created_workgroup->>'id')::uuid, json_build_array( select m into members from update_workgroup_members((created_workgroup->>'id')::uuid, json_build_array(
json_build_object('id', _citizen_id2), json_build_object('citizen', json_build_object('id', _citizen_id2), 'roles', '{MASTER}'::text[]),
json_build_object('id', _citizen_id) json_build_object('citizen', json_build_object('id', _citizen_id), 'roles', '{MASTER}'::text[])
)) m; )) m;
assert json_array_length(members) = 2, 'The members count must be equal to 2'; assert json_array_length(members) = 2, 'The members count must be equal to 2';
assert members::jsonb @> jsonb_build_array(jsonb_build_object('id', _citizen_id)), assert (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'Members must contain citizen2'; 'id', (created_workgroup->>'id'),
assert not members::jsonb @> jsonb_build_array(jsonb_build_object('id', _citizen_id3)), 'citizen', jsonb_build_object('id', _citizen_id),
'Members must NOT contain citizen3'; 'roles', jsonb_build_array('MASTER')
)), 'Members must contain citizen1';
assert not (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'citizen', jsonb_build_object('id', _citizen_id3)
)), 'Members must NOT contain citizen3';
-- remove -- remove
select m into members from remove_workgroup_members((created_workgroup->>'id')::uuid, json_build_array( select m into members from remove_workgroup_members((created_workgroup->>'id')::uuid, json_build_array(jsonb_build_object(
json_build_object('id', _citizen_id2) 'citizen', json_build_object('id', _citizen_id2)
)) m; ))) m;
assert json_array_length(members) = 1, 'The members count must be equal to 1'; assert json_array_length(members) = 1, 'The members count must be equal to 1';
assert members::jsonb @> jsonb_build_array(jsonb_build_object('id', _citizen_id)), assert (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'Members must contain citizen1'; 'citizen', jsonb_build_object('id', _citizen_id)
assert not members::jsonb @> jsonb_build_array(jsonb_build_object('id', _citizen_id2)), )), 'Members must contain citizen1';
'Members must NOT contain citizen2'; assert not (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'citizen', jsonb_build_object('id', _citizen_id2)
)), 'Members must NOT contain citizen2';
select m into members from find_workgroup_members((created_workgroup->>'id')::uuid) m; select m into members from find_workgroup_members((created_workgroup->>'id')::uuid) m;
assert json_array_length(members) = 1, 'The members count must be equal to 1'; assert json_array_length(members) = 1, 'The members count must be equal to 1';
assert members::jsonb @> jsonb_build_array(jsonb_build_object('id', _citizen_id)), assert (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'Members must contain citizen1'; 'citizen', jsonb_build_object('id', _citizen_id)
assert not members::jsonb @> jsonb_build_array(jsonb_build_object('id', _citizen_id2)), )), 'Members must contain citizen1';
'Members must NOT contain citizen2'; assert not (members::jsonb) @> jsonb_build_array(jsonb_build_object(
'citizen', jsonb_build_object('id', _citizen_id2)
)), 'Members must NOT contain citizen2';
-- Check if find_workgroup_by_id return members -- Check if find_workgroup_by_id return members
select find_workgroup_by_id((created_workgroup->>'id')::uuid) into selected_workgroup; select find_workgroup_by_id((created_workgroup->>'id')::uuid) into selected_workgroup;
assert json_array_length(selected_workgroup->'members') = 1, 'Workgroup must have members'; assert json_array_length(selected_workgroup->'members') = 1, 'Workgroup must have members';