|
inherit "etc/test/tests/pike_test_common.pike" : Parent; |
|
#include <testsuite.h> |
|
#charset utf-8 |
|
protected constant STATUS_OK = 200; |
protected constant STATUS_CREATED = 201; |
protected constant STATUS_NO_CONTENT = 204; |
protected constant STATUS_MULTI_STATUS = 207; |
protected constant STATUS_BAD_REQUEST = 400; |
protected constant STATUS_FORBIDDEN = 403; |
protected constant STATUS_NOT_FOUND = 404; |
protected constant STATUS_METHOD_NOT_ALLOWED = 405; |
protected constant STATUS_CONFLICT = 409; |
protected constant STATUS_PRECONDITION_FAILED = 412; |
protected constant STATUS_UNSUPPORTED_MEDIA_TYPE = 415; |
protected constant STATUS_LOCKED = 423; |
|
|
protected string webdav_mount_point; |
|
private string testdir; |
protected string testcase_dir; |
private mapping(string:string) all_locks = ([]); |
|
|
|
private Standards.URI base_uri; |
|
|
private Protocols.HTTP.Query con; |
|
|
private mapping(string:string) base_headers; |
|
|
protected mapping(string:string) current_locks; |
|
protected void create(string webdav_mount_point, |
Standards.URI base_uri, |
mapping(string:string) base_headers, |
string testdir) |
{ |
this::webdav_mount_point = webdav_mount_point; |
this::base_uri = base_uri; |
this::base_headers = base_headers; |
this::testdir = Stdio.append_path("/", testdir, "/"); |
} |
|
protected array(string) filesystem_get_dir(string path); |
|
protected int filesystem_is_dir(string path); |
|
protected int filesystem_is_file(string path); |
|
protected int filesystem_check_exists(string path); |
|
protected string filesystem_read_file(string path); |
|
|
|
protected int filesystem_check_content(string path, string expected_data) |
{ |
string actual_data = filesystem_read_file(path); |
TEST_EQUAL(actual_data, expected_data); |
return actual_data == expected_data; |
} |
|
protected int filesystem_compare_files(string first_path, string other_path) |
{ |
return filesystem_check_content(other_path, filesystem_read_file(first_path)); |
} |
|
protected class WebDAVResponse(int status, |
mapping(string:string) headers, |
string data) |
{ |
mixed `[](mixed index) { |
if (intp(index)) { |
if (index == 0) { |
return status; |
} |
if (index == 1) { |
return headers; |
} |
if (index == 2) { |
return data; |
} |
} |
return ::`[](index); |
} |
|
protected string _sprintf(int c) |
{ |
return sprintf("%O(%O, %O, %O)", this_program, status, headers, data); |
} |
} |
|
protected WebDAVResponse webdav_request(string method, |
string path, |
mapping(string:string)|void extra_headers, |
string|void data) |
{ |
mapping(string:string) headers = base_headers + ([]); |
|
if (extra_headers) { |
headers += extra_headers; |
} |
|
array(string) lock_paths = ({ path }); |
|
|
string new_uri = m_delete(headers, "new-uri"); |
if (new_uri) { |
if (lower_case(method) == "copy") { |
|
lock_paths = ({ new_uri }); |
} else { |
lock_paths += ({ new_uri }); |
} |
|
if (has_prefix(new_uri, "/")) { |
new_uri = new_uri[1..]; |
} |
new_uri = map((new_uri/"/"), Protocols.HTTP.percent_encode) * "/"; |
Standards.URI dest_uri = Standards.URI(new_uri, base_uri); |
dest_uri->password = dest_uri->password = ""; |
headers["destination"] = (string)dest_uri; |
} |
|
string if_header = ""; |
multiset(string) locks = (<>); |
if (current_locks) { |
foreach(lock_paths, string dir) { |
while(1) { |
string lock_token = current_locks[dir]; |
if (lock_token && !locks[lock_token]) { |
string path = map((dir/"/"), Protocols.HTTP.percent_encode) * "/"; |
if (has_prefix(path, "/")) { |
path = path[1..]; |
} |
path = Standards.URI(path, base_uri)->path; |
if_header += sprintf("<%s>(<%s>)", path, lock_token); |
locks[lock_token] = 1; |
} |
if (dir == "/") { |
break; |
} |
dir = dirname(dir); |
} |
} |
if ((lower_case(method) == "move") || |
(lower_case(method) == "copy") || |
(lower_case(method) == "delete")) { |
foreach(indices(current_locks), string path) { |
foreach(lock_paths, string dir) { |
string lock_token = current_locks[path]; |
if (has_prefix(path, dir + "/") && !locks[lock_token]) { |
if (has_prefix(path, "/")) { |
path = path[1..]; |
} |
path = map((path/"/"), Protocols.HTTP.percent_encode) * "/"; |
path = Standards.URI(path, base_uri)->path; |
if_header += sprintf("<%s>(<%s>)", path, lock_token); |
locks[lock_token] = 1; |
} |
} |
} |
} |
if (sizeof(if_header)) { |
headers->if = if_header; |
} |
} |
if (has_prefix(path, "/")) { |
path = path[1..]; |
} |
|
path = map((path/"/"), Protocols.HTTP.percent_encode) * "/"; |
Standards.URI url = Standards.URI(path, base_uri); |
con = Protocols.HTTP.do_method(method, url, UNDEFINED, headers, con, data); |
|
report_debug("Webdav: %s %O (url: %O) ==> code: %d\n", |
method, path, url, con?con->status:600); |
|
if (!con) { |
return WebDAVResponse(600, ([]), "" ); |
} |
|
return WebDAVResponse(con->status, con->headers, con->data()); |
} |
|
private mapping(string:string) make_lock_header(mapping(string:string) locks) |
{ |
string if_header = ""; |
foreach(locks; string path; string lock_token) { |
if (has_prefix(path, "/")) { |
path = path[1..]; |
} |
path = map((path / "/"), Protocols.HTTP.percent_encode) * "/"; |
path = Standards.URI(path, base_uri)->path; |
if_header += sprintf("<%s>(<%s>)", path, lock_token); |
} |
return (["if" : if_header]); |
} |
|
private WebDAVResponse do_webdav_get(string method, |
string path, |
int expected_status_code) |
{ |
ASSERT_TRUE(method == "GET" || method == "HEAD"); |
WebDAVResponse res = |
webdav_request(method, path); |
ASSERT_EQUAL(res->status, expected_status_code); |
return res; |
} |
|
|
protected WebDAVResponse webdav_get(string path, int expected_status_code) |
{ |
return do_webdav_get("GET", path, expected_status_code); |
} |
|
protected WebDAVResponse webdav_head(string path, int expected_status_code) |
{ |
return do_webdav_get("HEAD", path, expected_status_code); |
} |
|
protected WebDAVResponse webdav_put(string path, |
string data, |
int expected_status_code, |
mapping(string:string)|void headers) |
{ |
WebDAVResponse res = |
webdav_request("PUT", path, headers, data); |
ASSERT_EQUAL(res->status, expected_status_code); |
if ( (res->status >= 200) && (res->status < 300) ) { |
ASSERT_CALL_TRUE(filesystem_check_content, path, data); |
} |
return res; |
} |
|
protected WebDAVResponse webdav_lock(string path, |
mapping(string:string) locks, |
int expected_status_code) |
{ |
string lock_info = #" |
<?xml version='1.0' encoding='utf-8'?> |
<DAV:lockinfo xmlns:DAV='DAV:'> |
<DAV:locktype><DAV:write/></DAV:locktype> |
<DAV:lockscope><DAV:exclusive/></DAV:lockscope> |
</DAV:lockinfo> |
"; |
WebDAVResponse res = |
webdav_request("LOCK", path, UNDEFINED, lock_info); |
if (res[0] == 200 && res[1]["lock-token"]) { |
locks[path] = res[1]["lock-token"]; |
all_locks[path] = res[1]["lock-token"]; |
} |
ASSERT_EQUAL(res->status, expected_status_code); |
return res; |
} |
|
protected void low_unlock(string path, mapping(string:string) locks) |
{ |
m_delete(locks, path); |
m_delete(all_locks, path); |
} |
|
protected void low_recursive_unlock(string path, mapping(string:string) locks) |
{ |
foreach(indices(locks), string lock_path) { |
if (has_prefix(lock_path, path)) { |
low_unlock(lock_path, locks); |
} |
} |
foreach(indices(all_locks), string lock_path) { |
if (has_prefix(lock_path, path)) { |
low_unlock(lock_path, locks); |
} |
} |
} |
|
protected void webdav_unlock_all() |
{ |
foreach (all_locks; string path; string lock) { |
webdav_request("UNLOCK", path, ([ "lock-token": lock ])); |
} |
} |
|
protected WebDAVResponse webdav_unlock(string path, |
mapping(string:string) locks, |
int expected_status_code) |
{ |
WebDAVResponse res = |
webdav_request("UNLOCK", path, ([ |
"lock-token": locks[path], |
])); |
ASSERT_EQUAL(res->status, expected_status_code); |
if ((res[0] >= 200) && (res[0] < 300)) { |
low_unlock(path, locks); |
} |
return res; |
} |
|
protected WebDAVResponse webdav_delete(string path, |
mapping(string:string) locks, |
int expected_status_code, |
mapping(string:string)|void headers) |
{ |
WebDAVResponse res = |
webdav_request("DELETE", path, headers); |
ASSERT_EQUAL(res->status, expected_status_code); |
if ((res[0] >= 200) && (res[0] < 300) && (res[0] != STATUS_MULTI_STATUS) ){ |
low_recursive_unlock(path, locks); |
ASSERT_CALL_FALSE(filesystem_check_exists, path); |
} |
return res; |
} |
|
protected WebDAVResponse webdav_copy(string src_path, |
string dst_path, |
int expected_status_code) |
{ |
WebDAVResponse res = |
webdav_request("COPY", src_path, ([ |
"new-uri": dst_path, |
])); |
ASSERT_EQUAL(res->status, expected_status_code); |
if ( (res->status >= 200) && (res->status < 300) ) { |
if (filesystem_is_file(src_path)) { |
ASSERT_TRUE(filesystem_compare_files(src_path, dst_path)); |
} else if (filesystem_is_dir(src_path)) { |
|
} else { |
error("Probably a bug in the test code."); |
|
} |
} |
return res; |
} |
|
protected WebDAVResponse webdav_move(string src_path, |
string dst_path, |
mapping(string:string) locks, |
int expected_status_code) |
{ |
bool src_equals_dst = false; |
if (case_sensitive()) { |
src_equals_dst = Unicode.normalize(utf8_to_string(src_path), "NFC") == |
Unicode.normalize(utf8_to_string(dst_path), "NFC"); |
} else { |
src_equals_dst = lower_case(Unicode.normalize(utf8_to_string(src_path), "NFC")) == |
lower_case(Unicode.normalize(utf8_to_string(dst_path), "NFC")); |
} |
string expected_content; |
bool is_regular_file = filesystem_is_file(src_path); |
if (is_regular_file) { |
expected_content = filesystem_read_file(src_path); |
} |
WebDAVResponse res = |
webdav_request("MOVE", src_path, ([ |
"new-uri": dst_path, |
])); |
if (locks) { |
low_recursive_unlock(src_path, locks); |
} |
ASSERT_EQUAL(res->status, expected_status_code); |
if ( (res->status >= 200) && (res->status < 300) && res->status != 207) { |
|
ASSERT_CALL_TRUE(filesystem_check_exists, dst_path); |
if (is_regular_file) { |
ASSERT_CALL_TRUE(filesystem_check_content, dst_path, expected_content); |
} |
ASSERT_CALL_EQUAL(src_equals_dst, filesystem_check_exists, src_path); |
} |
return res; |
} |
|
protected WebDAVResponse webdav_mkcol(string path, |
int|void expected_status_code) |
{ |
expected_status_code = expected_status_code ? expected_status_code : |
STATUS_CREATED; |
WebDAVResponse res = |
webdav_request("MKCOL", path); |
ASSERT_EQUAL(res->status, expected_status_code); |
return res; |
} |
|
|
protected array(Parser.XML.Tree.AbstractNode) get_nodes_from_response( |
string element, string data) |
{ |
ASSERT_TRUE("DAV:href" == element || "DAV:response" == element); |
Parser.XML.Tree.SimpleRootNode root_node = |
Parser.XML.Tree.simple_parse_input(data); |
array(Parser.XML.Tree.AbstractNode) multistatus_nodes = |
root_node->get_elements("DAV:multistatus", true); |
TEST_TRUE(sizeof(multistatus_nodes) > 0); |
array(Parser.XML.Tree.AbstractNode) response_nodes = |
Array.flatten(multistatus_nodes->get_elements("DAV:response", true)); |
if (element == "DAV:response") { |
return response_nodes; |
} |
TEST_TRUE(sizeof(response_nodes) > 0); |
array(Parser.XML.Tree.AbstractNode) href_nodes = |
Array.flatten(response_nodes->get_elements("DAV:href", true)); |
TEST_TRUE(sizeof(href_nodes) > 0); |
return href_nodes; |
} |
|
|
protected array(string) get_values_from_response(string element, string data) |
{ |
ASSERT_EQUAL("DAV:href", element); |
array(Parser.XML.Tree.AbstractNode) href_nodes = |
get_nodes_from_response(element, data); |
array(string) hrefs = map(map(href_nodes->value_of_node(), |
Protocols.HTTP.percent_decode), |
utf8_to_string); |
return hrefs; |
} |
|
private int|WebDAVResponse do_webdav_ls(string path, |
array(string) expected, |
bool new_style, |
int|void expected_status_code) |
{ |
expected_status_code = expected_status_code ? expected_status_code : |
STATUS_MULTI_STATUS; |
string propfind = #" |
<?xml version='1.0' encoding='utf-8'?> |
<DAV:propfind xmlns:DAV='DAV:'> |
<DAV:propname/> |
</DAV:propfind> |
"; |
WebDAVResponse res = |
webdav_request("PROPFIND", path, UNDEFINED, propfind); |
|
report_debug("Webdav: propfind result: %d\n%O\n", res[0], res[2]); |
|
if (new_style) { |
ASSERT_EQUAL(res->status, expected_status_code); |
} else { |
TEST_TRUE(res[0] >= 200 && res[0] < 300); |
} |
if (res[0] < 200 || res[0] > 300) { |
return 0; |
} |
array(string) hrefs = get_values_from_response("DAV:href", res->data); |
array(string) actual = Array.flatten(map(hrefs, |
lambda(string href) { |
|
string webdav_mp = webdav_mount_point; |
if (!has_suffix(webdav_mp, "/")) { |
webdav_mp += "/"; |
} |
return array_sscanf(href, "%*s"+webdav_mp+"%s"); |
})); |
|
array(string) expected_ = map(expected, |
lambda(string path) { return has_prefix(path, "/") ? path[1..] : path; }); |
|
actual = filter(actual, lambda(string str) { return sizeof(str) > 0; }); |
expected_ = filter(expected_, lambda(string str) { return sizeof(str) > 0; }); |
expected_ = map(expected_, Unicode.normalize, "NFC"); |
if (new_style) { |
ASSERT_EQUAL(sort(expected_), sort(actual)); |
return res; |
} |
TEST_EQUAL(sort(expected_), sort(actual)); |
return equal(sort(expected_), sort(actual)); |
} |
|
protected WebDAVResponse webdav_ls(string path, |
array(string) expected, |
int|void expected_status_code) |
{ |
return [object(WebDAVResponse)] |
do_webdav_ls(path, expected, true, expected_status_code); |
} |
|
protected bool case_sensitive() |
{ |
string sysname = System.uname()->sysname; |
if (sysname == "Darwin") { |
return false; |
} |
if (has_value(sysname, "Win32")) { |
return false; |
} |
return true; |
} |
|
protected void prepare_testdir(string testdir) |
{ |
testdir = has_suffix(testdir, "/") ? testdir[..<1] : testdir; |
report_debug("Webdav: Test dir is: %O\n", testdir); |
|
|
|
|
|
|
webdav_request("DELETE", testdir); |
webdav_request("MKCOL", testdir); |
webdav_ls(testdir+"/", ({ testdir+"/" })); |
} |
|
|
protected void before_testcase(string testcase) |
{ |
this::testcase_dir = Stdio.append_path(this::testdir, testcase, "/"); |
prepare_testdir(this::testcase_dir); |
} |
|
protected void after_testcase(string testcase) |
{ |
webdav_unlock_all(); |
} |
|
|
|
public void run() |
{ |
mixed e = catch { |
ASSERT_CALL(prepare_testdir, this::testdir); |
array(mixed) testcases = indices(this); |
if (getenv("TEST_CASE")) { |
testcases = ({ getenv("TEST_CASE") }); |
} |
foreach (testcases, mixed testcase) { |
if (stringp(testcase) && |
has_prefix((string) testcase, "test_") && |
!Parent::this[testcase]) |
{ |
mixed e2 = catch { |
ASSERT_CALL(before_testcase, testcase); |
|
report_debug("Webdav: Running testcase: %O\n", testcase); |
TEST_CALL(this[testcase]); |
ASSERT_CALL(after_testcase, testcase); |
}; |
} |
|
} |
}; |
} |
|
protected mapping(string:string) make_filenames(string dir, |
string filename, |
string|void unicode_method, |
bool|void apply_string_to_utf8) |
{ |
ASSERT_NOT_EQUAL(filename, lower_case(filename)); |
ASSERT_NOT_EQUAL(filename, upper_case(filename)); |
mapping(string:string) filenames = |
(["mc" : filename, |
"lc" : lower_case(filename), |
"uc" : upper_case(filename)]); |
if (unicode_method) { |
filenames = map(filenames, Unicode.normalize, unicode_method); |
} |
if (apply_string_to_utf8) { |
filenames = map(filenames, string_to_utf8); |
} |
|
return map(filenames, lambda(string filename) { |
return Stdio.append_path(dir, filename); |
}); |
} |
|
protected void verify_lock_token(WebDAVResponse res) |
{ |
ASSERT_TRUE((res->status == STATUS_LOCKED) || |
(res->status == STATUS_MULTI_STATUS)); |
|
|
ASSERT_CALL_TRUE(has_value, res->data, "lock-token-submitted"); |
} |
|
protected void verify_multistatus_response_when_resource_locked( |
WebDAVResponse res, |
array(string) locked_files) |
{ |
ASSERT_EQUAL(res->status, STATUS_MULTI_STATUS); |
foreach (locked_files, string file) { |
ASSERT_CALL_TRUE(has_value, res->data, file); |
} |
array(Parser.XML.Tree.AbstractNode) response_nodes = |
get_nodes_from_response("DAV:response", res->data); |
foreach (locked_files, string file) { |
bool href_found = false; |
foreach (response_nodes, Parser.XML.Tree.AbstractNode response_node) { |
Parser.XML.Tree.AbstractNode href_node = |
response_node->get_first_element("DAV:href", true); |
string href = utf8_to_string(Protocols.HTTP.percent_decode( |
href_node->value_of_node())); |
if (has_suffix(href, file)) { |
href_found = true; |
Parser.XML.Tree.AbstractNode status_node = |
response_node->get_first_element("DAV:status", true); |
string status = status_node->value_of_node(); |
ASSERT_TRUE(has_suffix, status, STATUS_LOCKED); |
break; |
} |
} |
ASSERT_TRUE(href_found); |
} |
ASSERT_EQUAL(sizeof(locked_files), sizeof(response_nodes)); |
} |
|
|
public void test_basics() |
{ |
int webdav_put(string path, string data) |
{ |
WebDAVResponse res = |
webdav_request("PUT", path, UNDEFINED, data); |
|
if (!((res[0] >= 200) && (res[0] < 300))) { |
return 0; |
} |
|
return filesystem_check_content(path, data); |
}; |
|
int webdav_lock(string path, mapping(string:string) locks) |
{ |
string lock_info = #" |
<?xml version='1.0' encoding='utf-8'?> |
<DAV:lockinfo xmlns:DAV='DAV:'> |
<DAV:locktype><DAV:write/></DAV:locktype> |
<DAV:lockscope><DAV:exclusive/></DAV:lockscope> |
</DAV:lockinfo> |
"; |
|
WebDAVResponse res = |
webdav_request("LOCK", path, UNDEFINED, lock_info); |
|
if (res[0] != 200) return 0; |
|
if (!res[1]["lock-token"]) return 0; |
|
locks[path] = res[1]["lock-token"]; |
all_locks[path] = res[1]["lock-token"]; |
return 1; |
}; |
|
int webdav_unlock(string path, mapping(string:string) locks) |
{ |
WebDAVResponse res = |
webdav_request("UNLOCK", path, ([ |
"lock-token": locks[path], |
])); |
|
if (!((res[0] >= 200) && (res[0] < 300))) return 0; |
|
low_unlock(path, locks); |
return 1; |
}; |
|
int webdav_ls(string path, array(string) expected) |
{ |
return [int] do_webdav_ls(path, expected, false); |
}; |
|
int webdav_delete(string path, mapping(string:string) locks) |
{ |
WebDAVResponse res = |
webdav_request("DELETE", path); |
|
if (!((res[0] >= 200) && (res[0] < 300))) return 0; |
|
low_recursive_unlock(path, locks); |
return !filesystem_check_exists(path); |
}; |
|
int webdav_copy(string src_path, string dst_path) |
{ |
WebDAVResponse res = |
webdav_request("COPY", src_path, ([ |
"new-uri": dst_path, |
])); |
|
if (!((res[0] >= 200) && (res[0] < 300))) return 0; |
|
return filesystem_compare_files(src_path, dst_path); |
}; |
|
int webdav_move(string src_path, |
string dst_path, |
mapping(string:string) locks) |
{ |
string expected_content = filesystem_read_file(src_path); |
|
WebDAVResponse res = |
webdav_request("MOVE", src_path, ([ |
"new-uri": dst_path, |
])); |
|
if (!((res[0] >= 200) && (res[0] < 300))) { |
return 0; |
} |
|
low_recursive_unlock(src_path, locks); |
|
return TEST_CALL_TRUE(filesystem_check_exists, dst_path) && |
TEST_CALL_TRUE(filesystem_check_content, dst_path, expected_content) && |
!TEST_CALL_FALSE(filesystem_check_exists, src_path); |
}; |
|
int webdav_mkcol(string path) |
{ |
WebDAVResponse res = |
webdav_request("MKCOL", path); |
|
return (res[0] >= 200) && (res[0] < 300); |
}; |
|
|
string testdir = this::testcase_dir; |
|
mapping(string:string) locks = ([]); |
|
|
TEST_CALL_TRUE(webdav_put, testdir+"test_file.txt", "TEST FILE\n"); |
|
|
TEST_CALL_TRUE(webdav_ls, testdir, ({ testdir, |
testdir+"test_file.txt" })); |
|
|
TEST_CALL_TRUE(webdav_lock, testdir+"test_file.txt", locks); |
TEST_CALL_FALSE(webdav_lock, testdir+"test_file.txt", ([])); |
TEST_CALL_FALSE(webdav_put, testdir+"test_file.txt", "TEST FILE 2\n"); |
TEST_CALL_FALSE(webdav_delete, testdir+"test_file.txt", locks); |
current_locks = locks + ([]); |
TEST_CALL_TRUE(webdav_put, testdir+"test_file.txt", "TEST FILE 3\n"); |
TEST_CALL_TRUE(webdav_unlock, testdir+"test_file.txt", locks); |
TEST_CALL_FALSE(webdav_put, testdir+"test_file.txt", "TEST FILE 4\n"); |
current_locks = locks + ([]); |
TEST_CALL_TRUE(webdav_put, testdir+"test_file.txt", "TEST FILE 5\n"); |
TEST_CALL_TRUE(webdav_lock, testdir+"test_file.txt", locks); |
TEST_CALL_FALSE(webdav_delete, testdir+"test_file.txt", locks); |
current_locks = locks + ([]); |
TEST_CALL_TRUE(webdav_delete, testdir+"test_file.txt", locks); |
TEST_CALL_FALSE(webdav_put, testdir+"test_file.txt", "TEST FILE 6\n"); |
current_locks = locks + ([]); |
TEST_CALL_TRUE(webdav_put, testdir+"test_file.txt", "TEST FILE 7\n"); |
TEST_CALL_TRUE(webdav_delete, testdir+"test_file.txt", locks); |
|
|
TEST_CALL_TRUE(webdav_mkcol, testdir+"test_dir"); |
TEST_CALL_TRUE(webdav_mkcol, testdir+"test_dir/sub_dir"); |
TEST_CALL_TRUE(webdav_put, testdir+"test_dir/test_file.txt", "TEST FILE\n"); |
|
TEST_CALL_TRUE(webdav_lock, testdir+"test_dir/test_file.txt", locks); |
TEST_CALL_FALSE(webdav_move, testdir+"test_dir/test_file.txt", testdir+"test_file.txt", locks); |
TEST_CALL_TRUE(webdav_copy, testdir+"test_dir/test_file.txt", testdir+"test_file.txt"); |
TEST_CALL_FALSE(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt"); |
current_locks = locks + ([]); |
TEST_CALL_TRUE(webdav_move, testdir+"test_dir/test_file.txt", testdir+"test_file_2.txt", locks); |
|
TEST_CALL_FALSE(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt"); |
current_locks = locks + ([]); |
TEST_CALL_TRUE(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt"); |
TEST_CALL_TRUE(webdav_lock, testdir+"test_dir/test_file.txt", locks); |
TEST_CALL_FALSE(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt"); |
current_locks = locks + ([]); |
TEST_CALL_TRUE(webdav_copy, testdir+"test_file.txt", testdir+"test_dir/test_file.txt"); |
TEST_CALL_TRUE(webdav_unlock, testdir+"test_dir/test_file.txt", locks); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void test_mkcol_dir_already_exist() |
{ |
string dir = Stdio.append_path(this::testcase_dir, "mydir"); |
webdav_mkcol(dir, STATUS_CREATED); |
webdav_mkcol(dir, STATUS_METHOD_NOT_ALLOWED); |
} |
|
|
|
public void test_mkcol_unsupported_request_entity_type() |
{ |
WebDAVResponse res = |
webdav_request("MKCOL", |
Stdio.append_path(this::testcase_dir, "foo"), |
([ "Content-type" : "application/json; charset=\"utf-8\"" ]), |
Standards.JSON.encode((["foo": ({ "fizz", "buzz" })]), |
Standards.JSON.PIKE_CANONICAL)); |
ASSERT_EQUAL(res->status, STATUS_UNSUPPORTED_MEDIA_TYPE); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void test_mkcol_intermediate_collection_missing() |
{ |
string dir = Stdio.append_path(this::testcase_dir, "missing_col", "new_col"); |
|
webdav_mkcol(dir, STATUS_CONFLICT); |
} |
|
|
|
public void test_mkcol_no_message_body() |
{ |
string dir = Stdio.append_path(this::testcase_dir, "mydir"); |
webdav_mkcol(dir, STATUS_CREATED); |
webdav_ls(dir, ({ dir })); |
ASSERT_CALL_TRUE(filesystem_is_dir, dir); |
ASSERT_CALL_EQUAL( ({ }), filesystem_get_dir, dir); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void do_test_get_non_existing_collection(function webdav_f ) |
{ |
webdav_f(Stdio.append_path(this::testcase_dir, "non-existing-collection"), |
STATUS_NOT_FOUND); |
} |
|
public void test_get_non_existing_collection() |
{ |
do_test_get_non_existing_collection(webdav_get); |
} |
|
private void do_test_get_empty_collection(function webdav_f ) |
{ |
WebDAVResponse res = webdav_f(this::testcase_dir, STATUS_OK); |
|
} |
|
|
public void test_get_empty_collection() |
{ |
do_test_get_empty_collection(webdav_get); |
} |
|
private void do_test_get_collection(function webdav_f ) |
{ |
webdav_put(Stdio.append_path(this::testcase_dir, "index.html"), |
"Hello world!", |
STATUS_CREATED); |
WebDAVResponse res = webdav_get(this::testcase_dir, STATUS_OK); |
|
res = webdav_f(Stdio.append_path(this::testcase_dir, "index.html"), |
STATUS_OK); |
|
webdav_mkcol(Stdio.append_path(this::testcase_dir, "mydir"), |
STATUS_CREATED); |
webdav_put(Stdio.append_path(this::testcase_dir, "mydir", "index.html"), |
"Hello in mydir!", |
STATUS_CREATED); |
res = webdav_f(Stdio.append_path(this::testcase_dir), |
STATUS_OK); |
|
} |
|
|
public void test_get_collection() |
{ |
do_test_get_collection(webdav_get); |
} |
|
public void test_head_non_existing_collection() |
{ |
do_test_get_non_existing_collection(webdav_head); |
} |
|
|
public void test_head_empty_collection() |
{ |
do_test_get_empty_collection(webdav_head); |
} |
|
|
public void test_head_collection() |
{ |
do_test_get_collection(webdav_head); |
} |
|
|
|
|
|
|
|
|
public void test_locks_deleted_when_resource_deleted_1() |
{ |
|
string path = Stdio.append_path(this::testcase_dir, "myfile.txt"); |
webdav_put(path, "My content", STATUS_CREATED); |
mapping(string:string) locks = ([]); |
webdav_lock(path, locks, STATUS_OK); |
webdav_put(path, "New content", STATUS_LOCKED); |
|
current_locks = locks + ([]); |
webdav_delete(path, locks, STATUS_NO_CONTENT); |
|
webdav_put(path, "New content", STATUS_PRECONDITION_FAILED); |
current_locks = ([ ]); |
|
webdav_put(path, "New content", STATUS_CREATED); |
} |
|
public void test_locks_deleted_when_resource_deleted_2() |
{ |
|
string dir = Stdio.append_path(this::testcase_dir, "mydir"); |
webdav_mkcol(dir, STATUS_CREATED); |
mapping(string:string) locks = ([]); |
webdav_lock(dir, locks, STATUS_OK); |
string subdir = Stdio.append_path(dir, "subdir"); |
webdav_mkcol(subdir, STATUS_LOCKED); |
|
current_locks = locks + ([]); |
webdav_delete(dir, locks, STATUS_NO_CONTENT); |
|
webdav_mkcol(dir, STATUS_PRECONDITION_FAILED); |
|
current_locks = locks + ([]); |
webdav_mkcol(dir, STATUS_CREATED); |
webdav_mkcol(subdir, STATUS_CREATED); |
} |
|
public void test_locks_deleted_when_resource_deleted_3() |
{ |
|
|
string dir = Stdio.append_path(this::testcase_dir, "mydir"); |
string file = Stdio.append_path(dir, "myfile.txt"); |
webdav_mkcol(dir, STATUS_CREATED); |
webdav_put(file, "My content", STATUS_CREATED); |
mapping(string:string) locks = ([]); |
webdav_lock(file, locks, STATUS_OK); |
webdav_put(file, "New content", STATUS_LOCKED); |
|
current_locks = locks + ([]); |
webdav_delete(dir, locks, STATUS_NO_CONTENT); |
|
|
|
|
webdav_ls(this::testcase_dir, ({ this::testcase_dir })); |
webdav_mkcol(dir, STATUS_CREATED); |
|
webdav_put(file, "New content", STATUS_PRECONDITION_FAILED); |
current_locks = locks + ([]); |
webdav_put(file, "New content", STATUS_CREATED); |
} |
|
|
|
|
|
|
public void test_delete() |
{ |
string dir = this::testcase_dir; |
webdav_get(dir, STATUS_OK); |
webdav_head(dir, STATUS_OK); |
webdav_ls(dir, ({ dir })); |
webdav_delete(dir, ([ ]), STATUS_NO_CONTENT); |
webdav_get(dir, STATUS_NOT_FOUND); |
webdav_head(dir, STATUS_NOT_FOUND); |
webdav_ls(dir, ({ }), STATUS_NOT_FOUND); |
} |
|
|
|
|
|
|
|
|
public void test_delete_using_invalid_depth_header() |
{ |
foreach (({"invalid-value", "0", "1"}), string depth) { |
WebDAVResponse res = webdav_request("DELETE", |
this::testcase_dir, |
([ "Depth" : depth ])); |
ASSERT_EQUAL(res->status, STATUS_BAD_REQUEST); |
} |
WebDAVResponse res = webdav_request("DELETE", |
this::testcase_dir, |
([ "Depth" : "infinity" ])); |
ASSERT_EQUAL(res->status, STATUS_NO_CONTENT); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void test_delete_fails_partly() |
{ |
string dir = this::testcase_dir; |
string file = Stdio.append_path(dir, "file1.txt"); |
string file_locked = Stdio.append_path(dir, "file2.txt"); |
webdav_put(file, "My content", STATUS_CREATED); |
webdav_put(file_locked, "My content 2", STATUS_CREATED); |
webdav_lock(file_locked, ([]), STATUS_OK); |
WebDAVResponse res = webdav_delete(dir, ([]), STATUS_MULTI_STATUS); |
verify_multistatus_response_when_resource_locked(res, ({ file_locked })); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void test_put_on_existing_file() |
{ |
string file = Stdio.append_path(this::testcase_dir, "myfile.txt"); |
webdav_put(file, "My content", STATUS_CREATED); |
WebDAVResponse res = webdav_get(file, STATUS_OK); |
ASSERT_EQUAL(res->data, "My content"); |
webdav_put(file, "New content", STATUS_OK); |
res = webdav_get(file, STATUS_OK); |
ASSERT_EQUAL(res->data, "New content"); |
} |
|
|
|
|
public void test_put_when_parent_collection_missing() |
{ |
string file = Stdio.append_path(this::testcase_dir, |
"non_existing_collection", |
"myfile"); |
webdav_put(file, "My content", STATUS_CONFLICT); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void test_put_on_existing_collection() |
{ |
string dir = this::testcase_dir; |
ASSERT_CALL_TRUE(filesystem_is_dir, dir); |
webdav_put(dir, "My content", STATUS_METHOD_NOT_ALLOWED); |
} |
|
|
|
|
|
|
|
|
|
public void test_copy_with_missing_destination_header() |
{ |
WebDAVResponse res = webdav_request("COPY", this::testcase_dir); |
ASSERT_EQUAL(res->status, STATUS_BAD_REQUEST); |
} |
|
|
|
|
|
public void test_copy_file_to_new_collection() |
{ |
string src_dir = Stdio.append_path(this::testcase_dir, "srcdir"); |
string dst_dir = Stdio.append_path(this::testcase_dir, "dstdir"); |
string src_file = Stdio.append_path(src_dir, "myfile.txt"); |
string dst_file = Stdio.append_path(dst_dir, "copy_of_myfile.txt"); |
webdav_mkcol(src_dir, STATUS_CREATED); |
webdav_mkcol(dst_dir, STATUS_CREATED); |
webdav_put(src_file, "My content", STATUS_CREATED); |
webdav_copy(src_file, dst_file, STATUS_CREATED); |
} |
|
public void test_copy_file_to_same_collection() |
{ |
string src_file = Stdio.append_path(this::testcase_dir, "myfile.txt"); |
string dst_file = Stdio.append_path(this::testcase_dir, "copy_of_myfile.txt"); |
webdav_put(src_file, "My content", STATUS_CREATED); |
webdav_copy(src_file, dst_file, STATUS_CREATED); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void do_test_copy_col(string|void depth) |
{ |
ASSERT_TRUE(!depth || depth == "0" || depth == "infinity"); |
string A = Stdio.append_path(this::testcase_dir, "A"); |
array(string) directories = |
({ |
A, |
Stdio.append_path(A, "X"), |
Stdio.append_path(A, "X", "Y"), |
}); |
array(string) files = |
({ |
Stdio.append_path(A, "file.txt"), |
Stdio.append_path(A, "X", "x_file.txt"), |
Stdio.append_path(A, "X", "Y", "y_file.txt"), |
}); |
foreach(directories, string dir) { |
webdav_mkcol(dir, STATUS_CREATED); |
} |
foreach (files, string file) { |
webdav_put(file, "Some content", STATUS_CREATED); |
} |
string B = Stdio.append_path(this::testcase_dir, "B"); |
WebDAVResponse res = |
webdav_request("COPY", A, |
([ "new-uri": B ]) + ( depth ? ([ "Depth" : depth ]) : ([]) ) |
); |
ASSERT_EQUAL(res->status, STATUS_CREATED); |
array(string) expected; |
if (!depth || depth == "infinity") { |
expected = map(directories + files, replace, "/A", "/B"); |
} else if (depth == "0") { |
expected = ({ B }); |
} |
webdav_ls(B, expected); |
|
webdav_ls(A, directories + files); |
} |
|
|
|
public void test_copy_col_no_depth_header() |
{ |
do_test_copy_col(UNDEFINED); |
} |
|
|
|
|
|
|
public void test_copy_col_depth_header_infinity() |
{ |
do_test_copy_col("infinity"); |
} |
|
|
|
|
public void test_copy_col_depth_header_0() |
{ |
do_test_copy_col("0"); |
} |
|
|
|
public void test_copy_col_does_not_cause_recursion() |
{ |
string A = Stdio.append_path(this::testcase_dir); |
string AB = Stdio.append_path(A, "B"); |
WebDAVResponse res = webdav_request("COPY", A, |
([ "new-uri": AB, |
"Depth" : "infinity" ])); |
ASSERT_EQUAL(res->status, STATUS_FORBIDDEN); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void do_test_copy_dir_to_existing_dir(string method, |
string|void overwrite) |
{ |
ASSERT_TRUE(method == "COPY" || method == "MOVE"); |
ASSERT_TRUE(!overwrite || overwrite == "T"); |
mapping(string:string) headers = ([]); |
if (overwrite) { |
headers = ([ "Overwrite" : overwrite ]); |
} |
|
string dir1 = Stdio.append_path(testcase_dir, "dir1"); |
string file1 = Stdio.append_path(dir1, "file1.txt"); |
string dir2 = Stdio.append_path(testcase_dir, "dir2"); |
string file2 = Stdio.append_path(dir2, "file2.txt"); |
webdav_mkcol(dir1, STATUS_CREATED); |
webdav_mkcol(dir2, STATUS_CREATED); |
webdav_put(file1, "Content 1", STATUS_CREATED); |
webdav_put(file2, "Content 2", STATUS_CREATED); |
mapping(string:string) locks = ([]); |
webdav_lock(dir2, locks, STATUS_OK); |
WebDAVResponse res = webdav_request(method, dir1, |
([ "new-uri": dir2 ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_LOCKED); |
verify_lock_token(res); |
current_locks = locks; |
res = webdav_request(method, dir1, |
([ "new-uri": dir2 ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_NO_CONTENT); |
if (method == "COPY") { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
dir1, |
file1, |
dir2, |
Stdio.append_path(dir2, "file1.txt") })); |
} else { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
dir2, |
Stdio.append_path(dir2, "file1.txt") })); |
} |
} |
|
private void do_test_copy_file_to_existing_file(string method, |
string|void overwrite) |
{ |
ASSERT_TRUE(method == "COPY" || method == "MOVE"); |
ASSERT_TRUE(!overwrite || overwrite == "T"); |
mapping(string:string) headers = ([]); |
if (overwrite) { |
headers = ([ "Overwrite" : overwrite ]); |
} |
|
string file1 = Stdio.append_path(testcase_dir, "file1.txt"); |
string file2 = Stdio.append_path(testcase_dir, "file2.txt"); |
webdav_put(file1, "Content 1", STATUS_CREATED); |
webdav_put(file2, "Content 2", STATUS_CREATED); |
mapping(string:string) locks = ([]); |
webdav_lock(file2, locks, STATUS_OK); |
WebDAVResponse res = webdav_request(method, file1, |
([ "new-uri": file2 ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_LOCKED); |
verify_lock_token(res); |
current_locks = locks; |
res = webdav_request(method, file1, |
([ "new-uri": file2 ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_NO_CONTENT); |
ASSERT_TRUE(filesystem_compare_files, file1, file2); |
ASSERT_TRUE(filesystem_check_content, file2, "Content 1"); |
if (method == "COPY") { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
file1, |
file2 })); |
} else { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
file2 })); |
} |
} |
|
private void do_test_copy_file_to_existing_dir(string method, |
string|void overwrite) |
{ |
ASSERT_TRUE(method == "COPY" || method == "MOVE"); |
ASSERT_TRUE(!overwrite || overwrite == "T"); |
mapping(string:string) headers = ([]); |
if (overwrite) { |
headers = ([ "Overwrite" : overwrite ]); |
} |
|
string dir = Stdio.append_path(testcase_dir, "mydir"); |
string file = Stdio.append_path(testcase_dir, "myfile.txt"); |
webdav_mkcol(dir, STATUS_CREATED); |
ASSERT_CALL_TRUE(filesystem_is_dir, dir); |
ASSERT_CALL_FALSE(filesystem_is_file, dir); |
webdav_put(file, "My content", STATUS_CREATED); |
mapping(string:string) locks = ([]); |
webdav_lock(dir, locks, STATUS_OK); |
WebDAVResponse res = webdav_request(method, file, |
([ "new-uri": dir ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_LOCKED); |
verify_lock_token(res); |
current_locks = locks; |
res = webdav_request(method, file, |
([ "new-uri": dir ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_NO_CONTENT); |
ASSERT_CALL_TRUE(filesystem_is_file, dir); |
ASSERT_CALL_FALSE(filesystem_is_dir, dir); |
ASSERT_CALL_TRUE(filesystem_check_content, dir, "My content"); |
if (method == "COPY") { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
dir, |
file })); |
} else { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
dir })); |
} |
} |
|
private void do_test_copy_dir_to_existing_file(string method, |
string|void overwrite) |
{ |
ASSERT_TRUE(method == "COPY" || method == "MOVE"); |
ASSERT_TRUE(!overwrite || overwrite == "T"); |
mapping(string:string) headers = ([]); |
if (overwrite) { |
headers = ([ "Overwrite" : overwrite ]); |
} |
|
string dir = Stdio.append_path(testcase_dir, "mydir"); |
string file = Stdio.append_path(testcase_dir, "myfile.txt"); |
webdav_mkcol(dir, STATUS_CREATED); |
webdav_put(file, "My content", STATUS_CREATED); |
ASSERT_CALL_TRUE(filesystem_is_file, file); |
ASSERT_CALL_FALSE(filesystem_is_dir, file); |
mapping(string:string) locks = ([]); |
webdav_lock(file, locks, STATUS_OK); |
WebDAVResponse res = webdav_request(method, dir, |
([ "new-uri": file ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_LOCKED); |
verify_lock_token(res); |
current_locks = locks + ([]); |
res = webdav_request(method, dir, |
([ "new-uri": file ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_NO_CONTENT); |
ASSERT_CALL_TRUE(filesystem_is_dir, file); |
ASSERT_CALL_FALSE(filesystem_is_file, file); |
if (method == "COPY") { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
dir, |
file })); |
} else { |
webdav_ls(testcase_dir, |
({ testcase_dir, |
file })); |
} |
} |
|
|
public void test_copy_file_to_existing_file_1() |
{ |
do_test_copy_file_to_existing_file("COPY", UNDEFINED); |
} |
|
|
public void test_copy_file_to_existing_dir_1() |
{ |
do_test_copy_file_to_existing_dir("COPY", UNDEFINED); |
} |
|
|
public void test_copy_dir_to_existing_file_1() |
{ |
do_test_copy_dir_to_existing_file("COPY", UNDEFINED); |
} |
|
|
public void test_copy_dir_to_existing_dir_1() |
{ |
do_test_copy_dir_to_existing_dir("COPY", UNDEFINED); |
} |
|
|
public void test_copy_file_to_existing_file_2() |
{ |
do_test_copy_file_to_existing_file("COPY", "T"); |
} |
|
|
public void test_copy_file_to_existing_dir_2() |
{ |
do_test_copy_file_to_existing_dir("COPY", "T"); |
} |
|
|
public void test_copy_dir_to_existing_file_2() |
{ |
do_test_copy_dir_to_existing_file("COPY", "T"); |
} |
|
|
public void test_copy_dir_to_existing_dir_2() |
{ |
do_test_copy_dir_to_existing_dir("COPY", "T"); |
} |
|
private void do_test_copy_dest_exist_overwrite_header_F(string method) |
{ |
ASSERT_TRUE(method == "COPY" || method == "MOVE"); |
string dir1 = Stdio.append_path(this::testcase_dir, "mydir"); |
string dir2 = Stdio.append_path(this::testcase_dir, "my_other_dir"); |
string file1 = Stdio.append_path(this::testcase_dir, "myfile.txt"); |
string file2 = Stdio.append_path(this::testcase_dir, "my_other_file.txt"); |
webdav_mkcol(dir1, STATUS_CREATED); |
webdav_mkcol(dir2, STATUS_CREATED); |
webdav_put(file1, "Content 1", STATUS_CREATED); |
webdav_put(file2, "Content 2", STATUS_CREATED); |
foreach ( |
({ ({ dir1, dir2 }), |
({ dir1, file1 }), |
({ file1, file2 }), |
({ file1, dir1 }) }), array(string) src_and_dst ) { |
string src = src_and_dst[0]; |
string dst = src_and_dst[1]; |
WebDAVResponse res = webdav_request(method, src, |
([ "new-uri": dst, "Overwrite": "F" ])); |
ASSERT_EQUAL(res->status, STATUS_PRECONDITION_FAILED); |
} |
webdav_ls(this::testcase_dir, |
({ this::testcase_dir, dir1, dir2, file1, file2 })); |
} |
|
public void test_copy_dest_exist_overwrite_header_F() |
{ |
do_test_copy_dest_exist_overwrite_header_F("COPY"); |
} |
|
private void do_test_copy_col_fails_due_to_locked_file(string method) |
{ |
ASSERT_TRUE(method == "COPY" || method == "MOVE"); |
string src_dir = Stdio.append_path(this::testcase_dir, "A"); |
string dst_dir = Stdio.append_path(this::testcase_dir, "B"); |
string src_file1 = Stdio.append_path(src_dir, "file1.txt"); |
string src_file2 = Stdio.append_path(src_dir, "file2.txt"); |
string dst_file1 = Stdio.append_path(dst_dir, "file1.txt"); |
string dst_file2 = Stdio.append_path(dst_dir, "file2.txt"); |
webdav_mkcol(src_dir, STATUS_CREATED); |
webdav_mkcol(dst_dir, STATUS_CREATED); |
webdav_put(src_file1, "file1 in dir1", STATUS_CREATED); |
webdav_put(src_file2, "file2 in dir1", STATUS_CREATED); |
webdav_put(dst_file1, "file1 in dir2", STATUS_CREATED); |
webdav_put(dst_file2, "file2 in dir2", STATUS_CREATED); |
webdav_lock(dst_file2, ([]), STATUS_OK); |
WebDAVResponse res; |
if (method == "COPY") { |
res = webdav_copy(src_dir, dst_dir, STATUS_MULTI_STATUS); |
} else { |
res = webdav_move(src_dir, dst_dir, ([]), STATUS_MULTI_STATUS); |
} |
verify_multistatus_response_when_resource_locked(res, ({ dst_file2 })); |
|
|
|
webdav_ls(this::testcase_dir, |
({ this::testcase_dir, |
src_dir, |
src_file1, |
src_file2, |
dst_dir, |
dst_file1, |
dst_file2 })); |
ASSERT_CALL_TRUE(filesystem_check_content, dst_file2, "file2 in dir2"); |
} |
|
private void do_test_copy_col_fails_due_to_locked_non_existing_file(string method) |
{ |
ASSERT_TRUE(method == "COPY" || method == "MOVE"); |
string src_dir = Stdio.append_path(this::testcase_dir, "A"); |
string dst_dir = Stdio.append_path(this::testcase_dir, "B"); |
string src_file1 = Stdio.append_path(src_dir, "file1.txt"); |
string src_file2 = Stdio.append_path(src_dir, "file2.txt"); |
string dst_file1 = Stdio.append_path(dst_dir, "file1.txt"); |
string dst_file2 = Stdio.append_path(dst_dir, "file2.txt"); |
webdav_mkcol(src_dir, STATUS_CREATED); |
webdav_put(src_file1, "file1 in dir1", STATUS_CREATED); |
webdav_put(src_file2, "file2 in dir1", STATUS_CREATED); |
webdav_lock(dst_file2, ([]), STATUS_OK); |
WebDAVResponse res; |
if (method == "COPY") { |
res = webdav_copy(src_dir, dst_dir, STATUS_MULTI_STATUS); |
} else { |
res = webdav_move(src_dir, dst_dir, ([]), STATUS_MULTI_STATUS); |
} |
verify_multistatus_response_when_resource_locked(res, ({ dst_file2 })); |
|
|
|
|
if (method == "COPY") { |
webdav_ls(this::testcase_dir, |
({ this::testcase_dir, |
src_dir, |
src_file1, |
src_file2, |
dst_dir, |
dst_file1 })); |
ASSERT_CALL_TRUE(filesystem_check_content, dst_file1, "file1 in dir1"); |
} else { |
webdav_ls(this::testcase_dir, |
({ this::testcase_dir, |
src_dir, |
src_file1, |
src_file2 })); |
} |
ASSERT_CALL_FALSE(filesystem_check_exists, dst_file2); |
} |
|
public void test_copy_col_fails_due_to_locked_file() |
{ |
do_test_copy_col_fails_due_to_locked_file("COPY"); |
} |
|
public void test_copy_col_fails_due_to_locked_non_existing_file() |
{ |
do_test_copy_col_fails_due_to_locked_non_existing_file("COPY"); |
} |
|
|
|
|
|
|
|
|
private void do_test_copy_destination_equals_src(string method, |
string|void overwrite) |
{ |
ASSERT_TRUE(method = "COPY" || method == "MOVE"); |
ASSERT_TRUE(!overwrite || overwrite == "F" || overwrite == "T"); |
mapping(string:string) headers = ([]); |
if (overwrite) { |
headers = ([ "Overwrite" : overwrite ]); |
} |
|
|
string dir = this::testcase_dir; |
WebDAVResponse res = |
webdav_request("COPY", dir, ([ "new-uri": dir ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_FORBIDDEN); |
|
|
string file = Stdio.append_path(dir, "myfile.txt"); |
webdav_put(file, "My content", STATUS_CREATED); |
res = webdav_request("COPY", file, ([ "new-uri": file ]) + headers); |
ASSERT_EQUAL(res->status, STATUS_FORBIDDEN); |
|
webdav_ls(dir, ({ dir, file })); |
} |
|
|
|
|
public void test_copy_destination_equals_src_no_overwrite_header() |
{ |
do_test_copy_destination_equals_src("COPY", UNDEFINED); |
} |
|
public void test_copy_destination_equals_src_overwrite_header_T() |
{ |
do_test_copy_destination_equals_src("COPY", "T"); |
} |
|
public void test_copy_destination_equals_src_overwrite_header_F() |
{ |
do_test_copy_destination_equals_src("COPY", "F"); |
} |
|
|
|
|
public void test_copy_file_intermediate_destination_collection_missing() |
{ |
string file = Stdio.append_path(this::testcase_dir, "myfile.txt"); |
webdav_put(file, "My content", STATUS_CREATED); |
webdav_copy(file, |
Stdio.append_path(this::testcase_dir, |
"non-existing-dir", |
"copy-of-myfile.txt"), |
STATUS_CONFLICT); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void test_move_with_missing_destination_header() |
{ |
WebDAVResponse res = webdav_request("MOVE", this::testcase_dir); |
ASSERT_EQUAL(res->status, STATUS_BAD_REQUEST); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void do_test_move_col(string|void depth) |
{ |
ASSERT_TRUE(!depth || depth == "infinity"); |
string A = Stdio.append_path(this::testcase_dir, "A"); |
array(string) directories = |
({ |
A, |
Stdio.append_path(A, "X"), |
Stdio.append_path(A, "X", "Y"), |
}); |
array(string) files = |
({ |
Stdio.append_path(A, "file.txt"), |
Stdio.append_path(A, "X", "x_file.txt"), |
Stdio.append_path(A, "X", "Y", "y_file.txt"), |
}); |
foreach(directories, string dir) { |
webdav_mkcol(dir, STATUS_CREATED); |
} |
foreach (files, string file) { |
webdav_put(file, "Some content", STATUS_CREATED); |
} |
string B = Stdio.append_path(this::testcase_dir, "B"); |
WebDAVResponse res = webdav_request("MOVE", A, |
([ "new-uri": B ]) + |
( depth ? ([ "Depth" : depth ]) : ([]) )); |
ASSERT_EQUAL(res->status, STATUS_CREATED); |
array(string) expected = map(directories + files, replace, "/A", "/B"); |
ASSERT_CALL_TRUE(webdav_ls, B, expected); |
|
ASSERT_CALL_FALSE(webdav_ls, A, ({ }), STATUS_NOT_FOUND); |
} |
|
|
|
|
public void test_move_col_depth_header() |
{ |
do_test_move_col(UNDEFINED); |
} |
|
public void test_move_col_depth_header_infinity() |
{ |
do_test_move_col("infinity"); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void test_move_dir_to_existing_dir_1() |
{ |
do_test_copy_dir_to_existing_dir("MOVE", UNDEFINED); |
} |
|
|
public void test_move_dir_to_existing_file_1() |
{ |
do_test_copy_dir_to_existing_file( "MOVE", UNDEFINED); |
} |
|
|
public void test_move_file_to_existing_file_1() |
{ |
do_test_copy_file_to_existing_file("MOVE", UNDEFINED); |
} |
|
|
public void test_move_file_to_existing_dir_1() |
{ |
do_test_copy_file_to_existing_dir("MOVE", UNDEFINED); |
} |
|
|
public void test_move_dir_to_existing_dir_2() |
{ |
do_test_copy_dir_to_existing_dir("MOVE", "T"); |
} |
|
|
public void test_move_dir_to_existing_file_2() |
{ |
do_test_copy_dir_to_existing_file("MOVE", "T"); |
} |
|
|
public void test_move_file_to_existing_file_2() |
{ |
do_test_copy_file_to_existing_file("MOVE", "T"); |
} |
|
|
public void test_move_file_to_existing_dir_2() |
{ |
do_test_copy_file_to_existing_dir( "MOVE", "T"); |
} |
|
public void test_move_dest_exist_overwrite_header_F() |
{ |
do_test_copy_dest_exist_overwrite_header_F("MOVE"); |
} |
|
|
|
|
|
|
|
|
public void test_move_col_fails_due_to_locked_file() |
{ |
do_test_copy_col_fails_due_to_locked_file("MOVE"); |
} |
|
public void test_move_col_fails_due_to_locked_non_existing_file() |
{ |
do_test_copy_col_fails_due_to_locked_non_existing_file("MOVE"); |
} |
|
|
|
|
public void test_move_destination_equals_src_no_overwrite_header() |
{ |
do_test_copy_destination_equals_src("MOVE", UNDEFINED); |
} |
|
public void test_move_destination_equals_src_overwrite_header_T() |
{ |
do_test_copy_destination_equals_src("MOVE", "T"); |
} |
|
public void test_move_destination_equals_src_overwrite_header_F() |
{ |
do_test_copy_destination_equals_src("MOVE", "F"); |
} |
|
|
|
|
|
|
|
|
public void test_move_file_intermediate_destination_collection_missing() |
{ |
string file = Stdio.append_path(this::testcase_dir, "myfile.txt"); |
webdav_put(file, "My content", STATUS_CREATED); |
webdav_move(file, |
Stdio.append_path(this::testcase_dir, |
"non-existing-dir", |
"copy-of-myfile.txt"), |
([]), |
STATUS_CONFLICT); |
} |
|
|
|
|
|
public void test_move_src_locked() |
{ |
string src_parent = Stdio.append_path(this::testcase_dir, "parent"); |
string src = Stdio.append_path(src_parent, "src"); |
string child = Stdio.append_path(src, "child"); |
string dst = Stdio.append_path(this::testcase_dir, "dst"); |
webdav_mkcol(src_parent, STATUS_CREATED); |
webdav_mkcol(src, STATUS_CREATED); |
webdav_put(child, "Child content", STATUS_CREATED); |
foreach (({src_parent, src, child}), string resource_to_lock) { |
mapping(string:string) locks = ([]); |
webdav_lock(resource_to_lock, locks, STATUS_OK); |
WebDAVResponse res = webdav_move(src, dst, ([]), |
(resource_to_lock == child) ? |
STATUS_MULTI_STATUS: STATUS_LOCKED); |
verify_lock_token(res); |
webdav_unlock(resource_to_lock, locks, STATUS_NO_CONTENT); |
} |
WebDAVResponse res = webdav_move(src, dst, ([]), STATUS_CREATED); |
webdav_ls(this::testcase_dir, |
({ this::testcase_dir, |
src_parent, |
dst, |
Stdio.append_path(dst, "child") })); |
} |
|
|
|
|
|
public void test_move_destination_locked() |
{ |
string child_name = "child"; |
string src = Stdio.append_path(this::testcase_dir, "src"); |
string src_child = Stdio.append_path(src, child_name); |
string dst_parent = Stdio.append_path(this::testcase_dir, "dst_parent"); |
string dst = Stdio.append_path(dst_parent, "dst"); |
string dst_child = Stdio.append_path(dst, child_name); |
foreach (({src, dst_parent, dst}), string col) { |
webdav_mkcol(col, STATUS_CREATED); |
} |
webdav_put(src_child, "src child content", STATUS_CREATED); |
webdav_put(dst_child, "dst child content", STATUS_CREATED); |
foreach (({dst_parent, dst, dst_child}), string resource_to_lock) { |
mapping(string:string) locks = ([]); |
webdav_lock(resource_to_lock, locks, STATUS_OK); |
WebDAVResponse res = webdav_move(src, dst, ([]), |
(resource_to_lock == dst_child) ? |
STATUS_MULTI_STATUS:STATUS_LOCKED); |
verify_lock_token(res); |
webdav_unlock(resource_to_lock, locks, STATUS_NO_CONTENT); |
} |
WebDAVResponse res = webdav_move(src, dst, ([]), STATUS_NO_CONTENT); |
filesystem_check_content(dst_child, "src child content"); |
webdav_ls(this::testcase_dir, |
({ this::testcase_dir, |
dst_parent, |
dst, |
dst_child })); |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef WEBDAV_TEST_ASCII_ONLY |
protected constant FILENAMES = |
({ |
"myFile", |
}); |
#else |
protected constant FILENAMES = |
({ |
"myFile", |
"åÅäÄöÖæÆüÜñÑ@", |
"ąĄŁůŮăĂçÇ", |
"фщъЂЃЄЉЖ", |
"ώψφλξβΩΠΞΔ€", |
}); |
#endif |
|
|
|
|
public void test_x_ls() |
{ |
int count = 0; |
bool caseSensitive = case_sensitive(); |
int w = sizeof("" + (sizeof(FILENAMES)*2*3) ); |
foreach (FILENAMES, string str) { |
|
foreach (({"NFC", "NFD"}), string unicode_method_create) { |
foreach (({"mc", "lc", "uc"}), string case_create) { |
foreach (({"NFC", "NFD"}), string unicode_method_ls) { |
foreach (({"mc", "lc", "uc"}), string case_ls) { |
string filename = sprintf("%0"+w+"d_%s", count++, str); |
string new_dir = |
make_filenames(this::testcase_dir, filename, |
unicode_method_create, true)[case_create]; |
string new_file = |
make_filenames("", filename, unicode_method_create, |
true)[case_create]; |
string dir_ls = make_filenames(this::testcase_dir, filename, |
unicode_method_ls, true)[case_ls]; |
string file_ls = make_filenames("", filename, unicode_method_ls, |
true)[case_ls]; |
mapping(string:string) exp_dir = |
make_filenames(this::testcase_dir, filename, "NFC", false); |
mapping(string:string) exp_file = make_filenames("", filename, |
"NFC", false); |
webdav_mkcol(new_dir, STATUS_CREATED); |
if (case_create == case_ls) { |
webdav_ls(dir_ls, ({ exp_dir[case_ls] }) ); |
} else { |
webdav_ls(dir_ls, ({ exp_dir[case_ls] }), |
caseSensitive && STATUS_NOT_FOUND); |
} |
webdav_put(new_dir + "/" + new_file, "FILE " + count, STATUS_CREATED); |
if (case_create == case_ls) { |
webdav_ls(dir_ls, |
({ exp_dir[case_ls], |
exp_dir[case_ls] + "/" + exp_file[case_create] }) ); |
webdav_ls(dir_ls + "/" + file_ls, |
({ exp_dir[case_ls] + "/" + exp_file[case_create] }) ); |
} else { |
webdav_ls(dir_ls, |
caseSensitive ? |
({ }) : |
({ exp_dir[case_ls], |
exp_dir[case_ls] + "/" + exp_file[case_create] }), |
caseSensitive ? STATUS_NOT_FOUND : STATUS_MULTI_STATUS); |
webdav_ls(dir_ls + "/" + file_ls, |
caseSensitive ? |
({ }) : |
({ exp_dir[case_ls] + "/" + exp_file[case_ls] }), |
caseSensitive ? STATUS_NOT_FOUND : STATUS_MULTI_STATUS); |
} |
} |
} |
} |
} |
} |
} |
|
|
public void test_x_special_chars() |
{ |
string testdir = this::testcase_dir; |
|
|
array(string) FILENAMES = ({ " _ [](){}+-*#%&=?|$~ " }); |
foreach (FILENAMES, string file) { |
mixed e = catch { |
|
|
ASSERT_EQUAL(file, Unicode.normalize(file, "NFC")); |
ASSERT_EQUAL(file, Unicode.normalize(file, "NFD")); |
|
string dir_path = Stdio.append_path("/", testdir, file); |
string file_path = dir_path + "/" + file + ".txt"; |
report_debug("Webdav special chars test: Creating dir: %s.\n", dir_path); |
webdav_mkcol(dir_path, STATUS_CREATED); |
webdav_ls(dir_path, ({ dir_path }) ); |
webdav_put(file_path, "FILE\n", STATUS_CREATED); |
webdav_ls(dir_path, ({ dir_path, file_path }) ); |
}; |
} |
} |
|
public void test_x_put() |
{ |
int count = 0; |
bool caseSensitive = case_sensitive(); |
int w = sizeof("" + (sizeof(FILENAMES)*2*3) ); |
foreach (FILENAMES, string str) { |
|
foreach (({"NFC", "NFD"}), string unicode_method_put1) { |
foreach (({"mc", "lc", "uc"}), string case_put1) { |
foreach (({"NFC", "NFD"}), string unicode_method_put2) { |
foreach (({"mc", "lc", "uc"}), string case_put2) { |
string filename = sprintf("%0"+w+"d_%s", count++, str); |
string dir = make_filenames(this::testcase_dir, filename, |
unicode_method_put1, true)[case_put1]; |
string file1 = make_filenames(dir, filename, |
unicode_method_put1, true)[case_put1]; |
string file2 = make_filenames(dir, filename, |
unicode_method_put2, true)[case_put2]; |
string exp_dir = make_filenames(this::testcase_dir, filename, |
"NFC", false)[case_put1]; |
mapping(string:string) exp_file = make_filenames(exp_dir, filename, |
"NFC", false); |
webdav_mkcol(dir, STATUS_CREATED); |
webdav_put(file1, "FILE " + count, STATUS_CREATED); |
|
|
int expected_status_code = STATUS_CREATED; |
bool filenames_considered_equal; |
if (caseSensitive) { |
filenames_considered_equal = |
Unicode.normalize(utf8_to_string(file1), "NFC") == |
Unicode.normalize(utf8_to_string(file2), "NFC"); |
} else { |
filenames_considered_equal = |
lower_case(Unicode.normalize(utf8_to_string(file1), "NFC")) == |
lower_case(Unicode.normalize(utf8_to_string(file2), "NFC")); |
} |
if (filenames_considered_equal) { |
expected_status_code = STATUS_OK; |
} |
webdav_put(file2, "FILE 2" + count, expected_status_code); |
if (case_put1 == case_put2) { |
webdav_ls(dir, |
({ exp_dir, exp_file[case_put1] }) ); |
} else { |
webdav_ls(dir, |
caseSensitive ? |
({ exp_dir, |
exp_file[case_put1], |
exp_file[case_put2] }) : |
({ exp_dir, |
exp_file[case_put1] }) ); |
} |
} |
} |
} |
} |
} |
} |
|
|
public void test_x_copy_file() |
{ |
int count = 0; |
bool caseSensitive = case_sensitive(); |
int w = sizeof("" + (sizeof(FILENAMES)*2*3) ); |
foreach (FILENAMES, string str) { |
|
foreach (({"NFC", "NFD"}), string unicode_method_src) { |
foreach (({"mc", "lc", "uc"}), string case_src) { |
foreach (({"NFC", "NFD"}), string unicode_method_target) { |
foreach (({"mc", "lc", "uc"}), string case_target) { |
string filename = sprintf("%0"+w+"d_%s", count++, str); |
string src_file = |
make_filenames(this::testcase_dir, filename, unicode_method_src, |
true)[case_src]; |
string target_file = |
make_filenames(this::testcase_dir, filename, |
unicode_method_target, true)[case_target]; |
webdav_put(src_file, "FILE " + count, STATUS_CREATED); |
if (case_src == case_target) { |
|
|
webdav_copy(src_file, target_file, STATUS_FORBIDDEN); |
} else { |
|
webdav_copy(src_file, target_file, |
caseSensitive ? STATUS_CREATED : STATUS_FORBIDDEN); |
} |
} |
} |
} |
} |
} |
} |
|
|
public void test_x_mkcol() |
{ |
int count = 0; |
bool caseSensitive = case_sensitive(); |
int w = sizeof("" + (sizeof(FILENAMES)*2*3) ); |
foreach (FILENAMES, string str) { |
|
foreach (({"NFC", "NFD"}), string unicode_method_dir1) { |
foreach (({"mc", "lc", "uc"}), string case_dir1) { |
foreach (({"NFC", "NFD"}), string unicode_method_dir2) { |
foreach (({"mc", "lc", "uc"}), string case_dir2) { |
string filename = sprintf("%0"+w+"d_%s", count++, str); |
string dir1 = make_filenames(this::testcase_dir, filename, |
unicode_method_dir1, true)[case_dir1]; |
string dir2 = |
make_filenames(this::testcase_dir, filename, unicode_method_dir2, |
true)[case_dir2]; |
webdav_mkcol(dir1, STATUS_CREATED); |
if (case_dir1 == case_dir2) { |
|
|
webdav_mkcol(dir2, STATUS_METHOD_NOT_ALLOWED); |
} else { |
|
webdav_mkcol(dir2, |
caseSensitive ? STATUS_CREATED : STATUS_METHOD_NOT_ALLOWED); |
} |
} |
} |
} |
} |
} |
} |
|
|
public void test_x_move_file() |
{ |
int count = 0; |
bool caseSensitive = case_sensitive(); |
int w = sizeof("" + (sizeof(FILENAMES)*2*3) ); |
foreach (FILENAMES, string str) { |
|
foreach (({"NFC", "NFD"}), string unicode_method_src) { |
foreach (({"mc", "lc", "uc"}), string case_src) { |
foreach (({"NFC", "NFD"}), string unicode_method_target) { |
foreach (({"mc", "lc", "uc"}), string case_target) { |
string filename = sprintf("%0"+w+"d_%s", count++, str); |
string src_file = make_filenames(this::testcase_dir, filename, |
unicode_method_src, true)[case_src]; |
string target_file = |
make_filenames(this::testcase_dir, filename, unicode_method_target, |
true)[case_target]; |
webdav_put(src_file, "FILE " + count, STATUS_CREATED); |
mapping(string:string) locks = ([]); |
if (case_src == case_target) { |
|
|
webdav_move(src_file, target_file, locks, STATUS_FORBIDDEN); |
} else { |
|
webdav_move(src_file, target_file, locks, |
caseSensitive ? STATUS_CREATED : STATUS_NO_CONTENT); |
} |
} |
} |
} |
} |
} |
} |
|
public void test_x_lock() |
|
|
|
|
|
|
|
|
|
|
{ |
bool caseSensitive = case_sensitive(); |
array(string) cases = ({"mc", "lc", "uc"}); |
if (caseSensitive) { |
cases = ({ "mc" }); |
} |
foreach (FILENAMES, string filename) { |
foreach (({"NFC", "NFD"}), string unicode_method) { |
mapping(string:string) resources = make_filenames(this::testcase_dir, |
filename, |
unicode_method, |
true); |
string resource = resources->mc; |
string exp_name = make_filenames(this::testcase_dir, |
filename, |
"NFC", |
false)->mc; |
foreach (({"NFC", "NFD"}), string unicode_method) { |
mapping(string:string) resources = make_filenames(this::testcase_dir, |
filename, |
unicode_method, |
true); |
foreach (cases, string case_) { |
|
mapping(string:string) locks = ([]); |
webdav_lock(resource, locks, STATUS_OK); |
|
|
|
webdav_mkcol(resources[case_], STATUS_LOCKED); |
webdav_put(resources[case_], "My content", STATUS_LOCKED); |
webdav_ls(resources[case_], ({ }), STATUS_NOT_FOUND); |
webdav_delete(resources[case_], ([]), STATUS_NOT_FOUND); |
|
|
webdav_put(resource, "My content", STATUS_CREATED, |
make_lock_header(locks)); |
webdav_ls(resources[case_], ({ exp_name })); |
|
|
webdav_put(resources[case_], "New content", STATUS_LOCKED); |
webdav_delete(resources[case_], ([]), STATUS_LOCKED); |
|
string lock_token = locks[resource]; |
mapping(string:string) lock_header = |
make_lock_header(([ resources[case_] : lock_token ])); |
|
webdav_put(resources[case_], "New content", STATUS_OK, lock_header); |
|
webdav_delete(resource, ([]), STATUS_LOCKED); |
|
webdav_delete(resource, ([]), STATUS_NO_CONTENT, lock_header); |
|
|
webdav_ls(this::testcase_dir, ({ this::testcase_dir })); |
} |
} |
} |
} |
} |
|
|
|