From f74af69291044e1d81b87804c4cfeeffc2e68e42 Mon Sep 17 00:00:00 2001 From: Eric Nguyen Date: Mon, 10 Oct 2022 09:28:47 +0000 Subject: [PATCH] Merged PR 211: Add csharp classes to SVGLayoutDesigner and add tests --- .drone.yml | 1 - .vscode/tasks.json | 41 +++ README.md | 10 +- azure-pipelines.yml | 8 +- csharp/SVGLDLibs/.editorconfig | 9 + .../SVGLDLibs/Models/ActionContainerModel.cs | 21 ++ .../Models/AddingBehaviorEnumModel.cs | 19 ++ .../SVGLDLibs/Models/ApplicationStateModel.cs | 26 ++ .../Models/AvailableContainerModel.cs | 192 ++++++++++++ .../SVGLDLibs/Models/AvailableSymbolModel.cs | 18 ++ csharp/SVGLDLibs/SVGLDLibs/Models/CSSStyle.cs | 19 ++ csharp/SVGLDLibs/SVGLDLibs/Models/Category.cs | 13 + .../Models/ConfigurationResponseModel.cs | 32 ++ .../SVGLDLibs/Models/ContainerModel.cs | 17 ++ .../SVGLDLibs/Models/ContainerProperties.cs | 153 ++++++++++ .../SVGLDLibs/Models/GetFeedbackRequest.cs | 10 + .../SVGLDLibs/Models/GetFeedbackResponse.cs | 11 + .../SVGLDLibs/SVGLDLibs/Models/ImageModel.cs | 16 + csharp/SVGLDLibs/SVGLDLibs/Models/Margin.cs | 19 ++ csharp/SVGLDLibs/SVGLDLibs/Models/Message.cs | 8 + .../SVGLDLibs/SVGLDLibs/Models/MessageType.cs | 10 + .../SVGLDLibs/SVGLDLibs/Models/Orientation.cs | 12 + csharp/SVGLDLibs/SVGLDLibs/Models/Pattern.cs | 26 ++ .../SVGLDLibs/SVGLDLibs/Models/PointModel.cs | 12 + csharp/SVGLDLibs/SVGLDLibs/Models/Position.cs | 16 + .../Models/PositionReferenceEnumModel.cs | 26 ++ .../Models/SetContainerListRequest.cs | 22 ++ .../Models/SetContainerListResponse.cs | 14 + .../SVGLDLibs/SVGLDLibs/Models/SymbolModel.cs | 16 + csharp/SVGLDLibs/SVGLDLibs/SVGLDLibs.csproj | 9 + .../Controllers/SVGLDController.cs | 155 ++++++++++ csharp/SVGLDLibs/SVGLDWebAPI/Program.cs | 37 +++ .../Properties/launchSettings.json | 31 ++ csharp/SVGLDLibs/SVGLDWebAPI/README.md | 15 + .../SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj | 17 ++ .../SVGLDWebAPI/appsettings.Development.json | 8 + csharp/SVGLDLibs/SVGLDWebAPI/appsettings.json | 9 + package.json | 2 + src/Components/API/api.test.tsx | 277 +++++++++++++++++- tsconfig.json | 2 +- 40 files changed, 1346 insertions(+), 13 deletions(-) create mode 100644 .vscode/tasks.json create mode 100644 csharp/SVGLDLibs/.editorconfig create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/ActionContainerModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/AddingBehaviorEnumModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/ApplicationStateModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/AvailableContainerModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/AvailableSymbolModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/CSSStyle.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/Category.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/ConfigurationResponseModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/ContainerModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/ContainerProperties.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackRequest.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackResponse.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/ImageModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/Margin.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/Message.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/MessageType.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/Orientation.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/Pattern.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/PointModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/Position.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/PositionReferenceEnumModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListRequest.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListResponse.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/Models/SymbolModel.cs create mode 100644 csharp/SVGLDLibs/SVGLDLibs/SVGLDLibs.csproj create mode 100644 csharp/SVGLDLibs/SVGLDWebAPI/Controllers/SVGLDController.cs create mode 100644 csharp/SVGLDLibs/SVGLDWebAPI/Program.cs create mode 100644 csharp/SVGLDLibs/SVGLDWebAPI/Properties/launchSettings.json create mode 100644 csharp/SVGLDLibs/SVGLDWebAPI/README.md create mode 100644 csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj create mode 100644 csharp/SVGLDLibs/SVGLDWebAPI/appsettings.Development.json create mode 100644 csharp/SVGLDLibs/SVGLDWebAPI/appsettings.json diff --git a/.drone.yml b/.drone.yml index a548d55..64a7000 100644 --- a/.drone.yml +++ b/.drone.yml @@ -8,7 +8,6 @@ steps: commands: - node ./test-server/http.js & - npm i - - npm run test:nowatch - npm run build --- diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a34d5d6 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,41 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj", + "/property:GenerateFullPaths=true", + "/consoleloggerparameters:NoSummary" + ], + "problemMatcher": "$msCompile" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "--project", + "${workspaceFolder}/csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj" + ], + "problemMatcher": "$msCompile" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index fdc80c7..03be50b 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,12 @@ An svg layout designer. # Getting Started -Requierements : -- NodeJS -- npm -- Chrome > 98 -- pnpm (optional but recommanded unless you prefer having a huge `node_modules` directory) +Requirements : +- `node` >= 16.x (>= 17.x to run vitest tests) +- `npm` +- pnpm (optional) reduce `node_modules` folder size by using symlinks - [`git-lfs`](https://git-lfs.github.com/) (in order to clone the documentation) +- `dotnet` (optional) used for api test # Developping diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 24b650f..93570dc 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -34,12 +34,8 @@ steps: - bash: | set -euo pipefail node --version - node ./test-server/http.js & - jobs pnpm i - pnpm run test:nowatch pnpm run build - kill -2 %1 2>/dev/null displayName: 'Test on Node.js 16.x LTS' - task: NodeTool@0 @@ -51,11 +47,13 @@ steps: set -euo pipefail node --version node ./test-server/http.js & + dotnet run --project=./csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj & jobs + sleep 5 pnpm i pnpm run test:nowatch pnpm run build - kill -2 %1 2>/dev/null + kill -2 %1 %2 2>/dev/null displayName: 'Test on Node.js 18.x Latest' - publish: $(System.DefaultWorkingDirectory)/dist diff --git a/csharp/SVGLDLibs/.editorconfig b/csharp/SVGLDLibs/.editorconfig new file mode 100644 index 0000000..37707e0 --- /dev/null +++ b/csharp/SVGLDLibs/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +trim_trailing_whitespace = true +end_of_line = crlf +indent_style = space +indent_size = 4 +insert_final_newline = false diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/ActionContainerModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/ActionContainerModel.cs new file mode 100644 index 0000000..8e5da1f --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/ActionContainerModel.cs @@ -0,0 +1,21 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class ActionContainerModel + { + [DataMember(EmitDefaultValue = false)] + public string Id { get; set; } + [DataMember(EmitDefaultValue = false)] + public ImageModel CustomLogo { get; set; } + [DataMember(EmitDefaultValue = false)] + public string Label { get; set; } + [DataMember(EmitDefaultValue = false)] + public string Description { get; set; } + [DataMember(EmitDefaultValue = false)] + public string Action { get; set; } + [DataMember(EmitDefaultValue = false)] + public AddingBehaviorEnumModel AddingBehavior { get; set; } + + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/AddingBehaviorEnumModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/AddingBehaviorEnumModel.cs new file mode 100644 index 0000000..da5e4dc --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/AddingBehaviorEnumModel.cs @@ -0,0 +1,19 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public enum AddingBehaviorEnumModel + { + [EnumMember] + Append, + + [EnumMember] + InsertInto, + + [EnumMember] + Replace, + + [EnumMember] + ReplaceParent, + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/ApplicationStateModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/ApplicationStateModel.cs new file mode 100644 index 0000000..1c3cf0e --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/ApplicationStateModel.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class ApplicationStateModel + { + [DataMember(EmitDefaultValue = false)] + public string lastAction; + + [DataMember(EmitDefaultValue = false)] + public ContainerModel mainContainer; + + [DataMember(EmitDefaultValue = false)] + public string selectedContainerId; + + [DataMember(EmitDefaultValue = false)] + public Dictionary typeCounters; + + [DataMember(EmitDefaultValue = false)] + public Dictionary symbols; + + [DataMember(EmitDefaultValue = false)] + public string selectedSymbolId; + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/AvailableContainerModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/AvailableContainerModel.cs new file mode 100644 index 0000000..34e44d5 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/AvailableContainerModel.cs @@ -0,0 +1,192 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class AvailableContainerModel + { + /** type */ + [DataMember(EmitDefaultValue = false, IsRequired = true)] + public string Type { get; set; } + + /** displayed text */ + [DataMember(EmitDefaultValue = false)] + public string DisplayedText { get; set; } + + /** category */ + [DataMember(EmitDefaultValue = false)] + public string Category { get; set; } + + /** orientation */ + [DataMember(EmitDefaultValue = false)] + public Orientation Orientation { get; set; } + + /** horizontal offset */ + [DataMember(EmitDefaultValue = false)] + public double? X { get; set; } + + /** vertical offset */ + [DataMember(EmitDefaultValue = false)] + public double? Y { get; set; } + + /** width */ + [DataMember(EmitDefaultValue = false)] + public double? Width { get; set; } + + /** height */ + [DataMember(EmitDefaultValue = false)] + public double? Height { get; set; } + + /** + * Minimum width (min=1) + */ + [DataMember(EmitDefaultValue = false)] + public double? MinWidth { get; set; } + + /** + * Maximum width + */ + [DataMember(EmitDefaultValue = false)] + public double? MaxWidth { get; set; } + + /** + * Minimum height (min=1) + */ + [DataMember(EmitDefaultValue = false)] + public double? MinHeight { get; set; } + + /** + * Maximum height + */ + [DataMember(EmitDefaultValue = false)] + public double? MaxHeight { get; set; } + + /** margin */ + [DataMember(EmitDefaultValue = false)] + public Margin Margin { get; set; } + + /** true if anchor, false otherwise */ + [DataMember(EmitDefaultValue = false)] + public bool? IsAnchor { get; set; } + + /** true if flex, false otherwise */ + [DataMember(EmitDefaultValue = false)] + public bool? IsFlex { get; set; } + + /** + * Allow to use a Pattern to create the list of children + * Cannot be used with DefaultChildType, + * DefaultChildType will be disabled for this container and the children + */ + [DataMember(EmitDefaultValue = false)] + public string Pattern { get; set; } + + /** Method used on container add */ + [DataMember(EmitDefaultValue = false)] + public AddingBehaviorEnumModel? AddMethod { get; set; } + + /** + * (optional) + * Disabled when Pattern is used. + * + * Replace a by a customized "SVG". It is not really an svg but it at least allows + * to draw some patterns that can be bind to the properties of the container + * Use {prop} to bind a property. Use {{ styleProp }} to use an object. + * Example : + * ``` + * ` + * + * + * + * ` + * ``` + */ + [DataMember(EmitDefaultValue = false)] + public string DefaultChildType { get; set; } + + /** Horizontal alignment, also determines the visual location of x {Left = 0, Center, Right } */ + [DataMember(EmitDefaultValue = false)] + public PositionReferenceEnumModel? PositionReference { get; set; } + + [DataMember(EmitDefaultValue = false)] + public bool? HideChildrenInTreeview { get; set; } + + /** if true, show the dimension of the container */ + [DataMember(EmitDefaultValue = false)] + public Position[] ShowSelfDimensions { get; set; } + + /** if true show the overall dimensions of its children */ + [DataMember(EmitDefaultValue = false)] + public Position[] ShowChildrenDimensions { get; set; } + + /** + * if true, allows a parent dimension borrower to uses its x coordinate for as a reference point for a dimension + */ + [DataMember(EmitDefaultValue = false)] + public Orientation[] MarkPosition { get; set; } + + /** + * if true, show a dimension from the edge of the container to end + * and insert dimensions mark + */ + [DataMember(EmitDefaultValue = false)] + public Position[] ShowDimensionWithMarks { get; set; } + + /** + * if true, hide the entry in the sidebar (default: false) + */ + [DataMember(EmitDefaultValue = false)] + public bool? IsHidden { get; set; } + + /** + * if true, hide the entry in the sidebar (default: false) + */ + [DataMember(EmitDefaultValue = false)] + public string[] Blacklist { get; set; } + + /** + * Cannot be used with blacklist. Whitelist will be prioritized. + * To disable the whitelist, Whitelist must be undefined. + * Only allow a set of available container to be added inside + */ + [DataMember(EmitDefaultValue = false)] + public string[] Whitelist { get; set; } + + /** + * List of possible actions shown on right-click + */ + [DataMember(EmitDefaultValue = false)] + public List Actions { get; set; } + + /** + * (optional) + * Replace a by a customized "SVG". It is not really an svg but it at least allows + * to draw some patterns that can be bind to the properties of the container + * Use {prop} to bind a property. Use {{ styleProp }} to use an object. + * Example : + * ``` + * ` + * + * + * + * ` + * ``` + */ + [DataMember(EmitDefaultValue = false)] + public string CustomSVG { get; set; } + + /** + * (optional) + * Style of the + */ + [DataMember(EmitDefaultValue = false)] + public CSSStyle Style { get; set; } + + /** + * (optional) + * User data that can be used for data storage or custom SVG + */ + [DataMember(EmitDefaultValue = false)] + public Dictionary UserData { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/AvailableSymbolModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/AvailableSymbolModel.cs new file mode 100644 index 0000000..9736236 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/AvailableSymbolModel.cs @@ -0,0 +1,18 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class AvailableSymbolModel + { + [DataMember(EmitDefaultValue = false)] + public string Name { get; set; } + [DataMember(EmitDefaultValue = false)] + public ImageModel Image { get; set; } + [DataMember(EmitDefaultValue = false)] + public PositionReferenceEnumModel PositionReference { get; set; } + [DataMember(EmitDefaultValue = false)] + public double Width { get; set; } + [DataMember(EmitDefaultValue = false)] + public double Height { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/CSSStyle.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/CSSStyle.cs new file mode 100644 index 0000000..217ea28 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/CSSStyle.cs @@ -0,0 +1,19 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class CSSStyle + { + [DataMember(EmitDefaultValue = false)] + public double? strokeWidth; + + [DataMember(EmitDefaultValue = false)] + public double? fillOpacity; + + [DataMember(EmitDefaultValue = false)] + public string stroke; + + [DataMember(EmitDefaultValue = false)] + public string fill; + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/Category.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/Category.cs new file mode 100644 index 0000000..01550a8 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/Category.cs @@ -0,0 +1,13 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class Category + { + [DataMember(EmitDefaultValue = false)] + public string Type { get; set; } + + [DataMember(EmitDefaultValue = false)] + public string DisplayedText { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/ConfigurationResponseModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/ConfigurationResponseModel.cs new file mode 100644 index 0000000..6ec6bec --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/ConfigurationResponseModel.cs @@ -0,0 +1,32 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class ConfigurationResponseModel + { + public ConfigurationResponseModel(AvailableContainerModel mainContainer) + { + MainContainer = mainContainer; + AvailableContainers = new List(); + AvailableSymbols = new List(); + Categories = new List(); + Patterns = new List(); + } + + [DataMember(EmitDefaultValue = false)] + public List AvailableContainers { get; set; } + + [DataMember(EmitDefaultValue = false)] + public List AvailableSymbols { get; set; } + + [DataMember(EmitDefaultValue = false)] + public List Categories { get; set; } + + [DataMember(EmitDefaultValue = false)] + public List Patterns { get; set; } + + [DataMember(EmitDefaultValue = false, IsRequired = true)] + public AvailableContainerModel MainContainer { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/ContainerModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/ContainerModel.cs new file mode 100644 index 0000000..0cf2f30 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/ContainerModel.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class ContainerModel + { + [DataMember(EmitDefaultValue = false)] + public List children; + + [DataMember(EmitDefaultValue = false)] + public ContainerProperties properties; + + [DataMember(EmitDefaultValue = false)] + public Dictionary userData; + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/ContainerProperties.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/ContainerProperties.cs new file mode 100644 index 0000000..799fe69 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/ContainerProperties.cs @@ -0,0 +1,153 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class ContainerProperties + { + /** id of the container */ + [DataMember(EmitDefaultValue = false)] + public string id; + + /** type matching the configuration on construction */ + [DataMember(EmitDefaultValue = false)] + public string type; + + /** id of the parent container (null when there is no parent) */ + [DataMember(EmitDefaultValue = false)] + public string parentId; + + /** id of the linked symbol ('' when there is no parent) */ + [DataMember(EmitDefaultValue = false)] + public string linkedSymbolId; + + /** Text displayed in the container */ + [DataMember(EmitDefaultValue = false)] + public string displayedText; + + /** orientation */ + [DataMember(EmitDefaultValue =false)] + public Orientation orientation; + + /** horizontal offset */ + [DataMember(EmitDefaultValue = false)] + public double x; + + /** vertical offset */ + [DataMember(EmitDefaultValue = false)] + public double y; + + /** margin */ + [DataMember(EmitDefaultValue = false)] + public Margin margin; + + /** width */ + [DataMember(EmitDefaultValue = false)] + public double width; + + /** height */ + [DataMember(EmitDefaultValue = false)] + public double height; + + /** + * Minimum width (min=1) + */ + [DataMember(EmitDefaultValue = false)] + public double minWidth; + + /** + * Maximum width + */ + [DataMember(EmitDefaultValue = false)] + public double maxWidth; + + /** + * Minimum height (min=1) + * Allows the container to set isRigidBody to false when it gets squeezed + * by an anchor + */ + [DataMember(EmitDefaultValue = false)] + public double minHeight; + + /** + * Maximum height + */ + [DataMember(EmitDefaultValue = false)] + public double maxHeight; + + + /** true if anchor, false otherwise */ + [DataMember(EmitDefaultValue = false)] + public bool isAnchor; + + /** true if flex, false otherwise */ + [DataMember(EmitDefaultValue = false)] + public bool isFlex; + + /** Horizontal alignment, also determines the visual location of x {Left = 0, Center, Right } */ + [DataMember(EmitDefaultValue = false)] + public PositionReferenceEnumModel positionReference; + + /** Hide the children in the treeview */ + [DataMember(EmitDefaultValue = false)] + public bool hideChildrenInTreeview; + + /** if true, show the dimension of the container */ + [DataMember(EmitDefaultValue = false)] + public Position[] showSelfDimensions; + + /** if true show the overall dimensions of its children */ + [DataMember(EmitDefaultValue = false)] + public Position[] showChildrenDimensions; + + /** + * if true, allows a parent dimension borrower to borrow its x coordinate + * as a reference point for a dimension + */ + [DataMember(EmitDefaultValue = false)] + public Orientation[] markPosition; + + /** + * if true, show a dimension from the edge of the container to end + * and insert dimensions marks at lift up children (see liftDimensionToBorrower) + */ + [DataMember(EmitDefaultValue = false)] + public Position[] showDimensionWithMarks; + + /** + * Warnings of a container + */ + [DataMember(EmitDefaultValue = false)] + public string warning; + + /** + * (optional) + * Replace a by a customized "SVG". It is not really an svg but it at least allows + * to draw some patterns that can be bind to the properties of the container + * Use {prop} to bind a property. Use {{ styleProp }} to use an object. + * Example : + * ``` + * ` + * + * + * + * ` + * ``` + */ + [DataMember(EmitDefaultValue = false)] + public string customSVG; + + /** + * (optional) + * Style of the + */ + [DataMember(EmitDefaultValue = false)] + public CSSStyle style; + + /** + * (optional) + * User data that can be used for data storage or custom SVG + */ + [DataMember(EmitDefaultValue = false)] + public object userData; + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackRequest.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackRequest.cs new file mode 100644 index 0000000..4348c5d --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackRequest.cs @@ -0,0 +1,10 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class GetFeedbackRequest + { + [DataMember(EmitDefaultValue = false)] + public ApplicationStateModel ApplicationState { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackResponse.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackResponse.cs new file mode 100644 index 0000000..55aae84 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/GetFeedbackResponse.cs @@ -0,0 +1,11 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class GetFeedbackResponse + { + [DataMember(EmitDefaultValue = false)] + public List messages { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/ImageModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/ImageModel.cs new file mode 100644 index 0000000..6c28cdd --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/ImageModel.cs @@ -0,0 +1,16 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class ImageModel + { + [DataMember(EmitDefaultValue = false)] + public string Name { get; set; } + [DataMember(EmitDefaultValue = false)] + public string Url { get; set; } + [DataMember(EmitDefaultValue = false)] + public string Base64Image { get; set; } + [DataMember(EmitDefaultValue = false)] + public string Svg { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/Margin.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/Margin.cs new file mode 100644 index 0000000..db200e8 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/Margin.cs @@ -0,0 +1,19 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class Margin + { + [DataMember(EmitDefaultValue = false)] + public double? left { get; set; } + + [DataMember(EmitDefaultValue = false)] + public double? bottom { get; set; } + + [DataMember(EmitDefaultValue = false)] + public double? top { get; set; } + + [DataMember(EmitDefaultValue = false)] + public double? right { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/Message.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/Message.cs new file mode 100644 index 0000000..03b9f33 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/Message.cs @@ -0,0 +1,8 @@ +namespace SVGLDLibs.Models +{ + public class Message + { + public string text { get; set; } + public MessageType type { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/MessageType.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/MessageType.cs new file mode 100644 index 0000000..c752104 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/MessageType.cs @@ -0,0 +1,10 @@ +namespace SVGLDLibs.Models +{ + public enum MessageType + { + Normal, + Success, + Warning, + Error + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/Orientation.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/Orientation.cs new file mode 100644 index 0000000..bdc38ee --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/Orientation.cs @@ -0,0 +1,12 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public enum Orientation + { + [EnumMember] + Horizontal, + [EnumMember] + Vertical + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/Pattern.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/Pattern.cs new file mode 100644 index 0000000..af4ba0b --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/Pattern.cs @@ -0,0 +1,26 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class Pattern + { + + public Pattern() + { + children = new List(); + } + + [DataMember(EmitDefaultValue = false)] + public string id { get; set; } + + [DataMember(EmitDefaultValue = false)] + public string text { get; set; } + + [DataMember(EmitDefaultValue = false)] + public string wrapper { get; set; } + + [DataMember(EmitDefaultValue = true, IsRequired = true)] + public List children { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/PointModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/PointModel.cs new file mode 100644 index 0000000..327ad2e --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/PointModel.cs @@ -0,0 +1,12 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class PointModel + { + [DataMember(EmitDefaultValue = false)] + public string X { get; set; } + [DataMember(EmitDefaultValue = false)] + public string Y { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/Position.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/Position.cs new file mode 100644 index 0000000..3436aeb --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/Position.cs @@ -0,0 +1,16 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public enum Position + { + [EnumMember] + Left, + [EnumMember] + Down, + [EnumMember] + Up, + [EnumMember] + Right + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/PositionReferenceEnumModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/PositionReferenceEnumModel.cs new file mode 100644 index 0000000..7a8e6fd --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/PositionReferenceEnumModel.cs @@ -0,0 +1,26 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public enum PositionReferenceEnumModel + { + [EnumMember] + TopLeft, + [EnumMember] + TopCenter, + [EnumMember] + TopRight, + [EnumMember] + CenterLeft, + [EnumMember] + CenterCenter, + [EnumMember] + CenterRight, + [EnumMember] + BottomLeft, + [EnumMember] + BottomCenter, + [EnumMember] + BottomRight + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListRequest.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListRequest.cs new file mode 100644 index 0000000..f67d021 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListRequest.cs @@ -0,0 +1,22 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class SetContainerListRequest + { + [DataMember(EmitDefaultValue = false)] + public ActionContainerModel Action { get; set; } + + [DataMember(EmitDefaultValue = false)] + public ContainerModel Container { get; set; } + + [DataMember(EmitDefaultValue = false)] + public ContainerModel PreviousContainer { get; set; } + + [DataMember(EmitDefaultValue = false)] + public ContainerModel NextContainer { get; set; } + + [DataMember(EmitDefaultValue = false)] + public ApplicationStateModel ApplicationState { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListResponse.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListResponse.cs new file mode 100644 index 0000000..8da16e9 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/SetContainerListResponse.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class SetContainerListResponse + { + [DataMember(EmitDefaultValue = false)] + public List Containers { get; set; } + + [DataMember(EmitDefaultValue = false)] + public AddingBehaviorEnumModel AddingBehavior { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/Models/SymbolModel.cs b/csharp/SVGLDLibs/SVGLDLibs/Models/SymbolModel.cs new file mode 100644 index 0000000..1b06c00 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/Models/SymbolModel.cs @@ -0,0 +1,16 @@ +using System.Runtime.Serialization; + +namespace SVGLDLibs.Models +{ + public class SymbolModel : AvailableSymbolModel + { + [DataMember(EmitDefaultValue = false)] + public string Id { get; set; } + [DataMember(EmitDefaultValue = false)] + public PointModel Point { get; set; } + [DataMember(EmitDefaultValue = false)] + public bool IsLinkedToContainer { get; set; } + [DataMember(EmitDefaultValue = false)] + public string LinkedContainerId { get; set; } + } +} \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDLibs/SVGLDLibs.csproj b/csharp/SVGLDLibs/SVGLDLibs/SVGLDLibs.csproj new file mode 100644 index 0000000..bc76ab4 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDLibs/SVGLDLibs.csproj @@ -0,0 +1,9 @@ + + + + net6.0 + disable + disable + + + diff --git a/csharp/SVGLDLibs/SVGLDWebAPI/Controllers/SVGLDController.cs b/csharp/SVGLDLibs/SVGLDWebAPI/Controllers/SVGLDController.cs new file mode 100644 index 0000000..b12a231 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDWebAPI/Controllers/SVGLDController.cs @@ -0,0 +1,155 @@ +using Microsoft.AspNetCore.Mvc; +using SVGLDLibs.Models; + +namespace SVGLDWebAPI.Controllers; + + +[ApiController] +[Route("[controller]/[Action]")] +public class SVGLDController : ControllerBase +{ + [HttpPost(Name = nameof(SVGLDLibs.Models.ActionContainerModel))] + public bool ActionContainerModel(ActionContainerModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.AddingBehaviorEnumModel))] + public bool AddingBehaviorEnumModel(AddingBehaviorEnumModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.ApplicationStateModel))] + public bool ApplicationStateModel(ApplicationStateModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.AvailableContainerModel))] + public bool AvailableContainerModel(AvailableContainerModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.AvailableSymbolModel))] + public bool AvailableSymbolModel(AvailableSymbolModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.Category))] + public bool Category(Category model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.ConfigurationResponseModel))] + public bool ConfigurationResponseModel(ConfigurationResponseModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.ContainerModel))] + public bool ContainerModel(ContainerModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.ContainerProperties))] + public bool ContainerProperties(ContainerProperties model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.CSSStyle))] + public bool CSSStyle(CSSStyle model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.GetFeedbackRequest))] + public bool GetFeedbackRequest(GetFeedbackRequest model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.GetFeedbackResponse))] + public bool GetFeedbackResponse(GetFeedbackResponse model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.ImageModel))] + public bool ImageModel(ImageModel model) + { + return true; + } + + + [HttpPost(Name = nameof(SVGLDLibs.Models.Margin))] + public bool Margin(Margin model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.Message))] + public bool Message(Message model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.MessageType))] + public bool MessageType(MessageType model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.Orientation))] + public bool Orientation(Orientation model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.Pattern))] + public bool Pattern(Pattern model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.PointModel))] + public bool PointModel(PointModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.Position))] + public bool Position(Position model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.PositionReferenceEnumModel))] + public bool PositionReferenceEnumModel(PositionReferenceEnumModel model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.SetContainerListRequest))] + public bool SetContainerListRequest(SetContainerListRequest model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.SetContainerListResponse))] + public bool SetContainerListResponse(SetContainerListResponse model) + { + return true; + } + + [HttpPost(Name = nameof(SVGLDLibs.Models.SymbolModel))] + public bool SymbolModel(SymbolModel model) + { + return true; + } +} diff --git a/csharp/SVGLDLibs/SVGLDWebAPI/Program.cs b/csharp/SVGLDLibs/SVGLDWebAPI/Program.cs new file mode 100644 index 0000000..55fb432 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDWebAPI/Program.cs @@ -0,0 +1,37 @@ +var builder = WebApplication.CreateBuilder(args); + +// Add services to the container. + +builder.Services.AddControllers(); + +const string allowOrigin = "allowOrigin"; +// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddCors(options => +{ + options.AddPolicy(name: allowOrigin, + policy => + { + policy.WithOrigins("http://localhost:3000"); + }); +}); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +var app = builder.Build(); + +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(); +} + +app.UseCors(allowOrigin); + +// app.UseHttpsRedirection(); + +app.UseAuthorization(); + +app.MapControllers(); + +app.Run(); \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDWebAPI/Properties/launchSettings.json b/csharp/SVGLDLibs/SVGLDWebAPI/Properties/launchSettings.json new file mode 100644 index 0000000..0afd7d1 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDWebAPI/Properties/launchSettings.json @@ -0,0 +1,31 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:2891", + "sslPort": 44305 + } + }, + "profiles": { + "SVGLDWebAPI": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7280;http://localhost:5209", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/csharp/SVGLDLibs/SVGLDWebAPI/README.md b/csharp/SVGLDLibs/SVGLDWebAPI/README.md new file mode 100644 index 0000000..cb2ccd1 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDWebAPI/README.md @@ -0,0 +1,15 @@ +# SVGLDWebAPI + +This project tests the serialization of C# models of SVGLayoutDesigner +by creating an entry point for each model. + +This project must be used in pair with the api.test.tsx from SVGLayoutDesigner nodejs project. + +api.test.tsx will serialize each of its models accordingly to its types +and POST to each corresponding entry point. + +When a test is succeeding `true` will be return. + +When a test is failing `400 Bad Request` will be returned. + +This project does not test any logic in the models. \ No newline at end of file diff --git a/csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj b/csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj new file mode 100644 index 0000000..f993247 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj @@ -0,0 +1,17 @@ + + + + net6.0 + enable + enable + + + + + + + + + + + diff --git a/csharp/SVGLDLibs/SVGLDWebAPI/appsettings.Development.json b/csharp/SVGLDLibs/SVGLDWebAPI/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDWebAPI/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/csharp/SVGLDLibs/SVGLDWebAPI/appsettings.json b/csharp/SVGLDLibs/SVGLDWebAPI/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/csharp/SVGLDLibs/SVGLDWebAPI/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/package.json b/package.json index 17f0840..a0902d7 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "test": "vitest", "test:ui": "vitest --ui", "test:nowatch": "vitest run", + "test:full": "(node ./test-server/http.js &) && (dotnet run --project=./csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj &) && sleep 3 && vitest ; pkill dotnet ; pkill node", + "test:full:nowatch": "(node ./test-server/http.js &) && (dotnet run --project=./csharp/SVGLDLibs/SVGLDWebAPI/SVGLDWebAPI.csproj &) && sleep 3 && vitest run ; pkill dotnet ; pkill node", "coverage": "vitest run coverage" }, "dependencies": { diff --git a/src/Components/API/api.test.tsx b/src/Components/API/api.test.tsx index 9c1f7e4..29ebd81 100644 --- a/src/Components/API/api.test.tsx +++ b/src/Components/API/api.test.tsx @@ -1,7 +1,27 @@ +/* eslint-disable @typescript-eslint/naming-convention */ import { describe, it, expect } from 'vitest'; +import { AddMethod } from '../../Enums/AddMethod'; +import { Orientation } from '../../Enums/Orientation'; +import { Position } from '../../Enums/Position'; +import { PositionReference } from '../../Enums/PositionReference'; +import { IAction } from '../../Interfaces/IAction'; +import { IAvailableContainer } from '../../Interfaces/IAvailableContainer'; +import { IAvailableSymbol } from '../../Interfaces/IAvailableSymbol'; +import { ICategory } from '../../Interfaces/ICategory'; +import { IConfiguration } from '../../Interfaces/IConfiguration'; +import { IContainerModel, ContainerModel } from '../../Interfaces/IContainerModel'; +import { IEditorState } from '../../Interfaces/IEditorState'; +import { IHistoryState } from '../../Interfaces/IHistoryState'; +import { IPattern } from '../../Interfaces/IPattern'; +import { DEFAULT_MAINCONTAINER_PROPS, GetDefaultContainerProps } from '../../utils/default'; import { FetchConfiguration } from './api'; -describe.concurrent('API test', () => { +const CSHARP_WEB_API_BASE_URL = 'http://localhost:5209/'; +const CHARP_WEB_API_RESOURCE_URL = 'SVGLD'; +const CSHARP_WEB_API_URL = CSHARP_WEB_API_BASE_URL + CHARP_WEB_API_RESOURCE_URL + '/'; + +// TODO: Migrate this test to SVGLDWebAPI rather than using test-server/ +describe.concurrent('Test server test', () => { it('Load environment', () => { const url = import.meta.env.VITE_API_FETCH_URL; expect(url).toBe('http://localhost:5000'); @@ -16,3 +36,258 @@ describe.concurrent('API test', () => { expect(configuration.AvailableSymbols.length).toBeGreaterThan(-1); }); }); + +async function Post2API(resource: string, body: string, method = 'POST'): Promise { + return await new Promise((resolve, reject) => { + const xhr = new XMLHttpRequest(); + xhr.open(method, CSHARP_WEB_API_URL + resource, true); + xhr.onreadystatechange = () => { // Call a function when the state changes. + if (xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) { + resolve(xhr.response === 'true'); + } + if (xhr.status === 400) { + reject(xhr); + } + }; + xhr.onerror = () => { + reject(xhr); + }; + xhr.setRequestHeader('Content-type', 'application/json'); + xhr.send(body); + }); +} + +/** + * Serialization tests for type compatibility of csharp classes + * See csharp/SVGLDWebAPI/README.md + */ +describe.concurrent('Models test suite', () => { + it('ActionContainerModel', async() => { + const model: IAction = { + Id: 'string', + CustomLogo: { + Name: 'string', + Url: 'string', + Base64Image: 'string', + Svg: 'string' + }, + Label: 'string', + Description: 'string', + Action: 'string', + AddingBehavior: 0 + }; + const res = await Post2API('ActionContainerModel', JSON.stringify(model)); + expect(res).toBe(true); + }); + + it('AddingBehaviorEnumModel', async() => { + let model: AddMethod = AddMethod.Append; + const res0 = await Post2API('AddingBehaviorEnumModel', JSON.stringify(model)); + model = AddMethod.Insert; + const res1 = await Post2API('AddingBehaviorEnumModel', JSON.stringify(model)); + model = AddMethod.Replace; + const res2 = await Post2API('AddingBehaviorEnumModel', JSON.stringify(model)); + model = AddMethod.ReplaceParent; + const res3 = await Post2API('AddingBehaviorEnumModel', JSON.stringify(model)); + model = 69; + const res4 = await Post2API('AddingBehaviorEnumModel', JSON.stringify(model)); + expect(res0).toBe(true); + expect(res1).toBe(true); + expect(res2).toBe(true); + expect(res3).toBe(true); + expect(res4).toBe(true); + }); + + const mainContainer = new ContainerModel( + null, + DEFAULT_MAINCONTAINER_PROPS + ); + + const historyState: IHistoryState = { + lastAction: 'string', + mainContainer, + selectedContainerId: '3', + typeCounters: { + main: 1 + }, + symbols: new Map(), + selectedSymbolId: '' + }; + + it('ApplicationStateModel', async() => { + const res = await Post2API('ApplicationStateModel', JSON.stringify(historyState)); + expect(res).toBe(true); + }); + + const availableContainerModel: IAvailableContainer = { + Type: 'string', + DisplayedText: 'string', + Category: 'string', + Orientation: 0, + X: 0, + Y: 0, + Width: 0, + Height: 0, + MinWidth: 0, + MaxWidth: 0, + MinHeight: 0, + MaxHeight: 0, + Margin: { + left: 0, + bottom: 0, + top: 0, + right: 0 + }, + IsAnchor: true, + IsFlex: true, + Pattern: 'string', + AddMethod: 0, + DefaultChildType: 'string', + PositionReference: 0, + HideChildrenInTreeview: true, + ShowSelfDimensions: [ + Position.Down, + Position.Left, + Position.Right, + Position.Up + ], + ShowChildrenDimensions: [ + Position.Down, + Position.Left, + Position.Right, + Position.Up + ], + MarkPosition: [ + Orientation.Horizontal, + Orientation.Vertical + ], + ShowDimensionWithMarks: [ + Position.Down, + Position.Left, + Position.Right, + Position.Up + ], + IsHidden: true, + Blacklist: [ + 'string' + ], + Whitelist: [ + 'string' + ], + Actions: [ + { + Id: 'string', + CustomLogo: { + Name: 'string', + Url: 'string', + Base64Image: 'string', + Svg: 'string' + }, + Label: 'string', + Description: 'string', + Action: 'string', + AddingBehavior: 0 + } + ], + CustomSVG: 'string', + Style: {}, + UserData: { + additionalProp1: 'string', + additionalProp2: 'string', + additionalProp3: 'string' + } + }; + + it('AvailableContainerModel', async() => { + const res = await Post2API('ApplicationStateModel', JSON.stringify(availableContainerModel)); + expect(res).toBe(true); + }); + + const availableSymbolModel: IAvailableSymbol = { + Name: 'string', + Image: { + Name: 'string', + Url: 'string', + Base64Image: 'string', + Svg: 'string' + }, + PositionReference: PositionReference.BottomCenter, + Width: 0, + Height: 0 + }; + + it('AvailableSymbolModel', async() => { + const res = await Post2API('AvailableSymbolModel', JSON.stringify(availableSymbolModel)); + expect(res).toBe(true); + }); + + const category: ICategory = { + Type: 'string', + DisplayedText: 'string' + }; + + it('Category', async() => { + const res = await Post2API('Category', JSON.stringify(category)); + expect(res).toBe(true); + }); + + const pattern: IPattern = { + children: ['string'], + id: 'string', + text: 'string', + wrapper: 'string' + }; + + it('ConfigurationResponseModel', async() => { + const model: IConfiguration = { + AvailableContainers: [ + availableContainerModel + ], + AvailableSymbols: [ + availableSymbolModel + ], + Categories: [ + category + ], + MainContainer: availableContainerModel, + Patterns: [pattern] + }; + + const res = await Post2API('ConfigurationResponseModel', JSON.stringify(model)); + expect(res).toBe(true); + }); + + const containerProperties = GetDefaultContainerProps( + 'container', + 0, + null, + 0, 0, 0, 0, availableContainerModel); + + it('ContainerModel', async() => { + const model: IContainerModel = { + children: [], + parent: null, + properties: containerProperties, + userData: {} + }; + const res = await Post2API('ContainerModel', JSON.stringify(model)); + expect(res).toBe(true); + }); + + it('ContainerProperties', async() => { + const res = await Post2API('ContainerModel', JSON.stringify(containerProperties)); + expect(res).toBe(true); + }); + + it('CSSStyle', async() => { + const model: React.CSSProperties = { + strokeWidth: '0', + fillOpacity: '0', + stroke: 'black', + fill: 'black' + }; + + const res = await Post2API('CSSStyle', JSON.stringify(model)); + expect(res).toBe(true); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 034ee0e..4b64a19 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ESNext", + "target": "ES2021", "useDefineForClassFields": true, "lib": ["DOM", "DOM.Iterable", "ESNext"], "allowJs": false,