Skip to content

Commit

Permalink
Merge 7ceaca5 into 474a382
Browse files Browse the repository at this point in the history
  • Loading branch information
ruggi committed Jul 19, 2018
2 parents 474a382 + 7ceaca5 commit 2e8fb86
Show file tree
Hide file tree
Showing 3 changed files with 275 additions and 5 deletions.
54 changes: 54 additions & 0 deletions src/lib/client.js
Expand Up @@ -604,6 +604,60 @@ StreamClient.prototype = {
}, callback);
},

updateActivityPartial: function (data, callback) {
/**
* Update a single activity with partial operations.
* @since 3.20.0
* @param {object} data object containing either the ID or the foreign ID and time of the activity and the operations to issue as set:{...} and unset:[...].
* @return {Promise}
* @example
* client.updateActivityPartial({
* id: "54a60c1e-4ee3-494b-a1e3-50c06acb5ed4",
* set: {
* "product.price": 19.99,
* "shares": {
* "facebook": "...",
* "twitter": "...",
* }
* },
* unset: [
* "daily_likes",
* "popularity"
* ]
* })
* @example
* client.updateActivityPartial({
* foreignID: "product:123",
* time: "2016-11-10T13:20:00.000000",
* set: {
* ...
* },
* unset: [
* ...
* ]
* })
*/
if (data.foreignID) {
data['foreign_id'] = data.foreignID;
delete data.foreignID;
}
if (!data.id && !(data['foreign_id'] && data.time)) {
throw new TypeError('Missing id or foreign ID and time')
}
if (data.set && !(data.set instanceof Object)) {
throw new TypeError('set field should be an Object')
}
if (data.unset && !(data.unset instanceof Array)) {
throw new TypeError('unset field should be an Array')
}
var authToken = signing.JWTScopeToken(this.apiSecret, 'activities', '*', { feedId: '*', expireTokens: this.expireTokens });
return this.post({
url: 'activity/',
body: data,
signature: authToken,
}, callback);
},

};

if (qs) {
Expand Down
100 changes: 100 additions & 0 deletions test/integration/node/client_test.js
Expand Up @@ -550,4 +550,104 @@ describe('[INTEGRATION] Stream client (Node)', function() {
});
});

