import { strict as assert } from "assert" ; import { IContainer , IHostLoader , ILoaderOptions } from "@fluidframework/container-definitions" ; import { IFluidCodeDetails } from "@fluidframework/core-interfaces" ; import { LocalResolver , LocalDocumentServiceFactory } from "@fluidframework/local-driver" ; import { MessageType } from "@fluidframework/protocol-definitions" ; import { SharedString } from "@fluidframework/sequence" ; import { requestFluidObject } from "@fluidframework/runtime-utils" ; import { IUrlResolver } from "@fluidframework/driver-definitions" ; import { LocalDeltaConnectionServer , ILocalDeltaConnectionServer } from "@fluidframework/server-local-server" ; import { createAndAttachContainer , createLoader , LoaderContainerTracker , ITestFluidObject , TestFluidObjectFactory , } from "@fluidframework/test-utils" ; param packageEntries param deltaConnectionServer function createLocalLoader ( packageEntries , deltaConnectionServer , urlResolver , options ? ) { const documentServiceFactory = new LocalDocumentServiceFactory ( deltaConnectionServer ) ; return createLoader ( packageEntries , documentServiceFactory , urlResolver , undefined , options ) ; } describe ( "LocalTestServer" , ( ) => { const documentId = "localServerTest" ; const documentLoadUrl = `fluid-test://localhost/${ documentId }` ; const stringId = "stringKey" ; const codeDetails = { package : "localServerTestPackage" , config : { } } ; const factory = new TestFluidObjectFactory ( [ [ stringId , SharedString . getFactory ( ) ] ] ) ; let deltaConnectionServer ; let urlResolver ; let loaderContainerTracker ; let container1 ; let container2 ; let dataObject1 ; let dataObject2 ; let sharedString1 ; let sharedString2 ; async function createContainer ( ) { const loader = createLocalLoader ( [ [ codeDetails , factory ] ] , deltaConnectionServer , urlResolver ) ; loaderContainerTracker . add ( loader ) ; return createAndAttachContainer ( codeDetails , loader , urlResolver . createCreateNewRequest ( documentId ) ) ; } async function loadContainer ( ) { const loader = createLocalLoader ( [ [ codeDetails , factory ] ] , deltaConnectionServer , urlResolver ) ; loaderContainerTracker . add ( loader ) ; return loader . resolve ( { url : documentLoadUrl } ) ; } beforeEach ( async ( ) => { deltaConnectionServer = LocalDeltaConnectionServer . create ( ) ; urlResolver = new LocalResolver ( ) ; loaderContainerTracker = new LoaderContainerTracker ( ) ; container1 = await createContainer ( ) ; dataObject1 = await requestFluidObject < ITestFluidObject > ( container1 , "default" ) ; sharedString1 = await dataObject1 . getSharedObject < SharedString > ( stringId ) ; container2 = await loadContainer ( ) ; dataObject2 = await requestFluidObject < ITestFluidObject > ( container2 , "default" ) ; sharedString2 = await dataObject2 . getSharedObject < SharedString > ( stringId ) ; } ) ; afterEach ( ( ) => { loaderContainerTracker . reset ( ) ; } ) ; describe ( "Attach Op Handlers on Both Clients" , ( ) => { it ( "Validate messaging" , async ( ) => { let user1ReceivedMsgCount = 0 ; let user2ReceivedMsgCount = 0 ; sharedString1 . on ( "op" , ( msg , local ) => { if ( ! local ) { if ( msg . type === MessageType . Operation ) { user1ReceivedMsgCount = user1ReceivedMsgCount + 1 ; } } } ) ; sharedString2 . on ( "op" , ( msg , local ) => { if ( ! local ) { if ( msg . type === MessageType . Operation ) { user2ReceivedMsgCount = user2ReceivedMsgCount + 1 ; } } } ) ; await loaderContainerTracker . pauseProcessing ( ) ; sharedString1 . insertText ( 0 , "A" ) ; sharedString2 . insertText ( 0 , "C" ) ; assert . equal ( user1ReceivedMsgCount , 0 , "User1 received message count is incorrect" ) ; assert . equal ( user2ReceivedMsgCount , 0 , "User2 received message count is incorrect" ) ; await loaderContainerTracker . ensureSynchronized ( container1 ) ; assert . equal ( user1ReceivedMsgCount , 0 , "User1 received message count is incorrect" ) ; assert . equal ( user2ReceivedMsgCount , 0 , "User2 received message count is incorrect" ) ; await loaderContainerTracker . ensureSynchronized ( container2 ) ; assert . equal ( user1ReceivedMsgCount , 0 , "User1 received message count is incorrect" ) ; assert . equal ( user2ReceivedMsgCount , 1 , "User2 received message count is incorrect" ) ; await loaderContainerTracker . processIncoming ( container1 ) ; assert . equal ( user1ReceivedMsgCount , 1 , "User1 received message count is incorrect" ) ; assert . equal ( user2ReceivedMsgCount , 1 , "User2 received message count is incorrect" ) ; sharedString1 . insertText ( 0 , "B" ) ; await loaderContainerTracker . ensureSynchronized ( ) ; assert . equal ( sharedString1 . getText ( ) , sharedString2 . getText ( ) , "Shared string not synced" ) ; assert . equal ( sharedString1 . getText ( ) . length , 3 , sharedString1 . getText ( ) ) ; assert . equal ( user1ReceivedMsgCount , 1 , "User1 received message count is incorrect" ) ; assert . equal ( user2ReceivedMsgCount , 2 , "User2 received message count is incorrect" ) ; } ) ; } ) ; afterEach ( async ( ) => { await deltaConnectionServer . webSocketServer . close ( ) ; } ) ; } ) ;