@@ -605,6 +605,7 @@ describe('Orbit V6 Slice 5 dashboard and platform core', { concurrency: false },
605605 } ) ;
606606
607607 let allAnnouncementId = '' ;
608+ let targetedAnnouncementId = '' ;
608609 test ( 'owner publishes private announcements and agent audiences do not leak' , async ( ) => {
609610 const created = await ownerRequest ( '/v1/admin/announcements' , 'POST' , {
610611 title : 'Bakım penceresi' , bodyMarkdown : 'Orbit istemcileri kısa süreli yeniden bağlanabilir.' ,
@@ -629,25 +630,90 @@ describe('Orbit V6 Slice 5 dashboard and platform core', { concurrency: false },
629630 severity : 'critical' , audienceType : 'agent' , targetAgentId : externalAgent . id ,
630631 startsAt : NOW , expiresAt : null ,
631632 } ) ;
632- const targetedId = ( await targeted . json ( ) as { announcement : { id : string } } ) . announcement . id ;
633- assert . equal ( ( await ownerRequest ( `/v1/admin/announcements/${ targetedId } /publish` , 'POST' , { } ) ) . status , 200 ) ;
633+ targetedAnnouncementId = ( await targeted . json ( ) as { announcement : { id : string } } ) . announcement . id ;
634+ assert . equal ( ( await ownerRequest ( `/v1/admin/announcements/${ targetedAnnouncementId } /publish` , 'POST' , { } ) ) . status , 200 ) ;
634635
635636 const equinoxRows = ( await ( await agentRequest ( agents . get ( 'slice5-equinox' ) ! , '/v1/announcements' ) ) . json ( ) as { announcements : Array < { id : string } > } ) . announcements ;
636637 const externalRows = ( await ( await agentRequest ( externalAgent , '/v1/announcements' ) ) . json ( ) as { announcements : Array < { id : string } > } ) . announcements ;
637638 assert . deepEqual ( new Set ( equinoxRows . map ( ( item ) => item . id ) ) , new Set ( [ allAnnouncementId , equinoxOnlyId ] ) ) ;
638- assert . deepEqual ( new Set ( externalRows . map ( ( item ) => item . id ) ) , new Set ( [ allAnnouncementId , targetedId ] ) ) ;
639+ assert . deepEqual ( new Set ( externalRows . map ( ( item ) => item . id ) ) , new Set ( [ allAnnouncementId , targetedAnnouncementId ] ) ) ;
640+
641+ const equinoxUnread = await agentRequest ( agents . get ( 'slice5-equinox' ) ! , '/v1/announcements/unread-count' ) ;
642+ assert . equal ( equinoxUnread . status , 200 ) ;
643+ assert . deepEqual ( await equinoxUnread . json ( ) , {
644+ unreadCount : 2 ,
645+ criticalCount : 0 ,
646+ warningCount : 1 ,
647+ infoCount : 1 ,
648+ highestSeverity : 'warning' ,
649+ } ) ;
650+ const externalUnread = await agentRequest ( externalAgent , '/v1/announcements/unread-count' ) ;
651+ assert . equal ( externalUnread . status , 200 ) ;
652+ assert . deepEqual ( await externalUnread . json ( ) , {
653+ unreadCount : 2 ,
654+ criticalCount : 1 ,
655+ warningCount : 1 ,
656+ infoCount : 0 ,
657+ highestSeverity : 'critical' ,
658+ } ) ;
659+
660+ const blocked = await agentRequest ( externalAgent , '/v1/records' , 'POST' , {
661+ bodyMarkdown : 'Kritik duyuru okunmadan yayımlanmaması gereken kayıt.' ,
662+ projectSlug : null ,
663+ topicSlugs : [ ] ,
664+ } , 'slice5-critical-announcement-block' ) ;
665+ assert . equal ( blocked . status , 428 ) ;
666+ const blockedBody = await blocked . json ( ) as {
667+ error : { code : string ; details : { endpoint : string ; announcementIds : string [ ] } } ;
668+ } ;
669+ assert . equal ( blockedBody . error . code , 'critical_announcement_unread' ) ;
670+ assert . equal ( blockedBody . error . details . endpoint , '/v1/announcements' ) ;
671+ assert . deepEqual ( blockedBody . error . details . announcementIds , [ targetedAnnouncementId ] ) ;
672+ const blockedDm = await agentRequest ( externalAgent , '/v1/direct-messages' , 'POST' , {
673+ recipientHandle : agents . get ( 'slice5-equinox' ) ! . handle ,
674+ bodyMarkdown : 'Kritik duyuru okunmadan gönderilmemesi gereken DM.' ,
675+ } , 'slice5-critical-announcement-dm-block' ) ;
676+ assert . equal ( blockedDm . status , 428 ) ;
677+ assert . equal (
678+ ( await blockedDm . json ( ) as { error : { code : string } } ) . error . code ,
679+ 'critical_announcement_unread' ,
680+ ) ;
639681
640682 const publicFeed = await fetch ( `${ baseUrl } /v1/feed` ) . then ( ( response ) => response . text ( ) ) ;
641683 assert . doesNotMatch ( publicFeed , / B a k ı m p e n c e r e s i | E q u i n o x i ç n o t u | T e k a j a n n o t u / u) ;
642684 assert . equal ( ( await fetch ( `${ baseUrl } /v1/announcements` ) ) . status , 401 ) ;
685+ assert . equal ( ( await fetch ( `${ baseUrl } /v1/announcements/unread-count` ) ) . status , 401 ) ;
643686 } ) ;
644687
645688 test ( 'agent read receipt is private and idempotent' , async ( ) => {
646689 const agent = agents . get ( 'slice5-external' ) ! ;
647690 assert . equal ( ( await agentRequest ( agent , `/v1/announcements/${ allAnnouncementId } /read` , 'POST' , { } ) ) . status , 200 ) ;
648691 assert . equal ( ( await agentRequest ( agent , `/v1/announcements/${ allAnnouncementId } /read` , 'POST' , { } ) ) . status , 200 ) ;
692+ assert . equal ( ( await agentRequest ( agent , `/v1/announcements/${ targetedAnnouncementId } /read` , 'POST' , { } ) ) . status , 200 ) ;
649693 const rows = ( await ( await agentRequest ( agent , '/v1/announcements' ) ) . json ( ) as { announcements : Array < { id : string ; readAt : number | null } > } ) . announcements ;
650694 assert . equal ( rows . find ( ( item ) => item . id === allAnnouncementId ) ?. readAt , NOW ) ;
695+ assert . equal ( rows . find ( ( item ) => item . id === targetedAnnouncementId ) ?. readAt , NOW ) ;
696+ assert . deepEqual (
697+ await ( await agentRequest ( agent , '/v1/announcements/unread-count' ) ) . json ( ) ,
698+ {
699+ unreadCount : 0 ,
700+ criticalCount : 0 ,
701+ warningCount : 0 ,
702+ infoCount : 0 ,
703+ highestSeverity : null ,
704+ } ,
705+ ) ;
706+ const unblocked = await agentRequest ( agent , '/v1/records' , 'POST' , {
707+ bodyMarkdown : 'Kritik duyuru okunduktan sonra yayımlanabilen kayıt.' ,
708+ projectSlug : null ,
709+ topicSlugs : [ ] ,
710+ } , 'slice5-critical-announcement-unblocked' ) ;
711+ assert . ok ( unblocked . status === 201 || unblocked . status === 202 ) ;
712+ const unblockedDm = await agentRequest ( agent , '/v1/direct-messages' , 'POST' , {
713+ recipientHandle : agents . get ( 'slice5-equinox' ) ! . handle ,
714+ bodyMarkdown : 'Kritik duyuru okunduktan sonra gönderilebilen DM.' ,
715+ } , 'slice5-critical-announcement-dm-unblocked' ) ;
716+ assert . equal ( unblockedDm . status , 201 ) ;
651717 const authenticated = await agentRequest ( agent , '/v1/announcements' ) ;
652718 assert . match ( authenticated . headers . get ( 'cache-control' ) ?? '' , / ^ n o - s t o r e / u) ;
653719 } ) ;
0 commit comments