Skip to content

Commit 3bc06eb

Browse files
Add support for SearchFolders API
1 parent 8aa16fa commit 3bc06eb

File tree

13 files changed

+363
-130
lines changed

13 files changed

+363
-130
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using NUnit.Framework;
2+
using SystemHttp = System.Net.Http;
3+
4+
namespace CloudinaryDotNet.Tests.SearchApi
5+
{
6+
public class SearchFoldersTest
7+
{
8+
private MockedCloudinary _cloudinary = new MockedCloudinary();
9+
10+
[SetUp]
11+
public void SetUp()
12+
{
13+
_cloudinary = new MockedCloudinary();
14+
}
15+
16+
[Test]
17+
public void TestShouldSearchFolders()
18+
{
19+
_cloudinary
20+
.SearchFolders()
21+
.Expression("path:*")
22+
.MaxResults(1)
23+
.Execute();
24+
25+
_cloudinary.AssertHttpCall(SystemHttp.HttpMethod.Post, "folders/search");
26+
27+
var requestJson = _cloudinary.RequestJson();
28+
29+
Assert.IsNotNull(requestJson["expression"]);
30+
Assert.AreEqual("path:*", requestJson["expression"].ToString());
31+
Assert.IsNotNull(requestJson["max_results"]);
32+
Assert.AreEqual("1", requestJson["max_results"].ToString());
33+
}
34+
}
35+
}

CloudinaryDotNet.Tests/SearchTest.cs renamed to CloudinaryDotNet.Tests/SearchApi/SearchTest.cs

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
using Newtonsoft.Json.Linq;
44
using NUnit.Framework;
55

