mirror of https://github.com/Squidex/squidex.git
19 changed files with 532 additions and 111 deletions
@ -0,0 +1,22 @@ |
|||
// ==========================================================================
|
|||
// IUpdateableEntity.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using NodaTime; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities |
|||
{ |
|||
public interface IUpdateableEntity |
|||
{ |
|||
Guid Id { get; set; } |
|||
|
|||
Instant Created { get; set; } |
|||
|
|||
Instant LastModified { get; set; } |
|||
} |
|||
} |
|||
@ -0,0 +1,137 @@ |
|||
// ==========================================================================
|
|||
// AssetCommandMiddlewareTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
using System.Threading.Tasks; |
|||
using FakeItEasy; |
|||
using Squidex.Domain.Apps.Entities.Assets.Commands; |
|||
using Squidex.Domain.Apps.Entities.TestHelpers; |
|||
using Squidex.Infrastructure.Assets; |
|||
using Squidex.Infrastructure.Commands; |
|||
using Squidex.Infrastructure.Tasks; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Assets |
|||
{ |
|||
public class AssetCommandMiddlewareTests : HandlerTestBase<AssetDomainObject> |
|||
{ |
|||
private readonly IAssetThumbnailGenerator assetThumbnailGenerator = A.Fake<IAssetThumbnailGenerator>(); |
|||
private readonly IAssetStore assetStore = A.Fake<IAssetStore>(); |
|||
private readonly Guid assetId = Guid.NewGuid(); |
|||
private readonly Stream stream = new MemoryStream(); |
|||
private readonly ImageInfo image = new ImageInfo(2048, 2048); |
|||
private readonly AssetDomainObject asset = new AssetDomainObject(); |
|||
private readonly AssetFile file; |
|||
private readonly AssetCommandMiddleware sut; |
|||
|
|||
public AssetCommandMiddlewareTests() |
|||
{ |
|||
file = new AssetFile("my-image.png", "image/png", 1024, () => stream); |
|||
|
|||
sut = new AssetCommandMiddleware(Handler, assetStore, assetThumbnailGenerator); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Create_should_create_domain_object() |
|||
{ |
|||
var context = CreateContextForCommand(new CreateAsset { AssetId = assetId, File = file }); |
|||
|
|||
SetupStore(0, context.ContextId); |
|||
SetupImageInfo(); |
|||
|
|||
await TestCreate(asset, async _ => |
|||
{ |
|||
await sut.HandleAsync(context); |
|||
}); |
|||
|
|||
Assert.Equal(assetId, context.Result<EntityCreatedResult<Guid>>().IdOrValue); |
|||
|
|||
AssertAssetHasBeenUploaded(0, context.ContextId); |
|||
AssertAssetImageChecked(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Update_should_update_domain_object() |
|||
{ |
|||
var context = CreateContextForCommand(new UpdateAsset { AssetId = assetId, File = file }); |
|||
|
|||
SetupStore(1, context.ContextId); |
|||
SetupImageInfo(); |
|||
|
|||
CreateAsset(); |
|||
|
|||
await TestUpdate(asset, async _ => |
|||
{ |
|||
await sut.HandleAsync(context); |
|||
}); |
|||
|
|||
AssertAssetHasBeenUploaded(1, context.ContextId); |
|||
AssertAssetImageChecked(); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Rename_should_update_domain_object() |
|||
{ |
|||
CreateAsset(); |
|||
|
|||
var context = CreateContextForCommand(new RenameAsset { AssetId = assetId, FileName = "my-new-image.png" }); |
|||
|
|||
await TestUpdate(asset, async _ => |
|||
{ |
|||
await sut.HandleAsync(context); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public async Task Delete_should_update_domain_object() |
|||
{ |
|||
CreateAsset(); |
|||
|
|||
var command = CreateContextForCommand(new DeleteAsset { AssetId = assetId }); |
|||
|
|||
await TestUpdate(asset, async _ => |
|||
{ |
|||
await sut.HandleAsync(command); |
|||
}); |
|||
} |
|||
|
|||
private void CreateAsset() |
|||
{ |
|||
asset.Create(CreateCommand(new CreateAsset { File = file })); |
|||
} |
|||
|
|||
private void SetupImageInfo() |
|||
{ |
|||
A.CallTo(() => assetThumbnailGenerator.GetImageInfoAsync(stream)) |
|||
.Returns(image); |
|||
} |
|||
|
|||
private void SetupStore(long version, Guid commitId) |
|||
{ |
|||
A.CallTo(() => assetStore.UploadTemporaryAsync(commitId.ToString(), stream)) |
|||
.Returns(TaskHelper.Done); |
|||
A.CallTo(() => assetStore.CopyTemporaryAsync(commitId.ToString(), assetId.ToString(), version, null)) |
|||
.Returns(TaskHelper.Done); |
|||
A.CallTo(() => assetStore.DeleteTemporaryAsync(commitId.ToString())) |
|||
.Returns(TaskHelper.Done); |
|||
} |
|||
|
|||
private void AssertAssetImageChecked() |
|||
{ |
|||
A.CallTo(() => assetThumbnailGenerator.GetImageInfoAsync(stream)).MustHaveHappened(); |
|||
} |
|||
|
|||
private void AssertAssetHasBeenUploaded(long version, Guid commitId) |
|||
{ |
|||
A.CallTo(() => assetStore.UploadTemporaryAsync(commitId.ToString(), stream)).MustHaveHappened(); |
|||
A.CallTo(() => assetStore.CopyTemporaryAsync(commitId.ToString(), assetId.ToString(), version, null)).MustHaveHappened(); |
|||
A.CallTo(() => assetStore.DeleteTemporaryAsync(commitId.ToString())).MustHaveHappened(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,209 @@ |
|||
// ==========================================================================
|
|||
// AssetDomainObjectTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using System; |
|||
using System.IO; |
|||
using Squidex.Domain.Apps.Entities.Assets.Commands; |
|||
using Squidex.Domain.Apps.Entities.TestHelpers; |
|||
using Squidex.Domain.Apps.Events.Assets; |
|||
using Squidex.Infrastructure; |
|||
using Squidex.Infrastructure.Assets; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Assets |
|||
{ |
|||
public class AssetDomainObjectTests : HandlerTestBase<AssetDomainObject> |
|||
{ |
|||
private readonly ImageInfo image = new ImageInfo(2048, 2048); |
|||
private readonly Guid assetId = Guid.NewGuid(); |
|||
private readonly AssetFile file = new AssetFile("my-image.png", "image/png", 1024, () => new MemoryStream()); |
|||
private readonly AssetDomainObject sut = new AssetDomainObject(); |
|||
|
|||
[Fact] |
|||
public void Create_should_throw_exception_if_created() |
|||
{ |
|||
CreateAsset(); |
|||
|
|||
Assert.Throws<DomainException>(() => |
|||
{ |
|||
sut.Create(CreateAssetCommand(new CreateAsset { File = file })); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Create_should_create_events() |
|||
{ |
|||
sut.Create(CreateAssetCommand(new CreateAsset { File = file, ImageInfo = image })); |
|||
|
|||
Assert.Equal(0, sut.State.FileVersion); |
|||
|
|||
sut.GetUncomittedEvents() |
|||
.ShouldHaveSameEvents( |
|||
CreateAssetEvent(new AssetCreated |
|||
{ |
|||
IsImage = true, |
|||
FileName = file.FileName, |
|||
FileSize = file.FileSize, |
|||
FileVersion = 0, |
|||
MimeType = file.MimeType, |
|||
PixelWidth = image.PixelWidth, |
|||
PixelHeight = image.PixelHeight |
|||
}) |
|||
); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Update_should_throw_exception_if_not_created() |
|||
{ |
|||
Assert.Throws<DomainException>(() => |
|||
{ |
|||
sut.Update(CreateAssetCommand(new UpdateAsset { File = file })); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Update_should_throw_exception_if_asset_is_deleted() |
|||
{ |
|||
CreateAsset(); |
|||
DeleteAsset(); |
|||
|
|||
Assert.Throws<DomainException>(() => |
|||
{ |
|||
sut.Update(CreateAssetCommand(new UpdateAsset())); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Update_should_create_events() |
|||
{ |
|||
CreateAsset(); |
|||
|
|||
sut.Update(CreateAssetCommand(new UpdateAsset { File = file, ImageInfo = image })); |
|||
|
|||
Assert.Equal(1, sut.State.FileVersion); |
|||
|
|||
sut.GetUncomittedEvents() |
|||
.ShouldHaveSameEvents( |
|||
CreateAssetEvent(new AssetUpdated |
|||
{ |
|||
IsImage = true, |
|||
FileSize = file.FileSize, |
|||
FileVersion = 1, |
|||
MimeType = file.MimeType, |
|||
PixelWidth = image.PixelWidth, |
|||
PixelHeight = image.PixelHeight |
|||
}) |
|||
); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Rename_should_throw_exception_if_not_created() |
|||
{ |
|||
Assert.Throws<DomainException>(() => |
|||
{ |
|||
sut.Rename(CreateAssetCommand(new RenameAsset { FileName = "new-file.png" })); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Rename_should_throw_exception_if_asset_is_deleted() |
|||
{ |
|||
CreateAsset(); |
|||
DeleteAsset(); |
|||
|
|||
Assert.Throws<DomainException>(() => |
|||
{ |
|||
sut.Update(CreateAssetCommand(new UpdateAsset())); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Rename_should_create_events() |
|||
{ |
|||
CreateAsset(); |
|||
|
|||
sut.Rename(CreateAssetCommand(new RenameAsset { FileName = "my-new-image.png" })); |
|||
|
|||
Assert.Equal("my-new-image.png", sut.State.FileName); |
|||
|
|||
sut.GetUncomittedEvents() |
|||
.ShouldHaveSameEvents( |
|||
CreateAssetEvent(new AssetRenamed { FileName = "my-new-image.png" }) |
|||
); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Delete_should_throw_exception_if_not_created() |
|||
{ |
|||
Assert.Throws<DomainException>(() => |
|||
{ |
|||
sut.Delete(CreateAssetCommand(new DeleteAsset())); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Delete_should_throw_exception_if_already_deleted() |
|||
{ |
|||
CreateAsset(); |
|||
DeleteAsset(); |
|||
|
|||
Assert.Throws<DomainException>(() => |
|||
{ |
|||
sut.Delete(CreateAssetCommand(new DeleteAsset())); |
|||
}); |
|||
} |
|||
|
|||
[Fact] |
|||
public void Delete_should_create_events_with_total_file_size() |
|||
{ |
|||
CreateAsset(); |
|||
UpdateAsset(); |
|||
|
|||
sut.Delete(CreateAssetCommand(new DeleteAsset())); |
|||
|
|||
Assert.True(sut.State.IsDeleted); |
|||
|
|||
sut.GetUncomittedEvents() |
|||
.ShouldHaveSameEvents( |
|||
CreateAssetEvent(new AssetDeleted { DeletedSize = 2048 }) |
|||
); |
|||
} |
|||
|
|||
private void CreateAsset() |
|||
{ |
|||
sut.Create(CreateAssetCommand(new CreateAsset { File = file })); |
|||
sut.ClearUncommittedEvents(); |
|||
} |
|||
|
|||
private void UpdateAsset() |
|||
{ |
|||
sut.Update(CreateAssetCommand(new UpdateAsset { File = file })); |
|||
sut.ClearUncommittedEvents(); |
|||
} |
|||
|
|||
private void DeleteAsset() |
|||
{ |
|||
sut.Delete(CreateAssetCommand(new DeleteAsset())); |
|||
sut.ClearUncommittedEvents(); |
|||
} |
|||
|
|||
protected T CreateAssetEvent<T>(T @event) where T : AssetEvent |
|||
{ |
|||
@event.AssetId = assetId; |
|||
|
|||
return CreateEvent(@event); |
|||
} |
|||
|
|||
protected T CreateAssetCommand<T>(T command) where T : AssetAggregateCommand |
|||
{ |
|||
command.AssetId = assetId; |
|||
|
|||
return CreateCommand(command); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
// ==========================================================================
|
|||
// GuardAssetTests.cs
|
|||
// Squidex Headless CMS
|
|||
// ==========================================================================
|
|||
// Copyright (c) Squidex Group
|
|||
// All rights reserved.
|
|||
// ==========================================================================
|
|||
|
|||
using Squidex.Domain.Apps.Entities.Assets.Commands; |
|||
using Squidex.Infrastructure; |
|||
using Xunit; |
|||
|
|||
namespace Squidex.Domain.Apps.Entities.Assets.Guards |
|||
{ |
|||
public class GuardAssetTests |
|||
{ |
|||
[Fact] |
|||
public void CanRename_should_throw_exception_if_name_not_defined() |
|||
{ |
|||
var command = new RenameAsset(); |
|||
|
|||
Assert.Throws<ValidationException>(() => GuardAsset.CanRename(command, "asset-name")); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanRename_should_throw_exception_if_name_are_the_same() |
|||
{ |
|||
var command = new RenameAsset { FileName = "asset-name" }; |
|||
|
|||
Assert.Throws<ValidationException>(() => GuardAsset.CanRename(command, "asset-name")); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanRename_not_should_throw_exception_if_name_are_different() |
|||
{ |
|||
var command = new RenameAsset { FileName = "new-name" }; |
|||
|
|||
GuardAsset.CanRename(command, "asset-name"); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanCreate_should_not_throw_exception() |
|||
{ |
|||
var command = new CreateAsset(); |
|||
|
|||
GuardAsset.CanCreate(command); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanUpdate_should_not_throw_exception() |
|||
{ |
|||
var command = new UpdateAsset(); |
|||
|
|||
GuardAsset.CanUpdate(command); |
|||
} |
|||
|
|||
[Fact] |
|||
public void CanDelete_should_not_throw_exception() |
|||
{ |
|||
var command = new DeleteAsset(); |
|||
|
|||
GuardAsset.CanDelete(command); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue