*/
public void testSimpleSunnyDayCase() {
// This mock accepts all service calls. This is the wrong testing
// layer to be placing expectations on the mechanisms of the 3
// layers between the CcBasedWaveView and the underlying WaveViewService.
MockWaveViewService waveViewService = new MockWaveViewService();
OperationChannelMultiplexerImpl.LoggerContext loggers =
new OperationChannelMultiplexerImpl.LoggerContext(logger, logger, logger, logger);
OperationChannelMultiplexerImpl mux = new OperationChannelMultiplexerImpl(WAVE_ID,
ViewChannelImpl.factory(waveViewService, logger),
WaveletDataImpl.Factory.create(docFactory),
loggers, null, new ImmediateExcecutionScheduler(), FakeHashedVersionFactory.INSTANCE);
CcBasedWaveView waveView = CcBasedWaveViewImpl.create(docFactory, SCHEMAS, WAVE_ID, USER_ID,
mux, IdFilters.ALL_IDS, idGenerator, logger,
new BasicWaveletOperationContextFactory(USER_ID), ParticipationHelper.IGNORANT, null,
WaveletConfigurator.ADD_CREATOR, DuplexOpSinkFactory.PASS_THROUGH);
MockWaveViewListener viewListener = new MockWaveViewListener();
waveView.addListener(viewListener);
// Open the view and expect the open call on the service.
MockOpenListener openListener = new MockOpenListener();
waveView.open(openListener);
assertEquals(1, waveViewService.opens.size());
WaveViewService.OpenCallback openCallback = waveViewService.lastOpen().callback;
// Locally create a wavelet.
CcBasedWavelet createdWavelet = waveView.createWavelet();
assertEquals(GENERATED_WAVELET_ID, createdWavelet.getId());
assertNotNull(viewListener.addedWavelet);
viewListener.reset();
// Prime with channel id.
openCallback.onUpdate(new FakeWaveViewServiceUpdate().setChannelId("1"));
// Receive a new wavelet from the server.
openCallback.onUpdate(new FakeWaveViewServiceUpdate()
.setWaveletId(WaveletId.of("example.com", "newServerWavelet_1"))
.setWaveletSnapshot(WAVE_ID, USER_ID, 0L, HashedVersion.of(1L, sig(123)))
.setLastCommittedVersion(HashedVersion.unsigned(0)));
assertNotNull(viewListener.addedWavelet);
openCallback.onUpdate(new FakeWaveViewServiceUpdate().setMarker(false));
assertTrue(openListener.opened);
// Receive version-zero snapshot for locally generated wavelet.
openCallback.onUpdate(new FakeWaveViewServiceUpdate()
.setWaveletId(GENERATED_WAVELET_ID)
.setWaveletSnapshot(WAVE_ID, USER_ID, 0L, HashedVersion.unsigned(0))
.setLastCommittedVersion(HashedVersion.unsigned(0)));
// Ack the configurator's add-participant
assertEquals(1, waveViewService.submits.size());
waveViewService.lastSubmit().callback
.onSuccess(HashedVersion.of(1L, sig(111)), 1, null, ResponseCode.OK);
DeltaTestUtil util = new DeltaTestUtil(USER_ID);
// Receive an operation from the server that doesn't affect the document.
TransformedWaveletDelta delta1 =
util.delta(1L, util.addParticipant(new ParticipantId("reuben@example.com")));
openCallback.onUpdate(new FakeWaveViewServiceUpdate()
.setWaveletId(GENERATED_WAVELET_ID).addDelta(delta1));
assertEquals(2, createdWavelet.getParticipantIds().size());
// create an empty blip edit (i.e. implicit creation) and expect flush
TransformedWaveletDelta delta2 = util.delta(2L, util.noOpDocOp(GENERATED_BLIP_ID));
openCallback.onUpdate(new FakeWaveViewServiceUpdate()
.setWaveletId(GENERATED_WAVELET_ID).addDelta(delta2));
doc.expectedCall(MockCcDocument.MethodCall.FLUSH);
doc.expectedCall(MockCcDocument.MethodCall.CONSUME);
doc.expectedNothing();
// now hold back flush on another server op
doc.flush_return = false;
TransformedWaveletDelta delta3 = util.delta(3L, util.noOpDocOp(GENERATED_BLIP_ID));
openCallback.onUpdate(new FakeWaveViewServiceUpdate()
.setWaveletId(GENERATED_WAVELET_ID).addDelta(delta3));
MockCcDocument.MethodCallContext callContext =
doc.expectedCall(MockCcDocument.MethodCall.FLUSH);
doc.expectedNothing();
// now we are ready to get the ops
doc.flush_return = true;
callContext.command.run();
doc.expectedCall(MockCcDocument.MethodCall.FLUSH);
doc.expectedCall(MockCcDocument.MethodCall.CONSUME);
doc.expectedNothing();
// close the view
waveView.close();
assertEquals(1, waveViewService.closes.size());
waveViewService.lastClose().callback.onSuccess();
}