11import FlagsmithOpenFeatureProvider from './flagsmith-provider' ;
2- import {
3- FlagNotFoundError ,
4- TypeMismatchError ,
5- Logger ,
6- StandardResolutionReasons ,
7- ProviderEvents ,
8- ProviderStatus ,
9- ErrorCode ,
10- } from '@openfeature/server-sdk' ;
2+ import { FlagNotFoundError , Logger , StandardResolutionReasons , ErrorCode , GeneralError } from '@openfeature/server-sdk' ;
113import { Flagsmith , Flags , BaseFlag } from 'flagsmith-nodejs' ;
12- import { FlagsmithProviderError } from './exceptions' ;
134import { mockFlagData } from './flagsmith.mocks' ;
145
156jest . mock ( 'flagsmith-nodejs' ) ;
@@ -63,66 +54,6 @@ describe('FlagsmithOpenFeatureProvider', () => {
6354 } ) ;
6455 } ) ;
6556
66- describe ( 'provider status and events' , ( ) => {
67- it ( 'should start with NOT_READY status' , ( ) => {
68- const provider = new FlagsmithOpenFeatureProvider ( mockFlagsmith ) ;
69- expect ( provider . status ) . toBe ( ProviderStatus . NOT_READY ) ;
70- } ) ;
71-
72- it ( 'should set status to READY after successful initialization' , async ( ) => {
73- const provider = new FlagsmithOpenFeatureProvider ( mockFlagsmith ) ;
74- mockFlagsmith . getEnvironmentFlags . mockResolvedValue ( mockFlags ) ;
75-
76- await provider . initialize ( ) ;
77-
78- expect ( provider . status ) . toBe ( ProviderStatus . READY ) ;
79- } ) ;
80-
81- it ( 'should set status to ERROR when initialization fails' , async ( ) => {
82- const provider = new FlagsmithOpenFeatureProvider ( mockFlagsmith ) ;
83- mockFlagsmith . getEnvironmentFlags . mockRejectedValue ( new Error ( 'Connection failed' ) ) ;
84-
85- await expect ( provider . initialize ( ) ) . rejects . toThrow ( ) ;
86- expect ( provider . status ) . toBe ( ProviderStatus . ERROR ) ;
87- } ) ;
88-
89- it ( 'should emit ready event when status changes to READY' , async ( ) => {
90- const provider = new FlagsmithOpenFeatureProvider ( mockFlagsmith ) ;
91- const readyHandler = jest . fn ( ) ;
92- provider . events . addHandler ( ProviderEvents . Ready , readyHandler ) ;
93-
94- mockFlagsmith . getEnvironmentFlags . mockResolvedValue ( mockFlags ) ;
95- await provider . initialize ( ) ;
96-
97- expect ( readyHandler ) . toHaveBeenCalled ( ) ;
98- } ) ;
99-
100- it ( 'should emit error event when status changes to ERROR' , async ( ) => {
101- const provider = new FlagsmithOpenFeatureProvider ( mockFlagsmith ) ;
102- const errorHandler = jest . fn ( ) ;
103- provider . events . addHandler ( ProviderEvents . Error , errorHandler ) ;
104-
105- mockFlagsmith . getEnvironmentFlags . mockRejectedValue ( new Error ( 'Connection failed' ) ) ;
106-
107- try {
108- await provider . initialize ( ) ;
109- } catch ( error ) { }
110-
111- expect ( errorHandler ) . toHaveBeenCalled ( ) ;
112- } ) ;
113-
114- it ( 'should set status to NOT_READY when onClose is called' , async ( ) => {
115- const provider = new FlagsmithOpenFeatureProvider ( mockFlagsmith ) ;
116- mockFlagsmith . getEnvironmentFlags . mockResolvedValue ( mockFlags ) ;
117-
118- await provider . initialize ( ) ;
119- expect ( provider . status ) . toBe ( ProviderStatus . READY ) ;
120-
121- await provider . onClose ( ) ;
122- expect ( provider . status ) . toBe ( ProviderStatus . NOT_READY ) ;
123- } ) ;
124- } ) ;
125-
12657 describe ( 'configuration' , ( ) => {
12758 describe ( 'useBooleanConfigValue' , ( ) => {
12859 let useBooleanConfigProvider : FlagsmithOpenFeatureProvider ;
@@ -180,9 +111,16 @@ describe('FlagsmithOpenFeatureProvider', () => {
180111 useBooleanConfigValue : false ,
181112 } ) ;
182113 mockFlags . getFlag . mockReturnValue ( mockFlagData . booleanDefault ) ;
183- await expect (
184- useFlagsmithDefaultsProvider . resolveBooleanEvaluation ( 'default-flag' , false , evaluationContext , loggerMock ) ,
185- ) . rejects . toThrow ( FlagNotFoundError ) ;
114+ const result = await useFlagsmithDefaultsProvider . resolveBooleanEvaluation (
115+ 'default-flag' ,
116+ false ,
117+ evaluationContext ,
118+ loggerMock ,
119+ ) ;
120+ expect ( result . value ) . toBe ( false ) ;
121+ expect ( result . reason ) . toBe ( StandardResolutionReasons . ERROR ) ;
122+ expect ( result . errorCode ) . toBe ( ErrorCode . FLAG_NOT_FOUND ) ;
123+ expect ( result . errorMessage ) . toContain ( "Flag 'default-flag' was not found." ) ;
186124 } ) ;
187125
188126 it ( 'should throw FlagNotFoundError when flag does not exist (undefined) even with useFlagsmithDefaults true' , async ( ) => {
@@ -192,9 +130,16 @@ describe('FlagsmithOpenFeatureProvider', () => {
192130 useBooleanConfigValue : false ,
193131 } ) ;
194132 mockFlags . getFlag . mockReturnValue ( undefined as any ) ;
195- await expect (
196- provider . resolveBooleanEvaluation ( 'nonexistent-flag' , false , evaluationContext , loggerMock ) ,
197- ) . rejects . toThrow ( FlagNotFoundError ) ;
133+ const result = await provider . resolveBooleanEvaluation (
134+ 'nonexistent-flag' ,
135+ false ,
136+ evaluationContext ,
137+ loggerMock ,
138+ ) ;
139+ expect ( result . value ) . toBe ( false ) ;
140+ expect ( result . reason ) . toBe ( StandardResolutionReasons . ERROR ) ;
141+ expect ( result . errorCode ) . toBe ( ErrorCode . FLAG_NOT_FOUND ) ;
142+ expect ( result . errorMessage ) . toContain ( "Flag 'nonexistent-flag' was not found." ) ;
198143 } ) ;
199144
200145 it ( 'should return flag.value when boolean flag is default and useFlagsmithDefaults is true' , async ( ) => {
@@ -255,7 +200,7 @@ describe('FlagsmithOpenFeatureProvider', () => {
255200 mockFlags . getFlag . mockReturnValue ( mockFlagData . disabledFlag ) ;
256201 await expect (
257202 defaultProvider . resolveStringEvaluation ( 'disabled-flag' , 'test-string' , evaluationContext , loggerMock ) ,
258- ) . rejects . toThrow ( FlagsmithProviderError ) ;
203+ ) . rejects . toThrow ( GeneralError ) ;
259204 } ) ;
260205
261206 it ( 'should return string value when flag is disabled and returnValueForDisabledFlags is true' , async ( ) => {
@@ -429,7 +374,7 @@ describe('FlagsmithOpenFeatureProvider', () => {
429374 mockFlags . getFlag . mockReturnValue ( mockFlagData . disabledFlag ) ;
430375 await expect (
431376 defaultProvider . resolveStringEvaluation ( 'test-flag' , '' , evaluationContext , loggerMock ) ,
432- ) . rejects . toThrow ( FlagsmithProviderError ) ;
377+ ) . rejects . toThrow ( GeneralError ) ;
433378 } ) ;
434379
435380 it ( 'should return default value with error details when flag value is undefined' , async ( ) => {
@@ -556,7 +501,7 @@ describe('FlagsmithOpenFeatureProvider', () => {
556501
557502 await expect (
558503 defaultProvider . resolveBooleanEvaluation ( 'test-flag' , false , evaluationContext , loggerMock ) ,
559- ) . rejects . toThrow ( FlagsmithProviderError ) ;
504+ ) . rejects . toThrow ( GeneralError ) ;
560505 } ) ;
561506
562507 it ( 'should throw FlagNotFoundError when flag is not found and returnValueForDisabledFlags is false' , async ( ) => {
@@ -566,9 +511,11 @@ describe('FlagsmithOpenFeatureProvider', () => {
566511 useBooleanConfigValue : false ,
567512 } ) ;
568513 mockFlagsmith . getIdentityFlags . mockRejectedValue ( new Error ( 'not found' ) ) ;
569- await expect ( provider . resolveBooleanEvaluation ( 'not-exist' , false , { } , loggerMock ) ) . rejects . toThrow (
570- FlagNotFoundError ,
571- ) ;
514+ const result = await provider . resolveBooleanEvaluation ( 'not-exist' , false , { } , loggerMock ) ;
515+ expect ( result . value ) . toBe ( false ) ;
516+ expect ( result . reason ) . toBe ( StandardResolutionReasons . ERROR ) ;
517+ expect ( result . errorCode ) . toBe ( ErrorCode . FLAG_NOT_FOUND ) ;
518+ expect ( result . errorMessage ) . toContain ( "Flag 'not-exist' was not found." ) ;
572519 } ) ;
573520
574521 it ( 'should return default value with error details when flag value type does not match requested type' , async ( ) => {
0 commit comments