11import { jsonResponse } from '@sim/testing/helpers/http'
2+ import { resetEnvFlagsMock , setEnvFlags } from '@sim/testing/mocks/env-flags.mock'
23import { inputValidationMock } from '@sim/testing/mocks/input-validation.mock'
3- import { afterEach , describe , expect , it , vi } from 'vitest'
4+ import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
45
56const { sentMetricData } = vi . hoisted ( ( ) => ( {
67 sentMetricData : [ ] as Array < {
@@ -10,10 +11,6 @@ const { sentMetricData } = vi.hoisted(() => ({
1011} ) )
1112
1213vi . mock ( '@/lib/core/security/input-validation.server' , ( ) => inputValidationMock )
13- vi . mock ( '@/lib/core/config/env-flags' , async ( importOriginal ) => ( {
14- ...( await importOriginal < typeof import ( '@/lib/core/config/env-flags' ) > ( ) ) ,
15- isHosted : true ,
16- } ) )
1714vi . mock ( '@aws-sdk/client-cloudwatch' , ( ) => ( {
1815 StandardUnit : { Count : 'Count' , None : 'None' , Milliseconds : 'Milliseconds' } ,
1916 PutMetricDataCommand : class {
@@ -36,41 +33,58 @@ function stubFalSubmit(status: number, body: unknown) {
3633 )
3734}
3835
39- async function failedHostedKeyReasons ( ) : Promise < Array < Record < string , string | undefined > > > {
36+ async function failedHostedKeyDimensions ( ) : Promise < Array < Record < string , string | undefined > > > {
4037 await flushHostedKeyMetrics ( )
4138 return sentMetricData
4239 . filter ( ( datum ) => datum . MetricName === 'Failed' )
4340 . map ( ( datum ) => Object . fromEntries ( ( datum . Dimensions ?? [ ] ) . map ( ( d ) => [ d . Name , d . Value ] ) ) )
4441}
4542
4643describe ( 'a fal submit the hosted account refuses' , ( ) => {
47- afterEach ( ( ) => {
48- vi . unstubAllGlobals ( )
44+ beforeEach ( ( ) => {
45+ vi . useFakeTimers ( )
46+ setEnvFlags ( { isHosted : true } )
4947 sentMetricData . length = 0
5048 } )
5149
50+ afterEach ( ( ) => {
51+ vi . useRealTimers ( )
52+ resetEnvFlagsMock ( )
53+ } )
54+
5255 it . each ( [
5356 [ 403 , { detail : 'User is locked. Reason: Exhausted balance.' } ] ,
5457 [ 401 , { detail : 'Invalid API key' } ] ,
55- ] ) ( 'records a hosted-key auth failure for a %i' , async ( status , body ) => {
58+ ] ) ( 'records a hosted-key auth failure against the refused key for a %i' , async ( status , body ) => {
5659 stubFalSubmit ( status , body )
5760
58- await expect ( runFalQueue ( 'fal-ai/model' , { } , 'key' , 'generate_audio' ) ) . rejects . toThrow (
59- `Fal.ai API error: ${ status } `
60- )
61+ await expect (
62+ runFalQueue ( 'fal-ai/model' , { } , 'key' , {
63+ tool : 'generate_audio' ,
64+ envVarName : 'FALAI_API_KEY_2' ,
65+ } )
66+ ) . rejects . toThrow ( `Fal.ai API error: ${ status } ` )
6167
62- expect ( await failedHostedKeyReasons ( ) ) . toEqual ( [
63- expect . objectContaining ( { Provider : 'falai' , Tool : 'generate_audio' , Reason : 'auth' } ) ,
68+ expect ( await failedHostedKeyDimensions ( ) ) . toEqual ( [
69+ expect . objectContaining ( {
70+ Provider : 'falai' ,
71+ Tool : 'generate_audio' ,
72+ Key : 'FALAI_API_KEY_2' ,
73+ Reason : 'auth' ,
74+ } ) ,
6475 ] )
6576 } )
6677
6778 it ( 'records nothing when fal rejects the request input' , async ( ) => {
6879 stubFalSubmit ( 422 , { detail : [ { msg : 'field required' } ] } )
6980
70- await expect ( runFalQueue ( 'fal-ai/model' , { } , 'key' , 'generate_video' ) ) . rejects . toThrow (
71- 'Fal.ai API error: 422'
72- )
81+ await expect (
82+ runFalQueue ( 'fal-ai/model' , { } , 'key' , {
83+ tool : 'generate_video' ,
84+ envVarName : 'FALAI_API_KEY_1' ,
85+ } )
86+ ) . rejects . toThrow ( 'Fal.ai API error: 422' )
7387
74- expect ( await failedHostedKeyReasons ( ) ) . toEqual ( [ ] )
88+ expect ( await failedHostedKeyDimensions ( ) ) . toEqual ( [ ] )
7589 } )
7690} )
0 commit comments