Browse Source

Merge branch 'master' into feature/separators

pull/359/head
Sebastian Stehle 7 years ago
parent
commit
c671745a3d
  1. 25
      src/Squidex.Domain.Apps.Entities/Apps/Guards/GuardAppContributors.cs
  2. 2
      src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/ConfigAppPlansProvider.cs
  3. 25
      src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs
  4. 38
      src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs
  5. 38
      src/Squidex/Areas/Frontend/Middlewares/WebpackMiddleware.cs
  6. 2
      src/Squidex/app/features/settings/pages/plans/plans-page.component.html
  7. 4
      src/Squidex/app/framework/state.ts
  8. 1
      src/Squidex/app/shared/state/assets.forms.ts
  9. 4
      src/Squidex/appsettings.json
  10. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppGrainTests.cs
  11. 8
      tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppUISettingsGrainTests.cs
  12. 2
      tests/Squidex.Domain.Apps.Entities.Tests/Apps/Billing/ConfigAppLimitsProviderTests.cs
  13. 64
      tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppContributorsTests.cs
  14. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentQueryServiceTests.cs
  15. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs
  16. 52
      tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs
  17. 8
      tests/Squidex.Infrastructure.Tests/Assets/AssetStoreTests.cs
  18. 12
      tests/Squidex.Infrastructure.Tests/UsageTracking/BackgroundUsageTrackerTests.cs

25
src/Squidex.Domain.Apps.Entities/Apps/Guards/GuardAppContributors.cs

@ -44,21 +44,24 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards
command.ContributorId = user.Id;
if (string.Equals(command.ContributorId, command.Actor?.Identifier, StringComparison.OrdinalIgnoreCase) && !command.IsRestore)
if (!command.IsRestore)
{
throw new DomainForbiddenException("You cannot change your own role.");
}
if (string.Equals(command.ContributorId, command.Actor?.Identifier, StringComparison.OrdinalIgnoreCase))
{
throw new DomainForbiddenException("You cannot change your own role.");
}
if (contributors.TryGetValue(command.ContributorId, out var existing))
{
if (existing == command.Role)
if (contributors.TryGetValue(command.ContributorId, out var existing))
{
e(Not.New("Contributor", "role"), nameof(command.Role));
if (existing == command.Role)
{
e(Not.New("Contributor", "role"), nameof(command.Role));
}
}
else if (contributors.Count >= plan.MaxContributors)
{
e("You have reached the maximum number of contributors for your plan.");
}
}
else if (plan.MaxContributors == contributors.Count)
{
e("You have reached the maximum number of contributors for your plan.");
}
});
}

2
src/Squidex.Domain.Apps.Entities/Apps/Services/Implementations/ConfigAppPlansProvider.cs

@ -20,7 +20,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Services.Implementations
Name = "Infinite",
MaxApiCalls = -1,
MaxAssetSize = -1,
MaxContributors = -1
MaxContributors = int.MaxValue
};
private readonly Dictionary<string, ConfigAppLimitsPlan> plansById = new Dictionary<string, ConfigAppLimitsPlan>(StringComparer.OrdinalIgnoreCase);

25
src/Squidex.Domain.Apps.Entities/Backup/RestoreGrain.cs

