tm1npm 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +16 -0
- package/.eslintrc.js +28 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- package/.github/ISSUE_TEMPLATE/question.md +24 -0
- package/.github/workflows/publish-npm.yml +53 -0
- package/.github/workflows/test-on-tag.yml +172 -0
- package/DEVELOPMENT_GUIDE.md +587 -0
- package/LICENSE +21 -0
- package/README.md +580 -0
- package/jest.ci.config.js +83 -0
- package/jest.config.js +68 -0
- package/lib/exceptions/TM1Exception.d.ts +17 -0
- package/lib/exceptions/TM1Exception.d.ts.map +1 -0
- package/lib/exceptions/TM1Exception.js +36 -0
- package/lib/exceptions/TM1RestException.d.ts +10 -0
- package/lib/exceptions/TM1RestException.d.ts.map +1 -0
- package/lib/exceptions/TM1RestException.js +17 -0
- package/lib/exceptions/TM1TimeoutException.d.ts +9 -0
- package/lib/exceptions/TM1TimeoutException.d.ts.map +1 -0
- package/lib/exceptions/TM1TimeoutException.js +16 -0
- package/lib/index.d.ts +41 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +132 -0
- package/lib/objects/Annotation.d.ts +36 -0
- package/lib/objects/Annotation.d.ts.map +1 -0
- package/lib/objects/Annotation.js +134 -0
- package/lib/objects/Application.d.ts +67 -0
- package/lib/objects/Application.d.ts.map +1 -0
- package/lib/objects/Application.js +125 -0
- package/lib/objects/Axis.d.ts +36 -0
- package/lib/objects/Axis.d.ts.map +1 -0
- package/lib/objects/Axis.js +103 -0
- package/lib/objects/Chore.d.ts +43 -0
- package/lib/objects/Chore.d.ts.map +1 -0
- package/lib/objects/Chore.js +129 -0
- package/lib/objects/ChoreFrequency.d.ts +23 -0
- package/lib/objects/ChoreFrequency.d.ts.map +1 -0
- package/lib/objects/ChoreFrequency.js +61 -0
- package/lib/objects/ChoreStartTime.d.ts +15 -0
- package/lib/objects/ChoreStartTime.d.ts.map +1 -0
- package/lib/objects/ChoreStartTime.js +85 -0
- package/lib/objects/ChoreTask.d.ts +28 -0
- package/lib/objects/ChoreTask.d.ts.map +1 -0
- package/lib/objects/ChoreTask.js +66 -0
- package/lib/objects/Cube.d.ts +26 -0
- package/lib/objects/Cube.d.ts.map +1 -0
- package/lib/objects/Cube.js +109 -0
- package/lib/objects/Dimension.d.ts +26 -0
- package/lib/objects/Dimension.d.ts.map +1 -0
- package/lib/objects/Dimension.js +86 -0
- package/lib/objects/Element.d.ts +35 -0
- package/lib/objects/Element.d.ts.map +1 -0
- package/lib/objects/Element.js +115 -0
- package/lib/objects/ElementAttribute.d.ts +28 -0
- package/lib/objects/ElementAttribute.d.ts.map +1 -0
- package/lib/objects/ElementAttribute.js +97 -0
- package/lib/objects/Git.d.ts +21 -0
- package/lib/objects/Git.d.ts.map +1 -0
- package/lib/objects/Git.js +49 -0
- package/lib/objects/GitCommit.d.ts +12 -0
- package/lib/objects/GitCommit.d.ts.map +1 -0
- package/lib/objects/GitCommit.js +26 -0
- package/lib/objects/GitPlan.d.ts +35 -0
- package/lib/objects/GitPlan.d.ts.map +1 -0
- package/lib/objects/GitPlan.js +78 -0
- package/lib/objects/GitRemote.d.ts +12 -0
- package/lib/objects/GitRemote.d.ts.map +1 -0
- package/lib/objects/GitRemote.js +26 -0
- package/lib/objects/Hierarchy.d.ts +47 -0
- package/lib/objects/Hierarchy.d.ts.map +1 -0
- package/lib/objects/Hierarchy.js +165 -0
- package/lib/objects/MDXView.d.ts +19 -0
- package/lib/objects/MDXView.d.ts.map +1 -0
- package/lib/objects/MDXView.js +67 -0
- package/lib/objects/NativeView.d.ts +39 -0
- package/lib/objects/NativeView.d.ts.map +1 -0
- package/lib/objects/NativeView.js +209 -0
- package/lib/objects/Process.d.ts +70 -0
- package/lib/objects/Process.d.ts.map +1 -0
- package/lib/objects/Process.js +210 -0
- package/lib/objects/ProcessDebugBreakpoint.d.ts +60 -0
- package/lib/objects/ProcessDebugBreakpoint.d.ts.map +1 -0
- package/lib/objects/ProcessDebugBreakpoint.js +168 -0
- package/lib/objects/ProcessParameter.d.ts +23 -0
- package/lib/objects/ProcessParameter.d.ts.map +1 -0
- package/lib/objects/ProcessParameter.js +55 -0
- package/lib/objects/ProcessVariable.d.ts +26 -0
- package/lib/objects/ProcessVariable.d.ts.map +1 -0
- package/lib/objects/ProcessVariable.js +63 -0
- package/lib/objects/Rules.d.ts +30 -0
- package/lib/objects/Rules.d.ts.map +1 -0
- package/lib/objects/Rules.js +103 -0
- package/lib/objects/Sandbox.d.ts +21 -0
- package/lib/objects/Sandbox.d.ts.map +1 -0
- package/lib/objects/Sandbox.js +64 -0
- package/lib/objects/Server.d.ts +27 -0
- package/lib/objects/Server.d.ts.map +1 -0
- package/lib/objects/Server.js +26 -0
- package/lib/objects/Subset.d.ts +44 -0
- package/lib/objects/Subset.d.ts.map +1 -0
- package/lib/objects/Subset.js +222 -0
- package/lib/objects/TM1Object.d.ts +8 -0
- package/lib/objects/TM1Object.d.ts.map +1 -0
- package/lib/objects/TM1Object.js +17 -0
- package/lib/objects/TM1Project.d.ts +74 -0
- package/lib/objects/TM1Project.d.ts.map +1 -0
- package/lib/objects/TM1Project.js +409 -0
- package/lib/objects/User.d.ts +42 -0
- package/lib/objects/User.d.ts.map +1 -0
- package/lib/objects/User.js +157 -0
- package/lib/objects/View.d.ts +19 -0
- package/lib/objects/View.d.ts.map +1 -0
- package/lib/objects/View.js +33 -0
- package/lib/objects/index.d.ts +30 -0
- package/lib/objects/index.d.ts.map +1 -0
- package/lib/objects/index.js +68 -0
- package/lib/services/AnnotationService.d.ts +17 -0
- package/lib/services/AnnotationService.d.ts.map +1 -0
- package/lib/services/AnnotationService.js +91 -0
- package/lib/services/ApplicationService.d.ts +21 -0
- package/lib/services/ApplicationService.d.ts.map +1 -0
- package/lib/services/ApplicationService.js +227 -0
- package/lib/services/AuditLogService.d.ts +15 -0
- package/lib/services/AuditLogService.d.ts.map +1 -0
- package/lib/services/AuditLogService.js +153 -0
- package/lib/services/CellService.d.ts +191 -0
- package/lib/services/CellService.d.ts.map +1 -0
- package/lib/services/CellService.js +597 -0
- package/lib/services/ChoreService.d.ts +24 -0
- package/lib/services/ChoreService.d.ts.map +1 -0
- package/lib/services/ChoreService.js +219 -0
- package/lib/services/ConfigurationService.d.ts +18 -0
- package/lib/services/ConfigurationService.d.ts.map +1 -0
- package/lib/services/ConfigurationService.js +60 -0
- package/lib/services/CubeService.d.ts +43 -0
- package/lib/services/CubeService.d.ts.map +1 -0
- package/lib/services/CubeService.js +296 -0
- package/lib/services/DimensionService.d.ts +21 -0
- package/lib/services/DimensionService.d.ts.map +1 -0
- package/lib/services/DimensionService.js +146 -0
- package/lib/services/ElementService.d.ts +132 -0
- package/lib/services/ElementService.d.ts.map +1 -0
- package/lib/services/ElementService.js +579 -0
- package/lib/services/FileService.d.ts +14 -0
- package/lib/services/FileService.d.ts.map +1 -0
- package/lib/services/FileService.js +65 -0
- package/lib/services/GitService.d.ts +23 -0
- package/lib/services/GitService.d.ts.map +1 -0
- package/lib/services/GitService.js +225 -0
- package/lib/services/HierarchyService.d.ts +32 -0
- package/lib/services/HierarchyService.d.ts.map +1 -0
- package/lib/services/HierarchyService.js +235 -0
- package/lib/services/JobService.d.ts +13 -0
- package/lib/services/JobService.d.ts.map +1 -0
- package/lib/services/JobService.js +83 -0
- package/lib/services/LoggerService.d.ts +16 -0
- package/lib/services/LoggerService.d.ts.map +1 -0
- package/lib/services/LoggerService.js +101 -0
- package/lib/services/ManageService.d.ts +47 -0
- package/lib/services/ManageService.d.ts.map +1 -0
- package/lib/services/ManageService.js +221 -0
- package/lib/services/MessageLogService.d.ts +13 -0
- package/lib/services/MessageLogService.d.ts.map +1 -0
- package/lib/services/MessageLogService.js +175 -0
- package/lib/services/MonitoringService.d.ts +29 -0
- package/lib/services/MonitoringService.d.ts.map +1 -0
- package/lib/services/MonitoringService.js +86 -0
- package/lib/services/ObjectService.d.ts +8 -0
- package/lib/services/ObjectService.d.ts.map +1 -0
- package/lib/services/ObjectService.js +20 -0
- package/lib/services/PowerBiService.d.ts +13 -0
- package/lib/services/PowerBiService.d.ts.map +1 -0
- package/lib/services/PowerBiService.js +52 -0
- package/lib/services/ProcessService.d.ts +57 -0
- package/lib/services/ProcessService.d.ts.map +1 -0
- package/lib/services/ProcessService.js +499 -0
- package/lib/services/RestService.d.ts +68 -0
- package/lib/services/RestService.d.ts.map +1 -0
- package/lib/services/RestService.js +166 -0
- package/lib/services/SandboxService.d.ts +28 -0
- package/lib/services/SandboxService.d.ts.map +1 -0
- package/lib/services/SandboxService.js +197 -0
- package/lib/services/SecurityService.d.ts +33 -0
- package/lib/services/SecurityService.d.ts.map +1 -0
- package/lib/services/SecurityService.js +249 -0
- package/lib/services/ServerService.d.ts +55 -0
- package/lib/services/ServerService.d.ts.map +1 -0
- package/lib/services/ServerService.js +247 -0
- package/lib/services/SessionService.d.ts +15 -0
- package/lib/services/SessionService.d.ts.map +1 -0
- package/lib/services/SessionService.js +68 -0
- package/lib/services/SubsetService.d.ts +13 -0
- package/lib/services/SubsetService.d.ts.map +1 -0
- package/lib/services/SubsetService.js +46 -0
- package/lib/services/TM1Service.d.ts +39 -0
- package/lib/services/TM1Service.d.ts.map +1 -0
- package/lib/services/TM1Service.js +94 -0
- package/lib/services/ThreadService.d.ts +15 -0
- package/lib/services/ThreadService.d.ts.map +1 -0
- package/lib/services/ThreadService.js +104 -0
- package/lib/services/TransactionLogService.d.ts +11 -0
- package/lib/services/TransactionLogService.d.ts.map +1 -0
- package/lib/services/TransactionLogService.js +124 -0
- package/lib/services/UserService.d.ts +14 -0
- package/lib/services/UserService.d.ts.map +1 -0
- package/lib/services/UserService.js +103 -0
- package/lib/services/ViewService.d.ts +30 -0
- package/lib/services/ViewService.d.ts.map +1 -0
- package/lib/services/ViewService.js +331 -0
- package/lib/services/index.d.ts +26 -0
- package/lib/services/index.d.ts.map +1 -0
- package/lib/services/index.js +56 -0
- package/lib/tests/100PercentParityCheck.test.d.ts +6 -0
- package/lib/tests/100PercentParityCheck.test.d.ts.map +1 -0
- package/lib/tests/100PercentParityCheck.test.js +143 -0
- package/lib/tests/basic.test.d.ts +6 -0
- package/lib/tests/basic.test.d.ts.map +1 -0
- package/lib/tests/basic.test.js +52 -0
- package/lib/tests/cellService.test.d.ts +6 -0
- package/lib/tests/cellService.test.d.ts.map +1 -0
- package/lib/tests/cellService.test.js +311 -0
- package/lib/tests/ciSetup.d.ts +6 -0
- package/lib/tests/ciSetup.d.ts.map +1 -0
- package/lib/tests/ciSetup.js +23 -0
- package/lib/tests/comprehensive.service.test.d.ts +6 -0
- package/lib/tests/comprehensive.service.test.d.ts.map +1 -0
- package/lib/tests/comprehensive.service.test.js +507 -0
- package/lib/tests/connection.test.d.ts +6 -0
- package/lib/tests/connection.test.d.ts.map +1 -0
- package/lib/tests/connection.test.js +89 -0
- package/lib/tests/cubeService.test.d.ts +6 -0
- package/lib/tests/cubeService.test.d.ts.map +1 -0
- package/lib/tests/cubeService.test.js +368 -0
- package/lib/tests/dimensionService.comprehensive.test.d.ts +7 -0
- package/lib/tests/dimensionService.comprehensive.test.d.ts.map +1 -0
- package/lib/tests/dimensionService.comprehensive.test.js +614 -0
- package/lib/tests/dimensionService.test.d.ts +6 -0
- package/lib/tests/dimensionService.test.d.ts.map +1 -0
- package/lib/tests/dimensionService.test.js +293 -0
- package/lib/tests/edgeCases.test.d.ts +6 -0
- package/lib/tests/edgeCases.test.d.ts.map +1 -0
- package/lib/tests/edgeCases.test.js +301 -0
- package/lib/tests/elementService.comprehensive.test.d.ts +7 -0
- package/lib/tests/elementService.comprehensive.test.d.ts.map +1 -0
- package/lib/tests/elementService.comprehensive.test.js +846 -0
- package/lib/tests/elementService.test.d.ts +6 -0
- package/lib/tests/elementService.test.d.ts.map +1 -0
- package/lib/tests/elementService.test.js +350 -0
- package/lib/tests/enhancedCellService.test.d.ts +2 -0
- package/lib/tests/enhancedCellService.test.d.ts.map +1 -0
- package/lib/tests/enhancedCellService.test.js +152 -0
- package/lib/tests/enhancedCubeService.test.d.ts +2 -0
- package/lib/tests/enhancedCubeService.test.d.ts.map +1 -0
- package/lib/tests/enhancedCubeService.test.js +246 -0
- package/lib/tests/enhancedElementService.test.d.ts +2 -0
- package/lib/tests/enhancedElementService.test.d.ts.map +1 -0
- package/lib/tests/enhancedElementService.test.js +199 -0
- package/lib/tests/enhancedViewService.test.d.ts +2 -0
- package/lib/tests/enhancedViewService.test.d.ts.map +1 -0
- package/lib/tests/enhancedViewService.test.js +260 -0
- package/lib/tests/errorHandling.test.d.ts +6 -0
- package/lib/tests/errorHandling.test.d.ts.map +1 -0
- package/lib/tests/errorHandling.test.js +227 -0
- package/lib/tests/exceptions.test.d.ts +7 -0
- package/lib/tests/exceptions.test.d.ts.map +1 -0
- package/lib/tests/exceptions.test.js +257 -0
- package/lib/tests/hierarchyService.test.d.ts +6 -0
- package/lib/tests/hierarchyService.test.d.ts.map +1 -0
- package/lib/tests/hierarchyService.test.js +294 -0
- package/lib/tests/index.test.d.ts +6 -0
- package/lib/tests/index.test.d.ts.map +1 -0
- package/lib/tests/index.test.js +346 -0
- package/lib/tests/integration.test.d.ts +6 -0
- package/lib/tests/integration.test.d.ts.map +1 -0
- package/lib/tests/integration.test.js +302 -0
- package/lib/tests/integrationTests.test.d.ts +2 -0
- package/lib/tests/integrationTests.test.d.ts.map +1 -0
- package/lib/tests/integrationTests.test.js +252 -0
- package/lib/tests/mdx.advanced.test.d.ts +6 -0
- package/lib/tests/mdx.advanced.test.d.ts.map +1 -0
- package/lib/tests/mdx.advanced.test.js +437 -0
- package/lib/tests/objects.improved.test.d.ts +7 -0
- package/lib/tests/objects.improved.test.d.ts.map +1 -0
- package/lib/tests/objects.improved.test.js +302 -0
- package/lib/tests/performance.test.d.ts +6 -0
- package/lib/tests/performance.test.d.ts.map +1 -0
- package/lib/tests/performance.test.js +264 -0
- package/lib/tests/processService.comprehensive.test.d.ts +7 -0
- package/lib/tests/processService.comprehensive.test.d.ts.map +1 -0
- package/lib/tests/processService.comprehensive.test.js +656 -0
- package/lib/tests/processService.test.d.ts +6 -0
- package/lib/tests/processService.test.d.ts.map +1 -0
- package/lib/tests/processService.test.js +322 -0
- package/lib/tests/restService.test.d.ts +6 -0
- package/lib/tests/restService.test.d.ts.map +1 -0
- package/lib/tests/restService.test.js +177 -0
- package/lib/tests/security.advanced.test.d.ts +6 -0
- package/lib/tests/security.advanced.test.d.ts.map +1 -0
- package/lib/tests/security.advanced.test.js +407 -0
- package/lib/tests/security.test.d.ts +6 -0
- package/lib/tests/security.test.d.ts.map +1 -0
- package/lib/tests/security.test.js +204 -0
- package/lib/tests/securityService.comprehensive.test.d.ts +7 -0
- package/lib/tests/securityService.comprehensive.test.d.ts.map +1 -0
- package/lib/tests/securityService.comprehensive.test.js +457 -0
- package/lib/tests/setup.d.ts +4 -0
- package/lib/tests/setup.d.ts.map +1 -0
- package/lib/tests/setup.js +40 -0
- package/lib/tests/simpleCoverage.test.d.ts +6 -0
- package/lib/tests/simpleCoverage.test.d.ts.map +1 -0
- package/lib/tests/simpleCoverage.test.js +236 -0
- package/lib/tests/stress.performance.test.d.ts +6 -0
- package/lib/tests/stress.performance.test.d.ts.map +1 -0
- package/lib/tests/stress.performance.test.js +423 -0
- package/lib/tests/subsetService.test.d.ts +6 -0
- package/lib/tests/subsetService.test.d.ts.map +1 -0
- package/lib/tests/subsetService.test.js +271 -0
- package/lib/tests/testConfig.d.ts +18 -0
- package/lib/tests/testConfig.d.ts.map +1 -0
- package/lib/tests/testConfig.js +38 -0
- package/lib/tests/testUtils.d.ts +9 -0
- package/lib/tests/testUtils.d.ts.map +1 -0
- package/lib/tests/testUtils.js +100 -0
- package/lib/tests/tm1Service.test.d.ts +7 -0
- package/lib/tests/tm1Service.test.d.ts.map +1 -0
- package/lib/tests/tm1Service.test.js +290 -0
- package/lib/tests/viewService.test.d.ts +6 -0
- package/lib/tests/viewService.test.d.ts.map +1 -0
- package/lib/tests/viewService.test.js +240 -0
- package/lib/utils/Utils.d.ts +90 -0
- package/lib/utils/Utils.d.ts.map +1 -0
- package/lib/utils/Utils.js +379 -0
- package/package.json +81 -0
- package/run-all-tests.js +296 -0
- package/src/exceptions/TM1Exception.ts +38 -0
- package/src/exceptions/TM1RestException.ts +17 -0
- package/src/exceptions/TM1TimeoutException.ts +15 -0
- package/src/index.ts +94 -0
- package/src/objects/Annotation.ts +194 -0
- package/src/objects/Application.ts +146 -0
- package/src/objects/Axis.ts +149 -0
- package/src/objects/Chore.ts +174 -0
- package/src/objects/ChoreFrequency.ts +83 -0
- package/src/objects/ChoreStartTime.ts +111 -0
- package/src/objects/ChoreTask.ts +92 -0
- package/src/objects/Cube.ts +125 -0
- package/src/objects/Dimension.ts +107 -0
- package/src/objects/Element.ts +153 -0
- package/src/objects/ElementAttribute.ts +115 -0
- package/src/objects/Git.ts +86 -0
- package/src/objects/GitCommit.ts +31 -0
- package/src/objects/GitPlan.ts +121 -0
- package/src/objects/GitRemote.ts +31 -0
- package/src/objects/Hierarchy.ts +229 -0
- package/src/objects/MDXView.ts +91 -0
- package/src/objects/NativeView.ts +268 -0
- package/src/objects/Process.ts +320 -0
- package/src/objects/ProcessDebugBreakpoint.ts +239 -0
- package/src/objects/ProcessParameter.ts +76 -0
- package/src/objects/ProcessVariable.ts +89 -0
- package/src/objects/Rules.ts +117 -0
- package/src/objects/Sandbox.ts +90 -0
- package/src/objects/Server.ts +45 -0
- package/src/objects/Subset.ts +323 -0
- package/src/objects/TM1Object.ts +17 -0
- package/src/objects/TM1Project.ts +587 -0
- package/src/objects/User.ts +198 -0
- package/src/objects/View.ts +43 -0
- package/src/objects/index.ts +36 -0
- package/src/services/AnnotationService.ts +107 -0
- package/src/services/ApplicationService.ts +279 -0
- package/src/services/AuditLogService.ts +172 -0
- package/src/services/CellService.ts +814 -0
- package/src/services/ChoreService.ts +219 -0
- package/src/services/ConfigurationService.ts +69 -0
- package/src/services/CubeService.ts +338 -0
- package/src/services/DimensionService.ts +168 -0
- package/src/services/ElementService.ts +966 -0
- package/src/services/FileService.ts +67 -0
- package/src/services/GitService.ts +324 -0
- package/src/services/HierarchyService.ts +284 -0
- package/src/services/JobService.ts +59 -0
- package/src/services/LoggerService.ts +118 -0
- package/src/services/ManageService.ts +322 -0
- package/src/services/MessageLogService.ts +211 -0
- package/src/services/MonitoringService.ts +105 -0
- package/src/services/ObjectService.ts +21 -0
- package/src/services/PowerBiService.ts +85 -0
- package/src/services/ProcessService.ts +589 -0
- package/src/services/RestService.ts +224 -0
- package/src/services/SandboxService.ts +217 -0
- package/src/services/SecurityService.ts +284 -0
- package/src/services/ServerService.ts +313 -0
- package/src/services/SessionService.ts +81 -0
- package/src/services/SubsetService.ts +52 -0
- package/src/services/TM1Service.ts +133 -0
- package/src/services/ThreadService.ts +83 -0
- package/src/services/TransactionLogService.ts +148 -0
- package/src/services/UserService.ts +77 -0
- package/src/services/ViewService.ts +398 -0
- package/src/services/index.ts +28 -0
- package/src/tests/100PercentParityCheck.test.ts +166 -0
- package/src/tests/basic.test.ts +59 -0
- package/src/tests/cellService.test.ts +405 -0
- package/src/tests/ciSetup.ts +26 -0
- package/src/tests/comprehensive.service.test.ts +653 -0
- package/src/tests/config.ini.template +23 -0
- package/src/tests/connection.test.ts +90 -0
- package/src/tests/cubeService.test.ts +458 -0
- package/src/tests/dimensionService.comprehensive.test.ts +786 -0
- package/src/tests/dimensionService.test.ts +373 -0
- package/src/tests/edgeCases.test.ts +358 -0
- package/src/tests/elementService.comprehensive.test.ts +1190 -0
- package/src/tests/elementService.test.ts +472 -0
- package/src/tests/enhancedCellService.test.ts +237 -0
- package/src/tests/enhancedCubeService.test.ts +384 -0
- package/src/tests/enhancedElementService.test.ts +301 -0
- package/src/tests/enhancedViewService.test.ts +373 -0
- package/src/tests/errorHandling.test.ts +264 -0
- package/src/tests/exceptions.test.ts +313 -0
- package/src/tests/hierarchyService.test.ts +386 -0
- package/src/tests/index.test.ts +376 -0
- package/src/tests/integration.test.ts +333 -0
- package/src/tests/integrationTests.test.ts +302 -0
- package/src/tests/mdx.advanced.test.ts +513 -0
- package/src/tests/objects.improved.test.ts +385 -0
- package/src/tests/performance.test.ts +314 -0
- package/src/tests/processService.comprehensive.test.ts +933 -0
- package/src/tests/processService.test.ts +409 -0
- package/src/tests/restService.test.ts +218 -0
- package/src/tests/security.advanced.test.ts +464 -0
- package/src/tests/security.test.ts +233 -0
- package/src/tests/securityService.comprehensive.test.ts +582 -0
- package/src/tests/setup.ts +42 -0
- package/src/tests/simpleCoverage.test.ts +287 -0
- package/src/tests/stress.performance.test.ts +531 -0
- package/src/tests/subsetService.test.ts +350 -0
- package/src/tests/testConfig.ts +53 -0
- package/src/tests/testUtils.ts +94 -0
- package/src/tests/tm1Service.test.ts +361 -0
- package/src/tests/viewService.test.ts +324 -0
- package/src/utils/Utils.ts +395 -0
- package/tests/README.md +57 -0
- package/tests/connection/test-connection.ts +86 -0
- package/tests/edge-cases/edge-cases-test.ts +244 -0
- package/tests/integration/working-test.ts +193 -0
- package/tests/performance/performance-test.ts +133 -0
- package/tests/run-all-tests.sh +106 -0
- package/tests/security/security-test.ts +103 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Comprehensive SecurityService Tests
|
|
3
|
+
* Target: Achieve 80%+ coverage for SecurityService (currently 5.88%)
|
|
4
|
+
* Testing all security operations including users, groups, permissions
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { SecurityService } from '../services/SecurityService';
|
|
8
|
+
import { RestService } from '../services/RestService';
|
|
9
|
+
import { User } from '../objects/User';
|
|
10
|
+
|
|
11
|
+
// Mock dependencies
|
|
12
|
+
jest.mock('../objects/User');
|
|
13
|
+
|
|
14
|
+
describe('SecurityService - Comprehensive Tests', () => {
|
|
15
|
+
let securityService: SecurityService;
|
|
16
|
+
let mockRestService: jest.Mocked<RestService>;
|
|
17
|
+
|
|
18
|
+
const mockResponse = (data: any) => ({
|
|
19
|
+
data: data,
|
|
20
|
+
status: 200,
|
|
21
|
+
statusText: 'OK',
|
|
22
|
+
headers: {},
|
|
23
|
+
config: { headers: {} }
|
|
24
|
+
} as any);
|
|
25
|
+
|
|
26
|
+
const mockUser = {
|
|
27
|
+
name: 'testuser',
|
|
28
|
+
password: 'password123',
|
|
29
|
+
groups: ['TM1ConnectionPool'],
|
|
30
|
+
body: {
|
|
31
|
+
Name: 'testuser',
|
|
32
|
+
Password: 'password123',
|
|
33
|
+
Groups: [{ Name: 'TM1ConnectionPool' }]
|
|
34
|
+
}
|
|
35
|
+
} as any;
|
|
36
|
+
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
mockRestService = {
|
|
39
|
+
get: jest.fn(),
|
|
40
|
+
post: jest.fn(),
|
|
41
|
+
patch: jest.fn(),
|
|
42
|
+
put: jest.fn(),
|
|
43
|
+
delete: jest.fn()
|
|
44
|
+
} as any;
|
|
45
|
+
|
|
46
|
+
securityService = new SecurityService(mockRestService);
|
|
47
|
+
|
|
48
|
+
// Note: determineActualObjectName is private method, tested through public methods
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
afterEach(() => {
|
|
52
|
+
jest.clearAllMocks();
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
describe('Constructor and Initialization', () => {
|
|
56
|
+
test('should initialize SecurityService properly', () => {
|
|
57
|
+
expect(securityService).toBeDefined();
|
|
58
|
+
expect(securityService).toBeInstanceOf(SecurityService);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('User Name and Group Name Operations', () => {
|
|
63
|
+
test('should determine actual user name', async () => {
|
|
64
|
+
mockRestService.get.mockResolvedValue(mockResponse({
|
|
65
|
+
value: [{ Name: 'ActualUserName' }]
|
|
66
|
+
}));
|
|
67
|
+
|
|
68
|
+
const result = await securityService.determineActualUserName('TestUser');
|
|
69
|
+
expect(result).toBe('ActualUserName');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('should determine actual group name', async () => {
|
|
73
|
+
mockRestService.get.mockResolvedValue(mockResponse({
|
|
74
|
+
value: [{ Name: 'ActualGroupName' }]
|
|
75
|
+
}));
|
|
76
|
+
|
|
77
|
+
const result = await securityService.determineActualGroupName('TestGroup');
|
|
78
|
+
expect(result).toBe('ActualGroupName');
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('should handle special characters in user names', async () => {
|
|
82
|
+
const specialUserName = 'user@domain.com';
|
|
83
|
+
mockRestService.get.mockResolvedValue(mockResponse({
|
|
84
|
+
value: [{ Name: specialUserName }]
|
|
85
|
+
}));
|
|
86
|
+
|
|
87
|
+
const result = await securityService.determineActualUserName(specialUserName);
|
|
88
|
+
expect(result).toBe(specialUserName);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('should handle special characters in group names', async () => {
|
|
92
|
+
const specialGroupName = 'Domain\\AdminGroup';
|
|
93
|
+
mockRestService.get.mockResolvedValue(mockResponse({
|
|
94
|
+
value: [{ Name: specialGroupName }]
|
|
95
|
+
}));
|
|
96
|
+
|
|
97
|
+
const result = await securityService.determineActualGroupName(specialGroupName);
|
|
98
|
+
expect(result).toBe(specialGroupName);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe('User CRUD Operations', () => {
|
|
103
|
+
test('should create user successfully', async () => {
|
|
104
|
+
mockRestService.post.mockResolvedValue(mockResponse({}));
|
|
105
|
+
|
|
106
|
+
const result = await securityService.createUser(mockUser);
|
|
107
|
+
|
|
108
|
+
expect(result).toBeDefined();
|
|
109
|
+
expect(mockRestService.post).toHaveBeenCalledWith('/Users', mockUser.body);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('should get user by name', async () => {
|
|
113
|
+
const userData = {
|
|
114
|
+
Name: 'testuser',
|
|
115
|
+
Groups: [{ Name: 'TM1ConnectionPool' }]
|
|
116
|
+
};
|
|
117
|
+
mockRestService.get.mockResolvedValue(mockResponse(userData));
|
|
118
|
+
|
|
119
|
+
// Mock User.fromDict
|
|
120
|
+
const mockUserFromDict = jest.fn().mockReturnValue(mockUser);
|
|
121
|
+
(User as any).fromDict = mockUserFromDict;
|
|
122
|
+
|
|
123
|
+
const result = await securityService.getUser('testuser');
|
|
124
|
+
|
|
125
|
+
expect(mockUserFromDict).toHaveBeenCalledWith(userData);
|
|
126
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/Users('testuser')?$select=Name,FriendlyName,Password,Type,Enabled&$expand=Groups");
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('should get current user', async () => {
|
|
130
|
+
const currentUserData = {
|
|
131
|
+
Name: 'admin',
|
|
132
|
+
Groups: [{ Name: 'ADMIN' }]
|
|
133
|
+
};
|
|
134
|
+
mockRestService.get.mockResolvedValue(mockResponse(currentUserData));
|
|
135
|
+
|
|
136
|
+
const mockUserFromDict = jest.fn().mockReturnValue(mockUser);
|
|
137
|
+
(User as any).fromDict = mockUserFromDict;
|
|
138
|
+
|
|
139
|
+
const result = await securityService.getCurrentUser();
|
|
140
|
+
|
|
141
|
+
expect(mockUserFromDict).toHaveBeenCalledWith(currentUserData);
|
|
142
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/ActiveUser?$select=Name,FriendlyName,Password,Type,Enabled&$expand=Groups");
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
test('should update user', async () => {
|
|
146
|
+
// Mock determineActualUserName call
|
|
147
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
148
|
+
value: [{ Name: 'testuser' }]
|
|
149
|
+
}));
|
|
150
|
+
// Mock getGroups call (SecurityService.getGroups calls determineActualUserName again then gets groups)
|
|
151
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
152
|
+
value: [{ Name: 'testuser' }]
|
|
153
|
+
}));
|
|
154
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
155
|
+
value: [{ Name: 'TM1ConnectionPool' }]
|
|
156
|
+
}));
|
|
157
|
+
mockRestService.patch.mockResolvedValue(mockResponse({}));
|
|
158
|
+
|
|
159
|
+
const result = await securityService.updateUser(mockUser);
|
|
160
|
+
|
|
161
|
+
expect(result).toBeDefined();
|
|
162
|
+
expect(mockRestService.patch).toHaveBeenCalledWith("/Users('testuser')", mockUser.body);
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('should update user password', async () => {
|
|
166
|
+
mockRestService.patch.mockResolvedValue(mockResponse({}));
|
|
167
|
+
|
|
168
|
+
const result = await securityService.updateUserPassword('testuser', 'newpassword123');
|
|
169
|
+
|
|
170
|
+
expect(result).toBeDefined();
|
|
171
|
+
expect(mockRestService.patch).toHaveBeenCalledWith(
|
|
172
|
+
"/Users('testuser')",
|
|
173
|
+
JSON.stringify({ Password: 'newpassword123' })
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('should delete user', async () => {
|
|
178
|
+
// Mock determineActualUserName call
|
|
179
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
180
|
+
value: [{ Name: 'testuser' }]
|
|
181
|
+
}));
|
|
182
|
+
mockRestService.delete.mockResolvedValue(mockResponse({}));
|
|
183
|
+
|
|
184
|
+
const result = await securityService.deleteUser('testuser');
|
|
185
|
+
|
|
186
|
+
expect(result).toBeDefined();
|
|
187
|
+
expect(mockRestService.delete).toHaveBeenCalledWith("/Users('testuser')");
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
test('should check if user exists', async () => {
|
|
191
|
+
const userData = {
|
|
192
|
+
Name: 'testuser',
|
|
193
|
+
Groups: [{ Name: 'TM1ConnectionPool' }]
|
|
194
|
+
};
|
|
195
|
+
mockRestService.get.mockResolvedValue(mockResponse(userData));
|
|
196
|
+
|
|
197
|
+
// Mock User.fromDict
|
|
198
|
+
const mockUserFromDict = jest.fn().mockReturnValue(mockUser);
|
|
199
|
+
(User as any).fromDict = mockUserFromDict;
|
|
200
|
+
|
|
201
|
+
const result = await securityService.userExists('testuser');
|
|
202
|
+
|
|
203
|
+
expect(result).toBe(true);
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
test('should return false when user does not exist', async () => {
|
|
207
|
+
mockRestService.get.mockRejectedValue(new Error('User not found'));
|
|
208
|
+
|
|
209
|
+
const result = await securityService.userExists('nonexistent');
|
|
210
|
+
|
|
211
|
+
expect(result).toBe(false);
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test('should check if group exists', async () => {
|
|
215
|
+
mockRestService.get.mockResolvedValue(mockResponse({ value: [{ Name: 'TestGroup' }] }));
|
|
216
|
+
|
|
217
|
+
const result = await securityService.groupExists('testgroup');
|
|
218
|
+
|
|
219
|
+
expect(result).toBe(true);
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test('should return false when group does not exist', async () => {
|
|
223
|
+
mockRestService.get.mockRejectedValue(new Error('Group not found'));
|
|
224
|
+
|
|
225
|
+
const result = await securityService.groupExists('nonexistent');
|
|
226
|
+
|
|
227
|
+
expect(result).toBe(false);
|
|
228
|
+
});
|
|
229
|
+
});
|
|
230
|
+
|
|
231
|
+
describe('Group Operations', () => {
|
|
232
|
+
test('should create group successfully', async () => {
|
|
233
|
+
mockRestService.post.mockResolvedValue(mockResponse({}));
|
|
234
|
+
|
|
235
|
+
const result = await securityService.createGroup('TestGroup');
|
|
236
|
+
|
|
237
|
+
expect(result).toBeDefined();
|
|
238
|
+
expect(mockRestService.post).toHaveBeenCalledWith('/Groups', JSON.stringify({ Name: 'TestGroup' }));
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
test('should delete group', async () => {
|
|
242
|
+
// Mock determineActualGroupName call
|
|
243
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
244
|
+
value: [{ Name: 'TestGroup' }]
|
|
245
|
+
}));
|
|
246
|
+
mockRestService.delete.mockResolvedValue(mockResponse({}));
|
|
247
|
+
|
|
248
|
+
const result = await securityService.deleteGroup('TestGroup');
|
|
249
|
+
|
|
250
|
+
expect(result).toBeDefined();
|
|
251
|
+
expect(mockRestService.delete).toHaveBeenCalledWith("/Groups('TestGroup')");
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
test('should get all group names', async () => {
|
|
255
|
+
const groupsData = {
|
|
256
|
+
value: [
|
|
257
|
+
{ Name: 'ADMIN' },
|
|
258
|
+
{ Name: 'TM1ConnectionPool' },
|
|
259
|
+
{ Name: 'PowerUser' }
|
|
260
|
+
]
|
|
261
|
+
};
|
|
262
|
+
mockRestService.get.mockResolvedValue(mockResponse(groupsData));
|
|
263
|
+
|
|
264
|
+
const result = await securityService.getGroupNames();
|
|
265
|
+
|
|
266
|
+
expect(result).toEqual(['ADMIN', 'TM1ConnectionPool', 'PowerUser']);
|
|
267
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/Groups?$select=Name");
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test('should get users from group', async () => {
|
|
271
|
+
// Mock determineActualGroupName call
|
|
272
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
273
|
+
value: [{ Name: 'PowerUser' }]
|
|
274
|
+
}));
|
|
275
|
+
// Mock getUsersFromGroup call
|
|
276
|
+
const usersData = {
|
|
277
|
+
value: [
|
|
278
|
+
{ Name: 'admin' },
|
|
279
|
+
{ Name: 'poweruser1' },
|
|
280
|
+
{ Name: 'poweruser2' }
|
|
281
|
+
]
|
|
282
|
+
};
|
|
283
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse(usersData));
|
|
284
|
+
|
|
285
|
+
const result = await securityService.getUsersFromGroup('PowerUser');
|
|
286
|
+
|
|
287
|
+
expect(result).toEqual(['admin', 'poweruser1', 'poweruser2']);
|
|
288
|
+
});
|
|
289
|
+
|
|
290
|
+
test('should get groups for user', async () => {
|
|
291
|
+
// Mock determineActualUserName call
|
|
292
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
293
|
+
value: [{ Name: 'testuser' }]
|
|
294
|
+
}));
|
|
295
|
+
// Mock getGroups call
|
|
296
|
+
const groupsData = {
|
|
297
|
+
value: [
|
|
298
|
+
{ Name: 'TM1ConnectionPool' },
|
|
299
|
+
{ Name: 'PowerUser' }
|
|
300
|
+
]
|
|
301
|
+
};
|
|
302
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse(groupsData));
|
|
303
|
+
|
|
304
|
+
const result = await securityService.getGroups('testuser');
|
|
305
|
+
|
|
306
|
+
expect(result).toEqual(['TM1ConnectionPool', 'PowerUser']);
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
test('should get all groups when no user specified', async () => {
|
|
310
|
+
const allGroupsData = {
|
|
311
|
+
value: [
|
|
312
|
+
{ Name: 'ADMIN' },
|
|
313
|
+
{ Name: 'TM1ConnectionPool' },
|
|
314
|
+
{ Name: 'PowerUser' }
|
|
315
|
+
]
|
|
316
|
+
};
|
|
317
|
+
mockRestService.get.mockResolvedValue(mockResponse(allGroupsData));
|
|
318
|
+
|
|
319
|
+
const result = await securityService.getGroups();
|
|
320
|
+
|
|
321
|
+
expect(result).toEqual(['ADMIN', 'TM1ConnectionPool', 'PowerUser']);
|
|
322
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/Groups?$select=Name");
|
|
323
|
+
});
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
describe('User-Group Relationship Operations', () => {
|
|
327
|
+
test('should add user to multiple groups', async () => {
|
|
328
|
+
// Mock determineActualGroupName calls for both groups
|
|
329
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
330
|
+
value: [{ Name: 'PowerUser' }]
|
|
331
|
+
}));
|
|
332
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
333
|
+
value: [{ Name: 'testuser' }]
|
|
334
|
+
}));
|
|
335
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
336
|
+
value: [{ Name: 'DataEntry' }]
|
|
337
|
+
}));
|
|
338
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
339
|
+
value: [{ Name: 'testuser' }]
|
|
340
|
+
}));
|
|
341
|
+
mockRestService.post.mockResolvedValue(mockResponse({}));
|
|
342
|
+
|
|
343
|
+
const groupNames = ['PowerUser', 'DataEntry'];
|
|
344
|
+
const results = await securityService.addUserToGroups('testuser', groupNames);
|
|
345
|
+
|
|
346
|
+
expect(results).toHaveLength(2);
|
|
347
|
+
expect(mockRestService.post).toHaveBeenCalledTimes(2);
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
test('should add user to single group', async () => {
|
|
351
|
+
// Mock determineActualGroupName call
|
|
352
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
353
|
+
value: [{ Name: 'PowerUser' }]
|
|
354
|
+
}));
|
|
355
|
+
// Mock determineActualUserName call
|
|
356
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
357
|
+
value: [{ Name: 'testuser' }]
|
|
358
|
+
}));
|
|
359
|
+
mockRestService.post.mockResolvedValue(mockResponse({}));
|
|
360
|
+
|
|
361
|
+
const result = await securityService.addUserToGroup('PowerUser', 'testuser');
|
|
362
|
+
|
|
363
|
+
expect(result).toBeDefined();
|
|
364
|
+
});
|
|
365
|
+
|
|
366
|
+
test('should remove user from group', async () => {
|
|
367
|
+
// Mock determineActualGroupName call
|
|
368
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
369
|
+
value: [{ Name: 'PowerUser' }]
|
|
370
|
+
}));
|
|
371
|
+
// Mock determineActualUserName call
|
|
372
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
373
|
+
value: [{ Name: 'testuser' }]
|
|
374
|
+
}));
|
|
375
|
+
mockRestService.delete.mockResolvedValue(mockResponse({}));
|
|
376
|
+
|
|
377
|
+
const result = await securityService.removeUserFromGroup('PowerUser', 'testuser');
|
|
378
|
+
|
|
379
|
+
expect(result).toBeDefined();
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
test('should handle empty group list when adding user to groups', async () => {
|
|
383
|
+
const results = await securityService.addUserToGroups('testuser', []);
|
|
384
|
+
|
|
385
|
+
expect(results).toEqual([]);
|
|
386
|
+
expect(mockRestService.post).not.toHaveBeenCalled();
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
describe('User and Group Listing Operations', () => {
|
|
391
|
+
test('should get all user names', async () => {
|
|
392
|
+
const usersData = {
|
|
393
|
+
value: [
|
|
394
|
+
{ Name: 'admin' },
|
|
395
|
+
{ Name: 'user1' },
|
|
396
|
+
{ Name: 'user2' }
|
|
397
|
+
]
|
|
398
|
+
};
|
|
399
|
+
mockRestService.get.mockResolvedValue(mockResponse(usersData));
|
|
400
|
+
|
|
401
|
+
const result = await securityService.getUserNames();
|
|
402
|
+
|
|
403
|
+
expect(result).toEqual(['admin', 'user1', 'user2']);
|
|
404
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/Users?$select=Name");
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
test('should get all users with full details', async () => {
|
|
408
|
+
const usersData = {
|
|
409
|
+
value: [
|
|
410
|
+
{ Name: 'admin', Groups: [{ Name: 'ADMIN' }] },
|
|
411
|
+
{ Name: 'user1', Groups: [{ Name: 'PowerUser' }] }
|
|
412
|
+
]
|
|
413
|
+
};
|
|
414
|
+
mockRestService.get.mockResolvedValue(mockResponse(usersData));
|
|
415
|
+
|
|
416
|
+
const mockUserFromDict = jest.fn().mockImplementation((data) => ({ name: data.Name }));
|
|
417
|
+
(User as any).fromDict = mockUserFromDict;
|
|
418
|
+
|
|
419
|
+
const result = await securityService.getAllUsers();
|
|
420
|
+
|
|
421
|
+
expect(result).toHaveLength(2);
|
|
422
|
+
expect(mockUserFromDict).toHaveBeenCalledTimes(2);
|
|
423
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/Users?$select=Name,FriendlyName,Password,Type,Enabled&$expand=Groups");
|
|
424
|
+
});
|
|
425
|
+
});
|
|
426
|
+
|
|
427
|
+
describe('Security Configuration Operations', () => {
|
|
428
|
+
test('should get security refresh time', async () => {
|
|
429
|
+
mockRestService.get.mockResolvedValue(mockResponse({ Value: 300 }));
|
|
430
|
+
|
|
431
|
+
const result = await securityService.getSecurityRefreshTime();
|
|
432
|
+
|
|
433
|
+
expect(result).toBe(300);
|
|
434
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/StaticConfiguration/ServerSettings('SecurityRefreshTime')");
|
|
435
|
+
});
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
describe('Error Handling', () => {
|
|
441
|
+
test('should handle user creation errors', async () => {
|
|
442
|
+
const error = new Error('User already exists');
|
|
443
|
+
mockRestService.post.mockRejectedValue(error);
|
|
444
|
+
|
|
445
|
+
await expect(securityService.createUser(mockUser)).rejects.toThrow('User already exists');
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
test('should handle user retrieval errors', async () => {
|
|
449
|
+
const error = new Error('User not found');
|
|
450
|
+
mockRestService.get.mockRejectedValue(error);
|
|
451
|
+
|
|
452
|
+
await expect(securityService.getUser('nonexistent')).rejects.toThrow('User not found');
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
test('should handle group creation errors', async () => {
|
|
456
|
+
const error = new Error('Group already exists');
|
|
457
|
+
mockRestService.post.mockRejectedValue(error);
|
|
458
|
+
|
|
459
|
+
await expect(securityService.createGroup('ExistingGroup')).rejects.toThrow('Group already exists');
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
describe('Edge Cases and Special Scenarios', () => {
|
|
464
|
+
test('should handle empty results gracefully', async () => {
|
|
465
|
+
mockRestService.get.mockResolvedValue(mockResponse({ value: [] }));
|
|
466
|
+
|
|
467
|
+
const userNames = await securityService.getUserNames();
|
|
468
|
+
const groupNames = await securityService.getGroupNames();
|
|
469
|
+
const usersFromGroup = await securityService.getUsersFromGroup('EmptyGroup');
|
|
470
|
+
|
|
471
|
+
expect(userNames).toEqual([]);
|
|
472
|
+
expect(groupNames).toEqual([]);
|
|
473
|
+
expect(usersFromGroup).toEqual([]);
|
|
474
|
+
});
|
|
475
|
+
|
|
476
|
+
test('should handle special characters in names', async () => {
|
|
477
|
+
const specialName = "user@domain.com";
|
|
478
|
+
// Mock determineActualGroupName call
|
|
479
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
480
|
+
value: [{ Name: 'Domain\\Group' }]
|
|
481
|
+
}));
|
|
482
|
+
// Mock determineActualUserName call
|
|
483
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
484
|
+
value: [{ Name: specialName }]
|
|
485
|
+
}));
|
|
486
|
+
mockRestService.post.mockResolvedValue(mockResponse({}));
|
|
487
|
+
|
|
488
|
+
await securityService.addUserToGroup('Domain\\Group', specialName);
|
|
489
|
+
|
|
490
|
+
// The formatUrl function URL-encodes backslashes, so expect the encoded version
|
|
491
|
+
expect(mockRestService.post).toHaveBeenCalledWith(
|
|
492
|
+
"/Groups('Domain%5CGroup')/Users",
|
|
493
|
+
JSON.stringify({ '@odata.id': `Users('${specialName}')` })
|
|
494
|
+
);
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
test('should handle case sensitivity in group operations', async () => {
|
|
498
|
+
// Mock determineActualGroupName calls for both groups
|
|
499
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
500
|
+
value: [{ Name: 'admin' }]
|
|
501
|
+
}));
|
|
502
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({ value: [] }));
|
|
503
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
504
|
+
value: [{ Name: 'ADMIN' }]
|
|
505
|
+
}));
|
|
506
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({ value: [] }));
|
|
507
|
+
|
|
508
|
+
await securityService.getUsersFromGroup('admin');
|
|
509
|
+
await securityService.getUsersFromGroup('ADMIN');
|
|
510
|
+
|
|
511
|
+
expect(mockRestService.get).toHaveBeenCalledTimes(4);
|
|
512
|
+
});
|
|
513
|
+
|
|
514
|
+
test('should handle null and undefined parameters', async () => {
|
|
515
|
+
mockRestService.get.mockResolvedValue(mockResponse({ value: [] }));
|
|
516
|
+
|
|
517
|
+
// These should not throw errors
|
|
518
|
+
await expect(securityService.getGroups(undefined)).resolves.toBeDefined();
|
|
519
|
+
|
|
520
|
+
expect(mockRestService.get).toHaveBeenCalledWith("/Groups?$select=Name");
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
test('should handle large user/group lists', async () => {
|
|
524
|
+
const largeUserList = Array.from({ length: 10000 }, (_, i) => ({ Name: `user${i}` }));
|
|
525
|
+
mockRestService.get.mockResolvedValue(mockResponse({ value: largeUserList }));
|
|
526
|
+
|
|
527
|
+
const result = await securityService.getUserNames();
|
|
528
|
+
|
|
529
|
+
expect(result).toHaveLength(10000);
|
|
530
|
+
expect(result[0]).toBe('user0');
|
|
531
|
+
expect(result[9999]).toBe('user9999');
|
|
532
|
+
});
|
|
533
|
+
});
|
|
534
|
+
|
|
535
|
+
describe('Security Integration Patterns', () => {
|
|
536
|
+
test('should support user lifecycle management', async () => {
|
|
537
|
+
// Mock for addUserToGroup - determineActualGroupName call
|
|
538
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
539
|
+
value: [{ Name: 'PowerUser' }]
|
|
540
|
+
}));
|
|
541
|
+
// Mock for addUserToGroup - determineActualUserName call
|
|
542
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
543
|
+
value: [{ Name: 'testuser' }]
|
|
544
|
+
}));
|
|
545
|
+
// Mock for removeUserFromGroup - determineActualGroupName call
|
|
546
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
547
|
+
value: [{ Name: 'PowerUser' }]
|
|
548
|
+
}));
|
|
549
|
+
// Mock for removeUserFromGroup - determineActualUserName call
|
|
550
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
551
|
+
value: [{ Name: 'testuser' }]
|
|
552
|
+
}));
|
|
553
|
+
// Mock for deleteUser - determineActualUserName call
|
|
554
|
+
mockRestService.get.mockResolvedValueOnce(mockResponse({
|
|
555
|
+
value: [{ Name: 'testuser' }]
|
|
556
|
+
}));
|
|
557
|
+
|
|
558
|
+
mockRestService.post.mockResolvedValue(mockResponse({}));
|
|
559
|
+
mockRestService.patch.mockResolvedValue(mockResponse({}));
|
|
560
|
+
mockRestService.delete.mockResolvedValue(mockResponse({}));
|
|
561
|
+
|
|
562
|
+
// Create user
|
|
563
|
+
await securityService.createUser(mockUser);
|
|
564
|
+
|
|
565
|
+
// Add to group
|
|
566
|
+
await securityService.addUserToGroup('PowerUser', 'testuser');
|
|
567
|
+
|
|
568
|
+
// Update password
|
|
569
|
+
await securityService.updateUserPassword('testuser', 'newpassword');
|
|
570
|
+
|
|
571
|
+
// Remove from group
|
|
572
|
+
await securityService.removeUserFromGroup('PowerUser', 'testuser');
|
|
573
|
+
|
|
574
|
+
// Delete user
|
|
575
|
+
await securityService.deleteUser('testuser');
|
|
576
|
+
|
|
577
|
+
expect(mockRestService.post).toHaveBeenCalledTimes(2);
|
|
578
|
+
expect(mockRestService.patch).toHaveBeenCalledTimes(1);
|
|
579
|
+
expect(mockRestService.delete).toHaveBeenCalledTimes(2);
|
|
580
|
+
});
|
|
581
|
+
});
|
|
582
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jest setup file for tm1npm tests
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Increase timeout for integration tests
|
|
6
|
+
jest.setTimeout(30000);
|
|
7
|
+
|
|
8
|
+
// Setup global test configuration
|
|
9
|
+
beforeAll(() => {
|
|
10
|
+
// Suppress console logs during tests unless explicitly needed
|
|
11
|
+
if (!process.env.VERBOSE_TESTS) {
|
|
12
|
+
console.log = jest.fn();
|
|
13
|
+
console.warn = jest.fn();
|
|
14
|
+
console.info = jest.fn();
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
afterAll(() => {
|
|
19
|
+
// Cleanup any global resources if needed
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// Custom Jest matchers for TM1 responses
|
|
23
|
+
expect.extend({
|
|
24
|
+
toBeValidTM1Response(received: any) {
|
|
25
|
+
const pass = received &&
|
|
26
|
+
typeof received === 'object' &&
|
|
27
|
+
received.status >= 200 &&
|
|
28
|
+
received.status < 300;
|
|
29
|
+
|
|
30
|
+
if (pass) {
|
|
31
|
+
return {
|
|
32
|
+
message: () => `expected ${received} not to be a valid TM1 response`,
|
|
33
|
+
pass: true,
|
|
34
|
+
};
|
|
35
|
+
} else {
|
|
36
|
+
return {
|
|
37
|
+
message: () => `expected ${received} to be a valid TM1 response`,
|
|
38
|
+
pass: false,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
});
|