@@ -1698,6 +1698,108 @@ describe('Session', () => {
16981698 } ) ;
16991699 } ) ;
17001700
1701+ describe ( 'sends force_origin in /tokens request body when skipCache is true' , ( ) => {
1702+ let dispatchSpy : ReturnType < typeof vi . spyOn > ;
1703+ let fetchSpy : ReturnType < typeof vi . spyOn > ;
1704+
1705+ beforeEach ( ( ) => {
1706+ dispatchSpy = vi . spyOn ( eventBus , 'emit' ) ;
1707+ fetchSpy = vi . spyOn ( BaseResource , '_fetch' as any ) ;
1708+ BaseResource . clerk = clerkMock ( {
1709+ __internal_environment : {
1710+ authConfig : { sessionMinter : true } ,
1711+ } ,
1712+ } ) as any ;
1713+ } ) ;
1714+
1715+ afterEach ( ( ) => {
1716+ dispatchSpy ?. mockRestore ( ) ;
1717+ fetchSpy ?. mockRestore ( ) ;
1718+ BaseResource . clerk = null as any ;
1719+ } ) ;
1720+
1721+ it ( 'includes forceOrigin in body when skipCache is true' , async ( ) => {
1722+ const session = new Session ( {
1723+ status : 'active' ,
1724+ id : 'session_1' ,
1725+ object : 'session' ,
1726+ user : createUser ( { } ) ,
1727+ last_active_organization_id : null ,
1728+ last_active_token : { object : 'token' , jwt : mockJwt } ,
1729+ actor : null ,
1730+ created_at : new Date ( ) . getTime ( ) ,
1731+ updated_at : new Date ( ) . getTime ( ) ,
1732+ } as SessionJSON ) ;
1733+
1734+ SessionTokenCache . clear ( ) ;
1735+
1736+ fetchSpy . mockResolvedValueOnce ( { object : 'token' , jwt : mockJwt } ) ;
1737+
1738+ await session . getToken ( { skipCache : true } ) ;
1739+
1740+ expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1741+ expect ( fetchSpy . mock . calls [ 0 ] [ 0 ] ) . toMatchObject ( {
1742+ path : '/client/sessions/session_1/tokens' ,
1743+ method : 'POST' ,
1744+ body : expect . objectContaining ( { forceOrigin : 'true' } ) ,
1745+ search : { debug : 'skip_cache' } ,
1746+ } ) ;
1747+ expect ( fetchSpy . mock . calls [ 0 ] [ 0 ] . body ) . not . toHaveProperty ( 'debug' ) ;
1748+ } ) ;
1749+
1750+ it ( 'does not include forceOrigin in body when skipCache is false or undefined' , async ( ) => {
1751+ const session = new Session ( {
1752+ status : 'active' ,
1753+ id : 'session_1' ,
1754+ object : 'session' ,
1755+ user : createUser ( { } ) ,
1756+ last_active_organization_id : null ,
1757+ last_active_token : { object : 'token' , jwt : mockJwt } ,
1758+ actor : null ,
1759+ created_at : new Date ( ) . getTime ( ) ,
1760+ updated_at : new Date ( ) . getTime ( ) ,
1761+ } as SessionJSON ) ;
1762+
1763+ SessionTokenCache . clear ( ) ;
1764+
1765+ fetchSpy . mockResolvedValueOnce ( { object : 'token' , jwt : mockJwt } ) ;
1766+
1767+ await session . getToken ( ) ;
1768+
1769+ expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1770+ expect ( fetchSpy . mock . calls [ 0 ] [ 0 ] . body ) . not . toHaveProperty ( 'forceOrigin' ) ;
1771+ } ) ;
1772+
1773+ it ( 'does not include forceOrigin when sessionMinter is false even with skipCache true' , async ( ) => {
1774+ BaseResource . clerk = clerkMock ( {
1775+ __internal_environment : {
1776+ authConfig : { sessionMinter : false } ,
1777+ } ,
1778+ } ) as any ;
1779+
1780+ const session = new Session ( {
1781+ status : 'active' ,
1782+ id : 'session_1' ,
1783+ object : 'session' ,
1784+ user : createUser ( { } ) ,
1785+ last_active_organization_id : null ,
1786+ last_active_token : { object : 'token' , jwt : mockJwt } ,
1787+ actor : null ,
1788+ created_at : new Date ( ) . getTime ( ) ,
1789+ updated_at : new Date ( ) . getTime ( ) ,
1790+ } as SessionJSON ) ;
1791+
1792+ SessionTokenCache . clear ( ) ;
1793+
1794+ fetchSpy . mockResolvedValueOnce ( { object : 'token' , jwt : mockJwt } ) ;
1795+
1796+ await session . getToken ( { skipCache : true } ) ;
1797+
1798+ expect ( fetchSpy ) . toHaveBeenCalledTimes ( 1 ) ;
1799+ expect ( fetchSpy . mock . calls [ 0 ] [ 0 ] . body ) . not . toHaveProperty ( 'forceOrigin' ) ;
1800+ } ) ;
1801+ } ) ;
1802+
17011803 describe ( 'origin outage mode fallback' , ( ) => {
17021804 let dispatchSpy : ReturnType < typeof vi . spyOn > ;
17031805 let fetchSpy : ReturnType < typeof vi . spyOn > ;
0 commit comments