Skip to content

Commit

Permalink
Improved search parameters handling, two basic tests, fix iwebdavclie…
Browse files Browse the repository at this point in the history
…nt typo.
  • Loading branch information
usselite authored and skazantsev committed Mar 27, 2022
1 parent 05146a0 commit e0318b7
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 16 deletions.
43 changes: 43 additions & 0 deletions src/WebDav.Client.Tests/Methods/SearchTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Linq;
using WebDav.Client.Tests.TestDoubles;
using Xunit;

namespace WebDav.Client.Tests.Methods
{
public class SearchTests
{
[Fact]
public async void When_RequestIsSuccessfull_Should_ReturnStatusCode200()
{
var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
var response1 = await client.Search(new Uri("http://example.com/"), new Request.SearchParameters()
{
SearchPath = "/root/",
SearchKeyword = "test%",
SelectProperties = new[]
{
new XElement("{DAV:}displayname"),
new XElement("{DAV:}getcontenttype")
},
WhereProperties = new[]
{
new XElement("{DAV:}displayname")
}
});

Assert.Equal(200, response1.StatusCode);
}

[Fact]
public async void When_RequestIsBadRequest_Should_ReturnStatusCode400()
{
var client = new WebDavClient().SetWebDavDispatcher(Dispatcher.Mock());
var response1 = await client.Search(new Uri("http://example.com/"), new Request.SearchParameters());
Assert.Equal(400, response1.StatusCode);
}

}
}
2 changes: 1 addition & 1 deletion src/WebDav.Client/IWebDavClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,6 @@ public interface IWebDavClient : IDisposable
/// <param name="requestUri">Request uri.</param>
/// <param name="parameters">SEARCH parameters.</param>
/// <returns></returns>
Task<WebDavResponse> Search(Uri requestUri, SearchParameters parameters)
Task<PropfindResponse> Search(Uri requestUri, SearchParameters parameters);
}
}
18 changes: 17 additions & 1 deletion src/WebDav.Client/Request/SearchParameters.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,48 @@ namespace WebDav.Client.Request
{
public class SearchParameters
{
public SearchParameters()
{
Namespaces = new List<NamespaceAttr>();
Headers = new List<KeyValuePair<string, string>>();
SelectProperties = new List<XElement>();
WhereProperties = new List<XElement>();
CancellationToken = CancellationToken.None;
}

/// <summary>
/// Root directory where to search from.
/// </summary>
public string SearchPath { get; set; }

/// <summary>
/// Keyword on what to search. For example: 'test%' (without quotes), results in LIKE test%.
/// </summary>
public string SearchKeyword { get; set; }

/// <summary>
/// Set the cancellation token.
/// </summary>
public CancellationToken CancellationToken { get; set; }

/// <summary>
/// Gets or sets the collection of xml namespaces of properties.
/// </summary>
public IReadOnlyCollection<NamespaceAttr> Namespaces { get; set; }

/// <summary>
/// Gets or sets the collection of the headers.
/// </summary>
public IReadOnlyCollection<KeyValuePair<string, string>> Headers { get; set; }

/// <summary>
/// Gets or sets the Select properties.
/// </summary>
public IReadOnlyCollection<XElement> SelectProperties { get; set; }

/// <summary>
/// Gets or sets the Where properties.
/// </summary>
public IReadOnlyCollection<XElement> WhereProperties { get; set; }

}
}
21 changes: 9 additions & 12 deletions src/WebDav.Client/Request/SearchRequestBuilder.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using WebDav.Client.Request;

