@@ -1718,6 +1718,205 @@ describe('DecisionService', () => {
17181718 } ) ;
17191719 } ) ;
17201720
1721+ describe ( 'resolveVariationForFeatureList - sync' , ( ) => {
1722+ beforeEach ( ( ) => {
1723+ mockBucket . mockReset ( ) ;
1724+ } ) ;
1725+
1726+ it ( 'should skip cmab experiments' , async ( ) => {
1727+ const { decisionService, cmabService } = getDecisionService ( ) ;
1728+ const config = createProjectConfig ( getDecisionTestDatafile ( ) ) ;
1729+
1730+ const user = new OptimizelyUserContext ( {
1731+ optimizely : { } as any ,
1732+ userId : 'tester' ,
1733+ attributes : {
1734+ age : 15 , // should satisfy audience condition for all experiments and targeted delivery
1735+ } ,
1736+ } ) ;
1737+
1738+ mockBucket . mockImplementation ( ( param : BucketerParams ) => {
1739+ const ruleKey = param . experimentKey ;
1740+ if ( ruleKey === 'delivery_1' ) {
1741+ return {
1742+ result : '5004' ,
1743+ reasons : [ ] ,
1744+ } ;
1745+ }
1746+ return {
1747+ result : null ,
1748+ reasons : [ ] ,
1749+ } ;
1750+ } ) ;
1751+
1752+ const feature = config . featureKeyMap [ 'flag_1' ] ;
1753+ const value = decisionService . resolveVariationsForFeatureList ( 'sync' , config , [ feature ] , user , { } ) . get ( ) ;
1754+
1755+ const variation = value [ 0 ] ;
1756+
1757+ expect ( variation . result ) . toEqual ( {
1758+ experiment : config . experimentKeyMap [ 'delivery_1' ] ,
1759+ variation : config . variationIdMap [ '5004' ] ,
1760+ decisionSource : DECISION_SOURCES . ROLLOUT ,
1761+ } ) ;
1762+
1763+ expect ( mockBucket ) . toHaveBeenCalledTimes ( 3 ) ;
1764+ verifyBucketCall ( 0 , config , config . experimentKeyMap [ 'exp_1' ] , user ) ;
1765+ verifyBucketCall ( 1 , config , config . experimentKeyMap [ 'exp_2' ] , user ) ;
1766+ verifyBucketCall ( 2 , config , config . experimentKeyMap [ 'delivery_1' ] , user ) ;
1767+
1768+ expect ( cmabService . getDecision ) . not . toHaveBeenCalled ( ) ;
1769+ } ) ;
1770+
1771+ it ( 'should ignore async user profile service' , async ( ) => {
1772+ const { decisionService, userProfileServiceAsync } = getDecisionService ( {
1773+ userProfileService : false ,
1774+ userProfileServiceAsync : true ,
1775+ } ) ;
1776+
1777+ userProfileServiceAsync ?. lookup . mockResolvedValue ( {
1778+ user_id : 'tester' ,
1779+ experiment_bucket_map : {
1780+ '2002' : {
1781+ variation_id : '5001' ,
1782+ } ,
1783+ } ,
1784+ } ) ;
1785+ userProfileServiceAsync ?. save . mockResolvedValue ( null ) ;
1786+
1787+ mockBucket . mockImplementation ( ( param : BucketerParams ) => {
1788+ const ruleKey = param . experimentKey ;
1789+ if ( ruleKey === 'exp_2' ) {
1790+ return {
1791+ result : '5002' ,
1792+ reasons : [ ] ,
1793+ } ;
1794+ }
1795+ return {
1796+ result : null ,
1797+ reasons : [ ] ,
1798+ } ;
1799+ } ) ;
1800+
1801+ const config = createProjectConfig ( getDecisionTestDatafile ( ) ) ;
1802+
1803+ const user = new OptimizelyUserContext ( {
1804+ optimizely : { } as any ,
1805+ userId : 'tester' ,
1806+ attributes : {
1807+ age : 55 , // should satisfy audience condition for exp_2 and exp_3
1808+ } ,
1809+ } ) ;
1810+
1811+ const feature = config . featureKeyMap [ 'flag_1' ] ;
1812+ const value = decisionService . resolveVariationsForFeatureList ( 'sync' , config , [ feature ] , user , { } ) . get ( ) ;
1813+
1814+ const variation = value [ 0 ] ;
1815+
1816+ expect ( variation . result ) . toEqual ( {
1817+ experiment : config . experimentKeyMap [ 'exp_2' ] ,
1818+ variation : config . variationIdMap [ '5002' ] ,
1819+ decisionSource : DECISION_SOURCES . FEATURE_TEST ,
1820+ } ) ;
1821+
1822+ expect ( userProfileServiceAsync ?. lookup ) . not . toHaveBeenCalled ( ) ;
1823+ expect ( userProfileServiceAsync ?. save ) . not . toHaveBeenCalled ( ) ;
1824+ } ) ;
1825+
1826+ it ( 'should use sync user profile service' , async ( ) => {
1827+ const { decisionService, userProfileService, userProfileServiceAsync } = getDecisionService ( {
1828+ userProfileService : true ,
1829+ userProfileServiceAsync : true ,
1830+ } ) ;
1831+
1832+ userProfileService ?. lookup . mockImplementation ( ( userId : string ) => {
1833+ if ( userId === 'tester-1' ) {
1834+ return {
1835+ user_id : 'tester-1' ,
1836+ experiment_bucket_map : {
1837+ '2002' : {
1838+ variation_id : '5001' ,
1839+ } ,
1840+ } ,
1841+ } ;
1842+ }
1843+ return null ;
1844+ } ) ;
1845+
1846+ userProfileServiceAsync ?. lookup . mockResolvedValue ( null ) ;
1847+ userProfileServiceAsync ?. save . mockResolvedValue ( null ) ;
1848+
1849+ mockBucket . mockImplementation ( ( param : BucketerParams ) => {
1850+ const ruleKey = param . experimentKey ;
1851+ if ( ruleKey === 'exp_2' ) {
1852+ return {
1853+ result : '5002' ,
1854+ reasons : [ ] ,
1855+ } ;
1856+ }
1857+ return {
1858+ result : null ,
1859+ reasons : [ ] ,
1860+ } ;
1861+ } ) ;
1862+
1863+ const config = createProjectConfig ( getDecisionTestDatafile ( ) ) ;
1864+
1865+ const user1 = new OptimizelyUserContext ( {
1866+ optimizely : { } as any ,
1867+ userId : 'tester-1' ,
1868+ attributes : {
1869+ age : 55 , // should satisfy audience condition for exp_2 and exp_3
1870+ } ,
1871+ } ) ;
1872+
1873+ const feature = config . featureKeyMap [ 'flag_1' ] ;
1874+ const value = decisionService . resolveVariationsForFeatureList ( 'sync' , config , [ feature ] , user1 , { } ) . get ( ) ;
1875+
1876+ const variation = value [ 0 ] ;
1877+
1878+ expect ( variation . result ) . toEqual ( {
1879+ experiment : config . experimentKeyMap [ 'exp_2' ] ,
1880+ variation : config . variationIdMap [ '5001' ] ,
1881+ decisionSource : DECISION_SOURCES . FEATURE_TEST ,
1882+ } ) ;
1883+
1884+ expect ( userProfileService ?. lookup ) . toHaveBeenCalledTimes ( 1 ) ;
1885+ expect ( userProfileService ?. lookup ) . toHaveBeenCalledWith ( 'tester-1' ) ;
1886+
1887+ const user2 = new OptimizelyUserContext ( {
1888+ optimizely : { } as any ,
1889+ userId : 'tester-2' ,
1890+ attributes : {
1891+ age : 55 , // should satisfy audience condition for exp_2 and exp_3
1892+ } ,
1893+ } ) ;
1894+
1895+ const value2 = decisionService . resolveVariationsForFeatureList ( 'sync' , config , [ feature ] , user2 , { } ) . get ( ) ;
1896+ const variation2 = value2 [ 0 ] ;
1897+ expect ( variation2 . result ) . toEqual ( {
1898+ experiment : config . experimentKeyMap [ 'exp_2' ] ,
1899+ variation : config . variationIdMap [ '5002' ] ,
1900+ decisionSource : DECISION_SOURCES . FEATURE_TEST ,
1901+ } ) ;
1902+
1903+ expect ( userProfileService ?. lookup ) . toHaveBeenCalledTimes ( 2 ) ;
1904+ expect ( userProfileService ?. lookup ) . toHaveBeenNthCalledWith ( 2 , 'tester-2' ) ;
1905+ expect ( userProfileService ?. save ) . toHaveBeenCalledTimes ( 1 ) ;
1906+ expect ( userProfileService ?. save ) . toHaveBeenCalledWith ( {
1907+ user_id : 'tester-2' ,
1908+ experiment_bucket_map : {
1909+ '2002' : {
1910+ variation_id : '5002' ,
1911+ } ,
1912+ } ,
1913+ } ) ;
1914+
1915+ expect ( userProfileServiceAsync ?. lookup ) . not . toHaveBeenCalled ( ) ;
1916+ expect ( userProfileServiceAsync ?. save ) . not . toHaveBeenCalled ( ) ;
1917+ } ) ;
1918+ } ) ;
1919+
17211920 describe ( 'getVariationsForFeatureList' , ( ) => {
17221921 beforeEach ( ( ) => {
17231922 mockBucket . mockReset ( ) ;
0 commit comments