/**
* Copyright 2010 Voxeo Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
* file except in compliance with the License.
*
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
package com.voxeo.moho.voicexml;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import javax.media.mscontrol.MediaEventListener;
import javax.media.mscontrol.MsControlFactory;
import javax.media.mscontrol.Parameters;
import javax.media.mscontrol.join.Joinable.Direction;
import javax.media.mscontrol.networkconnection.NetworkConnection;
import javax.media.mscontrol.vxml.VxmlDialogEvent;
import javax.servlet.sip.SipServlet;
import junit.framework.TestCase;
import org.hamcrest.Description;
import org.hamcrest.TypeSafeMatcher;
import org.jmock.Expectations;
import org.jmock.Mockery;
import org.jmock.api.Action;
import org.jmock.api.Invocation;
import org.jmock.lib.legacy.ClassImposteriser;
import com.voxeo.moho.Application;
import com.voxeo.moho.ApplicationContextImpl;
import com.voxeo.moho.Participant.JoinType;
import com.voxeo.moho.common.event.MohoHangupEvent;
import com.voxeo.moho.media.fake.MockMediaSession;
import com.voxeo.moho.media.fake.MockParameters;
import com.voxeo.moho.media.fake.MockVxmlDialog;
import com.voxeo.moho.sip.SIPCallImpl;
import com.voxeo.moho.sip.fake.MockSipServlet;
import com.voxeo.moho.spi.ExecutionContext;
public class VoiceXMLDialogImplTest extends TestCase {
Mockery mockery = new Mockery() {
{
setImposteriser(ClassImposteriser.INSTANCE);
}
};
// JSR309 mock
MsControlFactory msFactory = mockery.mock(MsControlFactory.class);
MockMediaSession mediaSession = mockery.mock(MockMediaSession.class);
MockVxmlDialog dialog = mockery.mock(MockVxmlDialog.class);
// JSR289 mock
SipServlet servlet = new MockSipServlet(mockery);
// Moho
TestApp app = mockery.mock(TestApp.class);
// ApplicationContextImpl is simple, no need to mock it.
ExecutionContext appContext = null;
VoiceXMLEndpoint vXMLendPoint;
VoiceXMLDialogImpl vXMLDialog;
protected void setUp() throws Exception {
super.setUp();
if (appContext == null) {
appContext = new ApplicationContextImpl(app, msFactory, servlet);
}
}
protected void tearDown() throws Exception {
super.tearDown();
appContext.destroy();
}
/**
*
*/
public void testJoinAndUnjoin() {
// prepare
// test data
final String documentURL = "ftp://test";
try {
mockery.checking(new Expectations() {
{
// creation
oneOf(msFactory).createMediaSession();
will(returnValue(mediaSession));
oneOf(mediaSession).createVxmlDialog(with(any(Parameters.class)));
will(returnValue(dialog));
allowing(mediaSession).createParameters();
will(returnValue(new MockParameters()));
}
});
}
catch (Exception ex) {
ex.printStackTrace();
}
// create vXMLDialog.
vXMLendPoint = (VoiceXMLEndpoint) appContext.createEndpoint(documentURL);
vXMLDialog = (VoiceXMLDialogImpl) vXMLendPoint.create(null);
// mock the call
final SIPCallImpl call = mockery.mock(SIPCallImpl.class);
final NetworkConnection callNet = mockery.mock(NetworkConnection.class);
try {
mockery.checking(new Expectations() {
{
allowing(call).getMediaObject();
will(returnValue(callNet));
// join
oneOf(call).join(vXMLDialog, JoinType.BRIDGE, Direction.DUPLEX);
will(new Action() {
@Override
public void describeTo(Description description) {
}
@Override
public Object invoke(Invocation invocation) throws Throwable {
vXMLDialog.addParticipant(call, JoinType.BRIDGE, Direction.DUPLEX, null);
return null;
}
});
// unjoin
oneOf(dialog).unjoin(callNet);
oneOf(call).doUnjoin(vXMLDialog, false);
}
});
}
catch (Exception ex) {
ex.printStackTrace();
fail(ex.getMessage());
}
// join
vXMLDialog.join(call, JoinType.BRIDGE, Direction.DUPLEX);
assertTrue(vXMLDialog.getParticipants()[0] == call);
// unjoin
try {
vXMLDialog.unjoin(call).get();
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
assertTrue(vXMLDialog.getParticipants().length == 0);
// verify the result.
mockery.assertIsSatisfied();
}
/**
*
*/
public void testTerminate() {
// test data
final String documentURL = "ftp://test";
// prepare
try {
mockery.checking(new Expectations() {
{
// creation
oneOf(msFactory).createMediaSession();
will(returnValue(mediaSession));
oneOf(mediaSession).createVxmlDialog(with(any(Parameters.class)));
will(returnValue(dialog));
allowing(mediaSession).createParameters();
will(returnValue(new MockParameters()));
}
});
}
catch (Exception ex) {
ex.printStackTrace();
}
final VxmlDialogEvent mediaEvent0 = mockery.mock(VxmlDialogEvent.class, "mediaEvent0");
try {
mockery.checking(new Expectations() {
{
allowing(mediaEvent0).getEventType();
will(returnValue(VxmlDialogEvent.PREPARED));
}
});
}
catch (Exception ex) {
ex.printStackTrace();
}
final VxmlDialogEvent mediaEvent1 = mockery.mock(VxmlDialogEvent.class, "mediaEvent1");
try {
mockery.checking(new Expectations() {
{
allowing(mediaEvent1).getEventType();
will(returnValue(VxmlDialogEvent.STARTED));
}
});
}
catch (Exception ex) {
ex.printStackTrace();
}
final VxmlDialogEvent mediaEvent2 = mockery.mock(VxmlDialogEvent.class, "mediaEvent2");
final Map<String, Object> result = new HashMap<String, Object>();
try {
mockery.checking(new Expectations() {
{
allowing(mediaEvent2).getEventType();
will(returnValue(VxmlDialogEvent.DISCONNECTION_REQUESTED));
allowing(mediaEvent2).getNameList();
will(returnValue(result));
}
});
}
catch (Exception ex) {
ex.printStackTrace();
}
try {
mockery.checking(new Expectations() {
{
// dialog prepare
oneOf(dialog).prepare(with(new TypeSafeMatcher<URL>() {
@Override
public boolean matchesSafely(URL item) {
try {
if (item.equals(new URL(documentURL))) {
return true;
}
}
catch (MalformedURLException e) {
e.printStackTrace();
fail(e.getMessage());
}
return false;
}
@Override
public void describeTo(Description description) {
}
}), with(any(Parameters.class)), with(any(Map.class)));
will(new Action() {
@Override
public void describeTo(Description description) {
}
@Override
public Object invoke(Invocation invocation) throws Throwable {
Thread th = new Thread(new Runnable() {
@Override
public void run() {
Object[] ls = dialog.listeners.toArray();
for (Object listerner : ls) {
((MediaEventListener<VxmlDialogEvent>) listerner).onEvent(mediaEvent0);
}
}
});
th.start();
return null;
}
});
// dialog start.
oneOf(dialog).start(with(any(Map.class)));
will(new Action() {
@Override
public void describeTo(Description description) {
}
@Override
public Object invoke(Invocation invocation) throws Throwable {
Thread th = new Thread(new Runnable() {
@Override
public void run() {
Object[] ls = dialog.listeners.toArray();
for (Object listerner : ls) {
((MediaEventListener<VxmlDialogEvent>) listerner).onEvent(mediaEvent1);
}
}
});
th.start();
return null;
}
});
// dialog terminate
oneOf(dialog).terminate(true);
will(new Action() {
@Override
public void describeTo(Description description) {
}
@Override
public Object invoke(Invocation invocation) throws Throwable {
Thread th = new Thread(new Runnable() {
@Override
public void run() {
Object[] ls = dialog.listeners.toArray();
for (Object listerner : ls) {
((MediaEventListener<VxmlDialogEvent>) listerner).onEvent(mediaEvent2);
}
}
});
th.start();
return null;
}
});
}
});
}
catch (Exception ex) {
ex.printStackTrace();
}
// excute
// create dialog.
vXMLendPoint = (VoiceXMLEndpoint) appContext.createEndpoint(documentURL);
vXMLDialog = (VoiceXMLDialogImpl) vXMLendPoint.create(null);
vXMLDialog.prepare();
vXMLDialog.start();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
e.printStackTrace();
}
vXMLDialog.terminate(true);
try {
vXMLDialog.get();
}
catch (Exception ex) {
ex.printStackTrace();
fail(ex.getMessage());
}
// verify the result.
mockery.assertIsSatisfied();
}
abstract class TestApp implements Application {
public abstract void handleDisconnect(MohoHangupEvent event);
public final void destroy() {
}
}
}