Skip to content

Commit

Permalink
Add support for structured metadata in GetResources Admin API
Browse files Browse the repository at this point in the history
  • Loading branch information
YomesInc authored Jul 25, 2021
1 parent dd1dffc commit 49746eb
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CloudinaryDotNet.Actions;
using NUnit.Framework;

namespace CloudinaryDotNet.IntegrationTests.AdminApi
{
public class BrowseResourcesWithStructuredMetadataTest : IntegrationTestBase
{
private const string MODERATION_MANUAL = "manual";
private static string m_contextKey;
private static string m_contextValue;
private static string m_publicId;

public override void Initialize()
{
base.Initialize();

m_contextKey = $"{m_uniqueTestId}_context_key";
m_contextValue = $"{m_uniqueTestId}_context_value";
var context = $"{m_contextKey}={m_contextValue}";

CreateMetadataField("resource_with_metadata", p => p.DefaultValue = p.Label);
var uploadResult = UploadTestImageResource(p =>
{
p.Context = new StringDictionary(context);
p.Moderation = MODERATION_MANUAL;
});

m_publicId = uploadResult.PublicId;
}

[Test, RetryWithDelay]
public async Task TestListResources()
{
var @params = new ListResourcesParams
{
};
await AssertMetadataFlagBehavior(@params);
}

[Test, RetryWithDelay]
public async Task TestListResourcesByTag()
{
var @params = new ListResourcesByTagParams
{
Tag = m_apiTag,
};
await AssertMetadataFlagBehavior(@params);
}

[Test, RetryWithDelay]
public async Task TestListResourcesByModerationStatus()
{
var @params = new ListResourcesByModerationParams
{
ModerationStatus = ModerationStatus.Pending,
ModerationKind = MODERATION_MANUAL,
};
await AssertMetadataFlagBehavior(@params);
}

[Test, RetryWithDelay]
public async Task TestListResourcesByPrefix()
{
var @params = new ListResourcesByPrefixParams
{
Type = "upload",
Prefix = m_test_prefix,
};
await AssertMetadataFlagBehavior(@params);
}

private async Task AssertMetadataFlagBehavior(ListResourcesParams @params)
{
@params.Metadata = true;
CommonAssertions(await m_cloudinary.ListResourcesAsync(@params), true);

@params.Metadata = false;
CommonAssertions(await m_cloudinary.ListResourcesAsync(@params), false);
}

private void CommonAssertions(ListResourcesResult result, bool shouldHaveMetadata)
{
Assert.IsNotNull(result);
Assert.IsNotNull(result.Resources, result.Error?.Message);

var resourceWithMetadata = result.Resources.FirstOrDefault(r => r.PublicId == m_publicId);
Assert.IsNotNull(resourceWithMetadata);

if (shouldHaveMetadata)
{
Assert.IsNotNull(resourceWithMetadata.MetadataFields);
}
else
{
Assert.IsNull(resourceWithMetadata.MetadataFields);
}
}
}
}
4 changes: 3 additions & 1 deletion CloudinaryDotNet.IntegrationTests/IntegrationTestBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -308,11 +308,13 @@ protected Task<RawUploadResult> UploadTestRawResourceAsync(
/// A convenient method for creating a structured metadata field before testing.
/// </summary>
/// <param name="fieldLabelSuffix">The distinguishable suffix.</param>
/// <param name="setParamsAction">Action to set custom metadata field parameters.</param>
/// <returns>The ExternalId of the structured metadata field.</returns>
protected string CreateMetadataField(string fieldLabelSuffix)
protected string CreateMetadataField(string fieldLabelSuffix, Action<StringMetadataFieldCreateParams> setParamsAction = null)
{
var metadataLabel = GetUniqueMetadataFieldLabel(fieldLabelSuffix);
var metadataParameters = new StringMetadataFieldCreateParams(metadataLabel);
setParamsAction?.Invoke(metadataParameters);
var metadataResult = m_cloudinary.AddMetadataField(metadataParameters);

Assert.NotNull(metadataResult, metadataResult.Error?.Message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ public class ListResourcesParams : BaseParams
/// </summary>
public bool Context { get; set; }

/// <summary>
/// Gets or sets a value indicating whether if true, include metadata assigned to each resource.
/// </summary>
public bool Metadata { get; set; }

/// <summary>
/// Gets or sets when a listing request has more results to return than <see cref="ListResourcesParams.MaxResults"/>,
/// the <see cref="NextCursor"/> value is returned as part of the response. You can then specify this value as
Expand Down Expand Up @@ -84,6 +89,7 @@ public override SortedDictionary<string, object> ToParamsDictionary()
AddParam(dict, "context", Context);
AddParam(dict, "direction", Direction);
AddParam(dict, "type", Type);
AddParam(dict, "metadata", Metadata);

return dict;
}
Expand Down
37 changes: 30 additions & 7 deletions CloudinaryDotNet/Cloudinary.AdminApi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,18 @@ public ListResourcesResult ListResources(
/// <param name="nextCursor">Starting position.</param>
/// <param name="cancellationToken">(Optional) Cancellation token.</param>
/// <returns>Parsed result of the resources listing.</returns>
public Task<ListResourcesResult> ListResourcesByTypeAsync(string type, string nextCursor = null, CancellationToken? cancellationToken = null)
public Task<ListResourcesResult> ListResourcesByTypeAsync(
string type,
string nextCursor = null,
CancellationToken? cancellationToken = null)
{
return ListResourcesAsync(new ListResourcesParams() { Type = type, NextCursor = nextCursor }, cancellationToken);
var listResourcesParams = new ListResourcesParams()
{
Type = type,
NextCursor = nextCursor,
};

return ListResourcesAsync(listResourcesParams, cancellationToken);
}

/// <summary>
Expand Down Expand Up @@ -139,7 +148,10 @@ public Task<ListResourcesResult> ListResourcesByPrefixAsync(
/// <param name="type">Resource type.</param>
/// <param name="nextCursor">Starting position.</param>
/// <returns>Parsed result of the resources listing.</returns>
public ListResourcesResult ListResourcesByPrefix(string prefix, string type = "upload", string nextCursor = null)
public ListResourcesResult ListResourcesByPrefix(
string prefix,
string type = "upload",
string nextCursor = null)
{
return ListResourcesByPrefixAsync(prefix, type, nextCursor)
.GetAwaiter().GetResult();
Expand Down Expand Up @@ -200,7 +212,10 @@ public ListResourcesResult ListResourcesByPrefix(string prefix, bool tags, bool
/// <param name="nextCursor">Starting position.</param>
/// <param name="cancellationToken">(Optional) Cancellation token.</param>
/// <returns>Parsed result of the resources listing.</returns>
public Task<ListResourcesResult> ListResourcesByTagAsync(string tag, string nextCursor = null, CancellationToken? cancellationToken = null)
public Task<ListResourcesResult> ListResourcesByTagAsync(
string tag,
string nextCursor = null,
CancellationToken? cancellationToken = null)
{
var listResourcesByTagParams = new ListResourcesByTagParams()
{
Expand All @@ -227,7 +242,9 @@ public ListResourcesResult ListResourcesByTag(string tag, string nextCursor = nu
/// <param name="publicIds">Public identifiers.</param>
/// <param name="cancellationToken">(Optional) Cancellation token.</param>
/// <returns>Parsed result of the resources listing.</returns>
public Task<ListResourcesResult> ListResourcesByPublicIdsAsync(IEnumerable<string> publicIds, CancellationToken? cancellationToken = null)
public Task<ListResourcesResult> ListResourcesByPublicIdsAsync(
IEnumerable<string> publicIds,
CancellationToken? cancellationToken = null)
{
var listSpecificResourcesParams = new ListSpecificResourcesParams()
{
Expand Down Expand Up @@ -381,9 +398,15 @@ public Task<ListResourcesResult> ListResourcesByContextAsync(
/// <param name="context">If true, include context assigned to each resource.</param>
/// <param name="nextCursor">The next cursor.</param>
/// <returns>Parsed result of the resources listing.</returns>
public ListResourcesResult ListResourcesByContext(string key, string value = "", bool tags = false, bool context = false, string nextCursor = null)
public ListResourcesResult ListResourcesByContext(
string key,
string value = "",
bool tags = false,
bool context = false,
string nextCursor = null)
{
return ListResourcesByContextAsync(key, value, tags, context, nextCursor).GetAwaiter().GetResult();
return ListResourcesByContextAsync(key, value, tags, context, nextCursor)
.GetAwaiter().GetResult();
}

/// <summary>
Expand Down

0 comments on commit 49746eb

Please sign in to comment.