1
- import { IAgentRuntime } from "@ai16z/eliza" ;
1
+ import { IAgentRuntime , Memory , State } from "@ai16z/eliza" ;
2
2
import { describe , it , expect , beforeEach , vi } from "vitest" ;
3
3
4
4
// Mock the fetch function
5
5
global . fetch = vi . fn ( ) ;
6
6
7
7
// Mock the fs module
8
- vi . mock ( "fs" , async ( importOriginal ) => {
9
- const actual = await importOriginal ( ) ;
8
+ vi . mock ( "fs" , async ( ) => {
10
9
return {
11
- ...actual ,
12
10
default : {
13
11
writeFileSync : vi . fn ( ) ,
14
12
existsSync : vi . fn ( ) ,
@@ -20,31 +18,55 @@ vi.mock("fs", async (importOriginal) => {
20
18
} ;
21
19
} ) ;
22
20
23
- // Create a mock VideoService class
24
- class MockVideoService {
25
- private CONTENT_CACHE_DIR = "./content_cache" ;
21
+ // Mock the video generation plugin
22
+ const mockVideoGenerationPlugin = {
23
+ actions : [
24
+ {
25
+ validate : vi . fn ( ) . mockImplementation ( async ( runtime ) => {
26
+ const apiKey = runtime . getSetting ( "LUMA_API_KEY" ) ;
27
+ return ! ! apiKey ;
28
+ } ) ,
29
+ handler : vi . fn ( ) . mockImplementation ( async ( runtime , message , state , options , callback ) => {
30
+ // Initial response
31
+ callback ( {
32
+ text : "I'll generate a video based on your prompt" ,
33
+ } ) ;
26
34
27
- isVideoUrl ( url : string ) : boolean {
28
- return (
29
- url . includes ( "youtube.com" ) ||
30
- url . includes ( "youtu.be" ) ||
31
- url . includes ( "vimeo.com" )
32
- ) ;
33
- }
34
-
35
- async downloadMedia ( url : string ) : Promise < string > {
36
- if ( ! this . isVideoUrl ( url ) ) {
37
- throw new Error ( "Invalid video URL" ) ;
38
- }
39
- const videoId = url . split ( "v=" ) [ 1 ] || url . split ( "/" ) . pop ( ) ;
40
- return `${ this . CONTENT_CACHE_DIR } /${ videoId } .mp4` ;
41
- }
42
- }
43
-
44
- describe ( "Video Service" , ( ) => {
35
+ // Check if there's an API error
36
+ const fetchResponse = await global . fetch ( ) ;
37
+ if ( ! fetchResponse . ok ) {
38
+ callback ( {
39
+ text : "Video generation failed: API Error" ,
40
+ error : true ,
41
+ } ) ;
42
+ return ;
43
+ }
44
+
45
+ // Final response with video
46
+ callback (
47
+ {
48
+ text : "Here's your generated video!" ,
49
+ attachments : [
50
+ {
51
+ source : "videoGeneration" ,
52
+ url : "https://example.com/video.mp4" ,
53
+ } ,
54
+ ] ,
55
+ } ,
56
+ [ "generated_video_123.mp4" ]
57
+ ) ;
58
+ } ) ,
59
+ } ,
60
+ ] ,
61
+ } ;
62
+
63
+ vi . mock ( "../index" , ( ) => ( {
64
+ videoGenerationPlugin : mockVideoGenerationPlugin ,
65
+ } ) ) ;
66
+
67
+ describe ( "Video Generation Plugin" , ( ) => {
45
68
let mockRuntime : IAgentRuntime ;
46
69
let mockCallback : ReturnType < typeof vi . fn > ;
47
- let videoService : MockVideoService ;
48
70
49
71
beforeEach ( ( ) => {
50
72
// Reset mocks
@@ -58,7 +80,6 @@ describe("Video Service", () => {
58
80
} as unknown as IAgentRuntime ;
59
81
60
82
mockCallback = vi . fn ( ) ;
61
- videoService = new MockVideoService ( ) ;
62
83
63
84
// Setup fetch mock for successful response
64
85
( global . fetch as ReturnType < typeof vi . fn > ) . mockImplementation ( ( ) =>
@@ -77,25 +98,89 @@ describe("Video Service", () => {
77
98
) ;
78
99
} ) ;
79
100
80
- it ( "should validate video URLs" , ( ) => {
81
- expect ( videoService . isVideoUrl ( "https://www.youtube.com/watch?v=123" ) ) . toBe ( true ) ;
82
- expect ( videoService . isVideoUrl ( "https://youtu.be/123" ) ) . toBe ( true ) ;
83
- expect ( videoService . isVideoUrl ( "https://vimeo.com/123" ) ) . toBe ( true ) ;
84
- expect ( videoService . isVideoUrl ( "https://example.com/video" ) ) . toBe ( false ) ;
101
+ it ( "should validate when API key is present" , async ( ) => {
102
+ const mockMessage = { } as Memory ;
103
+ const result = await mockVideoGenerationPlugin . actions [ 0 ] . validate (
104
+ mockRuntime ,
105
+ mockMessage
106
+ ) ;
107
+ expect ( result ) . toBe ( true ) ;
108
+ expect ( mockRuntime . getSetting ) . toHaveBeenCalledWith ( "LUMA_API_KEY" ) ;
85
109
} ) ;
86
110
87
- it ( "should handle video download" , async ( ) => {
88
- const mockUrl = "https://www.youtube.com/watch?v=123" ;
89
- const result = await videoService . downloadMedia ( mockUrl ) ;
90
-
91
- expect ( result ) . toBeDefined ( ) ;
92
- expect ( typeof result ) . toBe ( "string" ) ;
93
- expect ( result ) . toContain ( ".mp4" ) ;
94
- expect ( result ) . toContain ( "123.mp4" ) ;
111
+ it ( "should handle video generation request" , async ( ) => {
112
+ const mockMessage = {
113
+ content : {
114
+ text : "Generate a video of a sunset" ,
115
+ } ,
116
+ } as Memory ;
117
+ const mockState = { } as State ;
118
+
119
+ await mockVideoGenerationPlugin . actions [ 0 ] . handler (
120
+ mockRuntime ,
121
+ mockMessage ,
122
+ mockState ,
123
+ { } ,
124
+ mockCallback
125
+ ) ;
126
+
127
+ // Check initial callback
128
+ expect ( mockCallback ) . toHaveBeenCalledWith (
129
+ expect . objectContaining ( {
130
+ text : expect . stringContaining (
131
+ "I'll generate a video based on your prompt"
132
+ ) ,
133
+ } )
134
+ ) ;
135
+
136
+ // Check final callback with video
137
+ expect ( mockCallback ) . toHaveBeenCalledWith (
138
+ expect . objectContaining ( {
139
+ text : "Here's your generated video!" ,
140
+ attachments : expect . arrayContaining ( [
141
+ expect . objectContaining ( {
142
+ source : "videoGeneration" ,
143
+ } ) ,
144
+ ] ) ,
145
+ } ) ,
146
+ expect . arrayContaining ( [
147
+ expect . stringMatching ( / g e n e r a t e d _ v i d e o _ .* \. m p 4 / ) ,
148
+ ] )
149
+ ) ;
95
150
} ) ;
96
151
97
- it ( "should handle download errors gracefully" , async ( ) => {
98
- const mockUrl = "https://example.com/invalid" ;
99
- await expect ( videoService . downloadMedia ( mockUrl ) ) . rejects . toThrow ( "Invalid video URL" ) ;
152
+ it ( "should handle API errors gracefully" , async ( ) => {
153
+ // Mock API error
154
+ ( global . fetch as ReturnType < typeof vi . fn > ) . mockImplementationOnce ( ( ) =>
155
+ Promise . resolve ( {
156
+ ok : false ,
157
+ status : 500 ,
158
+ statusText : "Internal Server Error" ,
159
+ text : ( ) => Promise . resolve ( "API Error" ) ,
160
+ } )
161
+ ) ;
162
+
163
+ const mockMessage = {
164
+ content : {
165
+ text : "Generate a video of a sunset" ,
166
+ } ,
167
+ } as Memory ;
168
+ const mockState = { } as State ;
169
+
170
+ await mockVideoGenerationPlugin . actions [ 0 ] . handler (
171
+ mockRuntime ,
172
+ mockMessage ,
173
+ mockState ,
174
+ { } ,
175
+ mockCallback
176
+ ) ;
177
+
178
+ // Check error callback
179
+ expect ( mockCallback ) . toHaveBeenCalledWith (
180
+ expect . objectContaining ( {
181
+ text : expect . stringContaining ( "Video generation failed" ) ,
182
+ error : true ,
183
+ } )
184
+ ) ;
100
185
} ) ;
101
186
} ) ;
0 commit comments