@@ -14,11 +14,12 @@ import type { NextRequest } from 'next/server'
1414
1515function makeReq (
1616 apiKey : string | null ,
17- opts : { instanceId ?: string } = { } ,
17+ opts : { instanceId ?: string ; cfCountry ?: string } = { } ,
1818) : NextRequest {
1919 const headers = new Headers ( )
2020 if ( apiKey ) headers . set ( 'Authorization' , `Bearer ${ apiKey } ` )
2121 if ( opts . instanceId ) headers . set ( FREEBUFF_INSTANCE_HEADER , opts . instanceId )
22+ if ( opts . cfCountry ) headers . set ( 'cf-ipcountry' , opts . cfCountry )
2223 return {
2324 headers,
2425 } as unknown as NextRequest
@@ -102,6 +103,31 @@ describe('POST /api/v1/freebuff/session', () => {
102103 const body = await resp . json ( )
103104 expect ( body . status ) . toBe ( 'disabled' )
104105 } )
106+
107+ test ( 'returns country_blocked without joining the queue for disallowed country' , async ( ) => {
108+ const sessionDeps = makeSessionDeps ( )
109+ const resp = await postFreebuffSession (
110+ makeReq ( 'ok' , { cfCountry : 'FR' } ) ,
111+ makeDeps ( sessionDeps , 'u1' ) ,
112+ )
113+ // 403 (not 200) so older CLIs that don't know `country_blocked` fall into
114+ // their error-retry backoff instead of tight-polling.
115+ expect ( resp . status ) . toBe ( 403 )
116+ const body = await resp . json ( )
117+ expect ( body . status ) . toBe ( 'country_blocked' )
118+ expect ( body . countryCode ) . toBe ( 'FR' )
119+ expect ( sessionDeps . rows . size ) . toBe ( 0 )
120+ } )
121+
122+ test ( 'allows queue entry for allowed country' , async ( ) => {
123+ const sessionDeps = makeSessionDeps ( )
124+ const resp = await postFreebuffSession (
125+ makeReq ( 'ok' , { cfCountry : 'US' } ) ,
126+ makeDeps ( sessionDeps , 'u1' ) ,
127+ )
128+ const body = await resp . json ( )
129+ expect ( body . status ) . toBe ( 'queued' )
130+ } )
105131} )
106132
107133describe ( 'GET /api/v1/freebuff/session' , ( ) => {
@@ -113,6 +139,18 @@ describe('GET /api/v1/freebuff/session', () => {
113139 expect ( body . status ) . toBe ( 'none' )
114140 } )
115141
142+ test ( 'returns country_blocked for disallowed country on GET' , async ( ) => {
143+ const sessionDeps = makeSessionDeps ( )
144+ const resp = await getFreebuffSession (
145+ makeReq ( 'ok' , { cfCountry : 'FR' } ) ,
146+ makeDeps ( sessionDeps , 'u1' ) ,
147+ )
148+ expect ( resp . status ) . toBe ( 403 )
149+ const body = await resp . json ( )
150+ expect ( body . status ) . toBe ( 'country_blocked' )
151+ expect ( body . countryCode ) . toBe ( 'FR' )
152+ } )
153+
116154 test ( 'returns superseded when active row exists with mismatched instance id' , async ( ) => {
117155 const sessionDeps = makeSessionDeps ( )
118156 sessionDeps . rows . set ( 'u1' , {
0 commit comments