Skip to content

[PBE-0]add users batch #143

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/IStreamClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public interface IStreamClient
/// </summary>
ICollections Collections { get; }

/// <summary>
/// Returns an <see cref="IUsersBatch"/> instance that let's you interact with UsersBatch.
/// You can used the returned instance as a singleton in your application.
/// </summary>
IUsersBatch UsersBatch { get; }

/// <summary>
/// Returns an <see cref="IReactions"/> instance that let's you interact with reactions.
/// You can used the returned instance as a singleton in your application.
Expand Down Expand Up @@ -77,4 +83,4 @@ public interface IStreamClient
/// </summary>
string CreateUserToken(string userId, IDictionary<string, object> extraData = null);
}
}
}
13 changes: 13 additions & 0 deletions src/IUsersBatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Stream.Models;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Stream
{
public interface IUsersBatch
{
Task<IEnumerable<User>> UpsertUsersAsync(IEnumerable<User> users, bool overrideExisting = false);
Task<IEnumerable<User>> GetUsersAsync(IEnumerable<string> userIds);
Task<IEnumerable<string>> DeleteUsersAsync(IEnumerable<string> userIds);
}
}
23 changes: 23 additions & 0 deletions src/Models/UsersBatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Stream.Utils;
using System;
using System.Collections.Generic;

namespace Stream.Models
{
public class AddUserBatchResponse
{
public IEnumerable<User> CreatedUsers { get; set; }
}

public class GetUserBatchResponse
{
public IEnumerable<User> Users { get; set; }
}

public class DeleteUsersBatchResponse
{
public IEnumerable<string> DeletedUserIds { get; set; }
}
}
4 changes: 3 additions & 1 deletion src/StreamClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ public StreamClient(string apiKey, string apiSecretOrToken, StreamClientOptions

Batch = new BatchOperations(this);
Collections = new Collections(this);
UsersBatch = new UsersBatch(this);
Reactions = new Reactions(this);
Users = new Users(this);
Moderation = new Moderation(this);
Expand All @@ -90,6 +91,7 @@ private StreamClient(string apiKey, IToken streamClientToken, RestClient client,

public IBatchOperations Batch { get; }
public ICollections Collections { get; }
public IUsersBatch UsersBatch { get; }
public IReactions Reactions { get; }
public IUsers Users { get; }
public IPersonalization Personalization { get; }
Expand Down Expand Up @@ -244,4 +246,4 @@ internal string JWToken(string feedId, string userId = null)
return _streamClientToken.For(payload);
}
}
}
}
73 changes: 73 additions & 0 deletions src/UsersBatch.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using Stream.Models;
using Stream.Utils;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

namespace Stream
{
public class UsersBatch : IUsersBatch
{
private readonly StreamClient _client;

internal UsersBatch(StreamClient client)
{
_client = client;
}

public async Task<IEnumerable<User>> UpsertUsersAsync(IEnumerable<User> users, bool overrideExisting = false)
{
var body = new Dictionary<string, object>
{
{ "users", users },
{ "override", overrideExisting },
};
var request = _client.BuildAppRequest("users/", HttpMethod.Post);
request.SetJsonBody(StreamJsonConverter.SerializeObject(body));

var response = await _client.MakeRequestAsync(request);

if (response.StatusCode == HttpStatusCode.Created)
{
var addUserBatchResponse = StreamJsonConverter.DeserializeObject<AddUserBatchResponse>(response.Content);
return addUserBatchResponse.CreatedUsers;
}

throw StreamException.FromResponse(response);
}

public async Task<IEnumerable<User>> GetUsersAsync(IEnumerable<string> userIds)
{
var request = _client.BuildAppRequest("users/", HttpMethod.Get);
request.AddQueryParameter("ids", string.Join(",", userIds));

var response = await _client.MakeRequestAsync(request);

if (response.StatusCode == HttpStatusCode.OK)
{
var getUserBatchResponse = StreamJsonConverter.DeserializeObject<GetUserBatchResponse>(response.Content);
return getUserBatchResponse.Users;
}

throw StreamException.FromResponse(response);
}

public async Task<IEnumerable<string>> DeleteUsersAsync(IEnumerable<string> userIds)
{
var request = _client.BuildAppRequest("users/", HttpMethod.Delete);
request.AddQueryParameter("ids", string.Join(",", userIds));

var response = await _client.MakeRequestAsync(request);

if (response.StatusCode == HttpStatusCode.OK)
{
var deleteUserBatchResponse = StreamJsonConverter.DeserializeObject<DeleteUsersBatchResponse>(response.Content);
return deleteUserBatchResponse.DeletedUserIds;
}

throw StreamException.FromResponse(response);
}
}
}
79 changes: 79 additions & 0 deletions tests/UsersBatchTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using NUnit.Framework;
using Stream;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace StreamNetTests
{
[TestFixture]
public class UsersBatchTests : TestBase
{
[Test]
public async Task TestAddGetUsersAsync()
{
var userIds = new List<string> { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() };

var users = new List<User>
{
new User { Id = userIds[0], Data = new Dictionary<string, object> { { "field", "value1" } } },
new User { Id = userIds[1], Data = new Dictionary<string, object> { { "field", "value2" } } },
};

var response = await Client.UsersBatch.UpsertUsersAsync(users);

Assert.NotNull(response);
Assert.AreEqual(users.Count, response.Count());

var usersReturned = await Client.UsersBatch.GetUsersAsync(userIds);

Assert.NotNull(usersReturned);
Assert.AreEqual(userIds.Count, usersReturned.Count());
}

[Test]
public async Task TestDeleteUsersAsync()
{
var userIds = new List<string> { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() };

var deletedUserIds = await Client.UsersBatch.DeleteUsersAsync(userIds);

Assert.NotNull(deletedUserIds);
Assert.AreEqual(userIds.Count, deletedUserIds.Count());
Assert.IsTrue(userIds.All(id => deletedUserIds.Contains(id)));
}

[Test]
public async Task AddGetDeleteGetUsersAsync()
{
var userIds = new List<string> { Guid.NewGuid().ToString(), Guid.NewGuid().ToString() };

// Add users
var users = new List<User>
{
new User { Id = userIds[0], Data = new Dictionary<string, object> { { "field", "value1" } } },
new User { Id = userIds[1], Data = new Dictionary<string, object> { { "field", "value2" } } },
};

var addResponse = await Client.UsersBatch.UpsertUsersAsync(users);
Assert.NotNull(addResponse);
Assert.AreEqual(users.Count, addResponse.Count());

// Get users to confirm they were added
var getUsersResponse = await Client.UsersBatch.GetUsersAsync(userIds);
Assert.NotNull(getUsersResponse);
Assert.AreEqual(users.Count, getUsersResponse.Count());

// Delete users
var deleteResponse = await Client.UsersBatch.DeleteUsersAsync(userIds);
Assert.NotNull(deleteResponse);
Assert.AreEqual(userIds.Count(), deleteResponse.Count());
Assert.IsTrue(userIds.All(id => deleteResponse.Contains(id)));

// Attempt to get deleted users to confirm they were deleted
var getDeletedUsersResponse = await Client.UsersBatch.GetUsersAsync(userIds);
Assert.IsEmpty(getDeletedUsersResponse);
}
}
}
Loading