diff --git a/src/main/resources/openapi2.yaml b/src/main/resources/openapi2.yaml index 6dc221d..32def80 100644 --- a/src/main/resources/openapi2.yaml +++ b/src/main/resources/openapi2.yaml @@ -1207,62 +1207,38 @@ paths: $ref: '#/components/schemas/Workgroup' 404: description: Workshop not exist or are deleted -# put: -# summary: Edit one workgroup -# security: -# - JWTAuth: [ ] -# tags: -# - workgroup -# requestBody: -# content: -# application/json: -# schema: -# required: -# - name -# properties: -# name: -# type: string -# example: Les partisants du RIC -# description: -# type: string -# example: Group formé pour la conception d'un RIC -# logo: -# type: string -# nullable: true -# anonymous: -# type: boolean -# example: false -# nullable: true -# default: true -# owner: -# type: string -# format: uuid -# example: 6434f4f9-f570-f22a-c134-8668350651ff -# nullable: true -# responses: -# 200: -# description: Workgroup updated -# content: -# application/json: -# schema: -# properties: -# id: -# type: string -# format: uuid -# name: -# type: string -# example: Les partisants du RIC -# description: -# type: string -# example: Group formé pour la conception d'un RIC -# logo: -# type: string -# anonymous: -# type: boolean -# example: false -# owner: -# type: string -# format: uuid + put: + summary: Edit one workgroup + security: + - JWTAuth: [ ] + tags: + - workgroup + requestBody: + content: + application/json: + schema: + properties: + name: + type: string + example: Les partisants du RIC + description: + type: string + example: Group formé pour la conception d'un RIC + logo: + type: string + nullable: true + anonymous: + type: boolean + example: false + nullable: true + default: true + responses: + 200: + description: Workgroup updated + content: + application/json: + schema: + $ref: '#/components/schemas/Workgroup' delete: summary: Delete one workgroup security: diff --git a/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql b/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql index 01f2446..00e1fbb 100644 --- a/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql +++ b/src/main/resources/sql/functions/workgroup/upsert_workgroup.sql @@ -3,7 +3,7 @@ create or replace function upsert_workgroup(inout resource json) $$ declare new_id uuid = coalesce((resource->>'id')::uuid, uuid_generate_v4()); - exists boolean = case when (select true from workgroup where id = new_id) is null then true else false end; + exists boolean = case when (select true from workgroup where id = new_id) is null then false else true end; begin insert into workgroup (id, created_by_id, name, description, anonymous, logo) select @@ -20,15 +20,25 @@ begin anonymous = excluded.anonymous, logo = excluded.logo; + -- remove old members + delete from citizen_in_workgroup cw + where cw.workgroup_id = new_id + and cw.citizen_id not in ( + select (m#>>'{citizen,id}')::uuid + from json_array_elements(resource->'members') m + ); + + -- insert new members insert into citizen_in_workgroup (workgroup_id, citizen_id, roles) select new_id::uuid, (m#>>'{citizen,id}')::uuid, json_to_array(m#>'{roles}') - from json_array_elements(resource->'members') m; + from json_array_elements(resource->'members') m + on conflict do nothing; -- insert master if no members - if (exists) then + if (exists = false) then insert into citizen_in_workgroup (workgroup_id, citizen_id, roles) select new_id::uuid, diff --git a/src/test/kotlin/integration/Workgroup routes.kt b/src/test/kotlin/integration/Workgroup routes.kt index 7db4e82..44884dd 100644 --- a/src/test/kotlin/integration/Workgroup routes.kt +++ b/src/test/kotlin/integration/Workgroup routes.kt @@ -16,6 +16,7 @@ import integration.steps.given.`Given I have workgroup` import integration.steps.given.`With members` import integration.steps.given.`authenticated as` import integration.steps.given.`with no content` +import integration.steps.then.`And have property` import io.ktor.http.HttpStatusCode.Companion.Created import io.ktor.http.HttpStatusCode.Companion.NoContent import io.ktor.http.HttpStatusCode.Companion.NotFound @@ -88,6 +89,47 @@ class `Workgroup routes` : BaseTest() { } } + @Test + fun `I can edit a workgroup`() { + withIntegrationApplication { + `Given I have citizen`("John", "Wheeler") + `Given I have citizen`("Heinrich", "Hertz", id = "94f92424-c257-4582-907c-98564a8c4ac9") + `Given I have citizen`("William", "Thomson", id = "87909ba3-2069-431c-9924-219fd8411cf2") + `Given I have workgroup`("aa875a24-0050-4252-9130-d37391714e26", createdBy = Name("John", "Wheeler")) { + `With members`( + Name("Heinrich", "Hertz"), + Name("William", "Thomson"), + ) + } + `When I send a PUT request`("/workgroups/aa875a24-0050-4252-9130-d37391714e26") { + `authenticated as`("John", "Wheeler") + `with body`(""" + { + "name":"La ratatouille", + "description":"Une petite souris" + } + """) + } `Then the response should be` OK and { + `And the response should contain`("$.id", "aa875a24-0050-4252-9130-d37391714e26") + `And the response should contain`("$.name", "La ratatouille") + `And the response should contain`("$.description", "Une petite souris") + + `And have property`("$.members") + `And the response should contain list`("$.members", 3, 3) + `And the response should contain`("$.members.[1]citizen.id", "94f92424-c257-4582-907c-98564a8c4ac9") + `And the response should contain`("$.members.[2]citizen.id", "87909ba3-2069-431c-9924-219fd8411cf2") + } + + `When I send a GET request`("/workgroups/aa875a24-0050-4252-9130-d37391714e26") { + `authenticated as`("John", "Wheeler") + } `Then the response should be` OK and { + `And the response should contain`("$.id", "aa875a24-0050-4252-9130-d37391714e26") + `And the response should contain`("$.name", "La ratatouille") + `And the response should contain`("$.description", "Une petite souris") + } + } + } + @Test fun `I can delete a workgroup`() { withIntegrationApplication { diff --git a/src/test/sql/workgroup.sql b/src/test/sql/workgroup.sql index de7065e..de6fee7 100644 --- a/src/test/sql/workgroup.sql +++ b/src/test/sql/workgroup.sql @@ -9,6 +9,11 @@ declare "description": "test", "anonymous": false }'; + created_workgroup_updated json := '{ + "name": "Le groupe des rouge", + "description": "red", + "anonymous": false + }'; created_workgroup_2 json := '{ "name": "hello", "description": "super", @@ -22,12 +27,19 @@ begin created_workgroup := jsonb_set(created_workgroup::jsonb, '{created_by}'::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); - -- upsert workgroup + -- insert workgroup select upsert_workgroup(created_workgroup) into created_workgroup; assert created_workgroup->>'description' is not null, 'description should not be null'; assert (created_workgroup->>'name') = 'Le groupe des vert', format('name must be equal to "Le groupe des vert", %s instead', created_workgroup->>'name'); assert (created_workgroup#>>'{members, 0, citizen, id}') = _citizen_id::text, 'workgroup must have creator in members on creation'; + -- update workgroup + created_workgroup_updated := jsonb_set(created_workgroup_updated::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json; + select upsert_workgroup(created_workgroup_updated) into created_workgroup_updated; + assert created_workgroup_updated->>'description' is not null, 'description should not be null'; + assert (created_workgroup_updated->>'name') = 'Le groupe des rouge', format('name must be equal to "Le groupe des rouge", %s instead', created_workgroup_updated->>'name'); + assert (created_workgroup_updated#>>'{members, 0, citizen, id}') = _citizen_id::text, 'workgroup must have creator in members on update'; + -- insert another workgroup created_workgroup_2 := jsonb_set(created_workgroup_2::jsonb, '{created_by}'::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);