/*
 * $Header: /home/cvspublic/jakarta-slide/proposals/wvcm/test/junit/src/org/apache/wvcm/test/FolderTest.java,v 1.3 2004/07/30 06:52:33 ozeigermann Exp $
 * $Revision: 1.3 $
 * $Date: 2004/07/30 06:52:33 $
 *
 * ====================================================================
 *
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution, if
 *    any, must include the following acknowlegement:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowlegement may appear in the software itself,
 *    if and wherever such third-party acknowlegements normally appear.
 *
 * 4. The names "The Jakarta Project", "Slide", and "Apache Software
 *    Foundation" must not be used to endorse or promote products derived
 *    from this software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache"
 *    nor may "Apache" appear in their names without prior written
 *    permission of the Apache Group.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 *
 * [Additional notices, if required by prior licensing conditions]
 *
 */

package org.apache.wvcm.test;

import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.wvcm.ControllableFolder;
import javax.wvcm.ControllableResource;
import javax.wvcm.Location;
import javax.wvcm.Folder;
import javax.wvcm.PropertyNameList;
import javax.wvcm.Resource;
import javax.wvcm.Version;
import javax.wvcm.WvcmException;
import javax.wvcm.PropertyNameList.NestedPropertyName;
import javax.wvcm.PropertyNameList.PropertyName;
import javax.wvcm.PropertyNameList.AttributeName;
import javax.wvcm.WvcmException.ReasonCode;

import junit.framework.Test;
import junit.framework.TestSuite;

import org.apache.wvcm.test.common.AbstractTest;

/**
 * Provides functional tests for the javax.wvcm.Folder interface.
 *
 * @author <a href="mailto:peter.nevermann@softwareag.com">Peter Nevermann</a>
 * @version $Revision: 1.3 $
 */
public class FolderTest extends AbstractTest
{
    
	private String testFolderFoo = "foo";
	private String testFolderBar = "bar";
	private String testFileName1 = "1.xml";
	private String testFileName2 = "2.xml";
	private String testFileName3 = "3.xml";
	private int numberOfCreatedResources = 0;
	
	// logger
	private static Logger logger = Logger.getLogger("org.apache.wvcm.test.FolderTest");
    
    /**
	 * Default Constructor
	 *
	 * @param    testName            Name of the test to run.
	 *
	 * @throws   Exception
	 *
	 */
    public FolderTest(String testName) throws Exception
	{
		super(testName);
		folderPath = rootFolderPath()+ "/" + testFolderFoo;
    }
    
    /**
	 * Returns the TestSuite for this class.
	 *
	 * @return   a Test
	 */
    public static Test suite()
	{
		return new TestSuite(FolderTest.class);
    }
    
    /**
	 * Start test suite contained in this class using the text interface. If a
	 * parameter is passed, it will use it as a test name and run only that test
	 * case.
	 *
	 * @param args   commandline options (first argument = test method name to run)
	 *
	 * @throws Exception
	 */
    public static void main( String[] args ) throws Exception
	{
		if (args.length == 1)
		{
			TestSuite testSuite = new TestSuite();
			testSuite.addTest(new FolderTest(args[0]));
			junit.textui.TestRunner.run(testSuite);
		}
		else
		{
			junit.textui.TestRunner.run( suite() );
		}
    }
    
    /**
	 * Common test setup.
	 *
	 * @throws Exception
	 */
    protected void setUp() throws Exception
	{
		super.setUp ();
    }
    
