mirror of https://github.com/abpframework/eventhub
committed by
GitHub
25 changed files with 3343 additions and 77 deletions
@ -0,0 +1,18 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Application.Services; |
|||
|
|||
namespace EventHub.Organizations.Memberships |
|||
{ |
|||
public interface IOrganizationMembershipAppService : IApplicationService |
|||
{ |
|||
Task JoinAsync(Guid organizationId); |
|||
|
|||
Task LeaveAsync(Guid organizationId); |
|||
|
|||
Task<bool> IsJoinedAsync(Guid organizationId); |
|||
|
|||
Task<PagedResultDto<OrganizationMemberDto>> GetMembersAsync(Guid organizationId); |
|||
} |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
using System; |
|||
|
|||
namespace EventHub.Organizations.Memberships |
|||
{ |
|||
public class OrganizationMemberDto |
|||
{ |
|||
public Guid Id { get; set; } |
|||
|
|||
public string UserName { get; set; } |
|||
|
|||
public string Name { get; set; } |
|||
|
|||
public string Surname { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,78 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Threading.Tasks; |
|||
using EventHub.Users; |
|||
using Microsoft.AspNetCore.Authorization; |
|||
using Volo.Abp.Application.Dtos; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace EventHub.Organizations.Memberships |
|||
{ |
|||
public class OrganizationMembershipAppService : EventHubAppService, IOrganizationMembershipAppService |
|||
{ |
|||
private readonly OrganizationMembershipManager _organizationMembershipManager; |
|||
private readonly IRepository<AppUser, Guid> _userRepository; |
|||
private readonly IRepository<Organization, Guid> _organizationRepository; |
|||
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipsRepository; |
|||
|
|||
public OrganizationMembershipAppService( |
|||
OrganizationMembershipManager organizationMembershipManager, |
|||
IRepository<AppUser, Guid> userRepository, |
|||
IRepository<Organization, Guid> organizationRepository, |
|||
IRepository<OrganizationMembership, Guid> organizationMembershipsRepository) |
|||
{ |
|||
_organizationMembershipManager = organizationMembershipManager; |
|||
_userRepository = userRepository; |
|||
_organizationRepository = organizationRepository; |
|||
_organizationMembershipsRepository = organizationMembershipsRepository; |
|||
} |
|||
|
|||
[Authorize] |
|||
public async Task JoinAsync(Guid organizationId) |
|||
{ |
|||
await _organizationMembershipManager.JoinAsync( |
|||
await _organizationRepository.GetAsync(organizationId), |
|||
await _userRepository.GetAsync(CurrentUser.GetId()) |
|||
); |
|||
} |
|||
|
|||
[Authorize] |
|||
public async Task LeaveAsync(Guid organizationId) |
|||
{ |
|||
await _organizationMembershipsRepository.DeleteAsync( |
|||
x => x.OrganizationId == organizationId && x.UserId == CurrentUser.GetId() |
|||
); |
|||
} |
|||
|
|||
[Authorize] |
|||
public async Task<bool> IsJoinedAsync(Guid organizationId) |
|||
{ |
|||
return await _organizationMembershipManager.IsJoinedAsync( |
|||
await _organizationRepository.GetAsync(organizationId), |
|||
await _userRepository.GetAsync(CurrentUser.GetId()) |
|||
); |
|||
} |
|||
|
|||
public async Task<PagedResultDto<OrganizationMemberDto>> GetMembersAsync(Guid organizationId) |
|||
{ |
|||
var organizationMembershipsQueryable = await _organizationMembershipsRepository.GetQueryableAsync(); |
|||
var userQueryable = await _userRepository.GetQueryableAsync(); |
|||
|
|||
var query = from organizationMembership in organizationMembershipsQueryable |
|||
join user in userQueryable on organizationMembership.UserId equals user.Id |
|||
where organizationMembership.OrganizationId == organizationId |
|||
orderby organizationMembership.CreationTime descending |
|||
select user; |
|||
|
|||
var totalCount = await AsyncExecuter.CountAsync(query); |
|||
var users = await AsyncExecuter.ToListAsync(query.Take(10)); |
|||
|
|||
return new PagedResultDto<OrganizationMemberDto>( |
|||
totalCount, |
|||
ObjectMapper.Map<List<AppUser>, List<OrganizationMemberDto>>(users) |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
using System; |
|||
using Volo.Abp.Domain.Entities.Auditing; |
|||
|
|||
namespace EventHub.Organizations.Memberships |
|||
{ |
|||
public class OrganizationMembership : CreationAuditedAggregateRoot<Guid> |
|||
{ |
|||
public Guid OrganizationId { get; private set; } |
|||
|
|||
public Guid UserId { get; private set; } |
|||
|
|||
private OrganizationMembership() |
|||
{ |
|||
|
|||
} |
|||
|
|||
internal OrganizationMembership( |
|||
Guid id, |
|||
Guid organizationId, |
|||
Guid userId) |
|||
: base(id) |
|||
{ |
|||
OrganizationId = organizationId; |
|||
UserId = userId; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using EventHub.Users; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Domain.Services; |
|||
|
|||
namespace EventHub.Organizations.Memberships |
|||
{ |
|||
public class OrganizationMembershipManager : DomainService |
|||
{ |
|||
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipsRepository; |
|||
|
|||
public OrganizationMembershipManager(IRepository<OrganizationMembership, Guid> organizationMembershipsRepository) |
|||
{ |
|||
_organizationMembershipsRepository = organizationMembershipsRepository; |
|||
} |
|||
|
|||
public async Task JoinAsync( |
|||
Organization organization, |
|||
AppUser user) |
|||
{ |
|||
if (await IsJoinedAsync(organization, user)) |
|||
{ |
|||
return; |
|||
} |
|||
|
|||
await _organizationMembershipsRepository.InsertAsync( |
|||
new OrganizationMembership( |
|||
GuidGenerator.Create(), |
|||
organization.Id, |
|||
user.Id |
|||
) |
|||
); |
|||
} |
|||
|
|||
public async Task<bool> IsJoinedAsync( |
|||
Organization organization, |
|||
AppUser user) |
|||
{ |
|||
return await _organizationMembershipsRepository |
|||
.AnyAsync(x => x.OrganizationId == organization.Id && x.UserId == user.Id); |
|||
} |
|||
} |
|||
} |
|||
File diff suppressed because it is too large
@ -0,0 +1,54 @@ |
|||
using System; |
|||
using Microsoft.EntityFrameworkCore.Migrations; |
|||
|
|||
namespace EventHub.Migrations |
|||
{ |
|||
public partial class Added_OrganizationMembership : Migration |
|||
{ |
|||
protected override void Up(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.CreateTable( |
|||
name: "AppOrganizationMemberships", |
|||
columns: table => new |
|||
{ |
|||
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|||
OrganizationId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|||
UserId = table.Column<Guid>(type: "uniqueidentifier", nullable: false), |
|||
ExtraProperties = table.Column<string>(type: "nvarchar(max)", nullable: true), |
|||
ConcurrencyStamp = table.Column<string>(type: "nvarchar(40)", maxLength: 40, nullable: true), |
|||
CreationTime = table.Column<DateTime>(type: "datetime2", nullable: false), |
|||
CreatorId = table.Column<Guid>(type: "uniqueidentifier", nullable: true) |
|||
}, |
|||
constraints: table => |
|||
{ |
|||
table.PrimaryKey("PK_AppOrganizationMemberships", x => x.Id); |
|||
table.ForeignKey( |
|||
name: "FK_AppOrganizationMemberships_AbpUsers_UserId", |
|||
column: x => x.UserId, |
|||
principalTable: "AbpUsers", |
|||
principalColumn: "Id"); |
|||
table.ForeignKey( |
|||
name: "FK_AppOrganizationMemberships_AppOrganizations_OrganizationId", |
|||
column: x => x.OrganizationId, |
|||
principalTable: "AppOrganizations", |
|||
principalColumn: "Id"); |
|||
}); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppOrganizationMemberships_OrganizationId_UserId", |
|||
table: "AppOrganizationMemberships", |
|||
columns: new[] { "OrganizationId", "UserId" }); |
|||
|
|||
migrationBuilder.CreateIndex( |
|||
name: "IX_AppOrganizationMemberships_UserId", |
|||
table: "AppOrganizationMemberships", |
|||
column: "UserId"); |
|||
} |
|||
|
|||
protected override void Down(MigrationBuilder migrationBuilder) |
|||
{ |
|||
migrationBuilder.DropTable( |
|||
name: "AppOrganizationMemberships"); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,42 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using EventHub.Organizations.Memberships; |
|||
using EventHub.Web.Pages.Organizations.Components.JoinArea; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
|
|||
namespace EventHub.Web.Controllers |
|||
{ |
|||
public class OrganizationMembershipController : AbpController |
|||
{ |
|||
private readonly IOrganizationMembershipAppService _organizationMembershipAppService; |
|||
|
|||
public OrganizationMembershipController(IOrganizationMembershipAppService organizationMembershipAppService) |
|||
{ |
|||
_organizationMembershipAppService = organizationMembershipAppService; |
|||
} |
|||
|
|||
[HttpPost] |
|||
public async Task<NoContentResult> Join(Guid organizationId) |
|||
{ |
|||
await _organizationMembershipAppService.JoinAsync(organizationId); |
|||
return NoContent(); |
|||
} |
|||
|
|||
[HttpPost] |
|||
public async Task<NoContentResult> Leave(Guid organizationId) |
|||
{ |
|||
await _organizationMembershipAppService.LeaveAsync(organizationId); |
|||
return NoContent(); |
|||
} |
|||
|
|||
[HttpGet] |
|||
public IActionResult Widget(Guid organizationId) |
|||
{ |
|||
return ViewComponent( |
|||
typeof(JoinAreaViewComponent), |
|||
new {organizationId} |
|||
); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
@using EventHub.Localization |
|||
@using Microsoft.AspNetCore.Mvc.Localization |
|||
@inject IHtmlLocalizer<EventHubResource> L |
|||
@model EventHub.Web.Pages.Organizations.Components.JoinArea.JoinAreaViewComponent.MembershipAreaViewComponentModel |
|||
<abp-card class="mb-3" data-organization-id="@Model.OrganizationId"> |
|||
<abp-card-body> |
|||
@if (Model.IsLoggedIn) |
|||
{ |
|||
if (Model.IsJoined) |
|||
{ |
|||
<abp-button id="OrganizationLeaveButton" |
|||
button-type="Secondary" |
|||
size="Block" |
|||
icon="fas fa-times" |
|||
text="@L["LeaveOrganization"].Value" |
|||
data-url="@Url.Action("Leave","OrganizationMembership", new { organizationId = Model.OrganizationId })" /> |
|||
} |
|||
else |
|||
{ |
|||
<abp-button id="OrganizationJoinButton" |
|||
button-type="Primary" |
|||
size="Block" |
|||
icon="fas fa-plus" |
|||
text="@L["JoinOrganization"].Value" |
|||
data-url="@Url.Action("Join","OrganizationMembership", new { organizationId = Model.OrganizationId })"/> |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
<a abp-button="Primary" |
|||
href="@Url.Action("Login", "Account", new { returnUrl = Context.Request.Path.Value })"> @L["LoginToRegister"]</a> |
|||
} |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,52 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using EventHub.Organizations.Memberships; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
using Volo.Abp.Users; |
|||
|
|||
namespace EventHub.Web.Pages.Organizations.Components.JoinArea |
|||
{ |
|||
[Widget( |
|||
AutoInitialize = true, |
|||
RefreshUrl = "/OrganizationMembership/Widget", |
|||
ScriptFiles = new[] {"/Pages/Organizations/Components/JoinArea/join-area.js"} |
|||
)] |
|||
public class JoinAreaViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly IOrganizationMembershipAppService _organizationMembershipAppService; |
|||
private readonly ICurrentUser _currentUser; |
|||
|
|||
public JoinAreaViewComponent( |
|||
IOrganizationMembershipAppService organizationMembershipAppService, |
|||
ICurrentUser currentUser) |
|||
{ |
|||
_organizationMembershipAppService = organizationMembershipAppService; |
|||
_currentUser = currentUser; |
|||
} |
|||
|
|||
public async Task<IViewComponentResult> InvokeAsync(Guid organizationId) |
|||
{ |
|||
var model = new MembershipAreaViewComponentModel |
|||
{ |
|||
OrganizationId = organizationId, |
|||
IsLoggedIn = _currentUser.IsAuthenticated |
|||
}; |
|||
|
|||
if (model.IsLoggedIn) |
|||
{ |
|||
model.IsJoined = await _organizationMembershipAppService.IsJoinedAsync(organizationId); |
|||
} |
|||
|
|||
return View("~/Pages/Organizations/Components/JoinArea/Default.cshtml", model); |
|||
} |
|||
|
|||
public class MembershipAreaViewComponentModel |
|||
{ |
|||
public Guid OrganizationId { get; set; } |
|||
public bool IsLoggedIn { get; set; } |
|||
public bool IsJoined { get; set; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
(function () { |
|||
var l = abp.localization.getResource('EventHub'); |
|||
abp.widgets.JoinArea = function ($wrapper) { |
|||
|
|||
var widgetManager = $wrapper.data('abp-widget-manager'); |
|||
var organizationId = $wrapper.find('[data-organization-id]').attr('data-organization-id'); |
|||
|
|||
function getFilters() { |
|||
return { |
|||
organizationId: organizationId |
|||
}; |
|||
} |
|||
|
|||
function init() { |
|||
var joinButton = $wrapper.find('#OrganizationJoinButton'); |
|||
joinButton.click(function (e) { |
|||
e.preventDefault(); |
|||
joinButton.buttonBusy(true); |
|||
abp.ajax({ |
|||
url: joinButton.attr('data-url') |
|||
}).then(function (){ |
|||
widgetManager.refresh(); |
|||
abp.event.trigger('EventHub.Organization.JoinStatusChanged'); |
|||
abp.message.success(l('OrganizationJoinSuccessMessage'), l('OrganizationJoinSuccessMessageTitle')); |
|||
}).always(function (){ |
|||
joinButton.buttonBusy(false); |
|||
}); |
|||
}); |
|||
|
|||
var $leaveButton = $wrapper.find('#OrganizationLeaveButton'); |
|||
$leaveButton.click(function (e) { |
|||
e.preventDefault(); |
|||
$leaveButton.buttonBusy(true); |
|||
abp.ajax({ |
|||
url: $leaveButton.attr('data-url') |
|||
}).then(function (){ |
|||
widgetManager.refresh(); |
|||
abp.event.trigger('EventHub.Organization.JoinStatusChanged'); |
|||
abp.notify.info(l('OrganizationMembershipLeaveMessage')); |
|||
}).always(function (){ |
|||
$leaveButton.buttonBusy(false); |
|||
}); |
|||
}); |
|||
} |
|||
|
|||
return { |
|||
getFilters: getFilters, |
|||
init: init |
|||
}; |
|||
}; |
|||
})(); |
|||
@ -0,0 +1,14 @@ |
|||
@model EventHub.Web.Pages.Organizations.Components.MembersArea.MembersAreaViewComponent.MembersAreaViewComponentModel |
|||
<abp-card class="mb-3" data-organization-id="@Model.OrganizationId"> |
|||
<abp-card-body> |
|||
<abp-card-title>Members (@Model.TotalCount)</abp-card-title> |
|||
<abp-card-text> |
|||
<ul id="OrganizationMemberList"> |
|||
@foreach (var member in Model.Members) |
|||
{ |
|||
<li class="border p-2 mb-2"><i class="fas fa-user"></i> @Model.GetMemberName(member)</li> |
|||
} |
|||
</ul> |
|||
</abp-card-text> |
|||
</abp-card-body> |
|||
</abp-card> |
|||
@ -0,0 +1,73 @@ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using EventHub.Organizations.Memberships; |
|||
using Microsoft.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc; |
|||
using Volo.Abp.AspNetCore.Mvc.UI.Widgets; |
|||
|
|||
namespace EventHub.Web.Pages.Organizations.Components.MembersArea |
|||
{ |
|||
[Widget( |
|||
AutoInitialize = true, |
|||
RefreshUrl = "/Widgets/OrganizationMembersArea", |
|||
ScriptFiles = new[] {"/Pages/Organizations/Components/MembersArea/members-area.js"}, |
|||
StyleFiles = new[] {"/Pages/Organizations/Components/MembersArea/members-area.css"} |
|||
)] |
|||
public class MembersAreaViewComponent : AbpViewComponent |
|||
{ |
|||
private readonly IOrganizationMembershipAppService _organizationMembershipAppService; |
|||
|
|||
public MembersAreaViewComponent(IOrganizationMembershipAppService organizationMembershipAppService) |
|||
{ |
|||
_organizationMembershipAppService = organizationMembershipAppService; |
|||
} |
|||
|
|||
public async Task<IViewComponentResult> InvokeAsync(Guid organizationId) |
|||
{ |
|||
var result = await _organizationMembershipAppService.GetMembersAsync(organizationId); |
|||
|
|||
return View( |
|||
"~/Pages/Organizations/Components/MembersArea/Default.cshtml", |
|||
new MembersAreaViewComponentModel |
|||
{ |
|||
OrganizationId = organizationId, |
|||
Members = result.Items, |
|||
TotalCount = result.TotalCount |
|||
} |
|||
); |
|||
} |
|||
|
|||
public class MembersAreaViewComponentModel |
|||
{ |
|||
public IReadOnlyList<OrganizationMemberDto> Members { get; set; } |
|||
|
|||
public long TotalCount { get; set; } |
|||
|
|||
public Guid OrganizationId { get; set; } |
|||
|
|||
public string GetMemberName(OrganizationMemberDto member) |
|||
{ |
|||
var nameBuilder = new StringBuilder(); |
|||
|
|||
if (!member.Name.IsNullOrEmpty()) |
|||
{ |
|||
nameBuilder.Append(member.Name); |
|||
} |
|||
|
|||
if (!member.Surname.IsNullOrEmpty()) |
|||
{ |
|||
nameBuilder.Append(member.Surname); |
|||
} |
|||
|
|||
if (nameBuilder.Length == 0) |
|||
{ |
|||
nameBuilder.Append(member.UserName); |
|||
} |
|||
|
|||
return nameBuilder.ToString(); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,5 @@ |
|||
#OrganizationMemberList |
|||
{ |
|||
list-style: none; |
|||
padding: 0; |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
(function () { |
|||
abp.widgets.MembersArea = function ($wrapper) { |
|||
var organizationId = $wrapper.find('[data-organization-id]').attr('data-organization-id'); |
|||
return { |
|||
getFilters: function () { |
|||
return { |
|||
organizationId: organizationId |
|||
}; |
|||
} |
|||
}; |
|||
}; |
|||
|
|||
abp.event.on("EventHub.Organization.JoinStatusChanged", function(){ |
|||
$('[data-widget-name="MembersArea"]') |
|||
.data('abp-widget-manager') |
|||
.refresh(); |
|||
}); |
|||
})(); |
|||
@ -0,0 +1,101 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Volo.Abp.Users; |
|||
using Xunit; |
|||
|
|||
namespace EventHub.Organizations.Memberships |
|||
{ |
|||
public class OrganizationMembershipAppServiceTests : EventHubApplicationTestBase |
|||
{ |
|||
private readonly IOrganizationMembershipAppService _organizationMembershipAppService; |
|||
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipRepository; |
|||
private readonly EventHubTestData _testData; |
|||
private readonly ICurrentUser _currentUser; |
|||
|
|||
public OrganizationMembershipAppServiceTests() |
|||
{ |
|||
_organizationMembershipAppService = GetRequiredService<IOrganizationMembershipAppService>(); |
|||
_organizationMembershipRepository = GetRequiredService<IRepository<OrganizationMembership, Guid>>(); |
|||
_testData = GetRequiredService<EventHubTestData>(); |
|||
_currentUser = GetRequiredService<ICurrentUser>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Join_To_An_Organization() |
|||
{ |
|||
await _organizationMembershipAppService.JoinAsync( |
|||
_testData.OrganizationVolosoftId |
|||
); |
|||
|
|||
(await GetMembershipOrNull( |
|||
_testData.OrganizationVolosoftId, |
|||
_currentUser.GetId() |
|||
)).ShouldNotBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Leave_From_An_Organization() |
|||
{ |
|||
await WithUnitOfWorkAsync(async () => |
|||
{ |
|||
await _organizationMembershipRepository.InsertAsync( |
|||
new OrganizationMembership( |
|||
Guid.NewGuid(), |
|||
_testData.OrganizationDotnetEuropeId, |
|||
_currentUser.GetId() |
|||
) |
|||
); |
|||
}); |
|||
|
|||
await _organizationMembershipAppService.LeaveAsync( |
|||
_testData.OrganizationDotnetEuropeId |
|||
); |
|||
|
|||
(await GetMembershipOrNull( |
|||
_testData.OrganizationDotnetEuropeId, |
|||
_currentUser.GetId()) |
|||
).ShouldBeNull(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Get_List_Of_Members() |
|||
{ |
|||
await WithUnitOfWorkAsync(async () => |
|||
{ |
|||
await _organizationMembershipRepository.InsertAsync( |
|||
new OrganizationMembership( |
|||
Guid.NewGuid(), |
|||
_testData.OrganizationVolosoftId, |
|||
_testData.UserAdminId |
|||
) |
|||
); |
|||
|
|||
await _organizationMembershipRepository.InsertAsync( |
|||
new OrganizationMembership( |
|||
Guid.NewGuid(), |
|||
_testData.OrganizationVolosoftId, |
|||
_testData.UserJohnId |
|||
) |
|||
); |
|||
}); |
|||
|
|||
var result = await _organizationMembershipAppService.GetMembersAsync(_testData.OrganizationVolosoftId); |
|||
|
|||
result.TotalCount.ShouldBeGreaterThanOrEqualTo(2); |
|||
result.Items.ShouldContain(x => x.Id == _testData.UserAdminId); |
|||
result.Items.ShouldContain(x => x.Id == _testData.UserJohnId); |
|||
} |
|||
|
|||
private async Task<OrganizationMembership> GetMembershipOrNull(Guid organizationId, Guid userId) |
|||
{ |
|||
return await WithUnitOfWorkAsync(async () => |
|||
{ |
|||
return await _organizationMembershipRepository.FirstOrDefaultAsync( |
|||
x => x.OrganizationId == organizationId && x.UserId == userId |
|||
); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,46 @@ |
|||
using System; |
|||
using System.Threading.Tasks; |
|||
using Shouldly; |
|||
using Volo.Abp.Domain.Repositories; |
|||
using Xunit; |
|||
|
|||
namespace EventHub.Organizations.Memberships |
|||
{ |
|||
public class OrganizationMembershipManagerTests : EventHubDomainTestBase |
|||
{ |
|||
private readonly OrganizationMembershipManager _organizationMembershipManager; |
|||
private readonly IRepository<OrganizationMembership, Guid> _organizationMembershipRepository; |
|||
private readonly EventHubTestData _testData; |
|||
|
|||
public OrganizationMembershipManagerTests() |
|||
{ |
|||
_organizationMembershipManager = GetRequiredService<OrganizationMembershipManager>(); |
|||
_organizationMembershipRepository = GetRequiredService<IRepository<OrganizationMembership, Guid>>(); |
|||
_testData = GetRequiredService<EventHubTestData>(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Should_Join_To_An_Organization() |
|||
{ |
|||
await WithUnitOfWorkAsync(async () => |
|||
{ |
|||
var user = await GetUserAsync(_testData.UserAdminId); |
|||
var organization = await GetOrganizationAsync(_testData.OrganizationVolosoftName); |
|||
await _organizationMembershipManager.JoinAsync(organization, user); |
|||
}); |
|||
|
|||
(await GetMembershipOrNull(_testData.OrganizationVolosoftId, _testData.UserAdminId)) |
|||
.ShouldNotBeNull(); |
|||
} |
|||
|
|||
private async Task<OrganizationMembership> GetMembershipOrNull(Guid organizationId, Guid userId) |
|||
{ |
|||
return await WithUnitOfWorkAsync(async () => |
|||
{ |
|||
return await _organizationMembershipRepository.FirstOrDefaultAsync( |
|||
x => x.OrganizationId == organizationId && x.UserId == userId |
|||
); |
|||
}); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue