├── .github
├── pull_request_template.md
└── workflows
│ ├── deploy-documentation.yml
│ └── php.yml
├── .gitignore
├── .phpcs.xml
├── ActionScripts
├── ActionZabbix
│ ├── ActionZabbix.json
│ ├── ActionZabbix.php
│ ├── composer.json
│ └── composer.lock
├── NotificationDiscord
│ ├── NotificationDiscord.json
│ ├── NotificationDiscord.php
│ ├── composer.json
│ └── composer.lock
├── NotificationMail
│ ├── NotificationMail.json
│ ├── NotificationMail.php
│ ├── README.md
│ ├── composer.json
│ ├── composer.lock
│ └── templates
│ │ ├── information.html
│ │ └── newItemITSM.html
└── autoload.php
├── LICENSE
├── Makefile
├── README.md
├── SPECS
├── ITIL4.md
└── specs.md
├── bin
└── cli
├── composer.json
├── composer.lock
├── config
└── current
│ └── .gitkeep
├── db
└── migrations
│ ├── 20200719120001_changes.php
│ ├── 20200719130001_menus.php
│ ├── 20200719140001_menuitems.php
│ ├── 20200719150001_menuitemcustoms.php
│ ├── 20200719160001_typepanels.php
│ ├── 20200719170001_typepanelitems.php
│ ├── 20200720091602_properties.php
│ ├── 20200720091613_types.php
│ ├── 20200720091620_property_type.php
│ ├── 20200720091657_propertylists.php
│ ├── 20200720091660_propertytypelinks.php
│ ├── 20200720091661_propertyitemlinks.php
│ ├── 20200720091683_propertyallowedtypes.php
│ ├── 20200720120829_items.php
│ ├── 20200720120838_itemstatus.php
│ ├── 20200720133434_item_property.php
│ ├── 20200725083703_relationshiptype.php
│ ├── 20200725083720_item_item.php
│ ├── 20200803061448_fusioninventory_item.php
│ ├── 20200803061453_fusioninventory_property.php
│ ├── 20200913080339_rules_creation.php
│ ├── 20220812125817_permissiondataproperty.php
│ ├── 20220812130039_permissiondata.php
│ ├── 20220812130052_permissionstructure.php
│ ├── 20220812130059_permissionstructurecustom.php
│ ├── 20220812130109_item_role.php
│ ├── 20220812130116_roles.php
│ ├── 20220903062128_fusioninventory_data_model.php
│ ├── 20220904071848_fill_userparams.php
│ ├── 20220905112557_fill_roles.php
│ └── 20220918075728_audit.php
├── devtools
├── README.md
├── _generateFileStructureTestSchemaRESTAPI.php
├── apidoc
│ ├── apidoc.json
│ ├── package.json
│ └── yarn.lock
├── generate_apidoc.sh
└── template
│ ├── fonts
│ ├── glyphicons-halflings-regular.eot
│ ├── glyphicons-halflings-regular.svg
│ ├── glyphicons-halflings-regular.ttf
│ ├── glyphicons-halflings-regular.woff
│ ├── glyphicons-halflings-regular.woff2
│ ├── oxygen-v15-latin-300.eot
│ ├── oxygen-v15-latin-300.svg
│ ├── oxygen-v15-latin-300.ttf
│ ├── oxygen-v15-latin-300.woff
│ ├── oxygen-v15-latin-300.woff2
│ ├── oxygen-v15-latin-700.eot
│ ├── oxygen-v15-latin-700.svg
│ ├── oxygen-v15-latin-700.ttf
│ ├── oxygen-v15-latin-700.woff
│ ├── oxygen-v15-latin-700.woff2
│ ├── oxygen-v15-latin-regular.eot
│ ├── oxygen-v15-latin-regular.svg
│ ├── oxygen-v15-latin-regular.ttf
│ ├── oxygen-v15-latin-regular.woff
│ ├── oxygen-v15-latin-regular.woff2
│ ├── roboto-v30-latin-300.eot
│ ├── roboto-v30-latin-300.svg
│ ├── roboto-v30-latin-300.ttf
│ ├── roboto-v30-latin-300.woff
│ ├── roboto-v30-latin-300.woff2
│ ├── roboto-v30-latin-500.eot
│ ├── roboto-v30-latin-500.svg
│ ├── roboto-v30-latin-500.ttf
│ ├── roboto-v30-latin-500.woff
│ ├── roboto-v30-latin-500.woff2
│ ├── roboto-v30-latin-700.eot
│ ├── roboto-v30-latin-700.svg
│ ├── roboto-v30-latin-700.ttf
│ ├── roboto-v30-latin-700.woff
│ ├── roboto-v30-latin-700.woff2
│ ├── roboto-v30-latin-regular.eot
│ ├── roboto-v30-latin-regular.svg
│ ├── roboto-v30-latin-regular.ttf
│ ├── roboto-v30-latin-regular.woff
│ ├── roboto-v30-latin-regular.woff2
│ ├── source-code-pro-v21-latin-300.eot
│ ├── source-code-pro-v21-latin-300.svg
│ ├── source-code-pro-v21-latin-300.ttf
│ ├── source-code-pro-v21-latin-300.woff
│ ├── source-code-pro-v21-latin-300.woff2
│ ├── source-code-pro-v21-latin-600.eot
│ ├── source-code-pro-v21-latin-600.svg
│ ├── source-code-pro-v21-latin-600.ttf
│ ├── source-code-pro-v21-latin-600.woff
│ ├── source-code-pro-v21-latin-600.woff2
│ ├── source-code-pro-v21-latin-700.eot
│ ├── source-code-pro-v21-latin-700.svg
│ ├── source-code-pro-v21-latin-700.ttf
│ ├── source-code-pro-v21-latin-700.woff
│ ├── source-code-pro-v21-latin-700.woff2
│ ├── source-code-pro-v21-latin-regular.eot
│ ├── source-code-pro-v21-latin-regular.svg
│ ├── source-code-pro-v21-latin-regular.ttf
│ ├── source-code-pro-v21-latin-regular.woff
│ └── source-code-pro-v21-latin-regular.woff2
│ ├── img
│ ├── android-chrome-192x192.png
│ ├── android-chrome-512x512.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ ├── favicon.ico
│ └── logo.png
│ ├── index.html
│ └── src
│ ├── css
│ └── main.css
│ ├── diff_match_patch.mjs
│ ├── hb_helpers.js
│ ├── jsonifier.mjs
│ ├── main.js
│ ├── sampreq_url_processor.mjs
│ ├── send_sample_request.js
│ └── webpack.config.js
├── docker
├── Dockerfile
├── bin
│ ├── cli
│ ├── composer
│ ├── mariadb
│ └── php
├── docker-compose.yml
├── install-composer.sh
└── nginx.conf
├── phpstan.neon
├── public
└── index.php
├── src
├── Route.php
├── config.php
├── constant.php
└── v1
│ ├── Common.php
│ ├── Controllers
│ ├── Cli
│ │ ├── Common.php
│ │ ├── EnvironmentCreate.php
│ │ ├── EnvironmentList.php
│ │ ├── EnvironmentSwitch.php
│ │ ├── Install.php
│ │ └── Reset.php
│ ├── Config
│ │ ├── Permissiondata.php
│ │ ├── Permissiondataproperty.php
│ │ ├── Permissionstructure.php
│ │ ├── Permissionstructurecustom.php
│ │ ├── Property.php
│ │ ├── Role.php
│ │ └── Type.php
│ ├── Display
│ │ ├── Menu
│ │ │ ├── Menu.php
│ │ │ ├── Menuitem.php
│ │ │ └── Menuitemcustom.php
│ │ └── Type
│ │ │ ├── Typepanel.php
│ │ │ └── Typepanelitem.php
│ ├── Fusioninventory.php
│ ├── Item.php
│ ├── Log
│ │ ├── Audit.php
│ │ └── Change.php
│ ├── Ping.php
│ ├── Rule.php
│ ├── Rules
│ │ ├── ActionScript.php
│ │ ├── GetType.php
│ │ └── SearchItem.php
│ ├── Status.php
│ ├── Token.php
│ └── User.php
│ ├── Models
│ ├── Common.php
│ ├── Config
│ │ ├── Permissiondata.php
│ │ ├── Permissiondataproperty.php
│ │ ├── Permissionstructure.php
│ │ ├── Permissionstructurecustom.php
│ │ ├── Property.php
│ │ ├── Propertyallowedtype.php
│ │ ├── Propertyitemlink.php
│ │ ├── Propertylist.php
│ │ ├── Propertytypelink.php
│ │ ├── Relationshiptype.php
│ │ ├── Role.php
│ │ └── Type.php
│ ├── Display
│ │ ├── Menu
│ │ │ ├── Menu.php
│ │ │ ├── Menuitem.php
│ │ │ └── Menuitemcustom.php
│ │ └── Type
│ │ │ ├── Typepanel.php
│ │ │ ├── Typepanelcustom.php
│ │ │ └── Typepanelitem.php
│ ├── Fusioninventoryitem.php
│ ├── Fusioninventoryproperty.php
│ ├── Item.php
│ ├── ItemProperty.php
│ ├── ItemState.php
│ ├── Log
│ │ ├── Audit.php
│ │ └── Change.php
│ ├── Rule.php
│ ├── Ruleaction.php
│ ├── Rulecriterium.php
│ └── Useraudit.php
│ ├── Permission.php
│ ├── Post.php
│ ├── Query.php
│ ├── Read.php
│ ├── Templates
│ ├── Incident_management.json
│ ├── Knowledge_management.json
│ ├── incident_contracts.json
│ └── tmp_computer.json
│ └── Validator
│ ├── Dateformat.php
│ ├── Datetimeformat.php
│ ├── Maxchars.php
│ ├── Minchars.php
│ ├── Timeformat.php
│ └── Type.php
└── tests
├── RESTAPI
├── .eslintrc.json
├── 00_status.js
├── 00_token.js
├── 01_type
│ ├── 0_type-GET.js
│ ├── 1_type-POST.js
│ ├── 2_type-id-PATCH.js
│ └── 3_type-id-DELETE.js
├── 02_items
│ ├── 0_create_type.js
│ ├── 1_type-items-POST.js
│ ├── 2_type-items-GET.js
│ ├── 3_item-id-PATCH.js
│ ├── 4_type-items-POST.js
│ ├── 6_items-PATCH-property.js
│ ├── 8_item-id-DELETE.js
│ └── 9_delete_types.js
├── 03_itemsHeaders
│ ├── 1_create_15_items.js
│ ├── 2_type-items-GET.js
│ └── 8_item-id-DELETE.js
├── 04_itemProperties
│ ├── boolean
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValueTrue.js
│ ├── common.js
│ ├── commonCreateItem.js
│ ├── date
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueCurrentdate.js
│ │ ├── 6_workingDefaultValueDate.js
│ │ └── 7_workingDefaultValueNull.js
│ ├── datetime
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueCurrentdatetime.js
│ │ ├── 6_workingDefaultValueDatetime.js
│ │ └── 7_workingDefaultValueNull.js
│ ├── decimal
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueDecimal.js
│ │ └── 6_workingDefaultValueNull.js
│ ├── integer
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueInteger.js
│ │ └── 6_workingDefaultValueNull.js
│ ├── itemlink
│ │ ├── 0_dataproviders.js
│ │ ├── 1_create_items.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueItemlink.js
│ │ ├── 6_workingDefaultValueNull.js
│ │ ├── 7_allowedtypes.js
│ │ └── 8_delete_items.js
│ ├── itemlinks
│ │ ├── 1_create_items.js
│ │ ├── 2_dataproviders.js
│ │ ├── 3_badDefaultValue.js
│ │ ├── 4_badValue.js
│ │ ├── 5_workingDefaultValueItemlinks.js
│ │ ├── 6_workingDefaultValueNull.js
│ │ ├── 7_allowedtypes.js
│ │ └── 8_delete_items.js
│ ├── list
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueList.js
│ │ ├── 6_workingDefaultValueNull.js
│ │ └── 7_add_delete_listvalues.js
│ ├── number
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValueNumber.js
│ ├── password
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValuePassword.js
│ ├── passwordhash
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValuePassword.js
│ ├── propertylink
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValuePropertylink.js
│ ├── string
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValueString.js
│ ├── text
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValueText.js
│ ├── time
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_workingDefaultValueCurrentime.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValueTime.js
│ ├── typelink
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValueTypelink.js
│ └── typelinks
│ │ ├── 1_dataproviders.js
│ │ ├── 2_badDefaultValue.js
│ │ ├── 3_badValue.js
│ │ ├── 4_canbenullNo.js
│ │ ├── 5_workingDefaultValueNull.js
│ │ └── 6_workingDefaultValueTypelinks.js
├── 05_itemsTree
│ ├── 1_createType.js
│ ├── 2_createRootItem.js
│ ├── 3_createSub1Item.js
│ ├── 4_createItemInErrors.js
│ ├── 5_deleteSub1Item.js
│ ├── 6_deleteRootItem.js
│ └── 7_deleteType.js
├── 06_itemsTreeMultipleRoots
│ ├── 1_createType.js
│ ├── 2_createRootItem.js
│ ├── 3_createSub1Item.js
│ ├── 4_createSecondRootItem.js
│ ├── 5_createItemInErrors.js
│ ├── 6_deleteSub1Item.js
│ ├── 7_deleteRootItem.js
│ └── 8_deleteType.js
├── 07_protectedSystem
│ ├── 1_type-delete-error-system.js
│ ├── 2_property-delete-error-system.js
│ └── 3_item-delete-error-system.js
├── 08_roles
│ ├── 1_none
│ │ ├── 1_create-role.js
│ │ ├── 2_attach-role-user.js
│ │ ├── 3_connect-user-check-permissions.js
│ │ └── 8_delete-role.js
│ ├── 2_grant
│ │ ├── 1_create-role.js
│ │ ├── 2_attach-role-user.js
│ │ ├── 3_connect-user-check-permissions.js
│ │ ├── 7_delete-laptop.js
│ │ └── 8_delete-role.js
│ └── 3_custom
│ │ ├── data
│ │ ├── 01_create-role.js
│ │ ├── 02_attach-role-user.js
│ │ ├── 03_laptop-create.js
│ │ ├── 04_laptop-update.js
│ │ ├── 05_laptop-view.js
│ │ ├── 06_laptop-softdelete.js
│ │ ├── 07_laptop-delete.js
│ │ ├── 30_delete-laptop.js
│ │ └── 31_delete-role.js
│ │ ├── data_property
│ │ ├── 01_create-role.js
│ │ ├── 02_attach-role-user.js
│ │ ├── 03_laptop-create.js
│ │ ├── 04_laptop-view-property.js
│ │ ├── 05_laptop-update-property.js
│ │ ├── 30_delete-laptop.js
│ │ └── 31_delete-role.js
│ │ ├── structure
│ │ ├── property
│ │ │ ├── 01_create-role.js
│ │ │ ├── 02_attach-role-user.js
│ │ │ ├── 03_get_properties.js
│ │ │ ├── 04_create_properties.js
│ │ │ ├── 05_update_properties.js
│ │ │ ├── 06_softdelete_properties.js
│ │ │ ├── 07_delete_properties.js
│ │ │ └── 31_delete-role.js
│ │ ├── role
│ │ │ ├── 01_create-role.js
│ │ │ ├── 02_attach-role-user.js
│ │ │ ├── 03_get_roles.js
│ │ │ ├── 04_create_role.js
│ │ │ ├── 05_update_roles.js
│ │ │ ├── 06_softdelete_roles.js
│ │ │ ├── 07_delete_roles.js
│ │ │ └── 31_delete-role.js
│ │ └── type
│ │ │ ├── 01_create-role.js
│ │ │ ├── 02_attach-role-user.js
│ │ │ ├── 03_get_types.js
│ │ │ ├── 04_create_type.js
│ │ │ ├── 05_update_types.js
│ │ │ ├── 06_softdelete_types.js
│ │ │ ├── 07_delete_types.js
│ │ │ └── 31_delete-role.js
│ │ └── structure_custom
│ │ ├── property
│ │ ├── 01_create-role.js
│ │ ├── 02_attach-role-user.js
│ │ ├── 03_create_property.js
│ │ ├── 04_get_properties.js
│ │ ├── 05_update_properties.js
│ │ ├── 06_softdelete_properties.js
│ │ ├── 07_delete_properties.js
│ │ └── 31_delete-role.js
│ │ ├── role
│ │ ├── 01_create-role.js
│ │ ├── 02_attach-role-user.js
│ │ ├── 03_create_role.js
│ │ ├── 04_get_roles.js
│ │ ├── 05_update_roles.js
│ │ ├── 06_softdelete_roles.js
│ │ ├── 07_delete_roles.js
│ │ └── 31_delete-role.js
│ │ └── type
│ │ ├── 01_create-role.js
│ │ ├── 02_attach-role-user.js
│ │ ├── 03_create_type.js
│ │ ├── 04_get_types.js
│ │ ├── 05_update_types.js
│ │ ├── 06_softdelete_types.js
│ │ ├── 07_delete_types.js
│ │ └── 31_delete-role.js
├── 09_organizations
│ ├── items
│ │ ├── 00_createType.js
│ │ ├── 01_create-organization-POST.js
│ │ ├── 02_create-users-POST.js
│ │ ├── 03_token-users.js
│ │ ├── 04_create-items-POST.js
│ │ ├── 05_get_all_items_rootorg.js
│ │ ├── 06_get_all_items_sub1org.js
│ │ ├── 07_get_all_items_sub2org.js
│ │ ├── 08_get_each_items_ok_notok.js
│ │ ├── 09_items-DELETE.js
│ │ ├── 10_delete-types.js
│ │ ├── 11_delete-users.js
│ │ └── 12_delete-organizations.js
│ ├── properties
│ │ ├── 01_create-organization-POST.js
│ │ ├── 02_create-users-POST.js
│ │ ├── 03_token-users.js
│ │ ├── 04_create-properties-POST.js
│ │ ├── 05_create-types-POST.js
│ │ ├── 06_attach_properties_to_type1_byadmin.js
│ │ ├── 07_attach_properties_to_typesub1_byadmin.js
│ │ ├── 08_attach_properties_to_type2_byadmin.js
│ │ ├── 09_detach_properties_to_type2_byadmin.js
│ │ ├── 10_attach_properties_to_type1_byuser1.js
│ │ ├── 11_attach_properties_to_type2_byuser1.js
│ │ ├── 12_detach_properties_to_type2_byadmin.js
│ │ ├── 13_attach_properties_to_type1_byuser1.js
│ │ ├── 14_attach_properties_to_type2_byuser1.js
│ │ ├── 30_delete-types.js
│ │ ├── 31_properties-DELETE.js
│ │ ├── 32_delete-users.js
│ │ └── 33_delete-organizations.js
│ └── types
│ │ ├── 01_create-organization-POST.js
│ │ ├── 02_create-users-POST.js
│ │ ├── 03_token-users.js
│ │ ├── 04_create-types-POST.js
│ │ ├── 05_get_all_types_user_admin.js
│ │ ├── 06_get_all_types_user_user1.js
│ │ ├── 07_get_all_types_user_user2.js
│ │ ├── 21_types-DELETE.js
│ │ ├── 22_delete-users.js
│ │ └── 23_delete-organizations.js
├── 10_usereventTimestamp
│ ├── 01_create-users-POST.js
│ ├── 02_token-users.js
│ ├── 03_create-property.js
│ ├── 04_create-type.js
│ ├── 05_create-item.js
│ ├── 06_update-property.js
│ ├── 07_update-type.js
│ ├── 08_update-item.js
│ ├── 09_softdelete-property.js
│ ├── 10_softdelete-item.js
│ ├── 11_softdelete-type.js
│ ├── 12_restore-property.js
│ ├── 13_restore-type.js
│ ├── 14_restore-item.js
│ ├── 15_attach-property-to-type.js
│ ├── 16_update-property-value-of-item.js
│ ├── 31_delete-users.js
│ ├── 32_check-item.js
│ ├── 33_check-type.js
│ ├── 34_check-property.js
│ ├── 35_delete-item.js
│ ├── 36_delete-type.js
│ ├── 37_delete-property.js
│ └── README.md
├── 15_userparams
│ └── 0_type-GET.js
├── 16_actionscripts
│ ├── actionZabbix
│ │ ├── 1_configutationRule.js
│ │ ├── 2_createItem.js
│ │ └── 2_deleteRule.js
│ └── notificationMail
│ │ ├── 1_configutationRule.js
│ │ ├── 2_createItem.js
│ │ └── 2_deleteRule.js
├── 17_logAudit
│ ├── 1_connection.js
│ ├── 2_property.js
│ ├── 3_type.js
│ └── 4_item.js
├── 18_items_unique_name
│ ├── with_unique_name.js
│ └── without_unique_name.js
├── 19_refreshToken
│ ├── 01_create-users-POST.js
│ ├── 02_token-users.js
│ └── 05_delete-users.js
├── 20_getToken
│ ├── 01_create-users-POST.js
│ ├── 02_token-users.js
│ └── 05_delete-users.js
├── 21_itemPropertyWhenAddDeletePropertyToType
│ ├── 1_createType.js
│ ├── 2_createItem.js
│ ├── 3_addNewPropertyToType.js
│ ├── 4_deletePropertyToType.js
│ ├── 5_addNewPropertyToTypeByTemplate.js
│ ├── 6_deleteItem.js
│ └── 7_deleteType.js
├── 22_changeslogs
│ ├── 1_properties
│ │ ├── 1_create_property.js
│ │ ├── 2_getall_properties.js
│ │ ├── 3_update_property.js
│ │ ├── 4_softdelete_property.js
│ │ └── 9_delete_property.js
│ ├── 2_type
│ │ ├── 1_create_type.js
│ │ ├── 2_getall_types.js
│ │ ├── 3_update_type.js
│ │ ├── 4_softdelete_property.js
│ │ └── 9_delete_type.js
│ └── 3_item
│ │ ├── 01_prepare_type.js
│ │ ├── 02_create_item.js
│ │ ├── 03_getall_item.js
│ │ ├── 04_update_item.js
│ │ ├── 05_softdelete_item.js
│ │ ├── 10_update_item_property_boolean.js
│ │ ├── 11_update_item_property_date.js
│ │ ├── 12_update_item_property_datetime.js
│ │ ├── 13_update_item_property_decimal.js
│ │ ├── 14_update_item_property_integer.js
│ │ ├── 15_update_item_property_itemlink.js
│ │ ├── 16_update_item_property_itemlinks.js
│ │ ├── 17_update_item_property_list.js
│ │ ├── 18_update_item_property_number.js
│ │ ├── 19_update_item_property_propertylink.js
│ │ ├── 20_update_item_property_string.js
│ │ ├── 21_update_item_property_text.js
│ │ ├── 22_update_item_property_time.js
│ │ ├── 23_update_item_property_typelink.js
│ │ ├── 24_update_item_property_typelinks.js
│ │ ├── 51_delete_item.js
│ │ └── 52_delete_type_properties.js
├── 23_display
│ ├── 1_menus
│ │ ├── 1_menu-POST.js
│ │ ├── 2_menu-GET.js
│ │ ├── 3_menu-id-PATCH.js
│ │ ├── 4_menu-id-DELETE.js
│ │ └── 5_menu-positions.js
│ ├── 2_menuitems
│ │ ├── 0_dataproviders.js
│ │ ├── 1_menuitem-POST.js
│ │ ├── 2_menuitem-GET.js
│ │ ├── 3_menuitem-DELETE-type.js
│ │ ├── 4_menuitem-id-PATCH.js
│ │ ├── 5_menuitem-id-DELETE.js
│ │ └── 6_menuitem-positions.js
│ ├── 3_menuitemcustoms
│ │ ├── 1_prepare-POST.js
│ │ ├── 2_menuitemcustom-POST.js
│ │ ├── 3_menuitemcustom-GET.js
│ │ ├── 5_menuitemcustom-DELETE.js
│ │ └── 9_finish.js
│ ├── 4_typepanel
│ │ ├── 1_type-autoadd.js
│ │ ├── 2_type-add-panel.js
│ │ ├── 3_type-transfert-properties.js
│ │ ├── 4_special-case-default-panel.js
│ │ ├── 5_special-case-icons.js
│ │ └── 9_finish.js
│ └── 5_typepanelitem
│ │ ├── 1_type-autoadd.js
│ │ ├── 2_GET-panelitems.js
│ │ ├── 3_PATCH-panelitems.js
│ │ └── 9_finish.js
├── 25_itemSearch
│ ├── 000_dataproviders.js
│ ├── 001_prepare-type.js
│ ├── 002_prepare-add-data.js
│ ├── 003_search-name.js
│ ├── 004_search-prop-boolean.js
│ ├── 005_search-prop-date.js
│ ├── 006_search-prop-datetime.js
│ ├── 007_search-prop-decimal.js
│ ├── 008_search-prop-integer.js
│ ├── 009_search-prop-itemlink.js
│ ├── 010_search-prop-itemlinks.js
│ ├── 011_search-prop-list.js
│ ├── 012_search-prop-number.js
│ ├── 013_search-prop-propertylink.js
│ ├── 014_search-prop-string.js
│ ├── 015_search-prop-text.js
│ ├── 016_search-prop-time.js
│ ├── 017_search-prop-typelink.js
│ ├── 018_search-prop-typelinks.js
│ ├── 103_search-name-notok.js
│ ├── 104_search-prop-boolean-notok.js
│ ├── 105_search-prop-date-notok.js
│ ├── 106_search-prop-datetime-notok.js
│ ├── 107_search-prop-decimal-notok.js
│ ├── 108_search-prop-integer-notok.js
│ ├── 109_search-prop-itemlink-notok.js
│ ├── 110_search-prop-itemlinks-notok.js
│ ├── 111_search-prop-list-notok.js
│ ├── 112_search-prop-number-notok.js
│ ├── 113_search-prop-propertylink-notok.js
│ ├── 114_search-prop-string.js
│ ├── 115_search-prop-text.js
│ ├── 116_search-prop-time-notok.js
│ ├── 117_search-prop-typelink-notok.js
│ ├── 118_search-prop-typelinks-notok.js
│ └── 999_clean-data.js
├── 26_items_users_properties_hidden
│ ├── 1_type-items-POST.js
│ ├── 2_type-items-GET.js
│ ├── 3_item-id-PATCH.js
│ └── 8_item-id-DELETE.js
├── 27_passwordUserLogin
│ ├── 01_create-users-with-passwordPOST.js
│ ├── 02_token-users.js
│ ├── 03_update_password_to_default.js
│ ├── 04_update_password.js
│ └── 05_delete-users.js
├── README.md
├── fusionsuite.conf
├── mountebank
│ ├── imposters.ejs
│ └── imposters
│ │ ├── smtp.ejs
│ │ └── zabbix.ejs
├── package.json
├── schemaValidation
│ ├── .old
│ ├── commonSchema.js
│ ├── ping
│ │ └── get
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ └── v1
│ │ ├── items
│ │ ├── post
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ ├── type
│ │ │ └── {typeid}
│ │ │ │ └── get
│ │ │ │ ├── schema.json
│ │ │ │ └── schema.json.old
│ │ └── {id}
│ │ │ ├── delete
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ │ ├── get
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ │ ├── patch
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ │ └── property
│ │ │ └── {propertyid}
│ │ │ ├── patch
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ │ └── typelinks
│ │ │ ├── post
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ │ └── {typelinkid}
│ │ │ └── delete
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ ├── rules
│ │ ├── {id}
│ │ │ └── delete
│ │ │ │ ├── schema.json
│ │ │ │ └── schema.json.old
│ │ └── {type}
│ │ │ ├── get
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ │ ├── post
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ │ └── {id}
│ │ │ ├── action
│ │ │ └── post
│ │ │ │ ├── schema.json
│ │ │ │ └── schema.json.old
│ │ │ ├── criteria
│ │ │ └── post
│ │ │ │ ├── schema.json
│ │ │ │ └── schema.json.old
│ │ │ └── get
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ ├── status
│ │ └── get
│ │ │ ├── schema.json
│ │ │ ├── schema.json.old
│ │ │ └── test.js
│ │ ├── token
│ │ └── post
│ │ │ ├── schema.json
│ │ │ └── schema.json.old
│ │ └── userparams
│ │ └── get
│ │ ├── schema.json
│ │ └── schema.json.old
├── testDatabaseAccess.php
├── yarn-error.log
└── yarn.lock
├── performances
├── README.md
├── itemsUniqueId.js
└── test.js
└── units
└── v1
└── Controllers
└── Cli
├── EnvironmentCreateTest.php
└── EnvironmentSwitchTest.php
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Changes proposed in this pull request:
2 |
3 | -
4 | -
5 | -
6 |
7 | How to test the feature manually:
8 |
9 | 1.
10 | 2.
11 | 3.
12 |
13 | Pull request checklist:
14 |
15 | - [ ] code is manually tested
16 | - [ ] tests are updated
17 | - [ ] commit messages are relevant
18 | - [ ] documentation is updated (including code comments, commit messages…)
19 |
20 | _If you think one of the item isn’t applicable to the PR, please check it
21 | anyway and precise `N/A` next to it._
22 |
23 | Related to #
24 |
--------------------------------------------------------------------------------
/.github/workflows/deploy-documentation.yml:
--------------------------------------------------------------------------------
1 | on:
2 | push:
3 | branches:
4 | - master
5 |
6 | env:
7 | NODE_VERSION: '16.x'
8 |
9 | jobs:
10 | buildAndDeploy:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 |
15 | - name: Set up Node.js
16 | uses: actions/setup-node@v2
17 | with:
18 | node-version: ${{ env.NODE_VERSION }}
19 | cache: 'yarn'
20 | cache-dependency-path: devtools/apidoc/yarn.lock
21 |
22 | - name: yarn install
23 | run: |
24 | cd devtools/apidoc/
25 | yarn install
26 |
27 | - name: generate the documentation
28 | run: |
29 | cd devtools/
30 | ./generate_apidoc.sh
31 |
32 | - name: Deploy with rsync
33 | uses: "Pendect/action-rsyncer@v1.1.0"
34 | env:
35 | DEPLOY_KEY: ${{ secrets.SSH_DOCUMENTATION_KEY }}
36 | with:
37 | flags: '-avzr --delete'
38 | options: ''
39 | ssh_options: ''
40 | src: 'documentation/'
41 | dest: '${{ secrets.SSH_DOCUMENTATION_USER }}@${{ secrets.SSH_HOST }}:${{ secrets.DOCUMENTATION_RESTAPI_PATH }}'
42 |
43 | - name: Display status from deploy
44 | run: echo "${{ steps.deploy.outputs.status }}"
45 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | **/vendor
3 | /documentation
4 | /devtools/apidoc/node_modules
5 | /tests/RESTAPI/node_modules
6 | tests/RESTAPI/mb*
7 | config
8 | devtools/apidoc/logfile.log
9 |
--------------------------------------------------------------------------------
/.phpcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | ActionScripts/*/vendor/*
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/ActionScripts/ActionZabbix/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "minimum-stability": "dev",
3 | "require": {
4 | "intellitrend/zabbixapi": "dev-master"
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/ActionScripts/NotificationDiscord/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "woeler/phpdiscord": "4.*"
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/ActionScripts/NotificationMail/README.md:
--------------------------------------------------------------------------------
1 | # Creation steps for templates
2 | For create template:
3 |
4 | 1/ use https://mosaico.io
5 | 2/ update code to use mustache variables: http://mustache.github.io/#demo
6 |
7 | # Useful links
8 |
9 | https://github.com/tijsverkoyen/CssToInlineStyles
10 | https://www.lafabriquedunet.fr/email-marketing/guide/coder-email-html-css/
11 | https://stackoverflow.com/questions/2229822/best-practices-considerations-when-writing-html-emails
12 | https://www.codeur.com/blog/email-builder-gratuit-sans-coder/
13 |
--------------------------------------------------------------------------------
/ActionScripts/NotificationMail/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "require": {
3 | "phpmailer/phpmailer": "6.*",
4 | "mustache/mustache": "2.14.*",
5 | "html2text/html2text": "^4.3"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/ActionScripts/NotificationMail/templates/newItemITSM.html:
--------------------------------------------------------------------------------
1 |
{{title}}
2 |
3 | Welcome {{firstname}}
4 |
--------------------------------------------------------------------------------
/ActionScripts/autoload.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | $baseFolder = __DIR__;
22 | $folders = scandir($baseFolder);
23 | foreach ($folders as $folder)
24 | {
25 | if ($folder == '.' || $folder == '..')
26 | {
27 | continue;
28 | }
29 | if (is_dir(__DIR__ . '/' . $folder))
30 | {
31 | require_once __DIR__ . '/' . $folder . '/vendor/autoload.php';
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FusionSuite::Backend
2 |
3 | ## Introduction
4 |
5 | It's the backend for the IT Service Management.
6 |
7 | It will offer REST API of data.
8 |
9 |
10 | ## Technologies
11 |
12 | It's written in PHP and use:
13 |
14 | * slim (microframework)
15 | * eloquent (database queries)
16 | * phinx (database migrations)
17 |
18 | ## Install
19 |
20 | Here are the steps to install the backend:
21 |
22 | * install dependencies `composer install`
23 | * configure into phinx.php the database information
24 | * run command `./vendor/bin/phinx migrate`
25 |
26 |
27 |
--------------------------------------------------------------------------------
/bin/cli:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | .
19 | */
20 |
21 | require __DIR__ . '/../vendor/autoload.php';
22 |
23 | use App\v1\Controllers\Cli\Common;
24 | use Ahc\Cli\Output\Cursor;
25 |
26 | $cursor = new Cursor;
27 | echo $cursor->clear();
28 |
29 | $cliCommon = new Common;
30 | $cliCommon->displayLogo();
31 |
32 | $version = '1.0.0';
33 | $app = new Ahc\Cli\Application('cli', $version);
34 |
35 | $app->add(new \App\v1\Controllers\Cli\EnvironmentCreate);
36 | $app->add(new \App\v1\Controllers\Cli\EnvironmentList);
37 | $app->add(new \App\v1\Controllers\Cli\EnvironmentSwitch);
38 | $app->add(new \App\v1\Controllers\Cli\Install);
39 | $app->add(new \App\v1\Controllers\Cli\Reset);
40 |
41 | $app->handle($_SERVER['argv']);
42 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fusionsuite/backend",
3 | "description": "It's the backend part of FusionSuite project",
4 | "type": "project",
5 | "homepage": "https://fusionsuite.org/",
6 | "license": [
7 | "AGPL-3.0-or-later"
8 | ],
9 | "require": {
10 | "php": "^8.1|^8.2|^8.3",
11 | "slim/slim": "4.*",
12 | "slim/psr7": "1.*",
13 | "robmorgan/phinx": "0.15.*",
14 | "illuminate/database": "10.*",
15 | "tuupola/slim-jwt-auth": "3.*",
16 | "tuupola/base62": "2.*",
17 | "spatie/array-to-xml": "3.2.*",
18 | "hoa/ruler": "^2.17.05.16",
19 | "illuminate/events": "10.*",
20 | "rakit/validation": "^1.4",
21 | "adhocore/cli": "1.6.*",
22 | "genealabs/laravel-pivot-events": "10.*",
23 | "symfony/error-handler": "6.*"
24 | },
25 | "autoload": {
26 | "psr-4": {
27 | "App\\": "src",
28 | "ActionScripts\\": "ActionScripts"
29 | }
30 | },
31 | "require-dev": {
32 | "phpstan/phpstan": "1.*",
33 | "squizlabs/php_codesniffer": "3.*",
34 | "phpunit/phpunit": "10.*",
35 | "bmitch/churn-php": "^1.7"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/config/current/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/config/current/.gitkeep
--------------------------------------------------------------------------------
/db/migrations/20200720120838_itemstatus.php:
--------------------------------------------------------------------------------
1 | .
18 | */
19 | declare(strict_types=1);
20 |
21 | use Phinx\Migration\AbstractMigration;
22 |
23 | final class Itemstatus extends AbstractMigration
24 | {
25 | /**
26 | * Change Method.
27 | *
28 | * Write your reversible migrations using this method.
29 | *
30 | * More information on writing migrations is available here:
31 | * https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
32 | *
33 | * Remember to call "create()" or "update()" and NOT "save()" when working
34 | * with the Table class.
35 | */
36 | public function change(): void
37 | {
38 | // create the table
39 | $table = $this->table('itemstates');
40 | $table->addColumn('name', 'string')
41 | ->addColumn('created_at', 'datetime')
42 | ->addColumn('updated_at', 'datetime', ['null' => true])
43 | ->addColumn('deleted_at', 'datetime', ['null' => true])
44 | ->create();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/db/migrations/20200725083703_relationshiptype.php:
--------------------------------------------------------------------------------
1 | .
18 | */
19 | declare(strict_types=1);
20 |
21 | use Phinx\Migration\AbstractMigration;
22 |
23 | final class Relationshiptype extends AbstractMigration
24 | {
25 | /**
26 | * Change Method.
27 | *
28 | * Write your reversible migrations using this method.
29 | *
30 | * More information on writing migrations is available here:
31 | * https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
32 | *
33 | * Remember to call "create()" or "update()" and NOT "save()" when working
34 | * with the Table class.
35 | */
36 | public function change(): void
37 | {
38 | // create the table
39 | $table = $this->table('relationshiptypes');
40 | $table->addColumn('name', 'string')
41 | ->addColumn('created_at', 'datetime')
42 | ->addColumn('updated_at', 'datetime', ['null' => true])
43 | ->addColumn('deleted_at', 'datetime', ['null' => true])
44 | ->create();
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/db/migrations/20220905112557_fill_roles.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | declare(strict_types=1);
22 |
23 | use Phinx\Migration\AbstractMigration;
24 |
25 | final class FillRoles extends AbstractMigration
26 | {
27 | /**
28 | * Change Method.
29 | *
30 | * Write your reversible migrations using this method.
31 | *
32 | * More information on writing migrations is available here:
33 | * https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
34 | *
35 | * Remember to call "create()" or "update()" and NOT "save()" when working
36 | * with the Table class.
37 | */
38 | public function change(): void
39 | {
40 | // ***** Create admin role ***** //
41 | $role = new \App\v1\Models\Config\Role();
42 | $role->name = 'admin';
43 | $role->permissionstructure = 'grant';
44 | $role->permissiondata = 'grant';
45 | $role->save();
46 |
47 | // Attach the default user to the admin role
48 | $role->users()->attach($GLOBALS['user_id']);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/devtools/README.md:
--------------------------------------------------------------------------------
1 | # Template apidoc
2 |
3 | The template is based on the works of https://github.com/ahmed-dinar/apidoc-template
4 |
5 |
6 |
--------------------------------------------------------------------------------
/devtools/apidoc/apidoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "REST API FusionSuite backend documentation",
3 | "version": "1.0.0-draft",
4 | "description": "The documentation of REST API (backend FusionSuite)",
5 | "title": "REST API FusionSuite backend documentation",
6 | "order": [
7 | "Ping",
8 | "Status",
9 | "Authentication",
10 | "GetConfigProperties",
11 | "GetConfigProperty",
12 | "PostConfigProperties",
13 | "PatchConfigProperties",
14 | "GetConfigPropertygroups",
15 | "GetConfigTypes",
16 | "GetConfigType",
17 | "PostConfigTypes",
18 | "PatchConfigTypes",
19 | "DeletConfigTypes",
20 | "PostConfigTypesProperty",
21 | "DeleteConfigTypesProperty",
22 | "PostConfigTypesTemplate"
23 | ]
24 | }
25 |
--------------------------------------------------------------------------------
/devtools/apidoc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "apidoc": "0.51.1",
4 | "apidoc-swagger-3": "^1.0.6",
5 | "apidoc-swagger-converter": "^1.0.9",
6 | "esbuild-loader": "^2.19.0",
7 | "install": "^0.13.0",
8 | "webpack": "^5.66.0"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/devtools/generate_apidoc.sh:
--------------------------------------------------------------------------------
1 | # Compile by default
2 | rm -fr ../documentation/*
3 | rm ../tests/RESTAPI/schemaValidation/swagger.json
4 | cd apidoc
5 | ./node_modules/.bin/apidoc -i ../../src -o ../../documentation/ -c apidoc.json
6 | # Compile second time with own template (needed because some files not generated only with own like 'main.bundle.js' file
7 | ./node_modules/.bin/apidoc -i ../../src -o ../../documentation/ -c apidoc.json -t ../template/
8 | # Generate schema json for schema tests from apidoc
9 | ./node_modules/.bin/apidoc-swagger-3 -i ../../src/ -o ../../tests/RESTAPI/schemaValidation/
10 | cd ..
11 | php _generateFileStructureTestSchemaRESTAPI.php
12 |
--------------------------------------------------------------------------------
/devtools/template/fonts/glyphicons-halflings-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/glyphicons-halflings-regular.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/glyphicons-halflings-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/glyphicons-halflings-regular.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/glyphicons-halflings-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/glyphicons-halflings-regular.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/glyphicons-halflings-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/glyphicons-halflings-regular.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-300.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-300.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-300.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-300.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-300.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-300.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-300.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-300.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-700.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-700.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-700.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-700.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-700.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-700.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-700.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-regular.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-regular.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-regular.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/oxygen-v15-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/oxygen-v15-latin-regular.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-300.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-300.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-300.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-300.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-300.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-300.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-300.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-300.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-500.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-500.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-500.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-500.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-500.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-500.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-500.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-500.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-700.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-700.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-700.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-700.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-700.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-700.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-700.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-regular.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-regular.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-regular.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/roboto-v30-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/roboto-v30-latin-regular.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-300.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-300.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-300.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-300.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-300.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-300.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-300.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-300.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-600.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-600.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-600.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-600.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-600.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-600.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-600.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-600.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-700.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-700.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-700.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-700.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-700.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-700.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-700.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-700.woff2
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-regular.eot
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-regular.ttf
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-regular.woff
--------------------------------------------------------------------------------
/devtools/template/fonts/source-code-pro-v21-latin-regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/fonts/source-code-pro-v21-latin-regular.woff2
--------------------------------------------------------------------------------
/devtools/template/img/android-chrome-192x192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/img/android-chrome-192x192.png
--------------------------------------------------------------------------------
/devtools/template/img/android-chrome-512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/img/android-chrome-512x512.png
--------------------------------------------------------------------------------
/devtools/template/img/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/img/apple-touch-icon.png
--------------------------------------------------------------------------------
/devtools/template/img/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/img/favicon-16x16.png
--------------------------------------------------------------------------------
/devtools/template/img/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/img/favicon-32x32.png
--------------------------------------------------------------------------------
/devtools/template/img/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/img/favicon.ico
--------------------------------------------------------------------------------
/devtools/template/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/fusionSuite/backend/10729781f13210eaf424781d6d90e1bae02704b3/devtools/template/img/logo.png
--------------------------------------------------------------------------------
/devtools/template/src/diff_match_patch.mjs:
--------------------------------------------------------------------------------
1 | import _DiffMatchPatch from 'diff-match-patch';
2 |
3 | export default class DiffMatchPatch extends _DiffMatchPatch {
4 | constructor (testMode) {
5 | super();
6 | this.testMode = testMode;
7 | }
8 |
9 | diffMain (text1, text2, optChecklines, optDeadline) {
10 | return super.diff_main(this._stripHtml(text1), this._stripHtml(text2), optChecklines, optDeadline);
11 | }
12 |
13 | diffPrettyHtml (diffs) {
14 | const html = [];
15 | const patternAmp = /&/g;
16 | const patternLt = //g;
18 | const patternPara = /\n/g;
19 | for (let x = 0; x < diffs.length; x++) {
20 | const op = diffs[x][0]; // Operation (insert, delete, equal)
21 | const data = diffs[x][1]; // Text of change.
22 | const text = data.replace(patternAmp, '&').replace(patternLt, '<')
23 | .replace(patternGt, '>').replace(patternPara, '¶
');
24 | switch (op) {
25 | case _DiffMatchPatch.DIFF_INSERT:
26 | html[x] = '' + text + '';
27 | break;
28 | case _DiffMatchPatch.DIFF_DELETE:
29 | html[x] = '' + text + '';
30 | break;
31 | case _DiffMatchPatch.DIFF_EQUAL:
32 | html[x] = '' + text + '';
33 | break;
34 | }
35 | }
36 | return html.join('');
37 | }
38 |
39 | diffCleanupSemantic (diffs) {
40 | return this.diff_cleanupSemantic(diffs);
41 | }
42 |
43 | _stripHtml (html) {
44 | // no document object with CLI when running tests
45 | if (this.testMode) { return html; }
46 | const div = document.createElement('div');
47 | div.innerHTML = html;
48 | return div.textContent || div.innerText || '';
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/devtools/template/src/jsonifier.mjs:
--------------------------------------------------------------------------------
1 | /*
2 | * apidoc
3 | * https://apidocjs.com
4 | *
5 | * Authors:
6 | * Peter Rottmann
7 | * Nicolas CARPi @ Deltablot
8 | * Copyright (c) 2013 inveris OHG
9 | * Licensed under the MIT license.
10 | */
11 | import pkg from 'lodash';
12 | const { defaultsDeep } = pkg;
13 |
14 | const setValueToField = (fields, value) => {
15 | const reducer = (acc, item, index, arr) => ({ [item]: index + 1 < arr.length ? acc : value });
16 | return fields.reduceRight(reducer, {});
17 | };
18 |
19 | const fieldsToJson = fields => {
20 | let obj = {};
21 | fields.forEach(field => {
22 | const line = setValueToField(field[0].split('.'), field[1]);
23 | obj = defaultsDeep(obj, line);
24 | });
25 | return beautify(obj);
26 | };
27 |
28 | /**
29 | * Stringify an obj to JSON with spaces
30 | */
31 | export function beautify (obj) {
32 | return JSON.stringify(obj, null, 4);
33 | }
34 |
35 | export function body2json (context) {
36 | // build an array of fields with their type
37 | const fields = [];
38 | context.forEach(entry => {
39 | let val;
40 | switch (entry.type.toLowerCase()) {
41 | case 'string':
42 | val = entry.defaultValue || '';
43 | break;
44 | case 'boolean':
45 | val = Boolean(entry.defaultValue) || false;
46 | break;
47 | case 'number':
48 | val = parseInt(entry.defaultValue || 0, 10);
49 | break;
50 | case 'date':
51 | // date field will have default value or formatted date of today in current locale
52 | val = entry.defaultValue || new Date().toLocaleDateString(window.navigator.language);
53 | break;
54 | }
55 | fields.push([entry.field, val]);
56 | });
57 | return fieldsToJson(fields);
58 | }
59 |
--------------------------------------------------------------------------------
/devtools/template/src/sampreq_url_processor.mjs:
--------------------------------------------------------------------------------
1 | /*
2 | * apidoc
3 | * https://apidocjs.com
4 | *
5 | * Authors:
6 | * Peter Rottmann
7 | * Nicolas CARPi @ Deltablot
8 | * Copyright (c) 2013 inveris OHG
9 | * Licensed under the MIT license.
10 | */
11 | export default class UrlProcessor {
12 | // Replace parameters from url (:id) by the parameters from input values
13 | hydrate (url, queryParameters) {
14 | // The dummy URL base is only used for parses of relative URLs in Node.js.
15 | const parsedUrl = new URL(url, typeof window === 'undefined' ? 'https://dummy.base' : window.location.origin);
16 | const queryParametersChangedInPathname = {};
17 |
18 | // For API parameters in the URL parts delimited by `/` (e.g. `/:foo/:bar`).
19 | parsedUrl.pathname.split('/').forEach((pathnamePart, i) => {
20 | if (pathnamePart.charAt(0) === ':') {
21 | const realPathnamePart = pathnamePart.slice(1);
22 |
23 | if (typeof queryParameters[realPathnamePart] !== 'undefined') {
24 | parsedUrl.pathname = parsedUrl.pathname.replace(pathnamePart, encodeURIComponent(queryParameters[realPathnamePart]));
25 | queryParametersChangedInPathname[realPathnamePart] = queryParameters[realPathnamePart];
26 | }
27 | }
28 | });
29 |
30 | // For API parameters in the URL query string (e.g. `?foo=:foo&bar=:bar`).
31 | for (const key in queryParameters) {
32 | if (
33 | typeof queryParametersChangedInPathname[key] === 'undefined' || // Avoid adding query parameter if it has already been changed in pathname.
34 | parsedUrl.searchParams.has(key)
35 | ) {
36 | parsedUrl.searchParams.set(key, queryParameters[key]);
37 | }
38 | }
39 |
40 | return parsedUrl.toString();
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/devtools/template/src/webpack.config.js:
--------------------------------------------------------------------------------
1 | /*
2 | * apidoc
3 | * https://apidocjs.com
4 | *
5 | * Authors:
6 | * Peter Rottmann
7 | * Nicolas CARPi @ Deltablot
8 | * Copyright (c) 2013 inveris OHG
9 | * Licensed under the MIT license.
10 | */
11 |
12 | /* webpack js bundler config file */
13 | const path = require('path');
14 | const { ESBuildMinifyPlugin } = require('esbuild-loader');
15 |
16 | module.exports = {
17 | entry: path.resolve(__dirname, 'main.js'),
18 | // mode is set at runtime
19 | resolve: {
20 | alias: {
21 | handlebars: 'handlebars/dist/handlebars.min.js',
22 | // use src jquery, not the minified version or it won't be found
23 | jquery: 'jquery/src/jquery',
24 | },
25 | extensions: ['.js', '.mjs'],
26 | },
27 | module: {
28 | rules: [
29 | // expose jquery globally
30 | {
31 | test: require.resolve('jquery'),
32 | loader: 'expose-loader',
33 | options: {
34 | exposes: ['$', 'jQuery'],
35 | },
36 | },
37 | ],
38 | },
39 | output: {
40 | filename: 'main.bundle.js',
41 | // path is set at runtime
42 | },
43 | optimization: {
44 | minimizer: [
45 | new ESBuildMinifyPlugin({
46 | target: 'es2015',
47 | }),
48 | ],
49 | },
50 | };
51 |
--------------------------------------------------------------------------------
/docker/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM php:8.0-fpm
2 |
3 | ENV COMPOSER_HOME /tmp
4 |
5 | RUN apt-get update && apt-get install -y \
6 | git \
7 | libzip-dev \
8 | unzip \
9 | && pecl install xdebug \
10 | && docker-php-ext-install -j$(nproc) zip pdo pdo_mysql \
11 | && docker-php-ext-enable xdebug \
12 | && echo "xdebug.mode=coverage" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini;
13 |
14 | COPY install-composer.sh .
15 | RUN sh ./install-composer.sh && rm ./install-composer.sh
16 |
--------------------------------------------------------------------------------
/docker/bin/cli:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SCRIPT_PATH=$(dirname $(realpath -s $0))
4 | export COMPOSE_PROJECT_NAME=fusionsuite-backend
5 | export COMPOSE_FILE=$SCRIPT_PATH/../docker-compose.yml
6 | export USER=$(id -u):$(id -g)
7 |
8 | if [ -z `docker-compose ps -q php` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q php)` ]; then
9 | docker-compose run -T --rm --no-deps php ./bin/cli "$@"
10 | else
11 | docker-compose exec -T php ./bin/cli "$@"
12 | fi
13 |
--------------------------------------------------------------------------------
/docker/bin/composer:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SCRIPT_PATH=$(dirname $(realpath -s $0))
4 | export COMPOSE_PROJECT_NAME=fusionsuite-backend
5 | export COMPOSE_FILE=$SCRIPT_PATH/../docker-compose.yml
6 | export USER=$(id -u):$(id -g)
7 |
8 | if [ -z `docker-compose ps -q php` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q php)` ]; then
9 | docker-compose run -T --rm --no-deps php composer "$@"
10 | else
11 | docker-compose exec -T php composer "$@"
12 | fi
13 |
--------------------------------------------------------------------------------
/docker/bin/mariadb:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SCRIPT_PATH=$(dirname $(realpath -s $0))
4 | export COMPOSE_PROJECT_NAME=fusionsuite-backend
5 | export COMPOSE_FILE=$SCRIPT_PATH/../docker-compose.yml
6 | export USER=$(id -u):$(id -g)
7 |
8 | if [ -z `docker-compose ps -q database` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q database)` ]; then
9 | docker-compose run --rm --no-deps database mariadb -u fusionsuite --password=fusionsuite fusionsuite_development "$@"
10 | else
11 | docker-compose exec database mariadb -u fusionsuite --password=fusionsuite fusionsuite_development "$@"
12 | fi
13 |
--------------------------------------------------------------------------------
/docker/bin/php:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | SCRIPT_PATH=$(dirname $(realpath -s $0))
4 | export COMPOSE_PROJECT_NAME=fusionsuite-backend
5 | export COMPOSE_FILE=$SCRIPT_PATH/../docker-compose.yml
6 | export USER=$(id -u):$(id -g)
7 |
8 | if [ -z `docker-compose ps -q php` ] || [ -z `docker ps -q --no-trunc | grep $(docker-compose ps -q php)` ]; then
9 | docker-compose run -T --rm --no-deps php php "$@"
10 | else
11 | docker-compose exec -T php php "$@"
12 | fi
13 |
--------------------------------------------------------------------------------
/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3'
2 |
3 | services:
4 | php:
5 | build:
6 | context: .
7 | dockerfile: Dockerfile
8 | restart: unless-stopped
9 | ports:
10 | - "9000:9000"
11 | volumes:
12 | - ..:/var/www/html:z
13 | - composer:/tmp
14 | user: $USER
15 | links:
16 | - database
17 |
18 | nginx:
19 | image: nginx:alpine
20 | restart: unless-stopped
21 | ports:
22 | - "8000:8000"
23 | volumes:
24 | - ..:/var/www/html:z
25 | - ./nginx.conf:/etc/nginx/conf.d/default.conf:z
26 | links:
27 | - php
28 |
29 | database:
30 | image: mariadb:10.7
31 | restart: unless-stopped
32 | environment:
33 | - MARIADB_ROOT_PASSWORD=fusionsuite
34 | - MARIADB_USER=fusionsuite
35 | - MARIADB_PASSWORD=fusionsuite
36 | - MARIADB_DATABASE=fusionsuite_development
37 |
38 | volumes:
39 | composer: {}
40 |
41 | networks:
42 | default:
43 | name: fusionsuite-network
44 |
--------------------------------------------------------------------------------
/docker/install-composer.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # Code from https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md
4 |
5 | EXPECTED_CHECKSUM="$(curl https://composer.github.io/installer.sig)"
6 | php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
7 | ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
8 |
9 | if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
10 | then
11 | >&2 echo 'ERROR: Invalid installer checksum'
12 | rm composer-setup.php
13 | exit 1
14 | fi
15 |
16 | php composer-setup.php --install-dir=/usr/local/bin --filename=composer
17 | RESULT=$?
18 | chmod +x /usr/local/bin/composer
19 | rm composer-setup.php
20 | exit $RESULT
21 |
--------------------------------------------------------------------------------
/docker/nginx.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 8000;
3 | server_name localhost;
4 |
5 | root /var/www/html/public;
6 | index index.html index.php;
7 |
8 | error_log /var/log/nginx/error.log;
9 | access_log /var/log/nginx/access.log;
10 |
11 | location / {
12 | fastcgi_pass php:9000;
13 |
14 | fastcgi_param SCRIPT_FILENAME $document_root/index.php$fastcgi_script_name;
15 | include fastcgi_params;
16 |
17 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
18 | add_header X-Frame-Options "SAMEORIGIN" always;
19 | add_header Access-Control-Allow-Origin * always;
20 | add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE' always;
21 | add_header Access-Control-Allow-Credentials true always;
22 | add_header Access-Control-Allow-Headers 'Origin,Content-Type,Accept,Authorization,Cache-Control,Pragma,Expires' always;
23 | add_header Access-Control-Expose-Headers 'X-Total-Count,Content-Range,Link' always;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/phpstan.neon:
--------------------------------------------------------------------------------
1 | parameters:
2 | level: 0
3 | bootstrapFiles:
4 | - vendor/autoload.php
5 | - ActionScripts/autoload.php
6 | excludePaths:
7 | analyseAndScan:
8 | - ActionScripts/*/vendor/*
9 |
--------------------------------------------------------------------------------
/src/config.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | if (!isset($phinxConfig))
22 | {
23 | $phinxConfig = include(__DIR__ . '/../config/current/database.php');
24 | }
25 | $environment = $phinxConfig['environments']['default_environment'];
26 | $phinxDatabase = $phinxConfig['environments'][$environment];
27 |
28 | return [
29 | 'determineRouteBeforeAppMiddleware' => false,
30 | 'outputBuffering' => false,
31 | 'displayErrorDetails' => true,
32 | 'db' => [
33 | 'driver' => $phinxDatabase['adapter'],
34 | 'host' => $phinxDatabase['host'],
35 | 'port' => $phinxDatabase['port'],
36 | 'database' => $phinxDatabase['name'],
37 | 'username' => $phinxDatabase['user'],
38 | 'password' => $phinxDatabase['pass'],
39 | 'charset' => $phinxDatabase['charset'],
40 | 'collation' => 'utf8_unicode_ci',
41 | ]
42 | ];
43 |
--------------------------------------------------------------------------------
/src/constant.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | define('TYPE_ORGANIZATION_ID', 1);
22 | define('TYPE_USER_ID', 2);
23 |
--------------------------------------------------------------------------------
/src/v1/Controllers/Ping.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Controllers;
22 |
23 | use Psr\Http\Message\ResponseInterface as Response;
24 | use Psr\Http\Message\ServerRequestInterface as Request;
25 |
26 | final class Ping
27 | {
28 | /**
29 | * @api {get} /ping Check if backend answer
30 | * @apiName GetPing
31 | * @apiGroup Ping
32 | * @apiVersion 1.0.0-draft
33 | *
34 | * @apiSuccessExample {text} Success-Response:
35 | * HTTP/1.1 200 OK
36 | * pong
37 | *
38 | */
39 | public function getPing(Request $request, Response $response, $args): Response
40 | {
41 | $response->getBody()->write('pong');
42 | return $response;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/v1/Models/Config/Propertyallowedtype.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Config;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Propertyallowedtype extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'type_id',
31 | 'property_id',
32 | 'created_at',
33 | 'updated_at'
34 | ];
35 | }
36 |
--------------------------------------------------------------------------------
/src/v1/Models/Config/Propertyitemlink.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Config;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Propertyitemlink extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'item_id',
31 | 'property_id',
32 | 'created_at',
33 | 'updated_at'
34 | ];
35 | }
36 |
--------------------------------------------------------------------------------
/src/v1/Models/Config/Propertylist.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Config;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Propertylist extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | // 'property_id',
31 | 'value',
32 | // 'created_at',
33 | // 'updated_at'
34 | ];
35 | protected $hidden = [
36 | 'is_type',
37 | ];
38 | }
39 |
--------------------------------------------------------------------------------
/src/v1/Models/Config/Propertytypelink.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Config;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Propertytypelink extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'type_id',
31 | 'property_id',
32 | 'created_at',
33 | 'updated_at'
34 | ];
35 | }
36 |
--------------------------------------------------------------------------------
/src/v1/Models/Config/Relationshiptype.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Config;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Relationshiptype extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'name',
31 | 'created_at',
32 | 'updated_at'
33 | ];
34 | protected $hidden = [];
35 | }
36 |
--------------------------------------------------------------------------------
/src/v1/Models/Display/Menu/Menu.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Display\Menu;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Menu extends Model
26 | {
27 | protected $appends = [
28 | 'items'
29 | ];
30 | protected $visible = [
31 | 'id',
32 | 'name',
33 | 'icon',
34 | 'position',
35 | 'items',
36 | 'created_at',
37 | 'updated_at',
38 | ];
39 |
40 | /**
41 | * The attributes that should be cast.
42 | *
43 | * @var array
44 | */
45 | protected $casts = [
46 | 'name' => 'string',
47 | 'icon' => 'string',
48 | 'position' => 'integer'
49 | ];
50 |
51 | public function getItemsAttribute()
52 | {
53 | return [];
54 | }
55 |
56 | public function items()
57 | {
58 | return $this->hasMany('\App\v1\Models\Display\Menu\Menuitem')->orderBy('position');
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/v1/Models/Display/Menu/Menuitem.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Display\Menu;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 | use Illuminate\Database\Eloquent\SoftDeletes;
25 | use Illuminate\Database\Capsule\Manager as DB;
26 |
27 | class Menuitem extends Model
28 | {
29 | protected $appends = [
30 | 'type',
31 | ];
32 | protected $visible = [
33 | 'id',
34 | 'name',
35 | 'icon',
36 | 'type',
37 | 'position',
38 | 'menu_id',
39 | 'created_at',
40 | 'updated_at',
41 | ];
42 |
43 | /**
44 | * The attributes that should be cast.
45 | *
46 | * @var array
47 | */
48 | protected $casts = [
49 | 'name' => 'string',
50 | 'icon' => 'string',
51 | 'position' => 'integer'
52 | ];
53 |
54 | public function getTypeAttribute()
55 | {
56 | $type = \App\v1\Models\Config\Type::find($this->attributes['type_id']);
57 | return $type;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/v1/Models/Display/Menu/Menuitemcustom.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Display\Menu;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 | use Illuminate\Database\Eloquent\SoftDeletes;
25 | use Illuminate\Database\Capsule\Manager as DB;
26 |
27 | class Menuitemcustom extends Model
28 | {
29 | protected $appends = [
30 | 'menuitem',
31 | ];
32 | protected $visible = [
33 | 'id',
34 | 'menuitem',
35 | 'position',
36 | 'user_id',
37 | 'created_at',
38 | 'updated_at',
39 | ];
40 |
41 | protected $hidden = [
42 | 'user_id'
43 | ];
44 |
45 | /**
46 | * The attributes that should be cast.
47 | *
48 | * @var array
49 | */
50 | protected $casts = [
51 | 'position' => 'integer'
52 | ];
53 |
54 | public function getMenuitemAttribute()
55 | {
56 | $type = \App\v1\Models\Display\Menu\Menuitem::find($this->attributes['menuitem_id']);
57 | return $type;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/v1/Models/Display/Type/Typepanel.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Display\Type;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 | use Illuminate\Database\Eloquent\SoftDeletes;
25 | use Illuminate\Database\Capsule\Manager as DB;
26 |
27 | class Typepanel extends Model
28 | {
29 | protected $appends = [
30 | ];
31 | protected $visible = [
32 | 'id',
33 | 'name',
34 | 'icon',
35 | 'position',
36 | 'displaytype',
37 | 'type_id',
38 | 'items'
39 | ];
40 |
41 | /**
42 | * The attributes that should be cast.
43 | *
44 | * @var array
45 | */
46 | protected $casts = [
47 | 'name' => 'string',
48 | 'icon' => 'string',
49 | 'position' => 'integer'
50 | ];
51 |
52 | public function getItemsAttribute()
53 | {
54 | return [];
55 | }
56 |
57 | public function items()
58 | {
59 | return $this->hasMany('\App\v1\Models\Display\Type\Typepanelitem')->orderBy('position');
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/v1/Models/Display/Type/Typepanelcustom.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Display\Type;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 | use Illuminate\Database\Eloquent\SoftDeletes;
25 | use Illuminate\Database\Capsule\Manager as DB;
26 |
27 | class Typepanelcustom extends Model
28 | {
29 | protected $appends = [
30 | ];
31 | protected $visible = [
32 | 'id',
33 | 'user_id',
34 | 'type_id',
35 | 'panelspositions'
36 | ];
37 |
38 | /**
39 | * The attributes that should be cast.
40 | *
41 | * @var array
42 | */
43 | protected $casts = [
44 | ];
45 | }
46 |
--------------------------------------------------------------------------------
/src/v1/Models/Display/Type/Typepanelitem.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models\Display\Type;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 | use Illuminate\Database\Eloquent\SoftDeletes;
25 | use Illuminate\Database\Capsule\Manager as DB;
26 |
27 | class Typepanelitem extends Model
28 | {
29 | protected $appends = [
30 | ];
31 | protected $visible = [
32 | 'id',
33 | 'position',
34 | 'property_id',
35 | 'typepanel_id',
36 | 'timeline_message',
37 | 'timeline_options',
38 | ];
39 |
40 | /**
41 | * The attributes that should be cast.
42 | *
43 | * @var array
44 | */
45 | protected $casts = [
46 | 'position' => 'integer'
47 | ];
48 | }
49 |
--------------------------------------------------------------------------------
/src/v1/Models/Fusioninventoryitem.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Fusioninventoryitem extends Model
26 | {
27 | protected $appends = [
28 | 'properties'
29 | ];
30 | protected $visible = [
31 | 'id',
32 | 'querytype',
33 | 'markup',
34 | 'markup_name',
35 | 'type_id',
36 | 'fusioninventoryitem_id',
37 | 'properties',
38 | 'created_at',
39 | 'updated_at'
40 | ];
41 | protected $hidden = [];
42 |
43 | public function getPropertiesAttribute()
44 | {
45 | return $this->properties()->get();
46 | }
47 |
48 | public function properties()
49 | {
50 | return $this->hasMany('App\v1\Models\Fusioninventoryproperty');
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/v1/Models/Fusioninventoryproperty.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Fusioninventoryproperty extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'markup',
31 | 'fusioninventoryitem_id',
32 | 'property_id',
33 | 'created_at',
34 | 'updated_at'
35 | ];
36 | protected $hidden = [];
37 | }
38 |
--------------------------------------------------------------------------------
/src/v1/Models/ItemProperty.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models;
22 |
23 | use Illuminate\Database\Eloquent\Relations\Pivot;
24 |
25 | class ItemProperty extends Pivot
26 | {
27 | }
28 |
--------------------------------------------------------------------------------
/src/v1/Models/ItemState.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class ItemState extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'name',
31 | 'created_at',
32 | 'updated_at'
33 | ];
34 | protected $hidden = [];
35 | }
36 |
--------------------------------------------------------------------------------
/src/v1/Models/Rule.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 | use Illuminate\Database\Eloquent\SoftDeletes;
25 |
26 | class Rule extends Model
27 | {
28 | use SoftDeletes;
29 |
30 | protected $appends = [
31 | 'criteria',
32 | 'actions'
33 | ];
34 | protected $visible = [
35 | 'id',
36 | 'name',
37 | 'type',
38 | 'serialized',
39 | 'comment',
40 | 'criteria',
41 | 'actions'
42 | ];
43 |
44 | protected $hidden = [
45 | 'serialized'
46 | ];
47 |
48 | public function getCriteriaAttribute()
49 | {
50 | return $this->criteria()->get();
51 | }
52 |
53 | public function getActionsAttribute()
54 | {
55 | return $this->actions()->get();
56 | }
57 |
58 | public function criteria()
59 | {
60 | return $this->hasMany('App\v1\Models\Rulecriterium');
61 | }
62 |
63 | public function actions()
64 | {
65 | return $this->hasMany('App\v1\Models\Ruleaction');
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/v1/Models/Ruleaction.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Ruleaction extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'name',
31 | 'field',
32 | 'type',
33 | 'values',
34 | 'res_in_property_id',
35 | 'comment',
36 | 'created_at',
37 | 'updated_at'
38 | ];
39 | protected $hidden = [];
40 | }
41 |
--------------------------------------------------------------------------------
/src/v1/Models/Rulecriterium.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Models;
22 |
23 | use Illuminate\Database\Eloquent\Model as Model;
24 |
25 | class Rulecriterium extends Model
26 | {
27 | protected $appends = [];
28 | protected $visible = [
29 | 'id',
30 | 'name',
31 | 'field',
32 | 'comparator',
33 | 'values',
34 | 'comment',
35 | 'created_at',
36 | 'updated_at'
37 | ];
38 | protected $hidden = [];
39 | }
40 |
--------------------------------------------------------------------------------
/src/v1/Post.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1;
22 |
23 | final class Post
24 | {
25 | public static function postHasProperties($obj, $properties)
26 | {
27 | foreach ($properties as $property)
28 | {
29 | if (
30 | is_null($obj)
31 | || property_exists($obj, $property) === false
32 | )
33 | {
34 | return false;
35 | }
36 | }
37 | return true;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/v1/Templates/Knowledge_management.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "itemName": "Knowledge base",
4 | "internalname": "knowledgebase",
5 | "panels": [
6 | {
7 | "name": "Classification",
8 | "properties": [
9 | {
10 | "name": "Knowledge type",
11 | "internalname": "knowledgetype",
12 | "valuetype": "list",
13 | "regexformat": "",
14 | "listvalues": ["Known solution", "Known workaround", "Known error"],
15 | "unit": "",
16 | "default": "",
17 | "description": ""
18 | },
19 | {
20 | "name": "Description",
21 | "internalname": "description",
22 | "valuetype": "string",
23 | "regexformat": "",
24 | "listvalues": [],
25 | "unit": "",
26 | "default": "",
27 | "description": ""
28 | }
29 | ]
30 | },
31 | {
32 | "name": "Knowledge",
33 | "properties": [
34 | {
35 | "name": "Knowledge",
36 | "internalname": "knowledge",
37 | "valuetype": "text",
38 | "regexformat": "",
39 | "listvalues": [],
40 | "unit": "",
41 | "default": "",
42 | "description": ""
43 | }
44 | ]
45 | }
46 | ]
47 | }
48 | ]
49 |
--------------------------------------------------------------------------------
/src/v1/Validator/Dateformat.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Validator;
22 |
23 | use Rakit\Validation\Rule;
24 |
25 | class Dateformat extends Rule
26 | {
27 | protected $message = "The :attribute is not valid date";
28 |
29 | protected $fillableParams = ['dateformat'];
30 |
31 | public function check($value): bool
32 | {
33 | // true for valid, false for invalid
34 | if ($value == '')
35 | {
36 | return true;
37 | }
38 | $date = date_create_from_format('Y-m-d', $value);
39 | if (!$date || date_format($date, 'Y-m-d') != $value)
40 | {
41 | return false;
42 | }
43 | return true;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/v1/Validator/Datetimeformat.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Validator;
22 |
23 | use Rakit\Validation\Rule;
24 |
25 | class Datetimeformat extends Rule
26 | {
27 | protected $message = "The :attribute is not valid datetime";
28 |
29 | protected $fillableParams = ['datetimeformat'];
30 |
31 | public function check($value): bool
32 | {
33 | // true for valid, false for invalid
34 | if ($value == '')
35 | {
36 | return true;
37 | }
38 | $date = date_create_from_format('Y-m-d H:i:s', $value);
39 | if (!$date || date_format($date, 'Y-m-d H:i:s') != $value)
40 | {
41 | return false;
42 | }
43 | return true;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/v1/Validator/Maxchars.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Validator;
22 |
23 | use Rakit\Validation\Rule;
24 |
25 | class Maxchars extends Rule
26 | {
27 | protected $message = "The :attribute property has too many characters";
28 |
29 | protected $fillableParams = ['maxchars'];
30 |
31 | public function check($value): bool
32 | {
33 | // make sure required parameters exists
34 | $this->requireParameters(['maxchars']);
35 |
36 | // getting parameters
37 | $maxchars = $this->parameter('maxchars');
38 |
39 | if (!is_null($value))
40 | {
41 | return strlen($value) <= $maxchars;
42 | }
43 | return true;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/v1/Validator/Minchars.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Validator;
22 |
23 | use Rakit\Validation\Rule;
24 |
25 | class Minchars extends Rule
26 | {
27 | protected $message = "The :attribute property has not enough characters";
28 |
29 | protected $fillableParams = ['minchars'];
30 |
31 | public function check($value): bool
32 | {
33 | // make sure required parameters exists
34 | $this->requireParameters(['minchars']);
35 |
36 | // getting parameters
37 | $minchars = $this->parameter('minchars');
38 |
39 | if (!is_null($value))
40 | {
41 | return strlen($value) >= $minchars;
42 | }
43 | return true;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/v1/Validator/Timeformat.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Validator;
22 |
23 | use Rakit\Validation\Rule;
24 |
25 | class Timeformat extends Rule
26 | {
27 | protected $message = "The :attribute is not valid time";
28 |
29 | protected $fillableParams = ['timeformat'];
30 |
31 | public function check($value): bool
32 | {
33 | // true for valid, false for invalid
34 | if ($value == '')
35 | {
36 | return true;
37 | }
38 | $date = date_create_from_format('H:i:s', $value);
39 | if (!$date || date_format($date, 'H:i:s') != $value)
40 | {
41 | return false;
42 | }
43 | return true;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/v1/Validator/Type.php:
--------------------------------------------------------------------------------
1 | .
19 | */
20 |
21 | namespace App\v1\Validator;
22 |
23 | use Rakit\Validation\Rule;
24 |
25 | class Type extends Rule
26 | {
27 | protected $message = "The :attribute is not valid type";
28 |
29 | protected $fillableParams = ['type'];
30 |
31 | public function check($value): bool
32 | {
33 | // make sure required parameters exists
34 | $this->requireParameters(['type']);
35 |
36 | // getting parameters
37 | $type = $this->parameter('type');
38 |
39 | // true for valid, false for invalid
40 | return gettype($value) === $type;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/tests/RESTAPI/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es2021": true
5 | },
6 | "extends": [
7 | "standard",
8 | "plugin:mocha/recommended"
9 | ],
10 | "globals": {
11 | "$localize": "readonly",
12 | "before": "readonly",
13 | "cy": "readonly",
14 | "Cypress": "readonly"
15 | },
16 | "parserOptions": {
17 | "ecmaVersion": "latest"
18 | },
19 | "plugins": [
20 | "mocha"
21 | ],
22 | "rules": {
23 | "comma-dangle": ["error", "always-multiline"],
24 | "no-useless-constructor": "off",
25 | "semi": ["error", "always"],
26 | "template-tag-spacing": ["error", "always"],
27 | "mocha/no-skipped-tests": "warn",
28 | "mocha/no-empty-description": "error"
29 | },
30 | "ignorePatterns": ["schemaValidation/**/*.js"]
31 | }
32 |
--------------------------------------------------------------------------------
/tests/RESTAPI/00_status.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('Endpoint /v1/status', function () {
6 | it('respond with json containing the status of the backend', function (done) {
7 | request
8 | .get('/v1/status')
9 | .set('Accept', 'application/json')
10 | .expect('Content-Type', /json/)
11 | .expect(200)
12 | .end(function (err, response) {
13 | if (err) {
14 | return done(err + ' | Response: ' + response.text);
15 | }
16 | return done();
17 | });
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/tests/RESTAPI/00_token.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | describe('Endpoint /v1/token', function () {
9 | it('respond with json containing the JWT token with login & password', function (done) {
10 | request
11 | .post('/v1/token')
12 | .send({ login: 'admin', password: 'admin' })
13 | .set('Accept', 'application/json')
14 | .expect(200)
15 | .expect('Content-Type', /json/)
16 | .expect(function (response) {
17 | assert(is.propertyCount(response.body, 3));
18 |
19 | assert(validator.isJWT(response.body.token));
20 | assert(validator.matches(response.body.refreshtoken, /^\w+$/));
21 |
22 | assert(is.integer(response.body.expires));
23 | assert(validator.matches('' + response.body.expires, /^\d{10}$/));
24 | global.token = response.body.token;
25 | })
26 | .end(function (err, response) {
27 | if (err) {
28 | return done(err + ' | Response: ' + response.text);
29 | }
30 | return done();
31 | });
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/tests/RESTAPI/01_type/0_type-GET.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | describe('type | Endpoint /v1/config/types', function () {
9 | it('respond with json containing the list of types', function (done) {
10 | request
11 | .get('/v1/config/types')
12 | .set('Accept', 'application/json')
13 | .set('Authorization', 'Bearer ' + global.token)
14 | .expect(200)
15 | .expect('Content-Type', /json/)
16 | .expect(function (response) {
17 | const laptopType = response.body[2]; // laptops
18 | assert(is.propertyCount(laptopType, 16));
19 | assert(is.number(laptopType.id));
20 | assert(is.string(laptopType.name));
21 | assert(is.string(laptopType.internalname));
22 | assert(is.string(laptopType.modeling));
23 | assert(is.boolean(laptopType.tree));
24 | assert(is.boolean(laptopType.allowtreemultipleroots));
25 | assert(validator.isISO8601(laptopType.created_at));
26 | assert(validator.isISO8601(laptopType.updated_at));
27 | assert(is.array(laptopType.properties));
28 |
29 | assert(validator.equals('' + laptopType.id, '3'));
30 | assert(validator.equals(laptopType.name, 'Laptop'));
31 | assert(validator.equals(laptopType.modeling, 'physical'));
32 | })
33 | .end(function (err, response) {
34 | if (err) {
35 | return done(err + ' | Response: ' + response.text);
36 | }
37 | return done();
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/tests/RESTAPI/01_type/3_type-id-DELETE.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('type | Delete /v1/config/types/:id', function () {
6 | it('soft delete the Firewall type', function (done) {
7 | request
8 | .delete('/v1/config/types/' + global.id)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('permanently delete the Firewall type', function (done) {
22 | request
23 | .delete('/v1/config/types/' + global.id)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/02_items/8_item-id-DELETE.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('items | delete /v1/items/:id', function () {
6 | it('soft delete the item', function (done) {
7 | request
8 | .delete('/v1/items/' + global.id)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('permanently delete the item', function (done) {
22 | request
23 | .delete('/v1/items/' + global.id)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/02_items/9_delete_types.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
3 |
4 | describe('items | Endpoint /v1/items | delete type', function () {
5 | it('soft delete a type', function (done) {
6 | request
7 | .delete('/v1/config/types/' + global.mytypeId)
8 | .set('Accept', 'application/json')
9 | .set('Authorization', 'Bearer ' + global.token)
10 | .expect(200)
11 | .expect('Content-Type', /json/)
12 | .end(function (err, response) {
13 | if (err) {
14 | return done(err + ' | Response: ' + response.text);
15 | }
16 | return done();
17 | });
18 | });
19 |
20 | it('hard delete a type', function (done) {
21 | request
22 | .delete('/v1/config/types/' + global.mytypeId)
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect(200)
26 | .expect('Content-Type', /json/)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/03_itemsHeaders/1_create_15_items.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | describe('itemsHeaders | Endpoint /v1/items', function () {
9 | for (let step = 1; step <= 15; step++) {
10 | it('create a new item ' + step, function (done) {
11 | request
12 | .post('/v1/items')
13 | .send({ name: 'Laptop' + step, type_id: 3 })
14 | .set('Accept', 'application/json')
15 | .set('Authorization', 'Bearer ' + global.token)
16 | .expect(200)
17 | .expect('Content-Type', /json/)
18 | .expect(function (response) {
19 | assert(is.propertyCount(response.body, 2));
20 | assert(is.integer(response.body.id));
21 | assert(is.integer(response.body.id_bytype));
22 | assert(validator.matches('' + response.body.id, /^\d+$/));
23 | })
24 | .end(function (err, response) {
25 | if (err) {
26 | return done(err + ' | Response: ' + response.text);
27 | }
28 | return done();
29 | });
30 | });
31 | }
32 | });
33 |
--------------------------------------------------------------------------------
/tests/RESTAPI/03_itemsHeaders/8_item-id-DELETE.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemsHeaders | Delete all items', function () {
6 | it('soft delete the item', function (done) {
7 | for (const id of global.itemsId) {
8 | request
9 | .delete('/v1/items/' + id)
10 | .set('Accept', 'application/json')
11 | .set('Authorization', 'Bearer ' + global.token)
12 | .expect('Content-Type', /json/)
13 | .expect(200)
14 | .end(function (err, response) {
15 | if (err) {
16 | return done(err + ' | Response: ' + response.text);
17 | }
18 | });
19 | }
20 | return done();
21 | });
22 |
23 | it('permanently delete the item', function (done) {
24 | for (const id of global.itemsId) {
25 | request
26 | .delete('/v1/items/' + id)
27 | .set('Accept', 'application/json')
28 | .set('Authorization', 'Bearer ' + global.token)
29 | .expect('Content-Type', /json/)
30 | .expect(200)
31 | .end(function (err, response) {
32 | if (err) {
33 | return done(err + ' | Response: ' + response.text);
34 | }
35 | });
36 | }
37 | return done();
38 | });
39 | });
40 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/boolean/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'boolean in string',
4 | value: 'false',
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'set 0 (integer) instead false',
9 | value: 0,
10 | errorMessage: 'The Default is not valid type',
11 | },
12 | {
13 | description: 'set 0 (string) instead false',
14 | value: '0',
15 | errorMessage: 'The Default is not valid type',
16 | },
17 | ];
18 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/boolean/3_badValue.js:
--------------------------------------------------------------------------------
1 | const common = require('../common.js');
2 |
3 | describe('itemProperties | boolean type | bad values | create items', function () {
4 | describe('prepare', function () {
5 | it('define the type boolean', function (done) {
6 | common.defineValuetype(done, 'boolean');
7 | });
8 |
9 | it('create a new type', function (done) {
10 | common.createType(done, 'boolean');
11 | });
12 |
13 | it('create the property ', function (done) {
14 | common.createProperty(done, true);
15 | });
16 |
17 | it('Get the property to check value is good', function (done) {
18 | common.checkProperty(done, true);
19 | });
20 |
21 | it('Attach a property to the type', function (done) {
22 | common.attachPropertyToType(done);
23 | });
24 | });
25 |
26 | describe('item, create: multiple bad values', function () {
27 | // eslint-disable-next-line mocha/no-setup-in-describe
28 | global.dataProvider.forEach(function ({ description, value, errorMessage }) {
29 | errorMessage = errorMessage.replace(' Default ', ' Value ');
30 | it('try create a new item but return error (' + description + ') => error', function (done) {
31 | common.createItemWithError(done, value, errorMessage);
32 | });
33 | });
34 | });
35 |
36 | describe('clean', function () {
37 | it('Soft delete the type: test boolean', function (done) {
38 | common.deleteType(done);
39 | });
40 |
41 | it('Hard delete the type: test boolean', function (done) {
42 | common.deleteType(done);
43 | });
44 |
45 | it('Soft delete the property', function (done) {
46 | common.deleteProperty(done);
47 | });
48 |
49 | it('Hard delete the property', function (done) {
50 | common.deleteProperty(done);
51 | });
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/date/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'date inversed',
4 | value: '06-05-2022',
5 | errorMessage: 'The Default is not valid date',
6 | },
7 | {
8 | description: 'integer',
9 | value: 2022,
10 | errorMessage: 'The Default is not valid type, The Value is not valid date',
11 | },
12 | {
13 | description: 'wrong month',
14 | value: '2022-15-13',
15 | errorMessage: 'The Default is not valid date',
16 | },
17 | {
18 | description: 'miss the 0 in month number',
19 | value: '2022-5-13',
20 | errorMessage: 'The Default is not valid date',
21 | },
22 | {
23 | description: 'text string',
24 | value: 'sometext',
25 | errorMessage: 'The Default is not valid date',
26 | },
27 | ];
28 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/date/3_badValue.js:
--------------------------------------------------------------------------------
1 | const common = require('../common.js');
2 |
3 | describe('itemProperties | date type | bad values | create items', function () {
4 | describe('prepare', function () {
5 | it('define the type date', function (done) {
6 | common.defineValuetype(done, 'date');
7 | });
8 |
9 | it('create a new type date', function (done) {
10 | common.createType(done, 'date');
11 | });
12 |
13 | it('create the property', function (done) {
14 | common.createProperty(done, '2022-04-25');
15 | });
16 |
17 | it('Get the property to check value is good', function (done) {
18 | common.checkProperty(done, '2022-04-25');
19 | });
20 |
21 | it('Attach a property to the type date', function (done) {
22 | common.attachPropertyToType(done);
23 | });
24 | });
25 |
26 | describe('item, create: multiple bad values', function () {
27 | // eslint-disable-next-line mocha/no-setup-in-describe
28 | global.dataProvider.forEach(({ description, value, errorMessage }) => {
29 | errorMessage = errorMessage.replace(' Default ', ' Value ');
30 | it('try create a new item but return error (' + description + ')', function (done) {
31 | common.createItemWithError(done, value, errorMessage);
32 | });
33 | });
34 | });
35 |
36 | describe('clean', function () {
37 | it('Soft delete the type: test date', function (done) {
38 | common.deleteType(done);
39 | });
40 |
41 | it('Hard delete the type: test date', function (done) {
42 | common.deleteType(done);
43 | });
44 |
45 | it('Soft delete the property', function (done) {
46 | common.deleteProperty(done);
47 | });
48 |
49 | it('Hard delete the property', function (done) {
50 | common.deleteProperty(done);
51 | });
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/datetime/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'bad datetime format',
4 | value: '2022-05-06 13:54',
5 | errorMessage: 'The Default is not valid datetime',
6 | },
7 | {
8 | description: 'integer',
9 | value: 2022,
10 | errorMessage: 'The Default is not valid type, The Value is not valid datetime',
11 | },
12 | {
13 | description: 'boolean instead string',
14 | value: true,
15 | errorMessage: 'The Default is not valid type, The Value is not valid datetime',
16 | },
17 | {
18 | description: 'miss the 0 in the hour',
19 | value: '2022-05-06 3:64:05',
20 | errorMessage: 'The Default is not valid datetime',
21 | },
22 | {
23 | description: 'bad minute',
24 | value: '2022-05-06 13:64:05',
25 | errorMessage: 'The Default is not valid datetime',
26 | },
27 | ];
28 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/decimal/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'integer',
4 | value: 10,
5 | errorMessage: 'The Value is not valid type',
6 | },
7 | {
8 | description: 'string',
9 | value: '3.1416',
10 | errorMessage: 'The Value is not valid type',
11 | },
12 | ];
13 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/decimal/3_badValue.js:
--------------------------------------------------------------------------------
1 | const common = require('../common.js');
2 |
3 | describe('itemProperties | decimal type | bad values | create items', function () {
4 | describe('prepare', function () {
5 | it('define the type decimal', function (done) {
6 | common.defineValuetype(done, 'decimal');
7 | });
8 |
9 | it('create a new type decimal', function (done) {
10 | common.createType(done, 'decimal');
11 | });
12 |
13 | it('create the property', function (done) {
14 | common.createProperty(done, 3.1416);
15 | });
16 |
17 | it('Get the property to check value is good', function (done) {
18 | common.checkProperty(done, 3.1416);
19 | });
20 |
21 | it('Attach a property to the type decimal', function (done) {
22 | common.attachPropertyToType(done);
23 | });
24 | });
25 |
26 | describe('item, create: multiple bad values', function () {
27 | // eslint-disable-next-line mocha/no-setup-in-describe
28 | global.dataProvider.forEach(({ description, value, errorMessage }) => {
29 | it('try create a new item but return error (' + description + ')', function (done) {
30 | common.createItemWithError(done, value, errorMessage);
31 | });
32 | });
33 | });
34 |
35 | describe('clean', function () {
36 | it('Soft delete the type: test decimal', function (done) {
37 | common.deleteType(done);
38 | });
39 |
40 | it('Hard delete the type: test decimal', function (done) {
41 | common.deleteType(done);
42 | });
43 |
44 | it('Soft delete the property', function (done) {
45 | common.deleteProperty(done);
46 | });
47 |
48 | it('Hard delete the property', function (done) {
49 | common.deleteProperty(done);
50 | });
51 | });
52 | });
53 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/integer/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'integer into string',
4 | value: '10',
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'float',
9 | value: 10.1,
10 | errorMessage: 'The Default is not valid type, The Value must be integer',
11 | },
12 | {
13 | description: 'boolean',
14 | value: true,
15 | errorMessage: 'The Default is not valid type',
16 | },
17 | ];
18 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/itemlink/0_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'item id in string',
4 | value: '123',
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'boolean',
9 | value: true,
10 | errorMessage: 'The Default is not valid type',
11 | },
12 | {
13 | description: 'item id not exists',
14 | value: 47586,
15 | errorMessage: 'The Default is an id than does not exist',
16 | },
17 | {
18 | description: 'wrong item id (negative integer)',
19 | value: -1,
20 | errorMessage: 'The Default is not valid format',
21 | },
22 | {
23 | description: 'wrong item id: 0',
24 | value: 0,
25 | errorMessage: 'The Default is an id than does not exist',
26 | },
27 | ];
28 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/itemlink/1_create_items.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | global.itemId1 = 0;
9 | global.itemId2 = 0;
10 | global.itemId3 = 0;
11 | global.itemId4 = 0;
12 | global.itemId5 = 0;
13 | global.itemId6 = 0;
14 |
15 | describe('itemProperties: itemlink type | create items', function () {
16 | for (let i = 1; i < 7; i++) {
17 | it('create an item ' + i, function (done) {
18 | request
19 | .post('/v1/items')
20 | .send({
21 | name: 'my item ' + i,
22 | type_id: 3,
23 | })
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect(200)
27 | .expect('Content-Type', /json/)
28 | .expect(function (response) {
29 | assert(is.propertyCount(response.body, 2));
30 | assert(is.integer(response.body.id));
31 | assert(is.integer(response.body.id_bytype));
32 | assert(validator.matches('' + response.body.id, /^\d+$/));
33 | global['itemId' + i] = response.body.id;
34 | })
35 | .end(function (err, response) {
36 | if (err) {
37 | return done(err + ' | Response: ' + response.text);
38 | }
39 | return done();
40 | });
41 | });
42 | }
43 | });
44 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/itemlink/8_delete_items.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
3 |
4 | describe('itemProperties: itemlink type | delete item', function () {
5 | for (let i = 1; i < 7; i++) {
6 | it('Soft delete the item ' + i, function (done) {
7 | request
8 | .delete('/v1/items/' + global['itemId' + i].toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the item ' + i, function (done) {
21 | request
22 | .delete('/v1/items/' + global['itemId' + i].toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | }
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/itemlinks/1_create_items.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | global.itemId1 = 0;
9 | global.itemId2 = 0;
10 | global.itemId3 = 0;
11 | global.itemId4 = 0;
12 | global.itemId5 = 0;
13 | global.itemId6 = 0;
14 |
15 | describe('itemProperties: itemlinks type | create items', function () {
16 | for (let i = 1; i < 7; i++) {
17 | it('create an item ' + i, function (done) {
18 | request
19 | .post('/v1/items')
20 | .send({
21 | name: 'my item ' + i,
22 | type_id: 3,
23 | })
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect(200)
27 | .expect('Content-Type', /json/)
28 | .expect(function (response) {
29 | assert(is.propertyCount(response.body, 2));
30 | assert(is.integer(response.body.id));
31 | assert(is.integer(response.body.id_bytype));
32 | assert(validator.matches('' + response.body.id, /^\d+$/));
33 | global['itemId' + i] = response.body.id;
34 | })
35 | .end(function (err, response) {
36 | if (err) {
37 | return done(err + ' | Response: ' + response.text);
38 | }
39 | return done();
40 | });
41 | });
42 | }
43 | });
44 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/itemlinks/8_delete_items.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
3 |
4 | describe('itemProperties: itemlinks type | delete items', function () {
5 | for (let i = 1; i < 7; i++) {
6 | it('Soft delete the item ' + i, function (done) {
7 | request
8 | .delete('/v1/items/' + global['itemId' + i].toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the item ' + i, function (done) {
21 | request
22 | .delete('/v1/items/' + global['itemId' + i].toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | }
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/list/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'integer 432',
4 | value: 432,
5 | errorMessageDefault: 'The Default is not valid type',
6 | errorMessage: 'The Value is an id than does not exist (property Test for list - ',
7 | },
8 | {
9 | description: 'unknown list value: list3',
10 | value: 'list3',
11 | errorMessageDefault: 'The Default property does not exist in listvalues',
12 | errorMessage: 'The Value is not valid type (property Test for list - ',
13 | },
14 | {
15 | description: 'array with good value',
16 | value: ['list3'],
17 | errorMessageDefault: 'The Default is not valid type',
18 | errorMessage: 'The Value is not valid type (property Test for list - ',
19 | },
20 | ];
21 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/number/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'string 5',
4 | value: '5',
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'negative integer -4',
9 | value: -4,
10 | errorMessage: 'The Default is not valid format',
11 | },
12 | ];
13 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/number/3_badValue.js:
--------------------------------------------------------------------------------
1 | const common = require('../common.js');
2 |
3 | describe('itemProperties | number type | bad values | create items', function () {
4 | describe('prepare', function () {
5 | it('define the type number', function (done) {
6 | common.defineValuetype(done, 'number');
7 | });
8 |
9 | it('create a new type number', function (done) {
10 | common.createType(done, 'number');
11 | });
12 |
13 | it('create the property', function (done) {
14 | common.createProperty(done, 5);
15 | });
16 |
17 | it('Get the property to check value is good', function (done) {
18 | common.checkProperty(done, 5);
19 | });
20 |
21 | it('Attach a property to the type number', function (done) {
22 | common.attachPropertyToType(done);
23 | });
24 | });
25 |
26 | describe('item, create: wrong values => error', function () {
27 | // eslint-disable-next-line mocha/no-setup-in-describe
28 | global.dataProvider.forEach(({ description, value, errorMessage }) => {
29 | errorMessage = errorMessage.replace(' Default ', ' Value ');
30 | it('try create a new item but return error (' + description + ')', function (done) {
31 | common.createItemWithError(done, value, errorMessage);
32 | });
33 | });
34 | });
35 |
36 | describe('clean', function () {
37 | it('Soft delete the type: test number', function (done) {
38 | common.deleteType(done);
39 | });
40 |
41 | it('Hard delete the type: test number', function (done) {
42 | common.deleteType(done);
43 | });
44 |
45 | it('Soft delete the property', function (done) {
46 | common.deleteProperty(done);
47 | });
48 |
49 | it('Hard delete the property', function (done) {
50 | common.deleteProperty(done);
51 | });
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/password/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'boolean',
4 | value: true,
5 | errorMessage: 'The Value is not valid type',
6 | },
7 | {
8 | description: 'integer',
9 | value: 2,
10 | errorMessage: 'The Value is not valid type',
11 | },
12 | ];
13 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/passwordhash/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'boolean',
4 | value: true,
5 | errorMessage: 'The Value is not valid type',
6 | },
7 | {
8 | description: 'integer',
9 | value: 2,
10 | errorMessage: 'The Value is not valid type',
11 | },
12 | ];
13 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/propertylink/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'string test1',
4 | value: 'test1',
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'not existant id 548774',
9 | value: 548774,
10 | errorMessage: 'The Default property id does not exist',
11 | },
12 | {
13 | description: 'negative integer',
14 | value: -40,
15 | errorMessage: 'The Default is not valid format',
16 | },
17 | {
18 | description: 'id 0',
19 | value: 0,
20 | errorMessage: 'The Default property id does not exist',
21 | },
22 | {
23 | description: 'property id is a string',
24 | value: '1',
25 | errorMessage: 'The Default is not valid type',
26 | },
27 | ];
28 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/string/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'number',
4 | value: 42,
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'too long string',
9 | value: 'Lorem ipsum dolor sit amet. Est porro eius sed dolorum consequatur et ducimus distinctio qui eius porro. Cum facilis quaerat ut excepturi animi qui vero voluptatum et cupiditate fuga et autem neque qui consectetur vitae qui delectus neque? Aut soluta ratione ad cupiditate maiores et modi rerum ad dignissimos nisi aut debi',
10 | errorMessage: 'The Default property has too many characters',
11 | },
12 | {
13 | description: 'boolean',
14 | value: true,
15 | errorMessage: 'The Default is not valid type',
16 | },
17 | ];
18 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/text/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'integer',
4 | value: 10,
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'boolean',
9 | value: true,
10 | errorMessage: 'The Default is not valid type',
11 | },
12 | ];
13 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/time/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'text not time',
4 | value: 'lala la',
5 | errorMessage: 'The Default is not valid time',
6 | },
7 | {
8 | description: 'bad time format',
9 | value: '23:62:04',
10 | errorMessage: 'The Default is not valid time',
11 | },
12 | {
13 | description: 'miss a 0 in the time',
14 | value: '3:42:04',
15 | errorMessage: 'The Default is not valid time',
16 | },
17 | ];
18 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/time/3_badValue.js:
--------------------------------------------------------------------------------
1 | const common = require('../common.js');
2 |
3 | describe('itemProperties | time type | bad values | create items', function () {
4 | describe('prepare', function () {
5 | it('define the type time', function (done) {
6 | common.defineValuetype(done, 'time');
7 | });
8 |
9 | it('create a new type time', function (done) {
10 | common.createType(done, 'time');
11 | });
12 |
13 | it('create the property', function (done) {
14 | common.createProperty(done, '07:04:21');
15 | });
16 |
17 | it('Get the property to check value is good', function (done) {
18 | common.checkProperty(done, '07:04:21');
19 | });
20 |
21 | it('Attach a property to the type time', function (done) {
22 | common.attachPropertyToType(done);
23 | });
24 | });
25 |
26 | describe('item, create: wrong values => error', function () {
27 | // eslint-disable-next-line mocha/no-setup-in-describe
28 | global.dataProvider.forEach(({ description, value, errorMessage }) => {
29 | errorMessage = errorMessage.replace(' Default ', ' Value ');
30 | it('try create a new item but return error (' + description + ')', function (done) {
31 | common.createItemWithError(done, value, errorMessage);
32 | });
33 | });
34 | });
35 |
36 | describe('clean', function () {
37 | it('Soft delete the type: test time', function (done) {
38 | common.deleteType(done);
39 | });
40 |
41 | it('Hard delete the type: test time', function (done) {
42 | common.deleteType(done);
43 | });
44 |
45 | it('Soft delete the property', function (done) {
46 | common.deleteProperty(done);
47 | });
48 |
49 | it('Hard delete the property', function (done) {
50 | common.deleteProperty(done);
51 | });
52 | });
53 | });
54 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/typelink/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'type id in string',
4 | value: '2',
5 | errorMessage: 'The Default is not valid type',
6 | },
7 | {
8 | description: 'boolean',
9 | value: true,
10 | errorMessage: 'The Default is not valid type',
11 | },
12 | {
13 | description: 'type id not exists',
14 | value: 47586,
15 | errorMessage: 'The Default type does not exist',
16 | },
17 | {
18 | description: 'wrong type id (negative integer)',
19 | value: -1,
20 | errorMessage: 'The Default is not valid format',
21 | },
22 | {
23 | description: 'wrong type id (0 value)',
24 | value: 0,
25 | errorMessage: 'The Default type does not exist',
26 | },
27 | ];
28 |
--------------------------------------------------------------------------------
/tests/RESTAPI/04_itemProperties/typelinks/1_dataproviders.js:
--------------------------------------------------------------------------------
1 | global.dataProvider = [
2 | {
3 | description: 'type id not in array',
4 | value: 2,
5 | errorMessage: 'The Default must be array',
6 | },
7 | {
8 | description: 'type id in string',
9 | value: '2',
10 | errorMessage: 'The Default must be array',
11 | },
12 | {
13 | description: 'types id (style array) in string',
14 | value: '[2,3]',
15 | errorMessage: 'The Default must be array',
16 | },
17 | {
18 | description: 'type id not exists',
19 | value: [267584],
20 | errorMessage: 'The Default is an id than does not exist',
21 | },
22 | {
23 | description: 'types id with 1 of the 2 not exists',
24 | value: [3, 267584],
25 | errorMessage: 'The Default is an id than does not exist',
26 | },
27 | ];
28 |
--------------------------------------------------------------------------------
/tests/RESTAPI/05_itemsTree/5_deleteSub1Item.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemsTree | delete root item', function () {
6 | it('Soft delete the sub1 item', function (done) {
7 | request
8 | .delete('/v1/items/' + global.itemLevel2Id.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the sub1 item', function (done) {
21 | request
22 | .delete('/v1/items/' + global.itemLevel2Id.toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/05_itemsTree/6_deleteRootItem.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemsTree | delete root item', function () {
6 | it('Soft delete the root item', function (done) {
7 | request
8 | .delete('/v1/items/' + global.itemLevel1Id.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the root item', function (done) {
21 | request
22 | .delete('/v1/items/' + global.itemLevel1Id.toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/05_itemsTree/7_deleteType.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemsTree | delete type', function () {
6 | it('Soft delete the type', function (done) {
7 | request
8 | .delete('/v1/config/types/' + global.typeId.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the type', function (done) {
21 | request
22 | .delete('/v1/config/types/' + global.typeId.toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/06_itemsTreeMultipleRoots/6_deleteSub1Item.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemsTreeMultipleRoots | delete root item', function () {
6 | it('Soft delete the sub1 item', function (done) {
7 | request
8 | .delete('/v1/items/' + global.itemLevel2Id.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the sub1 item', function (done) {
21 | request
22 | .delete('/v1/items/' + global.itemLevel2Id.toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/06_itemsTreeMultipleRoots/7_deleteRootItem.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemsTreeMultipleRoots | delete root item', function () {
6 | it('Soft delete the root item', function (done) {
7 | request
8 | .delete('/v1/items/' + global.itemLevel1Id.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the root item', function (done) {
21 | request
22 | .delete('/v1/items/' + global.itemLevel1Id.toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/06_itemsTreeMultipleRoots/8_deleteType.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemsTreeMultipleRoots | delete type', function () {
6 | it('Soft delete the type', function (done) {
7 | request
8 | .delete('/v1/config/types/' + global.typeId.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the type', function (done) {
21 | request
22 | .delete('/v1/config/types/' + global.typeId.toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/08_roles/2_grant/7_delete-laptop.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('roles | grant | delete laptops', function () {
6 | it('soft delete the laptop', function (done) {
7 | request
8 | .delete('/v1/items/' + global.item1Id)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('permanently delete the laptop', function (done) {
22 | request
23 | .delete('/v1/items/' + global.item1Id)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/08_roles/3_custom/data/30_delete-laptop.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('roles | custom > data | delete laptops', function () {
6 | it('soft delete the laptop', function (done) {
7 | request
8 | .delete('/v1/items/' + global.item1Id)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | // disable expect, because can be deleted or not, so need to be sure it's deleted
13 | // .expect(200)
14 | .end(function (err, response) {
15 | if (err) {
16 | return done(err + ' | Response: ' + response.text);
17 | }
18 | return done();
19 | });
20 | });
21 |
22 | it('permanently delete the laptop', function (done) {
23 | request
24 | .delete('/v1/items/' + global.item1Id)
25 | .set('Accept', 'application/json')
26 | .set('Authorization', 'Bearer ' + global.token)
27 | .expect('Content-Type', /json/)
28 | // disable expect, because can be deleted or not, so need to be sure it's deleted
29 | // .expect(200)
30 | .end(function (err, response) {
31 | if (err) {
32 | return done(err + ' | Response: ' + response.text);
33 | }
34 | return done();
35 | });
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/tests/RESTAPI/08_roles/3_custom/data_property/30_delete-laptop.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('roles | custom > data > properties | delete laptops', function () {
6 | it('soft delete the laptop', function (done) {
7 | request
8 | .delete('/v1/items/' + global.item1Id)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('permanently delete the laptop', function (done) {
22 | request
23 | .delete('/v1/items/' + global.item1Id)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/09_organizations/items/05_get_all_items_rootorg.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('organizations | items | get items with admin', function () {
8 | it('get all items in top level of oganization', function (done) {
9 | request
10 | .get('/v1/items/type/' + global.typeId)
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.token)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.not.empty(response.body), 'response body must not be empty');
17 | assert(is.array(response.body), 'response body must be an array');
18 | assert(is.propertyCount(response.body, 4), 'must have the 4 items');
19 | // check the organization field in items
20 | const firstItem = response.body[0];
21 | assert(is.object(firstItem.organization));
22 | assert(is.equal(2, Object.keys(firstItem.organization).length), 'organization must have only 2 attributes');
23 | assert(is.equal(1, firstItem.organization.id), 'organization id must be 1');
24 | assert(is.equal('My organization', firstItem.organization.name), 'organization name must be `My organization`');
25 | })
26 | .end(function (err, response) {
27 | if (err) {
28 | return done(err + ' | Response: ' + response.text);
29 | }
30 | return done();
31 | });
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/tests/RESTAPI/09_organizations/items/06_get_all_items_sub1org.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('organizations | items | get items with user1', function () {
8 | it('get all items in sub1 level of oganization', function (done) {
9 | request
10 | .get('/v1/items/type/' + global.typeId)
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.tokenUser1)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.not.empty(response.body), 'response body must not be empty');
17 | assert(is.array(response.body), 'response body must be an array');
18 | assert(is.propertyCount(response.body, 3), 'must have the 3 items');
19 | assert(is.equal(response.body[0].id, global.myitemSub1), 'must have the id of the myitemSub1');
20 | assert(is.equal(response.body[1].id, global.myitem2), 'must have the id of the myitem2');
21 | assert(is.equal(response.body[2].id, global.myitem3), 'must have the id of the myitem3');
22 | })
23 | .end(function (err, response) {
24 | if (err) {
25 | return done(err + ' | Response: ' + response.text);
26 | }
27 | return done();
28 | });
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/tests/RESTAPI/09_organizations/items/07_get_all_items_sub2org.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('organizations | items | get items with user2', function () {
8 | it('get all items in sub1 level of oganization', function (done) {
9 | request
10 | .get('/v1/items/type/' + global.typeId)
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.tokenUser2)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.not.empty(response.body), 'response body must not be empty');
17 | assert(is.array(response.body), 'response body must be an array');
18 | assert(is.propertyCount(response.body, 2), 'must have the third item');
19 | assert(is.equal(response.body[0].id, global.myitemSub1), 'must have the id of the myitemSub1');
20 | assert(is.equal(response.body[1].id, global.myitem3), 'must have the id of the myitem3');
21 | })
22 | .end(function (err, response) {
23 | if (err) {
24 | return done(err + ' | Response: ' + response.text);
25 | }
26 | return done();
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tests/RESTAPI/09_organizations/items/10_delete-types.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('organizations | items | delete type', function () {
6 | it('Soft delete the type', function (done) {
7 | request
8 | .delete('/v1/config/types/' + global.typeId.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | it('Hard delete the type', function (done) {
21 | request
22 | .delete('/v1/config/types/' + global.typeId.toString())
23 | .set('Accept', 'application/json')
24 | .set('Authorization', 'Bearer ' + global.token)
25 | .expect('Content-Type', /json/)
26 | .expect(200)
27 | .end(function (err, response) {
28 | if (err) {
29 | return done(err + ' | Response: ' + response.text);
30 | }
31 | return done();
32 | });
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/tests/RESTAPI/09_organizations/properties/09_detach_properties_to_type2_byadmin.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('organizations | properties | attach properties to type2 by admin', function () {
8 | it('detach mypropSub1', function (done) {
9 | request
10 | .delete('/v1/config/types/' + global.mytype2 + '/property/' + global.mypropSub1)
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.token)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.propertyCount(response.body, 0));
17 | })
18 | .end(function (err, response) {
19 | if (err) {
20 | return done(err + ' | Response: ' + response.text);
21 | }
22 | return done();
23 | });
24 | });
25 |
26 | it('detach prop2', function (done) {
27 | request
28 | .delete('/v1/config/types/' + global.mytype2 + '/property/' + global.myprop2)
29 | .set('Accept', 'application/json')
30 | .set('Authorization', 'Bearer ' + global.token)
31 | .expect(200)
32 | .expect('Content-Type', /json/)
33 | .expect(function (response) {
34 | assert(is.propertyCount(response.body, 0));
35 | })
36 | .end(function (err, response) {
37 | if (err) {
38 | return done(err + ' | Response: ' + response.text);
39 | }
40 | return done();
41 | });
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/tests/RESTAPI/09_organizations/properties/12_detach_properties_to_type2_byadmin.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('organizations | properties | attach properties to type2 by admin', function () {
8 | it('detach mypropSub1', function (done) {
9 | request
10 | .delete('/v1/config/types/' + global.mytype2 + '/property/' + global.mypropSub1)
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.token)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.propertyCount(response.body, 0));
17 | })
18 | .end(function (err, response) {
19 | if (err) {
20 | return done(err + ' | Response: ' + response.text);
21 | }
22 | return done();
23 | });
24 | });
25 |
26 | it('detach prop2', function (done) {
27 | request
28 | .delete('/v1/config/types/' + global.mytype2 + '/property/' + global.myprop2)
29 | .set('Accept', 'application/json')
30 | .set('Authorization', 'Bearer ' + global.token)
31 | .expect(200)
32 | .expect('Content-Type', /json/)
33 | .expect(function (response) {
34 | assert(is.propertyCount(response.body, 0));
35 | })
36 | .end(function (err, response) {
37 | if (err) {
38 | return done(err + ' | Response: ' + response.text);
39 | }
40 | return done();
41 | });
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/tests/RESTAPI/10_usereventTimestamp/35_delete-item.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('usereventTimestamp | delete item', function () {
6 | it('soft delete the item', function (done) {
7 | request
8 | .delete('/v1/items/' + global.itemId)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect(200)
12 | .expect('Content-Type', /json/)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('hard delete the item', function (done) {
22 | request
23 | .delete('/v1/items/' + global.itemId)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect(200)
27 | .expect('Content-Type', /json/)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/10_usereventTimestamp/36_delete-type.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('usereventTimestamp | delete type', function () {
6 | it('soft delete the type', function (done) {
7 | request
8 | .delete('/v1/config/types/' + global.typeId)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect(200)
12 | .expect('Content-Type', /json/)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('hard delete the type', function (done) {
22 | request
23 | .delete('/v1/config/types/' + global.typeId)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect(200)
27 | .expect('Content-Type', /json/)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/10_usereventTimestamp/37_delete-property.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('usereventTimestamp | delete property', function () {
6 | it('soft delete the property', function (done) {
7 | request
8 | .delete('/v1/config/properties/' + global.propertyId)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect(200)
12 | .expect('Content-Type', /json/)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('hard delete the property', function (done) {
22 | request
23 | .delete('/v1/config/properties/' + global.propertyId)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect(200)
27 | .expect('Content-Type', /json/)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/10_usereventTimestamp/README.md:
--------------------------------------------------------------------------------
1 | # User event and timestamp
2 |
3 | These tests will test for:
4 |
5 | * config/properties
6 | * config/types
7 | * items
8 |
9 | The following:
10 |
11 | * creating
12 | * fill *created_at* with datetime
13 | * fill *updated_at* with datetime
14 | * fill *created_by* with user id
15 | * updating
16 | * update *updated_at* with datetime
17 | * fill *updated_by* with user id
18 | * soft deleting
19 | * fill *deleted_at* with datetime
20 | * fill *deleted_by* with user id
21 | * restoring from soft delete
22 | * fill *deleted_at* to null
23 | * fill *deleted_by* to null
24 | * update *updated_at* with datetime
25 | * update *updated_by* with user id
26 |
27 |
--------------------------------------------------------------------------------
/tests/RESTAPI/16_actionscripts/actionZabbix/2_deleteRule.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('actionscripts/ActionZabbix - Delete the rule', function () {
6 | it('it delete a rule', function (done) {
7 | request
8 | .delete('/v1/rules/actionscript/' + global.ruleId)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect(200)
12 | .end(function (err, response) {
13 | if (err) {
14 | return done(err + ' | Response: ' + response.text);
15 | }
16 | return done();
17 | });
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/tests/RESTAPI/16_actionscripts/notificationMail/2_deleteRule.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('Delete the rule', function () {
6 | it('it delete a rule', function (done) {
7 | request
8 | .delete('/v1/rules/actionscript/' + global.ruleId)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect(200)
12 | .end(function (err, response) {
13 | if (err) {
14 | return done(err + ' | Response: ' + response.text);
15 | }
16 | return done();
17 | });
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/tests/RESTAPI/19_refreshToken/05_delete-users.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('refresh token | delete users', function () {
6 | it('Soft delete the user1', function (done) {
7 | request
8 | .delete('/v1/items/' + global.user1.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('Hard delete the user1', function (done) {
22 | request
23 | .delete('/v1/items/' + global.user1.toString())
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/20_getToken/05_delete-users.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('get token | delete users', function () {
6 | it('Soft delete the user1', function (done) {
7 | request
8 | .delete('/v1/items/' + global.user1.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('Hard delete the user1', function (done) {
22 | request
23 | .delete('/v1/items/' + global.user1.toString())
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/21_itemPropertyWhenAddDeletePropertyToType/1_createType.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | describe('itemPropertyWhenAddPropertyToType | create type', function () {
9 | it('create a new type', function (done) {
10 | request
11 | .post('/v1/config/types')
12 | .send({
13 | name: 'testType',
14 | internalname: 'testtype',
15 | })
16 | .set('Accept', 'application/json')
17 | .set('Authorization', 'Bearer ' + global.token)
18 | .expect(200)
19 | .expect('Content-Type', /json/)
20 | .expect(function (response) {
21 | assert(is.propertyCount(response.body, 1));
22 | assert(is.integer(response.body.id));
23 | assert(validator.matches('' + response.body.id, /^\d+$/));
24 | global.typeId = response.body.id;
25 | })
26 | .end(function (err, response) {
27 | if (err) {
28 | return done(err + ' | Response: ' + response.text);
29 | }
30 | return done();
31 | });
32 | });
33 |
34 | it('Attach a property to the type', function (done) {
35 | request
36 | .post('/v1/config/types/' + global.typeId.toString() + '/property/6')
37 | .send()
38 | .set('Accept', 'application/json')
39 | .set('Authorization', 'Bearer ' + global.token)
40 | .expect(200)
41 | .expect('Content-Type', /json/)
42 | .end(function (err, response) {
43 | if (err) {
44 | return done(err + ' | Response: ' + response.text);
45 | }
46 | return done();
47 | });
48 | });
49 | });
50 |
--------------------------------------------------------------------------------
/tests/RESTAPI/21_itemPropertyWhenAddDeletePropertyToType/2_createItem.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | describe('itemPropertyWhenAddPropertyToType | create item', function () {
9 | it('create an item', function (done) {
10 | request
11 | .post('/v1/items')
12 | .send({
13 | name: 'an item of the type',
14 | type_id: global.typeId,
15 | })
16 | .set('Accept', 'application/json')
17 | .set('Authorization', 'Bearer ' + global.token)
18 | .expect(200)
19 | .expect('Content-Type', /json/)
20 | .expect(function (response) {
21 | assert(is.propertyCount(response.body, 2));
22 | assert(is.integer(response.body.id));
23 | assert(is.integer(response.body.id_bytype));
24 | assert(validator.matches('' + response.body.id, /^\d+$/));
25 | assert(is.equal(1, response.body.id_bytype));
26 | global.itemId = response.body.id;
27 | })
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/21_itemPropertyWhenAddDeletePropertyToType/3_addNewPropertyToType.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('itemPropertyWhenAddPropertyToType | add new property to type', function () {
8 | it('Attach a property to the type', function (done) {
9 | request
10 | .post('/v1/config/types/' + global.typeId.toString() + '/property/7')
11 | .send()
12 | .set('Accept', 'application/json')
13 | .set('Authorization', 'Bearer ' + global.token)
14 | .expect(200)
15 | .expect('Content-Type', /json/)
16 | .end(function (err, response) {
17 | if (err) {
18 | return done(err + ' | Response: ' + response.text);
19 | }
20 | return done();
21 | });
22 | });
23 |
24 | it('verify the item have right the property 7', function (done) {
25 | request
26 | .get('/v1/items/' + global.itemId)
27 | .set('Accept', 'application/json')
28 | .set('Authorization', 'Bearer ' + global.token)
29 | .expect(200)
30 | .expect('Content-Type', /json/)
31 | .expect(function (response) {
32 | assert(is.not.empty(response.body), 'The body must contain something');
33 | assert(is.object(response.body), 'the body response must be an object');
34 | assert(is.equal(2, response.body.properties.length), 'must have 2 properties');
35 | assert(is.equal(7, response.body.properties[1].id), 'the second property id must be 7');
36 | })
37 | .end(function (err, response) {
38 | if (err) {
39 | return done(err + ' | Response: ' + response.text);
40 | }
41 | return done();
42 | });
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/tests/RESTAPI/21_itemPropertyWhenAddDeletePropertyToType/4_deletePropertyToType.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('itemPropertyWhenAddPropertyToType | delete property to type', function () {
8 | it('Attach a property to the type', function (done) {
9 | request
10 | .delete('/v1/config/types/' + global.typeId.toString() + '/property/7')
11 | .send()
12 | .set('Accept', 'application/json')
13 | .set('Authorization', 'Bearer ' + global.token)
14 | .expect(200)
15 | .expect('Content-Type', /json/)
16 | .end(function (err, response) {
17 | if (err) {
18 | return done(err + ' | Response: ' + response.text);
19 | }
20 | return done();
21 | });
22 | });
23 |
24 | it('verify the item not have right the property 7', function (done) {
25 | request
26 | .get('/v1/items/' + global.itemId)
27 | .set('Accept', 'application/json')
28 | .set('Authorization', 'Bearer ' + global.token)
29 | .expect(200)
30 | .expect('Content-Type', /json/)
31 | .expect(function (response) {
32 | assert(is.not.empty(response.body), 'The body must contain something');
33 | assert(is.object(response.body), 'the body response must be an object');
34 | assert(is.equal(1, response.body.properties.length), 'must have 1 property');
35 | assert(is.equal(6, response.body.properties[0].id), 'the id of the unique property must be 6');
36 | })
37 | .end(function (err, response) {
38 | if (err) {
39 | return done(err + ' | Response: ' + response.text);
40 | }
41 | return done();
42 | });
43 | });
44 | });
45 |
--------------------------------------------------------------------------------
/tests/RESTAPI/21_itemPropertyWhenAddDeletePropertyToType/6_deleteItem.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemPropertyWhenAddPropertyToType | delete item', function () {
6 | it('Soft delete the item', function (done) {
7 | request
8 | .delete('/v1/items/' + global.itemId.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('Hard delete the item', function (done) {
22 | request
23 | .delete('/v1/items/' + global.itemId.toString())
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/21_itemPropertyWhenAddDeletePropertyToType/7_deleteType.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemPropertyWhenAddPropertyToType | delete type', function () {
6 | it('Soft delete the type', function (done) {
7 | request
8 | .delete('/v1/config/types/' + global.typeId.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('Hard delete the type', function (done) {
22 | request
23 | .delete('/v1/config/types/' + global.typeId.toString())
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/22_changeslogs/1_properties/2_getall_properties.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('changes | properties | get all properties', function () {
8 | it('get all properties and check changes key not exists', function (done) {
9 | request
10 | .get('/v1/config/properties')
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.token)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.array(response.body));
17 | assert(is.above(response.body.length, 2));
18 |
19 | const firstProperty = response.body[0];
20 | assert(is.not.propertyDefined(firstProperty, 'changes'));
21 | })
22 | .end(function (err, response) {
23 | if (err) {
24 | return done(err + ' | Response: ' + response.text);
25 | }
26 | return done();
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tests/RESTAPI/22_changeslogs/2_type/2_getall_types.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('changes | types | get all types', function () {
8 | it('get all types and check changes key not exists', function (done) {
9 | request
10 | .get('/v1/config/types')
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.token)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.array(response.body));
17 | assert(is.above(response.body.length, 2));
18 |
19 | const firstType = response.body[0];
20 | assert(is.not.propertyDefined(firstType, 'changes'));
21 | })
22 | .end(function (err, response) {
23 | if (err) {
24 | return done(err + ' | Response: ' + response.text);
25 | }
26 | return done();
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tests/RESTAPI/22_changeslogs/3_item/03_getall_item.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('changes | items | get all items', function () {
8 | it('get all items and check changes key not exists', function (done) {
9 | request
10 | .get('/v1/items/type/' + global.typeId)
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.token)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.array(response.body));
17 | assert(is.above(response.body.length, 0));
18 |
19 | const firstItem = response.body[0];
20 | assert(is.not.propertyDefined(firstItem, 'changes'));
21 | })
22 | .end(function (err, response) {
23 | if (err) {
24 | return done(err + ' | Response: ' + response.text);
25 | }
26 | return done();
27 | });
28 | });
29 | });
30 |
--------------------------------------------------------------------------------
/tests/RESTAPI/23_display/1_menus/2_menu-GET.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | describe('Display menu | Get menu', function () {
9 | it('respond with json containing the list of menus', function (done) {
10 | request
11 | .get('/v1/display/menu')
12 | .set('Accept', 'application/json')
13 | .set('Authorization', 'Bearer ' + global.token)
14 | .expect(200)
15 | .expect('Content-Type', /json/)
16 | .expect(function (response) {
17 | const menu = response.body[0]; // assets menu
18 | assert(is.propertyCount(menu, 7));
19 | assert(is.number(menu.id));
20 | assert(is.string(menu.name));
21 | assert(is.null(menu.icon));
22 | assert(is.number(menu.position));
23 | assert(validator.isISO8601(menu.created_at));
24 | assert(validator.isISO8601(menu.updated_at));
25 | assert(is.array(menu.items));
26 |
27 | assert(is.equal(menu.id, global.id));
28 | assert(validator.equals(menu.name, 'Assets'));
29 | })
30 | .end(function (err, response) {
31 | if (err) {
32 | return done(err + ' | Response: ' + response.text);
33 | }
34 | return done();
35 | });
36 | });
37 | });
38 |
--------------------------------------------------------------------------------
/tests/RESTAPI/23_display/1_menus/4_menu-id-DELETE.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('Display menu | Delete menu', function () {
6 | it('delete the Assets menu', function (done) {
7 | request
8 | .delete('/v1/display/menu/' + global.id)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/tests/RESTAPI/23_display/2_menuitems/2_menuitem-GET.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const validator = require('validator');
3 | const assert = require('assert');
4 | const is = require('is_js');
5 |
6 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
7 |
8 | describe('Display menuitem | Get menuitem', function () {
9 | it('respond with json containing the list of menus', function (done) {
10 | request
11 | .get('/v1/display/menu/item')
12 | .set('Accept', 'application/json')
13 | .set('Authorization', 'Bearer ' + global.token)
14 | .expect(200)
15 | .expect('Content-Type', /json/)
16 | .expect(function (response) {
17 | assert(is.equal(2, response.body.length), 'must have 2 items in this menu');
18 | const menu = response.body[0];
19 | assert(is.propertyCount(menu, 8));
20 | assert(is.number(menu.id));
21 | assert(is.string(menu.name));
22 | assert(is.null(menu.icon));
23 | assert(is.object(menu.type));
24 | assert(is.number(menu.type.id));
25 | assert(is.number(menu.position));
26 | assert(is.number(menu.menu_id));
27 | assert(validator.isISO8601(menu.created_at));
28 | assert(validator.isISO8601(menu.updated_at));
29 |
30 | assert(is.equal(menu.id, global.id));
31 | assert(validator.equals(menu.name, 'Laptop'));
32 | })
33 | .end(function (err, response) {
34 | if (err) {
35 | return done(err + ' | Response: ' + response.text);
36 | }
37 | return done();
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/tests/RESTAPI/23_display/2_menuitems/5_menuitem-id-DELETE.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('Display menuitem | Delete menuitem', function () {
6 | it('delete the menu item', function (done) {
7 | request
8 | .delete('/v1/display/menu/item/' + global.id)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 | });
21 |
--------------------------------------------------------------------------------
/tests/RESTAPI/23_display/3_menuitemcustoms/9_finish.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('Display menuitemcustom | delete all', function () {
6 | it('delete a menu', function (done) {
7 | request
8 | .delete('/v1/display/menu/' + global.menu01id)
9 | .send({ name: 'Assets 01' })
10 | .set('Accept', 'application/json')
11 | .set('Authorization', 'Bearer ' + global.token)
12 | .expect(200)
13 | .expect('Content-Type', /json/)
14 | .end(function (err, response) {
15 | if (err) {
16 | return done(err + ' | Response: ' + response.text);
17 | }
18 | return done();
19 | });
20 | });
21 | });
22 |
--------------------------------------------------------------------------------
/tests/RESTAPI/23_display/5_typepanelitem/9_finish.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('Display typepanelitem | Delete types to finish', function () {
6 | it('soft delete the type', function (done) {
7 | request
8 | .delete('/v1/config/types/' + global.typeId)
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('permanently delete the type', function (done) {
22 | request
23 | .delete('/v1/config/types/' + global.typeId)
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/25_itemSearch/002_prepare-add-data.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('itemSearch | prepare data', function () {
6 | // eslint-disable-next-line mocha/no-setup-in-describe
7 | global.dataProvider.forEach((data) => {
8 | it('create an item: ' + data.name, function (done) {
9 | const itemData = {
10 | name: data.name,
11 | type_id: global.typeId,
12 | properties: [
13 | ],
14 | };
15 | for (let [valuetype, value] of Object.entries(data.properties)) {
16 | if (valuetype === 'list' && value !== null) {
17 | value = global.listvalues[value];
18 | }
19 | if (valuetype === 'itemlink' && value !== null) {
20 | value = global[value];
21 | }
22 | if (valuetype === 'itemlinks' && value !== null) {
23 | const values = [];
24 | for (const val of value) {
25 | values.push(global[val]);
26 | }
27 | value = values;
28 | }
29 |
30 | itemData.properties.push(
31 | {
32 | property_id: global.properties[valuetype],
33 | value,
34 | },
35 | );
36 | }
37 | request
38 | .post('/v1/items')
39 | .send(itemData)
40 | .set('Accept', 'application/json')
41 | .set('Authorization', 'Bearer ' + global.token)
42 | .expect(200)
43 | .expect('Content-Type', /json/)
44 | .expect(function (response) {
45 | })
46 | .end(function (err, response) {
47 | if (err) {
48 | return done(err + ' | Response: ' + response.text);
49 | }
50 | return done();
51 | });
52 | });
53 | });
54 | });
55 |
--------------------------------------------------------------------------------
/tests/RESTAPI/26_items_users_properties_hidden/2_type-items-GET.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 | const assert = require('assert');
3 | const is = require('is_js');
4 |
5 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
6 |
7 | describe('items_users_properties_hidden | Endpoint /v1/items/type/ users (GET all)', function () {
8 | it('Get the items of the type users', function (done) {
9 | request
10 | .get('/v1/items/type/2')
11 | .set('Accept', 'application/json')
12 | .set('Authorization', 'Bearer ' + global.token)
13 | .expect(200)
14 | .expect('Content-Type', /json/)
15 | .expect(function (response) {
16 | assert(is.not.empty(response.body), 'response body must not be empty');
17 | assert(is.array(response.body), 'response body must be an array');
18 | const firstElement = response.body[0];
19 | assert(is.array(firstElement.properties), 'the item properties must be an array');
20 |
21 | const propertiesIds = [];
22 | let password = null;
23 | for (const property of firstElement.properties) {
24 | propertiesIds.push(property.id);
25 | if (property.id === 5) {
26 | password = property.value;
27 | }
28 | }
29 |
30 | assert.deepEqual(propertiesIds, [1, 2, 5, 6], 'We must have only first name, last name, empty password and activated properties');
31 | assert(is.null(password), 'the password must be always null value when get, defined or not in the database');
32 | })
33 | .end(function (err, response) {
34 | if (err) {
35 | return done(err + ' | Response: ' + response.text);
36 | }
37 | return done();
38 | });
39 | });
40 | });
41 |
--------------------------------------------------------------------------------
/tests/RESTAPI/27_passwordUserLogin/05_delete-users.js:
--------------------------------------------------------------------------------
1 | const supertest = require('supertest');
2 |
3 | const request = supertest('http://127.0.0.1/fusionsuite/backend');
4 |
5 | describe('password user login | delete users', function () {
6 | it('Soft delete the user1', function (done) {
7 | request
8 | .delete('/v1/items/' + global.user1.toString())
9 | .set('Accept', 'application/json')
10 | .set('Authorization', 'Bearer ' + global.token)
11 | .expect('Content-Type', /json/)
12 | .expect(200)
13 | .end(function (err, response) {
14 | if (err) {
15 | return done(err + ' | Response: ' + response.text);
16 | }
17 | return done();
18 | });
19 | });
20 |
21 | it('Hard delete the user1', function (done) {
22 | request
23 | .delete('/v1/items/' + global.user1.toString())
24 | .set('Accept', 'application/json')
25 | .set('Authorization', 'Bearer ' + global.token)
26 | .expect('Content-Type', /json/)
27 | .expect(200)
28 | .end(function (err, response) {
29 | if (err) {
30 | return done(err + ' | Response: ' + response.text);
31 | }
32 | return done();
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/tests/RESTAPI/README.md:
--------------------------------------------------------------------------------
1 | # Run REST API tests
2 |
3 | Need run mountebank fake server (HTTP, SMTP):
4 |
5 | ```
6 | ./node_modules/.bin/mb --configfile mountebank/imposters.ejs
7 | ```
8 |
9 | Need run too php script to do actions on the database
10 |
11 | ```
12 | php -S 127.0.0.1:8012 testDatabaseAccess.php
13 | ```
14 |
15 | Then run the tests:
16 |
17 | ```
18 | ./node_modules/.bin/mocha --ignore "./node_modules/**/*.js" --ignore "./schemaValidation/**/*.js" "./**/*.js"
19 | ```
20 |
21 |
22 |
--------------------------------------------------------------------------------
/tests/RESTAPI/fusionsuite.conf:
--------------------------------------------------------------------------------
1 | server {
2 | listen 80 default_server;
3 | listen [::]:80 default_server;
4 |
5 | root /var/www/public;
6 | index index.php index.html;
7 | server_name _;
8 | add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
9 | add_header X-Frame-Options "SAMEORIGIN";
10 | add_header Access-Control-Allow-Origin *;
11 | add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, PUT, DELETE';
12 | add_header Access-Control-Allow-Credentials true;
13 | add_header Access-Control-Allow-Headers 'Origin,Content-Type,Accept,Authorization,Cache-Control,Pragma,Expires';
14 | add_header Access-Control-Expose-Headers 'X-Total-Count,Content-Range,Link';
15 |
16 | location /fusionsuite/backend/ {
17 | allow 127.0.0.1;
18 | fastcgi_split_path_info ^/fusionsuite/backend(.+)()$;
19 | fastcgi_param SCRIPT_FILENAME $document_root/index.php$fastcgi_script_name;
20 | include fastcgi_params;
21 | fastcgi_pass unix:/run/php/php8.0-fpm.sock;
22 | fastcgi_param PATH_INFO $fastcgi_path_info;
23 | }
24 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/mountebank/imposters.ejs:
--------------------------------------------------------------------------------
1 | {
2 | "imposters": [
3 | <% include imposters/smtp.ejs %>,
4 | <% include imposters/zabbix.ejs %>
5 | ]
6 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/mountebank/imposters/smtp.ejs:
--------------------------------------------------------------------------------
1 | {
2 | "port": 10025,
3 | "protocol": "smtp",
4 | "name": "smtp server not secured",
5 | "recordRequests": true,
6 | "requests": [
7 | {
8 | "requestFrom": "127.0.0.1",
9 | "ip": "127.0.0.1"
10 | }
11 | ],
12 | "stubs": []
13 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/mountebank/imposters/zabbix.ejs:
--------------------------------------------------------------------------------
1 | {
2 | "port": 10800,
3 | "protocol": "http",
4 | "name": "Zabbix API",
5 | "recordRequests": true,
6 | "requests": [
7 | {
8 | "requestFrom": "127.0.0.1",
9 | "ip": "127.0.0.1"
10 | }
11 | ],
12 | "stubs": [
13 | {
14 | "predicates": [{
15 | "contains": {
16 | "body": "user.login"
17 | }
18 | }],
19 | "responses": [
20 | {
21 | "is": {
22 | "body": {
23 | "jsonrpc": "2.0",
24 | "result": "0424bd59b807674191e7d77572075f33",
25 | "id": 1
26 | }
27 | }
28 | }
29 | ]
30 | },
31 | {
32 | "predicates": [{
33 | "contains": {
34 | "body": "apiinfo.version"
35 | }
36 | }],
37 | "responses": [
38 | {
39 | "is": {
40 | "body": {
41 | "jsonrpc": "2.0",
42 | "result": "5.4.2",
43 | "id": 1
44 | }
45 | }
46 | }
47 | ]
48 | },
49 | {
50 | "predicates": [{
51 | "contains": {
52 | "body": "host.create"
53 | }
54 | }],
55 | "responses": [
56 | {
57 | "is": {
58 | "body": {
59 | "jsonrpc": "2.0",
60 | "result": {
61 | "hostids": [
62 | "107819"
63 | ]
64 | },
65 | "id": "1"
66 | }
67 | }
68 | }
69 | ]
70 | }
71 | ]
72 | }
73 |
--------------------------------------------------------------------------------
/tests/RESTAPI/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "@faker-js/faker": "^8.3.1",
4 | "assert": "^2.1.0",
5 | "is_js": "^0.9.0",
6 | "mocha": "^10.2.0",
7 | "mountebank": "^2.9.1",
8 | "nock": "^13.4.0",
9 | "supertest": "^6.3.3",
10 | "validator": "^13.11.0"
11 | },
12 | "devDependencies": {
13 | "eslint": "^8.56.0",
14 | "eslint-config-standard": "^17.1.0",
15 | "eslint-plugin-import": "^2.29.1",
16 | "eslint-plugin-mocha": "^10.2.0",
17 | "eslint-plugin-n": "^16.5.0",
18 | "eslint-plugin-promise": "^6.1.1"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/ping",
3 | "method": "get",
4 | "parameters": [],
5 | "responses": []
6 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/ping/get/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/ping",
3 | "method": "get",
4 | "parameters": [
5 | {
6 | "in": "body",
7 | "schema": {
8 | "properties": [],
9 | "type": "object",
10 | "required": []
11 | }
12 | }
13 | ],
14 | "responses": []
15 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/ping/get/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/ping",
3 | "method": "get",
4 | "parameters": [],
5 | "responses": []
6 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/post/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "$schema": "http:\/\/json-schema.org\/draft-04\/schema#",
16 | "title": "Request-Example:",
17 | "type": "object",
18 | "properties": []
19 | },
20 | "description": "Request-Example:"
21 | }
22 | ],
23 | "responses": {
24 | "id": {
25 | "type": "number",
26 | "description": "The id of the item."
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/post/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "query",
8 | "name": "name",
9 | "description": "The name of the item.",
10 | "required": true
11 | },
12 | {
13 | "type": "number",
14 | "in": "query",
15 | "name": "type_id",
16 | "description": "The id of the type of the item.",
17 | "required": true
18 | },
19 | {
20 | "type": "object[]",
21 | "in": "query",
22 | "name": "properties",
23 | "description": "List of properties",
24 | "required": true
25 | },
26 | {
27 | "type": "number",
28 | "in": "query",
29 | "name": "properties.property_id",
30 | "description": "The id of the property.",
31 | "required": true
32 | },
33 | {
34 | "type": "string[]",
35 | "in": "query",
36 | "name": "properties.value",
37 | "description": "The value of the property for the item.",
38 | "required": true
39 | },
40 | {
41 | "type": "string",
42 | "in": "header",
43 | "name": "Authorization",
44 | "description": "The JWT token.",
45 | "required": true
46 | }
47 | ],
48 | "responses": {
49 | "id": {
50 | "type": "number",
51 | "description": "The id of the item."
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/delete/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}",
3 | "method": "delete",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "properties": {
16 | "id": {
17 | "type": "number",
18 | "description": "Unique ID of the item."
19 | }
20 | },
21 | "type": "object",
22 | "required": [
23 | "id"
24 | ]
25 | }
26 | }
27 | ],
28 | "responses": []
29 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/delete/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}",
3 | "method": "delete",
4 | "parameters": [
5 | {
6 | "type": "number",
7 | "in": "path",
8 | "name": "id",
9 | "description": "Unique ID of the item.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "header",
15 | "name": "Authorization",
16 | "description": "The JWT token.",
17 | "required": true
18 | }
19 | ],
20 | "responses": []
21 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/patch/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}",
3 | "method": "patch",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "$schema": "http:\/\/json-schema.org\/draft-04\/schema#",
16 | "title": "Request-Example:",
17 | "type": "object",
18 | "properties": {
19 | "id": {
20 | "type": "number",
21 | "description": "Unique ID of the item."
22 | }
23 | },
24 | "required": [
25 | "id"
26 | ]
27 | },
28 | "description": "Request-Example:"
29 | }
30 | ],
31 | "responses": []
32 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/patch/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}",
3 | "method": "patch",
4 | "parameters": [
5 | {
6 | "type": "number",
7 | "in": "path",
8 | "name": "id",
9 | "description": "Unique ID of the item.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "header",
15 | "name": "Authorization",
16 | "description": "The JWT token.",
17 | "required": true
18 | }
19 | ],
20 | "responses": {
21 | "name": {
22 | "type": "string",
23 | "description": "Name of the type."
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/property/{propertyid}/patch/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}\/property\/{propertyid}",
3 | "method": "patch",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "$schema": "http:\/\/json-schema.org\/draft-04\/schema#",
16 | "title": "Request-Example:",
17 | "type": "object",
18 | "properties": {
19 | "value": {
20 | "type": "null"
21 | },
22 | "reset_to_default": {
23 | "type": "boolean"
24 | },
25 | "id": {
26 | "type": "number",
27 | "description": "Unique ID of the item."
28 | },
29 | "propertyid": {
30 | "type": "number",
31 | "description": "Unique ID of the property."
32 | }
33 | },
34 | "required": [
35 | "id",
36 | "propertyid"
37 | ]
38 | },
39 | "description": "Request-Example:"
40 | }
41 | ],
42 | "responses": []
43 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/property/{propertyid}/patch/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}\/property\/{propertyid}",
3 | "method": "patch",
4 | "parameters": [
5 | {
6 | "type": "number",
7 | "in": "path",
8 | "name": "id",
9 | "description": "Unique ID of the item.",
10 | "required": true
11 | },
12 | {
13 | "type": "number",
14 | "in": "path",
15 | "name": "propertyid",
16 | "description": "Unique ID of the property.",
17 | "required": true
18 | },
19 | {
20 | "type": "string",
21 | "in": "header",
22 | "name": "Authorization",
23 | "description": "The JWT token.",
24 | "required": true
25 | }
26 | ],
27 | "responses": {
28 | "value": {
29 | "type": "string",
30 | "description": "Value of the property to update."
31 | },
32 | "reset_to_default": {
33 | "type": "boolean",
34 | "description": "To update with default value of property.",
35 | "default": "false"
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/property/{propertyid}/typelinks/post/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}\/property\/{propertyid}\/typelinks",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "$schema": "http:\/\/json-schema.org\/draft-04\/schema#",
16 | "title": "Request-Example:",
17 | "type": "object",
18 | "properties": {
19 | "value": {
20 | "type": "number"
21 | },
22 | "id": {
23 | "type": "number",
24 | "description": "Unique ID of the item."
25 | },
26 | "propertyid": {
27 | "type": "number",
28 | "description": "Unique ID of the property."
29 | }
30 | },
31 | "required": [
32 | "id",
33 | "propertyid"
34 | ]
35 | },
36 | "description": "Request-Example:"
37 | }
38 | ],
39 | "responses": {
40 | "value": {
41 | "type": "number",
42 | "description": "Unique ID of the type."
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/property/{propertyid}/typelinks/post/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}\/property\/{propertyid}\/typelinks",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "number",
7 | "in": "path",
8 | "name": "id",
9 | "description": "Unique ID of the item.",
10 | "required": true
11 | },
12 | {
13 | "type": "number",
14 | "in": "path",
15 | "name": "propertyid",
16 | "description": "Unique ID of the property.",
17 | "required": true
18 | },
19 | {
20 | "type": "string",
21 | "in": "header",
22 | "name": "Authorization",
23 | "description": "The JWT token.",
24 | "required": true
25 | }
26 | ],
27 | "responses": {
28 | "value": {
29 | "type": "number",
30 | "description": "Unique ID of the type."
31 | }
32 | }
33 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/property/{propertyid}/typelinks/{typelinkid}/delete/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}\/property\/{propertyid}\/typelinks\/{typelinkid}",
3 | "method": "delete",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "properties": {
16 | "id": {
17 | "type": "number",
18 | "description": "Unique ID of the item."
19 | },
20 | "propertyid": {
21 | "type": "number",
22 | "description": "Unique ID of the property."
23 | },
24 | "typelinkid": {
25 | "type": "number",
26 | "description": "Unique ID of the typelink."
27 | }
28 | },
29 | "type": "object",
30 | "required": [
31 | "id",
32 | "propertyid",
33 | "typelinkid"
34 | ]
35 | }
36 | }
37 | ],
38 | "responses": []
39 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/items/{id}/property/{propertyid}/typelinks/{typelinkid}/delete/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/items\/{id}\/property\/{propertyid}\/typelinks\/{typelinkid}",
3 | "method": "delete",
4 | "parameters": [
5 | {
6 | "type": "number",
7 | "in": "path",
8 | "name": "id",
9 | "description": "Unique ID of the item.",
10 | "required": true
11 | },
12 | {
13 | "type": "number",
14 | "in": "path",
15 | "name": "propertyid",
16 | "description": "Unique ID of the property.",
17 | "required": true
18 | },
19 | {
20 | "type": "number",
21 | "in": "path",
22 | "name": "typelinkid",
23 | "description": "Unique ID of the typelink.",
24 | "required": true
25 | },
26 | {
27 | "type": "string",
28 | "in": "header",
29 | "name": "Authorization",
30 | "description": "The JWT token.",
31 | "required": true
32 | }
33 | ],
34 | "responses": []
35 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{id}/delete/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{id}",
3 | "method": "delete",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "properties": {
16 | "id": {
17 | "type": "number",
18 | "description": "Unique ID of the item."
19 | }
20 | },
21 | "type": "object",
22 | "required": [
23 | "id"
24 | ]
25 | }
26 | }
27 | ],
28 | "responses": []
29 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{id}/delete/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{id}",
3 | "method": "delete",
4 | "parameters": [
5 | {
6 | "type": "number",
7 | "in": "path",
8 | "name": "id",
9 | "description": "Unique ID of the item.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "header",
15 | "name": "Authorization",
16 | "description": "The JWT token.",
17 | "required": true
18 | }
19 | ],
20 | "responses": []
21 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/get/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}",
3 | "method": "get",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "query",
8 | "name": "type",
9 | "description": "The type of the rules.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "header",
15 | "name": "Authorization",
16 | "description": "The JWT token.",
17 | "required": true
18 | },
19 | {
20 | "in": "body",
21 | "schema": {
22 | "properties": [],
23 | "type": "object",
24 | "required": []
25 | }
26 | }
27 | ],
28 | "responses": {
29 | "id": {
30 | "type": "integer",
31 | "description": "The id of the item."
32 | },
33 | "name": {
34 | "type": "string",
35 | "description": "The name of the item."
36 | },
37 | "comment": {
38 | "type": "string",
39 | "description": "The comment of the item."
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/get/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}",
3 | "method": "get",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "path",
8 | "name": "type",
9 | "description": "The type of the rules.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "header",
15 | "name": "Authorization",
16 | "description": "The JWT token.",
17 | "required": true
18 | }
19 | ],
20 | "responses": {
21 | "id": {
22 | "type": "integer",
23 | "description": "The id of the item."
24 | },
25 | "name": {
26 | "type": "string",
27 | "description": "The name of the item."
28 | },
29 | "comment": {
30 | "type": "string",
31 | "description": "The comment of the item."
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/post/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "properties": {
16 | "type": {
17 | "type": "number",
18 | "description": "Id of the type."
19 | }
20 | },
21 | "type": "object",
22 | "required": [
23 | "type"
24 | ]
25 | }
26 | }
27 | ],
28 | "responses": []
29 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/post/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "query",
8 | "name": "name",
9 | "description": "Name of the rule.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "query",
15 | "name": "comment",
16 | "description": "Comment of the rule.",
17 | "required": true
18 | },
19 | {
20 | "type": "string",
21 | "in": "header",
22 | "name": "Authorization",
23 | "description": "The JWT token.",
24 | "required": true
25 | }
26 | ],
27 | "responses": []
28 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/{id}/action/post/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}\/{id}\/action",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "properties": {
16 | "name": {
17 | "type": "string",
18 | "description": "Name of the rule."
19 | },
20 | "comment": {
21 | "type": "string",
22 | "description": "Comment of the rule."
23 | }
24 | },
25 | "type": "object",
26 | "required": [
27 | "name",
28 | "comment"
29 | ]
30 | }
31 | }
32 | ],
33 | "responses": []
34 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/{id}/action/post/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}\/{id}\/action",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "query",
8 | "name": "name",
9 | "description": "Name of the rule.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "query",
15 | "name": "comment",
16 | "description": "Comment of the rule.",
17 | "required": true
18 | },
19 | {
20 | "type": "string",
21 | "in": "header",
22 | "name": "Authorization",
23 | "description": "The JWT token.",
24 | "required": true
25 | }
26 | ],
27 | "responses": []
28 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/{id}/criteria/post/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}\/{id}\/criteria",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "header",
8 | "name": "Authorization",
9 | "description": "The JWT token.",
10 | "required": true
11 | },
12 | {
13 | "in": "body",
14 | "schema": {
15 | "properties": {
16 | "name": {
17 | "type": "string",
18 | "description": "Name of the rule."
19 | },
20 | "comment": {
21 | "type": "string",
22 | "description": "Comment of the rule."
23 | }
24 | },
25 | "type": "object",
26 | "required": [
27 | "name",
28 | "comment"
29 | ]
30 | }
31 | }
32 | ],
33 | "responses": []
34 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/rules/{type}/{id}/criteria/post/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/rules\/{type}\/{id}\/criteria",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "type": "string",
7 | "in": "query",
8 | "name": "name",
9 | "description": "Name of the rule.",
10 | "required": true
11 | },
12 | {
13 | "type": "string",
14 | "in": "query",
15 | "name": "comment",
16 | "description": "Comment of the rule.",
17 | "required": true
18 | },
19 | {
20 | "type": "string",
21 | "in": "header",
22 | "name": "Authorization",
23 | "description": "The JWT token.",
24 | "required": true
25 | }
26 | ],
27 | "responses": []
28 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/status/get/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/status",
3 | "method": "get",
4 | "parameters": [
5 | {
6 | "in": "body",
7 | "schema": {
8 | "properties": [],
9 | "type": "object",
10 | "required": []
11 | }
12 | }
13 | ],
14 | "responses": {
15 | "connections": {
16 | "type": "object",
17 | "properties": {
18 | "database": {
19 | "type": "boolean",
20 | "description": "true if the connection to the database is OK"
21 | }
22 | },
23 | "required": [
24 | "database"
25 | ]
26 | },
27 | "crontasks": {
28 | "type": "array",
29 | "description": "The status of the crontasks."
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/status/get/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/status",
3 | "method": "get",
4 | "parameters": [],
5 | "responses": {
6 | "connections": {
7 | "type": "object",
8 | "properties": {
9 | "database": {
10 | "type": "boolean",
11 | "description": "true if the connection to the database is OK"
12 | }
13 | },
14 | "required": [
15 | "database"
16 | ]
17 | },
18 | "crontasks": {
19 | "type": "array",
20 | "description": "The status of the crontasks."
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/status/get/test.js:
--------------------------------------------------------------------------------
1 | const commonSchema = require('../../../commonSchema.js');
2 |
3 | const fs = require('fs');
4 | const json = JSON.parse(fs.readFileSync('schemaValidation/v1/status/get/schema.json', 'utf-8'));
5 | const path = json.path;
6 | const method = json.method;
7 |
8 | describe('Schema REST API | ' + path + ' | ' + method, function () {
9 | describe('test the get status', function () {
10 | it('generate the headers', function (done) {
11 | commonSchema.generateHeaders(done, json.parameters);
12 | });
13 |
14 | it('generate the data', function (done) {
15 | commonSchema.generateData(done, json.parameters, {});
16 | });
17 |
18 | it('generate the path: ' + path, function (done) {
19 | commonSchema.generatePath(done, path, {});
20 | });
21 |
22 | it('check the endpoint and the response', function (done) {
23 | commonSchema.executeRequest(done, json.method, json.responses);
24 | });
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/token/post/schema.json:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/token",
3 | "method": "post",
4 | "parameters": [
5 | {
6 | "in": "body",
7 | "schema": {
8 | "$schema": "http:\/\/json-schema.org\/draft-04\/schema#",
9 | "title": "Request-Example:",
10 | "type": "object",
11 | "properties": {
12 | "login": {
13 | "type": "string"
14 | },
15 | "password": {
16 | "type": "string"
17 | }
18 | }
19 | },
20 | "description": "Request-Example:"
21 | }
22 | ],
23 | "responses": {
24 | "token": {
25 | "type": "string",
26 | "description": "The token string."
27 | },
28 | "refreshtoken": {
29 | "type": "string",
30 | "description": "The token string can be used to refresh \/ regenerate a new token when this token expire."
31 | },
32 | "expires": {
33 | "type": "integer",
34 | "description": "The expiration timestamp."
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/tests/RESTAPI/schemaValidation/v1/token/post/schema.json.old:
--------------------------------------------------------------------------------
1 | {
2 | "path": "\/v1\/token",
3 | "method": "post",
4 | "parameters": [],
5 | "responses": {
6 | "token": {
7 | "type": "string",
8 | "description": "The token string."
9 | },
10 | "refreshtoken": {
11 | "type": "string",
12 | "description": "The token string can be used to refresh \/ regenerate a new token when this token expire."
13 | },
14 | "expires": {
15 | "type": "integer",
16 | "description": "The expiration timestamp."
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/tests/performances/README.md:
--------------------------------------------------------------------------------
1 | # Performances tests
2 |
3 | In this folder, there are scripts for use with k6 (https://k6.io/).
4 |
5 | The goal is to have scripts testing the performances of the backend in queries charge.
6 | Needs too test with many data in the backend.
7 |
8 | # Run
9 |
10 | The command to run the script is:
11 |
12 | ```
13 | k6 run --vus 10 --duration 30s file.js
14 | ```
15 |
16 |
--------------------------------------------------------------------------------
/tests/performances/itemsUniqueId.js:
--------------------------------------------------------------------------------
1 | // Check if no collisions when generate internal id incremented by 1 and based on type_id
2 |
3 | import http from 'k6/http';
4 |
5 | import { sleep } from 'k6';
6 |
7 | export const options = {
8 |
9 | thresholds: {
10 | http_req_failed: ['rate<0.01'], // http errors should be less than 1%
11 | http_req_duration: ['p(95)<200'], // 95% of requests should be below 200ms
12 | },
13 | };
14 |
15 | export function setup() {
16 | const url = 'http://127.0.0.1/fusionsuite/backend/v1/token';
17 |
18 | const params = {
19 | headers: {
20 | 'Content-Type': 'application/json'
21 | },
22 | };
23 |
24 | const payload = JSON.stringify({
25 | login: 'admin',
26 | password: 'admin',
27 | });
28 |
29 | const res = http.post(url, payload, params);
30 | return res.json();
31 | }
32 |
33 | export default function (data) {
34 |
35 | const url = 'http://127.0.0.1/fusionsuite/backend/v1/items';
36 |
37 | const params = {
38 | headers: {
39 | 'Content-Type': 'application/json',
40 | 'Authorization': 'Bearer '+data.token
41 | },
42 | };
43 |
44 | const payload = JSON.stringify({
45 | name: 'test',
46 | type_id: 3,
47 | });
48 |
49 | http.post(url, payload, params);
50 |
51 | sleep(1);
52 | }
53 |
--------------------------------------------------------------------------------
/tests/performances/test.js:
--------------------------------------------------------------------------------
1 | import http from 'k6/http';
2 |
3 | import { sleep } from 'k6';
4 |
5 | export const options = {
6 |
7 | thresholds: {
8 | http_req_failed: ['rate<0.01'], // http errors should be less than 1%
9 | http_req_duration: ['p(95)<200'], // 95% of requests should be below 200ms
10 | },
11 | };
12 |
13 | export function setup() {
14 | const url = 'http://127.0.0.1/fusionsuite/backend/v1/token';
15 |
16 | const params = {
17 | headers: {
18 | 'Content-Type': 'application/json'
19 | },
20 | };
21 |
22 | const payload = JSON.stringify({
23 | login: 'admin',
24 | password: 'admin',
25 | });
26 |
27 | const res = http.post(url, payload, params);
28 | return res.json();
29 | }
30 |
31 | export default function (data) {
32 |
33 | const url = 'http://127.0.0.1/fusionsuite/backend/v1/config/types/3';
34 |
35 | const params = {
36 | headers: {
37 | 'Content-Type': 'application/json',
38 | 'Authorization': 'Bearer '+data.token
39 | },
40 | };
41 |
42 | http.get(url, params);
43 |
44 | sleep(1);
45 | }
--------------------------------------------------------------------------------