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