public void Should_transform_content_with_old_content() { var content = new NamedContentData() .AddField("number0", new ContentFieldData() .AddValue("iv", 3.0)); var oldContent = new NamedContentData() .AddField("number0", new ContentFieldData() .AddValue("iv", 5.0)); var expected = new NamedContentData() .AddField("number0", new ContentFieldData() .AddValue("iv", 13.0)); var userIdentity = new ClaimsIdentity(); var userPrincipal = new ClaimsPrincipal(userIdentity); userIdentity.AddClaim(new Claim(OpenIdClaims.ClientId, "2")); var context = new ScriptContext { Data = content, DataOld = oldContent, User = userPrincipal }; var result = sut.ExecuteAndTransform(context, @" ctx.data.number0.iv = ctx.data.number0.iv + ctx.oldData.number0.iv * parseInt(ctx.user.id, 10); replace(ctx.data);"); Assert.Equal(expected, result); }
public async Task HandleAsync(CommandContext context, Func <Task> next) { await next(); if (context.IsCompleted && context.Command is CreateSchema createSchema && createSchema.Singleton) { var schemaId = new NamedId <Guid>(createSchema.SchemaId, createSchema.Name); var data = new NamedContentData(); var contentId = schemaId.Id; var content = new CreateContent { Data = data, ContentId = contentId, SchemaId = schemaId, DoNotValidate = true }; SimpleMapper.Map(createSchema, content); content.Publish = true; await context.CommandBus.PublishAsync(content); } }
public async Task Should_cleanup_references_when_everything_deleted() { var id1 = Guid.NewGuid(); var id2 = Guid.NewGuid(); var source = BuildTestData(id1, id2); var content = CreateContent(source); var expected = new NamedContentData() .AddField("references", new ContentFieldData() .AddJsonValue(JsonValue.Array())) .AddField("assets", new ContentFieldData() .AddJsonValue(JsonValue.Array())) .AddField("array", new ContentFieldData() .AddJsonValue( JsonValue.Array( JsonValue.Object() .Add("nested", JsonValue.Array())))); A.CallTo(() => assetRepository.QueryIdsAsync(appId.Id, A <HashSet <Guid> > .That.Is(id1, id2))) .Returns(new List <Guid>()); A.CallTo(() => contentRepository.QueryIdsAsync(appId.Id, A <HashSet <Guid> > .That.Is(id1, id2), SearchScope.All)) .Returns(new List <(Guid, Guid)>()); var ctx = new Context(Mocks.FrontendUser(), Mocks.App(appId)); await sut.EnrichAsync(ctx, Enumerable.Repeat(content, 1), schemaProvider); Assert.Equal(expected, content.Data); }
public void Should_not_be_equal_when_data_have_not_same_structure() { var lhs = new NamedContentData() .AddField("field1", new ContentFieldData() .AddValue("iv", 2)) .AddField("field2", new ContentFieldData() .AddValue("iv", 2)); var rhs = new NamedContentData() .AddField("field1", new ContentFieldData() .AddValue("en", 2)) .AddField("field3", new ContentFieldData() .AddValue("iv", 2)); Assert.False(lhs.Equals(rhs)); Assert.False(lhs.Equals((object)rhs)); Assert.NotEqual(lhs.GetHashCode(), rhs.GetHashCode()); }
public async Task Should_add_error_if_field_object_is_defined() { var schema = new Schema("my-schema") .AddUI(1, "my-ui1", Partitioning.Invariant) .AddUI(2, "my-ui2", Partitioning.Invariant); var data = new NamedContentData() .AddField("my-ui1", new ContentFieldData()) .AddField("my-ui2", new ContentFieldData() .AddValue("iv", null)); var dataErrors = new List <ValidationError>(); await data.ValidateAsync(x => InvariantPartitioning.Instance, dataErrors, schema); dataErrors.Should().BeEquivalentTo( new[] { new ValidationError("Value must not be defined.", "my-ui1"), new ValidationError("Value must not be defined.", "my-ui2") }); }
public void Enrich(NamedContentData data) { Guard.NotNull(data, nameof(data)); foreach (var field in schema.Fields) { var fieldData = data.GetOrCreate(field.Name, k => new ContentFieldData()); if (fieldData != null) { var partitioning = partitionResolver(field.Partitioning); foreach (var partitionKey in partitioning.AllKeys) { Enrich(field, fieldData, partitionKey); } if (fieldData.Count > 0) { data[field.Name] = fieldData; } } } }
public async Task Patch_should_update_domain_object() { A.CallTo(() => scriptEngine.ExecuteAndTransform(A <ScriptContext> .Ignored, A <string> .Ignored)) .Returns(data); var patch = new NamedContentData().AddField("my-field", new ContentFieldData().SetValue(3)); A.CallTo(() => scriptEngine.ExecuteAndTransform(A <ScriptContext> .Ignored, A <string> .Ignored)).Returns(patch); CreateContent(); var context = CreateContextForCommand(new PatchContent { ContentId = contentId, Data = patch, User = user }); await TestUpdate(content, async _ => { await sut.HandleAsync(context); }); Assert.NotNull(context.Result <ContentDataChangedResult>().Data); A.CallTo(() => scriptEngine.ExecuteAndTransform(A <ScriptContext> .Ignored, "<update-script>")).MustHaveHappened(); }
public static Dictionary <string, string> ToTexts(this NamedContentData data) { var result = new Dictionary <string, string>(); if (data != null) { var languages = new Dictionary <string, StringBuilder>(); try { foreach (var value in data.Values) { if (value != null) { foreach (var(key, jsonValue) in value) { AppendJsonText(languages, key, jsonValue); } } } foreach (var(key, sb) in languages) { result[key] = sb.ToString(); } } finally { foreach (var(_, sb) in languages) { StringBuilderPool.Return(sb); } } } return(result); }
public void Should_convert_name_to_name() { var input = new NamedContentData() .AddField("field1", new ContentFieldData() .AddValue("en", "EN")) .AddField("field2", new ContentFieldData() .AddValue("iv", 1)) .AddField("invalid", new ContentFieldData() .AddValue("iv", 2)); var actual = input.ConvertName2Name(schema, (data, field) => field.Name == "field2" ? null : data); var expected = new NamedContentData() .AddField("field1", new ContentFieldData() .AddValue("en", "EN")); Assert.Equal(expected, actual); }
public static object ToFlatLanguageModel(this NamedContentData content, LanguagesConfig languagesConfig, IReadOnlyCollection <Language>?languagePreferences = null) { Guard.NotNull(languagesConfig); if (languagePreferences == null || languagePreferences.Count == 0) { return(content); } if (languagePreferences.Count == 1 && languagesConfig.TryGetConfig(languagePreferences.First(), out var languageConfig)) { languagePreferences = languagePreferences.Union(languageConfig.LanguageFallbacks).ToList(); } var result = new Dictionary <string, IJsonValue>(); foreach (var fieldValue in content) { var fieldData = fieldValue.Value; if (fieldData != null) { foreach (var language in languagePreferences) { if (fieldData.TryGetValue(language, out var value) && value.Type != JsonValueType.Null) { result[fieldValue.Key] = value; break; } } } } return(result); }
public async Task <bool> CanPublishOnCreateAsync(ISchemaEntity schema, NamedContentData data, ClaimsPrincipal user) { var workflow = await GetWorkflowAsync(schema.AppId.Id, schema.Id); return(workflow.TryGetTransition(workflow.Initial, Status.Published, out var transition) && IsTrue(transition, data, user)); }
public static NamedContentData ToApiModel(this NamedContentData content, Schema schema, LanguagesConfig languagesConfig, bool excludeHidden = true, bool checkTypeCompatibility = false) { Guard.NotNull(schema, nameof(schema)); Guard.NotNull(languagesConfig, nameof(languagesConfig)); var codeForInvariant = InvariantPartitioning.Instance.Master.Key; var codeForMasterLanguage = languagesConfig.Master.Language.Iso2Code; var result = new NamedContentData(); foreach (var fieldValue in content) { if (!schema.FieldsByName.TryGetValue(fieldValue.Key, out var field) || (excludeHidden && field.IsHidden)) { continue; } if (checkTypeCompatibility) { var isValid = true; foreach (var value in fieldValue.Value.Values) { try { if (!value.IsNull()) { JsonValueConverter.ConvertValue(field, value); } } catch { isValid = false; break; } } if (!isValid) { continue; } } var fieldResult = new ContentFieldData(); var fieldValues = fieldValue.Value; if (field.Partitioning.Equals(Partitioning.Language)) { foreach (var languageConfig in languagesConfig) { var languageCode = languageConfig.Key; if (fieldValues.TryGetValue(languageCode, out var value)) { fieldResult.Add(languageCode, value); } else if (languageConfig == languagesConfig.Master && fieldValues.TryGetValue(codeForInvariant, out value)) { fieldResult.Add(languageCode, value); } } } else { if (fieldValues.TryGetValue(codeForInvariant, out var value)) { fieldResult.Add(codeForInvariant, value); } else if (fieldValues.TryGetValue(codeForMasterLanguage, out value)) { fieldResult.Add(codeForInvariant, value); } else if (fieldValues.Count > 0) { fieldResult.Add(codeForInvariant, fieldValues.Values.First()); } } result.Add(field.Name, fieldResult); } return(result); }
public Task GenerateDefaultValuesAsync(NamedContentData data) { data.GenerateDefaultValues(schema.SchemaDef, app.PartitionResolver()); return(Task.CompletedTask); }
public ContentDataObject(Engine engine, NamedContentData contentData) : base(engine) { this.contentData = contentData; }
public async Task <IActionResult> PatchContent(string app, string name, DomainId id, [FromBody] NamedContentData request) { var command = new PatchContent { ContentId = id, Data = request.ToCleaned() }; var response = await InvokeCommandAsync(command); return(Ok(response)); }
protected static IEnrichedContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null, NamedContentData dataDraft = null) { var now = SystemClock.Instance.GetCurrentInstant(); data = data ?? new NamedContentData() .AddField("my-string", new ContentFieldData() .AddValue("de", "value")) .AddField("my-assets", new ContentFieldData() .AddValue("iv", JsonValue.Array(assetId.ToString()))) .AddField("my-number", new ContentFieldData() .AddValue("iv", 1.0)) .AddField("my_number", new ContentFieldData() .AddValue("iv", 2.0)) .AddField("my-boolean", new ContentFieldData() .AddValue("iv", true)) .AddField("my-datetime", new ContentFieldData() .AddValue("iv", now)) .AddField("my-tags", new ContentFieldData() .AddValue("iv", JsonValue.Array("tag1", "tag2"))) .AddField("my-references", new ContentFieldData() .AddValue("iv", JsonValue.Array(refId.ToString()))) .AddField("my-geolocation", new ContentFieldData() .AddValue("iv", JsonValue.Object().Add("latitude", 10).Add("longitude", 20))) .AddField("my-json", new ContentFieldData() .AddValue("iv", JsonValue.Object().Add("value", 1))) .AddField("my-localized", new ContentFieldData() .AddValue("de-DE", "de-DE")) .AddField("my-array", new ContentFieldData() .AddValue("iv", JsonValue.Array( JsonValue.Object() .Add("nested-boolean", true) .Add("nested-number", 10) .Add("nested_number", 11), JsonValue.Object() .Add("nested-boolean", false) .Add("nested-number", 20) .Add("nested_number", 21)))); var content = new ContentEntity { Id = id, Version = 1, Created = now, CreatedBy = new RefToken(RefTokenType.Subject, "user1"), LastModified = now, LastModifiedBy = new RefToken(RefTokenType.Subject, "user2"), Data = data, DataDraft = dataDraft, Status = Status.Draft, StatusColor = "red" }; return(content); }
public async Task <IActionResult> PutContent(string app, string name, Guid id, [FromBody] NamedContentData request) { await contentQuery.GetSchemaOrThrowAsync(Context, name); var command = new UpdateContent { ContentId = id, Data = request.ToCleaned() }; var response = await InvokeCommandAsync(command); return(Ok(response)); }
public void Should_throw_exception_when_assigning_non_object_as_field() { var original = new NamedContentData(); Assert.Throws <JavaScriptException>(() => ExecuteScript(original, @"data.number = 1")); }
public async Task <IActionResult> PatchContent(string app, string name, Guid id, [FromBody] NamedContentData request, [FromQuery] bool asDraft = false) { await contentQuery.ThrowIfSchemaNotExistsAsync(Context().WithSchemaName(name)); var command = new PatchContent { ContentId = id, Data = request.ToCleaned(), AsDraft = asDraft }; var context = await CommandBus.PublishAsync(command); var result = context.Result <ContentDataChangedResult>(); var response = result.Data; return(Ok(response)); }
public static IdContentData ToMongoModel(this NamedContentData result, Schema schema) { return(result.ToIdModel(schema, FieldConverters.EncodeJson())); }
public async Task <IActionResult> PatchContent(string app, string name, Guid id, [FromBody] NamedContentData request, [FromQuery] bool asDraft = false) { await contentQuery.GetSchemaOrThrowAsync(Context, name); var command = new PatchContent { ContentId = id, Data = request.ToCleaned(), AsDraft = asDraft }; var response = await InvokeCommandAsync(command); return(Ok(response)); }
public Task EnrichAsync(NamedContentData data) { data.Enrich(schemaEntity.SchemaDef, appEntity.PartitionResolver()); return(TaskHelper.Done); }
public async Task <IActionResult> PostContent(string app, string name, DomainId id, [FromBody] NamedContentData request, [FromQuery] bool publish = false) { var command = new UpsertContent { ContentId = id, Data = request.ToCleaned(), Publish = publish }; var response = await InvokeCommandAsync(command); return(Ok(response)); }
public Task ValidatePartialAsync(NamedContentData data) { var ctx = CreateValidationContext(); return(data.ValidatePartialAsync(ctx, schemaEntity.SchemaDef, appEntity.PartitionResolver(), message)); }
protected static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null, bool noJson = false) { var now = DateTime.UtcNow.ToInstant(); data = data ?? new NamedContentData() .AddField("my-string", new ContentFieldData() .AddValue("de", "value")) .AddField("my-assets", new ContentFieldData() .AddValue("iv", JToken.FromObject(new[] { assetId }))) .AddField("my-number", new ContentFieldData() .AddValue("iv", 1)) .AddField("my-boolean", new ContentFieldData() .AddValue("iv", true)) .AddField("my-datetime", new ContentFieldData() .AddValue("iv", now.ToDateTimeUtc())) .AddField("my-tags", new ContentFieldData() .AddValue("iv", JToken.FromObject(new[] { "tag1", "tag2" }))) .AddField("my-references", new ContentFieldData() .AddValue("iv", JToken.FromObject(new[] { refId }))) .AddField("my-geolocation", new ContentFieldData() .AddValue("iv", JToken.FromObject(new { latitude = 10, longitude = 20 }))); if (!noJson) { data.AddField("my-json", new ContentFieldData() .AddValue("iv", JToken.FromObject(new { value = 1 }))); } var content = new ContentEntity { Id = id, Version = 1, Created = now, CreatedBy = new RefToken("subject", "user1"), LastModified = now, LastModifiedBy = new RefToken("subject", "user2"), Data = data }; return(content); }
public static void Enrich(this NamedContentData data, Schema schema, PartitionResolver partitionResolver) { var enricher = new ContentEnricher(schema, partitionResolver); enricher.Enrich(data); }
protected static IContentEntity CreateContent(Guid id, Guid refId, Guid assetId, NamedContentData data = null) { var now = DateTime.UtcNow.ToInstant(); data = data ?? new NamedContentData() .AddField("my-string", new ContentFieldData() .AddValue("de", "value")) .AddField("my-assets", new ContentFieldData() .AddValue("iv", JToken.FromObject(new[] { assetId }))) .AddField("my-number", new ContentFieldData() .AddValue("iv", 1)) .AddField("my-boolean", new ContentFieldData() .AddValue("iv", true)) .AddField("my-datetime", new ContentFieldData() .AddValue("iv", now.ToDateTimeUtc())) .AddField("my-tags", new ContentFieldData() .AddValue("iv", JToken.FromObject(new[] { "tag1", "tag2" }))) .AddField("my-references", new ContentFieldData() .AddValue("iv", JToken.FromObject(new[] { refId }))) .AddField("my-geolocation", new ContentFieldData() .AddValue("iv", JToken.FromObject(new { latitude = 10, longitude = 20 }))) .AddField("my-json", new ContentFieldData() .AddValue("iv", JToken.FromObject(new { value = 1 }))) .AddField("my-localized", new ContentFieldData() .AddValue("de-DE", "de-DE")) .AddField("my-array", new ContentFieldData() .AddValue("iv", new JArray( new JObject( new JProperty("nested-boolean", true), new JProperty("nested-number", 1)), new JObject( new JProperty("nested-boolean", false), new JProperty("nested-number", 2))))); var content = new ContentEntity { Id = id, Version = 1, Created = now, CreatedBy = new RefToken(RefTokenType.Subject, "user1"), LastModified = now, LastModifiedBy = new RefToken(RefTokenType.Subject, "user2"), Data = data }; return(content); }
public static async Task NormalizeAsync(this ITagService tagService, Guid appId, Guid schemaId, Schema schema, NamedContentData newData, NamedContentData?oldData) { Guard.NotNull(tagService); Guard.NotNull(schema); Guard.NotNull(newData); var newValues = new HashSet <string>(); var newArrays = new List <JsonArray>(); var oldValues = new HashSet <string>(); var oldArrays = new List <JsonArray>(); GetValues(schema, newValues, newArrays, newData); if (oldData != null) { GetValues(schema, oldValues, oldArrays, oldData); } if (newValues.Count > 0) { var normalized = await tagService.NormalizeTagsAsync(appId, TagGroups.Schemas(schemaId), newValues, oldValues); foreach (var array in newArrays) { for (var i = 0; i < array.Count; i++) { if (normalized.TryGetValue(array[i].ToString(), out var result)) { array[i] = JsonValue.Create(result); } } } } }
public void ParseData(Schema schema) { data = DataByIds.ToData(schema, ReferencedIdsDeleted); }
public async Task <IActionResult> PatchContent(string app, string name, Guid id, [FromBody] NamedContentData request) { await contentQuery.FindSchemaAsync(App, name); var command = new PatchContent { ContentId = id, Data = request.ToCleaned() }; var context = await CommandBus.PublishAsync(command); var result = context.Result <ContentDataChangedResult>(); var response = result.Data; return(Ok(response)); }