diff --git a/src/main/kotlin/fr/dcproject/repository/Follow.kt b/src/main/kotlin/fr/dcproject/repository/Follow.kt index 0b74d57..d629c78 100644 --- a/src/main/kotlin/fr/dcproject/repository/Follow.kt +++ b/src/main/kotlin/fr/dcproject/repository/Follow.kt @@ -55,13 +55,14 @@ sealed class Follow(override var requester: Req open fun findFollow( citizen: CitizenI, - target: UuidEntity + target: TargetRef ): FollowEntity? = requester .getFunction("find_follow") .selectOne( "citizen_id" to citizen.id, - "target_id" to target.id + "target_id" to target.id, + "target_reference" to target.reference ) fun findFollowsByTarget( diff --git a/src/main/resources/sql/functions/follow/find_follow.sql b/src/main/resources/sql/functions/follow/find_follow.sql index ab9fbd1..17072e8 100644 --- a/src/main/resources/sql/functions/follow/find_follow.sql +++ b/src/main/resources/sql/functions/follow/find_follow.sql @@ -1,22 +1,43 @@ create or replace function find_follow( _target_id uuid, _citizen_id uuid, + _target_reference regclass, out resource json, out following boolean ) language plpgsql as $$ +declare + _target_ids uuid[]; begin - select to_json(t) - into resource - from ( - select - f.*, - json_build_object('id', f.target_id, 'reference', f.target_reference) as target, - find_citizen_by_id(f.created_by_id) as created_by - from follow as f - where f.created_by_id = _citizen_id - and f.target_id = _target_id - ) as t; + if (_target_reference = 'article'::regclass) then + select array_agg(a2.id) into _target_ids + from article a1 + join article a2 using (version_id) + where a1.id = _target_id; + + select to_json(t) into resource from ( + select + f.*, + json_build_object('id', f.target_id, 'reference', f.target_reference) as target, + find_citizen_by_id(f.created_by_id) as created_by + from follow as f + where f.created_by_id = _citizen_id + and array[f.target_id] <@ _target_ids + limit 1 + ) as t; + else + select to_json(t) + into resource + from ( + select + f.*, + json_build_object('id', f.target_id, 'reference', f.target_reference) as target, + find_citizen_by_id(f.created_by_id) as created_by + from follow as f + where f.created_by_id = _citizen_id + and f.target_id = _target_id + ) as t; + end if; select resource is not null into following; end; diff --git a/src/test/sql/fixtures/fixture_article.sql b/src/test/sql/fixtures/fixture_article.sql index ff35bb4..194afc0 100644 --- a/src/test/sql/fixtures/fixture_article.sql +++ b/src/test/sql/fixtures/fixture_article.sql @@ -1,10 +1,9 @@ -create or replace function fixture_article(in name text default 'love', _citizen_id uuid default fixture_citizen(), out _article_id uuid) +create or replace function fixture_article(in name text default 'love', _citizen_id uuid default fixture_citizen(), _version_id uuid default uuid_generate_v4(), out _article_id uuid) language plpgsql as $$ declare created_article json := $json$ { - "version_id": "933b6a1b-50c9-42b6-989f-c02a57814ef9", "title": "Love the world", "anonymous": false, "content": "bla bal bla", @@ -19,6 +18,7 @@ begin if (name = 'love') then -- set citizen id to article created_article := jsonb_set(created_article::jsonb, '{created_by}'::text[], jsonb_build_object('id', _citizen_id::text), true)::json; + created_article := jsonb_set(created_article::jsonb, '{version_id}'::text[], to_jsonb(_version_id), true)::json; assert created_article#>>'{created_by, id}' = _citizen_id::text, format('citizenId in article must be the same as citizen, %s != %s', created_article#>>'{created_by, id}', _citizen_id::text); -- upsert article select (a->>'id')::uuid into _article_id from upsert_article(created_article) a; diff --git a/src/test/sql/follow.sql b/src/test/sql/follow.sql index 6a38a1c..58c27bd 100644 --- a/src/test/sql/follow.sql +++ b/src/test/sql/follow.sql @@ -4,12 +4,13 @@ declare _citizen_id uuid := fixture_citizen('george'); _citizen_id2 uuid := fixture_citizen('john'); - first_article_id uuid := fixture_article(_citizen_id := _citizen_id); + _version_id1 uuid = uuid_generate_v4(); + first_article_id uuid := fixture_article(_citizen_id := _citizen_id, _version_id := _version_id1); first_article_updated_id uuid; begin perform follow('citizen'::regclass, _citizen_id, _citizen_id2); assert (select count(*) = 1 from follow), 'follow must be inserted'; - assert (select following = true from find_follow(_citizen_id, _citizen_id2)), 'find_follow must return the following'; + assert (select following = true from find_follow(_citizen_id, _citizen_id2, 'citizen')), 'find_follow must return the following'; perform follow('citizen'::regclass, _citizen_id, _citizen_id2); assert (select count(*) = 1 from follow), 'follow must be inserted'; @@ -18,13 +19,15 @@ begin assert (select count(*) = 0 from follow), 'follow must be deleted after unfollow'; perform follow('article'::regclass, first_article_id, _citizen_id); - assert (select following = true from find_follow(first_article_id, _citizen_id)), 'find_follow must return the following'; - assert (select following = false from find_follow(first_article_id, _citizen_id2)), 'find_follow must not return the following if not followinf'; + assert (select following = true from find_follow(first_article_id, _citizen_id, 'article')), 'find_follow must return the following'; + assert (select following = false from find_follow(first_article_id, _citizen_id2, 'article')), 'find_follow must not return the following if not followinf'; assert (select count(*) = 1 from follow), 'must have 1 following'; -- add new version for article, then unfollow the new one - select fixture_article(_citizen_id := _citizen_id) into first_article_updated_id; + select fixture_article(_citizen_id := _citizen_id, _version_id := _version_id1) into first_article_updated_id; assert first_article_id != first_article_updated_id; + assert (select following = true from find_follow(first_article_id, _citizen_id, 'article')), '(v1) find_follow must return the following'; + assert (select following = true from find_follow(first_article_updated_id, _citizen_id, 'article')), '(v2) find_follow must return the following'; perform unfollow('article'::regclass, first_article_id, _citizen_id); assert (select count(*) = 0 from follow), 'follow must be deleted after unfollow, event if article is on other version'; diff --git a/src/test/sql/workgroup.sql b/src/test/sql/workgroup.sql index baf6f46..ad3f7d1 100644 --- a/src/test/sql/workgroup.sql +++ b/src/test/sql/workgroup.sql @@ -87,7 +87,3 @@ begin raise notice 'workgroup test pass'; end $$; - - - --- select w->>'id' from json_array_elements('[{"id":"plop"}]') w \ No newline at end of file