src/server/plugins/postgresql/pgtest.c

branch
webdav
changeset 313
3ad0b65ec838
parent 307
8787cb5ebab3
child 315
b608b7aa43a6
--- a/src/server/plugins/postgresql/pgtest.c	Mon Apr 25 21:40:26 2022 +0200
+++ b/src/server/plugins/postgresql/pgtest.c	Mon Apr 25 22:35:30 2022 +0200
@@ -46,8 +46,7 @@
 
 #include <libpq-fe.h>
 
-#include <libxml/tree.h>
-
+#define xstreq(a,b) xmlStrEqual(BAD_CAST a, BAD_CAST b)
 
 static char *pg_connstr = "postgresql://localhost/test1";
 static int abort_pg_tests = 0;
@@ -100,6 +99,114 @@
     }
 }
 
+static void parse_response_tag(TestMultistatus *ms, xmlNode *node) {
+    // thanks to dav for some of this code
+    UcxAllocator *a = ms->mp->allocator;
+    node = node->children;
+    
+    sstr_t href = {NULL, 0};
+    UcxMap *properties = ucx_map_new_a(ms->mp->allocator, 16);
+    
+    while(node) {
+        if(node->type == XML_ELEMENT_NODE) {
+            if(xstreq(node->name, "href")) {
+                xmlNode *href_node = node->children;
+                if(href_node->type != XML_TEXT_NODE) {
+                    return;
+                }
+                href = sstrdup_a(ms->mp->allocator, scstr((const char*)href_node->content));
+            } else if(xstreq(node->name, "propstat")) {
+                xmlNode *n = node->children;
+                xmlNode *prop_node = NULL;
+                int status_code = 0;
+                while(n) {
+                    if(n->type == XML_ELEMENT_NODE) {
+                        if(xstreq(n->name, "prop")) {
+                            prop_node = n;
+                        } else if(xstreq(n->name, "status")) {
+                            xmlNode *status_node = n->children;
+                            if(status_node->type != XML_TEXT_NODE) {
+                                return;
+                            }
+                            sstr_t status_str = sstr((char*)status_node->content);
+                            if(status_str.length < 13) {
+                                return;
+                            }
+                            status_str = sstrsubsl(status_str, 9, 3);
+                            sstr_t status_s = sstrdup(status_str);
+                            status_code = atoi(status_s.ptr);
+                            free(status_s.ptr);
+                        }
+                    }    
+                    n = n->next;
+                }
+                
+                n = prop_node->children;
+                while(n) {
+                    if(n->type == XML_ELEMENT_NODE) {
+                        TestProperty *property = ucx_mempool_calloc(ms->mp, 1, sizeof(TestProperty));
+                        if(n->ns) {
+                            property->prefix = n->ns->prefix ? sstrdup_a(a, scstr((const char*)n->ns->prefix)).ptr : NULL;
+                            property->namespace = n->ns->href ? sstrdup_a(a, scstr((const char*)n->ns->href)).ptr : NULL;
+                        }
+                        property->name = sstrdup_a(a, scstr((const char*)n->name)).ptr;
+                        property->node = n;
+                        property->status = status_code;
+                        xmlNode *value = n->children;
+                        if(value && value->type == XML_TEXT_NODE) {
+                            property->value = sstrdup_a(a, scstr((const char*)value->content)).ptr;
+                        }
+                        sstr_t pname = sstrcat(3, sstr(property->prefix), S(":"), sstr(property->name));
+                        ucx_map_sstr_put(properties, pname, property);
+                        free(pname.ptr);
+                    }
+                    n = n->next;
+                }
+            }
+        }
+        node = node->next;
+    }
+    
+    TestResponse *resp =almalloc(a, sizeof(TestResponse));
+    resp->href = href.ptr;
+    resp->properties = properties;
+    
+    ucx_map_sstr_put(ms->responses, href, resp);
+}
+
+TestMultistatus* test_parse_multistatus(const char *space, size_t size) {
+    xmlDoc *doc = xmlReadMemory(space, size, NULL, NULL, 0);
+    if(!doc) {
+        return NULL;
+    }
+    
+    UcxMempool *mp = ucx_mempool_new(64);
+    TestMultistatus *ms = ucx_mempool_malloc(mp, sizeof(TestMultistatus));
+    ms->doc = doc;
+    ms->mp = mp;
+    ms->responses = ucx_map_new_a(mp->allocator, 8);
+    
+    // parse response
+    xmlNode *xml_root = xmlDocGetRootElement(doc);
+    xmlNode *node = xml_root->children;
+    while(node) {
+        if(node->type == XML_ELEMENT_NODE) {
+            if(xstreq(node->name, "response")) {
+                parse_response_tag(ms, node);
+            }
+        }
+        node = node->next;
+    }
+    
+    return ms;
+}
+
+
+void test_multistatus_destroy(TestMultistatus *ms) {
+    
+}
+
+
 UCX_TEST(test_pg_conn) {
     char *msg = test_connection ? PQerrorMessage(test_connection) : "no connection";
     
@@ -464,15 +571,25 @@
     
     UCX_TEST_ASSERT(ret == REQ_PROCEED, "webdav_propfind (1) failed");
     
-    xmlDoc *doc = xmlReadMemory(
-            st->buf->space, st->buf->size, NULL, NULL, 0);
-    UCX_TEST_ASSERT(doc, "propfind1: response is not valid xml");
+    TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size);
+    UCX_TEST_ASSERT(ms, "propfind1: response is not valid xml");
+    
+    TestResponse *r1 = ucx_map_cstr_get(ms->responses, "/propfind/");
+    UCX_TEST_ASSERT(r1, "propfind1: missing /propfind/ response");
+    
+    TestProperty *p = ucx_map_cstr_get(r1->properties, "D:resourcetype");
+    UCX_TEST_ASSERT(p, "propfind1: missing property 'resourcetype'");
+    UCX_TEST_ASSERT(p->status == 200, "propfind1: wrong status code for property 'resourcetype'");
+    
+    p = ucx_map_cstr_get(r1->properties, "D:getlastmodified");
+    UCX_TEST_ASSERT(p, "propfind1: missing property 'getlastmodified'");
+    UCX_TEST_ASSERT(p->status == 200, "propfind1: wrong status code for property 'getlastmodified'");
     
     printf("\n\n%.*s\n", (int)st->buf->size, st->buf->space);
     
     
     testutil_destroy_session(sn);
-    xmlFreeDoc(doc);
+    test_multistatus_destroy(ms);
     testutil_iostream_destroy(st);
     
     UCX_TEST_END;

mercurial