Browse Source

JScript editor.

pull/104/head
Sebastian Stehle 9 years ago
parent
commit
824c88bed3
  1. 2
      Squidex.sln.DotSettings
  2. 2
      src/Squidex.Domain.Apps.Core/ContentEnricher.cs
  3. 2
      src/Squidex.Domain.Apps.Core/ContentValidator.cs
  4. 2
      src/Squidex.Domain.Apps.Core/Contents/IdContentData.cs
  5. 10
      src/Squidex.Domain.Apps.Core/Contents/NamedContentData.cs
  6. 4
      src/Squidex.Domain.Apps.Core/Schemas/Field_Generic.cs
  7. 2
      src/Squidex.Domain.Apps.Core/Schemas/Schema.cs
  8. 4
      src/Squidex.Domain.Apps.Core/Schemas/Validators/AssetsValidator.cs
  9. 4
      src/Squidex.Domain.Apps.Core/Schemas/Validators/ReferencesValidator.cs
  10. 4
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/Visitors/ConstantVisitor.cs
  11. 2
      src/Squidex.Domain.Apps.Read.MongoDb/Contents/Visitors/PropertyVisitor.cs
  12. 2
      src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj
  13. 2
      src/Squidex.Domain.Apps.Read/Contents/GraphQL/Types/ContentQueryGraphType.cs
  14. 2
      src/Squidex.Domain.Apps.Read/Webhooks/WebhookSender.cs
  15. 2
      src/Squidex.Domain.Apps.Write/Apps/AppContributors.cs
  16. 16
      src/Squidex.Domain.Apps.Write/Contents/ContentCommandMiddleware.cs
  17. 2
      src/Squidex.Domain.Apps.Write/Schemas/SchemaDomainObject.cs
  18. 1
      src/Squidex.Domain.Users/UserExtensions.cs
  19. 2
      src/Squidex.Infrastructure.GetEventStore/CQRS/Events/GetEventStoreSubscription.cs
  20. 2
      src/Squidex.Infrastructure.Redis/RedisSubscription.cs
  21. 2
      src/Squidex.Infrastructure/CQRS/DomainObjectBase.cs
  22. 4
      src/Squidex.Infrastructure/CollectionExtensions.cs
  23. 2
      src/Squidex.Infrastructure/DomainObjectException.cs
  24. 2
      src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs
  25. 2
      src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs
  26. 5
      src/Squidex.Infrastructure/Json/PropertiesBagConverter.cs
  27. 2
      src/Squidex.Infrastructure/Language.cs
  28. 2
      src/Squidex.Infrastructure/PropertiesBag.cs
  29. 6
      src/Squidex.Infrastructure/PropertyValue.cs
  30. 2
      src/Squidex.Infrastructure/Reflection/PropertiesTypeAccessor.cs
  31. 2
      src/Squidex.Infrastructure/StringExtensions.cs
  32. 1
      src/Squidex.Infrastructure/TypeNameRegistry.cs
  33. 1
      src/Squidex/Config/Identity/IdentityUsage.cs
  34. 1
      src/Squidex/Config/Identity/MicrosoftIdentityUsage.cs
  35. 4
      src/Squidex/Config/Swagger/XmlResponseTypesProcessor.cs
  36. 30
      src/Squidex/Controllers/Api/Schemas/Models/SchemaDetailsDto.cs
  37. 4
      src/Squidex/Controllers/ContentApi/ContentsController.cs
  38. 2
      src/Squidex/Controllers/ContentApi/Generator/SchemaSwaggerGenerator.cs
  39. 22
      src/Squidex/Controllers/ContentApi/Models/ContentDto.cs
  40. 1
      src/Squidex/Pipeline/ApiExceptionFilterAttribute.cs
  41. 2
      src/Squidex/Pipeline/CommandHandlers/ETagCommandMiddleware.cs
  42. 2
      src/Squidex/Pipeline/Swagger/SwaggerHelper.cs
  43. 2
      src/Squidex/Squidex.csproj
  44. 4
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  45. 1
      src/Squidex/app/framework/angular/jscript-editor.component.html
  46. 8
      src/Squidex/app/framework/angular/jscript-editor.component.scss
  47. 108
      src/Squidex/app/framework/angular/jscript-editor.component.ts
  48. 1
      src/Squidex/app/framework/declarations.ts
  49. 3
      src/Squidex/app/framework/module.ts
  50. 59
      src/Squidex/app/shared/services/schemas.service.spec.ts
  51. 117
      src/Squidex/app/shared/services/schemas.service.ts
  52. 24
      tests/Squidex.Domain.Apps.Write.Tests/Schemas/SchemaDomainObjectTests.cs
  53. 7
      tests/Squidex.Infrastructure.Tests/Caching/InvalidatingMemoryCacheTest.cs
  54. 4
      tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj

2
Squidex.sln.DotSettings

@ -24,8 +24,10 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToAutoProperty/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToAutoPropertyWhenPossible/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ConvertToConstant_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InheritdocConsiderUsage/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=MemberCanBePrivate_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=Mvc_002EViewNotResolved/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ParameterOnlyUsedForPreconditionCheck_002ELocal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReturnTypeCanBeEnumerable_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnnecessaryWhitespace/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=UnusedAutoPropertyAccessor_002EGlobal/@EntryIndexedValue">DO_NOT_SHOW</s:String>

2
src/Squidex.Domain.Apps.Core/ContentEnricher.cs

@ -64,7 +64,7 @@ namespace Squidex.Domain.Apps.Core
var key = partitionItem.Key;
if (!fieldData.TryGetValue(key, out JToken value) || value == null || value.Type == JTokenType.Null)
if (!fieldData.TryGetValue(key, out var value) || value == null || value.Type == JTokenType.Null)
{
fieldData.AddValue(key, defaultValue);
}

2
src/Squidex.Domain.Apps.Core/ContentValidator.cs