describe('update activity partial', function () {
var activity, expected;

beforeEach(function (done) {
var self = this;
this.user1.addActivity({
'actor': 1,
'verb': 'test',
'object': 1,
'foreign_id': 1234,
'time': new Date(),
'shares': {
'facebook': 123,
'twitter': 2000,
},
'popularity': 50,
'color': 'blue',
}).then(function () {
return self.user1.get();
}).then(function (resp) {
activity = resp.results[0];

expected = activity;
delete expected.color;
expected.popularity = 75;
expected.shares = {
"facebook": 234,
"twitter": 2000,
"googleplus": 42
};
expected.foo = {
bar: {
baz: 999
}
};

done();
});
});

describe('by ID', function () {
it("allows to update the activity", function (done) {
var self = this;

this.client.updateActivityPartial({
id: activity['id'],
set: {
popularity: 75,
"shares.facebook": 234,
"shares.googleplus": 42,
foo: {
bar: {
baz: 999,
}
}
},
unset: [
"color",
]
}).then(function() {
self.client.getActivities({ids: [activity['id']]})
.then(function(resp) {
expect(resp.results[0]).to.eql(expected);
done();
})
})
})
});

describe('by foreign ID and time', function () {
it("allows to update the activity", function (done) {
var self = this;

this.client.updateActivityPartial({
foreignID: activity['foreign_id'],
time: activity['time'],
set: {
popularity: 75,
"shares.facebook": 234,
"shares.googleplus": 42,
foo: {
bar: {
baz: 999,
}
}
},
unset: [
"color",
]
}).then(function () {
self.client.getActivities({ ids: [activity['id']] })
.then(function (resp) {
expect(resp.results[0]).to.eql(expected);
done();
})
})
})
});
});

});
126 changes: 121 additions & 5 deletions test/unit/node/client_test.js
Expand Up @@ -129,20 +129,27 @@ describe('[UNIT] Stream Client (Node)', function() {
describe('#getActivities', function() {

it('throws', function() {
var self = this;

function isGoingToThrow1() {
this.client.getActivities({});
self.client.getActivities({});
}

function isGoingToThrow2() {
this.client.getActivities(0);
self.client.getActivities(0);
}

function isGoingToThrow3() {
this.client.getActivities(null);
self.client.getActivities(null);
}

function isGoingToThrow4() {
self.client.getActivities([]);
}

function isNotGoingToThrow() {
this.client.getActivities([]);
self.client.getActivities({ ids: [] });
self.client.getActivities({ foreignIDTimes: [] });
}

function isTypeError(err) {
Expand All @@ -152,7 +159,8 @@ describe('[UNIT] Stream Client (Node)', function() {
expect(isGoingToThrow1).to.throwException(isTypeError);
expect(isGoingToThrow2).to.throwException(isTypeError);
expect(isGoingToThrow3).to.throwException(isTypeError);
expect(isNotGoingToThrow).to.not.throw;
expect(isGoingToThrow4).to.throwException(isTypeError);
expect(isNotGoingToThrow).to.not.throwException(isTypeError);
});

describe('by ID', function() {
Expand Down Expand Up @@ -222,6 +230,114 @@ describe('[UNIT] Stream Client (Node)', function() {
});

});

describe('#updateActivityPartial', function () {

it('throws', function () {
var self = this;

function isGoingToThrow1() {
self.client.updateActivityPartial({});
}

function isGoingToThrow2() {
self.client.updateActivityPartial(0);
}

function isGoingToThrow3() {
self.client.updateActivityPartial(null);
}

function isGoingToThrow4() {
self.client.updateActivityPartial({ foreignID: "foo:bar" });
}

function isGoingToThrow5() {
self.client.updateActivityPartial({ time: "2016-11-10T13:20:00.000000" });
}

function isGoingToThrow6() {
self.client.updateActivityPartial({ id: "test", set: "wrong" });
}

function isGoingToThrow7() {
self.client.updateActivityPartial({ id: "test", unset: "wrong" });
}

function isTypeError(err) {
expect(err).to.be.a(TypeError);
}

expect(isGoingToThrow1).to.throwException(isTypeError);
expect(isGoingToThrow2).to.throwException(isTypeError);
expect(isGoingToThrow3).to.throwException(isTypeError);
expect(isGoingToThrow4).to.throwException(isTypeError);
expect(isGoingToThrow5).to.throwException(isTypeError);
expect(isGoingToThrow6).to.throwException(isTypeError);
expect(isGoingToThrow7).to.throwException(isTypeError);
});

describe('by ID', function () {

it('(1) works', function () {
var post = td.function();
td.replace(this.client, 'post', post);

var data = {id: "54a60c1e-4ee3-494b-a1e3-50c06acb5ed4", set: {"foo.bar": 42}, unset: ["baz"]};

this.client.updateActivityPartial(data);

td.verify(post(td.matchers.contains({
url: 'activity/',
}), undefined));
});

it('(2) works - callback', function () {
var post = td.function();
td.replace(this.client, 'post', post);

var data = {id: "54a60c1e-4ee3-494b-a1e3-50c06acb5ed4", set: {"foo.bar": 42}, unset: ["baz"]};
var fn = function () { };

this.client.updateActivityPartial(data, fn);

td.verify(post(td.matchers.contains({
url: 'activity/',
}), fn));
});
});

describe('by foreign ID and time', function () {

it('(1) works', function () {
var post = td.function();
td.replace(this.client, 'post', post);

var data = {foreignID: "product:123", time: "2016-11-10T13:20:00.000000", set: {"foo.bar": 42}, unset: ["baz"]};

this.client.updateActivityPartial(data);

td.verify(post(td.matchers.contains({
url: 'activity/',
}), undefined));
});

it('(2) works - callback', function () {
var post = td.function();
td.replace(this.client, 'post', post);

var data = {foreignID: "product:123", time: "2016-11-10T13:20:00.000000", set: {"foo.bar": 42}, unset: ["baz"]};
var fn = function () { };

this.client.updateActivityPartial(data, fn)

td.verify(post(td.matchers.contains({
url: 'activity/',
}), fn));
});
});

});

describe('connect', function() {

Expand Down

0 comments on commit 2e8fb86

Please sign in to comment.