mirror of https://github.com/abpframework/abp.git
committed by
GitHub
98 changed files with 1240 additions and 291 deletions
@ -0,0 +1,103 @@ |
|||||
|
## Using MatBlazor UI Components With the ABP Framework |
||||
|
|
||||
|
Hi, in this step by step article, I will show you how to integrate [MatBlazor](https://www.matblazor.com/), a blazor UI components into ABP Framework-based applications. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
*(A screenshot from the example application developed in this article)* |
||||
|
|
||||
|
## Create the Project |
||||
|
|
||||
|
> First thing is to create the project. ABP Framework offers startup templates to get into business faster. |
||||
|
|
||||
|
In this article, I will create a new startup template with EF Core as a database provider and Blazor for UI framework. But if you already have a project with Blazor UI, you don't need to create a new startup template, you can directly implement the following steps to your existing project. |
||||
|
|
||||
|
> If you already have a project with the Blazor UI, you can skip this section. |
||||
|
|
||||
|
* Before starting the development, we will create a new solution named `MatBlazorSample` (or whatever you want). We will create a new startup template with EF Core as a database provider and Blazor for UI framework by using [ABP CLI](https://docs.abp.io/en/abp/latest/CLI): |
||||
|
|
||||
|
````bash |
||||
|
abp new MatBlazorSample -u blazor |
||||
|
```` |
||||
|
|
||||
|
This will create new project inside of `aspnet-core`, so: |
||||
|
|
||||
|
````bash |
||||
|
cd aspnet-core |
||||
|
```` |
||||
|
|
||||
|
and |
||||
|
|
||||
|
````bash |
||||
|
dotnet restore |
||||
|
```` |
||||
|
|
||||
|
* Our project boilerplate will be ready after the download is finished. Then, we can open the solution in the Visual Studio (or any other IDE) and run the `MatBlazorSample.DbMigrator` to create the database and seed initial data (which creates the admin user, admin role, permissions etc.) |
||||
|
|
||||
|
 |
||||
|
|
||||
|
* After database and initial data created, |
||||
|
* Run the `MatBlazorSample.HttpApi.Host` to see our server side working and |
||||
|
* Run the `MatBlazorSample.Blazor` to see our UI working properly. |
||||
|
|
||||
|
> _Default login credentials for admin: username is **admin** and password is **1q2w3E\***_ |
||||
|
|
||||
|
## Install MatBlazor |
||||
|
|
||||
|
You can follow [this documentation](https://www.matblazor.com/) to install MatBlazor packages into your computer. |
||||
|
|
||||
|
### Adding MatBlazor NuGet Packages |
||||
|
|
||||
|
```bash |
||||
|
Install-Package MatBlazor |
||||
|
``` |
||||
|
|
||||
|
### Register MatBlazor Resources |
||||
|
|
||||
|
1. Add the following line to the HEAD section of the `wwwroot/index.html` file within the `MatBlazorSample.Blazor` project: |
||||
|
|
||||
|
```Razor |
||||
|
<head> |
||||
|
<!--...--> |
||||
|
<script src="_content/MatBlazor/dist/matBlazor.js"></script> |
||||
|
<link href="_content/MatBlazor/dist/matBlazor.css" rel="stylesheet" /> |
||||
|
</head> |
||||
|
``` |
||||
|
|
||||
|
2. In the `MatBlazorSampleBlazorModule` class, call the `AddMatBlazor()` method from your project's `ConfigureServices()` method: |
||||
|
|
||||
|
```csharp |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
var environment = context.Services.GetSingletonInstance<IWebAssemblyHostEnvironment>(); |
||||
|
var builder = context.Services.GetSingletonInstance<WebAssemblyHostBuilder>(); |
||||
|
// ... |
||||
|
builder.Services.AddMatBlazor(); |
||||
|
} |
||||
|
``` |
||||
|
|
||||
|
3. Register the **MatBlazorSample.Blazor** namespace in the `_Imports.razor` file: |
||||
|
|
||||
|
```Razor |
||||
|
@using MatBlazor |
||||
|
``` |
||||
|
|
||||
|
## The Sample Application |
||||
|
|
||||
|
We have created a sample application with [Table](https://www.matblazor.com/Table) example. |
||||
|
|
||||
|
### The Source Code |
||||
|
|
||||
|
You can download the source code from [here](https://github.com/abpframework/abp-samples/tree/master/MatBlazorSample). |
||||
|
|
||||
|
The related files for this example are marked in the following screenshots. |
||||
|
|
||||
|
 |
||||
|
|
||||
|
 |
||||
|
|
||||
|
 |
||||
|
|
||||
|
## Conclusion |
||||
|
|
||||
|
In this article, I've explained how to use [MatBlazor](https://www.matblazor.com/) components in your application. ABP Framework is designed so that it can work with any UI library/framework. |
||||
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 8.5 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 14 KiB |
@ -0,0 +1,12 @@ |
|||||
|
using System; |
||||
|
using Volo.Abp.Application.Dtos; |
||||
|
|
||||
|
namespace Volo.CmsKit.Admin.Contents |
||||
|
{ |
||||
|
public class ContentGetListDto : EntityDto<Guid> |
||||
|
{ |
||||
|
public string EntityType { get; set; } |
||||
|
|
||||
|
public string EntityId { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace Volo.CmsKit.Admin.Tags |
||||
|
{ |
||||
|
public class EntityTagCreateDto |
||||
|
{ |
||||
|
[Required] |
||||
|
public string TagName { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
public string EntityType { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
public string EntityId { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,17 @@ |
|||||
|
using System; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
|
||||
|
namespace Volo.CmsKit.Admin.Tags |
||||
|
{ |
||||
|
public class EntityTagRemoveDto |
||||
|
{ |
||||
|
[Required] |
||||
|
public Guid TagId { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
public string EntityType { get; set; } |
||||
|
|
||||
|
[Required] |
||||
|
public string EntityId { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.CmsKit.Admin.Tags |
||||
|
{ |
||||
|
public interface IEntityTagAdminAppService |
||||
|
{ |
||||
|
Task AddTagToEntityAsync(EntityTagCreateDto input); |
||||
|
|
||||
|
Task RemoveTagFromEntityAsync(EntityTagRemoveDto input); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,18 @@ |
|||||
|
namespace Volo.CmsKit.Admin.Tags |
||||
|
{ |
||||
|
public class TagDefinitionDto |
||||
|
{ |
||||
|
public TagDefinitionDto() |
||||
|
{ |
||||
|
} |
||||
|
public TagDefinitionDto(string entityType, string displayName) |
||||
|
{ |
||||
|
EntityType = entityType; |
||||
|
DisplayName = displayName; |
||||
|
} |
||||
|
|
||||
|
public string EntityType { get; set; } |
||||
|
|
||||
|
public string DisplayName { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
using System; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.CmsKit.Admin.Tags; |
||||
|
using Volo.CmsKit.Tags; |
||||
|
|
||||
|
namespace Volo.CmsKit.Admin.Application.Volo.CmsKit.Admin.Tags |
||||
|
{ |
||||
|
public class EntityTagAdminAppService : CmsKitAdminAppServiceBase, IEntityTagAdminAppService |
||||
|
{ |
||||
|
protected ITagDefinitionStore _tagDefinitionStore; |
||||
|
protected IEntityTagManager _entityTagManager; |
||||
|
protected ITagManager _tagManager; |
||||
|
|
||||
|
public EntityTagAdminAppService( |
||||
|
ITagDefinitionStore tagDefinitionStore, |
||||
|
IEntityTagManager entityTagManager, |
||||
|
ITagManager tagManager) |
||||
|
{ |
||||
|
_tagDefinitionStore = tagDefinitionStore; |
||||
|
_entityTagManager = entityTagManager; |
||||
|
_tagManager = tagManager; |
||||
|
} |
||||
|
|
||||
|
public async Task AddTagToEntityAsync(EntityTagCreateDto input) |
||||
|
{ |
||||
|
var definition = await _tagDefinitionStore.GetTagEntityTypeDefinitionsAsync(input.EntityType); |
||||
|
|
||||
|
await CheckPolicyAsync(definition.CreatePolicy); |
||||
|
|
||||
|
var tag = await _tagManager.GetOrAddAsync(input.EntityType, input.TagName, CurrentTenant?.Id); |
||||
|
|
||||
|
await _entityTagManager.AddTagToEntityAsync( |
||||
|
tag.Id, |
||||
|
input.EntityType, |
||||
|
input.EntityId, |
||||
|
CurrentTenant?.Id); |
||||
|
} |
||||
|
|
||||
|
public async Task RemoveTagFromEntityAsync(EntityTagRemoveDto input) |
||||
|
{ |
||||
|
var definition = await _tagDefinitionStore.GetTagEntityTypeDefinitionsAsync(input.EntityType); |
||||
|
|
||||
|
await CheckPolicyAsync(definition.DeletePolicy); |
||||
|
|
||||
|
await _entityTagManager.RemoveTagFromEntityAsync( |
||||
|
input.TagId, |
||||
|
input.EntityType, |
||||
|
input.EntityId, |
||||
|
CurrentTenant?.Id); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,16 +1,12 @@ |
|||||
using JetBrains.Annotations; |
using JetBrains.Annotations; |
||||
using Volo.CmsKit.Reactions; |
using Volo.CmsKit.Reactions; |
||||
|
using Volo.CmsKit.Tags; |
||||
|
|
||||
namespace Volo.CmsKit |
namespace Volo.CmsKit |
||||
{ |
{ |
||||
public class CmsKitOptions |
public class CmsKitOptions |
||||
{ |
{ |
||||
[NotNull] |
[NotNull] |
||||
public ReactionDefinitionDictionary Reactions { get; } |
public ReactionDefinitionDictionary Reactions { get; } = new ReactionDefinitionDictionary(); |
||||
|
|
||||
public CmsKitOptions() |
|
||||
{ |
|
||||
Reactions = new ReactionDefinitionDictionary(); |
|
||||
} |
|
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,32 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace Volo.CmsKit.Domain.Volo.CmsKit |
||||
|
{ |
||||
|
public abstract class PolicySpecifiedDefinition |
||||
|
{ |
||||
|
protected PolicySpecifiedDefinition() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public PolicySpecifiedDefinition( |
||||
|
[CanBeNull] string createPolicy = null, |
||||
|
[CanBeNull] string updatePolicy = null, |
||||
|
[CanBeNull] string deletePolicy = null) |
||||
|
{ |
||||
|
CreatePolicy = createPolicy; |
||||
|
DeletePolicy = deletePolicy; |
||||
|
UpdatePolicy = updatePolicy; |
||||
|
} |
||||
|
|
||||
|
[CanBeNull] |
||||
|
public virtual string CreatePolicy { get; set; } |
||||
|
|
||||
|
[CanBeNull] |
||||
|
public virtual string UpdatePolicy { get; set; } |
||||
|
|
||||
|
[CanBeNull] |
||||
|
public virtual string DeletePolicy { get; set; } |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Volo.CmsKit.Tags; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public class CmsKitTagOptions |
||||
|
{ |
||||
|
[NotNull] |
||||
|
public TagEntityTypeDefinitionDictionary EntityTypes { get; } = new TagEntityTypeDefinitionDictionary(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,40 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public class DefaultTagDefinitionStore : ITagDefinitionStore, ITransientDependency |
||||
|
{ |
||||
|
private readonly CmsKitTagOptions options; |
||||
|
|
||||
|
public DefaultTagDefinitionStore(IOptions<CmsKitTagOptions> options) |
||||
|
{ |
||||
|
this.options = options.Value; |
||||
|
} |
||||
|
|
||||
|
public virtual Task<TagEntityTypeDefiniton> GetTagEntityTypeDefinitionsAsync([NotNull] string entityType) |
||||
|
{ |
||||
|
Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); |
||||
|
|
||||
|
var result = options.EntityTypes.GetOrDefault(entityType) ?? throw new EntityNotTaggableException(entityType); |
||||
|
|
||||
|
return Task.FromResult(result); |
||||
|
} |
||||
|
|
||||
|
public virtual Task<List<TagEntityTypeDefiniton>> GetTagDefinitionsAsync() |
||||
|
{ |
||||
|
return Task.FromResult(options.EntityTypes.Values.ToList()); |
||||
|
} |
||||
|
|
||||
|
public virtual Task<bool> IsDefinedAsync([NotNull] string entityType) |
||||
|
{ |
||||
|
Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); |
||||
|
return Task.FromResult(options.EntityTypes.ContainsKey(entityType)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
using Microsoft.Extensions.Logging; |
||||
|
using System; |
||||
|
using Volo.Abp; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
[Serializable] |
||||
|
public class EntityNotTaggableException : BusinessException |
||||
|
{ |
||||
|
public EntityNotTaggableException( |
||||
|
string code = null, |
||||
|
string message = null, |
||||
|
string details = null, |
||||
|
Exception innerException = null, |
||||
|
LogLevel logLevel = LogLevel.Warning) |
||||
|
: base(code, message, details, innerException, logLevel) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public EntityNotTaggableException(string entityType) |
||||
|
{ |
||||
|
Code = CmsKitErrorCodes.Tags.EntityNotTaggable; |
||||
|
WithData(nameof(Tag.EntityType), entityType); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,52 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Domain.Services; |
||||
|
using Volo.CmsKit.Tags; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public class EntityTagManager : DomainService, IEntityTagManager |
||||
|
{ |
||||
|
protected readonly IEntityTagRepository _entityTagRepository; |
||||
|
protected readonly ITagDefinitionStore _tagDefinitionStore; |
||||
|
|
||||
|
public EntityTagManager( |
||||
|
IEntityTagRepository entityTagRepository, |
||||
|
ITagDefinitionStore tagDefinitionStore) |
||||
|
{ |
||||
|
_entityTagRepository = entityTagRepository; |
||||
|
_tagDefinitionStore = tagDefinitionStore; |
||||
|
} |
||||
|
|
||||
|
public async Task<EntityTag> AddTagToEntityAsync( |
||||
|
[NotNull] Guid tagId, |
||||
|
[NotNull] string entityType, |
||||
|
[NotNull] string entityId, |
||||
|
[CanBeNull] Guid? tenantId = null, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
if (!await _tagDefinitionStore.IsDefinedAsync(entityType)) |
||||
|
{ |
||||
|
throw new EntityNotTaggableException(entityType); |
||||
|
} |
||||
|
|
||||
|
var entityTag = new EntityTag(tagId, entityId, tenantId); |
||||
|
|
||||
|
return await _entityTagRepository.InsertAsync(entityTag, cancellationToken: cancellationToken); |
||||
|
} |
||||
|
|
||||
|
public async Task RemoveTagFromEntityAsync( |
||||
|
[NotNull] Guid tagId, |
||||
|
[NotNull] string entityType, |
||||
|
[NotNull] string entityId, |
||||
|
[CanBeNull] Guid? tenantId = null, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var entityTag = await _entityTagRepository.FindAsync(tagId, entityId, tenantId, cancellationToken); |
||||
|
|
||||
|
await _entityTagRepository.DeleteAsync(entityTag); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public interface IEntityTagManager |
||||
|
{ |
||||
|
Task<EntityTag> AddTagToEntityAsync( |
||||
|
[NotNull] Guid tagId, |
||||
|
[NotNull] string entityType, |
||||
|
[NotNull] string entityId, |
||||
|
[CanBeNull] Guid? tenantId = null, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
|
||||
|
Task RemoveTagFromEntityAsync( |
||||
|
[NotNull] Guid tagId, |
||||
|
[NotNull] string entityType, |
||||
|
[NotNull] string entityId, |
||||
|
[CanBeNull] Guid? tenantId = null, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
} |
||||
|
} |
||||
@ -1,9 +1,17 @@ |
|||||
using Volo.Abp.Domain.Repositories; |
using JetBrains.Annotations; |
||||
|
using System; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Domain.Repositories; |
||||
|
|
||||
namespace Volo.CmsKit.Tags |
namespace Volo.CmsKit.Tags |
||||
{ |
{ |
||||
public interface IEntityTagRepository : IBasicRepository<EntityTag> |
public interface IEntityTagRepository : IBasicRepository<EntityTag> |
||||
{ |
{ |
||||
|
Task<EntityTag> FindAsync( |
||||
|
[NotNull] Guid tagId, |
||||
|
[NotNull] string entityId, |
||||
|
[CanBeNull] Guid? tenantId, |
||||
|
CancellationToken cancellationToken = default); |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,15 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public interface ITagDefinitionStore |
||||
|
{ |
||||
|
Task<List<TagEntityTypeDefiniton>> GetTagDefinitionsAsync(); |
||||
|
|
||||
|
Task<TagEntityTypeDefiniton> GetTagEntityTypeDefinitionsAsync([NotNull] string entityType); |
||||
|
|
||||
|
Task<bool> IsDefinedAsync([NotNull] string entityType); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using System.Collections.Generic; |
||||
|
using Volo.Abp.Localization; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public class TagEntityTypeDefinitionDictionary : Dictionary<string, TagEntityTypeDefiniton> |
||||
|
{ |
||||
|
public void AddOrReplace( |
||||
|
[NotNull] string entityType, |
||||
|
[CanBeNull] ILocalizableString displayName = null, |
||||
|
[CanBeNull] string createPolicy = null, |
||||
|
[CanBeNull] string updatePolicy = null, |
||||
|
[CanBeNull] string deletePolicy = null |
||||
|
) |
||||
|
{ |
||||
|
this[entityType] = new TagEntityTypeDefiniton(entityType, displayName, createPolicy, updatePolicy, deletePolicy); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Volo.Abp; |
||||
|
using Volo.Abp.Localization; |
||||
|
using Volo.CmsKit.Domain.Volo.CmsKit; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public class TagEntityTypeDefiniton : PolicySpecifiedDefinition |
||||
|
{ |
||||
|
public string EntityType { get; } |
||||
|
|
||||
|
[CanBeNull] |
||||
|
public virtual ILocalizableString DisplayName { get; } |
||||
|
|
||||
|
public TagEntityTypeDefiniton() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public TagEntityTypeDefiniton( |
||||
|
[NotNull] string entityType, |
||||
|
[CanBeNull] ILocalizableString displayName = null, |
||||
|
[CanBeNull] string createPolicy = null, |
||||
|
[CanBeNull] string updatePolicy = null, |
||||
|
[CanBeNull] string deletePolicy = null) : base(createPolicy, updatePolicy, deletePolicy) |
||||
|
{ |
||||
|
EntityType = Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); |
||||
|
|
||||
|
DisplayName = displayName; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,3 +1,3 @@ |
|||||
@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents.ContentViewComponent.ContentViewModel |
@model Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents.ContentViewComponent.ContentViewModel |
||||
|
|
||||
@Html.Raw(Model.Rendered) |
@Html.Raw(Model.Value) |
||||
|
|||||
@ -0,0 +1,60 @@ |
|||||
|
using Shouldly; |
||||
|
using System.Linq; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.Guids; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.CmsKit.Tags |
||||
|
{ |
||||
|
public class EntityTagManager_Tests : CmsKitDomainTestBase |
||||
|
{ |
||||
|
private readonly CmsKitTestData _cmsKitTestData; |
||||
|
private readonly IEntityTagManager _entityTagManager; |
||||
|
private readonly ITagRepository _tagRepository; |
||||
|
private readonly IGuidGenerator _guidGenerator; |
||||
|
|
||||
|
public EntityTagManager_Tests() |
||||
|
{ |
||||
|
_cmsKitTestData = GetRequiredService<CmsKitTestData>(); |
||||
|
_entityTagManager = GetRequiredService<IEntityTagManager>(); |
||||
|
_tagRepository = GetRequiredService<ITagRepository>(); |
||||
|
_guidGenerator = GetRequiredService<IGuidGenerator>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task AddTagToEntityAsync_ShouldAdd_WhenEverythingCorrect() |
||||
|
{ |
||||
|
var tag = await _tagRepository.InsertAsync(new Tag(_guidGenerator.Create(), _cmsKitTestData.EntityType1, "My Test Tag #1")); |
||||
|
|
||||
|
var entityTag = await _entityTagManager.AddTagToEntityAsync(tag.Id, _cmsKitTestData.EntityType1, _cmsKitTestData.EntityId1); |
||||
|
|
||||
|
entityTag.ShouldNotBeNull(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task AddTagToEntity_ShouldThrowNotTaggable_WithNotConfiguredEntityType() |
||||
|
{ |
||||
|
var entityType = "Not.Configured.EntityType"; |
||||
|
|
||||
|
var exception = Should.Throw<EntityNotTaggableException>(async () => |
||||
|
await _entityTagManager.AddTagToEntityAsync(_cmsKitTestData.TagId_1, entityType, _cmsKitTestData.EntityId1) |
||||
|
); |
||||
|
|
||||
|
exception.ShouldNotBeNull(); |
||||
|
exception.Data[nameof(Tag.EntityType)].ShouldBe(entityType); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task RemoveTagFromEntityAsync_ShouldRemove_WhenEverythingCorrect() |
||||
|
{ |
||||
|
var tagToDelete = (await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.EntityType1, _cmsKitTestData.EntityId1)) |
||||
|
.First(); |
||||
|
|
||||
|
await _entityTagManager.RemoveTagFromEntityAsync(tagToDelete.Id, tagToDelete.EntityType, _cmsKitTestData.EntityId1); |
||||
|
|
||||
|
var tags = await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.EntityType1, _cmsKitTestData.EntityId1); |
||||
|
|
||||
|
tags.ShouldNotContain(x => x.Id == tagToDelete.Id); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue