Skip to content

Commit

Permalink
Merge branch 'main' into feature/new-datasets
Browse files Browse the repository at this point in the history
  • Loading branch information
exyi committed May 13, 2024
2 parents 4fbe3cb + b8bef11 commit 6e8ce44
Show file tree
Hide file tree
Showing 17 changed files with 248 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,16 @@ initDotvvm({
"C": 4,
"D": 8,
}
},
tValidated: {
type: "object",
properties: {
RegexValidated: {
validationRules: [
{ ruleName: "regularExpression", errorMessage: "Must have even length", parameters: ["^(..)+$"] }
]
}
}
}
}
})
Expand Down
21 changes: 21 additions & 0 deletions src/Framework/Framework/Resources/Scripts/tests/validation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ import { globalValidationObject as validation, ValidationErrorDescriptor } from
import { createComplexObservableSubViewmodel, createComplexObservableViewmodel, ObservableHierarchy, ObservableSubHierarchy } from "./observableHierarchies"
import { getErrors } from "../validation/error"
import { setLogger } from "../utils/logging";
import { runClientSideValidation } from '../validation/validation'
import dotvvm from '../dotvvm-root'
import { getStateManager } from "../dotvvm-base";
import { StateManager } from "../state-manager";

require("./stateManagement.data")


describe("DotVVM.Validation - public API", () => {
Expand Down Expand Up @@ -319,6 +325,21 @@ describe("DotVVM.Validation - public API", () => {
})
});


describe("DotVVM.Validation - view model validation", () => {
const s = getStateManager() as StateManager<any>
test("Validated object in dynamic", () => {
dotvvm.updateState(x => ({...x, Dynamic: { something: "abc", validatedObj: { $type: "tValidated", RegexValidated: "abcd" } } }))
s.doUpdateNow()
runClientSideValidation(s.stateObservable, {} as any)
expect(dotvvm.validation.errors).toHaveLength(0)
s.patchState({ Dynamic: { validatedObj: { RegexValidated: "abcde" }}})
s.doUpdateNow()
runClientSideValidation(s.stateObservable, {} as any)
expect(dotvvm.validation.errors).toHaveLength(1)
})
})

function SetupComplexObservableViewmodelWithErrorsOnProp1AndProp21() {
validation.removeErrors("/");
const vm = createComplexObservableViewmodel();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ const createValidationHandler = (pathFunction: (context: KnockoutBindingContext)
}
})