@ -246,16 +246,23 @@ namespace Squidex.Domain.Apps.Entities.Backup
if (actor?.IsSubject == true)
{
await commandBus.PublishAsync(new AssignContributor
try
{
Actor = actor,
AppId = CurrentJob.AppId,
ContributorId = actor.Identifier,
IsRestore = true,
Role = Role.Owner
});
Log("Assigned current user.");
await commandBus.PublishAsync(new AssignContributor
{
Actor = actor,
AppId = CurrentJob.AppId,
ContributorId = actor.Identifier,
IsRestore = true,
Role = Role.Owner
});
Log("Assigned current user.");
}
catch (DomainException ex)
{
Log($"Failed to assign contributor: {ex.Message}");
}
}
else
{

38
src/Squidex/Areas/Api/Controllers/Assets/AssetContentController.cs

@ -8,6 +8,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Net.Http.Headers;
using Squidex.Domain.Apps.Entities.Assets;
@ -47,7 +48,8 @@ namespace Squidex.Areas.Api.Controllers.Assets
/// <summary>
/// Get the asset content.
/// </summary>
/// <param name="id">The id of the asset.</param>
/// <param name="app">The name of the app.</param>
/// <param name="idOrSlug">The id or slug of the asset.</param>
/// <param name="more">Optional suffix that can be used to seo-optimize the link to the image Has not effect.</param>
/// <param name="version">The optional version of the asset.</param>
/// <param name="width">The target width of the asset, if it is an image.</param>
@ -59,17 +61,27 @@ namespace Squidex.Areas.Api.Controllers.Assets
/// 404 => Asset or app not found.
/// </returns>
[HttpGet]
[Route("assets/{id}/{*more}")]
[Route("assets/{app}/{idOrSlug}/{*more}")]
[ProducesResponseType(typeof(FileResult), 200)]
[ApiCosts(0.5)]
public async Task<IActionResult> GetAssetContent(Guid id, string more,
[AllowAnonymous]
public async Task<IActionResult> GetAssetContentBySlug(string app, string idOrSlug, string more,
[FromQuery] long version = EtagVersion.Any,
[FromQuery] int? width = null,
[FromQuery] int? height = null,
[FromQuery] int? quality = null,
[FromQuery] string mode = null)
{
var entity = await assetRepository.FindAssetAsync(id);
IAssetEntity entity;
if (Guid.TryParse(idOrSlug, out var guid))
{
entity = await assetRepository.FindAssetAsync(guid);
}
else
{
entity = await assetRepository.FindAssetBySlugAsync(App.Id, idOrSlug);
}
return DeliverAsset(entity, version, width, height, quality, mode);
}
@ -77,8 +89,7 @@ namespace Squidex.Areas.Api.Controllers.Assets
/// <summary>
/// Get the asset content.
/// </summary>
/// <param name="app">The name of the app.</param>
/// <param name="idOrSlug">The id or slug of the asset.</param>
/// <param name="id">The id of the asset.</param>
/// <param name="more">Optional suffix that can be used to seo-optimize the link to the image Has not effect.</param>
/// <param name="version">The optional version of the asset.</param>
/// <param name="width">The target width of the asset, if it is an image.</param>
@ -90,26 +101,17 @@ namespace Squidex.Areas.Api.Controllers.Assets
/// 404 => Asset or app not found.
/// </returns>
[HttpGet]
[Route("assets/{app}/{idOrSlug}/{*more}")]
[Route("assets/{id}/{*more}")]
[ProducesResponseType(typeof(FileResult), 200)]
[ApiCosts(0.5)]
public async Task<IActionResult> GetAssetContent(string app, string idOrSlug, string more,
public async Task<IActionResult> GetAssetContent(Guid id, string more,
[FromQuery] long version = EtagVersion.Any,
[FromQuery] int? width = null,
[FromQuery] int? height = null,
[FromQuery] int? quality = null,
[FromQuery] string mode = null)
{
IAssetEntity entity;
if (Guid.TryParse(idOrSlug, out var guid))
{
entity = await assetRepository.FindAssetAsync(guid);
}
else
{
entity = await assetRepository.FindAssetBySlugAsync(App.Id, idOrSlug);
}
var entity = await assetRepository.FindAssetAsync(id);
return DeliverAsset(entity, version, width, height, quality, mode);
}

38
src/Squidex/Areas/Frontend/Middlewares/WebpackMiddleware.cs

@ -25,28 +25,25 @@ namespace Squidex.Areas.Frontend.Middlewares
public async Task Invoke(HttpContext context)
{
if (context.IsIndex())
if (context.IsIndex() && context.Response.StatusCode != 304)
{
if (context.Response.StatusCode != 304)
using (var client = new HttpClient())
{
using (var client = new HttpClient())
{
var result = await client.GetAsync(WebpackUrl);
var result = await client.GetAsync(WebpackUrl);
context.Response.StatusCode = (int)result.StatusCode;
context.Response.StatusCode = (int)result.StatusCode;
if (result.IsSuccessStatusCode)
{
var html = await result.Content.ReadAsStringAsync();
if (result.IsSuccessStatusCode)
{
var html = await result.Content.ReadAsStringAsync();
html = AdjustBase(html, context.Request.PathBase);
html = AdjustBase(html, context.Request.PathBase);
await context.Response.WriteHtmlAsync(html);
}
await context.Response.WriteHtmlAsync(html);
}
}
}
else if (context.IsHtmlPath())
else if (context.IsHtmlPath() && context.Response.StatusCode != 304)
{
var responseBuffer = new MemoryStream();
var responseBody = context.Response.Body;
@ -55,16 +52,19 @@ namespace Squidex.Areas.Frontend.Middlewares
await next(context);
context.Response.Body = responseBody;
if (context.Response.StatusCode != 304)
{
context.Response.Body = responseBody;
var html = Encoding.UTF8.GetString(responseBuffer.ToArray());
var html = Encoding.UTF8.GetString(responseBuffer.ToArray());
html = AdjustBase(html, context.Request.PathBase);
html = AdjustBase(html, context.Request.PathBase);
context.Response.ContentLength = Encoding.UTF8.GetByteCount(html);
context.Response.Body = responseBody;
context.Response.ContentLength = Encoding.UTF8.GetByteCount(html);
context.Response.Body = responseBody;
await context.Response.WriteAsync(html);
await context.Response.WriteAsync(html);
}
}
else
{

2
src/Squidex/app/features/settings/pages/plans/plans-page.component.html

@ -1,6 +1,6 @@
<sqx-title message="{app} | Plans | Settings" parameter1="app" [value1]="appsState.appName"></sqx-title>
<sqx-panel desiredWidth="63rem" [showSidebar]="true">
<sqx-panel desiredWidth="64rem" [showSidebar]="true">
<ng-container title>
Update Plan
</ng-container>

4
src/Squidex/app/framework/state.ts

@ -71,7 +71,9 @@ export class Form<T extends AbstractControl, V> {
if (this.form.valid) {
const value = this.transformSubmit(fullValue(this.form));
this.disable();
if (value) {
this.disable();
}
return value;
} else {

1
src/Squidex/app/shared/state/assets.forms.ts

@ -57,6 +57,7 @@ export class AnnotateAssetForm extends Form<FormGroup, { fileName?: string, slug
}
if (Object.keys(result).length === 0) {
this.enable();
return null;
}
}

4
src/Squidex/appsettings.json

@ -104,7 +104,7 @@
/*
* The email body when a new user is added as contributor.
*/
"newUserBody": "Welcome to Squidex\r\nDear User,\r\n\r\n{{$ASSIGNER_NAME}} ($ASSIGNER_EMAIL) has invited you to join Project (also called an App) {{var:app_name}} at Squidex Headless CMS. Login with your Github, Google or Microsoft credentials to create a new user account and start editing content now.\r\n\r\nThank you very much,\r\nThe Squidex Team\r\n\r\n<<Start now!>> [$UI_URL]",
"newUserBody": "Welcome to Squidex\r\nDear User,\r\n\r\n$ASSIGNER_NAME ($ASSIGNER_EMAIL) has invited you to join Project (also called an App) $APP_NAME at Squidex Headless CMS. Login with your Github, Google or Microsoft credentials to create a new user account and start editing content now.\r\n\r\nThank you very much,\r\nThe Squidex Team\r\n\r\n<<Start now!>> [$UI_URL]",
/*
* The email subject when an existing user is added as contributor.
*/
@ -112,7 +112,7 @@
/*
* The email body when an existing user is added as contributor.
*/
"existingUserBody": "Dear User,\r\n\r\n{{$ASSIGNER_NAME}} ($ASSIGNER_EMAIL) has invited you to join App {{var:app_name}} at Squidex Headless CMS.\r\n\r\nLogin or reload the Management UI to see the App.\r\n\r\nThank you very much,\r\nThe Squidex Team\r\n\r\n<<Start now!>> [$UI_URL]"
"existingUserBody": "Dear User,\r\n\r\n$ASSIGNER_NAME ($ASSIGNER_EMAIL) has invited you to join App $APP_NAME at Squidex Headless CMS.\r\n\r\nLogin or reload the Management UI to see the App.\r\n\r\nThank you very much,\r\nThe Squidex Team\r\n\r\n<<Start now!>> [$UI_URL]"
}
},

4
tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppGrainTests.cs

@ -12,6 +12,7 @@ using FakeItEasy;
using Squidex.Domain.Apps.Core.Apps;
using Squidex.Domain.Apps.Entities.Apps.Commands;
using Squidex.Domain.Apps.Entities.Apps.Services;
using Squidex.Domain.Apps.Entities.Apps.Services.Implementations;
using Squidex.Domain.Apps.Entities.Apps.State;
using Squidex.Domain.Apps.Entities.TestHelpers;
using Squidex.Domain.Apps.Events.Apps;
@ -54,6 +55,9 @@ namespace Squidex.Domain.Apps.Entities.Apps
A.CallTo(() => userResolver.FindByIdOrEmailAsync(contributorId))
.Returns(user);
A.CallTo(() => appPlansProvider.GetPlan(A<string>.Ignored))
.Returns(new ConfigAppLimitsPlan { MaxContributors = 10 });
initialPatterns = new InitialPatterns
{
{ patternId1, new AppPattern("Number", "[0-9]") },

8
tests/Squidex.Domain.Apps.Entities.Tests/Apps/AppUISettingsGrainTests.cs

@ -107,15 +107,15 @@ namespace Squidex.Domain.Apps.Entities.Apps
}
[Fact]
public Task Should_do_nothing_if_deleting_and_nested_not_found()
public async Task Should_do_nothing_if_deleting_and_nested_not_found()
{
return sut.RemoveAsync("root.nested");
await sut.RemoveAsync("root.nested");
}
[Fact]
public Task Should_do_nothing_if_deleting_and_key_not_found()
public async Task Should_do_nothing_if_deleting_and_key_not_found()
{
return sut.RemoveAsync("root");
await sut.RemoveAsync("root");
}
}
}

2
tests/Squidex.Domain.Apps.Entities.Tests/Apps/Billing/ConfigAppLimitsProviderTests.cs

@ -23,7 +23,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Billing
Name = "Infinite",
MaxApiCalls = -1,
MaxAssetSize = -1,
MaxContributors = -1
MaxContributors = int.MaxValue
};
private static readonly ConfigAppLimitsPlan FreePlan = new ConfigAppLimitsPlan

64
tests/Squidex.Domain.Apps.Entities.Tests/Apps/Guards/GuardAppContributorsTests.cs

@ -51,52 +51,62 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards
}
[Fact]
public Task CanAssign_should_throw_exception_if_contributor_id_is_null()
public async Task CanAssign_should_throw_exception_if_contributor_id_is_null()
{
var command = new AssignContributor();
return ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan),
await ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan),
new ValidationError("Contributor id is required.", "ContributorId"));
}
[Fact]
public Task CanAssign_should_throw_exception_if_role_not_valid()
public async Task CanAssign_should_throw_exception_if_role_not_valid()
{
var command = new AssignContributor { ContributorId = "1", Role = "Invalid" };
return ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan),
await ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan),
new ValidationError("Role is not a valid value.", "Role"));
}
[Fact]
public Task CanAssign_should_throw_exception_if_user_already_exists_with_same_role()
public async Task CanAssign_should_throw_exception_if_user_already_exists_with_same_role()
{
var command = new AssignContributor { ContributorId = "1", Role = Role.Owner };
var contributors_1 = contributors_0.Assign("1", Role.Owner);
return ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_1, roles, command, users, appPlan),
await ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_1, roles, command, users, appPlan),
new ValidationError("Contributor has already this role.", "Role"));
}
[Fact]
public Task CanAssign_should_throw_exception_if_user_not_found()
public async Task CanAssign_should_not_throw_exception_if_user_already_exists_with_some_role_but_is_from_restore()
{
var command = new AssignContributor { ContributorId = "1", Role = Role.Owner, IsRestore = true };
var contributors_1 = contributors_0.Assign("1", Role.Owner);
await GuardAppContributors.CanAssign(contributors_1, roles, command, users, appPlan);
}
[Fact]
public async Task CanAssign_should_throw_exception_if_user_not_found()
{
var command = new AssignContributor { ContributorId = "notfound", Role = Role.Owner };
return Assert.ThrowsAsync<DomainObjectNotFoundException>(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan));
await Assert.ThrowsAsync<DomainObjectNotFoundException>(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan));
}
[Fact]
public Task CanAssign_should_throw_exception_if_user_is_actor()
public async Task CanAssign_should_throw_exception_if_user_is_actor()
{
var command = new AssignContributor { ContributorId = "3", Role = Role.Editor, Actor = new RefToken("user", "3") };
return Assert.ThrowsAsync<DomainForbiddenException>(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan));
await Assert.ThrowsAsync<DomainForbiddenException>(() => GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan));
}
[Fact]
public Task CanAssign_should_throw_exception_if_contributor_max_reached()
public async Task CanAssign_should_throw_exception_if_contributor_max_reached()
{
A.CallTo(() => appPlan.MaxContributors)
.Returns(2);
@ -106,7 +116,7 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards
var contributors_1 = contributors_0.Assign("1", Role.Owner);
var contributors_2 = contributors_1.Assign("2", Role.Editor);
return ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_2, roles, command, users, appPlan),
await ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(contributors_2, roles, command, users, appPlan),
new ValidationError("You have reached the maximum number of contributors for your plan."));
}
@ -121,35 +131,49 @@ namespace Squidex.Domain.Apps.Entities.Apps.Guards
}
[Fact]
public Task CanAssign_should_not_throw_exception_if_user_found()
public async Task CanAssign_should_not_throw_exception_if_user_found()
{
var command = new AssignContributor { ContributorId = "1" };
return GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan);
await GuardAppContributors.CanAssign(contributors_0, roles, command, users, appPlan);
}
[Fact]
public Task CanAssign_should_not_throw_exception_if_contributor_has_another_role()
public async Task CanAssign_should_not_throw_exception_if_contributor_has_another_role()
{
var command = new AssignContributor { ContributorId = "1", Role = Role.Developer };
var command = new AssignContributor { ContributorId = "1" };
var contributors_1 = contributors_0.Assign("1", Role.Editor);
return GuardAppContributors.CanAssign(contributors_1, roles, command, users, appPlan);
await GuardAppContributors.CanAssign(contributors_1, roles, command, users, appPlan);
}
[Fact]
public async Task CanAssign_should_not_throw_exception_if_contributor_max_reached_but_role_changed()
{
A.CallTo(() => appPlan.MaxContributors)
.Returns(2);
var command = new AssignContributor { ContributorId = "1" };
var contributors_1 = contributors_0.Assign("1", Role.Editor);
var contributors_2 = contributors_1.Assign("2", Role.Editor);
await GuardAppContributors.CanAssign(contributors_2, roles, command, users, appPlan);
}
[Fact]
public Task CanAssign_should_not_throw_exception_if_contributor_max_reached_but_role_changed()
public async Task CanAssign_should_not_throw_exception_if_contributor_max_reached_but_from_restore()
{
A.CallTo(() => appPlan.MaxContributors)
.Returns(2);
var command = new AssignContributor { ContributorId = "1", Role = Role.Developer };
var command = new AssignContributor { ContributorId = "3", IsRestore = true };
var contributors_1 = contributors_0.Assign("1", Role.Editor);
var contributors_2 = contributors_1.Assign("2", Role.Editor);
return GuardAppContributors.CanAssign(contributors_2, roles, command, users, appPlan);
await GuardAppContributors.CanAssign(contributors_2, roles, command, users, appPlan);
}
[Fact]