    /**
	 * Tears down the fixture, for example, close a network connection.
	 * This method is called after a test is executed.
	 *
	 * @throws Exception
	 */
    protected void tearDown() throws Exception
	{
    }
	
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>Create a valid PropertyNameList with some props.
	 * <li>doReadMemberList with those props and deep=false.
	 * <li>Check Iterator returned: one folder + one resource (version=1.0).
	 *
	 * @throws   Exception
	 *
	 */
	public void testDoReadMemberListPropsDeepFalse() throws Exception
	{
		// create the resources: /foo/, /foo/a.xml, /foo/bar/, /foo/bar/b.xml, /foo/bar/c.xml
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		numberOfCreatedResources+=1;
		
		createTestFolderStructure();
		
		// Specify properties to be returned.
		PropertyName[] vrPnames =
		{
			PropertyName.DISPLAY_NAME,
				PropertyName.VERSION_NAME
		};
		PropertyName[] pnames =
		{
			new NestedPropertyName(
				PropertyName.CHECKED_IN, new PropertyNameList(vrPnames) )
		};
		PropertyNameList wantedprops = new PropertyNameList( pnames );
		
		// Read Members only in test folder (excluding child folder content).
		Iterator boundMembers = testFolder.doReadMemberList( wantedprops, false );
		ControllableResource tempControllableResource;
		Resource tempResource;
		if (logger.isLoggable(Level.CONFIG))
			logger.config("DO READ MEMBER LIST(PROPS, FALSE)");
		while( boundMembers.hasNext() )
		{
			tempResource = (Resource)boundMembers.next();
			
			if (logger.isLoggable(Level.CONFIG))
				logger.config(tempResource.toString());
			
			if( tempResource instanceof ControllableFolder )
			{
				assertTrue(tempResource.location().string().endsWith(testFolderBar));
			}
			else if( tempResource instanceof ControllableResource )
			{
				tempControllableResource = (ControllableResource)tempResource;
				Version v = tempControllableResource.getCheckedIn();
				assertEquals(testFileName1, v.getDisplayName());
				assertEquals("1.0", v.getVersionName());
			}
		}
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Create a resource in the folder.
	 * <li>Unbind folder.
	 * <li>Check that the resource in the folder and the folder itself are not
	 * accessible any more.
	 *
	 * @throws Exception
	 */
	public void testDoUnbindFolder() throws Exception
	{
		
		// Create a folder
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		
		// Create resource in the folder.
		resourceInFolderPath=folderPath+ "/" + testFileName1;
		location = testFolder.location().child(testFileName1);
		testResource = createControllableResource(location);
		assertTrue( resourceExistsOnServer(resourceInFolderPath) );
		
		// unbind folder
		testFolder.doUnbind();
		assertFalse("Folder has been unbound, but it is still on origin location.",
					resourceExistsOnServer(folderPath));
		assertFalse("Resource has been unbound, but it is still on origin location.",
					resourceExistsOnServer(	resourceInFolderPath));
		
		
		
	}
	
	/**
	 * <ul>
	 * <li>Try to Unbind a non existing folder.
	 * <li>Exception should be thrown (I guess).
	 *
	 * @throws Exception
	 */
	public void testDoUnbindNonExistingFolder() throws Exception
	{
		// Create a non existing location.
		String nonExistingLocation = rootFolderPath() + "/nonExistingTestFolder";
		location= provider.location( nonExistingLocation );
		assertFalse( resourceExistsOnServer(folderPath) );
		Folder testFolder = location.folder();
		
		// unbind folder
		try
		{
			testFolder.doUnbind();
		}
		catch (WvcmException expected)
		{
			// TODO: CHECK THAT THIS REASON CODE IS THE CORRECT ONE.
			assertEquals("Unexpected reason code after unbinding non existing folder.",
						 ReasonCode.CANNOT_UNBIND_RESOURCE,
						 expected.getReasonCode());
			
		}
	}
	
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>Create a valid PropertyNameList with some props.
	 * <li>doReadMemberList with those props and deep=true.
	 * <li>Check Resources returned for the properties. Expecting no display name
	 * or content type on folders.
	 *
	 * @throws   Exception
	 *
	 */
	// TODO: check the checks built are correct->Folders get no display name
	// and/or content type.
	public void testDoReadMemberListCheckProps() throws Exception
	{
		// create the resources: /foo/, /foo/a.xml, /foo/bar/, /foo/bar/b.xml, /foo/bar/c.xml
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		numberOfCreatedResources+=1;
		
		createTestFolderStructure();
		
		// Refresh the props wanted.
		PropertyName[] pnames = new PropertyName[]
		{
			PropertyName.DISPLAY_NAME,
				PropertyName.CONTENT_TYPE,
				PropertyName.LAST_MODIFIED
		};
		PropertyNameList wantedprops = new PropertyNameList( pnames );
		
		Resource tempResource;
		// Read members including child folders.
		Iterator allMembers = testFolder.doReadMemberList( wantedprops, true );
		if(logger.isLoggable(Level.CONFIG))
			logger.config("DO READ MEMBER LIST(PROPS, TRUE) - WORK FOLDER");
		
		while( allMembers.hasNext() )
		{
			tempResource = (Resource)allMembers.next();
			if (tempResource instanceof ControllableFolder)
			{
				
				// Folders should not have a display name. ??
				try
				{
					tempResource.getDisplayName();
					fail("Folders should not have a display name?");
				}
				catch (WvcmException e)
				{
					assertEquals("Unexpected exception",
								 ReasonCode.VALUE_UNAVAILABLE,
								 e.getReasonCode());
				}
				
				try
				{
					tempResource.getContentType();
					fail("Folders should not have a content type?");
				}
				catch (WvcmException e)
				{
					assertEquals("Unexpected exception",
								 ReasonCode.VALUE_UNAVAILABLE,
								 e.getReasonCode());
				}
				
				try
				{
					tempResource.getLastModified();
				}
				catch (WvcmException e)
				{
					assertEquals("Unexpected exception",
								 ReasonCode.VALUE_UNAVAILABLE,
								 e.getReasonCode());
				}
				
			}
			else if (tempResource instanceof ControllableResource)
			{
				try
				{
					assertTrue("Display Name in a Resource should not be null.",
							   tempResource.getDisplayName() != null);
				}
				catch (WvcmException e)
				{
					fail("Unexpected Exception: " + e.toString());
					//					assertEquals("Unexpected exception",
					//								 ReasonCode.VALUE_UNAVAILABLE,
					//								 e.getReasonCode());
				}
				
				try
				{
					assertTrue("Content Type in a Resource should not be null.",
							   tempResource.getContentType() != null);
					assertTrue("Unexpected ContentType.",
							   tempResource.getContentType().equalsIgnoreCase("text/xml"));
				}
				catch (WvcmException e)
				{
					fail("Unexpected Exception: " + e.toString());
					//					assertEquals("Unexpected exception",
					//								 ReasonCode.VALUE_UNAVAILABLE,
					//								 e.getReasonCode());
				}
				
				try
				{
					assertTrue("Last Modified should not be null.",
							   tempResource.getLastModified() != null);
				}
				catch (WvcmException e)
				{
					fail("Unexpected Exception: " + e.toString());
					//					assertEquals("Unexpected exception",
					//								 ReasonCode.VALUE_UNAVAILABLE,
					//								 e.getReasonCode());
				}
			}
			else
			{
				fail("Unexpected type of resource received.");
			}
		}
	}
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>Create a valid PropertyNameList with some props.
	 * <li>doReadMemberList with those props and deep=true.
	 * <li>Check amount of resources returned are OK.
	 *
	 * @throws   Exception
	 *
	 */
	public void testDoReadMemberListRootFolder() throws Exception
	{
		location= provider.location( folderPath );
		folder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		numberOfCreatedResources+=1;
		
		createTestFolderStructure();
		
		location = provider.location( rootFolderPath() );
		Folder rootFolder = location.folder();
		
		PropertyName[] pnames = new PropertyName[]
		{
			PropertyName.DISPLAY_NAME,
				PropertyName.CONTENT_TYPE,
				PropertyName.LAST_MODIFIED
		};
		PropertyNameList wantedprops = new PropertyNameList( pnames );
		
		Iterator allMembersOfRoot = rootFolder.doReadMemberList( wantedprops, true );
		
		if(logger.isLoggable(Level.CONFIG))
			logger.config("DO READ MEMBER LIST( PROPS, TRUE) - ROOT FOLDER");
		
		int resxCounted = 0;
		while( allMembersOfRoot.hasNext() )
		{
			allMembersOfRoot.next();
			resxCounted+=1;
		}
		assertEquals("Unexpected number of resources found",
					 numberOfCreatedResources+1,
					 resxCounted);
	}
	
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>doReadMemberList with null props and deep=true.
	 * <li>Check Resources returned has no props (check with getLastModified).
	 * <li>Check number of resources returned in the Iterator.
	 *
	 * @throws   Exception
	 *
	 */
	public void testDoReadMemberListDeepTrue() throws Exception
	{
		// create the resources: /foo/, /foo/a.xml, /foo/bar/, /foo/bar/b.xml, /foo/bar/c.xml
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		numberOfCreatedResources+=1;
		
		createTestFolderStructure();
		
		Iterator members = testFolder.doReadMemberList( null, true );
		if(logger.isLoggable(Level.CONFIG))
			logger.config("DO READ MEMBER LIST( PROPS, TRUE) - FOO FOLDER -"
							  + " EXCLUDING SELF.");
		
		int membersAmount = 0;
		Resource tempResx;
		while( members.hasNext() )
		{
			tempResx = (Resource)members.next();
			membersAmount+=1;
			try
			{
				tempResx.getLastModified();
				fail("WvcmException with not available property value expected.");
			}
			catch (WvcmException we)
			{
				assertEquals("Unexpected exception",
							 ReasonCode.VALUE_UNAVAILABLE,
							 we.getReasonCode());
			}
		}
		assertEquals("Unexpected size of members list.",
					 numberOfCreatedResources,
					 membersAmount);
	}
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>doReadMemberList with null props and deep=false.
	 * <li>Check resources returned belong only to the folder used in test.
	 *
	 * @throws   Exception
	 *
	 */
	public void testDoReadMemberListDeepFalse() throws Exception
	{
		// Create basis folder for the test.
		location = provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		
		createTestFolderStructure();
		
		Iterator members = testFolder.doReadMemberList( null, false );
		if(logger.isLoggable(Level.CONFIG))
			logger.config("DO READ MEMBER LIST( NULL, FALSE) - FOO FOLDER");
		
		// Expecting only members in folder /<rootfolder>/foo
		String tempResourcePath;
		int pathSeparatorIndex = 0;
		while (members.hasNext())
		{
			tempResourcePath = ((Resource)members.next()).toString();
			
			// Check if there are children of the given location among the members
			// returned.
			pathSeparatorIndex = tempResourcePath.indexOf("/",
														  folderPath.length()+1);
			assertTrue("Not Expected Member Found:\t" + tempResourcePath,
					   pathSeparatorIndex == -1);
		}
	}
	
	/**
	 * Creates a folder structure to be used in the test (root folder is defined
	 * in the configuration file).
	 * <ul>
	 * <li>/foo/a.xml
	 * <li>/bar
	 * <li>/bar/b.xml
	 * <li>/bar/c.xml
	 * Updates the variable counting the resources created for the test.
	 *
	 * @throws   Exception
	 *
	 */
	private void createTestFolderStructure() throws Exception
	{
		
		String newLocationPath = folderPath + "/" + testFileName1;
		location = provider.location(newLocationPath);
		resource = location.controllableResource();
		resource.doCreateResource();
		resource.doControl();
		assertTrue( resourceExistsOnServer(newLocationPath) );
		numberOfCreatedResources+=1;
		
		newLocationPath = folderPath + "/" + testFolderBar;
		location = provider.location(newLocationPath);
		ControllableFolder subfolder = (ControllableFolder)location.folder();
		subfolder.doCreateResource();
		assertTrue( resourceExistsOnServer(newLocationPath) );
		numberOfCreatedResources+=1;
		
		newLocationPath = folderPath + "/" + testFolderBar + "/" + testFileName2;
		location = provider.location(newLocationPath);
		resource = location.controllableResource();
		resource.doCreateResource();
		resource.doControl();
		assertTrue( resourceExistsOnServer(newLocationPath) );
		numberOfCreatedResources+=1;
		
		newLocationPath = folderPath + "/" + testFolderBar + "/" + testFileName3;
		location = provider.location(newLocationPath);
		resource = location.controllableResource();
		resource.doCreateResource();
		resource.doControl();
		assertTrue( resourceExistsOnServer(newLocationPath) );
		numberOfCreatedResources+=1;
	}
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>doReadMemberList in an empty folder.
	 * <li>Iterator returned should contain no element.
	 *
	 * @throws   Exception
	 *
	 */
	public void testDoReadMemberListEmtpyFolder() throws Exception
	{
		fail("Not Implemented");
	}
	
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>getBindingList with no bound members.
	 * <li>List returned should be empty.
	 *
	 * @throws   Exception
	 *
	 */
	public void testGetBindingListNoBoundMembers() throws Exception
	{
		fail("Not Implemented");
	}
	
	/**
	 * <ul>
	 * <li>Create test folder structure.
	 * <li>getBindingList with some bound members.
	 * <li>List returned should be empty.
	 *
	 * @throws   Exception
	 *
	 */
	public void testGetBindingListSomeMembers() throws Exception
	{
		fail("Not Implemented");
	}
	
	/**
	 * <ul>
	 * <li>Create one folder containing two other folders and a resource in one
	 * of them (<store>/folderA, <store>/folderA/folderB, <store>/folderA/folderC,
	 * <store>/folderA/folderB/testResource.xml).
	 * <li>Bind the folder <store>/folderA/folderB/testResource.xml to
	 * <store>/folderA/folderC/folderBound
	 * <li>Check that bound has been correctly done.
	 *
	 * @throws Exception
	 */
	public void testDoBindFolder() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a test folder and a resource in it.
	 * <li>Try to bind the folder to itself again.
	 * <li>Exception should be thrown.
	 * <li>Try to bind the folder to be a subfolder of itself.
	 * <li>This should work.
	 *
	 * @throws Exception
	 */
	public void testDoBindFolderToItself() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder, a resource in it and a resource somewhere else.
	 * <li>Try to bind the folder to that resource.
	 * <li>Exception should be thrown.
	 *
	 * @throws Exception
	 */
	// TODO: CHECK IF THIS TEST SHOULD PRODUCE AN EXCEPTION OR IT SHOULD WORK.
	public void testDoBindFolderOverExistingResource() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Try to create a VCR that identifies a folder version.
	 * <li>Read again javadoc regarding
	 * ControllableResource.doCreateVersionControlledResource(Version v),
	 * Postconditions: (new-version-controlled-folder) and try to write a test case for that.
	 *
	 * @throws Exception
	 */
	// TODO: IMPROVE TEST CASE DESCRIPTION ACCORDING WITH JAVADOC.
	public void testDoCreateVCRFolder() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Get the resourcetype property from the folder
	 * <li>Check it is a valid one (collection).
	 *
	 * @throws Exception
	 */
	public void testGetNonWvcmWebDAVPropertyAsAttribute() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Read some property from the folder.
	 * <li>Get some property from the folder by its name...
	 *
	 * @throws Exception
	 */
	public void testGetPropertyFromFolder() throws Exception
	{
		//location = provider.location( rootFolderPath()+"/foo" );
		location = provider.location( rootFolderPath()+"/"+ testFolderFoo );
		folder = createControllableFolder(location);
		String propToRead = "resourcetype";
		AttributeName resxTypeAttribute = new AttributeName("DAV:", propToRead);
		PropertyNameList wantedprops = new PropertyNameList(
			new PropertyName[]{resxTypeAttribute} );
		
		PropertyName[] pns = folder.getPropertyNameList(false).getPropertyNames();
		
		folder = (ControllableFolder)folder.doReadProperties(wantedprops);
		pns = folder.getPropertyNameList(false).getPropertyNames();
		
		for ( int i = 0; i < pns.length; i++)
		{
			if (pns[i].getString().equals(propToRead))
				assertTrue("Resource type returned is not the expected for this folder.",
						   String.valueOf(folder.getProperty(pns[i])).indexOf("collection") !=0);
			else
				assertNotNull("Property returned a null value.",
							  folder.getProperty(pns[i]));
		}
	}
	
	/**
	 * <ul>
	 * <li>Create a folder and a resource in it.
	 * <li>Copy the folder to a valid location.
	 * <li>Check that the folder and its contents have been correctly copied.
	 *
	 * @throws Exception
	 */
	public void testDoCopy() throws Exception
	{
		
		// Create a folder
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		
		
		// Create resource in the folder.
		resourceInFolderPath=folderPath+ "/" + testFileName1;
		location = testFolder.location().child(testFileName1);
		testResource = createControllableResource(location);
		assertTrue( resourceExistsOnServer(resourceInFolderPath) );
		
		//create new location
		String destFolderPath= rootFolderPath()+"/"+testFolderBar;
		
		//copy the folder to another location
		testFolder.doCopy(destFolderPath, true);
		
		assertTrue(resourceExistsOnServer(destFolderPath));
		assertTrue(resourceExistsOnServer(destFolderPath+ "/" + testFileName1));
		
		
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Copy it to a valid location.
	 * <li>Check copied folder is there.
	 *
	 * @throws Exception
	 */
	public void testDoCopyEmpty() throws Exception
	{
		
		// Create a folder
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		
		//define a new location
		String destFolderPath= rootFolderPath()+"/"+testFolderBar;
		
		//copy the folder to new location
		testFolder.doCopy(destFolderPath, true);
		
		assertTrue(resourceExistsOnServer(destFolderPath));
		
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Try to copy the folder over itself.
	 * <li>Exception should be thrown.
	 *
	 * @throws Exception
	 */
	
	public void testDoCopyOverItself() throws Exception
	{
		
		// Create a folder
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		
		//copy the folder over itself
		try
		{
			testFolder.doCopy(folderPath, true);
		}
		catch (WvcmException expected)
		{
			
			assertEquals("Expected exception",
						 ReasonCode.FORBIDDEN,
						 expected.getReasonCode());
		}
		
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Read properties from the folder.
	 * <li>Check values are as expected
	 *
	 * @throws Exception
	 */
	// TODO: ADD WHAT PROPERTIES SHOULD BE READ IN DOCUMENTATION AND TEST.
	public void testDoReadProperties() throws Exception
	{
		// Create a folder
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		
		
		
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a resource.
	 * <li>Read some props of the resource.
	 * <li>Update some of them.
	 * <li>Get the updated list.
	 * <li>It should contain the props that have been updated.
	 * <li>Persist property changes.
	 * <li>Get updated property list again. It should be empty.
	 *
	 * @throws Exception
	 */
	public void testGetUpdatedPropertyList() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder and a resource in it.
	 * <li>Try to read the content from the folder.
	 * <li>An Exception should be thrown.
	 *
	 * @throws Exception
	 */
	public void testDoReadContent() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Try to write some content into it.
	 * <li>Exception is thrown.
	 *
	 * @throws Exception
	 */
	public void testDoWriteContent() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder and a resource in it.
	 * <li>Rebind folder to a valid location.
	 * <li>Check that the folder and its content have been correctly moved.
	 *
	 * @throws Exception
	 */
	public void testDoRebind() throws Exception
	{
		
		// Create a folder
		folderPath = rootFolderPath()+ "/" + testFolderFoo;
		location= provider.location( folderPath );
		Folder testFolder = createControllableFolder(location);
		assertTrue( resourceExistsOnServer(folderPath) );
		
		
		// Create resource in the folder.
		resourceInFolderPath=folderPath+ "/" + testFileName1;
		location = testFolder.location().child(testFileName1);
		testResource = createControllableResource(location);
		assertTrue( resourceExistsOnServer(resourceInFolderPath) );
		
		//create new location
		String destFolderPath= rootFolderPath()+"/"+testFolderBar;
		location= provider.location( destFolderPath );
		
		//doUnbind
		testFolder.doRebind(location, true);
		
		
		assertFalse("Folder has been rebound, but it is still on origin location.",
					resourceExistsOnServer(folderPath));
		assertFalse("Resource has been rebound, but it is still on origin location.",
					resourceExistsOnServer(	resourceInFolderPath));
		
		assertTrue("Folder has been rebound, but it is not moved to the new location.",
				   resourceExistsOnServer(destFolderPath));
		//  resourceExistsOnServer(destFolderPath + "/" + testFolderFoo));
		assertTrue("Resource has been rebound, but it is not moved to the new location.",
				   resourceExistsOnServer(	destFolderPath + "/" + testFileName1));
		// resourceExistsOnServer(	destFolderPath + "/" + testFolderFoo + "/" + testFileName1));
		
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Set an attribute.
	 * <li>Get the attributes of the folder and check for the set one.
	 * <li>Remove the set attribute.
	 * <li>Check attribute has been removed.
	 *
	 * @throws Exception
	 */
	public void testSetGetRemoveAttribute() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create one folder and two resources in it...
	 * <li>Make a doSearch on the folder with a null SearchToken.
	 *
	 * @throws Exception
	 */
	public void testDoSearchNothing() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder and two resources.
	 * <li>Set a property to both resources.
	 * <li>Make a doSearch in the folder with a search token such that no result
	 * should come.
	 * <li>List returned should be empty.
	 *
	 * @throws Exception
	 */
	public void testDoSearchEmptyResult() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder and two resources.
	 * <li>Set a property to both resources (different values).
	 * <li>Make a doSearch in the folder such that one of the resources is returned.
	 * <li>Check list returned for the wanted resource.
	 *
	 * @throws Exception
	 */
	public void testDoSearchFindSomething() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder and two resources.
	 * <li>Set a property to both resources (different values).
	 * <li>Make a doSearch on the folder such that all of the resources is returned.
	 * <li>Check list returned for the wanted resources.
	 *
	 * @throws Exception
	 */
	public void testDoSearchFindAll() throws Exception
	{
		fail("Not Implemented.");
	}
	
	/**
	 * <ul>
	 * <li>Create a folder.
	 * <li>Create an ACL with an ACE in it.
	 * <li>Write ACL to folder.
	 * <li>Check ACL has been correctly set.
	 *
	 * @throws Exception
	 */
	public void testDoWriteACL() throws Exception
	{
		fail("Not Implemented.");
	}
}