@ -50,7 +50,7 @@ namespace Squidex.Domain.Apps.Core
{
var fieldName = fieldData.Key;
if (!schema.FieldsByName.TryGetValue(fieldData.Key, out Field field))
if (!schema.FieldsByName.TryGetValue(fieldData.Key, out var field))
{
errors.AddError("<FIELD> is not a known field", fieldName);
}

2
src/Squidex.Domain.Apps.Core/Contents/IdContentData.cs

@ -85,7 +85,7 @@ namespace Squidex.Domain.Apps.Core.Contents
foreach (var fieldValue in this)
{
if (!schema.FieldsById.TryGetValue(fieldValue.Key, out Field field))
if (!schema.FieldsById.TryGetValue(fieldValue.Key, out var field))
{
continue;
}

10
src/Squidex.Domain.Apps.Core/Contents/NamedContentData.cs

@ -52,7 +52,7 @@ namespace Squidex.Domain.Apps.Core.Contents
foreach (var fieldValue in this)
{
if (!schema.FieldsByName.TryGetValue(fieldValue.Key, out Field field))
if (!schema.FieldsByName.TryGetValue(fieldValue.Key, out var field))
{
continue;
}
@ -100,7 +100,7 @@ namespace Squidex.Domain.Apps.Core.Contents
foreach (var fieldValue in this)
{
if (!schema.FieldsByName.TryGetValue(fieldValue.Key, out Field field) || (excludeHidden && field.IsHidden))
if (!schema.FieldsByName.TryGetValue(fieldValue.Key, out var field) || (excludeHidden && field.IsHidden))
{
continue;
}
@ -114,7 +114,7 @@ namespace Squidex.Domain.Apps.Core.Contents
{
var languageCode = languageConfig.Key;
if (fieldValues.TryGetValue(languageCode, out JToken value))
if (fieldValues.TryGetValue(languageCode, out var value))
{
fieldResult.Add(languageCode, value);
}
@ -126,7 +126,7 @@ namespace Squidex.Domain.Apps.Core.Contents
}
else
{
if (fieldValues.TryGetValue(codeForInvariant, out JToken value))
if (fieldValues.TryGetValue(codeForInvariant, out var value))
{
fieldResult.Add(codeForInvariant, value);
}
@ -168,7 +168,7 @@ namespace Squidex.Domain.Apps.Core.Contents
foreach (var language in languagePreferences)
{
if (fieldValues.TryGetValue(language, out JToken value) && value != null)
if (fieldValues.TryGetValue(language, out var value) && value != null)
{
result[fieldValue.Key] = value;

4
src/Squidex.Domain.Apps.Core/Schemas/Field_Generic.cs

@ -46,9 +46,7 @@ namespace Squidex.Domain.Apps.Core.Schemas
newProperties.Freeze();
var typedProperties = newProperties as T;
if (typedProperties == null)
if (!(newProperties is T typedProperties))
{
throw new ArgumentException($"Properties must be of type '{typeof(T)}", nameof(newProperties));
}

2
src/Squidex.Domain.Apps.Core/Schemas/Schema.cs

@ -179,7 +179,7 @@ namespace Squidex.Domain.Apps.Core.Schemas
{
Guard.NotNull(updater, nameof(updater));
if (!fieldsById.TryGetValue(fieldId, out Field field))
if (!fieldsById.TryGetValue(fieldId, out var field))
{
throw new DomainObjectNotFoundException(fieldId.ToString(), "Fields", typeof(Field));
}

4
src/Squidex.Domain.Apps.Core/Schemas/Validators/AssetsValidator.cs

@ -26,9 +26,7 @@ namespace Squidex.Domain.Apps.Core.Schemas.Validators
public async Task ValidateAsync(object value, ValidationContext context, Action<string> addError)
{
var assets = value as AssetsValue;
if (assets == null || assets.AssetIds.Count == 0)
if (!(value is AssetsValue assets) || assets.AssetIds.Count == 0)
{
if (isRequired && !context.IsOptional)
{

4
src/Squidex.Domain.Apps.Core/Schemas/Validators/ReferencesValidator.cs

@ -28,9 +28,7 @@ namespace Squidex.Domain.Apps.Core.Schemas.Validators
public async Task ValidateAsync(object value, ValidationContext context, Action<string> addError)
{
var references = value as ReferencesValue;
if (references == null || references.ContentIds.Count == 0)
if (!(value is ReferencesValue references) || references.ContentIds.Count == 0)
{
if (isRequired && !context.IsOptional)
{

4
src/Squidex.Domain.Apps.Read.MongoDb/Contents/Visitors/ConstantVisitor.cs

@ -45,9 +45,9 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents.Visitors
{
var value = Visit(nodeIn.Source);
if (value is DateTimeOffset)
if (value is DateTimeOffset dateTimeOffset)
{
return Instant.FromDateTimeOffset((DateTimeOffset)value);
return Instant.FromDateTimeOffset(dateTimeOffset);
}
return InstantPattern.General.Parse(Visit(nodeIn.Source).ToString()).Value;

2
src/Squidex.Domain.Apps.Read.MongoDb/Contents/Visitors/PropertyVisitor.cs

@ -30,7 +30,7 @@ namespace Squidex.Domain.Apps.Read.MongoDb.Contents.Visitors
{
var edmName = propertyNames[1].UnescapeEdmField();
if (!schema.FieldsByName.TryGetValue(edmName, out Field field))
if (!schema.FieldsByName.TryGetValue(edmName, out var field))
{
throw new NotSupportedException();
}

2
src/Squidex.Domain.Apps.Read.MongoDb/Squidex.Domain.Apps.Read.MongoDb.csproj

@ -14,7 +14,7 @@
<ProjectReference Include="..\Squidex.Domain.Apps.Read\Squidex.Domain.Apps.Read.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.OData.Core" Version="7.2.0" />
<PackageReference Include="Microsoft.OData.Core" Version="7.3.1" />
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
</ItemGroup>

2
src/Squidex.Domain.Apps.Read/Contents/GraphQL/Types/ContentQueryGraphType.cs

@ -14,6 +14,8 @@ using GraphQL.Types;
using Squidex.Domain.Apps.Read.Schemas;
using Squidex.Infrastructure;
// ReSharper disable ImpureMethodCallOnReadonlyValueField
namespace Squidex.Domain.Apps.Read.Contents.GraphQL.Types
{
public sealed class ContentQueryGraphType : ObjectGraphType

2
src/Squidex.Domain.Apps.Read/Webhooks/WebhookSender.cs

@ -25,7 +25,7 @@ namespace Squidex.Domain.Apps.Read.Webhooks
{
try
{
HttpRequestMessage request = BuildRequest(job);
var request = BuildRequest(job);
HttpResponseMessage response = null;
var responseString = string.Empty;

2
src/Squidex.Domain.Apps.Write/Apps/AppContributors.cs

@ -55,7 +55,7 @@ namespace Squidex.Domain.Apps.Write.Apps
private void ThrowIfFound(string contributorId, PermissionLevel permission, Func<string> message)
{
if (contributors.TryGetValue(contributorId, out PermissionLevel currentPermission) && currentPermission == permission)
if (contributors.TryGetValue(contributorId, out var currentPermission) && currentPermission == permission)
{
var error = new ValidationError("Contributor is already part of the app with same permissions", "ContributorId");

16
src/Squidex.Domain.Apps.Write/Contents/ContentCommandMiddleware.cs

@ -68,8 +68,8 @@ namespace Squidex.Domain.Apps.Write.Contents
var schemaAndApp = await ResolveSchemaAndAppAsync(command);
var scriptContext = CreateScriptContext(content, command, command.Data);
command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.Schema.ScriptCreate, "create content", true);
command.Data.Enrich(schemaAndApp.Schema.Schema, schemaAndApp.App.PartitionResolver);
command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.SchemaEntity.ScriptCreate, "create content", true);
command.Data.Enrich(schemaAndApp.SchemaEntity.Schema, schemaAndApp.AppEntity.PartitionResolver);
await ValidateAsync(schemaAndApp, command, () => "Failed to create content", false);
@ -86,7 +86,7 @@ namespace Squidex.Domain.Apps.Write.Contents
var schemaAndApp = await ResolveSchemaAndAppAsync(command);
var scriptContext = CreateScriptContext(content, command, command.Data);
command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.Schema.ScriptUpdate, "update content", true);
command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.SchemaEntity.ScriptUpdate, "update content", true);
await ValidateAsync(schemaAndApp, command, () => "Failed to update content", false);
@ -103,7 +103,7 @@ namespace Squidex.Domain.Apps.Write.Contents
var schemaAndApp = await ResolveSchemaAndAppAsync(command);
var scriptContext = CreateScriptContext(content, command, command.Data);
command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.Schema.ScriptUpdate, "patch content", true);
command.Data = scriptEngine.ExecuteAndTransform(scriptContext, schemaAndApp.SchemaEntity.ScriptUpdate, "patch content", true);
await ValidateAsync(schemaAndApp, command, () => "Failed to patch content", true);
@ -120,7 +120,7 @@ namespace Squidex.Domain.Apps.Write.Contents
var schemaAndApp = await ResolveSchemaAndAppAsync(command);
var scriptContext = CreateScriptContext(content, command);
scriptEngine.Execute(scriptContext, schemaAndApp.Schema.ScriptPublish, "publish content");
scriptEngine.Execute(scriptContext, schemaAndApp.SchemaEntity.ScriptPublish, "publish content");
content.Publish(command);
});
@ -133,7 +133,7 @@ namespace Squidex.Domain.Apps.Write.Contents
var schemaAndApp = await ResolveSchemaAndAppAsync(command);
var scriptContext = CreateScriptContext(content, command);
scriptEngine.Execute(scriptContext, schemaAndApp.Schema.ScriptUnpublish, "unpublish content");
scriptEngine.Execute(scriptContext, schemaAndApp.SchemaEntity.ScriptUnpublish, "unpublish content");
content.Unpublish(command);
});
@ -146,7 +146,7 @@ namespace Squidex.Domain.Apps.Write.Contents
var schemaAndApp = await ResolveSchemaAndAppAsync(command);
var scriptContext = CreateScriptContext(content, command);
scriptEngine.Execute(scriptContext, schemaAndApp.Schema.ScriptDelete, "delete content");
scriptEngine.Execute(scriptContext, schemaAndApp.SchemaEntity.ScriptDelete, "delete content");
content.Delete(command);
});
@ -199,7 +199,7 @@ namespace Squidex.Domain.Apps.Write.Contents
return new ScriptContext { ContentId = content.Id, Data = data, OldData = content.Data, User = ScriptUser.Create(command.Principal) };
}
private async Task<(ISchemaEntity Schema, IAppEntity App)> ResolveSchemaAndAppAsync(SchemaCommand command)
private async Task<(ISchemaEntity SchemaEntity, IAppEntity AppEntity)> ResolveSchemaAndAppAsync(SchemaCommand command)
{
var taskForApp = appProvider.FindAppByIdAsync(command.AppId.Id);
var taskForSchema = schemas.FindSchemaByIdAsync(command.SchemaId.Id);

2
src/Squidex.Domain.Apps.Write/Schemas/SchemaDomainObject.cs

@ -300,7 +300,7 @@ namespace Squidex.Domain.Apps.Write.Schemas
{
SimpleMapper.Map(fieldCommand, @event);
if (schema.FieldsById.TryGetValue(fieldCommand.FieldId, out Field field))
if (schema.FieldsById.TryGetValue(fieldCommand.FieldId, out var field))
{
@event.FieldId = new NamedId<long>(field.Id, field.Name);
}

1
src/Squidex.Domain.Users/UserExtensions.cs

@ -12,6 +12,7 @@ using Squidex.Infrastructure;
using Squidex.Shared.Identity;
using Squidex.Shared.Users;
// ReSharper disable PossibleNullReferenceException
// ReSharper disable InvertIf
namespace Squidex.Domain.Users

2
src/Squidex.Infrastructure.GetEventStore/CQRS/Events/GetEventStoreSubscription.cs

@ -276,7 +276,7 @@ namespace Squidex.Infrastructure.CQRS.Events
{
var addressParts = projectionHost.Split(':');
if (addressParts.Length < 2 || !int.TryParse(addressParts[1], out int port))
if (addressParts.Length < 2 || !int.TryParse(addressParts[1], out var port))
{
port = 2113;
}

2
src/Squidex.Infrastructure.Redis/RedisSubscription.cs

@ -67,7 +67,7 @@ namespace Squidex.Infrastructure
return;
}
if (!Guid.TryParse(parts[0], out Guid sender))
if (!Guid.TryParse(parts[0], out var sender))
{
return;
}

2
src/Squidex.Infrastructure/CQRS/DomainObjectBase.cs

@ -10,6 +10,8 @@ using System;
using System.Collections.Generic;
using Squidex.Infrastructure.CQRS.Events;
// ReSharper disable ImpureMethodCallOnReadonlyValueField
namespace Squidex.Infrastructure.CQRS
{
public abstract class DomainObjectBase : IAggregate, IEquatable<IAggregate>

4
src/Squidex.Infrastructure/CollectionExtensions.cs

@ -109,7 +109,7 @@ namespace Squidex.Infrastructure
public static TValue GetOrCreate<TKey, TValue>(this IReadOnlyDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> creator)
{
if (!dictionary.TryGetValue(key, out TValue result))
if (!dictionary.TryGetValue(key, out var result))
{
result = creator(key);
}
@ -119,7 +119,7 @@ namespace Squidex.Infrastructure
public static TValue GetOrAdd<TKey, TValue>(this IDictionary<TKey, TValue> dictionary, TKey key, Func<TKey, TValue> creator)
{
if (!dictionary.TryGetValue(key, out TValue result))
if (!dictionary.TryGetValue(key, out var result))
{
result = creator(key);

2
src/Squidex.Infrastructure/DomainObjectException.cs

@ -8,6 +8,8 @@
using System;
// ReSharper disable SuggestBaseTypeForParameter
namespace Squidex.Infrastructure
{
public class DomainObjectException : Exception

2
src/Squidex.Infrastructure/Json/NamedGuidIdConverter.cs

@ -35,7 +35,7 @@ namespace Squidex.Infrastructure.Json
throw new JsonException("Named id must have more than 2 parts divided by commata");
}
if (!Guid.TryParse(parts[0], out Guid id))
if (!Guid.TryParse(parts[0], out var id))
{
throw new JsonException("Named id must be a valid guid");
}

2
src/Squidex.Infrastructure/Json/NamedLongIdConverter.cs

@ -35,7 +35,7 @@ namespace Squidex.Infrastructure.Json
throw new JsonException("Named id must have more than 2 parts divided by commata");
}
if (!long.TryParse(parts[0], out long id))
if (!long.TryParse(parts[0], out var id))
{
throw new JsonException("Named id must be a valid long");
}

5
src/Squidex.Infrastructure/Json/PropertiesBagConverter.cs

@ -7,7 +7,6 @@
// ==========================================================================
using System;
using System.Reflection;
using Newtonsoft.Json;
using NodaTime;
using NodaTime.Extensions;
@ -38,9 +37,9 @@ namespace Squidex.Infrastructure.Json
var value = reader.Value;
if (value is DateTime)
if (value is DateTime dateTime)
{
properties.Set(key, ((DateTime)value).ToInstant());
properties.Set(key, dateTime.ToInstant());
}
else
{

2
src/Squidex.Infrastructure/Language.cs

@ -111,7 +111,7 @@ namespace Squidex.Infrastructure
input = match.Groups[0].Value;
}
if (TryGetLanguage(input.ToLowerInvariant(), out Language result))
if (TryGetLanguage(input.ToLowerInvariant(), out var result))
{
return result;
}

2
src/Squidex.Infrastructure/PropertiesBag.cs

@ -99,7 +99,7 @@ namespace Squidex.Infrastructure
throw new ArgumentException($"The property names '{newPropertyName}' are equal.", newPropertyName);
}
if (!internalDictionary.TryGetValue(oldPropertyName, out PropertyValue property))
if (!internalDictionary.TryGetValue(oldPropertyName, out var property))
{
return false;
}

6
src/Squidex.Infrastructure/PropertyValue.cs

@ -58,7 +58,7 @@ namespace Squidex.Infrastructure
{
result = null;
if (!Parsers.TryGetValue(binder.Type, out Func<PropertyValue, CultureInfo, object> parser))
if (!Parsers.TryGetValue(binder.Type, out var parser))
{
return false;
}
@ -145,12 +145,12 @@ namespace Squidex.Infrastructure
private T? ToNullableOrParseValue<T>(IFormatProvider culture, Func<string, T> parser) where T : struct
{
return TryParse(culture, parser, out T result) ? result : (T?)null;
return TryParse(culture, parser, out var result) ? result : (T?)null;
}
private T ToOrParseValue<T>(IFormatProvider culture, Func<string, T> parser)
{
return TryParse(culture, parser, out T result) ? result : default(T);
return TryParse(culture, parser, out var result) ? result : default(T);
}
private bool TryParse<T>(IFormatProvider culture, Func<string, T> parser, out T result)

2
src/Squidex.Infrastructure/Reflection/PropertiesTypeAccessor.cs

@ -68,7 +68,7 @@ namespace Squidex.Infrastructure.Reflection
{
Guard.NotNullOrEmpty(propertyName, nameof(propertyName));
if (!accessors.TryGetValue(propertyName, out IPropertyAccessor accessor))
if (!accessors.TryGetValue(propertyName, out var accessor))
{
throw new ArgumentException("Property does not exist.", nameof(propertyName));
}

2
src/Squidex.Infrastructure/StringExtensions.cs

@ -356,7 +356,7 @@ namespace Squidex.Infrastructure
var lower = char.ToLowerInvariant(character);
if (LowerCaseDiacritics.TryGetValue(character, out string replacement))
if (LowerCaseDiacritics.TryGetValue(character, out var replacement))
{
if (singleCharDiactric)
{

1
src/Squidex.Infrastructure/TypeNameRegistry.cs

@ -10,6 +10,7 @@ using System;
using System.Collections.Generic;
using System.Reflection;
// ReSharper disable PossibleNullReferenceException
// ReSharper disable InvertIf
namespace Squidex.Infrastructure

1
src/Squidex/Config/Identity/IdentityUsage.cs

@ -19,6 +19,7 @@ using Squidex.Infrastructure.Log;
using Squidex.Shared.Identity;
using Squidex.Shared.Users;
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
// ReSharper disable InvertIf
namespace Squidex.Config.Identity

1
src/Squidex/Config/Identity/MicrosoftIdentityUsage.cs

@ -6,7 +6,6 @@
// All rights reserved.
// ==========================================================================
using Microsoft.AspNetCore.Authentication.MicrosoftAccount;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

4
src/Squidex/Config/Swagger/XmlResponseTypesProcessor.cs

@ -35,7 +35,7 @@ namespace Squidex.Config.Swagger
{
var statusCode = match.Groups["Code"].Value;
if (!operation.Responses.TryGetValue(statusCode, out SwaggerResponse response))
if (!operation.Responses.TryGetValue(statusCode, out var response))
{
response = new SwaggerResponse();
@ -72,7 +72,7 @@ namespace Squidex.Config.Swagger
private static void RemoveOkResponse(SwaggerOperation operation)
{
if (operation.Responses.TryGetValue("200", out SwaggerResponse response) &&
if (operation.Responses.TryGetValue("200", out var response) &&
response.Description != null &&
response.Description.Contains("=>"))
{

30
src/Squidex/Controllers/Api/Schemas/Models/SchemaDetailsDto.cs

@ -33,6 +33,36 @@ namespace Squidex.Controllers.Api.Schemas.Models
/// </summary>
public bool IsPublished { get; set; }
/// <summary>
/// The script that is executed for each query when querying contents.
/// </summary>
public string ScriptQuery { get; set; }
/// <summary>
/// The script that is executed when creating a content.
/// </summary>
public string ScriptCreate { get; set; }
/// <summary>
/// The script that is executed when updating a content.
/// </summary>
public string ScriptUpdate { get; set; }
/// <summary>
/// The script that is executed when deleting a content.
/// </summary>
public string ScriptDelete { get; set; }
/// <summary>
/// The script that is executed when publishing a content.
/// </summary>
public string ScriptPublish { get; set; }
/// <summary>
/// The script that is executed when unpublishing a content.
/// </summary>
public string ScriptUnpublish { get; set; }
/// <summary>
/// The list of fields.
/// </summary>

4
src/Squidex/Controllers/ContentApi/ContentsController.cs

@ -44,7 +44,7 @@ namespace Squidex.Controllers.ContentApi
public ContentsController(
ICommandBus commandBus,
ISchemaProvider schemas,
ISchemaProvider schemas,
IScriptEngine scriptEngine,
IContentRepository contentRepository,
IGraphQLService graphQL)
@ -196,7 +196,7 @@ namespace Squidex.Controllers.ContentApi
var context = await CommandBus.PublishAsync(command);
var result = context.Result<EntityCreatedResult<NamedContentData>>();
var response = result.IdOrValue;
var response = ContentDto.Create(command, result);
return CreatedAtAction(nameof(GetContent), new { id = command.ContentId }, response);
}

2
src/Squidex/Controllers/ContentApi/Generator/SchemaSwaggerGenerator.cs

@ -150,7 +150,7 @@ namespace Squidex.Controllers.ContentApi.Generator
operation.AddBodyParameter("data", dataSchema, SchemaBodyDescription);
operation.AddQueryParameter("publish", JsonObjectType.Boolean, "Set to true to autopublish content.");
operation.AddResponse("201", $"{schemaName} created.", dataSchema);
operation.AddResponse("201", $"{schemaName} created.", contentSchema);
operation.Security = EditorSecurity;
});

22
src/Squidex/Controllers/ContentApi/Models/ContentDto.cs

@ -9,7 +9,10 @@
using System;
using System.ComponentModel.DataAnnotations;
using NodaTime;
using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Write.Contents.Commands;
using Squidex.Infrastructure;
using Squidex.Infrastructure.CQRS.Commands;
namespace Squidex.Controllers.ContentApi.Models
{
@ -57,5 +60,24 @@ namespace Squidex.Controllers.ContentApi.Models
/// The version of the content.
/// </summary>
public long Version { get; set; }
public static ContentDto Create(CreateContent command, EntityCreatedResult<NamedContentData> result)
{
var now = SystemClock.Instance.GetCurrentInstant();
var response = new ContentDto
{
Id = command.ContentId,
Data = result.IdOrValue,
Version = result.Version,
Created = now,
CreatedBy = command.Actor,
LastModified = now,
LastModifiedBy = command.Actor,
IsPublished = command.Publish
};
return response;
}
}
}

1
src/Squidex/Pipeline/ApiExceptionFilterAttribute.cs

@ -9,7 +9,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Squidex.Controllers.Api;

2
src/Squidex/Pipeline/CommandHandlers/ETagCommandMiddleware.cs

@ -29,7 +29,7 @@ namespace Squidex.Pipeline.CommandHandlers
var headers = httpContextAccessor.HttpContext.Request.Headers;
var headerMatch = headers["If-Match"].ToString();
if (!string.IsNullOrWhiteSpace(headerMatch) && long.TryParse(headerMatch, NumberStyles.Any, CultureInfo.InvariantCulture, out long expectedVersion))
if (!string.IsNullOrWhiteSpace(headerMatch) && long.TryParse(headerMatch, NumberStyles.Any, CultureInfo.InvariantCulture, out var expectedVersion))
{
context.Command.ExpectedVersion = expectedVersion;
}

2
src/Squidex/Pipeline/Swagger/SwaggerHelper.cs

@ -97,7 +97,7 @@ namespace Squidex.Pipeline.Swagger
{ SquidexRoles.AppOwner, "App contributor with Owner permission." },
{ SquidexRoles.AppEditor, "Client (writer) or App contributor with Editor permission." },
{ SquidexRoles.AppReader, "Client (readonly) or App contributor with Editor permission." },
{ SquidexRoles.AppDeveloper, "App contributor with Developer permission." },
{ SquidexRoles.AppDeveloper, "App contributor with Developer permission." }
},
Description = securityDescription
};

2
src/Squidex/Squidex.csproj

@ -71,7 +71,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="1.1.2" />
<PackageReference Include="Microsoft.Data.Edm" Version="5.8.2" />
<PackageReference Include="Microsoft.OData.Core" Version="7.2.0" />
<PackageReference Include="Microsoft.OData.Core" Version="7.3.1" />
<PackageReference Include="MongoDB.Driver" Version="2.4.4" />
<PackageReference Include="NJsonSchema" Version="9.5.0" />
<PackageReference Include="NodaTime.Serialization.JsonNet" Version="2.0.0" />

4
src/Squidex/app/features/content/pages/content/content-page.component.ts

@ -129,8 +129,8 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone
} else {
this.appNameOnce()
.switchMap(app => this.contentsService.putContent(app, this.schema.name, this.contentId!, requestDto, this.version))
.subscribe(() => {
this.content = this.content.update(requestDto, this.authService.user.token);
.subscribe(dto => {
this.content = this.content.update(dto, this.authService.user.token);
this.emitContentUpdated(this.content);
this.notifyInfo('Content saved successfully.');

1
src/Squidex/app/framework/angular/jscript-editor.component.html

@ -0,0 +1 @@
<div class="editor" #editor></div>

8
src/Squidex/app/framework/angular/jscript-editor.component.scss

@ -0,0 +1,8 @@
@import '_mixins';
@import '_vars';
.editor {
background: $color-dark-foreground;
border: 1px solid $color-input;
height: 30rem;
}

108
src/Squidex/app/framework/angular/jscript-editor.component.ts

@ -0,0 +1,108 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import { AfterViewInit, Component, forwardRef, ElementRef, ViewChild } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject } from 'rxjs';
import { ResourceLoaderService } from './../services/resource-loader.service';
declare var ace: any;
const NOOP = () => { /* NOOP */ };
export const SQX_JSCRIPT_EDITOR_CONTROL_VALUE_ACCESSOR: any = {
provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => JscriptEditorComponent), multi: true
};
@Component({
selector: 'sqx-jscript-editor',
styleUrls: ['./jscript-editor.component.scss'],
templateUrl: './jscript-editor.component.html',
providers: [SQX_JSCRIPT_EDITOR_CONTROL_VALUE_ACCESSOR]
})
export class JscriptEditorComponent implements ControlValueAccessor, AfterViewInit {
private changeCallback: (value: any) => void = NOOP;
private touchedCallback: () => void = NOOP;
private valueChanged = new Subject();
private aceEditor: any;
private oldValue: string;
private isDisabled = false;
@ViewChild('editor')
public editor: ElementRef;
constructor(
private readonly resourceLoader: ResourceLoaderService
) {
}
public writeValue(value: any) {
this.oldValue = value;
if (this.aceEditor) {
this.setValue(value);
}
}
public setDisabledState(isDisabled: boolean): void {
this.isDisabled = isDisabled;
if (this.aceEditor) {
this.aceEditor.setReadOnly(isDisabled);
}
}
public registerOnChange(fn: any) {
this.changeCallback = fn;
}
public registerOnTouched(fn: any) {
this.touchedCallback = fn;
}
public ngAfterViewInit() {
this.valueChanged.debounceTime(500)
.subscribe(() => {
this.changeValue();
});
this.resourceLoader.loadScript('https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.6/ace.js').then(() => {
this.aceEditor = ace.edit(this.editor.nativeElement);
this.aceEditor.getSession().setMode('ace/mode/javascript');
this.aceEditor.setReadOnly(this.isDisabled);
this.aceEditor.setFontSize(14);
this.setValue(this.oldValue);
this.aceEditor.on('blur', () => {
this.changeValue();
this.touchedCallback();
});
this.aceEditor.on('change', () => {
this.valueChanged.next();
});
});
}
private changeValue() {
const newValue = this.aceEditor.getValue();
if (this.oldValue !== newValue) {
this.changeCallback(newValue);
}
this.oldValue = newValue;
}
private setValue(value: any) {
this.aceEditor.setValue(value);
this.aceEditor.clearSelection();
}
}

1
src/Squidex/app/framework/declarations.ts

@ -21,6 +21,7 @@ export * from './angular/geolocation-editor.component';
export * from './angular/http-extensions-impl';
export * from './angular/image-source.directive';
export * from './angular/indeterminate-value.directive';
export * from './angular/jscript-editor.component';
export * from './angular/json-editor.component';
export * from './angular/lowercase-input.directive';
export * from './angular/markdown-editor.component';

3
src/Squidex/app/framework/module.ts

@ -33,6 +33,7 @@ import {
GeolocationEditorComponent,
ImageSourceDirective,
IndeterminateValueDirective,
JscriptEditorComponent,
JsonEditorComponent,
KNumberPipe,
LocalCacheService,
@ -96,6 +97,7 @@ import {
GeolocationEditorComponent,
ImageSourceDirective,
IndeterminateValueDirective,
JscriptEditorComponent,
JsonEditorComponent,
KNumberPipe,
LowerCaseInputDirective,
@ -143,6 +145,7 @@ import {
GeolocationEditorComponent,
ImageSourceDirective,
IndeterminateValueDirective,
JscriptEditorComponent,
JsonEditorComponent,
KNumberPipe,
LowerCaseInputDirective,

59
src/Squidex/app/shared/services/schemas.service.spec.ts

@ -22,6 +22,7 @@ import {
SchemasService,
UpdateFieldDto,
UpdateSchemaDto,
UpdateSchemaScriptsDto,
Version
} from './../';
@ -62,6 +63,31 @@ describe('SchemaDto', () => {
expect(schema_2.lastModified).toEqual(now);
expect(schema_2.lastModifiedBy).toEqual('me');
});
it('should update scripts properties and user info when configure scripts', () => {
const newScripts =
new UpdateSchemaScriptsDto(
'<script-query>',
'<script-create>',
'<script-update>',
'<script-delete>',
'<script-publish>',
'<script-unpublish>');
const now = DateTime.now();
const schema_1 = new SchemaDetailsDto('1', 'name', properties, false, 'other', 'other', DateTime.now(), DateTime.now(), null, []);
const schema_2 = schema_1.configureScripts(newScripts, 'me', now);
expect(schema_2.scriptQuery).toEqual('<script-query>');
expect(schema_2.scriptCreate).toEqual('<script-create>');
expect(schema_2.scriptUpdate).toEqual('<script-update>');
expect(schema_2.scriptDelete).toEqual('<script-delete>');
expect(schema_2.scriptPublish).toEqual('<script-publish>');
expect(schema_2.scriptUnpublish).toEqual('<script-unpublish>');
expect(schema_2.lastModified).toEqual(now);
expect(schema_2.lastModifiedBy).toEqual('me');
});
});
describe('SchemaDetailsDto', () => {
@ -361,7 +387,13 @@ describe('SchemasService', () => {
fieldType: 'References'
}
}
]
],
scriptsQuery: '<script-query>',
scriptsCreate: '<script-create>',
scriptsUpdate: '<script-update>',
scriptsDelete: '<script-delete>',
scriptsPublish: '<script-publish>',
scriptsUnpublish: '<script-unpublish>'
});
expect(schema).toEqual(
@ -378,7 +410,13 @@ describe('SchemasService', () => {
new FieldDto(6, 'field6', true, true, true, 'language', createProperties('Geolocation')),
new FieldDto(7, 'field7', true, true, true, 'language', createProperties('Assets')),
new FieldDto(8, 'field8', true, true, true, 'language', createProperties('References'))
]));
],
'<script-query>',
'<script-create>',
'<script-update>',
'<script-delete>',
'<script-publish>',
'<script-unpublish>'));
}));
it('should provide entry from cache if not found',
@ -460,7 +498,22 @@ describe('SchemasService', () => {
expect(req.request.method).toEqual('PUT');
expect(req.request.headers.get('If-Match')).toBe(version.value);
req.flush({ id: 123 });
req.flush({});
}));
it('should make put request to update schema scripts',
inject([SchemasService, HttpTestingController], (schemasService: SchemasService, httpMock: HttpTestingController) => {
const dto = new UpdateSchemaScriptsDto();
schemasService.putSchemaScripts('my-app', 'my-schema', dto, version).subscribe();
const req = httpMock.expectOne('http://service/p/api/apps/my-app/schemas/my-schema/scripts');
expect(req.request.method).toEqual('PUT');
expect(req.request.headers.get('If-Match')).toBe(version.value);
req.flush({});
}));
it('should make put request to update field',

117
src/Squidex/app/shared/services/schemas.service.ts

@ -121,7 +121,13 @@ export class SchemaDto {
export class SchemaDetailsDto extends SchemaDto {
constructor(id: string, name: string, properties: SchemaPropertiesDto, isPublished: boolean, createdBy: string, lastModifiedBy: string, created: DateTime, lastModified: DateTime, version: Version,
public readonly fields: FieldDto[]
public readonly fields: FieldDto[],
public readonly scriptQuery?: string,
public readonly scriptCreate?: string,
public readonly scriptUpdate?: string,
public readonly scriptDelete?: string,
public readonly scriptPublish?: string,
public readonly scriptUnpublish?: string
) {
super(id, name, properties, isPublished, createdBy, lastModifiedBy, created, lastModified, version);
}
@ -135,7 +141,13 @@ export class SchemaDetailsDto extends SchemaDto {
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
this.fields);
this.fields,
this.scriptQuery,
this.scriptCreate,
this.scriptUpdate,
this.scriptDelete,
this.scriptPublish,
this.scriptUnpublish);
}
public unpublish(user: string, now?: DateTime): SchemaDetailsDto {
@ -147,7 +159,31 @@ export class SchemaDetailsDto extends SchemaDto {
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
this.fields);
this.fields,
this.scriptQuery,
this.scriptCreate,
this.scriptUpdate,
this.scriptDelete,
this.scriptPublish,
this.scriptUnpublish);
}
public configureScripts(scripts: UpdateSchemaScriptsDto, user: string, now?: DateTime): SchemaDetailsDto {
return new SchemaDetailsDto(
this.id,
this.name,
this.properties,
this.isPublished,
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
this.fields,
scripts.scriptQuery,
scripts.scriptCreate,
scripts.scriptUpdate,
scripts.scriptDelete,
scripts.scriptPublish,
scripts.scriptUnpublish);
}
public update(properties: SchemaPropertiesDto, user: string, now?: DateTime): SchemaDetailsDto {
@ -159,7 +195,13 @@ export class SchemaDetailsDto extends SchemaDto {
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
this.fields);
this.fields,
this.scriptQuery,
this.scriptCreate,
this.scriptUpdate,
this.scriptDelete,
this.scriptPublish,
this.scriptUnpublish);
}
public addField(field: FieldDto, user: string, now?: DateTime): SchemaDetailsDto {
@ -171,7 +213,13 @@ export class SchemaDetailsDto extends SchemaDto {
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
[...this.fields, field]);
[...this.fields, field],
this.scriptQuery,
this.scriptCreate,
this.scriptUpdate,
this.scriptDelete,
this.scriptPublish,
this.scriptUnpublish);
}
public updateField(field: FieldDto, user: string, now?: DateTime): SchemaDetailsDto {
@ -183,7 +231,13 @@ export class SchemaDetailsDto extends SchemaDto {
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
this.fields.map(f => f.fieldId === field.fieldId ? field : f));
this.fields.map(f => f.fieldId === field.fieldId ? field : f),
this.scriptQuery,
this.scriptCreate,
this.scriptUpdate,
this.scriptDelete,
this.scriptPublish,
this.scriptUnpublish);
}
public replaceFields(fields: FieldDto[], user: string, now?: DateTime): SchemaDetailsDto {
@ -195,7 +249,13 @@ export class SchemaDetailsDto extends SchemaDto {
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
fields);
fields,
this.scriptQuery,
this.scriptCreate,
this.scriptUpdate,
this.scriptDelete,
this.scriptPublish,
this.scriptUnpublish);
}
public removeField(field: FieldDto, user: string, now?: DateTime): SchemaDetailsDto {
@ -207,7 +267,13 @@ export class SchemaDetailsDto extends SchemaDto {
this.createdBy, user,
this.created, now || DateTime.now(),
this.version,
this.fields.filter(f => f.fieldId !== field.fieldId));
this.fields.filter(f => f.fieldId !== field.fieldId),
this.scriptQuery,
this.scriptCreate,
this.scriptUpdate,
this.scriptDelete,
this.scriptPublish,
this.scriptUnpublish);
}
}
@ -616,6 +682,18 @@ export class CreateSchemaDto {
}
}
export class UpdateSchemaScriptsDto {
constructor(
public readonly scriptQuery?: string,
public readonly scriptCreate?: string,
public readonly scriptUpdate?: string,
public readonly scriptDelete?: string,
public readonly scriptPublish?: string,
public readonly scriptUnpublish?: string
) {
}
}
@Injectable()
export class SchemasService {
constructor(
@ -681,7 +759,13 @@ export class SchemasService {
DateTime.parseISO_UTC(response.created),
DateTime.parseISO_UTC(response.lastModified),
new Version(response.version.toString()),
fields);
fields,
response.scriptsQuery,
response.scriptsCreate,
response.scriptsUpdate,
response.scriptsDelete,
response.scriptsPublish,
response.scriptsUnpublish);
})
.catch(error => {
if (error instanceof HttpErrorResponse && error.status === 404) {
@ -714,7 +798,13 @@ export class SchemasService {
now,
now,
version,
dto.fields || []);
dto.fields || [],
response.scriptsQuery,
response.scriptsCreate,
response.scriptsUpdate,
response.scriptsDelete,
response.scriptsPublish,
response.scriptsUnpublish);
})
.do(schema => {
this.localCache.set(`schema.${appName}.${schema.id}`, schema, 5000);
@ -750,6 +840,13 @@ export class SchemasService {
.pretifyError('Failed to delete schema. Please reload.');
}
public putSchemaScripts(appName: string, schemaName: string, dto: UpdateSchemaScriptsDto, version?: Version): Observable<any> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/schemas/${schemaName}/scripts`);
return HTTP.putVersioned(this.http, url, dto, version)
.pretifyError('Failed to update schema scripts. Please reload.');
}
public putSchema(appName: string, schemaName: string, dto: UpdateSchemaDto, version?: Version): Observable<any> {
const url = this.apiUrl.buildUrl(`api/apps/${appName}/schemas/${schemaName}`);

24
tests/Squidex.Domain.Apps.Write.Tests/Schemas/SchemaDomainObjectTests.cs

@ -187,24 +187,24 @@ namespace Squidex.Domain.Apps.Write.Schemas
sut.ConfigureScripts(CreateCommand(new ConfigureScripts
{
ScriptCreate = "<create>",
ScriptUpdate = "<update>",
ScriptDelete = "<delete>",
ScriptPublish = "<publish>",
ScriptUnpublish = "<unpublish>",
ScriptQuery = "<query>",
ScriptQuery = "<script-query>",
ScriptCreate = "<script-create>",
ScriptUpdate = "<script-update>",
ScriptDelete = "<script-delete>",
ScriptPublish = "<script-publish>",
ScriptUnpublish = "<script-unpublish>"
}));
sut.GetUncomittedEvents()
.ShouldHaveSameEvents(
CreateEvent(new ScriptsConfigured
{
ScriptCreate = "<create>",
ScriptUpdate = "<update>",
ScriptDelete = "<delete>",
ScriptPublish = "<publish>",
ScriptUnpublish = "<unpublish>",
ScriptQuery = "<query>",
ScriptQuery = "<script-query>",
ScriptCreate = "<script-create>",
ScriptUpdate = "<script-update>",
ScriptDelete = "<script-delete>",
ScriptPublish = "<script-publish>",
ScriptUnpublish = "<script-unpublish>"
})
);
}

7
tests/Squidex.Infrastructure.Tests/Caching/InvalidatingMemoryCacheTest.cs

@ -11,6 +11,7 @@ using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Xunit;
// ReSharper disable NotAccessedVariable
// ReSharper disable RedundantAssignment
namespace Squidex.Infrastructure.Caching
@ -98,12 +99,12 @@ namespace Squidex.Infrastructure.Caching
[Fact]
public void Should_use_inner_cache_to_get_value()
{
object currentOut = 123;
object outValue;
A.CallTo(() => cache.TryGetValue("a-key", out currentOut))
A.CallTo(() => cache.TryGetValue("a-key", out outValue))
.Returns(true);
var exists = sut.TryGetValue("a-key", out object result);
var exists = sut.TryGetValue("a-key", out var result);
Assert.Equal(123, result);
Assert.True(exists);

4
tests/Squidex.Infrastructure.Tests/Squidex.Infrastructure.Tests.csproj

@ -13,8 +13,8 @@
<PackageReference Include="FakeItEasy" Version="4.0.0" />
<PackageReference Include="FluentAssertions" Version="4.19.4" />
<PackageReference Include="Google.Cloud.Storage.V1" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.0.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" Version="1.1.2" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="1.1.2" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
<PackageReference Include="System.ValueTuple" Version="4.4.0" />
<PackageReference Include="xunit" Version="2.2.0" />

Loading…
Cancel
Save