1+ import React from 'react' ;
12import { render , screen , waitFor } from '@testing-library/react' ;
2- import { expect , test , describe , vi , beforeEach } from 'vitest' ;
3-
3+ import { expect , test , describe , vi , beforeEach , Mock } from 'vitest' ;
44import { DevServerProvider , useDevServerContext } from '../ui/Toolbar/context/DevServerProvider' ;
55
6- // Mock the DevServerClient and FlagStateManager
7- const mockDevServerClient = {
6+ // Create mock instances that we can access in tests
7+ const mockDevServerClientInstance = {
88 getAvailableProjects : vi . fn ( ) . mockResolvedValue ( [ 'test-project' ] ) ,
99 setProjectKey : vi . fn ( ) ,
1010 getProjectKey : vi . fn ( ) . mockReturnValue ( 'test-project' ) ,
@@ -17,23 +17,37 @@ const mockDevServerClient = {
1717 } ) ,
1818 setOverride : vi . fn ( ) ,
1919 clearOverride : vi . fn ( ) ,
20- healthCheck : vi . fn ( ) . mockResolvedValue ( true ) ,
2120} ;
2221
23- const mockFlagStateManager = {
22+ const mockFlagStateManagerInstance = {
2423 getEnhancedFlags : vi . fn ( ) . mockResolvedValue ( { } ) ,
2524 setOverride : vi . fn ( ) ,
2625 clearOverride : vi . fn ( ) ,
2726 subscribe : vi . fn ( ) . mockReturnValue ( ( ) => { } ) ,
2827} ;
2928
30- vi . mock ( '../services/DevServerClient' , ( ) => ( {
31- DevServerClient : vi . fn ( ) . mockImplementation ( ( ) => mockDevServerClient ) ,
32- } ) ) ;
29+ vi . mock ( '../services/DevServerClient' , ( ) => {
30+ function MockDevServerClient ( ) {
31+ // Assign all methods to this instance
32+ Object . assign ( this , mockDevServerClientInstance ) ;
33+ return this ;
34+ }
35+
36+ return {
37+ DevServerClient : MockDevServerClient ,
38+ } ;
39+ } ) ;
40+
41+ vi . mock ( '../services/FlagStateManager' , ( ) => {
42+ function MockFlagStateManager ( ) {
43+ Object . assign ( this , mockFlagStateManagerInstance ) ;
44+ return this ;
45+ }
3346
34- vi . mock ( '../services/FlagStateManager' , ( ) => ( {
35- FlagStateManager : vi . fn ( ) . mockImplementation ( ( ) => mockFlagStateManager ) ,
36- } ) ) ;
47+ return {
48+ FlagStateManager : MockFlagStateManager ,
49+ } ;
50+ } ) ;
3751
3852// Test component that consumes the context
3953function TestConsumer ( ) {
@@ -54,6 +68,21 @@ describe('DevServerProvider - Integration Flows', () => {
5468 beforeEach ( ( ) => {
5569 vi . clearAllMocks ( ) ;
5670 localStorage . clear ( ) ;
71+
72+ // Reset mock instances to default state
73+ mockDevServerClientInstance . getAvailableProjects . mockResolvedValue ( [ 'test-project' ] ) ;
74+ mockDevServerClientInstance . setProjectKey . mockClear ( ) ;
75+ mockDevServerClientInstance . getProjectKey . mockReturnValue ( 'test-project' ) ;
76+ mockDevServerClientInstance . getProjectData . mockResolvedValue ( {
77+ sourceEnvironmentKey : 'test-environment' ,
78+ flagsState : { } ,
79+ overrides : { } ,
80+ availableVariations : { } ,
81+ _lastSyncedFromSource : Date . now ( ) ,
82+ } ) ;
83+
84+ mockFlagStateManagerInstance . getEnhancedFlags . mockResolvedValue ( { } ) ;
85+ mockFlagStateManagerInstance . subscribe . mockReturnValue ( ( ) => { } ) ;
5786 } ) ;
5887
5988 describe ( 'Developer Setup Flow - Dev Server Mode' , ( ) => {
@@ -93,7 +122,7 @@ describe('DevServerProvider - Integration Flows', () => {
93122
94123 test ( 'developer specifies exact project and connects successfully' , async ( ) => {
95124 // GIVEN: Developer knows exactly which project they want to work with
96- mockDevServerClient . getAvailableProjects . mockResolvedValueOnce ( [ 'explicit-project' , 'test-project' ] ) ;
125+ mockDevServerClientInstance . getAvailableProjects . mockResolvedValueOnce ( [ 'explicit-project' , 'test-project' ] ) ;
97126
98127 // WHEN: They configure the toolbar with their specific project
99128 render (
@@ -114,12 +143,12 @@ describe('DevServerProvider - Integration Flows', () => {
114143 return connectionStatus . textContent === 'connected' ;
115144 } ) ;
116145
117- expect ( mockDevServerClient . setProjectKey ) . toHaveBeenCalledWith ( 'explicit-project' ) ;
146+ expect ( mockDevServerClientInstance . setProjectKey ) . toHaveBeenCalledWith ( 'explicit-project' ) ;
118147 } ) ;
119148
120149 test ( 'developer handles dev server connection issues gracefully' , async ( ) => {
121150 // GIVEN: Developer's dev server is not running or misconfigured
122- mockDevServerClient . getAvailableProjects . mockRejectedValueOnce ( new Error ( 'Connection failed' ) ) ;
151+ mockDevServerClientInstance . getAvailableProjects . mockRejectedValueOnce ( new Error ( 'Connection failed' ) ) ;
123152
124153 // WHEN: They try to connect with the toolbar
125154 render (
@@ -145,7 +174,7 @@ describe('DevServerProvider - Integration Flows', () => {
145174
146175 test ( 'developer handles network timeout errors during initial connection' , async ( ) => {
147176 // GIVEN: Developer's network connection is slow or unreliable
148- mockDevServerClient . getAvailableProjects . mockRejectedValueOnce ( new Error ( 'ETIMEDOUT: connect timeout' ) ) ;
177+ mockDevServerClientInstance . getAvailableProjects . mockRejectedValueOnce ( new Error ( 'ETIMEDOUT: connect timeout' ) ) ;
149178
150179 // WHEN: They attempt to connect with the toolbar
151180 render (
@@ -198,7 +227,7 @@ describe('DevServerProvider - Integration Flows', () => {
198227 expect ( screen . getByTestId ( 'error' ) ) . toHaveTextContent ( 'none' ) ;
199228
200229 // AND: Doesn't attempt to make server connections
201- expect ( mockDevServerClient . getAvailableProjects ) . not . toHaveBeenCalled ( ) ;
230+ expect ( mockDevServerClientInstance . getAvailableProjects ) . not . toHaveBeenCalled ( ) ;
202231 } ) ;
203232 } ) ;
204233} ) ;
0 commit comments