Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
10 changes: 9 additions & 1 deletion src/Clients/IUserClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,19 @@ public interface IUserClient
Task<GenericUserResponse> ReactivateAsync(string id, bool restoreMessages = false, string name = null, string createdById = null);

/// <summary>
/// Exports a user and returns an object containing all of it's data.
/// Exports a user and returns an object containing all of its data.
/// </summary>
/// <remarks>https://getstream.io/chat/docs/dotnet-csharp/update_users/?language=csharp#exporting-users</remarks>
Task<ExportedUser> ExportAsync(string userId);

/// <summary>
/// Schedules user export task for a list of users
/// </summary>
/// <param name="userIds">user IDs to export</param>
/// <returns>returns task ID that you can use to get export status (see <see cref="ITaskClient.GetTaskStatusAsync"/>)</returns>
/// <remarks>https://getstream.io/chat/docs/dotnet-csharp/exporting_users/?language=csharp</remarks>
Task<GenericTaskIdResponse> ExportUsersAsync(IEnumerable<string> userIds);

/// <summary>
/// <para>Shadow bans a user.</para>
/// When a user is shadow banned, they will still be allowed to post messages,
Expand Down
9 changes: 9 additions & 0 deletions src/Clients/UserClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,15 @@ public async Task<ExportedUser> ExportAsync(string userId)
HttpMethod.GET,
HttpStatusCode.OK);

public async Task<GenericTaskIdResponse> ExportUsersAsync(IEnumerable<string> userIds)
=> await ExecuteRequestAsync<GenericTaskIdResponse>("export/users",
HttpMethod.POST,
HttpStatusCode.Created,
body: new
{
user_ids = userIds,
});

public async Task<ApiResponse> ShadowBanAsync(ShadowBanRequest shadowBanRequest)
=> await BanAsync(shadowBanRequest.ToBanRequest());

Expand Down
37 changes: 35 additions & 2 deletions tests/UserClientTests.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using StreamChat;
using StreamChat.Clients;
using StreamChat.Exceptions;
using StreamChat.Models;

Expand Down Expand Up @@ -344,7 +346,7 @@ public async Task TestManyRevokeTokenAsync()
}

[Test]
public async Task TestQueryBannedUsers()
public async Task TestQueryBannedUsersAsync()
{
await _userClient.BanAsync(new BanRequest
{
Expand All @@ -364,5 +366,36 @@ await _userClient.BanAsync(new BanRequest

resp.Bans.Should().NotBeEmpty();
}

[Test]
public async Task TestExportUsersAsync()
{
var resp = await _userClient.ExportUsersAsync(new[] { _user1.Id, _user2.Id });

resp.TaskId.Should().NotBeNullOrEmpty();

AsyncTaskStatusResponse status = null;
await WaitForAsync(async () =>
{
status = await _taskClient.GetTaskStatusAsync(resp.TaskId);

return status.Status == AsyncTaskStatus.Completed;
}, timeout: 10000);

status.Should().NotBeNull();
status.Status.Should().Be(AsyncTaskStatus.Completed);
status.CreatedAt.Should().NotBeNull();
status.Result.Should().NotBeNullOrEmpty();
var exportUrl = status.Result.Values.First().ToString();
exportUrl.Should().Contain("exports/users");

using var client = new HttpClient();
using var response = await client.GetAsync(exportUrl);
response.EnsureSuccessStatusCode();

var exportFile = await response.Content.ReadAsStringAsync();
exportFile.Should().Contain(_user1.Id);
exportFile.Should().Contain(_user2.Id);
}
}
}
Loading