98 PGresult *result = PQexec(test_connection, "BEGIN"); |
97 PGresult *result = PQexec(test_connection, "BEGIN"); |
99 PQclear(result); |
98 PQclear(result); |
100 } |
99 } |
101 } |
100 } |
102 |
101 |
|
102 static void parse_response_tag(TestMultistatus *ms, xmlNode *node) { |
|
103 // thanks to dav for some of this code |
|
104 UcxAllocator *a = ms->mp->allocator; |
|
105 node = node->children; |
|
106 |
|
107 sstr_t href = {NULL, 0}; |
|
108 UcxMap *properties = ucx_map_new_a(ms->mp->allocator, 16); |
|
109 |
|
110 while(node) { |
|
111 if(node->type == XML_ELEMENT_NODE) { |
|
112 if(xstreq(node->name, "href")) { |
|
113 xmlNode *href_node = node->children; |
|
114 if(href_node->type != XML_TEXT_NODE) { |
|
115 return; |
|
116 } |
|
117 href = sstrdup_a(ms->mp->allocator, scstr((const char*)href_node->content)); |
|
118 } else if(xstreq(node->name, "propstat")) { |
|
119 xmlNode *n = node->children; |
|
120 xmlNode *prop_node = NULL; |
|
121 int status_code = 0; |
|
122 while(n) { |
|
123 if(n->type == XML_ELEMENT_NODE) { |
|
124 if(xstreq(n->name, "prop")) { |
|
125 prop_node = n; |
|
126 } else if(xstreq(n->name, "status")) { |
|
127 xmlNode *status_node = n->children; |
|
128 if(status_node->type != XML_TEXT_NODE) { |
|
129 return; |
|
130 } |
|
131 sstr_t status_str = sstr((char*)status_node->content); |
|
132 if(status_str.length < 13) { |
|
133 return; |
|
134 } |
|
135 status_str = sstrsubsl(status_str, 9, 3); |
|
136 sstr_t status_s = sstrdup(status_str); |
|
137 status_code = atoi(status_s.ptr); |
|
138 free(status_s.ptr); |
|
139 } |
|
140 } |
|
141 n = n->next; |
|
142 } |
|
143 |
|
144 n = prop_node->children; |
|
145 while(n) { |
|
146 if(n->type == XML_ELEMENT_NODE) { |
|
147 TestProperty *property = ucx_mempool_calloc(ms->mp, 1, sizeof(TestProperty)); |
|
148 if(n->ns) { |
|
149 property->prefix = n->ns->prefix ? sstrdup_a(a, scstr((const char*)n->ns->prefix)).ptr : NULL; |
|
150 property->namespace = n->ns->href ? sstrdup_a(a, scstr((const char*)n->ns->href)).ptr : NULL; |
|
151 } |
|
152 property->name = sstrdup_a(a, scstr((const char*)n->name)).ptr; |
|
153 property->node = n; |
|
154 property->status = status_code; |
|
155 xmlNode *value = n->children; |
|
156 if(value && value->type == XML_TEXT_NODE) { |
|
157 property->value = sstrdup_a(a, scstr((const char*)value->content)).ptr; |
|
158 } |
|
159 sstr_t pname = sstrcat(3, sstr(property->prefix), S(":"), sstr(property->name)); |
|
160 ucx_map_sstr_put(properties, pname, property); |
|
161 free(pname.ptr); |
|
162 } |
|
163 n = n->next; |
|
164 } |
|
165 } |
|
166 } |
|
167 node = node->next; |
|
168 } |
|
169 |
|
170 TestResponse *resp =almalloc(a, sizeof(TestResponse)); |
|
171 resp->href = href.ptr; |
|
172 resp->properties = properties; |
|
173 |
|
174 ucx_map_sstr_put(ms->responses, href, resp); |
|
175 } |
|
176 |
|
177 TestMultistatus* test_parse_multistatus(const char *space, size_t size) { |
|
178 xmlDoc *doc = xmlReadMemory(space, size, NULL, NULL, 0); |
|
179 if(!doc) { |
|
180 return NULL; |
|
181 } |
|
182 |
|
183 UcxMempool *mp = ucx_mempool_new(64); |
|
184 TestMultistatus *ms = ucx_mempool_malloc(mp, sizeof(TestMultistatus)); |
|
185 ms->doc = doc; |
|
186 ms->mp = mp; |
|
187 ms->responses = ucx_map_new_a(mp->allocator, 8); |
|
188 |
|
189 // parse response |
|
190 xmlNode *xml_root = xmlDocGetRootElement(doc); |
|
191 xmlNode *node = xml_root->children; |
|
192 while(node) { |
|
193 if(node->type == XML_ELEMENT_NODE) { |
|
194 if(xstreq(node->name, "response")) { |
|
195 parse_response_tag(ms, node); |
|
196 } |
|
197 } |
|
198 node = node->next; |
|
199 } |
|
200 |
|
201 return ms; |
|
202 } |
|
203 |
|
204 |
|
205 void test_multistatus_destroy(TestMultistatus *ms) { |
|
206 |
|
207 } |
|
208 |
|
209 |
103 UCX_TEST(test_pg_conn) { |
210 UCX_TEST(test_pg_conn) { |
104 char *msg = test_connection ? PQerrorMessage(test_connection) : "no connection"; |
211 char *msg = test_connection ? PQerrorMessage(test_connection) : "no connection"; |
105 |
212 |
106 UCX_TEST_BEGIN; |
213 UCX_TEST_BEGIN; |
107 |
214 |
462 |
569 |
463 ret = webdav_propfind(pb, sn, rq); |
570 ret = webdav_propfind(pb, sn, rq); |
464 |
571 |
465 UCX_TEST_ASSERT(ret == REQ_PROCEED, "webdav_propfind (1) failed"); |
572 UCX_TEST_ASSERT(ret == REQ_PROCEED, "webdav_propfind (1) failed"); |
466 |
573 |
467 xmlDoc *doc = xmlReadMemory( |
574 TestMultistatus *ms = test_parse_multistatus(st->buf->space, st->buf->size); |
468 st->buf->space, st->buf->size, NULL, NULL, 0); |
575 UCX_TEST_ASSERT(ms, "propfind1: response is not valid xml"); |
469 UCX_TEST_ASSERT(doc, "propfind1: response is not valid xml"); |
576 |
|
577 TestResponse *r1 = ucx_map_cstr_get(ms->responses, "/propfind/"); |
|
578 UCX_TEST_ASSERT(r1, "propfind1: missing /propfind/ response"); |
|
579 |
|
580 TestProperty *p = ucx_map_cstr_get(r1->properties, "D:resourcetype"); |
|
581 UCX_TEST_ASSERT(p, "propfind1: missing property 'resourcetype'"); |
|
582 UCX_TEST_ASSERT(p->status == 200, "propfind1: wrong status code for property 'resourcetype'"); |
|
583 |
|
584 p = ucx_map_cstr_get(r1->properties, "D:getlastmodified"); |
|
585 UCX_TEST_ASSERT(p, "propfind1: missing property 'getlastmodified'"); |
|
586 UCX_TEST_ASSERT(p->status == 200, "propfind1: wrong status code for property 'getlastmodified'"); |
470 |
587 |
471 printf("\n\n%.*s\n", (int)st->buf->size, st->buf->space); |
588 printf("\n\n%.*s\n", (int)st->buf->size, st->buf->space); |
472 |
589 |
473 |
590 |
474 testutil_destroy_session(sn); |
591 testutil_destroy_session(sn); |
475 xmlFreeDoc(doc); |
592 test_multistatus_destroy(ms); |
476 testutil_iostream_destroy(st); |
593 testutil_iostream_destroy(st); |
477 |
594 |
478 UCX_TEST_END; |
595 UCX_TEST_END; |
479 } |
596 } |