<?xml version="1.0" ?>
<!--

  Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You 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.

-->

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:qa="http://www.adobe.com/2006/flexqa" creationComplete="run()">
	
	<mx:Script>
	<![CDATA[
	    
        /******************************************************************
        *  Simple remoteobject test that receives a server side exception
        * *****************************************************************/
        
		import qa.mxunit.*;
		import mx.rpc.events.*;
        import mx.messaging.messages.ErrorMessage;
        import mx.rpc.remoting.RemoteObject;
        
        public var myException:RemoteObject;
		public var myData : String = "Extra data.";
		public var actualData : String;
		
		public function run():void {
			myException = new RemoteObject();
			myException.destination = "qa.errorhandling";
			myException.addEventListener(FaultEvent.FAULT, onServiceFault);
			myException.addEventListener(ResultEvent.RESULT, onServiceResult);
			
			run_exception();

            MXUnitManager.delay = 6000;
            MXUnitManager.addTests(this,["Test_exception"],10000);
		}

		public function onServiceResult(event:ResultEvent):void {
			trace("this test should have resulted in a FAULT instead of RESULT");
		}
		
		public function onServiceFault(event:FaultEvent):void {
            actualData = ErrorMessage(event.message).extendedData.extraData;
		}

		public function run_exception():void {
        	var call : Object = myException.generateMessageExceptionWithExtendedData(myData);
		}		
	
        public function Test_exception():void {
			Assert.assertTrue("expect an exception along with the extra data", myData == actualData);
  		}
	]]>
	</mx:Script>
</mx:Application>