Skip to content

Commit 8b79a60

Browse files
Merge pull request #606 from cloudinary/structured-metadata-rules-api
feat: exposing structured metadata rules api
2 parents 966b0f5 + fa2315a commit 8b79a60

File tree

7 files changed

+293
-11
lines changed

7 files changed

+293
-11
lines changed

lib-es5/api.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,4 +768,32 @@ exports.reorder_metadata_fields = function reorder_metadata_fields(order_by, dir
768768
options.content_type = "json";
769769
var params = { order_by, direction };
770770
return call_api("put", ["metadata_fields", "order"], params, callback, options);
771+
};
772+
773+
exports.list_metadata_rules = function list_metadata_rules(callback) {
774+
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
775+
776+
return call_api('get', ['metadata_rules'], {}, callback, options);
777+
};
778+
779+
exports.add_metadata_rule = function add_metadata_rule(metadata_rule, callback) {
780+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
781+
782+
options.content_type = 'json';
783+
var params = pickOnlyExistingValues(metadata_rule, 'metadata_field_id', 'condition', 'result', 'name');
784+
return call_api('post', ['metadata_rules'], params, callback, options);
785+
};
786+
787+
exports.update_metadata_rule = function update_metadata_rule(field_external_id, updated_metadata_rule, callback) {
788+
var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
789+
790+
options.content_type = 'json';
791+
var params = pickOnlyExistingValues(updated_metadata_rule, 'metadata_field_id', 'condition', 'result', 'name', 'state');
792+
return call_api('put', ['metadata_rules', field_external_id], params, callback, options);
793+
};
794+
795+
exports.delete_metadata_rule = function delete_metadata_rule(field_external_id, callback) {
796+
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
797+
798+
return call_api('delete', ['metadata_rules', field_external_id], {}, callback, options);
771799
};

lib-es5/v2/api.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,9 @@ v1_adapters(exports, api, {
6666
delete_datasource_entries: 2,
6767
restore_metadata_field_datasource: 2,
6868
order_metadata_field_datasource: 3,
69-
reorder_metadata_fields: 2
69+
reorder_metadata_fields: 2,
70+
list_metadata_rules: 1,
71+
add_metadata_rule: 1,
72+
delete_metadata_rule: 1,
73+
update_metadata_rule: 2
7074
});

lib/api.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,3 +616,23 @@ exports.reorder_metadata_fields = function reorder_metadata_fields(order_by, dir
616616
const params = { order_by, direction };
617617
return call_api("put", ["metadata_fields", "order"], params, callback, options);
618618
};
619+
620+
exports.list_metadata_rules = function list_metadata_rules(callback, options = {}) {
621+
return call_api('get', ['metadata_rules'], {}, callback, options);
622+
};
623+
624+
exports.add_metadata_rule = function add_metadata_rule(metadata_rule, callback, options = {}) {
625+
options.content_type = 'json';
626+
const params = pickOnlyExistingValues(metadata_rule, 'metadata_field_id', 'condition', 'result', 'name');
627+
return call_api('post', ['metadata_rules'], params, callback, options);
628+
};
629+
630+
exports.update_metadata_rule = function update_metadata_rule(field_external_id, updated_metadata_rule, callback, options = {}) {
631+
options.content_type = 'json';
632+
const params = pickOnlyExistingValues(updated_metadata_rule, 'metadata_field_id', 'condition', 'result', 'name', 'state');
633+
return call_api('put', ['metadata_rules', field_external_id], params, callback, options);
634+
};
635+
636+
exports.delete_metadata_rule = function delete_metadata_rule(field_external_id, callback, options = {}) {
637+
return call_api('delete', ['metadata_rules', field_external_id], {}, callback, options);
638+
};

lib/v2/api.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,5 +64,9 @@ v1_adapters(exports, api, {
6464
delete_datasource_entries: 2,
6565
restore_metadata_field_datasource: 2,
6666
order_metadata_field_datasource: 3,
67-
reorder_metadata_fields: 2
67+
reorder_metadata_fields: 2,
68+
list_metadata_rules: 1,
69+
add_metadata_rule: 1,
70+
delete_metadata_rule: 1,
71+
update_metadata_rule: 2
6872
});

test/integration/api/admin/structured_metadata_spec.js

Lines changed: 96 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const assert = require('assert');
12
const Q = require('q');
23
const sinon = require('sinon');
34
const cloudinary = require("../../../../cloudinary");
@@ -96,14 +97,16 @@ describe("structured metadata api", function () {
9697
// Create the metadata fields required for the tests
9798
return Q.allSettled(
9899
metadata_fields_to_create.map(field => createMetadataFieldForTest(field))
99-
).finally(function () {});
100+
).finally(function () {
101+
});
100102
});
101103