namespace WebDav
{
Expand All @@ -9,20 +10,16 @@ internal static class SearchRequestBuilder
/// <summary>
/// Build the WEBDAV XML body.
/// </summary>
/// <param name="select">Set arguments to select parameters</param>
/// <param name="fromDirectory">Set root directory to search from.</param>
/// <param name="searchKeyWord">Set search keyword, e.g. 'test%' % = like.</param>
/// <param name="where">Set argument where to search for.</param>
/// <param name="namespaces">Optional, add namespaces.</param>
/// <param name="parameters">Set the SEARCH requests parameters</param>
/// <returns></returns>
public static string BuildRequestBody(IReadOnlyCollection<XElement> select, string fromDirectory, string searchKeyWord, IReadOnlyCollection<XElement> where, IReadOnlyCollection<NamespaceAttr> namespaces = null)
public static string BuildRequestBody(SearchParameters parameters)
{
var doc = new XDocument(new XDeclaration("1.0", "utf-8", null));
var searchrequest = new XElement("{DAV:}searchrequest", new XAttribute(XNamespace.Xmlns + "D", "DAV:"));
if (!string.IsNullOrEmpty(fromDirectory))
if (!string.IsNullOrEmpty(parameters.SearchPath))
{
var propBs = new XElement("{DAV:}basicsearch");
foreach (var ns in namespaces)
foreach (var ns in parameters.Namespaces)
{
var nsAttr = string.IsNullOrEmpty(ns.Prefix) ? "xmlns" : XNamespace.Xmlns + ns.Prefix;
searchrequest.SetAttributeValue(nsAttr, ns.Namespace);
Expand All @@ -32,7 +29,7 @@ public static string BuildRequestBody(IReadOnlyCollection<XElement> select, stri
var propSelect = new XElement("{DAV:}select");
var propSelectProp = new XElement("{DAV:}prop");

foreach (var prop in select)
foreach (var prop in parameters.SelectProperties)
{
propSelectProp.Add(new XElement(prop));
}
Expand All @@ -43,7 +40,7 @@ public static string BuildRequestBody(IReadOnlyCollection<XElement> select, stri
var propFrom = new XElement("{DAV:}from");
var propFromScope = new XElement("{DAV:}scope");

var propFromScopeHref = new XElement("{DAV:}href", fromDirectory);
var propFromScopeHref = new XElement("{DAV:}href", parameters.SearchPath);

//Hardcoded depth for now.
var propFromScopeDepth = new XElement("{DAV:}depth", "infinity");
Expand All @@ -58,12 +55,12 @@ public static string BuildRequestBody(IReadOnlyCollection<XElement> select, stri
var propWhereLike = new XElement("{DAV:}like");
var propWhereLikeProp = new XElement("{DAV:}prop");

foreach (var prop in where)
foreach (var prop in parameters.WhereProperties)
{
propWhereLikeProp.Add(new XElement(prop));
}

var propWhereLikeLiteral = new XElement("{DAV:}literal", searchKeyWord);
var propWhereLikeLiteral = new XElement("{DAV:}literal", parameters.SearchKeyword);

propWhereLike.Add(new XElement(propWhereLikeProp));
propWhereLike.Add(new XElement(propWhereLikeLiteral));
Expand Down
4 changes: 2 additions & 2 deletions src/WebDav.Client/WebDavClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -739,15 +739,15 @@ public async Task<WebDavResponse> Unlock(Uri requestUri, UnlockParameters parame
/// <param name="requestUri">Base URI.</param>
/// <param name="parameters">Set additional search parameters.</param>
/// <returns></returns>
public async Task<WebDavResponse> Search(Uri requestUri, SearchParameters parameters)
public async Task<PropfindResponse> Search(Uri requestUri, SearchParameters parameters)
{
Guard.NotNull(requestUri, "requestUri");

var headers = new HeaderBuilder()
.AddWithOverwrite(parameters.Headers)
.Build();

HttpContent requestBody = new StringContent(SearchRequestBuilder.BuildRequestBody(parameters.SelectProperties, parameters.SearchPath, parameters.SearchKeyword, parameters.WhereProperties, parameters.Namespaces));
HttpContent requestBody = new StringContent(SearchRequestBuilder.BuildRequestBody(parameters));

var requestParams = new RequestParameters { Headers = headers, Content = requestBody, ContentType = new MediaTypeHeaderValue("text/xml") };
var response = await _dispatcher.Send(requestUri, WebDavMethod.Search, requestParams, parameters.CancellationToken).ConfigureAwait(false);
Expand Down

0 comments on commit e0318b7

Please sign in to comment.