class ProppatchTest(unittest.TestCase):

    testDirPath = os.path.sep.join([repositoryPath, "TEST"])

    def setUp(self):
        try:
            os.mkdir(self.testDirPath)
        except:
            pass
        self.dirResource = Crypto(self.testDirPath)
        self.dirResource._registerWithParent()
        self.dirResource._updateMetadata()

    def tearDown(self):
        self.dirResource.remove()

    def testProppatchRequestGenerateParse(self):
        """
        Make a PROPPATCH request body, then parse it back in and compare to the input.
        """
        body = clone.makeCloneBody(self.dirResource)
        xml = davxml.WebDAVDocument.fromString(body)
        cloneElement = proppatch.validateBodyXML(xml)
        cc = clone.cloneFromElement(cloneElement)
        assert cc.path == self.dirResource.relativePath()
class ProppatchTest(unittest.TestCase):

    testDirPath = os.path.sep.join([repositoryPath, "TEST"])

    def setUp(self):
        try:
            os.mkdir(self.testDirPath)
        except:
            pass
        self.dirResource = Crypto(self.testDirPath) 
        self.dirResource._registerWithParent()  
        self.dirResource._updateMetadata()
    
    def tearDown(self):
        self.dirResource.remove()
    
    def testProppatchRequestGenerateParse(self):
        """
        Make a PROPPATCH request body, then parse it back in and compare to the input.
        """
        body = clone.makeCloneBody(self.dirResource)
        xml =  davxml.WebDAVDocument.fromString(body)
        cloneElement = proppatch.validateBodyXML(xml)
        cc = clone.cloneFromElement(cloneElement)
        assert cc.path == self.dirResource.relativePath()
        
class ForbiddenTest(unittest.TestCase):
    """
    I make sure that all destructive method calls are forbidden on the external interface.
    """
    
    testDirPath = os.path.sep.join([repositoryPath, "TEST"])

    def setUp(self):
        try:
            os.mkdir(self.testDirPath)
        except:
            pass
        self.dirResource = Crypto(self.testDirPath) 
        self.dirResource._registerWithParent()  
        self.dirResource._updateMetadata()
        
    def tearDown(self):
        self.dirResource.remove()
        
    def testDenyRemoteResourceModification(self):
        """
        Assert (except for PROPPATCH) that all modification requests for the root resource are denied.
        For this test to run, you need a running instance of the provider.
        """
        
        from angel_app.resource.remote.clone import Clone
        
        # fake resource, modification of which should be disallowed 
        dd = Clone("localhost", providerport, "/TEST/")
        assert dd.ping(), "Test resource root unreachable."
        
        methodsAndExpectedResponseCodes = [
                                           ("MKCOL", responsecode.FORBIDDEN),
                                           ("DELETE", responsecode.FORBIDDEN),
                                           ("PUT", responsecode.FORBIDDEN),
                                           ("MOVE", responsecode.FORBIDDEN),
                                           ("COPY", responsecode.FORBIDDEN)
                                           ]
        
        for method, expect in methodsAndExpectedResponseCodes:
            runRequest(dd, method, expect)

        
    def testAllowRemoteResourceRead(self):
        """
        Perform read-only requests on remote resource
        """
        
        from angel_app.resource.remote.clone import Clone
        
        # fake resource, modification of which should be disallowed 
        dd = Clone("localhost", providerport, "/TEST/")
        assert dd.ping(), "Test resource root unreachable. Make sure you have a provider instance running."
        assert self.dirResource.exists()
        
        methodsAndExpectedResponseCodes = [
                                           ("GET", responsecode.OK),
                                           ("PROPFIND", responsecode.MULTI_STATUS),
                                           ]
        
        for method, expect in methodsAndExpectedResponseCodes:
            runRequest(dd, method, expect)


    def testCollectionRedirect(self):
        """
        path without trailing backslash affords redirect for directories
        """
                
        from angel_app.resource.remote.clone import Clone
        
        dd = Clone("localhost", providerport, "/TEST")
        
        methodsAndExpectedResponseCodes = [("GET", responsecode.MOVED_PERMANENTLY)]
        
        for method, expect in methodsAndExpectedResponseCodes:
            runRequest(dd, method, expect)

    def testProppatch(self):
        """
        Assert (except for PROPPATCH) that all modification requests for the root resource are denied.
        For this test to run, you need a running instance of the provider.
        """

        
        # fake resource, modification of which should be disallowed 
        dd = clone.Clone("localhost", providerport, "/TEST/")
        
        assert dd.ping(), "Test resource root unreachable. Make sure you have a running provider instance."
        
        method = "PROPPATCH"
        
        response = dd.remote.performRequest(method)
        assert (response.status == responsecode.BAD_REQUEST), \
            "Request with empty body must fail with 400 BAD_REQUEST. Received: " + `response.status`
            
        body = makePushBody(self.dirResource)
        
        response = dd.remote.performRequest(method, body = body)
        assert (response.status == responsecode.FORBIDDEN), \
            "Request with extensive property update must fail with 403 FORBIDDEN. Received: " + `response.status`
            
        body = clone.makeCloneBody(self.dirResource)
        response = dd.remote.performRequest(method, body = body)
        
        # TODO: we might want to add a detailed analysis of the MULTI_STATUS response here.
        assert (response.status == responsecode.MULTI_STATUS), \
            "Request with well-formed property update must succeed with MULTI_STATUS response. Received: " + `response.status`