6-
namespace CloudinaryDotNet.Tests
6+
namespace CloudinaryDotNet.Tests.SearchApi
77
{
88
public class SearchTest
99
{
10-
private MockedCloudinary cloudinary = new MockedCloudinary();
10+
private MockedCloudinary _cloudinary = new MockedCloudinary();
1111

12-
private Search search;
12+
private Search _search;
1313

14-
private string searchExpression = "resource_type:image AND tags=kitten AND uploaded_at>1d AND bytes>1m";
14+
private const string SearchExpression = "resource_type:image AND tags=kitten AND uploaded_at>1d AND bytes>1m";
1515

1616
private const string B64Query = "eyJleHByZXNzaW9uIjoicmVzb3VyY2VfdHlwZTppbWFnZSBBTkQgdGFncz1raXR0ZW4gQU5EIHV" +
1717
"wbG9hZGVkX2F0PjFkIEFORCBieXRlcz4xbSIsIm1heF9yZXN1bHRzIjozMCwic29ydF9ieSI6W3" +
@@ -26,16 +26,16 @@ public class SearchTest
2626
[SetUp]
2727
public void SetUp()
2828
{
29-
cloudinary = new MockedCloudinary
29+
_cloudinary = new MockedCloudinary
3030
{
3131
Api =
3232
{
3333
Secure = true
3434
}
3535
};
3636

37-
search = cloudinary.Search()
38-
.Expression(searchExpression)
37+
_search = _cloudinary.Search()
38+
.Expression(SearchExpression)
3939
.SortBy("public_id", "desc")
4040
.MaxResults(30);
4141
}
@@ -44,15 +44,15 @@ public void SetUp()
4444
[Test]
4545
public void TestSearchUrl()
4646
{
47-
Assert.AreEqual($"{SearchUrlPrefix}/{Ttl300Sig}/300/{B64Query}", search.ToUrl());
47+
Assert.AreEqual($"{SearchUrlPrefix}/{Ttl300Sig}/300/{B64Query}", _search.ToUrl());
4848
}
4949

5050
[Test]
5151
public void TestSearchUrlWithNextCursor()
5252
{
5353
Assert.AreEqual(
5454
$"{SearchUrlPrefix}/{Ttl300Sig}/300/{B64Query}/{NextCursor}",
55-
search.ToUrl(null, NextCursor)
55+
_search.ToUrl(null, NextCursor)
5656
);
5757
}
5858

@@ -61,7 +61,7 @@ public void TestSearchUrlWithCustomTtlAndNextCursor()
6161
{
6262
Assert.AreEqual(
6363
$"{SearchUrlPrefix}/{Ttl1000Sig}/1000/{B64Query}/{NextCursor}",
64-
search.ToUrl(1000, NextCursor)
64+
_search.ToUrl(1000, NextCursor)
6565
);
6666
}
6767

@@ -70,27 +70,26 @@ public void TestSearchUrlWithCustomTtlAndNextCursorSetFromTheClass()
7070
{
7171
Assert.AreEqual(
7272
$"{SearchUrlPrefix}/{Ttl1000Sig}/1000/{B64Query}/{NextCursor}",
73-
search.Ttl(1000).NextCursor(NextCursor).ToUrl()
73+
_search.Ttl(1000).NextCursor(NextCursor).ToUrl()
7474
);
7575
}
7676

7777
[Test]
7878
public void TestSearchUrlPrivateCdn()
7979
{
80-
cloudinary.Api.UsePrivateCdn = true;
80+
_cloudinary.Api.UsePrivateCdn = true;
8181

8282
Assert.AreEqual(
8383
$"https://test123-res.cloudinary.com/search/{Ttl300Sig}/300/{B64Query}",
84-
cloudinary.Search().Expression(searchExpression).SortBy("public_id", "desc")
84+
_cloudinary.Search().Expression(SearchExpression).SortBy("public_id", "desc")
8585
.MaxResults(30).ToUrl()
8686
);
8787
}
8888

89-
9089
[Test]
9190
public void TestShouldNotDuplicateValues()
9291
{
93-
cloudinary
92+
_cloudinary
9493
.Search()
9594
.SortBy("created_at", "asc")
9695
.SortBy("created_at", "desc")
@@ -103,7 +102,7 @@ public void TestShouldNotDuplicateValues()
103102
.WithField("tags")
104103
.Execute();
105104

106-
AssertCorrectRequest(cloudinary.HttpRequestContent);
105+
AssertCorrectRequest(_cloudinary.HttpRequestContent);
107106
}
108107

109108
private static void AssertCorrectRequest(string request)
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
namespace CloudinaryDotNet.Actions
2+
{
3+
using System.Runtime.Serialization;
4+
5+
/// <summary>
6+
/// The details of the folder found.
7+
/// </summary>
8+
[DataContract]
9+
public class SearchFolder
10+
{
11+
/// <summary>
12+
/// Gets or sets the name of the folder.
13+
/// </summary>
14+
[DataMember(Name = "name")]
15+
public string Name;
16+
17+
/// <summary>
18+
/// Gets or sets the path of the folder.
19+
/// </summary>
20+
[DataMember(Name = "path")]
21+
public string Path { get; set; }
22+
23+
/// <summary>
24+
/// Gets or sets date when the folder was created.
25+
/// </summary>
26+
[DataMember(Name = "created_at")]
27+
public string CreatedAt { get; set; }
28+
29+
/// <summary>
30+
/// Gets or sets the eternal id of the folder.
31+
/// </summary>
32+
[DataMember(Name = "external_id")]
33+
public string ExternalId { get; set; }
34+
}
35+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace CloudinaryDotNet.Actions
2+
{
3+
using System.Collections.Generic;
4+
using System.Runtime.Serialization;
5+
6+
/// <summary>
7+
/// Search response with information about the folders matching the search criteria.
8+
/// </summary>
9+
[DataContract]
10+
public class SearchFoldersResult : SearchResultBase
11+
{
12+
/// <summary>
13+
/// Gets or sets the details of each of the folders found.
14+
/// </summary>
15+
[DataMember(Name = "folders")]
16+
public List<SearchFolder> Folders { get; set; }
17+
}
18+
}

CloudinaryDotNet/Actions/Search/SearchResource.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ public class SearchResource
8484
[Obsolete("Property Created is deprecated, please use CreatedAt instead")]
8585
public string Created
8686
{
87-
get { return CreatedAt; }
88-
set { CreatedAt = value; }
87+
get => CreatedAt;
88+
set => CreatedAt = value;
8989
}
9090

9191
/// <summary>
@@ -100,8 +100,8 @@ public string Created
100100
[Obsolete("Property Uploaded is deprecated, please use UploadedAt instead")]
101101
public string Uploaded
102102
{
103-
get { return UploadedAt; }
104-
set { UploadedAt = value; }
103+
get => UploadedAt;
104+
set => UploadedAt = value;
105105
}
106106

107107
/// <summary>
@@ -116,8 +116,8 @@ public string Uploaded
116116
[Obsolete("Property Length is deprecated, please use Bytes instead")]
117117
public long Length
118118
{
119-
get { return Bytes; }
120-
set { Bytes = value; }
119+
get => Bytes;
120+
set => Bytes = value;
121121
}
122122

123123
/// <summary>

CloudinaryDotNet/Actions/Search/SearchResult.cs

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,14 @@
77
/// Search response with information about the assets matching the search criteria.
88
/// </summary>
99
[DataContract]
10-
public class SearchResult : BaseResult
10+
public class SearchResult : SearchResultBase
1111
{
12-
/// <summary>
13-
/// Gets or sets the total count of assets matching the search criteria.
14-
/// </summary>
15-
[DataMember(Name = "total_count")]
16-
public int TotalCount { get; set; }
17-
18-
/// <summary>
19-
/// Gets or sets the time taken to process the request.
20-
/// </summary>
21-
[DataMember(Name = "time")]
22-
public long Time { get; set; }
23-
2412
/// <summary>
2513
/// Gets or sets the details of each of the assets (resources) found.
2614
/// </summary>
2715
[DataMember(Name = "resources")]
2816
public List<SearchResource> Resources { get; set; }
2917

30-
/// <summary>
31-
/// Gets or sets when a search request has more results to return than max_results, the next_cursor value is returned as
32-
/// part of the response.
33-
/// </summary>
34-
[DataMember(Name = "next_cursor")]
35-
public string NextCursor { get; set; }
36-
3718
/// <summary>
3819
/// Gets or sets counts of assets, grouped by specified parameters.
3920
/// </summary>
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
namespace CloudinaryDotNet.Actions
2+
{
3+
using System.Runtime.Serialization;
4+
5+
/// <summary>
6+
/// Search response with information matching the search criteria.
7+
/// </summary>
8+
public class SearchResultBase : BaseResult
9+
{
10+
/// <summary>
11+
/// Gets or sets the total count of assets matching the search criteria.
12+
/// </summary>
13+
[DataMember(Name = "total_count")]
14+
public int TotalCount { get; set; }
15+
16+
/// <summary>
17+
/// Gets or sets the time taken to process the request.
18+
/// </summary>
19+
[DataMember(Name = "time")]
20+
public long Time { get; set; }
21+
22+
/// <summary>
23+
/// Gets or sets when a search request has more results to return than max_results, the next_cursor value is returned as
24+
/// part of the response.
25+
/// </summary>
26+
[DataMember(Name = "next_cursor")]
27+
public string NextCursor { get; set; }
28+
}
29+
}

CloudinaryDotNet/Cloudinary.AdminApi.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,15 @@ public Search Search()
2323
return new Search(m_api);
2424
}
2525

26+
/// <summary>
27+
/// Gets the advanced search folders provider used by the Cloudinary instance.
28+
/// </summary>
29+
/// <returns>Instance of the <see cref="SearchFolders"/> class.</returns>
30+
public SearchFolders SearchFolders()
31+
{
32+
return new SearchFolders(m_api);
33+
}
34+
2635
/// <summary>
2736
/// Lists resource types asynchronously.
2837
/// </summary>

CloudinaryDotNet/Search/Search.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace CloudinaryDotNet
2+
{
3+
/// <summary>
4+
/// Advanced search provider. Allows you to retrieve information on all the assets in your account with the help of
5+
/// query expressions in a Lucene-like query language.
6+
/// </summary>
7+
public class Search : SearchFluent<Search>
8+
{
9+
/// <summary>
10+
/// Initializes a new instance of the <see cref="Search"/> class.
11+
/// </summary>
12+
/// <param name="api">Provider of the API calls.</param>
13+
public Search(ApiShared api)
14+
: base(api)
15+
{
16+
}
17+
}
18+
}

0 commit comments

Comments
 (0)