From d360e5bdc11d101c218c0280eadea3548c554001 Mon Sep 17 00:00:00 2001 From: Mehmet Cevheri BOZOGLAN Date: Tue, 19 Nov 2024 02:33:36 +0300 Subject: [PATCH] UnitTest and StorageCache improvement (#28) * test: add account repository test * fix: register json data * chore: sget_torage package erase * test: add account test * fix: flutter analyze issues * feat: IMPORTANT feat... add AppLocalStorage management. removed get_storage, path_provider, synchronized and fake_async * test: data/models coverage %100 OK - +128 ~12: All tests passed! * test: when save button clicked, snackbar(timer) problem fixed. +130 ~10: All tests passed! * chore: LocalStorage cache using increased. Use AppLocalStorage singleton instead of storage cache * docs: add changelog template --- CHANGELOG.md | 79 + docs/unittest.excalidraw | 5013 +++++++++++++++++ lib/data/http_utils.dart | 6 +- lib/data/models/authorities.dart | 21 +- lib/main/main_local.dart | 6 +- lib/main/main_prod.dart | 5 +- .../common_widgets/drawer/drawer_widget.dart | 3 +- .../screen/user/edit/edit_form_widget.dart | 1 + lib/utils/security_utils.dart | 5 +- test/data/model/authority_test.dart | 47 +- test/data/model/change_password_test.dart | 66 +- test/data/model/city_test.dart | 41 +- test/data/model/customer_test.dart | 23 + test/data/model/district_test.dart | 84 +- test/data/model/jwt_token_test.dart | 51 + test/data/model/menu_test.dart | 15 + test/data/model/user_jwt_test.dart | 102 + test/data/model/user_test.dart | 31 +- .../repository/account_repository_test.dart | 19 +- test/fake/city_data.dart | 6 +- test/fake/user_data.dart | 6 +- test/presentation/blocs/user_bloc_test.dart | 15 +- .../screen/account/account_screen_test.dart | 2 +- .../screen/user/create_user_screen_test.dart | 2 +- .../screen/user/edit_user_screen_test.dart | 89 +- .../screen/user/list_user_screen_test.dart | 2 +- test/test_utils.dart | 17 +- 27 files changed, 5613 insertions(+), 144 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 docs/unittest.excalidraw create mode 100644 test/data/model/user_jwt_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..95c0f55 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,79 @@ +# Flutter Template Changelog + +@formatter:off +* All notable changes to this project will be documented in this file. +* The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +* This template is based on [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/). + +### Guiding Principles + +- Changelogs are for humans, not machines. +- There should be an entry for every single version. +- The same types of changes should be grouped. +- Versions and sections should be linkable. +- The latest version comes first. +- The release date of each version is displayed. +- Mention whether you follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +### Types of changes + +- `Added` for new features. +- `Changed` for changes in existing functionality. +- `Deprecated` for soon-to-be removed features. +- `Removed` for now removed features. +- `Fixed` for any bug fixes. +- `Security` in case of vulnerabilities. +- `Performance` for improvements in performance. +- `Style` for changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) +- `Docs` for documentation only changes +- `Build` for changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) + +### [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) + +A specification for adding human and machine readable meaning to commit messages. + +- `feat` a new feature +- `fix` a bug fix +- `docs` documentation only changes +- `style` changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc) +- `refactor` a code change that neither fixes a bug nor adds a feature +- `perf` a code change that improves performance +- `test` adding missing tests or correcting existing tests +- `build` changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm) +- `chore` other changes +- **BREAKING CHANGE**: a commit that has a footer BREAKING CHANGE:, or appends a ! after the type/scope, introduces a breaking API change (correlating with MAJOR in Semantic Versioning). A BREAKING CHANGE can be part of commits of any type. + +--- + +### Well-known flutter-analyzer issues + + +--- + +### Appendix Issues + + +--- + +@formatter:off + +# Releases + +## [Unreleased]() +### Added +- None + +### Changed +- None + +### Fixed +- None + +### Removed +- None + +### BREAKING CHANGES +- None + + +--- diff --git a/docs/unittest.excalidraw b/docs/unittest.excalidraw new file mode 100644 index 0000000..9779bbe --- /dev/null +++ b/docs/unittest.excalidraw @@ -0,0 +1,5013 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://marketplace.visualstudio.com/items?itemName=pomdtr.excalidraw-editor", + "elements": [ + { + "id": "pYTVUuejMoPMOY73hdNYH", + "type": "rectangle", + "x": 265, + "y": -3282, + "width": 243.00000000000003, + "height": 77.00000000000003, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 77448442, + "version": 254, + "versionNonce": 842636710, + "isDeleted": false, + "boundElements": null, + "updated": 1731962229435, + "link": null, + "locked": false + }, + { + "id": "k0tqSBDKhPFGF14dIQnzc", + "type": "rectangle", + "x": 1547, + "y": -3028, + "width": 243.00000000000003, + "height": 77.00000000000003, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1525138726, + "version": 387, + "versionNonce": 1646602726, + "isDeleted": false, + "boundElements": [ + { + "id": "D89HoGofnJl3Z5t7vgoGd", + "type": "arrow" + }, + { + "id": "IgDR8j0FZ3WvtOvUSx0f8", + "type": "arrow" + }, + { + "id": "MrvBYBlQgEscr7LN-T9Xj", + "type": "arrow" + } + ], + "updated": 1731962225386, + "link": null, + "locked": false + }, + { + "id": "URlHpkvQ897XvfNefBqx5", + "type": "rectangle", + "x": 594, + "y": -2918, + "width": 243.00000000000003, + "height": 77.00000000000003, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 2063317946, + "version": 490, + "versionNonce": 1618825786, + "isDeleted": false, + "boundElements": [ + { + "id": "JkHQbGB0F3Ha66-jmTBaO", + "type": "arrow" + }, + { + "id": "DaK6bg_30iYJZaXc1haIV", + "type": "arrow" + }, + { + "id": "D89HoGofnJl3Z5t7vgoGd", + "type": "arrow" + }, + { + "id": "0x80WnmJOvmDYepErQnBx", + "type": "arrow" + }, + { + "id": "FLe4Fy761MGtkmboMWfOO", + "type": "arrow" + }, + { + "id": "2ACIv3vs1H1vlU7wJCNas", + "type": "arrow" + }, + { + "id": "YpKimDWKhrbP18wiz0qx1", + "type": "arrow" + }, + { + "id": "oQS3xjCotbyszhXpx-BLH", + "type": "arrow" + }, + { + "id": "pO4Z_WFw4GttS3eT1mrGg", + "type": "arrow" + } + ], + "updated": 1731962386740, + "link": null, + "locked": false + }, + { + "id": "ZoHqsxxoWgZCqK0eYgRCO", + "type": "rectangle", + "x": 615, + "y": -3542, + "width": 243.00000000000003, + "height": 77.00000000000003, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1538242022, + "version": 622, + "versionNonce": 273597798, + "isDeleted": false, + "boundElements": [ + { + "id": "Mpz6Qvtma3M0b9CyQDCVL", + "type": "arrow" + }, + { + "id": "JkHQbGB0F3Ha66-jmTBaO", + "type": "arrow" + }, + { + "id": "gJnkI4rzdPtGwfsp_cc6h", + "type": "arrow" + }, + { + "id": "JYIFp5brFph_akt8NRLVe", + "type": "arrow" + }, + { + "id": "2ACIv3vs1H1vlU7wJCNas", + "type": "arrow" + }, + { + "id": "pO4Z_WFw4GttS3eT1mrGg", + "type": "arrow" + }, + { + "id": "RSKlo952T-s09BcwCUovi", + "type": "arrow" + } + ], + "updated": 1731962391284, + "link": null, + "locked": false + }, + { + "id": "f2EOun2JPCq-bxulS1kjn", + "type": "rectangle", + "x": 1369, + "y": -3284, + "width": 243.00000000000003, + "height": 77.00000000000003, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 469562150, + "version": 408, + "versionNonce": 1467107558, + "isDeleted": false, + "boundElements": [ + { + "id": "0x80WnmJOvmDYepErQnBx", + "type": "arrow" + }, + { + "id": "IgDR8j0FZ3WvtOvUSx0f8", + "type": "arrow" + }, + { + "id": "MfCU-YPzf3WlqyTlYX7GK", + "type": "arrow" + }, + { + "id": "pTBZAA3QL_uFyK6o8NL7Z", + "type": "arrow" + }, + { + "id": "YpKimDWKhrbP18wiz0qx1", + "type": "arrow" + }, + { + "id": "rTEQzSB_1WyI2N_H_-1my", + "type": "arrow" + }, + { + "id": "uH5tSdNTUI4qLowcXyWO7", + "type": "arrow" + }, + { + "id": "oQS3xjCotbyszhXpx-BLH", + "type": "arrow" + } + ], + "updated": 1731962382354, + "link": null, + "locked": false + }, + { + "id": "FTCcYxUVYUZruvq9oZxL_", + "type": "rectangle", + "x": 942, + "y": -2223, + "width": 243.00000000000003, + "height": 77.00000000000003, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 621685990, + "version": 606, + "versionNonce": 781399674, + "isDeleted": false, + "boundElements": [ + { + "id": "9NMl6F2JSDc_WxAJcDSdX", + "type": "arrow" + }, + { + "id": "DHUw95Hb-z5Qr50c8xscr", + "type": "arrow" + }, + { + "id": "s5kV5EKlOOgHtrRecLw9n", + "type": "arrow" + } + ], + "updated": 1731962721874, + "link": null, + "locked": false + }, + { + "id": "VUBbaLLX-5jAeDSgQuwZs", + "type": "rectangle", + "x": 1183, + "y": -3555, + "width": 243.00000000000003, + "height": 77.00000000000003, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 509568762, + "version": 314, + "versionNonce": 1025796198, + "isDeleted": false, + "boundElements": [ + { + "id": "Mpz6Qvtma3M0b9CyQDCVL", + "type": "arrow" + }, + { + "id": "DaK6bg_30iYJZaXc1haIV", + "type": "arrow" + }, + { + "id": "MfCU-YPzf3WlqyTlYX7GK", + "type": "arrow" + } + ], + "updated": 1731962225386, + "link": null, + "locked": false + }, + { + "id": "SudY9_HogmAeo5AJYL1ta", + "type": "text", + "x": 326, + "y": -3249, + "width": 121.27986145019531, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1715589414, + "version": 147, + "versionNonce": 1640167654, + "isDeleted": false, + "boundElements": null, + "updated": 1731962229435, + "link": null, + "locked": false, + "text": "presentation", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "presentation", + "lineHeight": 1.25 + }, + { + "id": "l6_Lg5IIANg6zayot1PfL", + "type": "text", + "x": 1252, + "y": -3523, + "width": 54.57994079589844, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 2136698490, + "version": 71, + "versionNonce": 1116105638, + "isDeleted": false, + "boundElements": null, + "updated": 1731962225386, + "link": null, + "locked": false, + "text": "config", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "config", + "lineHeight": 1.25 + }, + { + "id": "eZeTQsuixbmWKdCxqE_aX", + "type": "text", + "x": 1638, + "y": -2999, + "width": 62.179931640625, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1254113830, + "version": 188, + "versionNonce": 1612974522, + "isDeleted": false, + "boundElements": null, + "updated": 1731962225386, + "link": null, + "locked": false, + "text": "models", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "models", + "lineHeight": 1.25 + }, + { + "id": "090Whj3czq3Pl-LNKq0tB", + "type": "text", + "x": 686, + "y": -2889, + "width": 50.47996520996094, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 276460774, + "version": 291, + "versionNonce": 801006202, + "isDeleted": false, + "boundElements": null, + "updated": 1731962247368, + "link": null, + "locked": false, + "text": "BLoC", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "BLoC", + "lineHeight": 1.25 + }, + { + "id": "VNzQvCFa5GHExlQti50Pl", + "type": "text", + "x": 706, + "y": -3514, + "width": 71.57992553710938, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1086030714, + "version": 432, + "versionNonce": 760121510, + "isDeleted": false, + "boundElements": null, + "updated": 1731962243118, + "link": null, + "locked": false, + "text": "screens", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "screens", + "lineHeight": 1.25 + }, + { + "id": "RG9ef-JGMDTtGDaZtzBc_", + "type": "text", + "x": 1460, + "y": -3255, + "width": 96.07987976074219, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1692121658, + "version": 195, + "versionNonce": 1743796774, + "isDeleted": false, + "boundElements": null, + "updated": 1731962225386, + "link": null, + "locked": false, + "text": "repository", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "repository", + "lineHeight": 1.25 + }, + { + "id": "SLqaf6dT5GHuhxbniWcvS", + "type": "text", + "x": 1033, + "y": -2194, + "width": 96.07987976074219, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 467926138, + "version": 390, + "versionNonce": 730164070, + "isDeleted": false, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "text": "repository", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "repository", + "lineHeight": 1.25 + }, + { + "id": "Mpz6Qvtma3M0b9CyQDCVL", + "type": "arrow", + "x": 865, + "y": -3490.9340406563997, + "width": 311, + "height": 28.0224040477342, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 952204090, + "version": 493, + "versionNonce": 1370392678, + "isDeleted": false, + "boundElements": null, + "updated": 1731962243118, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 311, + -28.0224040477342 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ZoHqsxxoWgZCqK0eYgRCO", + "focus": 0.4873894221720307, + "gap": 7 + }, + "endBinding": { + "elementId": "VUBbaLLX-5jAeDSgQuwZs", + "focus": 0.2838321099190664, + "gap": 7 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "JkHQbGB0F3Ha66-jmTBaO", + "type": "arrow", + "x": 799.7604136151409, + "y": -3464, + "width": 74.43092450750908, + "height": 536, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 932709818, + "version": 937, + "versionNonce": 1271892986, + "isDeleted": false, + "boundElements": null, + "updated": 1731962247384, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -74.43092450750908, + 536 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ZoHqsxxoWgZCqK0eYgRCO", + "focus": -0.5419593817856687, + "gap": 1 + }, + "endBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": 0.024396474645548602, + "gap": 10 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "DaK6bg_30iYJZaXc1haIV", + "type": "arrow", + "x": 846, + "y": -2873.2745414482824, + "width": 419.4359193226462, + "height": 595.725458551718, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1726191462, + "version": 471, + "versionNonce": 1237603706, + "isDeleted": false, + "boundElements": null, + "updated": 1731962247384, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 419.4359193226462, + -595.725458551718 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": 0.9076507722237661, + "gap": 9 + }, + "endBinding": { + "elementId": "VUBbaLLX-5jAeDSgQuwZs", + "focus": 0.03782109818557192, + "gap": 9 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "D89HoGofnJl3Z5t7vgoGd", + "type": "arrow", + "x": 841, + "y": -2858.537240721086, + "width": 689, + "height": 140.79046078299052, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1736334330, + "version": 670, + "versionNonce": 2100608762, + "isDeleted": false, + "boundElements": null, + "updated": 1731962247384, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 689, + -140.79046078299052 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": 0.7359766447145086, + "gap": 4 + }, + "endBinding": { + "elementId": "k0tqSBDKhPFGF14dIQnzc", + "focus": 0.6020911127707244, + "gap": 17 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "0x80WnmJOvmDYepErQnBx", + "type": "arrow", + "x": 844, + "y": -2876.0853263270997, + "width": 517, + "height": 357.53839130675397, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 907031654, + "version": 656, + "versionNonce": 867747962, + "isDeleted": false, + "boundElements": null, + "updated": 1731962247384, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 517, + -357.53839130675397 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": 0.7531571184047579, + "gap": 7 + }, + "endBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": 0.6340030131648483, + "gap": 8 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "IgDR8j0FZ3WvtOvUSx0f8", + "type": "arrow", + "x": 1495.4290192343638, + "y": -3196, + "width": 124.90281697976593, + "height": 163, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 31986470, + "version": 321, + "versionNonce": 848323558, + "isDeleted": false, + "boundElements": null, + "updated": 1731962225386, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 124.90281697976593, + 163 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": 0.21713810316139762, + "gap": 11 + }, + "endBinding": { + "elementId": "k0tqSBDKhPFGF14dIQnzc", + "focus": -0.09824534866132201, + "gap": 5 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "MfCU-YPzf3WlqyTlYX7GK", + "type": "arrow", + "x": 1506, + "y": -3295, + "width": 168, + "height": 172, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 128151782, + "version": 50, + "versionNonce": 1208268154, + "isDeleted": false, + "boundElements": null, + "updated": 1731962225386, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -168, + -172 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": 0.4013008843089965, + "gap": 11 + }, + "endBinding": { + "elementId": "VUBbaLLX-5jAeDSgQuwZs", + "focus": 0.09332748666228166, + "gap": 11 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "X0o9ubJgmB_g9-GxGw7sP", + "type": "rectangle", + "x": 1178, + "y": -2742, + "width": 189, + "height": 62, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1341268582, + "version": 105, + "versionNonce": 1173545382, + "isDeleted": false, + "boundElements": [ + { + "id": "FLe4Fy761MGtkmboMWfOO", + "type": "arrow" + }, + { + "id": "MrvBYBlQgEscr7LN-T9Xj", + "type": "arrow" + }, + { + "id": "pTBZAA3QL_uFyK6o8NL7Z", + "type": "arrow" + }, + { + "id": "gJnkI4rzdPtGwfsp_cc6h", + "type": "arrow" + } + ], + "updated": 1731962259550, + "link": null, + "locked": false + }, + { + "id": "Rmd1jjMYJBwW2xmLgd81j", + "type": "text", + "x": 1238, + "y": -2716, + "width": 43.159942626953125, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1865784570, + "version": 68, + "versionNonce": 1880880870, + "isDeleted": false, + "boundElements": null, + "updated": 1731962259551, + "link": null, + "locked": false, + "text": "utils", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "utils", + "lineHeight": 1.25 + }, + { + "id": "FLe4Fy761MGtkmboMWfOO", + "type": "arrow", + "x": 756.0535099967108, + "y": -2835, + "width": 414.9464900032892, + "height": 93.98074767548178, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1471953338, + "version": 736, + "versionNonce": 121057318, + "isDeleted": false, + "boundElements": null, + "updated": 1731962259550, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 414.9464900032892, + 93.98074767548178 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": 0.5364409104541544, + "gap": 6 + }, + "endBinding": { + "elementId": "X0o9ubJgmB_g9-GxGw7sP", + "focus": 0.13416425140353064, + "gap": 7 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "MrvBYBlQgEscr7LN-T9Xj", + "type": "arrow", + "x": 1670.376179372676, + "y": -2939, + "width": 295.376179372676, + "height": 200.85213458238195, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 458018042, + "version": 241, + "versionNonce": 966385318, + "isDeleted": false, + "boundElements": null, + "updated": 1731962259551, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -295.376179372676, + 200.85213458238195 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "k0tqSBDKhPFGF14dIQnzc", + "focus": -0.43032450195111915, + "gap": 12 + }, + "endBinding": { + "elementId": "X0o9ubJgmB_g9-GxGw7sP", + "focus": 0.4466868155081083, + "gap": 8 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "pTBZAA3QL_uFyK6o8NL7Z", + "type": "arrow", + "x": 1450.4388765232743, + "y": -3196, + "width": 91.48366725102665, + "height": 449, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 56191866, + "version": 200, + "versionNonce": 822275366, + "isDeleted": false, + "boundElements": null, + "updated": 1731962259551, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -91.48366725102665, + 449 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": 0.22973283822417928, + "gap": 11 + }, + "endBinding": { + "elementId": "X0o9ubJgmB_g9-GxGw7sP", + "focus": 0.7847963040739186, + "gap": 5 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "gJnkI4rzdPtGwfsp_cc6h", + "type": "arrow", + "x": 848.5256883196287, + "y": -3455.0000000000005, + "width": 436.1777568790699, + "height": 702.0000000000005, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1947981114, + "version": 640, + "versionNonce": 1733974950, + "isDeleted": false, + "boundElements": null, + "updated": 1731962259551, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 436.1777568790699, + 702.0000000000005 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ZoHqsxxoWgZCqK0eYgRCO", + "focus": -0.5640497993620742, + "gap": 10 + }, + "endBinding": { + "elementId": "X0o9ubJgmB_g9-GxGw7sP", + "focus": 0.33666557053600793, + "gap": 11 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "ellipse", + "version": 1781, + "versionNonce": 1933386726, + "isDeleted": false, + "id": "-bHwg9yPLmf_ReAnvN2QZ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 0, + "angle": 0, + "x": 346.6213384181644, + "y": -3569.378661581836, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.75732316367123, + "height": 116.75732316367123, + "seed": 1932144870, + "groupIds": [ + "41qpLIKFwDKT5QLeQAjH0" + ], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "JYIFp5brFph_akt8NRLVe", + "type": "arrow" + }, + { + "id": "RSKlo952T-s09BcwCUovi", + "type": "arrow" + } + ], + "updated": 1731962391284, + "link": null, + "locked": false + }, + { + "type": "line", + "version": 2162, + "versionNonce": 1683036474, + "isDeleted": false, + "id": "tj5gPNVwQHW8D2Ug0YpLU", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 376.3074823453873, + "y": -3489.538311866634, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 54.3478260869565, + "height": 48.3951783478699, + "seed": 901719078, + "groupIds": [ + "mpgPTc-TdyWBioVF6srl0", + "41qpLIKFwDKT5QLeQAjH0" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1731962272833, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 6.0869565217391255, + -32.0690940859379 + ], + [ + 26.086956521739125, + -48.3951783478699 + ], + [ + 46.086956521739125, + -35.567540713494715 + ], + [ + 54.3478260869565, + -3.3299690403347313 + ], + [ + 0, + 0 + ] + ] + }, + { + "type": "ellipse", + "version": 1902, + "versionNonce": 1141760506, + "isDeleted": false, + "id": "3nmQykNP8TiM_5IhNDmzN", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 390.0532463186285, + "y": -3563.1719645040166, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 27.82608695652175, + "height": 24.347826086956616, + "seed": 399748966, + "groupIds": [ + "mpgPTc-TdyWBioVF6srl0", + "41qpLIKFwDKT5QLeQAjH0" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1731962272833, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3111, + "versionNonce": 1253282490, + "isDeleted": false, + "id": "P0H0MPu0jkyrrL6iKGBnW", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 381.6263163471826, + "y": -3483.828035495984, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 44.67994689941406, + "height": 25, + "seed": 901042854, + "groupIds": [ + "g1EwXbnl4WFPwtDoRBIa6", + "41qpLIKFwDKT5QLeQAjH0" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1731962272833, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "User", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "User", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "ellipse", + "version": 1932, + "versionNonce": 1674514086, + "isDeleted": false, + "id": "Y0k2cKsgPFLRdvYShC-Lc", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 0, + "angle": 0, + "x": 618.6213384181644, + "y": -2240.378661581836, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.75732316367123, + "height": 116.75732316367123, + "seed": 779122662, + "groupIds": [ + "PiSEXTNAUHugf3VIPaIRv" + ], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "9NMl6F2JSDc_WxAJcDSdX", + "type": "arrow" + } + ], + "updated": 1731962699883, + "link": null, + "locked": false + }, + { + "type": "line", + "version": 2312, + "versionNonce": 1403788582, + "isDeleted": false, + "id": "CGxZE1beXntPb6f7NY18x", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 648.3074823453874, + "y": -2160.538311866634, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 54.3478260869565, + "height": 48.3951783478699, + "seed": 148889978, + "groupIds": [ + "tbgieo-8-cSj0AYAKXh4P", + "PiSEXTNAUHugf3VIPaIRv" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 6.0869565217391255, + -32.0690940859379 + ], + [ + 26.086956521739125, + -48.3951783478699 + ], + [ + 46.086956521739125, + -35.567540713494715 + ], + [ + 54.3478260869565, + -3.3299690403347313 + ], + [ + 0, + 0 + ] + ] + }, + { + "type": "ellipse", + "version": 2052, + "versionNonce": 1069123686, + "isDeleted": false, + "id": "SiMlcjiYOo5oeGjh1EU2-", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 662.0532463186286, + "y": -2234.1719645040166, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 27.82608695652175, + "height": 24.347826086956616, + "seed": 1587841830, + "groupIds": [ + "tbgieo-8-cSj0AYAKXh4P", + "PiSEXTNAUHugf3VIPaIRv" + ], + "frameId": null, + "roundness": null, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 3261, + "versionNonce": 1970768806, + "isDeleted": false, + "id": "doYd06zdNXKr1uADld5S2", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 653.6263163471826, + "y": -2154.828035495984, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 44.67994689941406, + "height": 25, + "seed": 874095162, + "groupIds": [ + "JigLTGqMLJ4gYI4qr3jBl", + "PiSEXTNAUHugf3VIPaIRv" + ], + "frameId": null, + "roundness": null, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "User", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "User", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "id": "JYIFp5brFph_akt8NRLVe", + "type": "arrow", + "x": 467, + "y": -3465, + "width": 138, + "height": 13, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 182823994, + "version": 43, + "versionNonce": 1323761702, + "isDeleted": false, + "boundElements": null, + "updated": 1731962283065, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 138, + -13 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "-bHwg9yPLmf_ReAnvN2QZ", + "focus": 0.8840914906500092, + "gap": 18.822374680639527 + }, + "endBinding": { + "elementId": "ZoHqsxxoWgZCqK0eYgRCO", + "focus": -0.26253173739571994, + "gap": 10 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "2ACIv3vs1H1vlU7wJCNas", + "type": "arrow", + "x": 693, + "y": -3450, + "width": 4, + "height": 515, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 2006977382, + "version": 107, + "versionNonce": 1373486458, + "isDeleted": false, + "boundElements": null, + "updated": 1731962297635, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 4, + 515 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ZoHqsxxoWgZCqK0eYgRCO", + "focus": 0.36055734019911834, + "gap": 15 + }, + "endBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": -0.148350378229297, + "gap": 17 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "YpKimDWKhrbP18wiz0qx1", + "type": "arrow", + "x": 845, + "y": -2867, + "width": 566, + "height": 333, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 202647290, + "version": 62, + "versionNonce": 665627622, + "isDeleted": false, + "boundElements": null, + "updated": 1731962309501, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 566, + -333 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": 0.8063951293563907, + "gap": 8 + }, + "endBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": 0.01157420422325925, + "gap": 7 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "ellipse", + "version": 1960, + "versionNonce": 489123258, + "isDeleted": false, + "id": "MIk2ZQGpmDTLZDdlUN2ZO", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 0, + "angle": 0, + "x": 1799.6213384181644, + "y": -3329.378661581836, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.75732316367123, + "height": 116.75732316367123, + "seed": 1183197862, + "groupIds": [ + "E0QjzkoDqja29hhto95x6" + ], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "rTEQzSB_1WyI2N_H_-1my", + "type": "arrow" + }, + { + "id": "aVpZjPMmv5iWyUAETTFpE", + "type": "arrow" + }, + { + "id": "YsTCEwqvT61oXQFJUhhDh", + "type": "arrow" + }, + { + "id": "uH5tSdNTUI4qLowcXyWO7", + "type": "arrow" + } + ], + "updated": 1731962375781, + "link": null, + "locked": false + }, + { + "type": "line", + "version": 2252, + "versionNonce": 80746874, + "isDeleted": false, + "id": "dPoxhk9-PYLD4X5FGYfnu", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1831.8279205782599, + "y": -3258.8098866324954, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 74.92871086792869, + "height": 52.1896071366814, + "seed": 922084838, + "groupIds": [ + "E0QjzkoDqja29hhto95x6" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1731962319748, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 53.89609027342239, + -0.521896071366772 + ], + [ + 63.974220974956665, + -11.481713570069886 + ], + [ + 50.828833103390224, + -26.094803568340623 + ], + [ + 51.70519229482798, + -40.18599749524468 + ], + [ + 40.75070240185597, + -52.1896071366814 + ], + [ + 25.414416551695105, + -50.10202285121416 + ], + [ + 19.279902211630755, + -41.75168570934514 + ], + [ + 10.516310297253115, + -44.36116606617914 + ], + [ + 3.9436163614699264, + -38.6203092811442 + ], + [ + 3.9436163614699264, + -29.748076067908407 + ], + [ + -5.696334744345467, + -27.660491782441092 + ], + [ + -10.954489892972026, + -18.266362497838443 + ], + [ + -9.639951105815392, + -5.740856785034943 + ], + [ + 0, + 0 + ] + ] + }, + { + "type": "text", + "version": 2972, + "versionNonce": 528722214, + "isDeleted": false, + "id": "1V97CW867YOw2uP-LMBoK", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1838.5038182366184, + "y": -3251.8219269206515, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 37.23997497558594, + "height": 25, + "seed": 1347172646, + "groupIds": [ + "sx90BQRooRRuaNuiLpWXQ", + "S93jm3EgjC3TwYYXE3SQx", + "E0QjzkoDqja29hhto95x6" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1731962327476, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "API", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "API", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "ellipse", + "version": 2105, + "versionNonce": 588457702, + "isDeleted": false, + "id": "HcVayVc10YHZIJycD9u0k", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 0, + "angle": 0, + "x": 1582.6213384181644, + "y": -2265.378661581836, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.75732316367123, + "height": 116.75732316367123, + "seed": 1846980134, + "groupIds": [ + "D0E3Gr6mycKCRpr40q4aS" + ], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "DHUw95Hb-z5Qr50c8xscr", + "type": "arrow" + }, + { + "id": "E8P9ipOh4Q6Gwax4kYYJq", + "type": "arrow" + } + ], + "updated": 1731962699883, + "link": null, + "locked": false + }, + { + "type": "line", + "version": 2391, + "versionNonce": 1954121894, + "isDeleted": false, + "id": "ENfkVJvp_xkXt8S16r1Fm", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1614.8279205782599, + "y": -2194.8098866324954, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 74.92871086792869, + "height": 52.1896071366814, + "seed": 646917946, + "groupIds": [ + "D0E3Gr6mycKCRpr40q4aS" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 53.89609027342239, + -0.521896071366772 + ], + [ + 63.974220974956665, + -11.481713570069886 + ], + [ + 50.828833103390224, + -26.094803568340623 + ], + [ + 51.70519229482798, + -40.18599749524468 + ], + [ + 40.75070240185597, + -52.1896071366814 + ], + [ + 25.414416551695105, + -50.10202285121416 + ], + [ + 19.279902211630755, + -41.75168570934514 + ], + [ + 10.516310297253115, + -44.36116606617914 + ], + [ + 3.9436163614699264, + -38.6203092811442 + ], + [ + 3.9436163614699264, + -29.748076067908407 + ], + [ + -5.696334744345467, + -27.660491782441092 + ], + [ + -10.954489892972026, + -18.266362497838443 + ], + [ + -9.639951105815392, + -5.740856785034943 + ], + [ + 0, + 0 + ] + ] + }, + { + "type": "text", + "version": 3111, + "versionNonce": 1254982630, + "isDeleted": false, + "id": "CBeiv2XJqsv-rD3eGWolN", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1621.5038182366184, + "y": -2187.8219269206515, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 37.23997497558594, + "height": 25, + "seed": 816445798, + "groupIds": [ + "9xRBqhfDcNv3p44Dfewmw", + "Mfbnq__WYkIiTrY2DtZCG", + "D0E3Gr6mycKCRpr40q4aS" + ], + "frameId": null, + "roundness": null, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "API", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "API", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "id": "rTEQzSB_1WyI2N_H_-1my", + "type": "arrow", + "x": 1620, + "y": -3238, + "width": 165, + "height": 21, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1925824934, + "version": 48, + "versionNonce": 506521338, + "isDeleted": false, + "boundElements": null, + "updated": 1731962323799, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 165, + -21 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": 0.4444070080862533, + "gap": 8 + }, + "endBinding": { + "elementId": "MIk2ZQGpmDTLZDdlUN2ZO", + "focus": -0.04603415788695993, + "gap": 15.601065370891071 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "type": "ellipse", + "version": 2021, + "versionNonce": 403119590, + "isDeleted": false, + "id": "5xSfoUVhHMHbxHtKAMx0K", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 0, + "angle": 0, + "x": 2071.1213384181647, + "y": -3333.878661581836, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.75732316367123, + "height": 116.75732316367123, + "seed": 1394109670, + "groupIds": [ + "HaKQrXpZ46bZ2n16NdFbH" + ], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "aVpZjPMmv5iWyUAETTFpE", + "type": "arrow" + }, + { + "id": "YsTCEwqvT61oXQFJUhhDh", + "type": "arrow" + } + ], + "updated": 1731962371462, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1785, + "versionNonce": 539093606, + "isDeleted": false, + "id": "n-whw8HlyWL6rB9BIyuTv", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2080.06005859375, + "y": -3257.142174383894, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 98.8798828125, + "height": 25, + "seed": 1954930726, + "groupIds": [ + "HaKQrXpZ46bZ2n16NdFbH" + ], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1731962342247, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Database", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Database", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "line", + "version": 1534, + "versionNonce": 780381606, + "isDeleted": false, + "id": "0RQSK4eYlBePg4lFsHa7m", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2104.5871844731405, + "y": -3300.802669868198, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.903292935976054, + "height": 59.210922138681, + "seed": 1180887910, + "groupIds": [ + "ckGUhulNu_tPeXieE3SV7", + "HaKQrXpZ46bZ2n16NdFbH" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1731962342247, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 28.299530811487102 + ], + [ + 1.6417076378563409, + 33.443548076769844 + ], + [ + 7.442407958281753, + 38.0403294627672 + ], + [ + 15.650946147562784, + 40.667061683337124 + ], + [ + 26.157875029842657, + 40.33872015576604 + ], + [ + 35.1325434501233, + 36.72696335248227 + ], + [ + 41.042690946405656, + 32.458523494056095 + ], + [ + 42.356057056690666, + 27.31450622877327 + ], + [ + 42.79384576011894, + 10.569088322639786 + ], + [ + 42.903292935976054, + -5.847988055922443 + ], + [ + 42.574951408404885, + -11.648688376347728 + ], + [ + 37.6498284948362, + -15.5887867072027 + ], + [ + 26.70511090912805, + -18.54386045534388 + ], + [ + 14.994263092420281, + -18.434413279486808 + ], + [ + 5.910147496282524, + -15.917128234773912 + ], + [ + 1.09447175857095, + -11.86758272806195 + ], + [ + 0.10944717585711185, + -6.6141182869220145 + ], + [ + 0, + 0 + ] + ] + }, + { + "type": "line", + "version": 685, + "versionNonce": 1783302374, + "isDeleted": false, + "id": "MRUgpIwZV8YDHYlXwmpgi", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2104.915526000712, + "y": -3310.5907562549755, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.79384576011894, + "height": 8.865221244423617, + "seed": 1190956710, + "groupIds": [ + "ckGUhulNu_tPeXieE3SV7", + "HaKQrXpZ46bZ2n16NdFbH" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1731962342247, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 4.59678138599735, + 5.144017265282825 + ], + [ + 15.213157444134335, + 8.536879716852367 + ], + [ + 26.486216557413655, + 8.865221244423617 + ], + [ + 36.4459095604083, + 5.910147496282398 + ], + [ + 42.79384576011894, + 1.0944717585708237 + ] + ] + }, + { + "type": "line", + "version": 751, + "versionNonce": 1124400166, + "isDeleted": false, + "id": "0ky_Q70lnpzMD5nVhgfM0", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2104.5641255518035, + "y": -3301.327476106443, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.79384576011894, + "height": 8.865221244423617, + "seed": 587188710, + "groupIds": [ + "ckGUhulNu_tPeXieE3SV7", + "HaKQrXpZ46bZ2n16NdFbH" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1731962342247, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 4.59678138599735, + 5.144017265282825 + ], + [ + 15.213157444134335, + 8.536879716852367 + ], + [ + 26.486216557413655, + 8.865221244423617 + ], + [ + 36.4459095604083, + 5.910147496282398 + ], + [ + 42.79384576011894, + 1.0944717585708237 + ] + ] + }, + { + "type": "line", + "version": 791, + "versionNonce": 782141286, + "isDeleted": false, + "id": "WaxW6GOVZZIyOQNcFF0Pv", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 2104.263305411255, + "y": -3294.616230998856, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.79384576011894, + "height": 8.865221244423617, + "seed": 1769577766, + "groupIds": [ + "ckGUhulNu_tPeXieE3SV7", + "HaKQrXpZ46bZ2n16NdFbH" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1731962342247, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 4.59678138599735, + 5.144017265282825 + ], + [ + 15.213157444134335, + 8.536879716852367 + ], + [ + 26.486216557413655, + 8.865221244423617 + ], + [ + 36.4459095604083, + 5.910147496282398 + ], + [ + 42.79384576011894, + 1.0944717585708237 + ] + ] + }, + { + "type": "ellipse", + "version": 2165, + "versionNonce": 58726182, + "isDeleted": false, + "id": "bMr7eob1JPNyn4XT7Xy49", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 0, + "angle": 0, + "x": 1854.1213384181647, + "y": -2269.878661581836, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 116.75732316367123, + "height": 116.75732316367123, + "seed": 35207162, + "groupIds": [ + "KGK9buIFF5urQdqX3Fx8h" + ], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "E8P9ipOh4Q6Gwax4kYYJq", + "type": "arrow" + } + ], + "updated": 1731962699883, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 1924, + "versionNonce": 672466342, + "isDeleted": false, + "id": "gZGTozERSCJhJaCcosCvX", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1863.06005859375, + "y": -2193.142174383894, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 98.8798828125, + "height": 25, + "seed": 825351334, + "groupIds": [ + "KGK9buIFF5urQdqX3Fx8h" + ], + "frameId": null, + "roundness": null, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Database", + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Database", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "type": "line", + "version": 1673, + "versionNonce": 1475436774, + "isDeleted": false, + "id": "2QNsM29aSTweHF-rnACAz", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1887.5871844731405, + "y": -2236.802669868198, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.903292935976054, + "height": 59.210922138681, + "seed": 417605818, + "groupIds": [ + "BPgc1qFpCXFAfdPuc_TpA", + "KGK9buIFF5urQdqX3Fx8h" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 28.299530811487102 + ], + [ + 1.6417076378563409, + 33.443548076769844 + ], + [ + 7.442407958281753, + 38.0403294627672 + ], + [ + 15.650946147562784, + 40.667061683337124 + ], + [ + 26.157875029842657, + 40.33872015576604 + ], + [ + 35.1325434501233, + 36.72696335248227 + ], + [ + 41.042690946405656, + 32.458523494056095 + ], + [ + 42.356057056690666, + 27.31450622877327 + ], + [ + 42.79384576011894, + 10.569088322639786 + ], + [ + 42.903292935976054, + -5.847988055922443 + ], + [ + 42.574951408404885, + -11.648688376347728 + ], + [ + 37.6498284948362, + -15.5887867072027 + ], + [ + 26.70511090912805, + -18.54386045534388 + ], + [ + 14.994263092420281, + -18.434413279486808 + ], + [ + 5.910147496282524, + -15.917128234773912 + ], + [ + 1.09447175857095, + -11.86758272806195 + ], + [ + 0.10944717585711185, + -6.6141182869220145 + ], + [ + 0, + 0 + ] + ] + }, + { + "type": "line", + "version": 824, + "versionNonce": 1512068134, + "isDeleted": false, + "id": "qkDdS9AACgDk6jUdMiTyK", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1887.915526000712, + "y": -2246.5907562549755, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.79384576011894, + "height": 8.865221244423617, + "seed": 1968920550, + "groupIds": [ + "BPgc1qFpCXFAfdPuc_TpA", + "KGK9buIFF5urQdqX3Fx8h" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 4.59678138599735, + 5.144017265282825 + ], + [ + 15.213157444134335, + 8.536879716852367 + ], + [ + 26.486216557413655, + 8.865221244423617 + ], + [ + 36.4459095604083, + 5.910147496282398 + ], + [ + 42.79384576011894, + 1.0944717585708237 + ] + ] + }, + { + "type": "line", + "version": 890, + "versionNonce": 2022629222, + "isDeleted": false, + "id": "LfIe8wixP54sfBXYlZke9", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1887.5641255518035, + "y": -2237.327476106443, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.79384576011894, + "height": 8.865221244423617, + "seed": 580059514, + "groupIds": [ + "BPgc1qFpCXFAfdPuc_TpA", + "KGK9buIFF5urQdqX3Fx8h" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 4.59678138599735, + 5.144017265282825 + ], + [ + 15.213157444134335, + 8.536879716852367 + ], + [ + 26.486216557413655, + 8.865221244423617 + ], + [ + 36.4459095604083, + 5.910147496282398 + ], + [ + 42.79384576011894, + 1.0944717585708237 + ] + ] + }, + { + "type": "line", + "version": 930, + "versionNonce": 931791526, + "isDeleted": false, + "id": "JIX-aC0urHrBtaiaUqC0-", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1887.2633054112548, + "y": -2230.616230998856, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 42.79384576011894, + "height": 8.865221244423617, + "seed": 1160997670, + "groupIds": [ + "BPgc1qFpCXFAfdPuc_TpA", + "KGK9buIFF5urQdqX3Fx8h" + ], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": null, + "updated": 1731962699883, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 4.59678138599735, + 5.144017265282825 + ], + [ + 15.213157444134335, + 8.536879716852367 + ], + [ + 26.486216557413655, + 8.865221244423617 + ], + [ + 36.4459095604083, + 5.910147496282398 + ], + [ + 42.79384576011894, + 1.0944717585708237 + ] + ] + }, + { + "id": "aVpZjPMmv5iWyUAETTFpE", + "type": "arrow", + "x": 1931, + "y": -3272, + "width": 123, + "height": 1, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 411908794, + "version": 47, + "versionNonce": 408609638, + "isDeleted": false, + "boundElements": null, + "updated": 1731962347348, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 123, + 1 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "MIk2ZQGpmDTLZDdlUN2ZO", + "focus": -0.027294960706014747, + "gap": 14.628187411940232 + }, + "endBinding": { + "elementId": "5xSfoUVhHMHbxHtKAMx0K", + "focus": -0.087594542265731, + "gap": 17.25532548747077 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "YsTCEwqvT61oXQFJUhhDh", + "type": "arrow", + "x": 2103, + "y": -3207, + "width": 186, + "height": 24, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1799829562, + "version": 48, + "versionNonce": 1786147110, + "isDeleted": false, + "boundElements": null, + "updated": 1731962371462, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -186, + -24 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "5xSfoUVhHMHbxHtKAMx0K", + "focus": -1.2218167114304739, + "gap": 15.068598407901291 + }, + "endBinding": { + "elementId": "MIk2ZQGpmDTLZDdlUN2ZO", + "focus": 0.5502148366343107, + "gap": 12.902471966951303 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "uH5tSdNTUI4qLowcXyWO7", + "type": "arrow", + "x": 1810, + "y": -3224, + "width": 191, + "height": 10, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 884793254, + "version": 34, + "versionNonce": 673556090, + "isDeleted": false, + "boundElements": null, + "updated": 1731962375781, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -191, + 10 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "MIk2ZQGpmDTLZDdlUN2ZO", + "focus": -0.7609983193139022, + "gap": 8.800204142438119 + }, + "endBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": 0.852132812044115, + "gap": 7 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "oQS3xjCotbyszhXpx-BLH", + "type": "arrow", + "x": 1435, + "y": -3194, + "width": 592, + "height": 351, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 2117455866, + "version": 119, + "versionNonce": 155466790, + "isDeleted": false, + "boundElements": null, + "updated": 1731962382354, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -592, + 351 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "f2EOun2JPCq-bxulS1kjn", + "focus": -0.16821137403821904, + "gap": 13 + }, + "endBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": 1.0140895650114226, + "gap": 6 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "pO4Z_WFw4GttS3eT1mrGg", + "type": "arrow", + "x": 646, + "y": -2927, + "width": 5, + "height": 530, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 215214758, + "version": 44, + "versionNonce": 1078655738, + "isDeleted": false, + "boundElements": null, + "updated": 1731962386740, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -5, + -530 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "URlHpkvQ897XvfNefBqx5", + "focus": -0.5666344106831817, + "gap": 9 + }, + "endBinding": { + "elementId": "ZoHqsxxoWgZCqK0eYgRCO", + "focus": 0.787265337720147, + "gap": 8 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "RSKlo952T-s09BcwCUovi", + "type": "arrow", + "x": 598, + "y": -3523, + "width": 127, + "height": 5, + "angle": 0, + "strokeColor": "#2f9e44", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 460326010, + "version": 43, + "versionNonce": 1516054694, + "isDeleted": false, + "boundElements": null, + "updated": 1731962391284, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -127, + 5 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ZoHqsxxoWgZCqK0eYgRCO", + "focus": 0.5764962706931052, + "gap": 17 + }, + "endBinding": { + "elementId": "-bHwg9yPLmf_ReAnvN2QZ", + "focus": -0.0753386154654083, + "gap": 7.991512442344835 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "WyQBPJoRHXZV4FfqHv8tt", + "type": "text", + "x": 481, + "y": -3455, + "width": 110.53988647460938, + "height": 50, + "angle": 0, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1023129382, + "version": 22, + "versionNonce": 235920890, + "isDeleted": false, + "boundElements": null, + "updated": 1731962430233, + "link": null, + "locked": false, + "text": "Integration\nTEST", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 43, + "containerId": null, + "originalText": "Integration\nTEST", + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 130, + "versionNonce": 163495398, + "isDeleted": false, + "id": "BBQZCUwmTYhLaRQ4Plt0H", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 635.7600555419922, + "y": -2311.5, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 98.47988891601562, + "height": 25, + "seed": 472494138, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1731962699883, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "Unit Test", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "Unit Test", + "lineHeight": 1.25, + "baseline": 18 + }, + { + "id": "9NMl6F2JSDc_WxAJcDSdX", + "type": "arrow", + "x": 749, + "y": -2185, + "width": 178, + "height": 1, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1428268838, + "version": 274, + "versionNonce": 437412218, + "isDeleted": false, + "boundElements": null, + "updated": 1731962700161, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 178, + -1 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "Y0k2cKsgPFLRdvYShC-Lc", + "focus": -0.04445913265861475, + "gap": 13.683811314950269 + }, + "endBinding": { + "elementId": "FTCcYxUVYUZruvq9oZxL_", + "focus": 0.057853609577747475, + "gap": 15 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "agkdahj_bXgqZhTu2xmkz", + "type": "text", + "x": 780, + "y": -2235, + "width": 116.91986083984375, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1443665722, + "version": 88, + "versionNonce": 1677766630, + "isDeleted": false, + "boundElements": null, + "updated": 1731962724315, + "link": null, + "locked": false, + "text": "create user", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "create user", + "lineHeight": 1.25 + }, + { + "id": "pnE_CH1AhAuXJaOYn0gR9", + "type": "text", + "x": 1387, + "y": -2095, + "width": 154.4998016357422, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1728841318, + "version": 158, + "versionNonce": 426252710, + "isDeleted": false, + "boundElements": null, + "updated": 1731962808729, + "link": null, + "locked": false, + "text": "create user api", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "create user api", + "lineHeight": 1.25 + }, + { + "id": "PQUbO14DNdlCHIkaaA_Aw", + "type": "text", + "x": 1024, + "y": -1471, + "width": 154.4998016357422, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 708143802, + "version": 199, + "versionNonce": 1364788710, + "isDeleted": false, + "boundElements": [ + { + "id": "GXoKpKAOfAQ-EE8qSbylV", + "type": "arrow" + } + ], + "updated": 1731962921959, + "link": null, + "locked": false, + "text": "create user api", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "create user api", + "lineHeight": 1.25 + }, + { + "id": "DHUw95Hb-z5Qr50c8xscr", + "type": "arrow", + "x": 1208, + "y": -1991, + "width": 359, + "height": 214, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 132483898, + "version": 363, + "versionNonce": 1960354278, + "isDeleted": false, + "boundElements": null, + "updated": 1731962737033, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 359, + -214 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "yMZwe9IZ9IpY4HSYwOLNC", + "focus": 0.5030409613834542, + "gap": 19 + }, + "endBinding": { + "elementId": "HcVayVc10YHZIJycD9u0k", + "focus": 0.619615602036549, + "gap": 15.648360511451315 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "E8P9ipOh4Q6Gwax4kYYJq", + "type": "arrow", + "x": 1710, + "y": -2214, + "width": 124, + "height": 5, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 417894650, + "version": 259, + "versionNonce": 1453380730, + "isDeleted": false, + "boundElements": null, + "updated": 1731962700161, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 124, + 5 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "HcVayVc10YHZIJycD9u0k", + "focus": -0.16742958721623463, + "gap": 10.975501955763129 + }, + "endBinding": { + "elementId": "bMr7eob1JPNyn4XT7Xy49", + "focus": -0.0969656100737057, + "gap": 20.161137246529385 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "frhGqlqOh-kEwiFqvcv-Y", + "type": "freedraw", + "x": 1287, + "y": -2258, + "width": 83, + "height": 817.0000000000001, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 339938534, + "version": 386, + "versionNonce": 15547130, + "isDeleted": false, + "boundElements": null, + "updated": 1731962863494, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 0, + 1.4963369963369966 + ], + [ + -1, + 5.985347985347986 + ], + [ + -2, + 16.459706959706963 + ], + [ + -4, + 29.92673992673993 + ], + [ + -5, + 46.38644688644689 + ], + [ + -5, + 61.34981684981686 + ], + [ + -5, + 74.81684981684982 + ], + [ + -4, + 86.7875457875458 + ], + [ + -3, + 92.77289377289378 + ], + [ + -1, + 104.74358974358977 + ], + [ + 0, + 109.23260073260074 + ], + [ + 1, + 113.72161172161174 + ], + [ + 2, + 118.21062271062273 + ], + [ + 4, + 121.20329670329673 + ], + [ + 6, + 130.18131868131871 + ], + [ + 8, + 137.66300366300368 + ], + [ + 18, + 158.61172161172163 + ], + [ + 25, + 172.0787545787546 + ], + [ + 29, + 178.0641025641026 + ], + [ + 32, + 182.55311355311358 + ], + [ + 33, + 185.54578754578756 + ], + [ + 33, + 187.04212454212458 + ], + [ + 34, + 194.52380952380955 + ], + [ + 35, + 199.01282051282055 + ], + [ + 35, + 203.50183150183153 + ], + [ + 35, + 209.48717948717953 + ], + [ + 35, + 215.4725274725275 + ], + [ + 36, + 224.4505494505495 + ], + [ + 36, + 230.43589743589746 + ], + [ + 37, + 236.42124542124546 + ], + [ + 37, + 242.40659340659346 + ], + [ + 37, + 251.38461538461542 + ], + [ + 37, + 257.3699633699634 + ], + [ + 37, + 266.3479853479854 + ], + [ + 37, + 272.33333333333337 + ], + [ + 36, + 276.82234432234435 + ], + [ + 34, + 282.8076923076924 + ], + [ + 33, + 285.80036630036636 + ], + [ + 32, + 290.28937728937734 + ], + [ + 32, + 293.2820512820513 + ], + [ + 32, + 297.7710622710623 + ], + [ + 31, + 300.7637362637363 + ], + [ + 31, + 302.2600732600733 + ], + [ + 30, + 303.7564102564103 + ], + [ + 30, + 306.7490842490843 + ], + [ + 30, + 309.7417582417583 + ], + [ + 30, + 312.7344322344323 + ], + [ + 30, + 314.2307692307693 + ], + [ + 31, + 318.71978021978026 + ], + [ + 33, + 323.20879120879124 + ], + [ + 39, + 335.17948717948724 + ], + [ + 42, + 341.1648351648352 + ], + [ + 45, + 347.1501831501832 + ], + [ + 47, + 351.6391941391942 + ], + [ + 49, + 356.1282051282052 + ], + [ + 50, + 360.6172161172162 + ], + [ + 51, + 365.10622710622715 + ], + [ + 52, + 368.09890109890114 + ], + [ + 53, + 375.58058608058616 + ], + [ + 53, + 380.06959706959714 + ], + [ + 53, + 384.5586080586081 + ], + [ + 53, + 393.5366300366301 + ], + [ + 53, + 399.5219780219781 + ], + [ + 53, + 407.00366300366306 + ], + [ + 52, + 412.98901098901104 + ], + [ + 50, + 418.97435897435906 + ], + [ + 49, + 424.95970695970703 + ], + [ + 47, + 432.441391941392 + ], + [ + 45, + 439.923076923077 + ], + [ + 43, + 444.412087912088 + ], + [ + 41, + 448.901098901099 + ], + [ + 39, + 451.89377289377296 + ], + [ + 36, + 456.38278388278394 + ], + [ + 34, + 460.8717948717949 + ], + [ + 32, + 463.86446886446896 + ], + [ + 31, + 468.35347985347994 + ], + [ + 30, + 471.3461538461539 + ], + [ + 29, + 474.3388278388279 + ], + [ + 29, + 475.8351648351649 + ], + [ + 29, + 478.8278388278389 + ], + [ + 29, + 481.8205128205129 + ], + [ + 30, + 487.8058608058609 + ], + [ + 31, + 490.7985347985349 + ], + [ + 36, + 501.27289377289384 + ], + [ + 43, + 505.7619047619048 + ], + [ + 48, + 511.74725274725284 + ], + [ + 53, + 519.2289377289378 + ], + [ + 55, + 522.2216117216118 + ], + [ + 56, + 523.7179487179488 + ], + [ + 56, + 525.2142857142858 + ], + [ + 56, + 528.2069597069598 + ], + [ + 56, + 534.1923076923077 + ], + [ + 56, + 537.1849816849817 + ], + [ + 56, + 540.1776556776557 + ], + [ + 56, + 544.6666666666667 + ], + [ + 54, + 555.1410256410257 + ], + [ + 53, + 561.1263736263737 + ], + [ + 52, + 565.6153846153848 + ], + [ + 51, + 570.1043956043957 + ], + [ + 50, + 576.0897435897436 + ], + [ + 50, + 577.5860805860807 + ], + [ + 50, + 579.0824175824176 + ], + [ + 50, + 580.5787545787547 + ], + [ + 50, + 582.0750915750916 + ], + [ + 50, + 585.0677655677656 + ], + [ + 51, + 589.5567765567766 + ], + [ + 53, + 594.0457875457877 + ], + [ + 54, + 597.0384615384617 + ], + [ + 55, + 600.0311355311356 + ], + [ + 57, + 604.5201465201466 + ], + [ + 58, + 607.5128205128206 + ], + [ + 61, + 612.0018315018316 + ], + [ + 64, + 617.9871794871796 + ], + [ + 66, + 620.9798534798535 + ], + [ + 67, + 622.4761904761906 + ], + [ + 68, + 622.4761904761906 + ], + [ + 68, + 623.9725274725275 + ], + [ + 70, + 625.4688644688646 + ], + [ + 72, + 628.4615384615386 + ], + [ + 73, + 628.4615384615386 + ], + [ + 74, + 629.9578754578755 + ], + [ + 74, + 631.4542124542126 + ], + [ + 74, + 635.9432234432236 + ], + [ + 73, + 638.9358974358976 + ], + [ + 72, + 643.4249084249085 + ], + [ + 71, + 646.4175824175825 + ], + [ + 70, + 649.4102564102565 + ], + [ + 69, + 650.9065934065935 + ], + [ + 69, + 652.4029304029305 + ], + [ + 69, + 653.8992673992675 + ], + [ + 69, + 655.3956043956046 + ], + [ + 69, + 658.3882783882785 + ], + [ + 68, + 659.8846153846155 + ], + [ + 68, + 661.3809523809525 + ], + [ + 68, + 662.8772893772895 + ], + [ + 68, + 667.3663003663005 + ], + [ + 67, + 670.3589743589745 + ], + [ + 67, + 671.8553113553114 + ], + [ + 67, + 674.8479853479854 + ], + [ + 67, + 677.8406593406595 + ], + [ + 67, + 685.3223443223444 + ], + [ + 67, + 688.3150183150184 + ], + [ + 67, + 692.8040293040294 + ], + [ + 67, + 697.2930402930403 + ], + [ + 67, + 700.2857142857144 + ], + [ + 67, + 701.7820512820514 + ], + [ + 67, + 703.2783882783884 + ], + [ + 67, + 704.7747252747254 + ], + [ + 67, + 707.7673992673994 + ], + [ + 67, + 710.7600732600733 + ], + [ + 67, + 713.7527472527473 + ], + [ + 67, + 715.2490842490844 + ], + [ + 66, + 718.2417582417584 + ], + [ + 65, + 722.7307692307694 + ], + [ + 65, + 725.7234432234434 + ], + [ + 64, + 725.7234432234434 + ], + [ + 64, + 727.2197802197803 + ], + [ + 64, + 728.7161172161174 + ], + [ + 64, + 731.7087912087914 + ], + [ + 64, + 734.7014652014653 + ], + [ + 64, + 736.1978021978023 + ], + [ + 64, + 743.6794871794873 + ], + [ + 64, + 748.1684981684983 + ], + [ + 66, + 757.1465201465203 + ], + [ + 67, + 760.1391941391943 + ], + [ + 68, + 761.6355311355312 + ], + [ + 69, + 761.6355311355312 + ], + [ + 71, + 764.6282051282052 + ], + [ + 73, + 766.1245421245422 + ], + [ + 74, + 766.1245421245422 + ], + [ + 74, + 767.6208791208793 + ], + [ + 75, + 769.1172161172162 + ], + [ + 76, + 772.1098901098902 + ], + [ + 76, + 773.6062271062273 + ], + [ + 76, + 778.0952380952382 + ], + [ + 74, + 781.0879120879122 + ], + [ + 71, + 785.5769230769232 + ], + [ + 69, + 787.0732600732601 + ], + [ + 68, + 790.0659340659342 + ], + [ + 67, + 791.5622710622712 + ], + [ + 66, + 794.5549450549452 + ], + [ + 66, + 796.0512820512822 + ], + [ + 66, + 797.5476190476192 + ], + [ + 67, + 800.5402930402931 + ], + [ + 70, + 805.0293040293042 + ], + [ + 73, + 809.5183150183151 + ], + [ + 77, + 815.5036630036632 + ], + [ + 77, + 817.0000000000001 + ], + [ + 78, + 817.0000000000001 + ], + [ + 78, + 817.0000000000001 + ] + ], + "pressures": [], + "simulatePressure": true, + "lastCommittedPoint": [ + 78, + 546 + ] + }, + { + "id": "yMZwe9IZ9IpY4HSYwOLNC", + "type": "rectangle", + "x": 954, + "y": -2011, + "width": 235, + "height": 88, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 1244681062, + "version": 63, + "versionNonce": 379806330, + "isDeleted": false, + "boundElements": [ + { + "id": "s5kV5EKlOOgHtrRecLw9n", + "type": "arrow" + }, + { + "id": "DHUw95Hb-z5Qr50c8xscr", + "type": "arrow" + }, + { + "id": "_ylo5V4pTAO5hkhmSmNkY", + "type": "arrow" + }, + { + "id": "3Kkd64LPYBPFyRImd-oeh", + "type": "arrow" + } + ], + "updated": 1731963117915, + "link": null, + "locked": false + }, + { + "id": "ilzwunjOyc10WCC6YrRJV", + "type": "rectangle", + "x": 947, + "y": -1707, + "width": 285.9999999999999, + "height": 88, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 2031246758, + "version": 168, + "versionNonce": 418504826, + "isDeleted": false, + "boundElements": [ + { + "id": "_ylo5V4pTAO5hkhmSmNkY", + "type": "arrow" + }, + { + "id": "-GUX0COZhd6Uz_Oajalz4", + "type": "arrow" + } + ], + "updated": 1731962856759, + "link": null, + "locked": false + }, + { + "id": "s5kV5EKlOOgHtrRecLw9n", + "type": "arrow", + "x": 1069, + "y": -2132, + "width": 11, + "height": 105, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 624024358, + "version": 29, + "versionNonce": 1385846586, + "isDeleted": false, + "boundElements": null, + "updated": 1731962721874, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 11, + 105 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "FTCcYxUVYUZruvq9oZxL_", + "focus": 0, + "gap": 14 + }, + "endBinding": { + "elementId": "yMZwe9IZ9IpY4HSYwOLNC", + "focus": 0.12108567640291698, + "gap": 16 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "8b_SwGNExWyG_gw4gC062", + "type": "text", + "x": 979, + "y": -1997, + "width": 154.3598175048828, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 327659942, + "version": 40, + "versionNonce": 1686163002, + "isDeleted": false, + "boundElements": null, + "updated": 1731963020470, + "link": null, + "locked": false, + "text": "user_repository", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "user_repository", + "lineHeight": 1.25 + }, + { + "id": "YUxm7zPZKz1JdVuYsvNwm", + "type": "text", + "x": 990, + "y": -1965, + "width": 80.21990966796875, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1984662950, + "version": 72, + "versionNonce": 1958212282, + "isDeleted": false, + "boundElements": null, + "updated": 1731963032502, + "link": null, + "locked": false, + "text": "create()", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "create()", + "lineHeight": 1.25 + }, + { + "id": "bXgvbMf5ufcEXWv4RUDj0", + "type": "text", + "x": 985, + "y": -1674, + "width": 227.5797576904297, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1078404198, + "version": 77, + "versionNonce": 1207638374, + "isDeleted": false, + "boundElements": null, + "updated": 1731962778163, + "link": null, + "locked": false, + "text": "mock_create_user_api", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "mock_create_user_api", + "lineHeight": 1.25 + }, + { + "id": "_ylo5V4pTAO5hkhmSmNkY", + "type": "arrow", + "x": 1102.6422044593046, + "y": -1911, + "width": 6.982522123792023, + "height": 193, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 1603877114, + "version": 92, + "versionNonce": 1628163622, + "isDeleted": false, + "boundElements": null, + "updated": 1731962778163, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -6.982522123792023, + 193 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "yMZwe9IZ9IpY4HSYwOLNC", + "focus": -0.2799845157960386, + "gap": 12 + }, + "endBinding": { + "elementId": "ilzwunjOyc10WCC6YrRJV", + "focus": 0.025380710659898487, + "gap": 11 + }, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "-GUX0COZhd6Uz_Oajalz4", + "type": "arrow", + "x": 1083, + "y": -1604, + "width": 11, + "height": 104, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 912728294, + "version": 35, + "versionNonce": 968392102, + "isDeleted": false, + "boundElements": null, + "updated": 1731962904392, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 11, + 104 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "ilzwunjOyc10WCC6YrRJV", + "focus": 0.08967178952852307, + "gap": 15 + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "GXoKpKAOfAQ-EE8qSbylV", + "type": "arrow", + "x": 1092, + "y": -1437, + "width": 7, + "height": 80, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 229950010, + "version": 23, + "versionNonce": 919423654, + "isDeleted": false, + "boundElements": null, + "updated": 1731962921959, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + 7, + 80 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "PQUbO14DNdlCHIkaaA_Aw", + "focus": 0.14208108381045664, + "gap": 9 + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "zksvpOxDMUFDUpRewhR6E", + "type": "rectangle", + "x": 991, + "y": -1331, + "width": 297, + "height": 175, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 512668730, + "version": 41, + "versionNonce": 562164282, + "isDeleted": false, + "boundElements": null, + "updated": 1731962929907, + "link": null, + "locked": false + }, + { + "id": "V1c9puL7qShHS0J2wPe5_", + "type": "text", + "x": 1019, + "y": -1293, + "width": 262.72934570312503, + "height": 28.000000000000014, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1380068282, + "version": 103, + "versionNonce": 483008038, + "isDeleted": false, + "boundElements": null, + "updated": 1731962977191, + "link": null, + "locked": false, + "text": "{\"id\":1, firstName:\"name\"}", + "fontSize": 22.4, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 20.000000000000014, + "containerId": null, + "originalText": "{\"id\":1, firstName:\"name\"}", + "lineHeight": 1.25 + }, + { + "id": "JUVEzLAUmMJIqenm8oV9n", + "type": "text", + "x": 1050, + "y": -1243, + "width": 189.05979919433594, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 2027225126, + "version": 18, + "versionNonce": 992940538, + "isDeleted": false, + "boundElements": null, + "updated": 1731962999802, + "link": null, + "locked": false, + "text": "status code : 200", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "status code : 200", + "lineHeight": 1.25 + }, + { + "id": "3Kkd64LPYBPFyRImd-oeh", + "type": "arrow", + "x": 947, + "y": -1917, + "width": 221, + "height": 177, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "seed": 83206630, + "version": 37, + "versionNonce": 397191610, + "isDeleted": false, + "boundElements": null, + "updated": 1731963117915, + "link": null, + "locked": false, + "points": [ + [ + 0, + 0 + ], + [ + -221, + 177 + ] + ], + "lastCommittedPoint": null, + "startBinding": { + "elementId": "yMZwe9IZ9IpY4HSYwOLNC", + "focus": 0.3599593729010697, + "gap": 7 + }, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": "arrow" + }, + { + "id": "d4SErYia75w06Vd7I10PO", + "type": "rectangle", + "x": 484, + "y": -1729, + "width": 357, + "height": 254, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "seed": 533005114, + "version": 44, + "versionNonce": 1566724986, + "isDeleted": false, + "boundElements": null, + "updated": 1731963121526, + "link": null, + "locked": false + }, + { + "id": "fo0ycrlrfjrksXEgvgms2", + "type": "text", + "x": 551, + "y": -1610, + "width": 186.05979919433594, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 1676360954, + "version": 45, + "versionNonce": 1990244218, + "isDeleted": false, + "boundElements": null, + "updated": 1731963139765, + "link": null, + "locked": false, + "text": "asset/mock/.....json", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "asset/mock/.....json", + "lineHeight": 1.25 + }, + { + "id": "cINdjcCCynkj0_RjoGh8m", + "type": "text", + "x": 508, + "y": -1656, + "width": 308.3797607421875, + "height": 25, + "angle": 0, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "frameId": null, + "roundness": null, + "seed": 548504486, + "version": 143, + "versionNonce": 390317862, + "isDeleted": false, + "boundElements": null, + "updated": 1731963167931, + "link": null, + "locked": false, + "text": "Environment.LOCAL, TEST, DEV", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "left", + "verticalAlign": "top", + "baseline": 18, + "containerId": null, + "originalText": "Environment.LOCAL, TEST, DEV", + "lineHeight": 1.25 + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/lib/data/http_utils.dart b/lib/data/http_utils.dart index 9f61ae0..29b7ae7 100644 --- a/lib/data/http_utils.dart +++ b/lib/data/http_utils.dart @@ -63,8 +63,10 @@ class HttpUtils { log("default headers : $_defaultHttpHeaders"); } - if (AppLocalStorageCached.jwtToken != null) { - headerParameters['Authorization'] = 'Bearer ${AppLocalStorageCached.jwtToken}'; + final jwtToken = await AppLocalStorage().read(StorageKeys.jwtToken.name); + + if (jwtToken != null) { + headerParameters['Authorization'] = 'Bearer $jwtToken'; } else { headerParameters.remove('Authorization'); } diff --git a/lib/data/models/authorities.dart b/lib/data/models/authorities.dart index a686fa5..9a9e71f 100644 --- a/lib/data/models/authorities.dart +++ b/lib/data/models/authorities.dart @@ -21,22 +21,21 @@ class Authorities extends Equatable { } static Authorities? fromJson(Map json) { - var result = JsonMapper.fromMap(json); - if (result == null) { - return null; + if (json['name'] != null) { + return Authorities(name: json['name']); } - return result; + return null; } - static Authorities? fromJsonString(String json){ - var result = JsonMapper.deserialize(jsonDecode(json)); - if (result == null) { - return null; - } - return result; + static Authorities? fromJsonString(String json) { + return fromJson(jsonDecode(json)); } - Map? toJson() => JsonMapper.toMap(this); + Map? toJson() { + return { + 'name': name, + }; + } @override List get props => [ diff --git a/lib/main/main_local.dart b/lib/main/main_local.dart index c0f5d4e..4db12cf 100644 --- a/lib/main/main_local.dart +++ b/lib/main/main_local.dart @@ -15,11 +15,11 @@ void main() async { ProfileConstants.setEnvironment(Environment.DEV); initializeJsonMapper(); WidgetsFlutterBinding.ensureInitialized(); - - await AppLocalStorage().save(StorageKeys.language.name, "en"); + const defaultLanguage = "en"; + await AppLocalStorage().save(StorageKeys.language.name, defaultLanguage); WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) { - runApp(App(language: AppLocalStorageCached.language!)); + runApp(App(language: defaultLanguage)); }); } diff --git a/lib/main/main_prod.dart b/lib/main/main_prod.dart index 1d019d6..849c380 100644 --- a/lib/main/main_prod.dart +++ b/lib/main/main_prod.dart @@ -16,10 +16,11 @@ void main() async { initializeJsonMapper(); WidgetsFlutterBinding.ensureInitialized(); - await AppLocalStorage().save(StorageKeys.language.name, "en"); + const defaultLanguage = "en"; + await AppLocalStorage().save(StorageKeys.language.name, defaultLanguage); WidgetsFlutterBinding.ensureInitialized(); SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]).then((_) { - runApp(App(language: AppLocalStorageCached.language!)); + runApp(App(language: defaultLanguage)); }); } diff --git a/lib/presentation/common_widgets/drawer/drawer_widget.dart b/lib/presentation/common_widgets/drawer/drawer_widget.dart index d091d21..3b53f0a 100644 --- a/lib/presentation/common_widgets/drawer/drawer_widget.dart +++ b/lib/presentation/common_widgets/drawer/drawer_widget.dart @@ -237,7 +237,8 @@ class LanguageSwitchButtonState extends State { } Future _loadLanguage() async { - final lang = AppLocalStorageCached.language; + + final lang = await AppLocalStorage().read(StorageKeys.language.name); setState(() { isTurkish = lang == 'tr'; }); diff --git a/lib/presentation/screen/user/edit/edit_form_widget.dart b/lib/presentation/screen/user/edit/edit_form_widget.dart index e9e3c7c..fe4d8ea 100644 --- a/lib/presentation/screen/user/edit/edit_form_widget.dart +++ b/lib/presentation/screen/user/edit/edit_form_widget.dart @@ -219,6 +219,7 @@ class SubmitButton extends StatelessWidget { if (cacheUser == newUser) { Message.getMessage(context: context, title: "Değişiklik bulunmadı", content: ''); //TODO internationalization + Navigator.pop(context); } }, ), diff --git a/lib/utils/security_utils.dart b/lib/utils/security_utils.dart index f924cb0..5781d3e 100644 --- a/lib/utils/security_utils.dart +++ b/lib/utils/security_utils.dart @@ -2,8 +2,9 @@ import 'package:flutter_bloc_advance/configuration/local_storage.dart'; class SecurityUtils { static bool isCurrentUserAdmin() { - if (AppLocalStorageCached.roles != null) { - return AppLocalStorageCached.roles!.contains("ROLE_ADMIN"); + final roles = AppLocalStorageCached.roles; + if (roles != null) { + return roles.contains("ROLE_ADMIN"); } else { return false; } diff --git a/test/data/model/authority_test.dart b/test/data/model/authority_test.dart index 7816aee..845e3a9 100644 --- a/test/data/model/authority_test.dart +++ b/test/data/model/authority_test.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import 'package:flutter_bloc_advance/data/models/authorities.dart'; import 'package:flutter_bloc_advance/main/main_local.mapper.g.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -5,19 +8,23 @@ import '../../fake/user_data.dart'; /// Test the Authorities model void main() { - var model = mockAuthorityPayload; - setUp(() { initializeJsonMapper(); }); group("Authorities Model", () { test('should create a Authorities instance (Constructor)', () { - expect(model.name, 'ROLE_USER'); + expect(mockAuthorityPayload.name, 'ROLE_USER'); + }); + + test('should copy a Authorities instance with new values (copyWith)', () { + final updatedAuthorities = mockAuthorityPayload.copyWith(); + + expect(updatedAuthorities == mockAuthorityPayload, true); }); test('should copy a Authorities instance with new values (copyWith)', () { - final updatedAuthorities = model.copyWith( + final updatedAuthorities = mockAuthorityPayload.copyWith( name: 'ROLE_ADMIN', ); @@ -25,7 +32,7 @@ void main() { }); test('should compare two Authorities instances', () { - final finalAuthorities = model; + final finalAuthorities = mockAuthorityPayload; final updatedAuthorities = finalAuthorities.copyWith( name: 'ROLE_ADMIN', @@ -34,4 +41,34 @@ void main() { expect(finalAuthorities == updatedAuthorities, false); }); }); + + group("Authority Model Json Test", () { + test('should convert Authorities from Json', () { + final json = mockAuthorityPayload.toJson(); + + final authority = Authorities.fromJson(json!); + + expect(authority?.name, 'ROLE_USER'); + }); + + test('should convert Authorities from JsonString', () { + final jsonString = jsonEncode(mockAuthorityPayload.toJson()); + + final authority = Authorities.fromJsonString(jsonString); + + expect(authority?.name, 'ROLE_USER'); + }); + + test('should convert Authorities to Json', () { + final json = mockAuthorityPayload.toJson()!; + + expect(json['name'], 'ROLE_USER'); + }); + + test("to string method", () { + final authority = mockAuthorityPayload; + + expect(authority.toString(), 'Authorities(ROLE_USER)'); + }); + }); } diff --git a/test/data/model/change_password_test.dart b/test/data/model/change_password_test.dart index 6a6832b..380a9eb 100644 --- a/test/data/model/change_password_test.dart +++ b/test/data/model/change_password_test.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import 'package:flutter_bloc_advance/data/models/change_password.dart'; import 'package:flutter_bloc_advance/main/main_local.mapper.g.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -5,7 +8,6 @@ import '../../fake/user_data.dart'; /// Test the Change Password model void main() { - var model = mockPasswordChangePayload; setUp(() { initializeJsonMapper(); @@ -13,27 +15,77 @@ void main() { group("Change Password Model", () { test('should create a ChangePassword instance (Constructor)', () { - expect(model.currentPassword, 'password'); - expect(model.newPassword, 'new_password'); + expect(mockPasswordChangePayload.currentPassword, 'password'); + expect(mockPasswordChangePayload.newPassword, 'new_password'); }); test('should copy a ChangePassword instance with new values (copyWith)', () { - final updatedChangePassword = model.copyWith( + final updatedChangePassword = mockPasswordChangePayload.copyWith( currentPassword: 'new_password', newPassword: 'password', ); - expect(updatedChangePassword.currentPassword, 'new_password'); expect(updatedChangePassword.newPassword, 'password'); }); + test('should copy a ChangePassword instance with new values (copyWith)', () { + final updatedChangePassword = mockPasswordChangePayload.copyWith(); + expect(updatedChangePassword == mockPasswordChangePayload, true); + }); + test('should compare two ChangePassword instances', () { - final updatedChangePassword = model.copyWith( + final updatedChangePassword = mockPasswordChangePayload.copyWith( currentPassword: 'new_password', newPassword: 'password', ); - expect(model == updatedChangePassword, false); + expect(mockPasswordChangePayload == updatedChangePassword, false); }); }); + + //fromJson, fromJsonString, toJson, props, toString + group("Change Password Model Json Test", () { + test('should convert ChangePassword from Json', () { + final json = mockPasswordChangePayload.toJson(); + + final changePassword = PasswordChangeDTO.fromJson(json!); + + expect(changePassword?.currentPassword, 'password'); + expect(changePassword?.newPassword, 'new_password'); + }); + + test('should convert ChangePassword from JsonString', () { + final jsonString = jsonEncode(mockPasswordChangePayload.toJson()); + + final changePassword = PasswordChangeDTO.fromJsonString(jsonString); + + expect(changePassword?.currentPassword, 'password'); + expect(changePassword?.newPassword, 'new_password'); + }); + + test('should convert ChangePassword to Json', () { + final json = mockPasswordChangePayload.toJson()!; + expect(json['currentPassword'], 'password'); + expect(json['newPassword'], 'new_password'); + }); + + test('should compare two ChangePassword instances props', () { + final updatedChangePassword = mockPasswordChangePayload.copyWith( + currentPassword: 'new_password', + newPassword: 'password', + ); + + expect(mockPasswordChangePayload.props == updatedChangePassword.props, false); + }); + + test('should compare two ChangePassword instances toString', () { + final updatedChangePassword = mockPasswordChangePayload.copyWith( + currentPassword: 'new_password', + newPassword: 'password', + ); + + expect(mockPasswordChangePayload.toString() == updatedChangePassword.toString(), false); + }); + }); + } diff --git a/test/data/model/city_test.dart b/test/data/model/city_test.dart index 3e44503..adf4e0a 100644 --- a/test/data/model/city_test.dart +++ b/test/data/model/city_test.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import 'package:flutter_bloc_advance/data/models/city.dart'; import 'package:flutter_bloc_advance/main/main_local.mapper.g.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -18,7 +21,7 @@ void main() { expect(finalCity.plateCode, '34'); }); - test('should copy a City instance with new values (copyWith)', () { + test('should copy a City instance with new values (copyWith) new data', () { final updatedCity = cityMockPayload.copyWith( name: 'ankara', plateCode: '06', @@ -29,6 +32,12 @@ void main() { expect(updatedCity.plateCode, '06'); }); + test('should copy a City instance with new values (copyWith)', () { + final updatedCity = cityMockPayload.copyWith(); + + expect(updatedCity == cityMockPayload, true); + }); + test('should compare two City instances', () { final updatedCity = cityMockPayload.copyWith( id: 1, @@ -39,4 +48,34 @@ void main() { expect(cityMockPayload == updatedCity, false); }); }); + + //fromJson, fromJsonString, toJson, props + group("City Model Json Test", () { + test('should convert City from Json', () { + final json = cityMockPayload.toJson(); + + final city = City.fromJson(json!); + + expect(city?.id, 1); + expect(city?.name, 'istanbul'); + expect(city?.plateCode, '34'); + }); + + test('should convert City from JsonString', () { + final jsonString = jsonEncode(cityMockPayload.toJson()); + + final city = City.fromJsonString(jsonString); + + expect(city?.id, 1); + expect(city?.name, 'istanbul'); + expect(city?.plateCode, '34'); + }); + + test('should convert City to Json', () { + final json = cityMockPayload.toJson()!; + expect(json['id'], 1); + expect(json['name'], 'istanbul'); + expect(json['plateCode'], '34'); + }); + }); } diff --git a/test/data/model/customer_test.dart b/test/data/model/customer_test.dart index dbb34de..a05146c 100644 --- a/test/data/model/customer_test.dart +++ b/test/data/model/customer_test.dart @@ -28,6 +28,14 @@ void main() { test('should copy a Customer instance with new values (copyWith)', () { final finalCustomer = customerMockFullPayload; + final updatedCustomer = finalCustomer.copyWith(); + + expect(updatedCustomer == finalCustomer, true); + }); + + test('should copy a Customer instance with new values (copyWith) new values', () { + final finalCustomer = customerMockFullPayload; + final updatedCustomer = finalCustomer.copyWith( name: 'new Acme', cityName: 'izmir', @@ -74,5 +82,20 @@ void main() { expect(finalCustomer?.address, 'yazır mh.'); expect(finalCustomer?.active, true); }); + + //props + test('props test', () { + final finalCustomer = customerMockFullPayload; + final updatedCustomer = finalCustomer.copyWith(); + + expect(finalCustomer.props, updatedCustomer.props); + }); + + //toString + test('should return string', () { + final finalCustomer = customerMockFullPayload; + expect(finalCustomer.toString(), + 'Customer(1, Acme, 5055055050, john.doe@example.com, Konya, selçuklu, yazır mh., true)'); + }); }); } diff --git a/test/data/model/district_test.dart b/test/data/model/district_test.dart index 9b34fc0..9c12481 100644 --- a/test/data/model/district_test.dart +++ b/test/data/model/district_test.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import 'package:flutter_bloc_advance/data/models/district.dart'; import 'package:flutter_bloc_advance/main/main_local.mapper.g.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -12,34 +15,81 @@ void main() { test('should create a City instance (Constructor)', () { final finalDistrict = districtMockPayload; - expect(finalDistrict.id, '1'); - expect(finalDistrict.name, 'istanbul'); - expect(finalDistrict.code, '01'); + expect(finalDistrict.id, 'id'); + expect(finalDistrict.name, 'kadikoy'); + expect(finalDistrict.code, '34'); }); test('should copy a District instance with new values (copyWith)', () { final finalDistrict = districtMockPayload; - final updatedDistrict = finalDistrict.copyWith( - id: '1', - name: 'ankara', - code: '01', - ); + final updatedDistrict = finalDistrict.copyWith(); + + expect(updatedDistrict.id, 'id'); + expect(updatedDistrict.name, 'kadikoy'); + expect(updatedDistrict.code, '34'); + }); + + test('should compare two District instances copyWith ID', () { + final finalDistrict = districtMockPayload; + final updatedDistrict = finalDistrict.copyWith(id: '1'); expect(updatedDistrict.id, '1'); + }); + + test('should compare two District instances copyWith name', () { + final finalDistrict = districtMockPayload; + final updatedDistrict = finalDistrict.copyWith(name: 'ankara'); + expect(updatedDistrict.name, 'ankara'); - expect(updatedDistrict.code, '01'); }); - test('should compare two District instances', () { + test('should compare two District instances copyWith code', () { + final finalDistrict = districtMockPayload; + final updatedDistrict = finalDistrict.copyWith(code: '06'); + + expect(updatedDistrict.code, '06'); + }); + }); + + // fromJson, fromJsonString, toJson, props + group("District Model Json Test", () { + test('should convert District from Json', () { + final json = districtMockPayload.toJson(); + + final district = District.fromJson(json!); + + expect(district?.id, 'id'); + expect(district?.name, 'kadikoy'); + expect(district?.code, '34'); + }); + + test('should convert District from Json String', () { + final jsonString = jsonEncode(districtMockPayload.toJson()); + + final district = District.fromJsonString(jsonString); + + expect(district?.id, 'id'); + expect(district?.name, 'kadikoy'); + expect(district?.code, '34'); + }); + + test('should convert District to Json', () { + final district = districtMockPayload; + + final json = district.toJson()!; + + expect(json['id'], 'id'); + expect(json['name'], 'kadikoy'); + expect(json['code'], '34'); + }); + + test('should compare two District instances props', () { final finalDistrict = districtMockPayload; - final updatedDistrict = finalDistrict.copyWith( - id: '1', - name: 'ankara', - code: '01', - ); + final updatedDistrict = finalDistrict.copyWith(); - ///districtModel and updatedDistrict should not be equal because they have different name values. - expect(finalDistrict == updatedDistrict, false); + expect(finalDistrict.props, updatedDistrict.props); }); }); + + } diff --git a/test/data/model/jwt_token_test.dart b/test/data/model/jwt_token_test.dart index a839a79..bc9ab84 100644 --- a/test/data/model/jwt_token_test.dart +++ b/test/data/model/jwt_token_test.dart @@ -1,3 +1,6 @@ +import 'dart:convert'; + +import 'package:flutter_bloc_advance/data/models/jwt_token.dart'; import 'package:flutter_bloc_advance/main/main_local.mapper.g.dart'; import 'package:flutter_test/flutter_test.dart'; @@ -23,6 +26,12 @@ void main() { expect(updatedJWTToken.idToken, 'new_idToken'); }); + test('should copy a JWTToken instance with new values (copyWith)', () { + final finalJWTToken = jWTTokenMockPayload; + final updatedJWTToken = finalJWTToken.copyWith(); + expect(updatedJWTToken == finalJWTToken, true); + }); + test('should compare two JWTToken instances', () { final finalJWTToken = jWTTokenMockPayload; final updatedJWTToken = finalJWTToken.copyWith( @@ -30,5 +39,47 @@ void main() { ); expect(finalJWTToken == updatedJWTToken, false); }); + + test('should compare two JWTToken copy old values', () { + final finalJWTToken = jWTTokenMockPayload; + final updatedJWTToken = finalJWTToken.copyWith(); + expect(finalJWTToken.idToken, updatedJWTToken.idToken); + }); + }); + + //from json + group('JWTToken from JSON', () { + test('should deserialize from JSON', () { + final json = jWTTokenMockPayload.toJson(); + final jwtToken = JWTToken.fromJson(json!); + expect(jwtToken?.idToken, 'idToken'); + }); + + test('should deserialize from JSON string', () { + final json = jWTTokenMockPayload.toJson(); + final jwtToken = JWTToken.fromJsonString(jsonEncode(json!)); + expect(jwtToken?.idToken, 'idToken'); + }); + }); + + // toString, equals, hashcode + group("toString, equals and hashcode", (){ + test('should return string', () { + final finalJWTToken = jWTTokenMockPayload; + expect(finalJWTToken.toString(), 'JWTToken{idToken: idToken}'); + }); + + test('should return true when comparing two JWTToken instances', () { + final finalJWTToken = jWTTokenMockPayload; + final updatedJWTToken = finalJWTToken.copyWith( + idToken: 'new_idToken', + ); + expect(finalJWTToken == updatedJWTToken, false); + }); + + test('should return hashcode', () { + final finalJWTToken = jWTTokenMockPayload; + expect(finalJWTToken.hashCode, finalJWTToken.idToken.hashCode); + }); }); } diff --git a/test/data/model/menu_test.dart b/test/data/model/menu_test.dart index 512583f..8bc5784 100644 --- a/test/data/model/menu_test.dart +++ b/test/data/model/menu_test.dart @@ -44,6 +44,21 @@ void main() { expect(updatedMenu.level, 01); }); + test('should copy a Menu instance with copyWith just copy', () { + final finalMenu = menuMockPayload; + final updatedMenu = finalMenu.copyWith(); + + expect(updatedMenu.id, 0); + expect(updatedMenu.name, 'test name'); + expect(updatedMenu.description, ''); + expect(updatedMenu.url, 'https://dhw-api.onrender.com/'); + expect(updatedMenu.icon, ''); + expect(updatedMenu.orderPriority, 01); + expect(updatedMenu.active, false); + expect(updatedMenu.parent, null); + expect(updatedMenu.level, 01); + }); + test('should deserialize from JSON', () { final json = menuMockPayload.toJson(); diff --git a/test/data/model/user_jwt_test.dart b/test/data/model/user_jwt_test.dart new file mode 100644 index 0000000..49b5754 --- /dev/null +++ b/test/data/model/user_jwt_test.dart @@ -0,0 +1,102 @@ +import 'dart:convert'; + +import 'package:flutter_bloc_advance/data/models/user_jwt.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import '../../fake/user_data.dart'; +import '../../test_utils.dart'; + +void main() { + setUp(() async { + TestUtils().setupUnitTest(); + }); + + // model test, constructor, copyWith, toJson, fromJson, props, toString, equals, hashcode + group("UserJWT Model", () { + test('should create a UserJWT instance (Constructor)', () { + final finalUserJWT = userJWTMockPayload; + + expect(finalUserJWT.username, 'username'); + expect(finalUserJWT.password, 'password'); + }); + + test('should copy a UserJWT instance with new values (copyWith)', () { + final finalUserJWT = userJWTMockPayload; + final updatedUserJWT = finalUserJWT.copyWith(); + + expect(updatedUserJWT == finalUserJWT, true); + }); + + test('should copy a UserJWT instance with new values (copyWith) username', () { + final finalUserJWT = userJWTMockPayload; + final updatedUserJWT = finalUserJWT.copyWith(username: 'new_username'); + + expect(updatedUserJWT.username, 'new_username'); + }); + test('should copy a UserJWT instance with new values (copyWith) pass', () { + final finalUserJWT = userJWTMockPayload; + final updatedUserJWT = finalUserJWT.copyWith(password: 'new_password'); + + expect(updatedUserJWT.password, 'new_password'); + }); + + test('should deserialize from JSON', () { + final json = userJWTMockPayload.toJson(); + + final userJWT = UserJWT.fromJson(json!); + + expect(userJWT?.username, 'username'); + expect(userJWT?.password, 'password'); + }); + + test('should deserialize from JSON string', () { + final json = userJWTMockPayload.toJson(); + final userJWT = UserJWT.fromJsonString(jsonEncode(json!)); + + expect(userJWT?.username, 'username'); + expect(userJWT?.password, 'password'); + }); + + test('should serialize to JSON', () { + final userJWT = userJWTMockPayload; + + final json = userJWT.toJson()!; + + expect(json['username'], 'username'); + expect(json['password'], 'password'); + }); + + // props, toString, equals, hashcode + test("props should return list of properties", () { + final userJWT = userJWTMockPayload; + + expect(userJWT.props, [userJWT.username, userJWT.password]); + }); + + test('toString should return string', () { + final userJWT = userJWTMockPayload; + + expect(userJWT.toString(), 'UserJWT{password: password}'); + }); + + test('should return true when comparing two UserJWT instances', () { + final userJWT = userJWTMockPayload; + final updatedUserJWT = userJWT.copyWith( + username: 'new_username', + password: 'new_password', + ); + + expect(userJWT == updatedUserJWT, false); + }); + + test("hashCode should return hash code", () { + final userJWT = userJWTMockPayload; + final updatedUserJWT = userJWT.copyWith( + username: 'new_username', + password: 'new_password', + ); + + expect(userJWT.hashCode == updatedUserJWT.hashCode, false); + }); + }); +} diff --git a/test/data/model/user_test.dart b/test/data/model/user_test.dart index 8c6df2b..3f35ee1 100644 --- a/test/data/model/user_test.dart +++ b/test/data/model/user_test.dart @@ -35,15 +35,12 @@ void main() { test('should copy a User instance with new values (copyWith)', () { final finalUser = model; - final updatedUser = finalUser.copyWith( - firstName: 'Jane', - lastName: 'Smith', - ); + final updatedUser = finalUser.copyWith(); expect(updatedUser.id, '1'); expect(updatedUser.login, 'test_login'); - expect(updatedUser.firstName, 'Jane'); - expect(updatedUser.lastName, 'Smith'); + expect(updatedUser.firstName, 'John'); + expect(updatedUser.lastName, 'Doe'); expect(updatedUser.email, 'john.doe@example.com'); expect(updatedUser.activated, true); expect(updatedUser.langKey, 'en'); @@ -54,23 +51,17 @@ void main() { expect(updatedUser.authorities, ['ROLE_USER']); }); - test('should copy a User instance with new values (copyWith)', () { + test('should copy a User instance with new values copyWith fistName', () { final finalUser = model; - final updatedUser = finalUser.copyWith(); + final updatedUser = finalUser.copyWith(firstName: 'Jane'); + expect(updatedUser.firstName, 'Jane'); + }); + test('should copy a User instance with new values copyWith lastname', () { + final finalUser = model; - expect(updatedUser.id, '1'); - expect(updatedUser.login, 'test_login'); - expect(updatedUser.firstName, 'John'); - expect(updatedUser.lastName, 'Doe'); - expect(updatedUser.email, 'john.doe@example.com'); - expect(updatedUser.activated, true); - expect(updatedUser.langKey, 'en'); - expect(updatedUser.createdBy, 'admin'); - expect(updatedUser.createdDate, createdDate); - expect(updatedUser.lastModifiedBy, 'admin'); - expect(updatedUser.lastModifiedDate, createdDate); - expect(updatedUser.authorities, ['ROLE_USER']); + final updatedUser = finalUser.copyWith(lastName: 'Smith'); + expect(updatedUser.lastName, 'Smith'); }); test('should deserialize from JSON', () { diff --git a/test/data/repository/account_repository_test.dart b/test/data/repository/account_repository_test.dart index faf6857..44d93f0 100644 --- a/test/data/repository/account_repository_test.dart +++ b/test/data/repository/account_repository_test.dart @@ -16,17 +16,6 @@ void main() { }); //endregion setup - // ProfileConstants.setEnvironment(Environment.TEST); - // initializeJsonMapper(); - // TestWidgetsFlutterBinding.ensureInitialized(); - // SharedPreferences.setMockInitialValues({}); - // - // TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger - // .setMockMethodCallHandler(const MethodChannel('plugins.flutter.io/path_provider'), (MethodCall methodCall) async { - // return '.'; - // }); - // GetStorage.init("${Directory.systemTemp.createTempSync().path}/${Random().nextInt(1000)}"); - // TestWidgetsFlutterBinding.ensureInitialized(); //test register success group("AccountRepository Register success", () { @@ -75,7 +64,7 @@ void main() { //test change password success group("AccountRepository Change Password success", () { test("Given valid passwordChangeDTO when changePassword then return 200", () async { - await TestUtils().addMockTokenToStorage(); + await TestUtils().setupAuthentication(); final passwordChangeDTO = mockPasswordChangePayload; final result = await AccountRepository().changePassword(passwordChangeDTO); expect(result, 200); @@ -99,7 +88,7 @@ void main() { //test reset password success group("AccountRepository Reset Password success", () { test("Given valid mailAddress when resetPassword then return 200", () async { - await TestUtils().addMockTokenToStorage(); + await TestUtils().setupAuthentication(); final mailAddress = "admin@sekoya.tech"; final result = await AccountRepository().resetPassword(mailAddress); expect(result, 200); @@ -119,7 +108,7 @@ void main() { //test get account success group("AccountRepository Get Account success", () { test("Given valid user when getAccount then return user successfully", () async { - await TestUtils().addMockTokenToStorage(); + await TestUtils().setupAuthentication(); final result = await AccountRepository().getAccount(); expect(result, isA()); }); @@ -136,7 +125,7 @@ void main() { //test save account success group("AccountRepository Save Account success", () { test("Given valid user when saveAccount then return user successfully", () async { - await TestUtils().addMockTokenToStorage(); + await TestUtils().setupAuthentication(); final newUser = mockUserFullPayload; final result = await AccountRepository().saveAccount(newUser); expect(result, isA()); diff --git a/test/fake/city_data.dart b/test/fake/city_data.dart index 119a386..a4856a0 100644 --- a/test/fake/city_data.dart +++ b/test/fake/city_data.dart @@ -10,7 +10,7 @@ final cityMockPayload = City( /// District Fake data with full payload final districtMockPayload = District( - id: '1', - name: 'istanbul', - code: '01', + id: 'id', + name: 'kadikoy', + code: '34', ); diff --git a/test/fake/user_data.dart b/test/fake/user_data.dart index 02b59df..9cf1f92 100644 --- a/test/fake/user_data.dart +++ b/test/fake/user_data.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc_advance/data/models/change_password.dart'; import 'package:flutter_bloc_advance/data/models/jwt_token.dart'; import 'package:flutter_bloc_advance/data/models/menu.dart'; import 'package:flutter_bloc_advance/data/models/user.dart'; +import 'package:flutter_bloc_advance/data/models/user_jwt.dart'; final DateTime createdDate = DateTime(2024, 1, 1); @@ -49,4 +50,7 @@ final menuMockPayload = Menu( active: false, parent: null, level: 01, -); \ No newline at end of file +); + +/// UserJWT fake data with full payload +final userJWTMockPayload = UserJWT("username", "password"); \ No newline at end of file diff --git a/test/presentation/blocs/user_bloc_test.dart b/test/presentation/blocs/user_bloc_test.dart index ac004ef..c69d967 100644 --- a/test/presentation/blocs/user_bloc_test.dart +++ b/test/presentation/blocs/user_bloc_test.dart @@ -34,25 +34,16 @@ void main() { /// User State Tests group("UserState", () { test("supports value comparisons", () { - expect( - const UserState(), - const UserState(), - ); + expect(const UserState(), const UserState()); }); test("copyWith retains the same values if no arguments are provided", () { - const state = UserState( - user: null, - status: UserStatus.initial, - ); + const state = UserState(user: null, status: UserStatus.initial); expect(state.copyWith(), state); }); test("copyWith replaces non-null parameters", () { - const state = UserState( - user: null, - status: UserStatus.initial, - ); + const state = UserState(user: null, status: UserStatus.initial); final user = mockUserFullPayload; expect( state.copyWith(user: user, status: UserStatus.success), diff --git a/test/presentation/screen/account/account_screen_test.dart b/test/presentation/screen/account/account_screen_test.dart index 13f9148..6c7738c 100644 --- a/test/presentation/screen/account/account_screen_test.dart +++ b/test/presentation/screen/account/account_screen_test.dart @@ -67,7 +67,7 @@ void main() { group("AccountsScreen DataTest", () { testWidgets("Render Screen Validate Field Type Successful", (tester) async { debugPrint("begin Validate Field Type"); - await TestUtils().addMockTokenToStorage(); + await TestUtils().setupAuthentication(); debugPrint("getAccount initWidgetDependenciesWithToken"); // Given: await tester.pumpWidget(getWidget()); diff --git a/test/presentation/screen/user/create_user_screen_test.dart b/test/presentation/screen/user/create_user_screen_test.dart index 82612d3..6b561eb 100644 --- a/test/presentation/screen/user/create_user_screen_test.dart +++ b/test/presentation/screen/user/create_user_screen_test.dart @@ -141,7 +141,7 @@ void main() { /// validate mock data testWidgets(skip: true, "Render screen validate entered user data and click save button", (tester) async { - TestUtils().addMockTokenToStorage(); + await TestUtils().setupAuthentication(); // Given: await tester.pumpWidget(getWidget()); await tester.pumpAndSettle(); diff --git a/test/presentation/screen/user/edit_user_screen_test.dart b/test/presentation/screen/user/edit_user_screen_test.dart index 0edfbd1..008c231 100644 --- a/test/presentation/screen/user/edit_user_screen_test.dart +++ b/test/presentation/screen/user/edit_user_screen_test.dart @@ -18,12 +18,41 @@ import '../../../test_utils.dart'; /// Edit User Screen Test /// class UserScreen extends void main() { + // 1. setup + // 2. appbar + // 3. render screen with field type( text, switch, dropdown, button, label, etc.) + // 4. validate field name with English translation + // 5. Optional: validate loaded data + // 6. Optional: Enter data to fields + // 8. Optional: Validate data entered + // 9. Validate button click or bloc event + // 10. Optional: Validate saved data, listed data, updated data, etc. + // 11. Validate screen dispose: back button, saved data, etc. + //region setup + + // before + // setupAll run once before all tests setUpAll(() async { + debugPrint("setupAll run once before all tests"); await TestUtils().setupUnitTest(); }); + + // after + // tearDownAll run once after all tests + tearDownAll(() async { + debugPrint("tearDownAll run once after all tests"); + }); + + // setup run before each test + setUp(() async { + debugPrint("setUp run before each test"); + }); + + // tearDown run after each test tearDown(() async { await TestUtils().tearDownUnitTest(); + debugPrint("tearDown run after each test"); }); final blocs = [ @@ -33,10 +62,7 @@ void main() { GetMaterialApp getWidget(User user) { return GetMaterialApp( - home: MultiBlocProvider( - providers: blocs, - child: EditUserScreen(user: user), - ), + home: MultiBlocProvider(providers: blocs, child: EditUserScreen(user: user)), localizationsDelegates: const [ S.delegate, GlobalMaterialLocalizations.delegate, @@ -49,7 +75,6 @@ void main() { group("EditUserScreen Test", () { testWidgets("Validate AppBar", (tester) async { - // Given: await tester.pumpWidget(getWidget(mockUserFullPayload)); //When: @@ -80,17 +105,11 @@ void main() { //When: await tester.pumpAndSettle(); //Then: - // username / login name textField expect(find.text("Login"), findsOneWidget); - // firstName textField expect(find.text("First Name"), findsOneWidget); - // lastName textField expect(find.text("Last Name"), findsOneWidget); - // email textField expect(find.text("Email"), findsOneWidget); - // active switch button expect(find.text("Active"), findsOneWidget); - // save button expect(find.text("Save"), findsOneWidget); }); @@ -101,50 +120,56 @@ void main() { //When: await tester.pumpAndSettle(); //Then: - // username / login name expect(find.text("test_login"), findsOneWidget); - // firstName expect(find.text("John"), findsOneWidget); - // lastName expect(find.text("Doe"), findsOneWidget); - // email expect(find.text("john.doe@example.com"), findsOneWidget); - // activated // expect(find.text("true"), findsOneWidget); }); }); group("EditUserScreen Bloc Test", () { - testWidgets(skip: true, "Given valid user data with AccessToken when Save Button clicked then update user Successfully", (tester) async { - TestUtils().addMockTokenToStorage(); + testWidgets("Given valid user data with AccessToken when Save Button clicked then update user Successfully", (tester) async { + await TestUtils().setupAuthentication(); // Given: render screen with valid user data await tester.pumpWidget(getWidget(mockUserFullPayload)); //When: wait screen is ready - await tester.pumpAndSettle(); + await tester.pumpAndSettle(Duration(seconds: 1)); + // before click save button check button expect(find.byType(ElevatedButton), findsOneWidget); expect(find.text("Save"), findsOneWidget); - //await tester.tap(find.text('Save')); - // await tester.pumpAndSettle(); + + await tester.tap(find.text('Save')); + await tester.pumpAndSettle(Duration(seconds: 5)); + + // after click save button check screen, dispose EditUserScreen and should be navigate to user list screen + expect(find.byType(EditUserScreen), findsNothing); }); - testWidgets(skip: true, "Given valid user data without AccessToken when Save Button clicked then update user fail (Unauthorized)", - (tester) async { - expect(find.byType(ElevatedButton), findsOneWidget); - expect(find.text("Save"), findsOneWidget); - // await tester.tap(find.text('Save')); - // await tester.pumpAndSettle(); + testWidgets("Given valid user data without AccessToken when Save Button clicked then update user fail (Unauthorized)", (tester) async { // Given: render screen with valid user data await tester.pumpWidget(getWidget(mockUserFullPayload)); //When: wait screen is ready await tester.pumpAndSettle(); - //await tester.tap(find.text('Save')); - //await tester.pumpAndSettle(); + // before click save button check button + expect(find.byType(ElevatedButton), findsOneWidget); + expect(find.text("Save"), findsOneWidget); + + await tester.tap(find.text('Save')); + await tester.pumpAndSettle(Duration(seconds: 5)); + await tester.pumpWidget(getWidget(mockUserFullPayload)); + await tester.pumpAndSettle(); + + // after click save button check screen, without AccessToken should be stay in EditUserScreen + expect(find.byType(EditUserScreen), findsOneWidget); }); - testWidgets(skip: true, "Given same user data (no-changes) when Save Button clicked then no-action", (tester) async { + testWidgets( + skip: true, // skip this test because of no-changes + "Given same user data (no-changes) without AccessToken when Save Button clicked then no-action", (tester) async { // Given: render screen with valid user data await tester.pumpWidget(getWidget(mockUserFullPayload)); //When: wait screen is ready @@ -154,6 +179,10 @@ void main() { expect(find.text("Save"), findsOneWidget); await tester.tap(find.text('Save')); + await tester.pumpAndSettle(Duration(seconds: 5)); + + // after click save button check screen, with same user data, EditUserScreen will not call bloc event then go back + expect(find.byType(EditUserScreen), findsNothing); }); }); } diff --git a/test/presentation/screen/user/list_user_screen_test.dart b/test/presentation/screen/user/list_user_screen_test.dart index d44cbac..c92a173 100644 --- a/test/presentation/screen/user/list_user_screen_test.dart +++ b/test/presentation/screen/user/list_user_screen_test.dart @@ -70,7 +70,7 @@ void main() { }); testWidgets('displays user list when UserSearchSuccessState is emitted with JWTToken', (tester) async { - TestUtils().addMockTokenToStorage(); + await TestUtils().setupAuthentication(); await tester.pumpAndSettle(); // Given: A mock UserSearchSuccessState with a list of users diff --git a/test/test_utils.dart b/test/test_utils.dart index d67ad93..175e3df 100644 --- a/test/test_utils.dart +++ b/test/test_utils.dart @@ -24,22 +24,21 @@ class TestUtils { initializeJsonMapper(); TestWidgetsFlutterBinding.ensureInitialized(); EquatableConfig.stringify = true; - await clearStorage(); + await _clearStorage(); await AppLocalStorage().save(StorageKeys.language.name, "en"); - await AppLocalStorageCached.loadCache(); } - Future clearStorage() async { - SharedPreferences.setMockInitialValues({}); - await AppLocalStorage().clear(); + Future tearDownUnitTest() async { + return await _clearStorage(); } - + // add mock token to storage - Future addMockTokenToStorage() async { + Future setupAuthentication() async { await AppLocalStorage().save(StorageKeys.jwtToken.name, "UNITTEST_TOKEN"); } - Future tearDownUnitTest() async { - return await clearStorage(); + Future _clearStorage() async { + SharedPreferences.setMockInitialValues({}); + await AppLocalStorage().clear(); } }