const runClientSideValidation = (validationTarget: any, options: PostbackOptions) => {
export const runClientSideValidation = (validationTarget: any, options: PostbackOptions) => {

watchAndTriggerValidationErrorChanged(options,
() => {
Expand Down Expand Up @@ -171,6 +171,9 @@ function validateViewModel(viewModel: any, path: string): void {
}

function validateRecursive(observable: KnockoutObservable<any>, propertyValue: any, type: TypeDefinition, propertyPath: string) {
if (compileConstants.debug && !ko.isObservable(observable)) {
throw Error(`Property ${propertyPath} isn't a knockout observable and cannot be validated.`)
}
const lastSetError: CoerceResult = (observable as any)[lastSetErrorSymbol];
if (lastSetError && lastSetError.isError) {
ValidationError.attach(lastSetError.message, propertyPath, observable);
Expand Down Expand Up @@ -203,7 +206,7 @@ function validateRecursive(observable: KnockoutObservable<any>, propertyValue: a
validateViewModel(propertyValue, propertyPath);
} else {
for (const k of keys(propertyValue)) {
validateRecursive(ko.unwrap(propertyValue[k]), propertyValue[k], { type: "dynamic" }, propertyPath + "/" + k);
validateRecursive(propertyValue[k], ko.unwrap(propertyValue[k]), { type: "dynamic" }, propertyPath + "/" + k);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Framework/Hosting.AspNetCore/Hosting/DotvvmHealthCheck.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,14 @@ public Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, Canc

public static void RegisterHealthCheck(IServiceCollection services)
{
services.ConfigureWithServices<HealthCheckServiceOptions>((options, s) => {
services.Configure<HealthCheckServiceOptions>(options => {
if (options.Registrations.Any(c => c.Name == "DotVVM"))
return;

options.Registrations.Add(
new HealthCheckRegistration(
"DotVVM",
ActivatorUtilities.CreateInstance<DotvvmHealthCheck>(s),
s => ActivatorUtilities.CreateInstance<DotvvmHealthCheck>(s),
null,
new [] { "dotvvm" }
)
Expand Down
13 changes: 12 additions & 1 deletion src/Samples/AspNetCore/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,17 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
}

private string GetApplicationPath(IWebHostEnvironment env)
=> Path.Combine(Path.GetDirectoryName(env.ContentRootPath), "Common");
{
var common = Path.Combine(Path.GetDirectoryName(env.ContentRootPath), "Common");
if (Directory.Exists(common))
{
return common;
}
if (File.Exists(Path.Combine(env.ContentRootPath, "Views/Default.dothtml")))
{
return env.ContentRootPath;
}
throw new DirectoryNotFoundException("Cannot find the 'Common' directory nor the 'Views' directory in the application root.");
}
}
}
13 changes: 12 additions & 1 deletion src/Samples/AspNetCoreLatest/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,17 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ILoggerF
}

private string GetApplicationPath(IWebHostEnvironment env)
=> Path.Combine(Path.GetDirectoryName(env.ContentRootPath), "Common");
{
if (File.Exists(Path.Combine(env.ContentRootPath, "Views/Default.dothtml")))
{
return env.ContentRootPath;
}
var common = Path.Combine(Path.GetDirectoryName(env.ContentRootPath), "Common");
if (File.Exists(Path.Combine(common, "Views/Default.dothtml")))
{
return common;
}
throw new DirectoryNotFoundException("Cannot find the 'Common' directory nor the 'Views' directory in the application root.");
}
}
}
162 changes: 1 addition & 161 deletions src/Samples/Common/DotVVM.Samples.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,171 +19,11 @@
<None Remove="node_modules\**" />
<None Remove="script\**" />
</ItemGroup>
<ItemGroup>
<Content Remove="Views\FeatureSamples\EmbeddedResourceControls\EmbeddedResourceMasterPage.dotmaster" />
<Content Remove="Views\FeatureSamples\ViewModules\ModuleControl.dotcontrol" />
</ItemGroup>
<ItemGroup>
<None Remove="sampleConfig.json" />
<None Remove="tsconfig.react.json" />
<None Remove="Scripts\ControlSamples_NamedCommand_ParameterStaticCommand.js" />
<None Remove="Views\ComplexSamples\NestedComboBox\InnerWrapper.dotcontrol" />
<None Remove="Views\ComplexSamples\NestedComboBox\OuterWrapper.dotcontrol" />
<None Remove="Views\ComplexSamples\SPAErrorReporting\default.dothtml" />
<None Remove="Views\ComplexSamples\SPAErrorReporting\site.dotmaster" />
<None Remove="Views\ComplexSamples\SPAErrorReporting\test.dothtml" />
<None Remove="Views\ComplexSamples\ViewModelPopulate\ViewModelPopulate.dothtml" />
<None Remove="Views\ControlSamples\AppendableDataPager\AppendableDataPager.dothtml" />
<None Remove="Views\ControlSamples\AppendableDataPager\AppendableDataPagerAutoLoad.dothtml" />
<None Remove="Views\ControlSamples\CheckBox\CheckBox_Objects.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\BindingCTValidation_StringToEnum.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\HeavilyNested.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\ItemBinding_ItemValueBinding_Complex_Error.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\ItemBinding_ItemValueBinding_Enum.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\ItemBinding_ItemValueBinding_Number.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\ItemBinding_ItemValueBinding_SelectedValue_ComplexToInt_Error.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\ItemBinding_ItemValueBinding_SelectedValue_StringToInt_Error.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\ItemBinding_ItemValueBinding_String.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\ItemBinding_ItemValueBinding_StringToObject.dothtml" />
<None Remove="Views\ControlSamples\ComboBox\Nullable.dothtml" />
<None Remove="Views\ControlSamples\GridView\GridViewCellDecorators.dothtml" />
<None Remove="Views\ControlSamples\HierarchyRepeater\Basic.dothtml" />
<None Remove="Views\ControlSamples\HierarchyRepeater\NodeControl.dotcontrol" />
<None Remove="Views\ControlSamples\HierarchyRepeater\WithMarkupControl.dothtml" />
<None Remove="Views\ControlSamples\Literal\Literal_NumberBinding.dothtml" />
<None Remove="Views\ControlSamples\MultiSelect\binded.dothtml" />
<None Remove="Views\ControlSamples\MultiSelect\hardcoded.dothtml" />
<None Remove="Views\ControlSamples\NamedCommand\ParameterStaticCommandService.dothtml" />
<None Remove="Views\ControlSamples\RadioButton\Nullable.dothtml" />
<None Remove="Views\ControlSamples\RadioButton\RadioButton_Objects.dothtml" />
<None Remove="Views\ControlSamples\Repeater\IndexInNestedRepeater.dothtml" />
<None Remove="Views\ControlSamples\Repeater\NamedTemplate.dothtml" />
<None Remove="Views\ControlSamples\RouteLink\RouteLinkQueryParameters.dothtml" />
<None Remove="Views\ControlSamples\TemplateHost\Basic.dothtml" />
<None Remove="Views\ControlSamples\TemplateHost\TemplatedListControl.dotcontrol" />
<None Remove="Views\ControlSamples\TemplateHost\TemplatedMarkupControl.dotcontrol" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressQueues.dothtml" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirect.dotmaster" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirect1.dothtml" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirect2.dothtml" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirectSPA.dotmaster" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirectSPA1.dothtml" />
<None Remove="Views\ControlSamples\UpdateProgress\UpdateProgressRedirectSPA2.dothtml" />
<None Remove="Views\ControlSamples\ValidationSummary\MessagesRendering.dothtml" />
<None Remove="Views\ControlSamples\ValidationSummary\Performance.dothtml" />
<None Remove="Views\Errors\CorruptedContentBetweenContentControls.dothtml" />
<None Remove="Views\Errors\ExceptionInLifecycle.dothtml" />
<None Remove="Views\Errors\ExceptionInRender.dothtml" />
<None Remove="Views\Errors\InvalidServiceDirective.dothtml" />
<None Remove="Views\Errors\InvalidLocationFallback.dothtml" />
<None Remove="Views\Errors\MarkupControlInvalidViewModel.dothtml" />
<None Remove="Views\Errors\MarkupControlPropertiesSameName.dotcontrol" />
<None Remove="Views\Errors\MarkupControlPropertiesSameNameWithBase.dotcontrol" />
<None Remove="Views\Errors\MarkupControlPropertiesSameNameWithBase.dothtml" />
<None Remove="Views\Errors\ResourceCircularDependency.dothtml" />
<None Remove="Views\FeatureSamples\Api\ApiInSpa_Master.dotmaster" />
<None Remove="Views\FeatureSamples\Api\ApiInSpa_PageA.dothtml" />
<None Remove="Views\FeatureSamples\Api\ApiInSpa_PageB.dothtml" />
<None Remove="Views\FeatureSamples\Api\ApiRefresh.dothtml" />
<None Remove="Views\FeatureSamples\Api\CollectionOddEvenWithRestApi.dothtml" />
<None Remove="Views\FeatureSamples\Api\IncludedInPage.dothtml" />
<None Remove="Views\FeatureSamples\Api\IsLoading.dothtml" />
<None Remove="Views\FeatureSamples\Attribute\ToStringConversion.dothtml" />
<None Remove="Views\FeatureSamples\AutoUI\AutoEditor.dothtml" />
<None Remove="Views\FeatureSamples\AutoUI\AutoForm.dothtml" />
<None Remove="Views\FeatureSamples\AutoUI\AutoGridViewColumns.dothtml" />
<None Remove="Views\FeatureSamples\AutoUI\BootstrapForm3.dothtml" />
<None Remove="Views\FeatureSamples\AutoUI\BootstrapForm4.dothtml" />
<None Remove="Views\FeatureSamples\AutoUI\BootstrapForm5.dothtml" />
<None Remove="Views\FeatureSamples\BindingVariables\StaticCommandVariablesWithService_Complex.dothtml" />
<None Remove="Views\FeatureSamples\BindingVariables\StaticCommandVariablesWithService_Complex2.dothtml" />
<None Remove="Views\FeatureSamples\BindingVariables\StaticCommandVariablesWithService_Simple.dothtml" />
<None Remove="Views\FeatureSamples\Caching\CachedValues.dothtml" />
<None Remove="Views\FeatureSamples\CompositeControls\ControlPropertyNamingConflict.dothtml" />
<None Remove="Views\FeatureSamples\CommandActionFilter\CommandActionFilter.dothtml" />
<None Remove="Views\FeatureSamples\CustomPrimitiveTypes\Basic.dothtml" />
<None Remove="Views\FeatureSamples\CustomPrimitiveTypes\RouteLink.dothtml" />
<None Remove="Views\FeatureSamples\CustomPrimitiveTypes\TextBox.dothtml" />
<None Remove="Views\FeatureSamples\CustomPrimitiveTypes\UsedInControls.dothtml" />
<None Remove="Views\FeatureSamples\DataSet\GitHubApiStaticCommands.dothtml" />
<None Remove="Views\FeatureSamples\EmbeddedResourceControls\EmbeddedResourceMasterPage.dotmaster" />
<None Remove="Views\FeatureSamples\EmbeddedResourceControls\PageWithEmbeddedResourceMasterPage.dothtml" />
<None Remove="Views\FeatureSamples\Formatting\AutoResourceInclusion.dothtml" />
<None Remove="Views\FeatureSamples\Formatting\AutoResourceInclusionMaster.dotmaster" />
<None Remove="Views\FeatureSamples\Formatting\ToStringGlobalFunctionBug.dothtml" />
<None Remove="Views\FeatureSamples\DataSet\GitHubApi.dothtml" />
<None Remove="Views\FeatureSamples\HotReload\ViewChanges.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\ArrayTranslation.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\DateTimeTranslations.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\DictionaryIndexerTranslation.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\GenericMethodTranslation.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\ListIndexerTranslation.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\ListMethodTranslations.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\WebUtilityTranslations.dothtml" />
<None Remove="Views\FeatureSamples\JavascriptTranslation\StringMethodTranslations.dothtml" />
<None Remove="Views\FeatureSamples\JsComponentIntegration\ReactComponentIntegration.dothtml" />
<None Remove="Views\FeatureSamples\JsDirectives\BasicSample.dothtml" />
<None Remove="Views\FeatureSamples\LambdaExpressions\ClientSideFiltering.dothtml" />
<None Remove="Views\FeatureSamples\LambdaExpressions\LambdaExpressions.dothtml" />
<None Remove="Views\FeatureSamples\Localization\Globalize.dothtml" />
<None Remove="Views\FeatureSamples\MarkupControl\MarkupDefinedProperties.dothtml" />
<None Remove="Views\FeatureSamples\MarkupControl\MarkupDefinedPropertiesControl.dotcontrol" />
<None Remove="Views\FeatureSamples\MarkupControl\ServiceDependency\ServiceDependencyControl.dotcontrol" />
<None Remove="Views\FeatureSamples\PostbackAbortSignal\LoadAbortViewModel.dothtml" />
<None Remove="Views\FeatureSamples\RenderSettingsModeServer\RepeaterCollectionSetToNull.dothtml" />
<None Remove="Views\FeatureSamples\Serialization\ByteArray.dothtml" />
<None Remove="Views\FeatureSamples\Serialization\DateOnlyTimeOnly.dothtml" />
<None Remove="Views\FeatureSamples\Serialization\TimeSpan.dothtml" />
<None Remove="Views\FeatureSamples\Serialization\EnumSerializationCoercion.dothtml" />
<None Remove="Views\FeatureSamples\Serialization\SerializationDateTimeOffset.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\StaticCommand_Validation.dothtml" />
<None Remove="Views\FeatureSamples\StringInterpolation\StringInterpolation.dothtml" />
<None Remove="Views\FeatureSamples\Validation\RangeClientSideValidation.dothtml" />
<None Remove="Views\FeatureSamples\Validation\ValidationTargetIsCollection.dothtml" />
<None Remove="Views\FeatureSamples\Validation\ValidatorValueComplexExpressions.dothtml" />
<None Remove="Views\FeatureSamples\ViewModelDeserialization\PropertyNullAssignment.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\Incrementer.dotcontrol" />
<None Remove="Views\FeatureSamples\ViewModules\IncrementerInRepeater.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\InnerModuleControl.dotcontrol" />
<None Remove="Views\FeatureSamples\ViewModules\LinkModuleControl.dotcontrol" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleControl.dotcontrol" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleInMarkupControl.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleInMarkupControlTwice.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleInPage.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleInPageCommandAmbiguous.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleInPageMasterPage.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleInPageSpaMasterPage.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleInPageSpaMasterPage2.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleMasterPage.dotmaster" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleRegistrationPropagation.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\ModuleSpaMasterPage.dotmaster" />
<None Remove="Views\FeatureSamples\MarkupControl\CommandPropertiesInMarkupControl.dothtml" />
<None Remove="Views\FeatureSamples\MarkupControl\Device.dotcontrol" />
<None Remove="Views\FeatureSamples\MarkupControl\Dialog.dotcontrol" />
<None Remove="Views\FeatureSamples\MarkupControl\StaticCommandInMarkupControl.dothtml" />
<None Remove="Views\FeatureSamples\MarkupControl\StaticCommandInMarkupControlCallingRegularCommand.dothtml" />
<None Remove="Views\FeatureSamples\PostbackConcurrency\RedirectPostbackQueue.dothtml" />
<None Remove="Views\FeatureSamples\PostbackConcurrency\StressTest.dothtml" />
<None Remove="Views\FeatureSamples\PostBack\RecursiveTextRepeater.dotcontrol" />
<None Remove="Views\FeatureSamples\PostBack\RecursiveTextRepeater2.dotcontrol" />
<None Remove="Views\FeatureSamples\PostBack\UniqueIdGenerationOnPostbackUpdate.dothtml" />
<None Remove="Views\FeatureSamples\Redirect\Redirect_StaticCommand.dothtml" />
<None Remove="Views\FeatureSamples\Resources\LocationFallback.dothtml" />
<None Remove="Views\FeatureSamples\Resources\RequiredOnPostback.dothtml" />
<None Remove="Views\FeatureSamples\Serialization\DeserializationVirtualElements.dothtml" />
<None Remove="Views\FeatureSamples\CustomResponseProperties\SimpleExceptionFilter.dothtml" />
<None Remove="Views\FeatureSamples\Serialization\Dictionary.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\CustomAwaitable.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\StaticCommand_ArrayAssigment.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\StaticCommand_LoadComplexDataFromService.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\StaticCommand_NullAssignment.dothtml" />
<None Remove="Views\FeatureSamples\StaticCommand\StaticCommand_TaskSequence.dothtml" />
<None Remove="Views\FeatureSamples\UsageValidation\OverrideValidation.dothtml" />
<None Remove="Views\FeatureSamples\Validation\EnforceClientSideValidationDisabled.dothtml" />
<None Remove="Views\FeatureSamples\Validation\InvalidCssClassNotDuplicated.dothtml" />
<None Remove="Views\FeatureSamples\Validation\ValidationPropertyPathResolving.dothtml" />
<None Remove="Views\FeatureSamples\ViewModelCache\ViewModelCache_Miss.dothtml" />
<None Remove="Views\FeatureSamples\ViewModules\OuterModuleControl.dotcontrol" />
<None Remove="**/*.dotmaster;**/*.dotcontrol;**/*.dothtml" />
</ItemGroup>
<ItemGroup>
<Content Include="sampleConfig.json">
Expand Down
Loading

0 comments on commit 6e8ce44

Please sign in to comment.