diff -r e820d433f405 -r d5031c30022c src/server/test/webdav.c --- a/src/server/test/webdav.c Sat Jan 25 09:00:27 2020 +0100 +++ b/src/server/test/webdav.c Sat Jan 25 11:16:55 2020 +0100 @@ -208,7 +208,7 @@ return NULL; } - return webdav_operation_create( + return webdav_create_propfind_operation( (*out_sn), (*out_rq), &backend1, @@ -1054,3 +1054,184 @@ UCX_TEST_END; } + +/* ------------------------------------------------------------------------- + * + * PROPPATCH TESTS + * + * ------------------------------------------------------------------------ */ + +static int test_proppatch_init( + Session **out_sn, + Request **out_rq, + WebdavProppatchRequest **out_proppatch, + const char *xml) +{ + if(!webdav_is_initialized) { + if(webdav_init(NULL, NULL, NULL) != REQ_PROCEED) { + return 1; + } + webdav_is_initialized = 1; + } + + Session *sn = testutil_session(); + Request *rq = testutil_request(sn->pool, "PROPPATCH", "/"); + + int error = 0; + + WebdavProppatchRequest *proppatch = proppatch_parse( + sn, + rq, + xml, + strlen(xml), + &error); + + if(error) { + return 1; + } + + if(!proppatch || !(proppatch->set || proppatch->remove)) { + return 1; + } + + *out_sn = sn; + *out_rq = rq; + *out_proppatch = proppatch; + return 0; +} + +static WebdavOperation* test_proppatch_op1( + Session **out_sn, + Request **out_rq, + const char *xml) +{ + WebdavProppatchRequest *proppatch; + if(test_proppatch_init(out_sn, out_rq, &proppatch, xml)) { + return NULL; + } + + Multistatus *ms = multistatus_response(*out_sn, *out_rq); + if(!ms) { + return NULL; + } + // WebdavResponse is the public interface used by Backends + // for adding resources to the response + WebdavResponse *response = (WebdavResponse*)ms; + + return webdav_create_proppatch_operation( + (*out_sn), + (*out_rq), + &backend1, + proppatch, + response); +} + + +UCX_TEST(test_proppatch_msresponse) { + Session *sn; + Request *rq; + WebdavOperation *op; + + Multistatus *ms; + WebdavResource *res; + + WebdavProperty p[16]; + const char *names[] = {"a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9"}; + for(int i=0;i<8;i++) { + p[i].namespace = webdav_dav_namespace(); + p[i].name = names[i]; + p[i].lang = NULL; + p[i].value.node = NULL; + p[1].vtype = 0; + } + + UCX_TEST_BEGIN; + + op = test_proppatch_op1(&sn, &rq, TEST_PROPPATCH2); + UCX_TEST_ASSERT(op, "failed to create proppatch operation"); + + ms = (Multistatus*)op->response; + ms->proppatch = TRUE; + res = ms->response.addresource(&ms->response, "/"); + UCX_TEST_ASSERT(res, "cannot create resource 1"); + + UCX_TEST_ASSERT(!res->addproperty(res, &p[0], 200), "addproperty 1 failed"); + UCX_TEST_ASSERT(!res->addproperty(res, &p[1], 200), "addproperty 2 failed"); + UCX_TEST_ASSERT(!res->addproperty(res, &p[2], 200), "addproperty 3 failed"); + UCX_TEST_ASSERT(!res->addproperty(res, &p[3], 200), "addproperty 4 failed"); + + UCX_TEST_ASSERT(!res->close(res), "close failed"); + + MSResponse *msres = (MSResponse*)res; + UCX_TEST_ASSERT(!msres->errors, "error list not NULL"); + UCX_TEST_ASSERT(msres->plist_begin, "elm1 missing"); + UCX_TEST_ASSERT(msres->plist_begin->next, "elm2 missing"); + UCX_TEST_ASSERT(msres->plist_begin->next->next, "elm3 missing"); + UCX_TEST_ASSERT(msres->plist_begin->next->next->next, "elm4 missing"); + UCX_TEST_ASSERT(!msres->plist_begin->next->next->next->next, "count != 4"); + + UCX_TEST_END; + testutil_destroy_session(sn); +} + +UCX_TEST(test_msresponse_addproperty_with_errors) { + Session *sn; + Request *rq; + WebdavOperation *op; + + Multistatus *ms; + WebdavResource *res; + + WebdavProperty p[16]; + const char *names[] = {"a1", "a2", "a3", "a4", "a5", "a6", "a7", "a8", "a9"}; + for(int i=0;i<8;i++) { + p[i].namespace = webdav_dav_namespace(); + p[i].name = names[i]; + p[i].lang = NULL; + p[i].value.node = NULL; + p[1].vtype = 0; + } + + UCX_TEST_BEGIN; + + op = test_proppatch_op1(&sn, &rq, TEST_PROPPATCH2); + UCX_TEST_ASSERT(op, "failed to create proppatch operation"); + + ms = (Multistatus*)op->response; + ms->proppatch = TRUE; + res = ms->response.addresource(&ms->response, "/"); + UCX_TEST_ASSERT(res, "cannot create resource 1"); + + UCX_TEST_ASSERT(!res->addproperty(res, &p[0], 200), "addproperty 1 failed"); + UCX_TEST_ASSERT(!res->addproperty(res, &p[1], 200), "addproperty 2 failed"); + UCX_TEST_ASSERT(!res->addproperty(res, &p[2], 409), "addproperty 3 failed"); + UCX_TEST_ASSERT(!res->addproperty(res, &p[3], 200), "addproperty 4 failed"); + + UCX_TEST_ASSERT(!res->close(res), "close failed"); + + // all properties should have an error status code now + // 1 x 409, 3 x 424 + + MSResponse *msres = (MSResponse*)res; + + UCX_TEST_ASSERT(!msres->plist_begin, "plist not NULL"); + UCX_TEST_ASSERT(msres->errors, "error list is NULL"); + UCX_TEST_ASSERT(msres->errors->next, "second error list is missing"); + UCX_TEST_ASSERT(!msres->errors->next->next, "wrong error list size"); + + // We know that we have 2 error lists, one with status code 409 and + // the other must have 409. However we don't enforce the order of the + // error lists, therefore check both variants + if(msres->errors->status == 409) { + UCX_TEST_ASSERT(msres->errors->next->status == 424, "wrong status code in second err elm"); + UCX_TEST_ASSERT(msres->errors->begin, "missing 409 property"); + UCX_TEST_ASSERT(msres->errors->next->begin, "missing 424 properties"); + } else { + UCX_TEST_ASSERT(msres->errors->next->status == 409, "wrong status code in second err elm"); + UCX_TEST_ASSERT(msres->errors->begin, "missing 424 properties"); + UCX_TEST_ASSERT(msres->errors->next->begin, "missing 409 property"); + } + + UCX_TEST_END; + testutil_destroy_session(sn); +}