102104
after(function () {
103105
// Delete all metadata fields created during testing
104106
return Q.allSettled(
105107
metadata_fields_external_ids.map(field => api.delete_metadata_field(field))
106-
).finally(function () {});
108+
).finally(function () {
109+
});
107110
});
108111

109112
describe("list_metadata_fields", function () {
@@ -123,7 +126,7 @@ describe("structured metadata api", function () {
123126
it("should return metadata field by external id", function () {
124127
return api.metadata_field_by_field_id(EXTERNAL_ID_GENERAL)
125128
.then((result) => {
126-
expect([result, { label: EXTERNAL_ID_GENERAL }]).to.beAMetadataField();
129+
expect([result, {label: EXTERNAL_ID_GENERAL}]).to.beAMetadataField();
127130
});
128131
});
129132
});
@@ -174,7 +177,10 @@ describe("structured metadata api", function () {
174177
expect(result).to.beAMetadataField();
175178
return api.metadata_field_by_field_id(EXTERNAL_ID_DATE);
176179
}).then((result) => {
177-
expect([result, { ...metadata, mandatory: false }]).to.beAMetadataField();
180+
expect([result, {
181+
...metadata,
182+
mandatory: false
183+
}]).to.beAMetadataField();
178184
});
179185
});
180186
it("should create enum metadata field", function () {
@@ -195,7 +201,7 @@ describe("structured metadata api", function () {
195201
sinon.assert.calledWith(writeSpy, sinon.match(helper.apiJsonParamMatcher('external_id', EXTERNAL_ID_ENUM)));
196202
sinon.assert.calledWith(writeSpy, sinon.match(helper.apiJsonParamMatcher('type', 'enum')));
197203
sinon.assert.calledWith(writeSpy, sinon.match(helper.apiJsonParamMatcher('label', EXTERNAL_ID_ENUM)));
198-
sinon.assert.calledWith(writeSpy, sinon.match(helper.apiJsonParamMatcher('datasource', { values: datasource_single })));
204+
sinon.assert.calledWith(writeSpy, sinon.match(helper.apiJsonParamMatcher('datasource', {values: datasource_single})));
199205
});
200206
});
201207
it("should create set metadata field", function () {
@@ -251,7 +257,7 @@ describe("structured metadata api", function () {
251257

252258
describe("update_metadata_field_datasource", function () {
253259
it("should update metadata field datasource by external id", function () {
254-
return api.update_metadata_field_datasource(EXTERNAL_ID_ENUM_2, { values: datasource_single })
260+
return api.update_metadata_field_datasource(EXTERNAL_ID_ENUM_2, {values: datasource_single})
255261
.then(() => api.metadata_field_by_field_id(EXTERNAL_ID_ENUM_2))
256262
.then((result) => {
257263
expect(result.datasource).to.beADatasource();
@@ -283,7 +289,7 @@ describe("structured metadata api", function () {
283289
expect(result.message).to.eql("ok");
284290
return api.add_metadata_field(metadata);
285291
})
286-
.catch(({ error }) => {
292+
.catch(({error}) => {
287293
expect(error).not.to.be(void 0);
288294
expect(error.http_code).to.eql(400);
289295
expect(error.message).to.contain(`external id ${EXTERNAL_ID_DELETE_2} already exists`);
@@ -393,7 +399,7 @@ describe("structured metadata api", function () {
393399
.then((result) => {
394400
expect(result).to.beAMetadataField();
395401
return api.metadata_field_by_field_id(EXTERNAL_ID_INT_VALIDATION_2);
396-
}).catch(({ error }) => {
402+
}).catch(({error}) => {
397403
expect(error).not.to.be(void 0);
398404
expect(error.http_code).to.eql(400);
399405
expect(error.message).to.contain(`default_value is invalid`);
@@ -509,4 +515,86 @@ describe("structured metadata api", function () {
509515
})
510516
});
511517
});
518+
519+
describe('rules', () => {
520+
it('should allow listing metadata rules', () => {
521+
const expectedPath = '/metadata_rules';
522+
return helper.provideMockObjects(function (mockXHR, writeSpy, requestSpy) {
523+
api.list_metadata_rules();
524+
sinon.assert.calledWith(requestSpy, sinon.match({
525+
pathname: sinon.match(new RegExp(expectedPath)),
526+
method: sinon.match('GET')
527+
}));
528+
});
529+
});
530+
531+
it('should allow adding new metadata rules', () => {
532+
const expectedPath = '/metadata_rules';
533+
return helper.provideMockObjects(function (mockXHR, writeSpy, requestSpy) {
534+
const newMetadataRule = {
535+
metadata_field_id: 'field_id',
536+
name: 'rule_name',
537+
condition: {},
538+
result: {}
539+
};
540+
api.add_metadata_rule(newMetadataRule);
541+
542+
sinon.assert.calledWith(requestSpy, sinon.match({
543+
pathname: sinon.match(new RegExp(expectedPath)),
544+
method: sinon.match('POST')
545+
}));
546+
547+
sinon.assert.calledOnce(writeSpy);
548+
549+
const firstCallArgs = JSON.parse(writeSpy.firstCall.args[0]);
550+
assert.deepStrictEqual(firstCallArgs, {
551+
metadata_field_id: 'field_id',
552+
name: 'rule_name',
553+
condition: {},
554+
result: {}
555+
});
556+
});
557+
});
558+
559+
it('should allow editing metadata rules', () => {
560+
const expectedPath = '/metadata_rules/some-metadata-rule-id';
561+
return helper.provideMockObjects(function (mockXHR, writeSpy, requestSpy) {
562+
const ruleUpdate = {
563+
metadata_field_id: 'new_field_id',
564+
name: 'new_rule_name',
565+
condition: {},
566+
result: {},
567+
state: 'inactive'
568+
};
569+
api.update_metadata_rule('some-metadata-rule-id', ruleUpdate);
570+
571+
sinon.assert.calledWith(requestSpy, sinon.match({
572+
pathname: sinon.match(new RegExp(expectedPath)),
573+
method: sinon.match('PUT')
574+
}));
575+
576+
sinon.assert.calledOnce(writeSpy);
577+
578+
const firstCallArgs = JSON.parse(writeSpy.firstCall.args[0]);
579+
assert.deepStrictEqual(firstCallArgs, {
580+
metadata_field_id: 'new_field_id',
581+
name: 'new_rule_name',
582+
condition: {},
583+
result: {},
584+
state: 'inactive'
585+
});
586+
});
587+
});
588+
589+
it('should allow removing existing metadata rules', () => {
590+
const expectedPath = '/metadata_rules/some-metadata-rule-id';
591+
return helper.provideMockObjects(function (mockXHR, writeSpy, requestSpy) {
592+
api.delete_metadata_rule('some-metadata-rule-id');
593+
sinon.assert.calledWith(requestSpy, sinon.match({
594+
pathname: sinon.match(new RegExp(expectedPath)),
595+
method: sinon.match('DELETE')
596+
}));
597+
});
598+
});
599+
});
512600
});

types/cloudinary_ts_spec.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,52 @@ cloudinary.v2.api.update_metadata_field_datasource('EXTERNAL_ID_GET_LIST1', data
663663
cloudinary.v2.api.delete_datasource_entries('EXTERNAL_ID_DELETE_DATASOURCE_ENTRIES', ['size_2'])
664664
.then((res)=>{console.log(res)})
665665

666+
cloudinary.v2.api.add_metadata_rule({
667+
metadata_field_id: 'EXTERNAL_ID_GET_LIST',
668+
name: 'rule-name',
669+
condition: {
670+
metadata_field_id: 'EXTERNAL_ID_GET_LIST',
671+
populated: true,
672+
},
673+
result: {
674+
enable: true,
675+
activate_values: 'all',
676+
},
677+
}).then((result) => {
678+
console.log(result);
679+
}).catch((error) => {
680+
console.error(error);
681+
});
682+
683+
cloudinary.v2.api.list_metadata_rules().then((rules) => {
684+
console.log(rules);
685+
}).catch((error) => {
686+
console.error(error);
687+
});
688+
689+
cloudinary.v2.api.update_metadata_rule('RULE_EXTERNAL_ID', {
690+
metadata_field_id: 'EXTERNAL_ID_GET_LIST',
691+
name: 'rule-name',
692+
condition: {
693+
metadata_field_id: 'EXTERNAL_ID_GET_LIST',
694+
populated: true,
695+
},
696+
result: {
697+
enable: true,
698+
activate_values: 'all',
699+
},
700+
}).then((updatedRule) => {
701+
console.log(updatedRule);
702+
}).catch((error) => {
703+
console.error(error);
704+
})
705+
706+
cloudinary.v2.api.delete_metadata_rule('RULE_EXTERNAL_ID').then((result) => {
707+
console.log(result);
708+
}).catch((error) => {
709+
console.error(error);
710+
});
711+
666712
// $ExpectType Promise<any>
667713
cloudinary.v2.uploader.add_context('alt=Animal|class=Mammalia', ['dog', 'lion'],
668714
function (error, result) {

0 commit comments

Comments
 (0)