4
tests/Squidex.Domain.Apps.Entities.Tests/Contents/ContentQueryServiceTests.cs

@ -328,14 +328,14 @@ namespace Squidex.Domain.Apps.Entities.Contents
}
[Fact]
public Task Should_throw_if_query_is_invalid()
public async Task Should_throw_if_query_is_invalid()
{
SetupClaims(isFrontend: false);
SetupSchemaFound();
var query = Q.Empty.WithODataQuery("$filter=invalid");
return Assert.ThrowsAsync<ValidationException>(() => sut.QueryAsync(context, schemaId.Name, query));
await Assert.ThrowsAsync<ValidationException>(() => sut.QueryAsync(context, schemaId.Name, query));
}
public static IEnumerable<object[]> ManyDataFrontend = new[]

4
tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleEnqueuerTests.cs

@ -60,9 +60,9 @@ namespace Squidex.Domain.Apps.Entities.Rules
}
[Fact]
public Task Should_do_nothing_on_clear()
public async Task Should_do_nothing_on_clear()
{
return sut.ClearAsync();
await sut.ClearAsync();
}
[Fact]

52
tests/Squidex.Domain.Apps.Entities.Tests/Schemas/Guards/GuardSchemaTests.cs

@ -41,25 +41,25 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
}
[Fact]
public Task CanCreate_should_throw_exception_if_name_not_valid()
public async Task CanCreate_should_throw_exception_if_name_not_valid()
{
var command = new CreateSchema { AppId = appId, Name = "INVALID NAME" };
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Name is not a valid slug.", "Name"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_name_already_in_use()
public async Task CanCreate_should_throw_exception_if_name_already_in_use()
{
var command = new CreateSchema { AppId = appId, Name = "existing" };
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("A schema with the same name already exists."));
}
[Fact]
public Task CanCreate_should_throw_exception_if_field_name_invalid()
public async Task CanCreate_should_throw_exception_if_field_name_invalid()
{
var command = new CreateSchema
{
@ -76,13 +76,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Field name must be a valid javascript property name.",
"Fields[1].Name"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_field_properties_null()
public async Task CanCreate_should_throw_exception_if_field_properties_null()
{
var command = new CreateSchema
{
@ -99,13 +99,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Field properties is required.",
"Fields[1].Properties"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_field_properties_not_valid()
public async Task CanCreate_should_throw_exception_if_field_properties_not_valid()
{
var command = new CreateSchema
{
@ -122,14 +122,14 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Max length must be greater or equal to min length.",
"Fields[1].Properties.MinLength",
"Fields[1].Properties.MaxLength"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_field_partitioning_not_valid()
public async Task CanCreate_should_throw_exception_if_field_partitioning_not_valid()
{
var command = new CreateSchema
{
@ -146,13 +146,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Partitioning is not a valid value.",
"Fields[1].Partitioning"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_fields_contains_duplicate_name()
public async Task CanCreate_should_throw_exception_if_fields_contains_duplicate_name()
{
var command = new CreateSchema
{
@ -175,13 +175,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Fields cannot have duplicate names.",
"Fields"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_nested_field_name_invalid()
public async Task CanCreate_should_throw_exception_if_nested_field_name_invalid()
{
var command = new CreateSchema
{
@ -206,13 +206,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Field name must be a valid javascript property name.",
"Fields[1].Nested[1].Name"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_nested_field_properties_null()
public async Task CanCreate_should_throw_exception_if_nested_field_properties_null()
{
var command = new CreateSchema
{
@ -237,13 +237,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Field properties is required.",
"Fields[1].Nested[1].Properties"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_nested_field_is_array()
public async Task CanCreate_should_throw_exception_if_nested_field_is_array()
{
var command = new CreateSchema
{
@ -268,13 +268,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Nested field cannot be array fields.",
"Fields[1].Nested[1].Properties"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_nested_field_properties_not_valid()
public async Task CanCreate_should_throw_exception_if_nested_field_properties_not_valid()
{
var command = new CreateSchema
{
@ -299,14 +299,14 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Max length must be greater or equal to min length.",
"Fields[1].Nested[1].Properties.MinLength",
"Fields[1].Nested[1].Properties.MaxLength"));
}
[Fact]
public Task CanCreate_should_throw_exception_if_nested_field_have_duplicate_names()
public async Task CanCreate_should_throw_exception_if_nested_field_have_duplicate_names()
{
var command = new CreateSchema
{
@ -336,13 +336,13 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
await ValidationAssert.ThrowsAsync(() => GuardSchema.CanCreate(command, appProvider),
new ValidationError("Fields cannot have duplicate names.",
"Fields[1].Nested"));
}
[Fact]
public Task CanCreate_should_not_throw_exception_if_command_is_valid()
public async Task CanCreate_should_not_throw_exception_if_command_is_valid()
{
var command = new CreateSchema
{
@ -384,7 +384,7 @@ namespace Squidex.Domain.Apps.Entities.Schemas.Guards
Name = "new-schema"
};
return GuardSchema.CanCreate(command, appProvider);
await GuardSchema.CanCreate(command, appProvider);
}
[Fact]

8
tests/Squidex.Infrastructure.Tests/Assets/AssetStoreTests.cs

@ -37,15 +37,15 @@ namespace Squidex.Infrastructure.Assets
public abstract T CreateStore();
[Fact]
public virtual Task Should_throw_exception_if_asset_to_download_is_not_found()
public virtual async Task Should_throw_exception_if_asset_to_download_is_not_found()
{
return Assert.ThrowsAsync<AssetNotFoundException>(() => Sut.DownloadAsync(fileName, new MemoryStream()));
await Assert.ThrowsAsync<AssetNotFoundException>(() => Sut.DownloadAsync(fileName, new MemoryStream()));
}
[Fact]
public Task Should_throw_exception_if_asset_to_copy_is_not_found()
public async Task Should_throw_exception_if_asset_to_copy_is_not_found()
{
return Assert.ThrowsAsync<AssetNotFoundException>(() => Sut.CopyAsync(fileName, sourceFile));
await Assert.ThrowsAsync<AssetNotFoundException>(() => Sut.CopyAsync(fileName, sourceFile));
}
[Fact]

12
tests/Squidex.Infrastructure.Tests/UsageTracking/BackgroundUsageTrackerTests.cs

@ -28,27 +28,27 @@ namespace Squidex.Infrastructure.UsageTracking
}
[Fact]
public Task Should_throw_exception_if_tracking_on_disposed_object()
public async Task Should_throw_exception_if_tracking_on_disposed_object()
{
sut.Dispose();
return Assert.ThrowsAsync<ObjectDisposedException>(() => sut.TrackAsync(key, "category1", 1, 1000));
await Assert.ThrowsAsync<ObjectDisposedException>(() => sut.TrackAsync(key, "category1", 1, 1000));
}
[Fact]
public Task Should_throw_exception_if_querying_on_disposed_object()
public async Task Should_throw_exception_if_querying_on_disposed_object()
{
sut.Dispose();
return Assert.ThrowsAsync<ObjectDisposedException>(() => sut.QueryAsync(key, DateTime.Today, DateTime.Today.AddDays(1)));
await Assert.ThrowsAsync<ObjectDisposedException>(() => sut.QueryAsync(key, DateTime.Today, DateTime.Today.AddDays(1)));
}
[Fact]
public Task Should_throw_exception_if_querying_montly_usage_on_disposed_object()
public async Task Should_throw_exception_if_querying_montly_usage_on_disposed_object()
{
sut.Dispose();
return Assert.ThrowsAsync<ObjectDisposedException>(() => sut.GetMonthlyCallsAsync(key, DateTime.Today));
await Assert.ThrowsAsync<ObjectDisposedException>(() => sut.GetMonthlyCallsAsync(key, DateTime.Today));
}
[Fact]

Loading…
Cancel
Save