From 41855332a7838a51d2382be90b6374143b082c9c Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Sat, 4 Mar 2023 23:10:27 +0300 Subject: [PATCH 01/17] initial setup --- example/clickup_dart_example.dart | 2 +- lib/src/clickup_dart_base.dart | 46 +++++++++++++++---------------- pubspec.yaml | 2 +- test/clickup_dart_sdk_test.dart | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/example/clickup_dart_example.dart b/example/clickup_dart_example.dart index ae23eb4..a69e69e 100644 --- a/example/clickup_dart_example.dart +++ b/example/clickup_dart_example.dart @@ -1,4 +1,4 @@ -import 'package:clickup_dart/clickup_dart_sdk.dart'; +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; void main() async { final token = "pk_testrandomtoken123"; diff --git a/lib/src/clickup_dart_base.dart b/lib/src/clickup_dart_base.dart index 71e7324..288e72d 100644 --- a/lib/src/clickup_dart_base.dart +++ b/lib/src/clickup_dart_base.dart @@ -1,26 +1,26 @@ -import 'package:clickup_dart/src/attachments/attachments.dart'; -import 'package:clickup_dart/src/auth/auth.dart'; -import 'package:clickup_dart/src/checklists/checklists.dart'; -import 'package:clickup_dart/src/comments/comments.dart'; -import 'package:clickup_dart/src/custom_fields/custom_fields.dart'; -import 'package:clickup_dart/src/dependencies/dependencies.dart'; -import 'package:clickup_dart/src/folders/folders.dart'; -import 'package:clickup_dart/src/goals/goals.dart'; -import 'package:clickup_dart/src/guests/guests.dart'; -import 'package:clickup_dart/src/lists/lists.dart'; -import 'package:clickup_dart/src/members/members.dart'; -import 'package:clickup_dart/src/roles/roles.dart'; -import 'package:clickup_dart/src/shared_hierarchy/shared_hierarchy.dart'; -import 'package:clickup_dart/src/spaces/spaces.dart'; -import 'package:clickup_dart/src/tags/tags.dart'; -import 'package:clickup_dart/src/tasks/task_templates.dart'; -import 'package:clickup_dart/src/tasks/tasks.dart'; -import 'package:clickup_dart/src/teams/teams.dart'; -import 'package:clickup_dart/src/time_tracking/time_tracking_legacy.dart'; -import 'package:clickup_dart/src/time_tracking/time_tracking_v2.dart'; -import 'package:clickup_dart/src/users/users.dart'; -import 'package:clickup_dart/src/views/views.dart'; -import 'package:clickup_dart/src/webhooks/webhooks.dart'; +import 'package:clickup_dart_sdk/src/attachments/attachments.dart'; +import 'package:clickup_dart_sdk/src/auth/auth.dart'; +import 'package:clickup_dart_sdk/src/checklists/checklists.dart'; +import 'package:clickup_dart_sdk/src/comments/comments.dart'; +import 'package:clickup_dart_sdk/src/custom_fields/custom_fields.dart'; +import 'package:clickup_dart_sdk/src/dependencies/dependencies.dart'; +import 'package:clickup_dart_sdk/src/folders/folders.dart'; +import 'package:clickup_dart_sdk/src/goals/goals.dart'; +import 'package:clickup_dart_sdk/src/guests/guests.dart'; +import 'package:clickup_dart_sdk/src/lists/lists.dart'; +import 'package:clickup_dart_sdk/src/members/members.dart'; +import 'package:clickup_dart_sdk/src/roles/roles.dart'; +import 'package:clickup_dart_sdk/src/shared_hierarchy/shared_hierarchy.dart'; +import 'package:clickup_dart_sdk/src/spaces/spaces.dart'; +import 'package:clickup_dart_sdk/src/tags/tags.dart'; +import 'package:clickup_dart_sdk/src/tasks/task_templates.dart'; +import 'package:clickup_dart_sdk/src/tasks/tasks.dart'; +import 'package:clickup_dart_sdk/src/teams/teams.dart'; +import 'package:clickup_dart_sdk/src/time_tracking/time_tracking_legacy.dart'; +import 'package:clickup_dart_sdk/src/time_tracking/time_tracking_v2.dart'; +import 'package:clickup_dart_sdk/src/users/users.dart'; +import 'package:clickup_dart_sdk/src/views/views.dart'; +import 'package:clickup_dart_sdk/src/webhooks/webhooks.dart'; class ClickUp { late final String apiEndpoint; diff --git a/pubspec.yaml b/pubspec.yaml index 2b90f7b..5e84558 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,4 +1,4 @@ -name: clickup_dart +name: clickup_dart_sdk description: An API wrapper for ClickUp for creating applications on top of the product. version: 0.1.0 repository: https://github.com/ayazemre/clickup-dart diff --git a/test/clickup_dart_sdk_test.dart b/test/clickup_dart_sdk_test.dart index cc374d3..0fc46c0 100644 --- a/test/clickup_dart_sdk_test.dart +++ b/test/clickup_dart_sdk_test.dart @@ -1,4 +1,4 @@ -import 'package:clickup_dart/clickup_dart_sdk.dart'; +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; import 'package:test/test.dart'; void main() { From ddb0e7a9522e34f5b75a481a454c6f365eca818b Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Mon, 10 Apr 2023 08:50:30 +0300 Subject: [PATCH 02/17] refactor tests and package --- README.md | 2 +- lib/src/clickup_dart_base.dart | 76 ++++++++----------- .../endpoints}/attachments.dart | 15 ++-- lib/src/{auth => core/endpoints}/auth.dart | 0 .../endpoints}/checklists.dart | 0 .../endpoints}/comments.dart | 0 .../endpoints}/custom_fields.dart | 0 .../endpoints}/dependencies.dart | 0 .../{folders => core/endpoints}/folders.dart | 0 lib/src/{goals => core/endpoints}/goals.dart | 0 .../{guests => core/endpoints}/guests.dart | 0 lib/src/{lists => core/endpoints}/lists.dart | 0 .../{members => core/endpoints}/members.dart | 0 lib/src/{roles => core/endpoints}/roles.dart | 0 .../endpoints}/shared_hierarchy.dart | 0 .../{spaces => core/endpoints}/spaces.dart | 0 lib/src/{tags => core/endpoints}/tags.dart | 0 .../endpoints}/task_templates.dart | 0 lib/src/{tasks => core/endpoints}/tasks.dart | 0 lib/src/{teams => core/endpoints}/teams.dart | 0 .../endpoints}/time_tracking_legacy.dart | 0 .../endpoints}/time_tracking_v2.dart | 0 lib/src/{users => core/endpoints}/users.dart | 0 lib/src/{views => core/endpoints}/views.dart | 0 .../endpoints}/webhooks.dart | 0 pubspec.yaml | 4 +- test/clickup_dart_sdk_test.dart | 23 +----- test/unit/attachment_test.dart | 27 +++++++ test/unit/auth_test.dart | 20 +++++ test/unit/checklists_test.dart | 20 +++++ test/unit/comments_test.dart | 20 +++++ test/unit/custom_fields.test.dart | 20 +++++ test/unit/dependencies_test.dart | 20 +++++ test/unit/folders_test.dart | 20 +++++ test/unit/goals_test.dart | 7 ++ test/unit/guests_test.dart | 20 +++++ test/unit/lists_test.dart | 20 +++++ test/unit/members_test.dart | 20 +++++ test/unit/roles_test.dart | 20 +++++ test/unit/shared_hierarchy_test.dart | 20 +++++ test/unit/spaces_test.dart | 20 +++++ test/unit/tags_test.dart | 20 +++++ test/unit/task_templates_test.dart | 20 +++++ test/unit/tasks_test.dart | 20 +++++ test/unit/teams_test.dart | 20 +++++ test/unit/time_tracking_legacy_test.dart | 20 +++++ test/unit/time_tracking_v2_test.dart | 20 +++++ test/unit/users_test.dart | 20 +++++ test/unit/views_test.dart | 20 +++++ test/unit/webhooks_test.dart | 20 +++++ 50 files changed, 498 insertions(+), 76 deletions(-) rename lib/src/{attachments => core/endpoints}/attachments.dart (66%) rename lib/src/{auth => core/endpoints}/auth.dart (100%) rename lib/src/{checklists => core/endpoints}/checklists.dart (100%) rename lib/src/{comments => core/endpoints}/comments.dart (100%) rename lib/src/{custom_fields => core/endpoints}/custom_fields.dart (100%) rename lib/src/{dependencies => core/endpoints}/dependencies.dart (100%) rename lib/src/{folders => core/endpoints}/folders.dart (100%) rename lib/src/{goals => core/endpoints}/goals.dart (100%) rename lib/src/{guests => core/endpoints}/guests.dart (100%) rename lib/src/{lists => core/endpoints}/lists.dart (100%) rename lib/src/{members => core/endpoints}/members.dart (100%) rename lib/src/{roles => core/endpoints}/roles.dart (100%) rename lib/src/{shared_hierarchy => core/endpoints}/shared_hierarchy.dart (100%) rename lib/src/{spaces => core/endpoints}/spaces.dart (100%) rename lib/src/{tags => core/endpoints}/tags.dart (100%) rename lib/src/{tasks => core/endpoints}/task_templates.dart (100%) rename lib/src/{tasks => core/endpoints}/tasks.dart (100%) rename lib/src/{teams => core/endpoints}/teams.dart (100%) rename lib/src/{time_tracking => core/endpoints}/time_tracking_legacy.dart (100%) rename lib/src/{time_tracking => core/endpoints}/time_tracking_v2.dart (100%) rename lib/src/{users => core/endpoints}/users.dart (100%) rename lib/src/{views => core/endpoints}/views.dart (100%) rename lib/src/{webhooks => core/endpoints}/webhooks.dart (100%) create mode 100644 test/unit/attachment_test.dart create mode 100644 test/unit/auth_test.dart create mode 100644 test/unit/checklists_test.dart create mode 100644 test/unit/comments_test.dart create mode 100644 test/unit/custom_fields.test.dart create mode 100644 test/unit/dependencies_test.dart create mode 100644 test/unit/folders_test.dart create mode 100644 test/unit/goals_test.dart create mode 100644 test/unit/guests_test.dart create mode 100644 test/unit/lists_test.dart create mode 100644 test/unit/members_test.dart create mode 100644 test/unit/roles_test.dart create mode 100644 test/unit/shared_hierarchy_test.dart create mode 100644 test/unit/spaces_test.dart create mode 100644 test/unit/tags_test.dart create mode 100644 test/unit/task_templates_test.dart create mode 100644 test/unit/tasks_test.dart create mode 100644 test/unit/teams_test.dart create mode 100644 test/unit/time_tracking_legacy_test.dart create mode 100644 test/unit/time_tracking_v2_test.dart create mode 100644 test/unit/users_test.dart create mode 100644 test/unit/views_test.dart create mode 100644 test/unit/webhooks_test.dart diff --git a/README.md b/README.md index d5495a5..8070838 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ and the Flutter guide for ![readmeheaderwhite](https://user-images.githubusercontent.com/68122318/216693937-2cbf9f31-d643-4457-941e-ba33ba3b638d.png#gh-dark-mode-only) -This is an API wrapper for ClickUp +This is a SDK for ClickUp ## Features diff --git a/lib/src/clickup_dart_base.dart b/lib/src/clickup_dart_base.dart index 288e72d..36046cf 100644 --- a/lib/src/clickup_dart_base.dart +++ b/lib/src/clickup_dart_base.dart @@ -1,26 +1,26 @@ -import 'package:clickup_dart_sdk/src/attachments/attachments.dart'; -import 'package:clickup_dart_sdk/src/auth/auth.dart'; -import 'package:clickup_dart_sdk/src/checklists/checklists.dart'; -import 'package:clickup_dart_sdk/src/comments/comments.dart'; -import 'package:clickup_dart_sdk/src/custom_fields/custom_fields.dart'; -import 'package:clickup_dart_sdk/src/dependencies/dependencies.dart'; -import 'package:clickup_dart_sdk/src/folders/folders.dart'; -import 'package:clickup_dart_sdk/src/goals/goals.dart'; -import 'package:clickup_dart_sdk/src/guests/guests.dart'; -import 'package:clickup_dart_sdk/src/lists/lists.dart'; -import 'package:clickup_dart_sdk/src/members/members.dart'; -import 'package:clickup_dart_sdk/src/roles/roles.dart'; -import 'package:clickup_dart_sdk/src/shared_hierarchy/shared_hierarchy.dart'; -import 'package:clickup_dart_sdk/src/spaces/spaces.dart'; -import 'package:clickup_dart_sdk/src/tags/tags.dart'; -import 'package:clickup_dart_sdk/src/tasks/task_templates.dart'; -import 'package:clickup_dart_sdk/src/tasks/tasks.dart'; -import 'package:clickup_dart_sdk/src/teams/teams.dart'; -import 'package:clickup_dart_sdk/src/time_tracking/time_tracking_legacy.dart'; -import 'package:clickup_dart_sdk/src/time_tracking/time_tracking_v2.dart'; -import 'package:clickup_dart_sdk/src/users/users.dart'; -import 'package:clickup_dart_sdk/src/views/views.dart'; -import 'package:clickup_dart_sdk/src/webhooks/webhooks.dart'; +import 'core/endpoints/attachments.dart'; +import 'core/endpoints/auth.dart'; +import 'core/endpoints/checklists.dart'; +import 'core/endpoints/comments.dart'; +import 'core/endpoints/custom_fields.dart'; +import 'core/endpoints/dependencies.dart'; +import 'core/endpoints/folders.dart'; +import 'core/endpoints/goals.dart'; +import 'core/endpoints/guests.dart'; +import 'core/endpoints/lists.dart'; +import 'core/endpoints/members.dart'; +import 'core/endpoints/roles.dart'; +import 'core/endpoints/shared_hierarchy.dart'; +import 'core/endpoints/spaces.dart'; +import 'core/endpoints/tags.dart'; +import 'core/endpoints/task_templates.dart'; +import 'core/endpoints/tasks.dart'; +import 'core/endpoints/teams.dart'; +import 'core/endpoints/time_tracking_legacy.dart'; +import 'core/endpoints/time_tracking_v2.dart'; +import 'core/endpoints/users.dart'; +import 'core/endpoints/views.dart'; +import 'core/endpoints/webhooks.dart'; class ClickUp { late final String apiEndpoint; @@ -55,38 +55,28 @@ class ClickUp { void initialize({required String authToken}) async { auth = ClickUpAuth(endPoint: apiEndpoint, authToken: authToken); - attachments = - ClickUpAttachments(endPoint: apiEndpoint, authToken: auth.authToken); - checklists = - ClickUpChecklists(endPoint: apiEndpoint, authToken: auth.authToken); - comments = - ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken); - customFields = - ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken); - dependencies = - ClickUpDependencies(endPoint: apiEndpoint, authToken: auth.authToken); + attachments = ClickUpAttachments(endPoint: apiEndpoint, authToken: auth.authToken); + checklists = ClickUpChecklists(endPoint: apiEndpoint, authToken: auth.authToken); + comments = ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken); + customFields = ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken); + dependencies = ClickUpDependencies(endPoint: apiEndpoint, authToken: auth.authToken); folders = ClickUpFolders(endPoint: apiEndpoint, authToken: auth.authToken); goals = ClickUpGoals(endPoint: apiEndpoint, authToken: auth.authToken); guests = ClickUpGuests(endPoint: apiEndpoint, authToken: auth.authToken); lists = ClickUpLists(endPoint: apiEndpoint, authToken: auth.authToken); members = ClickUpMembers(endPoint: apiEndpoint, authToken: auth.authToken); roles = ClickUpRoles(endPoint: apiEndpoint, authToken: auth.authToken); - sharedHierarchy = ClickUpSharedHierarchy( - endPoint: apiEndpoint, authToken: auth.authToken); + sharedHierarchy = ClickUpSharedHierarchy(endPoint: apiEndpoint, authToken: auth.authToken); spaces = ClickUpSpaces(endPoint: apiEndpoint, authToken: auth.authToken); tags = ClickUpTags(endPoint: apiEndpoint, authToken: auth.authToken); tasks = ClickUpTasks(endPoint: apiEndpoint, authToken: auth.authToken); - taskTemplates = - ClickUpTaskTemplates(endPoint: apiEndpoint, authToken: auth.authToken); + taskTemplates = ClickUpTaskTemplates(endPoint: apiEndpoint, authToken: auth.authToken); teams = ClickUpTeams(endPoint: apiEndpoint, authToken: auth.authToken); - timeTrackingLegacy = ClickUpTimeTrackingLegacy( - endPoint: apiEndpoint, authToken: auth.authToken); - timeTrackingV2 = - ClickUpTimeTrackingV2(endPoint: apiEndpoint, authToken: auth.authToken); + timeTrackingLegacy = ClickUpTimeTrackingLegacy(endPoint: apiEndpoint, authToken: auth.authToken); + timeTrackingV2 = ClickUpTimeTrackingV2(endPoint: apiEndpoint, authToken: auth.authToken); users = ClickUpUsers(endPoint: apiEndpoint, authToken: auth.authToken); views = ClickUpViews(endPoint: apiEndpoint, authToken: auth.authToken); - webhooks = - ClickUpWebhooks(endPoint: apiEndpoint, authToken: auth.authToken); + webhooks = ClickUpWebhooks(endPoint: apiEndpoint, authToken: auth.authToken); print("ClickUp Initialized.."); } } diff --git a/lib/src/attachments/attachments.dart b/lib/src/core/endpoints/attachments.dart similarity index 66% rename from lib/src/attachments/attachments.dart rename to lib/src/core/endpoints/attachments.dart index b54a94e..645d881 100644 --- a/lib/src/attachments/attachments.dart +++ b/lib/src/core/endpoints/attachments.dart @@ -1,5 +1,4 @@ import 'dart:convert'; - import 'package:http/http.dart'; class ClickUpAttachments { @@ -14,19 +13,19 @@ class ClickUpAttachments { int? teamID, }) async { try { - final request = MultipartRequest( - "POST", - Uri.parse(useCustomTaskID - ? "$endPoint/task/$taskID/attachment?custom_task_ids=true&team_id=$teamID" - : "$endPoint/task/$taskID/attachment")) - ..headers.addAll({"Authorization": authToken}) + final request = MultipartRequest("POST", Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/attachment?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/attachment")) + ..headers.addAll({ + "Authorization": authToken + }) ..files.add(await MultipartFile.fromPath("attachment", filePath)); final response = await request.send(); final result = await response.stream.bytesToString(); return jsonDecode(result); } catch (e) { print(e); - return {"error": e.toString()}; + return { + "error": e.toString() + }; } } } diff --git a/lib/src/auth/auth.dart b/lib/src/core/endpoints/auth.dart similarity index 100% rename from lib/src/auth/auth.dart rename to lib/src/core/endpoints/auth.dart diff --git a/lib/src/checklists/checklists.dart b/lib/src/core/endpoints/checklists.dart similarity index 100% rename from lib/src/checklists/checklists.dart rename to lib/src/core/endpoints/checklists.dart diff --git a/lib/src/comments/comments.dart b/lib/src/core/endpoints/comments.dart similarity index 100% rename from lib/src/comments/comments.dart rename to lib/src/core/endpoints/comments.dart diff --git a/lib/src/custom_fields/custom_fields.dart b/lib/src/core/endpoints/custom_fields.dart similarity index 100% rename from lib/src/custom_fields/custom_fields.dart rename to lib/src/core/endpoints/custom_fields.dart diff --git a/lib/src/dependencies/dependencies.dart b/lib/src/core/endpoints/dependencies.dart similarity index 100% rename from lib/src/dependencies/dependencies.dart rename to lib/src/core/endpoints/dependencies.dart diff --git a/lib/src/folders/folders.dart b/lib/src/core/endpoints/folders.dart similarity index 100% rename from lib/src/folders/folders.dart rename to lib/src/core/endpoints/folders.dart diff --git a/lib/src/goals/goals.dart b/lib/src/core/endpoints/goals.dart similarity index 100% rename from lib/src/goals/goals.dart rename to lib/src/core/endpoints/goals.dart diff --git a/lib/src/guests/guests.dart b/lib/src/core/endpoints/guests.dart similarity index 100% rename from lib/src/guests/guests.dart rename to lib/src/core/endpoints/guests.dart diff --git a/lib/src/lists/lists.dart b/lib/src/core/endpoints/lists.dart similarity index 100% rename from lib/src/lists/lists.dart rename to lib/src/core/endpoints/lists.dart diff --git a/lib/src/members/members.dart b/lib/src/core/endpoints/members.dart similarity index 100% rename from lib/src/members/members.dart rename to lib/src/core/endpoints/members.dart diff --git a/lib/src/roles/roles.dart b/lib/src/core/endpoints/roles.dart similarity index 100% rename from lib/src/roles/roles.dart rename to lib/src/core/endpoints/roles.dart diff --git a/lib/src/shared_hierarchy/shared_hierarchy.dart b/lib/src/core/endpoints/shared_hierarchy.dart similarity index 100% rename from lib/src/shared_hierarchy/shared_hierarchy.dart rename to lib/src/core/endpoints/shared_hierarchy.dart diff --git a/lib/src/spaces/spaces.dart b/lib/src/core/endpoints/spaces.dart similarity index 100% rename from lib/src/spaces/spaces.dart rename to lib/src/core/endpoints/spaces.dart diff --git a/lib/src/tags/tags.dart b/lib/src/core/endpoints/tags.dart similarity index 100% rename from lib/src/tags/tags.dart rename to lib/src/core/endpoints/tags.dart diff --git a/lib/src/tasks/task_templates.dart b/lib/src/core/endpoints/task_templates.dart similarity index 100% rename from lib/src/tasks/task_templates.dart rename to lib/src/core/endpoints/task_templates.dart diff --git a/lib/src/tasks/tasks.dart b/lib/src/core/endpoints/tasks.dart similarity index 100% rename from lib/src/tasks/tasks.dart rename to lib/src/core/endpoints/tasks.dart diff --git a/lib/src/teams/teams.dart b/lib/src/core/endpoints/teams.dart similarity index 100% rename from lib/src/teams/teams.dart rename to lib/src/core/endpoints/teams.dart diff --git a/lib/src/time_tracking/time_tracking_legacy.dart b/lib/src/core/endpoints/time_tracking_legacy.dart similarity index 100% rename from lib/src/time_tracking/time_tracking_legacy.dart rename to lib/src/core/endpoints/time_tracking_legacy.dart diff --git a/lib/src/time_tracking/time_tracking_v2.dart b/lib/src/core/endpoints/time_tracking_v2.dart similarity index 100% rename from lib/src/time_tracking/time_tracking_v2.dart rename to lib/src/core/endpoints/time_tracking_v2.dart diff --git a/lib/src/users/users.dart b/lib/src/core/endpoints/users.dart similarity index 100% rename from lib/src/users/users.dart rename to lib/src/core/endpoints/users.dart diff --git a/lib/src/views/views.dart b/lib/src/core/endpoints/views.dart similarity index 100% rename from lib/src/views/views.dart rename to lib/src/core/endpoints/views.dart diff --git a/lib/src/webhooks/webhooks.dart b/lib/src/core/endpoints/webhooks.dart similarity index 100% rename from lib/src/webhooks/webhooks.dart rename to lib/src/core/endpoints/webhooks.dart diff --git a/pubspec.yaml b/pubspec.yaml index 5e84558..0c52c5e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,7 +1,7 @@ name: clickup_dart_sdk -description: An API wrapper for ClickUp for creating applications on top of the product. +description: A SDK for ClickUp for integrating or creating applications on top of the product. version: 0.1.0 -repository: https://github.com/ayazemre/clickup-dart +repository: https://github.com/ayazemre/clickup-dart-sdk environment: sdk: '>=2.18.5 <3.0.0' diff --git a/test/clickup_dart_sdk_test.dart b/test/clickup_dart_sdk_test.dart index 0fc46c0..345e2de 100644 --- a/test/clickup_dart_sdk_test.dart +++ b/test/clickup_dart_sdk_test.dart @@ -8,31 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp( - apiEndpoint: - "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") - ..initialize(authToken: token); + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); /// TO-DO: Oauth Testing /// - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); - }); - test('Authorization - Get Authorized Teams', () async { - final teams = await clickUp.auth.getAuthorizedTeams(); - print(teams); - expect(teams.containsKey("teams"), true); - }); - test('Attachments - Create Task Attachment', () async { - final attachment = await clickUp.attachments.createTaskAttachment( - taskID: "8669e046h", - useCustomTaskID: false, - filePath: "./test/beksinski_sample.jpg"); - print(attachment); - expect(attachment.containsKey("message"), true); - }); }); } diff --git a/test/unit/attachment_test.dart b/test/unit/attachment_test.dart new file mode 100644 index 0000000..e66c533 --- /dev/null +++ b/test/unit/attachment_test.dart @@ -0,0 +1,27 @@ +import 'dart:convert'; +import 'package:path/path.dart' as p; + +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Upload an attachment', () async { + final response = await clickUp.attachments.createTaskAttachment(filePath: p.join(p.current, "test", "beksinski_sample.jpg"), taskID: "213123", useCustomTaskID: false); + print(response); + + expect(response, { + 'message': 'Mock server error. Media type multipart/form-data deserialization is not supported.' + }); + }); + }); +} diff --git a/test/unit/auth_test.dart b/test/unit/auth_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/auth_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/checklists_test.dart b/test/unit/checklists_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/checklists_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/comments_test.dart b/test/unit/comments_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/comments_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/custom_fields.test.dart b/test/unit/custom_fields.test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/custom_fields.test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/dependencies_test.dart b/test/unit/dependencies_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/dependencies_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/folders_test.dart b/test/unit/folders_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/folders_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/goals_test.dart b/test/unit/goals_test.dart new file mode 100644 index 0000000..2d60ff5 --- /dev/null +++ b/test/unit/goals_test.dart @@ -0,0 +1,7 @@ +import 'package:test/test.dart'; + +void main() { + test('goals ...', () async { + // TODO: Implement test + }); +} \ No newline at end of file diff --git a/test/unit/guests_test.dart b/test/unit/guests_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/guests_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/lists_test.dart b/test/unit/lists_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/lists_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/members_test.dart b/test/unit/members_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/members_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/roles_test.dart b/test/unit/roles_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/roles_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/shared_hierarchy_test.dart b/test/unit/shared_hierarchy_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/shared_hierarchy_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/spaces_test.dart b/test/unit/spaces_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/spaces_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/tags_test.dart b/test/unit/tags_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/tags_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/task_templates_test.dart b/test/unit/task_templates_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/task_templates_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/tasks_test.dart b/test/unit/tasks_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/tasks_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/teams_test.dart b/test/unit/teams_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/teams_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/time_tracking_legacy_test.dart b/test/unit/time_tracking_legacy_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/time_tracking_legacy_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/time_tracking_v2_test.dart b/test/unit/time_tracking_v2_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/time_tracking_v2_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/users_test.dart b/test/unit/users_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/users_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/views_test.dart b/test/unit/views_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/views_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} diff --git a/test/unit/webhooks_test.dart b/test/unit/webhooks_test.dart new file mode 100644 index 0000000..25fbe3a --- /dev/null +++ b/test/unit/webhooks_test.dart @@ -0,0 +1,20 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('API endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + print(user); + expect(user.containsKey("user"), true); + }); + }); +} From 5058487d3b2b1099e77ec6792c73836595262020 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Wed, 19 Apr 2023 02:53:10 +0300 Subject: [PATCH 03/17] Exception Handling, Unit Tests for Comments --- example/clickup_dart_example.dart | 9 +- lib/src/clickup_dart_base.dart | 15 +- lib/src/core/clickup_exception.dart | 12 ++ lib/src/core/endpoints/attachments.dart | 1 + lib/src/core/endpoints/auth.dart | 49 +++-- lib/src/core/endpoints/checklists.dart | 5 - lib/src/core/endpoints/comments.dart | 179 +++++++++++++++++- lib/src/core/endpoints/task_checklists.dart | 5 + test/unit/auth_test.dart | 5 + test/unit/comments_test.dart | 80 +++++++- ...ts_test.dart => task_checklists_test.dart} | 0 11 files changed, 314 insertions(+), 46 deletions(-) create mode 100644 lib/src/core/clickup_exception.dart delete mode 100644 lib/src/core/endpoints/checklists.dart create mode 100644 lib/src/core/endpoints/task_checklists.dart rename test/unit/{checklists_test.dart => task_checklists_test.dart} (100%) diff --git a/example/clickup_dart_example.dart b/example/clickup_dart_example.dart index a69e69e..9f494c3 100644 --- a/example/clickup_dart_example.dart +++ b/example/clickup_dart_example.dart @@ -3,14 +3,9 @@ import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; void main() async { final token = "pk_testrandomtoken123"; // Initialize with mock server for testing - final clickUp = ClickUp( - apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") - ..initialize(authToken: token); + final clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); - final attachment = await clickUp.attachments.createTaskAttachment( - taskID: "8669e046h", - useCustomTaskID: false, - filePath: "./test/beksinski_sample.jpg"); + final attachment = await clickUp.attachments.createTaskAttachment(taskID: "8669e046h", useCustomTaskID: false, filePath: "./test/beksinski_sample.jpg"); print(attachment); } diff --git a/lib/src/clickup_dart_base.dart b/lib/src/clickup_dart_base.dart index 36046cf..61b0f63 100644 --- a/lib/src/clickup_dart_base.dart +++ b/lib/src/clickup_dart_base.dart @@ -1,6 +1,8 @@ +import 'package:http/http.dart'; + import 'core/endpoints/attachments.dart'; import 'core/endpoints/auth.dart'; -import 'core/endpoints/checklists.dart'; +import 'core/endpoints/task_checklists.dart'; import 'core/endpoints/comments.dart'; import 'core/endpoints/custom_fields.dart'; import 'core/endpoints/dependencies.dart'; @@ -24,10 +26,11 @@ import 'core/endpoints/webhooks.dart'; class ClickUp { late final String apiEndpoint; + late final Client httpClient; late final ClickUpAuth auth; late final ClickUpAttachments attachments; - late final ClickUpChecklists checklists; + late final ClickUpTaskChecklists taskChecklists; late final ClickUpComments comments; late final ClickUpCustomFields customFields; late final ClickUpDependencies dependencies; @@ -54,10 +57,12 @@ class ClickUp { }); void initialize({required String authToken}) async { - auth = ClickUpAuth(endPoint: apiEndpoint, authToken: authToken); + httpClient = Client(); + + auth = ClickUpAuth(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); attachments = ClickUpAttachments(endPoint: apiEndpoint, authToken: auth.authToken); - checklists = ClickUpChecklists(endPoint: apiEndpoint, authToken: auth.authToken); - comments = ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken); + taskChecklists = ClickUpTaskChecklists(endPoint: apiEndpoint, authToken: auth.authToken); + comments = ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); customFields = ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken); dependencies = ClickUpDependencies(endPoint: apiEndpoint, authToken: auth.authToken); folders = ClickUpFolders(endPoint: apiEndpoint, authToken: auth.authToken); diff --git a/lib/src/core/clickup_exception.dart b/lib/src/core/clickup_exception.dart new file mode 100644 index 0000000..82dec63 --- /dev/null +++ b/lib/src/core/clickup_exception.dart @@ -0,0 +1,12 @@ +enum ClickUpExceptionType { + invalidModel, + invalidRequest, + unauthorized +} + +class ClickUpException implements Exception { + ClickUpException({required this.exceptionType, required this.exceptionMessage}); + + final ClickUpExceptionType exceptionType; + final String exceptionMessage; +} diff --git a/lib/src/core/endpoints/attachments.dart b/lib/src/core/endpoints/attachments.dart index 645d881..3d72d1a 100644 --- a/lib/src/core/endpoints/attachments.dart +++ b/lib/src/core/endpoints/attachments.dart @@ -5,6 +5,7 @@ class ClickUpAttachments { ClickUpAttachments({required this.endPoint, required this.authToken}); final String endPoint; final String authToken; + late Client httpClient; Future> createTaskAttachment({ required String taskID, diff --git a/lib/src/core/endpoints/auth.dart b/lib/src/core/endpoints/auth.dart index 421978a..c4766dc 100644 --- a/lib/src/core/endpoints/auth.dart +++ b/lib/src/core/endpoints/auth.dart @@ -4,48 +4,55 @@ import 'package:http/http.dart'; class ClickUpAuth { late String endPoint; late String authToken; + late Client httpClient; - ClickUpAuth({required this.endPoint, required this.authToken}); + ClickUpAuth({required this.endPoint, required this.authToken, required this.httpClient}); /// Get access token based on your credentials. - Future getAccessToken( - {required String clientID, - required String clientSecret, - required String code}) async { - try { - final response = await post(Uri.parse( - "$endPoint/oauth/token?client_id=$clientID&client_secret=$clientSecret&code=$code")); - print(response.body); - return response.body; - } catch (e) { - print(e.toString()); - return e.toString(); - } - } + // Future getAccessToken( + // {required String clientID, + // required String clientSecret, + // required String code}) async { + // try { + // final response = await post(Uri.parse( + // "$endPoint/oauth/token?client_id=$clientID&client_secret=$clientSecret&code=$code")); + // print(response.body); + // return response.body; + // } catch (e) { + // print(e.toString()); + // return e.toString(); + // } + // } /// Get the user bound to the token. Future> getAuthorizedUser() async { try { - final response = await get(Uri.parse("$endPoint/user"), - headers: {"Authorization": authToken}); + final response = await httpClient.get(Uri.parse("$endPoint/user"), headers: { + "Authorization": authToken + }); final user = jsonDecode(response.body); return user; } catch (e) { print(e.toString()); - return {"error": "$e"}; + return { + "error": "$e" + }; } } /// Get the teams bound to authorized user. Future> getAuthorizedTeams() async { try { - final response = await get(Uri.parse("$endPoint/team"), - headers: {"Authorization": authToken}); + final response = await httpClient.get(Uri.parse("$endPoint/team"), headers: { + "Authorization": authToken + }); final teams = jsonDecode(response.body); return teams; } catch (e) { print(e.toString()); - return {"error": "$e"}; + return { + "error": "$e" + }; } } } diff --git a/lib/src/core/endpoints/checklists.dart b/lib/src/core/endpoints/checklists.dart deleted file mode 100644 index 59b821d..0000000 --- a/lib/src/core/endpoints/checklists.dart +++ /dev/null @@ -1,5 +0,0 @@ -class ClickUpChecklists { - late String endPoint; - late String authToken; - ClickUpChecklists({required this.endPoint, required this.authToken}); -} diff --git a/lib/src/core/endpoints/comments.dart b/lib/src/core/endpoints/comments.dart index 0c94422..70fc4aa 100644 --- a/lib/src/core/endpoints/comments.dart +++ b/lib/src/core/endpoints/comments.dart @@ -1,11 +1,13 @@ import 'dart:convert'; +import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; import 'package:http/http.dart'; class ClickUpComments { late String endPoint; late String authToken; - ClickUpComments({required this.endPoint, required this.authToken}); + late Client httpClient; + ClickUpComments({required this.endPoint, required this.authToken, required this.httpClient}); Future> getTaskComments({ required String taskID, @@ -15,13 +17,182 @@ class ClickUpComments { String? startID, }) async { try { - final response = await get(Uri.parse("$endPoint/task/$taskID/comment"), - headers: {"Authorization": authToken}); + final response = await httpClient.get(Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/comment?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/comment"), headers: { + "Authorization": authToken + }); final comments = jsonDecode(response.body); return comments; } catch (e) { print(e.toString()); - return {"error": "$e"}; + return { + "error": "$e" + }; + } + } + + /// Creates a comment on specific task in your space. Map model for the comment parameter is; + /// + /// ``` + /// { + /// "comment_text": "This is my sample comment", // Should be String. + /// "assignee": 123456, // Should be an int ID of the assignee. + /// "notify_all": false // Should be a boolean. + /// } + /// ``` + + Future> createTaskComment({ + required String taskID, + required Map comment, + bool useCustomTaskID = false, + int? teamID, + }) async { + if (!comment.containsKey("comment_text") && !comment.containsKey("assignee") && !comment.containsKey("notify_all")) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + } + try { + final response = await httpClient.post(Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/comment?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/comment"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(comment)); + final createdComment = jsonDecode(response.body); + return createdComment; + } catch (e) { + print(e.toString()); + return { + "error": "$e" + }; + } + } + + Future> getChatViewComments({ + required String viewID, + int? start, + String? startID, + }) async { + try { + final response = await httpClient.get(Uri.parse(start != null && startID != null ? "$endPoint/view/$viewID/comment?start=$start&start_id=$startID" : "$endPoint/view/$viewID/comment"), headers: { + "Authorization": authToken, + }); + final createdComment = jsonDecode(response.body); + return createdComment; + } catch (e) { + print(e.toString()); + return { + "error": "$e" + }; + } + } + + Future> createChatViewComment({ + required String viewID, + required Map comment, + }) async { + if (!comment.containsKey("comment_text") && !comment.containsKey("notify_all")) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + } + try { + final response = await httpClient.post(Uri.parse("$endPoint/view/$viewID/comment"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(comment)); + final createdComment = jsonDecode(response.body); + return createdComment; + } catch (e) { + print(e.toString()); + return { + "error": "$e" + }; + } + } + + Future> getListComments({ + required double listID, + int? start, + String? startID, + }) async { + try { + final response = await httpClient.get(Uri.parse(start != null && startID != null ? "$endPoint/list/$listID/comment?start=$start&start_id=$startID" : "$endPoint/list/$listID/comment"), headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); + final createdComment = jsonDecode(response.body); + return createdComment; + } catch (e) { + print(e.toString()); + return { + "error": "$e" + }; + } + } + + Future> createListComment({ + required String listID, + required Map comment, + }) async { + if (!comment.containsKey("comment_text") && !comment.containsKey("assignee") && !comment.containsKey("notify_all")) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + } + + try { + final response = await httpClient.post(Uri.parse("$endPoint/list/$listID/comment"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(comment)); + final createdComment = jsonDecode(response.body); + return createdComment; + } catch (e) { + print(e.toString()); + return { + "error": "$e" + }; + } + } + + Future> updateComment({ + required double commentID, + required Map comment, + }) async { + if (!comment.containsKey("comment_text") && !comment.containsKey("assignee") && !comment.containsKey("resolved")) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + } + try { + final response = await httpClient.put(Uri.parse("$endPoint/comment/$commentID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(comment)); + final createdComment = jsonDecode(response.body); + return createdComment; + } catch (e) { + print(e.toString()); + return { + "error": "$e" + }; + } + } + + Future> deleteComment({ + required double commentID, + }) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/comment/$commentID"), headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); + final createdComment = jsonDecode(response.body); + return createdComment; + } catch (e) { + print(e.toString()); + return { + "error": "$e" + }; } } } diff --git a/lib/src/core/endpoints/task_checklists.dart b/lib/src/core/endpoints/task_checklists.dart new file mode 100644 index 0000000..149e12b --- /dev/null +++ b/lib/src/core/endpoints/task_checklists.dart @@ -0,0 +1,5 @@ +class ClickUpTaskChecklists { + late String endPoint; + late String authToken; + ClickUpTaskChecklists({required this.endPoint, required this.authToken}); +} diff --git a/test/unit/auth_test.dart b/test/unit/auth_test.dart index 25fbe3a..6dc3eb8 100644 --- a/test/unit/auth_test.dart +++ b/test/unit/auth_test.dart @@ -16,5 +16,10 @@ void main() { print(user); expect(user.containsKey("user"), true); }); + test('Authorization - Get Authorized Teams(Workspaces)', () async { + final teams = await clickUp.auth.getAuthorizedTeams(); + print(teams); + expect(teams.containsKey("teams"), true); + }); }); } diff --git a/test/unit/comments_test.dart b/test/unit/comments_test.dart index 25fbe3a..21e4d80 100644 --- a/test/unit/comments_test.dart +++ b/test/unit/comments_test.dart @@ -1,4 +1,5 @@ import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; import 'package:test/test.dart'; void main() { @@ -11,10 +12,81 @@ void main() { clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); + test('Comments - Get Task Comments', () async { + final taskComments = await clickUp.comments.getTaskComments(taskID: "a1b2c3"); + expect(taskComments.containsKey("comments"), true); + }); + test('Comments - Create Task Comment', () async { + final createdComment = await clickUp.comments.createTaskComment(taskID: "a1b2c3", comment: { + "comment_text": "Hi I am Emre", + "assignee": 123456, + "notify_all": true + }); + expect(createdComment.containsKey("id"), true); + }); + test('Comments - Create Task Comment - Invalid Data', () async { + expect(() async => await clickUp.comments.createTaskComment(taskID: "a1b2c3", comment: {}), throwsA(isA())); + }); + + test('Comments - Get Chat View Comments - Last 25', () async { + final chatViewComments = await clickUp.comments.getChatViewComments(viewID: "12345"); + print(chatViewComments); + expect(chatViewComments.containsKey("comments"), true); + }); + test('Comments - Get Chat View Comments - Custom Range', () async { + final chatViewComments = await clickUp.comments.getChatViewComments(viewID: "12345", start: 3, startID: "12345"); + print(chatViewComments); + expect(chatViewComments.containsKey("comments"), true); + }); + test('Comments - Create Chat View Comment', () async { + final createdChatViewComment = await clickUp.comments.createChatViewComment(viewID: "12345", comment: { + "comment_text": "Hi I am Emre", + "notify_all": true + }); + print(createdChatViewComment); + expect(createdChatViewComment.containsKey("id"), true); + }); + test('Comments - Create Chat View Comment - Invalid Data', () async { + expect(() async => await clickUp.comments.createChatViewComment(viewID: "12345", comment: {}), throwsA(isA())); + }); + test('Comments - Get List Comments - Last 25', () async { + final listComments = await clickUp.comments.getListComments(listID: 12345); + print(listComments); + expect(listComments.containsKey("comments"), true); + }); + test('Comments - Get List Comments - Custom Range', () async { + final listComments = await clickUp.comments.getListComments(listID: 12345, start: 2, startID: "123"); + print(listComments); + expect(listComments.containsKey("comments"), true); + }); + + test('Comments - Create List Comment', () async { + final listComment = await clickUp.comments.createListComment(listID: "12345", comment: { + "comment_text": "Hi I am Emre", + "assignee": 123456, + "notify_all": true + }); + expect(listComment.containsKey("id"), true); + }); + test('Comments - Create List Comment - Invalid Data', () async { + expect(() async => await clickUp.comments.createListComment(listID: "12345", comment: {}), throwsA(isA())); + }); + test('Comments - Update Comment', () async { + final updatedComment = await clickUp.comments.updateComment(commentID: 1234, comment: { + "comment_text": "Hi I am Emre", + "assignee": 123456, + "resolved": true + }); + print(updatedComment); + expect(updatedComment.isEmpty, true); + }); + test('Comments - Update Comment - Invalid Data', () async { + expect(() async => await clickUp.comments.updateComment(commentID: 1234, comment: {}), throwsA(isA())); + }); + test('Comments - Delete Comment', () async { + final deletedComment = await clickUp.comments.deleteComment(commentID: 1234); + print(deletedComment); + expect(deletedComment.isEmpty, true); }); }); } diff --git a/test/unit/checklists_test.dart b/test/unit/task_checklists_test.dart similarity index 100% rename from test/unit/checklists_test.dart rename to test/unit/task_checklists_test.dart From b0e7fd5099d047d48e948fb6bb8002d204036380 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Wed, 19 Apr 2023 02:53:42 +0300 Subject: [PATCH 04/17] version update --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 0c52c5e..5546e44 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: clickup_dart_sdk description: A SDK for ClickUp for integrating or creating applications on top of the product. -version: 0.1.0 +version: 0.2.0 repository: https://github.com/ayazemre/clickup-dart-sdk environment: From 6d4993b24661e111faf07305355a0af6d5fe2df2 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Thu, 20 Apr 2023 05:17:48 +0300 Subject: [PATCH 05/17] Custom Fields Done with Tests --- lib/src/clickup_dart_base.dart | 2 +- lib/src/core/clickup_exception.dart | 2 +- lib/src/core/endpoints/attachments.dart | 6 +- lib/src/core/endpoints/auth.dart | 9 +- lib/src/core/endpoints/comments.dart | 34 +--- lib/src/core/endpoints/custom_fields.dart | 204 +++++++++++++++++++++- test/unit/attachment_test.dart | 6 +- test/unit/auth_test.dart | 6 +- test/unit/comments_test.dart | 16 +- test/unit/custom_fields.test.dart | 20 --- test/unit/custom_fields_test.dart | 60 +++++++ 11 files changed, 291 insertions(+), 74 deletions(-) delete mode 100644 test/unit/custom_fields.test.dart create mode 100644 test/unit/custom_fields_test.dart diff --git a/lib/src/clickup_dart_base.dart b/lib/src/clickup_dart_base.dart index 61b0f63..cebf063 100644 --- a/lib/src/clickup_dart_base.dart +++ b/lib/src/clickup_dart_base.dart @@ -63,7 +63,7 @@ class ClickUp { attachments = ClickUpAttachments(endPoint: apiEndpoint, authToken: auth.authToken); taskChecklists = ClickUpTaskChecklists(endPoint: apiEndpoint, authToken: auth.authToken); comments = ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); - customFields = ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken); + customFields = ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); dependencies = ClickUpDependencies(endPoint: apiEndpoint, authToken: auth.authToken); folders = ClickUpFolders(endPoint: apiEndpoint, authToken: auth.authToken); goals = ClickUpGoals(endPoint: apiEndpoint, authToken: auth.authToken); diff --git a/lib/src/core/clickup_exception.dart b/lib/src/core/clickup_exception.dart index 82dec63..58dddde 100644 --- a/lib/src/core/clickup_exception.dart +++ b/lib/src/core/clickup_exception.dart @@ -1,6 +1,6 @@ enum ClickUpExceptionType { invalidModel, - invalidRequest, + requestError, unauthorized } diff --git a/lib/src/core/endpoints/attachments.dart b/lib/src/core/endpoints/attachments.dart index 3d72d1a..2595aee 100644 --- a/lib/src/core/endpoints/attachments.dart +++ b/lib/src/core/endpoints/attachments.dart @@ -1,6 +1,8 @@ import 'dart:convert'; import 'package:http/http.dart'; +import '../clickup_exception.dart'; + class ClickUpAttachments { ClickUpAttachments({required this.endPoint, required this.authToken}); final String endPoint; @@ -24,9 +26,7 @@ class ClickUpAttachments { return jsonDecode(result); } catch (e) { print(e); - return { - "error": e.toString() - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/auth.dart b/lib/src/core/endpoints/auth.dart index c4766dc..32340d9 100644 --- a/lib/src/core/endpoints/auth.dart +++ b/lib/src/core/endpoints/auth.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; import 'package:http/http.dart'; class ClickUpAuth { @@ -34,9 +35,7 @@ class ClickUpAuth { return user; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -50,9 +49,7 @@ class ClickUpAuth { return teams; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/comments.dart b/lib/src/core/endpoints/comments.dart index 70fc4aa..f8182be 100644 --- a/lib/src/core/endpoints/comments.dart +++ b/lib/src/core/endpoints/comments.dart @@ -24,9 +24,7 @@ class ClickUpComments { return comments; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -35,7 +33,7 @@ class ClickUpComments { /// ``` /// { /// "comment_text": "This is my sample comment", // Should be String. - /// "assignee": 123456, // Should be an int ID of the assignee. + /// "assignee": 123456, // Should be an int. /// "notify_all": false // Should be a boolean. /// } /// ``` @@ -60,9 +58,7 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -79,9 +75,7 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -103,9 +97,7 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -123,9 +115,7 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -148,9 +138,7 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -172,9 +160,7 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } @@ -190,9 +176,7 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - return { - "error": "$e" - }; + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/custom_fields.dart b/lib/src/core/endpoints/custom_fields.dart index 6788af1..328a8ca 100644 --- a/lib/src/core/endpoints/custom_fields.dart +++ b/lib/src/core/endpoints/custom_fields.dart @@ -1,6 +1,208 @@ +import 'dart:convert'; +import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; +import 'package:http/http.dart'; + +enum CustomFieldType { + url, + number +} + class ClickUpCustomFields { late String endPoint; late String authToken; + late Client httpClient; + + ClickUpCustomFields({required this.endPoint, required this.authToken, required this.httpClient}); + + Future> getAccessibleCustomFields({required String listID}) async { + try { + final response = await httpClient.get(Uri.parse("$endPoint/list/$listID/field"), headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); + final customFields = jsonDecode(response.body); + return customFields; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Sets the Custom Field to functions value parameter. You'll need to know the "task_id" of the task you want to update, and the universal unique identifier (UUID) "field_id" of the Custom Field you want to set. Value must be one of the following depending of the field type; + /// + /// URL Custom Field: + /// ``` + /// { + /// "value": "This is sample URL", // Should be String. + /// } + /// ``` + /// + /// Dropdown Custom Field: + /// + /// Enter the universal unique identifier (UUID) of the dropdown menu option you want to set. You can find the UUIDs available for each getAccessibleCustomFields function. + /// ``` + /// { + /// "value": "03efda77-c7a0-42d3-8afd-fd546353c2f5", // Should be String. + /// } + /// ``` + /// + /// Email Custom Field: + /// ``` + /// { + /// "value": "example@example.com", // Should be String. + /// } + /// ``` + /// + /// Phone Custom Field: + /// ``` + /// { + /// "value": "+0 123 456 78 90", // Should be String. + /// } + /// ``` + /// + /// Date Custom Field: + /// + /// The value must be Unix time in milliseconds. To display the time in a Date Custom Field in ClickUp, you must include time: true in the value_options property. + /// ``` + /// { + /// "value":123456787, // Should be int. + /// "value_options": {"time": true} // Should be an Map. + /// } + /// ``` + /// + /// Short or Long Text Custom Field: + /// ``` + /// { + /// "value": "This is a sample text", // Should be String. + /// } + /// ``` + /// + /// Number Custom Field: + /// ``` + /// { + /// "value": 12345678, // Should be int. + /// } + /// ``` + /// + /// Money Custom Field: + /// + /// You can set an amount, but not the currency of a Money Custom Field via the SDK. You can check the currency of a Money Custom Field using getAccessibleCustomFields function. + /// ``` + /// { + /// "value": 12345678, // Should be int. + /// } + /// ``` + /// + /// Task Relationship Custom Field: + /// + /// Enter an array of task ids in the "add" property to add them to a Task Relationship Custom Field. Enter them into the "rem" property to remove tasks from the Relationship. + /// ``` + /// { + /// "value": { + /// "add": [ + /// "abcd1234", // Should be String. + /// "efghi5678" // Should be String. + /// ], + /// "rem": [ + /// "jklm9876", // Should be String. + /// "yuiop5678" // Should be String. + /// ] + /// } + /// } + /// ``` + /// People Custom Field: + /// + /// Enter an array of user ids in the add property to "add" them to a People Custom Field. Enter them into the "rem" property to remove users from a People Custom Field. You can get a list of people in the Workspace using getAuthorizedTeams function in workspaces. + /// ``` + /// { + /// "value": { + /// "add": [ + /// 123, // Should be int. + /// 456 // Should be int. + /// ], + /// "rem": [ + /// 987, // Should be int. + /// 765 // Should be int. + /// ] + /// } + /// } + /// ``` + /// Emoji (Rating) Custom Field: + /// + /// Enter an integer that is greater than or equal to zero and where the count property is greater than or equal to the value. You can find the count property for each Emoji (Rating) Custom Field using getAccessibleCustomFields function. + /// ``` + /// { + /// "value": 12345678, // Should be int. + /// } + /// ``` + /// Manual Progress Custom Field: + /// + /// Enter a number between the "start" and "end" values of each Manual Progress Custom Field. For example, for a field with "start": "10" and "end": "30", sending "current": "20" will be displayed as 50% complete in ClickUp. You can find the start and end values for each Manual Progress Custom Field using getAccessibleCustomFields function. + /// ``` + /// { + /// "value": { + /// "current": 50 // Should be int. + /// }, // Should be an Map. + /// } + /// ``` + /// + /// Label Custom Field: + /// + /// Enter an array of the universal unique identifiers (UUIDs) of the labels you want to apply. You can find the UUIDs available for each Label Custom Field using getAccessibleCustomFields function. + /// ``` + /// { + /// "value": ["03efda77-c7a0-42d3-8afd-fd546353c2f5", "30efda77-c7a0-42d3-8afd-fd546353c4a3"], // Should be array of Strings. + /// } + /// ``` + /// + /// Location Custom Field: + /// + /// Include the latitude, longitude, and formatted address as defined in the Google Maps Geocoding API. + /// ``` + /// { + /// "value":{ + /// "location": { + /// "lat": 1234, // Should be int. + /// "lng": 1234 // Should be int. + /// }, // Should be Map. + /// "formatted_address":"This is a sample address." // Should be String. + /// }, // Should be Map. + /// } + /// ``` + Future> setCustomFieldValue({required String taskID, required String fieldID, required Map value, bool customTaskID = false, double? teamID}) async { + if (!value.containsKey("value")) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your value model is invalid. Please read the function documentation."); + } + + try { + final response = await httpClient.post(Uri.parse(customTaskID ? "$endPoint/task/$taskID/field/$fieldID?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/field/$fieldID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(value)); + final customFieldResponse = jsonDecode(response.body); + return customFieldResponse; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } - ClickUpCustomFields({required this.endPoint, required this.authToken}); + Future> removeCustomFieldValue({required String taskID, required String fieldID, bool customTaskID = false, double? teamID}) async { + try { + final response = await httpClient.delete( + Uri.parse(customTaskID ? "$endPoint/task/$taskID/field/$fieldID?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/field/$fieldID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + ); + final customFieldResponse = jsonDecode(response.body); + return customFieldResponse; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/test/unit/attachment_test.dart b/test/unit/attachment_test.dart index e66c533..3139f4c 100644 --- a/test/unit/attachment_test.dart +++ b/test/unit/attachment_test.dart @@ -8,17 +8,15 @@ void main() { late String token; late ClickUp clickUp; - group('API endpoint Tests', () { + group('Attachment Test', () { setUp(() async { - // Additional setup goes here. + // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. token = "pk_qwerty123456"; clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); test('Upload an attachment', () async { final response = await clickUp.attachments.createTaskAttachment(filePath: p.join(p.current, "test", "beksinski_sample.jpg"), taskID: "213123", useCustomTaskID: false); - print(response); - expect(response, { 'message': 'Mock server error. Media type multipart/form-data deserialization is not supported.' }); diff --git a/test/unit/auth_test.dart b/test/unit/auth_test.dart index 6dc3eb8..7aae6d8 100644 --- a/test/unit/auth_test.dart +++ b/test/unit/auth_test.dart @@ -4,21 +4,19 @@ import 'package:test/test.dart'; void main() { late String token; late ClickUp clickUp; - group('API endpoint Tests', () { + group('Authorization Tests', () { setUp(() async { - // Additional setup goes here. + // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. token = "pk_qwerty123456"; clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { final user = await clickUp.auth.getAuthorizedUser(); - print(user); expect(user.containsKey("user"), true); }); test('Authorization - Get Authorized Teams(Workspaces)', () async { final teams = await clickUp.auth.getAuthorizedTeams(); - print(teams); expect(teams.containsKey("teams"), true); }); }); diff --git a/test/unit/comments_test.dart b/test/unit/comments_test.dart index 21e4d80..f6116f9 100644 --- a/test/unit/comments_test.dart +++ b/test/unit/comments_test.dart @@ -5,9 +5,9 @@ import 'package:test/test.dart'; void main() { late String token; late ClickUp clickUp; - group('API endpoint Tests', () { + group('Comments Tests', () { setUp(() async { - // Additional setup goes here. + // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. token = "pk_qwerty123456"; clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); @@ -30,12 +30,12 @@ void main() { test('Comments - Get Chat View Comments - Last 25', () async { final chatViewComments = await clickUp.comments.getChatViewComments(viewID: "12345"); - print(chatViewComments); + expect(chatViewComments.containsKey("comments"), true); }); test('Comments - Get Chat View Comments - Custom Range', () async { final chatViewComments = await clickUp.comments.getChatViewComments(viewID: "12345", start: 3, startID: "12345"); - print(chatViewComments); + expect(chatViewComments.containsKey("comments"), true); }); test('Comments - Create Chat View Comment', () async { @@ -43,7 +43,7 @@ void main() { "comment_text": "Hi I am Emre", "notify_all": true }); - print(createdChatViewComment); + expect(createdChatViewComment.containsKey("id"), true); }); test('Comments - Create Chat View Comment - Invalid Data', () async { @@ -51,12 +51,12 @@ void main() { }); test('Comments - Get List Comments - Last 25', () async { final listComments = await clickUp.comments.getListComments(listID: 12345); - print(listComments); + expect(listComments.containsKey("comments"), true); }); test('Comments - Get List Comments - Custom Range', () async { final listComments = await clickUp.comments.getListComments(listID: 12345, start: 2, startID: "123"); - print(listComments); + expect(listComments.containsKey("comments"), true); }); @@ -77,7 +77,6 @@ void main() { "assignee": 123456, "resolved": true }); - print(updatedComment); expect(updatedComment.isEmpty, true); }); test('Comments - Update Comment - Invalid Data', () async { @@ -85,7 +84,6 @@ void main() { }); test('Comments - Delete Comment', () async { final deletedComment = await clickUp.comments.deleteComment(commentID: 1234); - print(deletedComment); expect(deletedComment.isEmpty, true); }); }); diff --git a/test/unit/custom_fields.test.dart b/test/unit/custom_fields.test.dart deleted file mode 100644 index 25fbe3a..0000000 --- a/test/unit/custom_fields.test.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; -import 'package:test/test.dart'; - -void main() { - late String token; - late ClickUp clickUp; - group('API endpoint Tests', () { - setUp(() async { - // Additional setup goes here. - token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); - }); - - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); - }); - }); -} diff --git a/test/unit/custom_fields_test.dart b/test/unit/custom_fields_test.dart new file mode 100644 index 0000000..38bca74 --- /dev/null +++ b/test/unit/custom_fields_test.dart @@ -0,0 +1,60 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + + group('Custom Fields Tests', () { + setUp(() async { + // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + // Tests are run for just getting the fields and updating the URL field. Remaining field types are dependent on the model and all of the models actually return success. This means testing for only one field type should be enough. + test('Custom Fields - Get Accessible Custom Fields', () async { + final customFields = await clickUp.customFields.getAccessibleCustomFields(listID: "1234"); + expect(customFields.containsKey("fields"), true); + }); + + test('Custom Fields - Set Custom Field Value - URL Custom Field', () async { + final customField = await clickUp.customFields.setCustomFieldValue(fieldID: "1234", taskID: "1234", value: { + "value": "https://ayazemre.com" + }); + print(customField); + expect(customField.isEmpty, true); + }); + test('Custom Fields - Set Custom Field Value - URL Custom Field - Custom Task ID', () async { + final customField = await clickUp.customFields.setCustomFieldValue( + fieldID: "1234", + taskID: "1234", + value: { + "value": "https://ayazemre.com" + }, + customTaskID: true, + teamID: 1234); + expect(customField.isEmpty, true); + }); + test('Custom Fields - Set Custom Field Value - Wrong Data Model', () async { + expect( + () async => await clickUp.customFields.setCustomFieldValue( + fieldID: "1234", + taskID: "1234", + value: { + "valeu": "https://ayazemre.com" + }, + customTaskID: true, + teamID: 1234), + throwsA(isA())); + }); + test('Custom Fields - Remove Custom Field Value', () async { + final result = await clickUp.customFields.removeCustomFieldValue(fieldID: "1234", taskID: "1234"); + expect(result.isEmpty, true); + }); + test('Custom Fields - Remove Custom Field Value - Custom Task ID', () async { + final result = await clickUp.customFields.removeCustomFieldValue(fieldID: "1234", taskID: "1234", customTaskID: true, teamID: 1234); + expect(result.isEmpty, true); + }); + }); +} From 403888caa6f2674cecd7f100db9080d39aab58f7 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Sun, 23 Apr 2023 06:16:07 +0300 Subject: [PATCH 06/17] Space Endpoint --- lib/src/clickup_dart_base.dart | 46 +++--- lib/src/core/endpoints/attachments.dart | 2 +- lib/src/core/endpoints/dependencies.dart | 6 - lib/src/core/endpoints/folders.dart | 84 +++++++++- lib/src/core/endpoints/goals.dart | 5 +- lib/src/core/endpoints/guests.dart | 5 +- lib/src/core/endpoints/lists.dart | 5 +- lib/src/core/endpoints/members.dart | 5 +- lib/src/core/endpoints/roles.dart | 5 +- lib/src/core/endpoints/shared_hierarchy.dart | 5 +- lib/src/core/endpoints/spaces.dart | 143 +++++++++++++++++- lib/src/core/endpoints/tags.dart | 5 +- lib/src/core/endpoints/task_checklists.dart | 5 +- .../core/endpoints/task_relationships.dart | 9 ++ lib/src/core/endpoints/task_templates.dart | 9 +- lib/src/core/endpoints/tasks.dart | 9 +- lib/src/core/endpoints/teams.dart | 9 +- .../core/endpoints/time_tracking_legacy.dart | 9 +- lib/src/core/endpoints/time_tracking_v2.dart | 9 +- lib/src/core/endpoints/users.dart | 9 +- lib/src/core/endpoints/views.dart | 9 +- lib/src/core/endpoints/webhooks.dart | 5 +- test/unit/folders_test.dart | 29 +++- test/unit/spaces_test.dart | 37 ++++- ...cies_test.dart => task_relationships.dart} | 0 25 files changed, 392 insertions(+), 72 deletions(-) delete mode 100644 lib/src/core/endpoints/dependencies.dart create mode 100644 lib/src/core/endpoints/task_relationships.dart rename test/unit/{dependencies_test.dart => task_relationships.dart} (100%) diff --git a/lib/src/clickup_dart_base.dart b/lib/src/clickup_dart_base.dart index cebf063..e7efb4f 100644 --- a/lib/src/clickup_dart_base.dart +++ b/lib/src/clickup_dart_base.dart @@ -5,7 +5,7 @@ import 'core/endpoints/auth.dart'; import 'core/endpoints/task_checklists.dart'; import 'core/endpoints/comments.dart'; import 'core/endpoints/custom_fields.dart'; -import 'core/endpoints/dependencies.dart'; +import 'core/endpoints/task_relationships.dart'; import 'core/endpoints/folders.dart'; import 'core/endpoints/goals.dart'; import 'core/endpoints/guests.dart'; @@ -30,10 +30,8 @@ class ClickUp { late final ClickUpAuth auth; late final ClickUpAttachments attachments; - late final ClickUpTaskChecklists taskChecklists; late final ClickUpComments comments; late final ClickUpCustomFields customFields; - late final ClickUpDependencies dependencies; late final ClickUpFolders folders; late final ClickUpGoals goals; late final ClickUpGuests guests; @@ -44,6 +42,8 @@ class ClickUp { late final ClickUpSpaces spaces; late final ClickUpTags tags; late final ClickUpTasks tasks; + late final ClickUpTaskRelationships taskRelationships; + late final ClickUpTaskChecklists taskChecklists; late final ClickUpTaskTemplates taskTemplates; late final ClickUpTeams teams; late final ClickUpTimeTrackingLegacy timeTrackingLegacy; @@ -60,28 +60,28 @@ class ClickUp { httpClient = Client(); auth = ClickUpAuth(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - attachments = ClickUpAttachments(endPoint: apiEndpoint, authToken: auth.authToken); - taskChecklists = ClickUpTaskChecklists(endPoint: apiEndpoint, authToken: auth.authToken); + attachments = ClickUpAttachments(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); comments = ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); customFields = ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); - dependencies = ClickUpDependencies(endPoint: apiEndpoint, authToken: auth.authToken); - folders = ClickUpFolders(endPoint: apiEndpoint, authToken: auth.authToken); - goals = ClickUpGoals(endPoint: apiEndpoint, authToken: auth.authToken); - guests = ClickUpGuests(endPoint: apiEndpoint, authToken: auth.authToken); - lists = ClickUpLists(endPoint: apiEndpoint, authToken: auth.authToken); - members = ClickUpMembers(endPoint: apiEndpoint, authToken: auth.authToken); - roles = ClickUpRoles(endPoint: apiEndpoint, authToken: auth.authToken); - sharedHierarchy = ClickUpSharedHierarchy(endPoint: apiEndpoint, authToken: auth.authToken); - spaces = ClickUpSpaces(endPoint: apiEndpoint, authToken: auth.authToken); - tags = ClickUpTags(endPoint: apiEndpoint, authToken: auth.authToken); - tasks = ClickUpTasks(endPoint: apiEndpoint, authToken: auth.authToken); - taskTemplates = ClickUpTaskTemplates(endPoint: apiEndpoint, authToken: auth.authToken); - teams = ClickUpTeams(endPoint: apiEndpoint, authToken: auth.authToken); - timeTrackingLegacy = ClickUpTimeTrackingLegacy(endPoint: apiEndpoint, authToken: auth.authToken); - timeTrackingV2 = ClickUpTimeTrackingV2(endPoint: apiEndpoint, authToken: auth.authToken); - users = ClickUpUsers(endPoint: apiEndpoint, authToken: auth.authToken); - views = ClickUpViews(endPoint: apiEndpoint, authToken: auth.authToken); - webhooks = ClickUpWebhooks(endPoint: apiEndpoint, authToken: auth.authToken); + folders = ClickUpFolders(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + goals = ClickUpGoals(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + guests = ClickUpGuests(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + lists = ClickUpLists(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + members = ClickUpMembers(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + roles = ClickUpRoles(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + sharedHierarchy = ClickUpSharedHierarchy(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + spaces = ClickUpSpaces(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + tags = ClickUpTags(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + tasks = ClickUpTasks(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskChecklists = ClickUpTaskChecklists(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskRelationships = ClickUpTaskRelationships(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskTemplates = ClickUpTaskTemplates(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + teams = ClickUpTeams(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + timeTrackingLegacy = ClickUpTimeTrackingLegacy(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + timeTrackingV2 = ClickUpTimeTrackingV2(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + users = ClickUpUsers(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + views = ClickUpViews(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + webhooks = ClickUpWebhooks(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); print("ClickUp Initialized.."); } } diff --git a/lib/src/core/endpoints/attachments.dart b/lib/src/core/endpoints/attachments.dart index 2595aee..978abc6 100644 --- a/lib/src/core/endpoints/attachments.dart +++ b/lib/src/core/endpoints/attachments.dart @@ -4,7 +4,7 @@ import 'package:http/http.dart'; import '../clickup_exception.dart'; class ClickUpAttachments { - ClickUpAttachments({required this.endPoint, required this.authToken}); + ClickUpAttachments({required this.endPoint, required this.authToken, required this.httpClient}); final String endPoint; final String authToken; late Client httpClient; diff --git a/lib/src/core/endpoints/dependencies.dart b/lib/src/core/endpoints/dependencies.dart deleted file mode 100644 index accde90..0000000 --- a/lib/src/core/endpoints/dependencies.dart +++ /dev/null @@ -1,6 +0,0 @@ -class ClickUpDependencies { - late String endPoint; - late String authToken; - - ClickUpDependencies({required this.endPoint, required this.authToken}); -} diff --git a/lib/src/core/endpoints/folders.dart b/lib/src/core/endpoints/folders.dart index eb24c22..ce01a24 100644 --- a/lib/src/core/endpoints/folders.dart +++ b/lib/src/core/endpoints/folders.dart @@ -1,6 +1,88 @@ +import 'dart:convert'; + +import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; +import 'package:http/http.dart'; + class ClickUpFolders { late String endPoint; late String authToken; + late Client httpClient; + + ClickUpFolders({required this.endPoint, required this.authToken, required this.httpClient}); + + Future> getFolders({required double spaceID, bool includeArchived = false}) async { + try { + final response = await httpClient.get(Uri.parse(includeArchived ? "$endPoint/space/$spaceID/folder?archived=true" : "$endPoint/space/$spaceID/folder"), headers: { + "Authorization": authToken, + }); + final folders = jsonDecode(response.body); + return folders; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> createFolder({required double spaceID, required String name}) async { + try { + final response = await httpClient.post(Uri.parse("$endPoint/space/$spaceID/folder"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": name + })); + final folder = jsonDecode(response.body); + return folder; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> getFolder({required double folderID}) async { + try { + final response = await httpClient.get(Uri.parse("$endPoint/folder/$folderID"), headers: { + "Authorization": authToken, + }); + final folder = jsonDecode(response.body); + return folder; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> updateFolder({required double folderID, required String name}) async { + try { + final response = await httpClient.put(Uri.parse("$endPoint/folder/$folderID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": name + })); + final folders = jsonDecode(response.body); + return folders; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } - ClickUpFolders({required this.endPoint, required this.authToken}); + Future> deleteFolder({required double folderID}) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/folder/$folderID"), headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); + final folders = jsonDecode(response.body); + return folders; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/lib/src/core/endpoints/goals.dart b/lib/src/core/endpoints/goals.dart index 25bb66b..1714c1c 100644 --- a/lib/src/core/endpoints/goals.dart +++ b/lib/src/core/endpoints/goals.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpGoals { late String endPoint; late String authToken; + late Client httpClient; - ClickUpGoals({required this.endPoint, required this.authToken}); + ClickUpGoals({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/guests.dart b/lib/src/core/endpoints/guests.dart index d6e9b65..81b1164 100644 --- a/lib/src/core/endpoints/guests.dart +++ b/lib/src/core/endpoints/guests.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpGuests { late String endPoint; late String authToken; + late Client httpClient; - ClickUpGuests({required this.endPoint, required this.authToken}); + ClickUpGuests({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/lists.dart b/lib/src/core/endpoints/lists.dart index 36df4d9..c1c307c 100644 --- a/lib/src/core/endpoints/lists.dart +++ b/lib/src/core/endpoints/lists.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpLists { late String endPoint; late String authToken; + late Client httpClient; - ClickUpLists({required this.endPoint, required this.authToken}); + ClickUpLists({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/members.dart b/lib/src/core/endpoints/members.dart index b754ddc..edd8a0e 100644 --- a/lib/src/core/endpoints/members.dart +++ b/lib/src/core/endpoints/members.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpMembers { late String endPoint; late String authToken; + late Client httpClient; - ClickUpMembers({required this.endPoint, required this.authToken}); + ClickUpMembers({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/roles.dart b/lib/src/core/endpoints/roles.dart index 5c708d7..aa00d4a 100644 --- a/lib/src/core/endpoints/roles.dart +++ b/lib/src/core/endpoints/roles.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpRoles { late String endPoint; late String authToken; + late Client httpClient; - ClickUpRoles({required this.endPoint, required this.authToken}); + ClickUpRoles({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/shared_hierarchy.dart b/lib/src/core/endpoints/shared_hierarchy.dart index 4fcfa47..c33ed30 100644 --- a/lib/src/core/endpoints/shared_hierarchy.dart +++ b/lib/src/core/endpoints/shared_hierarchy.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpSharedHierarchy { late String endPoint; late String authToken; + late Client httpClient; - ClickUpSharedHierarchy({required this.endPoint, required this.authToken}); + ClickUpSharedHierarchy({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/spaces.dart b/lib/src/core/endpoints/spaces.dart index eedf322..a06d977 100644 --- a/lib/src/core/endpoints/spaces.dart +++ b/lib/src/core/endpoints/spaces.dart @@ -1,6 +1,147 @@ +import 'dart:convert'; + +import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; +import 'package:http/http.dart'; + class ClickUpSpaces { late String endPoint; late String authToken; + late Client httpClient; + + ClickUpSpaces({required this.endPoint, required this.authToken, required this.httpClient}); + + final Map sampleSpaceSchema = { + "name": "Test Space", + "multiple_assignees": false, + "features": { + "due_dates": { + "enabled": false, + "start_date": false, + "remap_due_dates": false, + "remap_closed_due_date": false + }, + "time_tracking": { + "enabled": false + }, + "tags": { + "enabled": false + }, + "time_estimates": { + "enabled": false + }, + "checklists": { + "enabled": false + }, + "custom_fields": { + "enabled": false + }, + "remap_dependencies": { + "enabled": false + }, + "dependency_warning": { + "enabled": false + }, + "portfolios": { + "enabled": false + }, + } + }; + + Future> getSpaces({required double teamID, bool includeArchived = false}) async { + try { + final response = await httpClient.get(Uri.parse(includeArchived ? "$endPoint/team/$teamID/space?archived=true" : "$endPoint/team/$teamID/space"), headers: { + "Authorization": authToken, + }); + final spaces = jsonDecode(response.body); + return spaces; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> createSpace({required double teamID, required Map spaceSchema}) async { + bool schemaMatch = false; + for (var key in spaceSchema.keys) { + schemaMatch = sampleSpaceSchema.containsKey(key); + if (!schemaMatch) { + break; + } + } + + if (!schemaMatch) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your value model is invalid. Please read the function documentation."); + } + + try { + final response = await httpClient.post(Uri.parse("$endPoint/team/$teamID/space"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(spaceSchema)); + final space = jsonDecode(response.body); + return space; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> getSpace({required double spaceID}) async { + try { + final response = await httpClient.get(Uri.parse("$endPoint/space/$spaceID"), headers: { + "Authorization": authToken, + }); + final space = jsonDecode(response.body); + return space; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> updateSpace({required double spaceID, required Map spaceSchema}) async { + bool schemaMatch = false; + schemaMatch = spaceSchema.containsKey("color"); + schemaMatch = spaceSchema.containsKey("private"); + schemaMatch = spaceSchema.containsKey("admin_can_manage"); + for (var key in spaceSchema.keys) { + if (key != "color" && key != "private" && key != "admin_can_manage") { + schemaMatch = sampleSpaceSchema.containsKey(key); + } + if (!schemaMatch) { + break; + } + } + if (!schemaMatch) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your value model is invalid. Please read the function documentation."); + } + try { + final response = await httpClient.put(Uri.parse("$endPoint/space/$spaceID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(spaceSchema)); + final folders = jsonDecode(response.body); + return folders; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } - ClickUpSpaces({required this.endPoint, required this.authToken}); + Future> deleteSpace({required double spaceID}) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/folder/$spaceID"), headers: { + "Authorization": authToken, + }); + final folders = jsonDecode(response.body); + return folders; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/lib/src/core/endpoints/tags.dart b/lib/src/core/endpoints/tags.dart index 10fc3aa..3e8b48e 100644 --- a/lib/src/core/endpoints/tags.dart +++ b/lib/src/core/endpoints/tags.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpTags { late String endPoint; late String authToken; + late Client httpClient; - ClickUpTags({required this.endPoint, required this.authToken}); + ClickUpTags({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/task_checklists.dart b/lib/src/core/endpoints/task_checklists.dart index 149e12b..23c7ab9 100644 --- a/lib/src/core/endpoints/task_checklists.dart +++ b/lib/src/core/endpoints/task_checklists.dart @@ -1,5 +1,8 @@ +import 'package:http/http.dart'; + class ClickUpTaskChecklists { late String endPoint; late String authToken; - ClickUpTaskChecklists({required this.endPoint, required this.authToken}); + late Client httpClient; + ClickUpTaskChecklists({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/lib/src/core/endpoints/task_relationships.dart b/lib/src/core/endpoints/task_relationships.dart new file mode 100644 index 0000000..6d60994 --- /dev/null +++ b/lib/src/core/endpoints/task_relationships.dart @@ -0,0 +1,9 @@ +import 'package:http/http.dart'; + +class ClickUpTaskRelationships { + late String endPoint; + late String authToken; + late Client httpClient; + + ClickUpTaskRelationships({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/task_templates.dart b/lib/src/core/endpoints/task_templates.dart index 2b8c944..9e0d963 100644 --- a/lib/src/core/endpoints/task_templates.dart +++ b/lib/src/core/endpoints/task_templates.dart @@ -1,6 +1,9 @@ -class ClickUpTaskTemplates{ +import 'package:http/http.dart'; + +class ClickUpTaskTemplates { late String endPoint; late String authToken; + late Client httpClient; - ClickUpTaskTemplates({required this.endPoint, required this.authToken}); -} \ No newline at end of file + ClickUpTaskTemplates({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/tasks.dart b/lib/src/core/endpoints/tasks.dart index cdd349b..dd3c47f 100644 --- a/lib/src/core/endpoints/tasks.dart +++ b/lib/src/core/endpoints/tasks.dart @@ -1,6 +1,9 @@ -class ClickUpTasks{ +import 'package:http/http.dart'; + +class ClickUpTasks { late String endPoint; late String authToken; + late Client httpClient; - ClickUpTasks({required this.endPoint, required this.authToken}); -} \ No newline at end of file + ClickUpTasks({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/teams.dart b/lib/src/core/endpoints/teams.dart index 145b6fa..5a82634 100644 --- a/lib/src/core/endpoints/teams.dart +++ b/lib/src/core/endpoints/teams.dart @@ -1,6 +1,9 @@ -class ClickUpTeams{ +import 'package:http/http.dart'; + +class ClickUpTeams { late String endPoint; late String authToken; + late Client httpClient; - ClickUpTeams({required this.endPoint, required this.authToken}); -} \ No newline at end of file + ClickUpTeams({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/time_tracking_legacy.dart b/lib/src/core/endpoints/time_tracking_legacy.dart index 1f70476..15e64a7 100644 --- a/lib/src/core/endpoints/time_tracking_legacy.dart +++ b/lib/src/core/endpoints/time_tracking_legacy.dart @@ -1,6 +1,9 @@ -class ClickUpTimeTrackingLegacy{ +import 'package:http/http.dart'; + +class ClickUpTimeTrackingLegacy { late String endPoint; late String authToken; + late Client httpClient; - ClickUpTimeTrackingLegacy({required this.endPoint, required this.authToken}); -} \ No newline at end of file + ClickUpTimeTrackingLegacy({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/time_tracking_v2.dart b/lib/src/core/endpoints/time_tracking_v2.dart index 00cafad..f8c8591 100644 --- a/lib/src/core/endpoints/time_tracking_v2.dart +++ b/lib/src/core/endpoints/time_tracking_v2.dart @@ -1,6 +1,9 @@ -class ClickUpTimeTrackingV2{ +import 'package:http/http.dart'; + +class ClickUpTimeTrackingV2 { late String endPoint; late String authToken; + late Client httpClient; - ClickUpTimeTrackingV2({required this.endPoint, required this.authToken}); -} \ No newline at end of file + ClickUpTimeTrackingV2({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/users.dart b/lib/src/core/endpoints/users.dart index a087a2e..da65f0c 100644 --- a/lib/src/core/endpoints/users.dart +++ b/lib/src/core/endpoints/users.dart @@ -1,6 +1,9 @@ -class ClickUpUsers{ +import 'package:http/http.dart'; + +class ClickUpUsers { late String endPoint; late String authToken; + late Client httpClient; - ClickUpUsers({required this.endPoint, required this.authToken}); -} \ No newline at end of file + ClickUpUsers({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/views.dart b/lib/src/core/endpoints/views.dart index 0cbb0c9..a30c9c6 100644 --- a/lib/src/core/endpoints/views.dart +++ b/lib/src/core/endpoints/views.dart @@ -1,6 +1,9 @@ -class ClickUpViews{ +import 'package:http/http.dart'; + +class ClickUpViews { late String endPoint; late String authToken; + late Client httpClient; - ClickUpViews({required this.endPoint, required this.authToken}); -} \ No newline at end of file + ClickUpViews({required this.endPoint, required this.authToken, required this.httpClient}); +} diff --git a/lib/src/core/endpoints/webhooks.dart b/lib/src/core/endpoints/webhooks.dart index 062f247..2f2cf5a 100644 --- a/lib/src/core/endpoints/webhooks.dart +++ b/lib/src/core/endpoints/webhooks.dart @@ -1,6 +1,9 @@ +import 'package:http/http.dart'; + class ClickUpWebhooks { late String endPoint; late String authToken; + late Client httpClient; - ClickUpWebhooks({required this.endPoint, required this.authToken}); + ClickUpWebhooks({required this.endPoint, required this.authToken, required this.httpClient}); } diff --git a/test/unit/folders_test.dart b/test/unit/folders_test.dart index 25fbe3a..3df8b77 100644 --- a/test/unit/folders_test.dart +++ b/test/unit/folders_test.dart @@ -4,17 +4,36 @@ import 'package:test/test.dart'; void main() { late String token; late ClickUp clickUp; - group('API endpoint Tests', () { + group('Folders Tests', () { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); + test('Folders - Get Folders', () async { + final folders = await clickUp.folders.getFolders(spaceID: 123); + expect(folders.containsKey("folders"), true); + }); + test('Folders - Get Folders: Include Archived', () async { + final folders = await clickUp.folders.getFolders(spaceID: 123, includeArchived: true); + expect(folders.containsKey("folders"), true); + }); + test('Folders - Create Folder', () async { + final folder = await clickUp.folders.createFolder(spaceID: 123, name: "Test Folder"); + expect(folder.containsKey("name") && folder.containsValue("Test Folder"), true); + }); + test('Folders - Get Folder', () async { + final folder = await clickUp.folders.getFolder(folderID: 123); + expect(folder.containsKey("id"), true); + }); + test('Folders - Update Folder', () async { + final folder = await clickUp.folders.updateFolder(folderID: 123, name: "Test Updated Folder"); + expect(folder.containsKey("name") && folder.containsValue("Test Updated Folder") && folder.containsKey("id"), true); + }); + test('Folders - Delete Folder', () async { + final folder = await clickUp.folders.deleteFolder(folderID: 123); + expect(folder.isEmpty, true); }); }); } diff --git a/test/unit/spaces_test.dart b/test/unit/spaces_test.dart index 25fbe3a..e664fc9 100644 --- a/test/unit/spaces_test.dart +++ b/test/unit/spaces_test.dart @@ -4,17 +4,44 @@ import 'package:test/test.dart'; void main() { late String token; late ClickUp clickUp; - group('API endpoint Tests', () { + group('Spaces Tests', () { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); + test('Spaces - Get Spaces', () async { + final spaces = await clickUp.spaces.getSpaces(teamID: 123); + print(spaces); + expect(spaces.containsKey("spaces"), true); + }); + test('Spaces - Get Spaces: Include Archived', () async { + final spaces = await clickUp.spaces.getSpaces(teamID: 123, includeArchived: true); + expect(spaces.containsKey("spaces"), true); + }); + test('Spaces - Create Space', () async { + final space = await clickUp.spaces.createSpace(teamID: 123, spaceSchema: clickUp.spaces.sampleSpaceSchema); + expect(space.containsKey("features"), true); + }); + test('Spaces - Get Space', () async { + final space = await clickUp.spaces.getSpace(spaceID: 123); + expect(space.containsKey("features"), true); + }); + test('Spaces - Update Space', () async { + final space = await clickUp.spaces.updateSpace(spaceID: 123, spaceSchema: { + ...clickUp.spaces.sampleSpaceSchema, + ...{ + "color": "blue", + "private": false, + "admin_can_manage": false + } + }); + expect(space.containsKey("features"), true); + }); + test('Spaces - Delete Space', () async { + final space = await clickUp.spaces.deleteSpace(spaceID: 123); + expect(space.isEmpty, true); }); }); } diff --git a/test/unit/dependencies_test.dart b/test/unit/task_relationships.dart similarity index 100% rename from test/unit/dependencies_test.dart rename to test/unit/task_relationships.dart From 6c4067a1a20a1ab0c54ad5032662e843dbe835f2 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Tue, 16 May 2023 01:15:10 +0300 Subject: [PATCH 07/17] changelog update --- CHANGELOG.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea68fb9..b70f45e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ +## 0.3.0 + +- Tests added. +- Implemented endpoints for Attachments, Authentication, Comments, Custom Fields and Folders +- Classes for all api endpoints. + ## 0.1.0 - Initial version. - Added basic functionality -- Wraps all api endpoints. +- Classes for all api endpoints. From 1883b0be38f8f185ec99fa1a8624ba86d6641364 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Tue, 16 May 2023 01:18:53 +0300 Subject: [PATCH 08/17] changelog and pubspec update --- CHANGELOG.md | 2 +- pubspec.yaml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b70f45e..679e771 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.3.0 +## 0.2.0 - Tests added. - Implemented endpoints for Attachments, Authentication, Comments, Custom Fields and Folders diff --git a/pubspec.yaml b/pubspec.yaml index 5546e44..eae60ec 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,3 +11,4 @@ dev_dependencies: test: ^1.16.0 dependencies: http: ^0.13.5 + path: ^1.8.3 From df933f4913f0f15b80356d0e0b4260e1d2209fc4 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Tue, 16 May 2023 01:19:41 +0300 Subject: [PATCH 09/17] version update --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index eae60ec..2ba204d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: clickup_dart_sdk description: A SDK for ClickUp for integrating or creating applications on top of the product. -version: 0.2.0 +version: 0.2.1 repository: https://github.com/ayazemre/clickup-dart-sdk environment: From 7750877032a9de6fde55b1621e035a1ade472e4c Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Thu, 25 May 2023 13:28:24 +0300 Subject: [PATCH 10/17] tasks endpoints update --- CHANGELOG.md | 4 + README.md | 6 +- example/clickup_dart_example.dart | 3 +- lib/src/core/endpoints/tasks.dart | 346 ++++++++++++++++++ pubspec.yaml | 2 +- ..._dart_sdk_sample_user_behaviour_test.dart} | 3 +- .../attachment_test.dart | 3 +- test/{unit => integration}/auth_test.dart | 0 test/{ => integration}/beksinski_sample.jpg | Bin test/{unit => integration}/comments_test.dart | 0 .../custom_fields_test.dart | 0 test/{unit => integration}/folders_test.dart | 0 test/{unit => integration}/goals_test.dart | 0 test/{unit => integration}/guests_test.dart | 0 test/{unit => integration}/lists_test.dart | 0 test/{unit => integration}/members_test.dart | 0 test/{unit => integration}/roles_test.dart | 0 .../shared_hierarchy_test.dart | 0 test/{unit => integration}/spaces_test.dart | 0 test/{unit => integration}/tags_test.dart | 0 .../task_checklists_test.dart | 0 .../task_relationships.dart | 0 .../task_templates_test.dart | 0 test/integration/tasks_test.dart | 93 +++++ test/{unit => integration}/teams_test.dart | 0 .../time_tracking_legacy_test.dart | 0 .../time_tracking_v2_test.dart | 0 test/{unit => integration}/users_test.dart | 0 test/{unit => integration}/views_test.dart | 0 test/{unit => integration}/webhooks_test.dart | 0 test/unit/tasks_test.dart | 20 - 31 files changed, 449 insertions(+), 31 deletions(-) rename test/{clickup_dart_sdk_test.dart => e2e/clickup_dart_sdk_sample_user_behaviour_test.dart} (90%) rename test/{unit => integration}/attachment_test.dart (85%) rename test/{unit => integration}/auth_test.dart (100%) rename test/{ => integration}/beksinski_sample.jpg (100%) rename test/{unit => integration}/comments_test.dart (100%) rename test/{unit => integration}/custom_fields_test.dart (100%) rename test/{unit => integration}/folders_test.dart (100%) rename test/{unit => integration}/goals_test.dart (100%) rename test/{unit => integration}/guests_test.dart (100%) rename test/{unit => integration}/lists_test.dart (100%) rename test/{unit => integration}/members_test.dart (100%) rename test/{unit => integration}/roles_test.dart (100%) rename test/{unit => integration}/shared_hierarchy_test.dart (100%) rename test/{unit => integration}/spaces_test.dart (100%) rename test/{unit => integration}/tags_test.dart (100%) rename test/{unit => integration}/task_checklists_test.dart (100%) rename test/{unit => integration}/task_relationships.dart (100%) rename test/{unit => integration}/task_templates_test.dart (100%) create mode 100644 test/integration/tasks_test.dart rename test/{unit => integration}/teams_test.dart (100%) rename test/{unit => integration}/time_tracking_legacy_test.dart (100%) rename test/{unit => integration}/time_tracking_v2_test.dart (100%) rename test/{unit => integration}/users_test.dart (100%) rename test/{unit => integration}/views_test.dart (100%) rename test/{unit => integration}/webhooks_test.dart (100%) delete mode 100644 test/unit/tasks_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index 679e771..b43026d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +- Implemented endpoints for Tasks. + ## 0.2.0 - Tests added. diff --git a/README.md b/README.md index 8070838..75a9ecc 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,7 @@ and the Flutter guide for --> -![readmeheaderblack](https://user-images.githubusercontent.com/68122318/216693931-64f1b1a5-d69a-4af4-9f67-ab281bd68c3d.png#gh-light-mode-only) -![readmeheaderwhite](https://user-images.githubusercontent.com/68122318/216693937-2cbf9f31-d643-4457-941e-ba33ba3b638d.png#gh-dark-mode-only) - - -This is a SDK for ClickUp +This is a SDK for ClickUp written in Dart ## Features diff --git a/example/clickup_dart_example.dart b/example/clickup_dart_example.dart index 9f494c3..b5a5f8d 100644 --- a/example/clickup_dart_example.dart +++ b/example/clickup_dart_example.dart @@ -6,6 +6,7 @@ void main() async { final clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); final attachment = await clickUp.attachments.createTaskAttachment(taskID: "8669e046h", useCustomTaskID: false, filePath: "./test/beksinski_sample.jpg"); - print(attachment); + final listComments = await clickUp.comments.getListComments(listID: 1); + print(listComments); } diff --git a/lib/src/core/endpoints/tasks.dart b/lib/src/core/endpoints/tasks.dart index dd3c47f..657dbbe 100644 --- a/lib/src/core/endpoints/tasks.dart +++ b/lib/src/core/endpoints/tasks.dart @@ -1,9 +1,355 @@ +import 'dart:convert'; + import 'package:http/http.dart'; +import '../clickup_exception.dart'; + class ClickUpTasks { late String endPoint; late String authToken; late Client httpClient; ClickUpTasks({required this.endPoint, required this.authToken, required this.httpClient}); + + Future> getTasks({ + required double listID, + bool archived = false, + int page = 0, + String orderBy = "created", + bool reverse = true, + bool subtasks = true, + String statuses = "", + bool includeClosed = false, + List assignees = const [], + List tags = const [], + int dueDateGreaterThan = 0, + int dueDateLessThan = 0, + int dateCreatedGreaterThan = 0, + int dateCreatedLessThan = 0, + int dateUpdatedGreaterThan = 0, + int dateUpdatedLessThan = 0, + int dateDoneGreaterThan = 0, + int dateDoneLessThan = 0, + List> customFields = const [], + }) async { + ////TO:DO Parameter validation + + var assigneeQuery = ""; + var tagQuery = ""; + var customFieldQuery = "custom_fields=[${customFields.toString()}]"; + if (assignees.isNotEmpty) { + for (var assignee in assignees) { + assigneeQuery = "assignees[]=$assignee&"; + print(assigneeQuery.length); + assigneeQuery = assigneeQuery.substring(0, assigneeQuery.length - 1); + } + } + if (tags.isNotEmpty) { + for (var tag in tags) { + tagQuery = "tags[]=$tag&"; + } + tagQuery = assigneeQuery.substring(0, assigneeQuery.length - 1); + } + + final queryParams = "?archived=$archived&page=$page&order_by=$orderBy&reverse=$reverse&subtasks=$subtasks&statuses=$statuses&include_closed=$includeClosed&assignees=$assigneeQuery&tags=$tagQuery&due_date_gt=$dueDateGreaterThan&due_date_lt=$dueDateLessThan&date_created_gt=$dateCreatedGreaterThan&date_created_lt=$dateCreatedLessThan&date_updated_gt=$dateUpdatedGreaterThan&date_updated_lt=$dateUpdatedLessThan&date_done_gt=$dateDoneGreaterThan&date_done_lt=$dateDoneGreaterThan&custom_fields=$customFieldQuery"; + try { + final response = await httpClient.get(Uri.parse("$endPoint/list/$listID/task$queryParams"), headers: { + "Authorization": authToken + }); + final List tasks = jsonDecode(response.body); + return tasks.first; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Sample Task Schema + /// ``` + /// { + /// "name": "", + /// "description": "", + /// "assignees": [], //List of integers + /// "tags": [], //List of Strings + /// "status": "", + /// "priority": 0, + /// "due_date": 0, + /// "due_date_time": false, + /// "time_estimate": 0, + /// "start_date": 0, + /// "start_date_time": false, + /// "notify_all": false, + /// "parent": "", + /// "links_to": "", + /// "check_required_custom_fields": false, + /// "custom_fields": [] // List of Maps + /// } + /// ``` + + Future> createTask({ + required double listID, + required Map taskDescription, + bool customTaskIDs = false, + double teamID = 0, + }) async { + ////TO:DO Parameter validation + + var queryParams = ""; + if (customTaskIDs) { + queryParams = "?${queryParams}custom_task_ids=true"; + if (teamID != 0) { + queryParams = "$queryParams&team_id=$teamID"; + } + } + + try { + final response = await httpClient.post(Uri.parse("$endPoint/list/$listID/task$queryParams"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(taskDescription)); + final task = jsonDecode(response.body); + return task; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> getTask({required double taskID, bool customTaskIDs = false, double teamID = 0, bool includeSubtasks = false}) async { + ////TO:DO Parameter validation + + var queryParams = ""; + if (customTaskIDs && teamID != 0) { + queryParams = "?${queryParams}custom_task_ids=true&team_id=$teamID"; + if (includeSubtasks) { + queryParams = "$queryParams&include_subtasks=true"; + } + } else if (includeSubtasks) { + queryParams = "?include_subtasks=true"; + } + + try { + final response = await httpClient.get(Uri.parse("$endPoint/task/$taskID$queryParams"), headers: { + "Authorization": authToken, + }); + final task = jsonDecode(response.body); + return task; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Sample Task Schema + /// ``` + /// { + /// "name": "", + /// "description": "", + /// "status": "", + /// "priority": 0, + /// "due_date": 0, + /// "due_date_time": false, + /// "parent": "", + /// "time_estimate": 0, + /// "start_date": 0, + /// "start_date_time": false, + /// "assignees": { + /// "add": [], + /// "rem": [] + /// }, //List of integers + /// "archived": false + /// } + /// ``` + Future> updateTask({ + required double taskID, + required Map taskDescription, + bool customTaskIDs = false, + double teamID = 0, + }) async { + ////TO:DO Parameter validation + + var queryParams = ""; + if (customTaskIDs) { + queryParams = "?${queryParams}custom_task_ids=true"; + if (teamID != 0) { + queryParams = "$queryParams&team_id=$teamID"; + } + } + + try { + final response = await httpClient.put(Uri.parse("$endPoint/task/$taskID$queryParams"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(taskDescription)); + final task = jsonDecode(response.body); + return task; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> deleteTask({ + required double taskID, + bool customTaskIDs = false, + double teamID = 0, + }) async { + ////TO:DO Parameter validation + + var queryParams = ""; + if (customTaskIDs) { + queryParams = "?${queryParams}custom_task_ids=true"; + if (teamID != 0) { + queryParams = "$queryParams&team_id=$teamID"; + } + } + + try { + final response = await httpClient.delete(Uri.parse("$endPoint/task/$taskID$queryParams"), headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); + final task = jsonDecode(response.body); + return task; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Order by Options include: id, created, updated, and due_date. + Future> getFilteredTeamTasks({ + required double workspaceTeamID, + int page = 0, + String orderBy = "created", + bool reverse = false, + bool subtasks = false, + List spaceIDs = const [], + List projectIDs = const [], + List listIDs = const [], + List statuses = const [], + bool includeClosed = false, + List assignees = const [], + List tags = const [], + int dueDateGreaterThan = 0, + int dueDateLessThan = 0, + int dateCreatedGreaterThan = 0, + int dateCreatedLessThan = 0, + int dateUpdatedGreaterThan = 0, + int dateUpdatedLessThan = 0, + int dateDoneGreaterThan = 0, + int dateDoneLessThan = 0, + List> customFields = const [], + bool customTaskIDs = false, + double teamID = 0, + String parent = "", + }) async { + ////TO:DO Parameter validation + var spaceIDsQuery = ""; + var projectIDsQuery = ""; + var listIDsQuery = ""; + var statusesQuery = ""; + var assigneesQuery = ""; + var tagsQuery = ""; + var customFieldsQuery = ""; + + var queryParams = "?page=$page&order_by=$orderBy&reverse=$reverse&subtasks=$subtasks&space_ids=$spaceIDsQuery&project_ids=$projectIDsQuery&list_ids=$listIDsQuery&statuses=$statusesQuery&include_closed=$includeClosed&assignees=$assigneesQuery&tags=$tagsQuery&due_date_gt=$dueDateGreaterThan&due_date_lt=$dueDateLessThan&date_created_gt=$dateCreatedGreaterThan&date_created_lt=$dateCreatedLessThan&date_updated_gt=$dateUpdatedGreaterThan&date_updated_lt=$dateUpdatedLessThan&date_done_gt=$dateDoneGreaterThan&date_done_lt=$dateDoneLessThan&custom_fields=$customFieldsQuery"; + if (customTaskIDs) { + queryParams = "${queryParams}custom_task_ids=true"; + if (teamID != 0) { + queryParams = "$queryParams&team_id=$teamID"; + } + } + if (parent.isNotEmpty) { + queryParams = "$queryParams&parent=string"; + } + + try { + final response = await httpClient.get(Uri.parse("$endPoint/team/$workspaceTeamID/task$queryParams"), headers: { + "Authorization": authToken, + }); + final task = jsonDecode(response.body); + return task; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> getTasksTimeInStatus({ + required String taskID, + bool customTaskIDs = false, + double teamID = 0, + }) async { + ////TO:DO Parameter validation + + var queryParams = ""; + if (customTaskIDs) { + queryParams = "?${queryParams}custom_task_ids=true"; + if (teamID != 0) { + queryParams = "$queryParams&team_id=$teamID"; + } + } + + try { + final response = await httpClient.get(Uri.parse("$endPoint/task/$taskID/time_in_status$queryParams"), headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); + final task = jsonDecode(response.body); + return task; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + Future> getBulkTasksTimeInStatus({ + required List taskIDs, + bool customTaskIDs = false, + double teamID = 0, + }) async { + if (taskIDs.length > 99) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "You can only query up to 100 tasks per request"); + } + ////TO:DO Parameter validation + var queryParams = "?"; + final template = "task_ids="; + for (var taskID in taskIDs) { + queryParams = "$queryParams$template$taskID&"; + } + if (customTaskIDs) { + queryParams = "${queryParams}custom_task_ids=true"; + if (teamID != 0) { + queryParams = "$queryParams&team_id=$teamID"; + } + } + if (queryParams.isNotEmpty) { + queryParams = queryParams.substring(0, queryParams.length - 1); + } + + try { + final response = await httpClient.get(Uri.parse("$endPoint/task/bulk_time_in_status/task_ids$queryParams"), headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); + final task = jsonDecode(response.body); + return task; + } catch (e) { + print(e); + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/pubspec.yaml b/pubspec.yaml index 2ba204d..1a43124 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: clickup_dart_sdk description: A SDK for ClickUp for integrating or creating applications on top of the product. -version: 0.2.1 +version: 0.3.0 repository: https://github.com/ayazemre/clickup-dart-sdk environment: diff --git a/test/clickup_dart_sdk_test.dart b/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart similarity index 90% rename from test/clickup_dart_sdk_test.dart rename to test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart index 345e2de..33b72ae 100644 --- a/test/clickup_dart_sdk_test.dart +++ b/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart @@ -4,7 +4,7 @@ import 'package:test/test.dart'; void main() { late String token; late ClickUp clickUp; - group('API endpoint Tests', () { + group('User Behaviour Samples', () { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; @@ -12,6 +12,5 @@ void main() { }); /// TO-DO: Oauth Testing - /// }); } diff --git a/test/unit/attachment_test.dart b/test/integration/attachment_test.dart similarity index 85% rename from test/unit/attachment_test.dart rename to test/integration/attachment_test.dart index 3139f4c..2b1fd2e 100644 --- a/test/unit/attachment_test.dart +++ b/test/integration/attachment_test.dart @@ -1,4 +1,3 @@ -import 'dart:convert'; import 'package:path/path.dart' as p; import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; @@ -16,7 +15,7 @@ void main() { }); test('Upload an attachment', () async { - final response = await clickUp.attachments.createTaskAttachment(filePath: p.join(p.current, "test", "beksinski_sample.jpg"), taskID: "213123", useCustomTaskID: false); + final response = await clickUp.attachments.createTaskAttachment(filePath: p.join(p.current, "test", "integration", "beksinski_sample.jpg"), taskID: "213123", useCustomTaskID: false); expect(response, { 'message': 'Mock server error. Media type multipart/form-data deserialization is not supported.' }); diff --git a/test/unit/auth_test.dart b/test/integration/auth_test.dart similarity index 100% rename from test/unit/auth_test.dart rename to test/integration/auth_test.dart diff --git a/test/beksinski_sample.jpg b/test/integration/beksinski_sample.jpg similarity index 100% rename from test/beksinski_sample.jpg rename to test/integration/beksinski_sample.jpg diff --git a/test/unit/comments_test.dart b/test/integration/comments_test.dart similarity index 100% rename from test/unit/comments_test.dart rename to test/integration/comments_test.dart diff --git a/test/unit/custom_fields_test.dart b/test/integration/custom_fields_test.dart similarity index 100% rename from test/unit/custom_fields_test.dart rename to test/integration/custom_fields_test.dart diff --git a/test/unit/folders_test.dart b/test/integration/folders_test.dart similarity index 100% rename from test/unit/folders_test.dart rename to test/integration/folders_test.dart diff --git a/test/unit/goals_test.dart b/test/integration/goals_test.dart similarity index 100% rename from test/unit/goals_test.dart rename to test/integration/goals_test.dart diff --git a/test/unit/guests_test.dart b/test/integration/guests_test.dart similarity index 100% rename from test/unit/guests_test.dart rename to test/integration/guests_test.dart diff --git a/test/unit/lists_test.dart b/test/integration/lists_test.dart similarity index 100% rename from test/unit/lists_test.dart rename to test/integration/lists_test.dart diff --git a/test/unit/members_test.dart b/test/integration/members_test.dart similarity index 100% rename from test/unit/members_test.dart rename to test/integration/members_test.dart diff --git a/test/unit/roles_test.dart b/test/integration/roles_test.dart similarity index 100% rename from test/unit/roles_test.dart rename to test/integration/roles_test.dart diff --git a/test/unit/shared_hierarchy_test.dart b/test/integration/shared_hierarchy_test.dart similarity index 100% rename from test/unit/shared_hierarchy_test.dart rename to test/integration/shared_hierarchy_test.dart diff --git a/test/unit/spaces_test.dart b/test/integration/spaces_test.dart similarity index 100% rename from test/unit/spaces_test.dart rename to test/integration/spaces_test.dart diff --git a/test/unit/tags_test.dart b/test/integration/tags_test.dart similarity index 100% rename from test/unit/tags_test.dart rename to test/integration/tags_test.dart diff --git a/test/unit/task_checklists_test.dart b/test/integration/task_checklists_test.dart similarity index 100% rename from test/unit/task_checklists_test.dart rename to test/integration/task_checklists_test.dart diff --git a/test/unit/task_relationships.dart b/test/integration/task_relationships.dart similarity index 100% rename from test/unit/task_relationships.dart rename to test/integration/task_relationships.dart diff --git a/test/unit/task_templates_test.dart b/test/integration/task_templates_test.dart similarity index 100% rename from test/unit/task_templates_test.dart rename to test/integration/task_templates_test.dart diff --git a/test/integration/tasks_test.dart b/test/integration/tasks_test.dart new file mode 100644 index 0000000..95d59b1 --- /dev/null +++ b/test/integration/tasks_test.dart @@ -0,0 +1,93 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; +import 'package:test/test.dart'; + +void main() { + late String token; + late ClickUp clickUp; + group('Tasks Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Tasks - Get Tasks', () async { + final tasks = await clickUp.tasks.getTasks(listID: 1); + print(tasks); + expect(tasks.containsKey("tasks"), true); + }); + test('Tasks - Create Task', () async { + final task = await clickUp.tasks.createTask(listID: 1, taskDescription: { + "name": "", + "description": "", + "assignees": [], //List of integers + "tags": [], //List of Strings + "status": "", + "priority": 0, + "due_date": 0, + "due_date_time": false, + "time_estimate": 0, + "start_date": 0, + "start_date_time": false, + "notify_all": false, + "parent": "", + "links_to": "", + "check_required_custom_fields": false, + "custom_fields": [] // List of Maps + }); + print(task); + expect(task.containsKey("id"), true); + }); + test('Tasks - Get Specific Task ', () async { + final task = await clickUp.tasks.getTask(taskID: 1); + print(task); + expect(task.containsKey("id"), true); + }); + + test('Tasks - Update Task', () async { + final task = await clickUp.tasks.updateTask(taskID: 1, taskDescription: { + "name": "", + "description": "", + "status": "", + "priority": 0, + "due_date": 0, + "due_date_time": false, + "parent": "", + "time_estimate": 0, + "start_date": 0, + "start_date_time": false, + "assignees": { + "add": [], + "rem": [] + }, //List of integers + "archived": false + }); + print(task); + expect(task.containsKey("id"), true); + }); + test('Tasks - Delete Task', () async { + final task = await clickUp.tasks.deleteTask(taskID: 1); + print(task); + expect(task.isEmpty, true); + }); + test('Tasks - Get Filtered Team Tasks', () async { + final task = await clickUp.tasks.getFilteredTeamTasks(workspaceTeamID: 1); + print(task); + expect(task.containsKey("tasks"), true); + }); + test('Tasks - Get Tasks Time In Status', () async { + final task = await clickUp.tasks.getTasksTimeInStatus(taskID: "1"); + print(task); + expect(task.containsKey("current_status"), true); + }); + test('Tasks - Get Bulk Tasks Time In Status', () async { + final task = await clickUp.tasks.getBulkTasksTimeInStatus(taskIDs: [ + "1", + "2" + ]); + print(task); + final result = task.values.first as Map; + expect(result.containsKey("current_status"), true); + }); + }); +} diff --git a/test/unit/teams_test.dart b/test/integration/teams_test.dart similarity index 100% rename from test/unit/teams_test.dart rename to test/integration/teams_test.dart diff --git a/test/unit/time_tracking_legacy_test.dart b/test/integration/time_tracking_legacy_test.dart similarity index 100% rename from test/unit/time_tracking_legacy_test.dart rename to test/integration/time_tracking_legacy_test.dart diff --git a/test/unit/time_tracking_v2_test.dart b/test/integration/time_tracking_v2_test.dart similarity index 100% rename from test/unit/time_tracking_v2_test.dart rename to test/integration/time_tracking_v2_test.dart diff --git a/test/unit/users_test.dart b/test/integration/users_test.dart similarity index 100% rename from test/unit/users_test.dart rename to test/integration/users_test.dart diff --git a/test/unit/views_test.dart b/test/integration/views_test.dart similarity index 100% rename from test/unit/views_test.dart rename to test/integration/views_test.dart diff --git a/test/unit/webhooks_test.dart b/test/integration/webhooks_test.dart similarity index 100% rename from test/unit/webhooks_test.dart rename to test/integration/webhooks_test.dart diff --git a/test/unit/tasks_test.dart b/test/unit/tasks_test.dart deleted file mode 100644 index 25fbe3a..0000000 --- a/test/unit/tasks_test.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; -import 'package:test/test.dart'; - -void main() { - late String token; - late ClickUp clickUp; - group('API endpoint Tests', () { - setUp(() async { - // Additional setup goes here. - token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); - }); - - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); - }); - }); -} From 5a2f9750ba577a1dc60980dd0552712fe59fde53 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Thu, 25 May 2023 13:33:03 +0300 Subject: [PATCH 11/17] small linter fixes --- test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart | 7 ++++++- test/integration/goals_test.dart | 6 ++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart b/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart index 33b72ae..ef1616d 100644 --- a/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart +++ b/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart @@ -11,6 +11,11 @@ void main() { clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); - /// TO-DO: Oauth Testing + group("User Logs in, creates a task and uploads a file.", () { + test('Authorization - Get Authorized User', () async { + final user = await clickUp.auth.getAuthorizedUser(); + expect(user.containsKey("user"), true); + }); + }); }); } diff --git a/test/integration/goals_test.dart b/test/integration/goals_test.dart index 2d60ff5..5df8964 100644 --- a/test/integration/goals_test.dart +++ b/test/integration/goals_test.dart @@ -1,7 +1,5 @@ import 'package:test/test.dart'; void main() { - test('goals ...', () async { - // TODO: Implement test - }); -} \ No newline at end of file + test('goals ...', () async {}); +} From 1fde40f44d0b68a483b4b9cd32c1ed714e59988d Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Thu, 25 May 2023 13:45:20 +0300 Subject: [PATCH 12/17] refactor and small fix --- ...ple.dart => clickup_dart_sdk_example.dart} | 9 +- lib/src/clickup_dart_base.dart | 73 ++++++---- lib/src/core/clickup_exception.dart | 9 +- lib/src/core/endpoints/attachments.dart | 20 ++- lib/src/core/endpoints/auth.dart | 25 ++-- lib/src/core/endpoints/comments.dart | 127 +++++++++++++----- lib/src/core/endpoints/custom_fields.dart | 58 +++++--- lib/src/core/endpoints/folders.dart | 69 +++++++--- lib/src/core/endpoints/goals.dart | 5 +- lib/src/core/endpoints/guests.dart | 5 +- lib/src/core/endpoints/lists.dart | 5 +- lib/src/core/endpoints/members.dart | 5 +- lib/src/core/endpoints/roles.dart | 5 +- lib/src/core/endpoints/shared_hierarchy.dart | 5 +- lib/src/core/endpoints/spaces.dart | 105 +++++++++------ lib/src/core/endpoints/tags.dart | 5 +- lib/src/core/endpoints/task_checklists.dart | 5 +- .../core/endpoints/task_relationships.dart | 5 +- lib/src/core/endpoints/task_templates.dart | 5 +- lib/src/core/endpoints/tasks.dart | 107 ++++++++++----- lib/src/core/endpoints/teams.dart | 5 +- .../core/endpoints/time_tracking_legacy.dart | 5 +- lib/src/core/endpoints/time_tracking_v2.dart | 5 +- lib/src/core/endpoints/users.dart | 5 +- lib/src/core/endpoints/views.dart | 5 +- lib/src/core/endpoints/webhooks.dart | 5 +- pubspec.yaml | 2 +- ...p_dart_sdk_sample_user_behaviour_test.dart | 5 +- test/integration/attachment_test.dart | 14 +- test/integration/auth_test.dart | 5 +- test/integration/comments_test.dart | 87 +++++++----- test/integration/custom_fields_test.dart | 36 ++--- test/integration/folders_test.dart | 23 +++- test/integration/guests_test.dart | 5 +- test/integration/lists_test.dart | 5 +- test/integration/members_test.dart | 5 +- test/integration/roles_test.dart | 5 +- test/integration/shared_hierarchy_test.dart | 5 +- test/integration/spaces_test.dart | 20 +-- test/integration/tags_test.dart | 5 +- test/integration/task_checklists_test.dart | 5 +- test/integration/task_relationships.dart | 5 +- test/integration/task_templates_test.dart | 5 +- test/integration/tasks_test.dart | 16 +-- test/integration/teams_test.dart | 5 +- .../time_tracking_legacy_test.dart | 5 +- test/integration/time_tracking_v2_test.dart | 5 +- test/integration/users_test.dart | 5 +- test/integration/views_test.dart | 5 +- test/integration/webhooks_test.dart | 5 +- 50 files changed, 671 insertions(+), 294 deletions(-) rename example/{clickup_dart_example.dart => clickup_dart_sdk_example.dart} (57%) diff --git a/example/clickup_dart_example.dart b/example/clickup_dart_sdk_example.dart similarity index 57% rename from example/clickup_dart_example.dart rename to example/clickup_dart_sdk_example.dart index b5a5f8d..c49b1b9 100644 --- a/example/clickup_dart_example.dart +++ b/example/clickup_dart_sdk_example.dart @@ -3,9 +3,14 @@ import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; void main() async { final token = "pk_testrandomtoken123"; // Initialize with mock server for testing - final clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + final clickUp = ClickUp( + apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); - final attachment = await clickUp.attachments.createTaskAttachment(taskID: "8669e046h", useCustomTaskID: false, filePath: "./test/beksinski_sample.jpg"); + final attachment = await clickUp.attachments.createTaskAttachment( + taskID: "8669e046h", + useCustomTaskID: false, + filePath: "./test/beksinski_sample.jpg"); print(attachment); final listComments = await clickUp.comments.getListComments(listID: 1); print(listComments); diff --git a/lib/src/clickup_dart_base.dart b/lib/src/clickup_dart_base.dart index e7efb4f..19dab20 100644 --- a/lib/src/clickup_dart_base.dart +++ b/lib/src/clickup_dart_base.dart @@ -59,29 +59,56 @@ class ClickUp { void initialize({required String authToken}) async { httpClient = Client(); - auth = ClickUpAuth(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - attachments = ClickUpAttachments(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - comments = ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); - customFields = ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); - folders = ClickUpFolders(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - goals = ClickUpGoals(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - guests = ClickUpGuests(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - lists = ClickUpLists(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - members = ClickUpMembers(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - roles = ClickUpRoles(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - sharedHierarchy = ClickUpSharedHierarchy(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - spaces = ClickUpSpaces(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - tags = ClickUpTags(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - tasks = ClickUpTasks(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - taskChecklists = ClickUpTaskChecklists(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - taskRelationships = ClickUpTaskRelationships(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - taskTemplates = ClickUpTaskTemplates(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - teams = ClickUpTeams(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - timeTrackingLegacy = ClickUpTimeTrackingLegacy(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - timeTrackingV2 = ClickUpTimeTrackingV2(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - users = ClickUpUsers(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - views = ClickUpViews(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - webhooks = ClickUpWebhooks(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + auth = ClickUpAuth( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + attachments = ClickUpAttachments( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + comments = ClickUpComments( + endPoint: apiEndpoint, + authToken: auth.authToken, + httpClient: httpClient); + customFields = ClickUpCustomFields( + endPoint: apiEndpoint, + authToken: auth.authToken, + httpClient: httpClient); + folders = ClickUpFolders( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + goals = ClickUpGoals( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + guests = ClickUpGuests( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + lists = ClickUpLists( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + members = ClickUpMembers( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + roles = ClickUpRoles( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + sharedHierarchy = ClickUpSharedHierarchy( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + spaces = ClickUpSpaces( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + tags = ClickUpTags( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + tasks = ClickUpTasks( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskChecklists = ClickUpTaskChecklists( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskRelationships = ClickUpTaskRelationships( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskTemplates = ClickUpTaskTemplates( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + teams = ClickUpTeams( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + timeTrackingLegacy = ClickUpTimeTrackingLegacy( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + timeTrackingV2 = ClickUpTimeTrackingV2( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + users = ClickUpUsers( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + views = ClickUpViews( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + webhooks = ClickUpWebhooks( + endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); print("ClickUp Initialized.."); } } diff --git a/lib/src/core/clickup_exception.dart b/lib/src/core/clickup_exception.dart index 58dddde..f209b7f 100644 --- a/lib/src/core/clickup_exception.dart +++ b/lib/src/core/clickup_exception.dart @@ -1,11 +1,8 @@ -enum ClickUpExceptionType { - invalidModel, - requestError, - unauthorized -} +enum ClickUpExceptionType { invalidModel, requestError, unauthorized } class ClickUpException implements Exception { - ClickUpException({required this.exceptionType, required this.exceptionMessage}); + ClickUpException( + {required this.exceptionType, required this.exceptionMessage}); final ClickUpExceptionType exceptionType; final String exceptionMessage; diff --git a/lib/src/core/endpoints/attachments.dart b/lib/src/core/endpoints/attachments.dart index 978abc6..9c17246 100644 --- a/lib/src/core/endpoints/attachments.dart +++ b/lib/src/core/endpoints/attachments.dart @@ -4,7 +4,10 @@ import 'package:http/http.dart'; import '../clickup_exception.dart'; class ClickUpAttachments { - ClickUpAttachments({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpAttachments( + {required this.endPoint, + required this.authToken, + required this.httpClient}); final String endPoint; final String authToken; late Client httpClient; @@ -16,17 +19,22 @@ class ClickUpAttachments { int? teamID, }) async { try { - final request = MultipartRequest("POST", Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/attachment?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/attachment")) - ..headers.addAll({ - "Authorization": authToken - }) + final request = MultipartRequest( + "POST", + Uri.parse(useCustomTaskID + ? "$endPoint/task/$taskID/attachment?custom_task_ids=true&team_id=$teamID" + : "$endPoint/task/$taskID/attachment")) + ..headers.addAll({"Authorization": authToken}) ..files.add(await MultipartFile.fromPath("attachment", filePath)); final response = await request.send(); final result = await response.stream.bytesToString(); return jsonDecode(result); } catch (e) { print(e); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/auth.dart b/lib/src/core/endpoints/auth.dart index 32340d9..774e79a 100644 --- a/lib/src/core/endpoints/auth.dart +++ b/lib/src/core/endpoints/auth.dart @@ -7,7 +7,10 @@ class ClickUpAuth { late String authToken; late Client httpClient; - ClickUpAuth({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpAuth( + {required this.endPoint, + required this.authToken, + required this.httpClient}); /// Get access token based on your credentials. // Future getAccessToken( @@ -28,28 +31,32 @@ class ClickUpAuth { /// Get the user bound to the token. Future> getAuthorizedUser() async { try { - final response = await httpClient.get(Uri.parse("$endPoint/user"), headers: { - "Authorization": authToken - }); + final response = await httpClient.get(Uri.parse("$endPoint/user"), + headers: {"Authorization": authToken}); final user = jsonDecode(response.body); return user; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } /// Get the teams bound to authorized user. Future> getAuthorizedTeams() async { try { - final response = await httpClient.get(Uri.parse("$endPoint/team"), headers: { - "Authorization": authToken - }); + final response = await httpClient.get(Uri.parse("$endPoint/team"), + headers: {"Authorization": authToken}); final teams = jsonDecode(response.body); return teams; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/comments.dart b/lib/src/core/endpoints/comments.dart index f8182be..d76cea6 100644 --- a/lib/src/core/endpoints/comments.dart +++ b/lib/src/core/endpoints/comments.dart @@ -7,7 +7,10 @@ class ClickUpComments { late String endPoint; late String authToken; late Client httpClient; - ClickUpComments({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpComments( + {required this.endPoint, + required this.authToken, + required this.httpClient}); Future> getTaskComments({ required String taskID, @@ -17,14 +20,19 @@ class ClickUpComments { String? startID, }) async { try { - final response = await httpClient.get(Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/comment?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/comment"), headers: { - "Authorization": authToken - }); + final response = await httpClient.get( + Uri.parse(useCustomTaskID + ? "$endPoint/task/$taskID/comment?custom_task_ids=true&team_id=$teamID" + : "$endPoint/task/$taskID/comment"), + headers: {"Authorization": authToken}); final comments = jsonDecode(response.body); return comments; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -44,11 +52,19 @@ class ClickUpComments { bool useCustomTaskID = false, int? teamID, }) async { - if (!comment.containsKey("comment_text") && !comment.containsKey("assignee") && !comment.containsKey("notify_all")) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + if (!comment.containsKey("comment_text") && + !comment.containsKey("assignee") && + !comment.containsKey("notify_all")) { + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: + "Your data does not match API's model requirements. Please check documentation."); } try { - final response = await httpClient.post(Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/comment?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/comment"), + final response = await httpClient.post( + Uri.parse(useCustomTaskID + ? "$endPoint/task/$taskID/comment?custom_task_ids=true&team_id=$teamID" + : "$endPoint/task/$taskID/comment"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -58,7 +74,10 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -68,14 +87,21 @@ class ClickUpComments { String? startID, }) async { try { - final response = await httpClient.get(Uri.parse(start != null && startID != null ? "$endPoint/view/$viewID/comment?start=$start&start_id=$startID" : "$endPoint/view/$viewID/comment"), headers: { - "Authorization": authToken, - }); + final response = await httpClient.get( + Uri.parse(start != null && startID != null + ? "$endPoint/view/$viewID/comment?start=$start&start_id=$startID" + : "$endPoint/view/$viewID/comment"), + headers: { + "Authorization": authToken, + }); final createdComment = jsonDecode(response.body); return createdComment; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -83,11 +109,16 @@ class ClickUpComments { required String viewID, required Map comment, }) async { - if (!comment.containsKey("comment_text") && !comment.containsKey("notify_all")) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + if (!comment.containsKey("comment_text") && + !comment.containsKey("notify_all")) { + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: + "Your data does not match API's model requirements. Please check documentation."); } try { - final response = await httpClient.post(Uri.parse("$endPoint/view/$viewID/comment"), + final response = await httpClient.post( + Uri.parse("$endPoint/view/$viewID/comment"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -97,7 +128,10 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -107,15 +141,22 @@ class ClickUpComments { String? startID, }) async { try { - final response = await httpClient.get(Uri.parse(start != null && startID != null ? "$endPoint/list/$listID/comment?start=$start&start_id=$startID" : "$endPoint/list/$listID/comment"), headers: { - "Authorization": authToken, - "Content-Type": "application/json" - }); + final response = await httpClient.get( + Uri.parse(start != null && startID != null + ? "$endPoint/list/$listID/comment?start=$start&start_id=$startID" + : "$endPoint/list/$listID/comment"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); final createdComment = jsonDecode(response.body); return createdComment; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -123,12 +164,18 @@ class ClickUpComments { required String listID, required Map comment, }) async { - if (!comment.containsKey("comment_text") && !comment.containsKey("assignee") && !comment.containsKey("notify_all")) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + if (!comment.containsKey("comment_text") && + !comment.containsKey("assignee") && + !comment.containsKey("notify_all")) { + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: + "Your data does not match API's model requirements. Please check documentation."); } try { - final response = await httpClient.post(Uri.parse("$endPoint/list/$listID/comment"), + final response = await httpClient.post( + Uri.parse("$endPoint/list/$listID/comment"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -138,7 +185,10 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -146,11 +196,17 @@ class ClickUpComments { required double commentID, required Map comment, }) async { - if (!comment.containsKey("comment_text") && !comment.containsKey("assignee") && !comment.containsKey("resolved")) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your data does not match API's model requirements. Please check documentation."); + if (!comment.containsKey("comment_text") && + !comment.containsKey("assignee") && + !comment.containsKey("resolved")) { + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: + "Your data does not match API's model requirements. Please check documentation."); } try { - final response = await httpClient.put(Uri.parse("$endPoint/comment/$commentID"), + final response = await httpClient.put( + Uri.parse("$endPoint/comment/$commentID"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -160,7 +216,10 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -168,7 +227,8 @@ class ClickUpComments { required double commentID, }) async { try { - final response = await httpClient.delete(Uri.parse("$endPoint/comment/$commentID"), headers: { + final response = await httpClient + .delete(Uri.parse("$endPoint/comment/$commentID"), headers: { "Authorization": authToken, "Content-Type": "application/json" }); @@ -176,7 +236,10 @@ class ClickUpComments { return createdComment; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/custom_fields.dart b/lib/src/core/endpoints/custom_fields.dart index 328a8ca..1ebc89a 100644 --- a/lib/src/core/endpoints/custom_fields.dart +++ b/lib/src/core/endpoints/custom_fields.dart @@ -2,21 +2,23 @@ import 'dart:convert'; import 'package:clickup_dart_sdk/src/core/clickup_exception.dart'; import 'package:http/http.dart'; -enum CustomFieldType { - url, - number -} +enum CustomFieldType { url, number } class ClickUpCustomFields { late String endPoint; late String authToken; late Client httpClient; - ClickUpCustomFields({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpCustomFields( + {required this.endPoint, + required this.authToken, + required this.httpClient}); - Future> getAccessibleCustomFields({required String listID}) async { + Future> getAccessibleCustomFields( + {required String listID}) async { try { - final response = await httpClient.get(Uri.parse("$endPoint/list/$listID/field"), headers: { + final response = await httpClient + .get(Uri.parse("$endPoint/list/$listID/field"), headers: { "Authorization": authToken, "Content-Type": "application/json" }); @@ -24,7 +26,10 @@ class ClickUpCustomFields { return customFields; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -169,13 +174,24 @@ class ClickUpCustomFields { /// }, // Should be Map. /// } /// ``` - Future> setCustomFieldValue({required String taskID, required String fieldID, required Map value, bool customTaskID = false, double? teamID}) async { + Future> setCustomFieldValue( + {required String taskID, + required String fieldID, + required Map value, + bool customTaskID = false, + double? teamID}) async { if (!value.containsKey("value")) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your value model is invalid. Please read the function documentation."); + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: + "Your value model is invalid. Please read the function documentation."); } try { - final response = await httpClient.post(Uri.parse(customTaskID ? "$endPoint/task/$taskID/field/$fieldID?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/field/$fieldID"), + final response = await httpClient.post( + Uri.parse(customTaskID + ? "$endPoint/task/$taskID/field/$fieldID?custom_task_ids=true&team_id=$teamID" + : "$endPoint/task/$taskID/field/$fieldID"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -185,14 +201,23 @@ class ClickUpCustomFields { return customFieldResponse; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } - Future> removeCustomFieldValue({required String taskID, required String fieldID, bool customTaskID = false, double? teamID}) async { + Future> removeCustomFieldValue( + {required String taskID, + required String fieldID, + bool customTaskID = false, + double? teamID}) async { try { final response = await httpClient.delete( - Uri.parse(customTaskID ? "$endPoint/task/$taskID/field/$fieldID?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/field/$fieldID"), + Uri.parse(customTaskID + ? "$endPoint/task/$taskID/field/$fieldID?custom_task_ids=true&team_id=$teamID" + : "$endPoint/task/$taskID/field/$fieldID"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -202,7 +227,10 @@ class ClickUpCustomFields { return customFieldResponse; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/folders.dart b/lib/src/core/endpoints/folders.dart index ce01a24..7dcd673 100644 --- a/lib/src/core/endpoints/folders.dart +++ b/lib/src/core/endpoints/folders.dart @@ -8,73 +8,95 @@ class ClickUpFolders { late String authToken; late Client httpClient; - ClickUpFolders({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpFolders( + {required this.endPoint, + required this.authToken, + required this.httpClient}); - Future> getFolders({required double spaceID, bool includeArchived = false}) async { + Future> getFolders( + {required double spaceID, bool includeArchived = false}) async { try { - final response = await httpClient.get(Uri.parse(includeArchived ? "$endPoint/space/$spaceID/folder?archived=true" : "$endPoint/space/$spaceID/folder"), headers: { - "Authorization": authToken, - }); + final response = await httpClient.get( + Uri.parse(includeArchived + ? "$endPoint/space/$spaceID/folder?archived=true" + : "$endPoint/space/$spaceID/folder"), + headers: { + "Authorization": authToken, + }); final folders = jsonDecode(response.body); return folders; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } - Future> createFolder({required double spaceID, required String name}) async { + Future> createFolder( + {required double spaceID, required String name}) async { try { - final response = await httpClient.post(Uri.parse("$endPoint/space/$spaceID/folder"), + final response = await httpClient.post( + Uri.parse("$endPoint/space/$spaceID/folder"), headers: { "Authorization": authToken, "Content-Type": "application/json" }, - body: jsonEncode({ - "name": name - })); + body: jsonEncode({"name": name})); final folder = jsonDecode(response.body); return folder; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } Future> getFolder({required double folderID}) async { try { - final response = await httpClient.get(Uri.parse("$endPoint/folder/$folderID"), headers: { + final response = await httpClient + .get(Uri.parse("$endPoint/folder/$folderID"), headers: { "Authorization": authToken, }); final folder = jsonDecode(response.body); return folder; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } - Future> updateFolder({required double folderID, required String name}) async { + Future> updateFolder( + {required double folderID, required String name}) async { try { - final response = await httpClient.put(Uri.parse("$endPoint/folder/$folderID"), + final response = await httpClient.put( + Uri.parse("$endPoint/folder/$folderID"), headers: { "Authorization": authToken, "Content-Type": "application/json" }, - body: jsonEncode({ - "name": name - })); + body: jsonEncode({"name": name})); final folders = jsonDecode(response.body); return folders; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } Future> deleteFolder({required double folderID}) async { try { - final response = await httpClient.delete(Uri.parse("$endPoint/folder/$folderID"), headers: { + final response = await httpClient + .delete(Uri.parse("$endPoint/folder/$folderID"), headers: { "Authorization": authToken, "Content-Type": "application/json" }); @@ -82,7 +104,10 @@ class ClickUpFolders { return folders; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/goals.dart b/lib/src/core/endpoints/goals.dart index 1714c1c..c55deb7 100644 --- a/lib/src/core/endpoints/goals.dart +++ b/lib/src/core/endpoints/goals.dart @@ -5,5 +5,8 @@ class ClickUpGoals { late String authToken; late Client httpClient; - ClickUpGoals({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpGoals( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/guests.dart b/lib/src/core/endpoints/guests.dart index 81b1164..f1e4742 100644 --- a/lib/src/core/endpoints/guests.dart +++ b/lib/src/core/endpoints/guests.dart @@ -5,5 +5,8 @@ class ClickUpGuests { late String authToken; late Client httpClient; - ClickUpGuests({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpGuests( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/lists.dart b/lib/src/core/endpoints/lists.dart index c1c307c..486fa6a 100644 --- a/lib/src/core/endpoints/lists.dart +++ b/lib/src/core/endpoints/lists.dart @@ -5,5 +5,8 @@ class ClickUpLists { late String authToken; late Client httpClient; - ClickUpLists({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpLists( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/members.dart b/lib/src/core/endpoints/members.dart index edd8a0e..1a52e42 100644 --- a/lib/src/core/endpoints/members.dart +++ b/lib/src/core/endpoints/members.dart @@ -5,5 +5,8 @@ class ClickUpMembers { late String authToken; late Client httpClient; - ClickUpMembers({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpMembers( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/roles.dart b/lib/src/core/endpoints/roles.dart index aa00d4a..26067f2 100644 --- a/lib/src/core/endpoints/roles.dart +++ b/lib/src/core/endpoints/roles.dart @@ -5,5 +5,8 @@ class ClickUpRoles { late String authToken; late Client httpClient; - ClickUpRoles({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpRoles( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/shared_hierarchy.dart b/lib/src/core/endpoints/shared_hierarchy.dart index c33ed30..6d18711 100644 --- a/lib/src/core/endpoints/shared_hierarchy.dart +++ b/lib/src/core/endpoints/shared_hierarchy.dart @@ -5,5 +5,8 @@ class ClickUpSharedHierarchy { late String authToken; late Client httpClient; - ClickUpSharedHierarchy({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpSharedHierarchy( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/spaces.dart b/lib/src/core/endpoints/spaces.dart index a06d977..560dff7 100644 --- a/lib/src/core/endpoints/spaces.dart +++ b/lib/src/core/endpoints/spaces.dart @@ -8,7 +8,10 @@ class ClickUpSpaces { late String authToken; late Client httpClient; - ClickUpSpaces({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpSpaces( + {required this.endPoint, + required this.authToken, + required this.httpClient}); final Map sampleSpaceSchema = { "name": "Test Space", @@ -20,47 +23,41 @@ class ClickUpSpaces { "remap_due_dates": false, "remap_closed_due_date": false }, - "time_tracking": { - "enabled": false - }, - "tags": { - "enabled": false - }, - "time_estimates": { - "enabled": false - }, - "checklists": { - "enabled": false - }, - "custom_fields": { - "enabled": false - }, - "remap_dependencies": { - "enabled": false - }, - "dependency_warning": { - "enabled": false - }, - "portfolios": { - "enabled": false - }, + "time_tracking": {"enabled": false}, + "tags": {"enabled": false}, + "time_estimates": {"enabled": false}, + "checklists": {"enabled": false}, + "custom_fields": {"enabled": false}, + "remap_dependencies": {"enabled": false}, + "dependency_warning": {"enabled": false}, + "portfolios": {"enabled": false}, } }; - Future> getSpaces({required double teamID, bool includeArchived = false}) async { + Future> getSpaces( + {required double teamID, bool includeArchived = false}) async { try { - final response = await httpClient.get(Uri.parse(includeArchived ? "$endPoint/team/$teamID/space?archived=true" : "$endPoint/team/$teamID/space"), headers: { - "Authorization": authToken, - }); + final response = await httpClient.get( + Uri.parse(includeArchived + ? "$endPoint/team/$teamID/space?archived=true" + : "$endPoint/team/$teamID/space"), + headers: { + "Authorization": authToken, + }); final spaces = jsonDecode(response.body); return spaces; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } - Future> createSpace({required double teamID, required Map spaceSchema}) async { + Future> createSpace( + {required double teamID, + required Map spaceSchema}) async { bool schemaMatch = false; for (var key in spaceSchema.keys) { schemaMatch = sampleSpaceSchema.containsKey(key); @@ -70,11 +67,15 @@ class ClickUpSpaces { } if (!schemaMatch) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your value model is invalid. Please read the function documentation."); + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: + "Your value model is invalid. Please read the function documentation."); } try { - final response = await httpClient.post(Uri.parse("$endPoint/team/$teamID/space"), + final response = await httpClient.post( + Uri.parse("$endPoint/team/$teamID/space"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -84,24 +85,33 @@ class ClickUpSpaces { return space; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } Future> getSpace({required double spaceID}) async { try { - final response = await httpClient.get(Uri.parse("$endPoint/space/$spaceID"), headers: { + final response = + await httpClient.get(Uri.parse("$endPoint/space/$spaceID"), headers: { "Authorization": authToken, }); final space = jsonDecode(response.body); return space; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } - Future> updateSpace({required double spaceID, required Map spaceSchema}) async { + Future> updateSpace( + {required double spaceID, + required Map spaceSchema}) async { bool schemaMatch = false; schemaMatch = spaceSchema.containsKey("color"); schemaMatch = spaceSchema.containsKey("private"); @@ -115,10 +125,14 @@ class ClickUpSpaces { } } if (!schemaMatch) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Your value model is invalid. Please read the function documentation."); + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: + "Your value model is invalid. Please read the function documentation."); } try { - final response = await httpClient.put(Uri.parse("$endPoint/space/$spaceID"), + final response = await httpClient.put( + Uri.parse("$endPoint/space/$spaceID"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -128,20 +142,27 @@ class ClickUpSpaces { return folders; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } Future> deleteSpace({required double spaceID}) async { try { - final response = await httpClient.delete(Uri.parse("$endPoint/folder/$spaceID"), headers: { + final response = await httpClient + .delete(Uri.parse("$endPoint/folder/$spaceID"), headers: { "Authorization": authToken, }); final folders = jsonDecode(response.body); return folders; } catch (e) { print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/tags.dart b/lib/src/core/endpoints/tags.dart index 3e8b48e..1df1666 100644 --- a/lib/src/core/endpoints/tags.dart +++ b/lib/src/core/endpoints/tags.dart @@ -5,5 +5,8 @@ class ClickUpTags { late String authToken; late Client httpClient; - ClickUpTags({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTags( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/task_checklists.dart b/lib/src/core/endpoints/task_checklists.dart index 23c7ab9..051ccb9 100644 --- a/lib/src/core/endpoints/task_checklists.dart +++ b/lib/src/core/endpoints/task_checklists.dart @@ -4,5 +4,8 @@ class ClickUpTaskChecklists { late String endPoint; late String authToken; late Client httpClient; - ClickUpTaskChecklists({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTaskChecklists( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/task_relationships.dart b/lib/src/core/endpoints/task_relationships.dart index 6d60994..018bf5f 100644 --- a/lib/src/core/endpoints/task_relationships.dart +++ b/lib/src/core/endpoints/task_relationships.dart @@ -5,5 +5,8 @@ class ClickUpTaskRelationships { late String authToken; late Client httpClient; - ClickUpTaskRelationships({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTaskRelationships( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/task_templates.dart b/lib/src/core/endpoints/task_templates.dart index 9e0d963..1507496 100644 --- a/lib/src/core/endpoints/task_templates.dart +++ b/lib/src/core/endpoints/task_templates.dart @@ -5,5 +5,8 @@ class ClickUpTaskTemplates { late String authToken; late Client httpClient; - ClickUpTaskTemplates({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTaskTemplates( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/tasks.dart b/lib/src/core/endpoints/tasks.dart index 657dbbe..2a6d158 100644 --- a/lib/src/core/endpoints/tasks.dart +++ b/lib/src/core/endpoints/tasks.dart @@ -9,7 +9,10 @@ class ClickUpTasks { late String authToken; late Client httpClient; - ClickUpTasks({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTasks( + {required this.endPoint, + required this.authToken, + required this.httpClient}); Future> getTasks({ required double listID, @@ -51,17 +54,21 @@ class ClickUpTasks { tagQuery = assigneeQuery.substring(0, assigneeQuery.length - 1); } - final queryParams = "?archived=$archived&page=$page&order_by=$orderBy&reverse=$reverse&subtasks=$subtasks&statuses=$statuses&include_closed=$includeClosed&assignees=$assigneeQuery&tags=$tagQuery&due_date_gt=$dueDateGreaterThan&due_date_lt=$dueDateLessThan&date_created_gt=$dateCreatedGreaterThan&date_created_lt=$dateCreatedLessThan&date_updated_gt=$dateUpdatedGreaterThan&date_updated_lt=$dateUpdatedLessThan&date_done_gt=$dateDoneGreaterThan&date_done_lt=$dateDoneGreaterThan&custom_fields=$customFieldQuery"; + final queryParams = + "?archived=$archived&page=$page&order_by=$orderBy&reverse=$reverse&subtasks=$subtasks&statuses=$statuses&include_closed=$includeClosed&assignees=$assigneeQuery&tags=$tagQuery&due_date_gt=$dueDateGreaterThan&due_date_lt=$dueDateLessThan&date_created_gt=$dateCreatedGreaterThan&date_created_lt=$dateCreatedLessThan&date_updated_gt=$dateUpdatedGreaterThan&date_updated_lt=$dateUpdatedLessThan&date_done_gt=$dateDoneGreaterThan&date_done_lt=$dateDoneGreaterThan&custom_fields=$customFieldQuery"; try { - final response = await httpClient.get(Uri.parse("$endPoint/list/$listID/task$queryParams"), headers: { - "Authorization": authToken - }); + final response = await httpClient.get( + Uri.parse("$endPoint/list/$listID/task$queryParams"), + headers: {"Authorization": authToken}); final List tasks = jsonDecode(response.body); return tasks.first; } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -104,7 +111,8 @@ class ClickUpTasks { } try { - final response = await httpClient.post(Uri.parse("$endPoint/list/$listID/task$queryParams"), + final response = await httpClient.post( + Uri.parse("$endPoint/list/$listID/task$queryParams"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -115,11 +123,18 @@ class ClickUpTasks { } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } - Future> getTask({required double taskID, bool customTaskIDs = false, double teamID = 0, bool includeSubtasks = false}) async { + Future> getTask( + {required double taskID, + bool customTaskIDs = false, + double teamID = 0, + bool includeSubtasks = false}) async { ////TO:DO Parameter validation var queryParams = ""; @@ -133,7 +148,8 @@ class ClickUpTasks { } try { - final response = await httpClient.get(Uri.parse("$endPoint/task/$taskID$queryParams"), headers: { + final response = await httpClient + .get(Uri.parse("$endPoint/task/$taskID$queryParams"), headers: { "Authorization": authToken, }); final task = jsonDecode(response.body); @@ -141,7 +157,10 @@ class ClickUpTasks { } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -182,7 +201,8 @@ class ClickUpTasks { } try { - final response = await httpClient.put(Uri.parse("$endPoint/task/$taskID$queryParams"), + final response = await httpClient.put( + Uri.parse("$endPoint/task/$taskID$queryParams"), headers: { "Authorization": authToken, "Content-Type": "application/json" @@ -193,7 +213,10 @@ class ClickUpTasks { } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -213,7 +236,8 @@ class ClickUpTasks { } try { - final response = await httpClient.delete(Uri.parse("$endPoint/task/$taskID$queryParams"), headers: { + final response = await httpClient + .delete(Uri.parse("$endPoint/task/$taskID$queryParams"), headers: { "Authorization": authToken, "Content-Type": "application/json" }); @@ -222,7 +246,10 @@ class ClickUpTasks { } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -262,7 +289,8 @@ class ClickUpTasks { var tagsQuery = ""; var customFieldsQuery = ""; - var queryParams = "?page=$page&order_by=$orderBy&reverse=$reverse&subtasks=$subtasks&space_ids=$spaceIDsQuery&project_ids=$projectIDsQuery&list_ids=$listIDsQuery&statuses=$statusesQuery&include_closed=$includeClosed&assignees=$assigneesQuery&tags=$tagsQuery&due_date_gt=$dueDateGreaterThan&due_date_lt=$dueDateLessThan&date_created_gt=$dateCreatedGreaterThan&date_created_lt=$dateCreatedLessThan&date_updated_gt=$dateUpdatedGreaterThan&date_updated_lt=$dateUpdatedLessThan&date_done_gt=$dateDoneGreaterThan&date_done_lt=$dateDoneLessThan&custom_fields=$customFieldsQuery"; + var queryParams = + "?page=$page&order_by=$orderBy&reverse=$reverse&subtasks=$subtasks&space_ids=$spaceIDsQuery&project_ids=$projectIDsQuery&list_ids=$listIDsQuery&statuses=$statusesQuery&include_closed=$includeClosed&assignees=$assigneesQuery&tags=$tagsQuery&due_date_gt=$dueDateGreaterThan&due_date_lt=$dueDateLessThan&date_created_gt=$dateCreatedGreaterThan&date_created_lt=$dateCreatedLessThan&date_updated_gt=$dateUpdatedGreaterThan&date_updated_lt=$dateUpdatedLessThan&date_done_gt=$dateDoneGreaterThan&date_done_lt=$dateDoneLessThan&custom_fields=$customFieldsQuery"; if (customTaskIDs) { queryParams = "${queryParams}custom_task_ids=true"; if (teamID != 0) { @@ -274,15 +302,20 @@ class ClickUpTasks { } try { - final response = await httpClient.get(Uri.parse("$endPoint/team/$workspaceTeamID/task$queryParams"), headers: { - "Authorization": authToken, - }); + final response = await httpClient.get( + Uri.parse("$endPoint/team/$workspaceTeamID/task$queryParams"), + headers: { + "Authorization": authToken, + }); final task = jsonDecode(response.body); return task; } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -302,16 +335,21 @@ class ClickUpTasks { } try { - final response = await httpClient.get(Uri.parse("$endPoint/task/$taskID/time_in_status$queryParams"), headers: { - "Authorization": authToken, - "Content-Type": "application/json" - }); + final response = await httpClient.get( + Uri.parse("$endPoint/task/$taskID/time_in_status$queryParams"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); final task = jsonDecode(response.body); return task; } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } @@ -321,7 +359,9 @@ class ClickUpTasks { double teamID = 0, }) async { if (taskIDs.length > 99) { - throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "You can only query up to 100 tasks per request"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.invalidModel, + exceptionMessage: "You can only query up to 100 tasks per request"); } ////TO:DO Parameter validation var queryParams = "?"; @@ -340,16 +380,21 @@ class ClickUpTasks { } try { - final response = await httpClient.get(Uri.parse("$endPoint/task/bulk_time_in_status/task_ids$queryParams"), headers: { - "Authorization": authToken, - "Content-Type": "application/json" - }); + final response = await httpClient.get( + Uri.parse("$endPoint/task/bulk_time_in_status/task_ids$queryParams"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }); final task = jsonDecode(response.body); return task; } catch (e) { print(e); print(e.toString()); - throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException( + exceptionType: ClickUpExceptionType.requestError, + exceptionMessage: + "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/teams.dart b/lib/src/core/endpoints/teams.dart index 5a82634..ccde3b6 100644 --- a/lib/src/core/endpoints/teams.dart +++ b/lib/src/core/endpoints/teams.dart @@ -5,5 +5,8 @@ class ClickUpTeams { late String authToken; late Client httpClient; - ClickUpTeams({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTeams( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/time_tracking_legacy.dart b/lib/src/core/endpoints/time_tracking_legacy.dart index 15e64a7..6fc3b78 100644 --- a/lib/src/core/endpoints/time_tracking_legacy.dart +++ b/lib/src/core/endpoints/time_tracking_legacy.dart @@ -5,5 +5,8 @@ class ClickUpTimeTrackingLegacy { late String authToken; late Client httpClient; - ClickUpTimeTrackingLegacy({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTimeTrackingLegacy( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/time_tracking_v2.dart b/lib/src/core/endpoints/time_tracking_v2.dart index f8c8591..c850703 100644 --- a/lib/src/core/endpoints/time_tracking_v2.dart +++ b/lib/src/core/endpoints/time_tracking_v2.dart @@ -5,5 +5,8 @@ class ClickUpTimeTrackingV2 { late String authToken; late Client httpClient; - ClickUpTimeTrackingV2({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpTimeTrackingV2( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/users.dart b/lib/src/core/endpoints/users.dart index da65f0c..cbd505c 100644 --- a/lib/src/core/endpoints/users.dart +++ b/lib/src/core/endpoints/users.dart @@ -5,5 +5,8 @@ class ClickUpUsers { late String authToken; late Client httpClient; - ClickUpUsers({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpUsers( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/views.dart b/lib/src/core/endpoints/views.dart index a30c9c6..76064bb 100644 --- a/lib/src/core/endpoints/views.dart +++ b/lib/src/core/endpoints/views.dart @@ -5,5 +5,8 @@ class ClickUpViews { late String authToken; late Client httpClient; - ClickUpViews({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpViews( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/lib/src/core/endpoints/webhooks.dart b/lib/src/core/endpoints/webhooks.dart index 2f2cf5a..f4bf2fa 100644 --- a/lib/src/core/endpoints/webhooks.dart +++ b/lib/src/core/endpoints/webhooks.dart @@ -5,5 +5,8 @@ class ClickUpWebhooks { late String authToken; late Client httpClient; - ClickUpWebhooks({required this.endPoint, required this.authToken, required this.httpClient}); + ClickUpWebhooks( + {required this.endPoint, + required this.authToken, + required this.httpClient}); } diff --git a/pubspec.yaml b/pubspec.yaml index 1a43124..4bca773 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 0.3.0 repository: https://github.com/ayazemre/clickup-dart-sdk environment: - sdk: '>=2.18.5 <3.0.0' + sdk: '>=2.18.5 <4.0.0' dev_dependencies: lints: ^2.0.0 diff --git a/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart b/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart index ef1616d..3bc0b66 100644 --- a/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart +++ b/test/e2e/clickup_dart_sdk_sample_user_behaviour_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); group("User Logs in, creates a task and uploads a file.", () { diff --git a/test/integration/attachment_test.dart b/test/integration/attachment_test.dart index 2b1fd2e..7b83d46 100644 --- a/test/integration/attachment_test.dart +++ b/test/integration/attachment_test.dart @@ -11,13 +11,21 @@ void main() { setUp(() async { // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Upload an attachment', () async { - final response = await clickUp.attachments.createTaskAttachment(filePath: p.join(p.current, "test", "integration", "beksinski_sample.jpg"), taskID: "213123", useCustomTaskID: false); + final response = await clickUp.attachments.createTaskAttachment( + filePath: + p.join(p.current, "test", "integration", "beksinski_sample.jpg"), + taskID: "213123", + useCustomTaskID: false); expect(response, { - 'message': 'Mock server error. Media type multipart/form-data deserialization is not supported.' + 'message': + 'Mock server error. Media type multipart/form-data deserialization is not supported.' }); }); }); diff --git a/test/integration/auth_test.dart b/test/integration/auth_test.dart index 7aae6d8..2be8e00 100644 --- a/test/integration/auth_test.dart +++ b/test/integration/auth_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/comments_test.dart b/test/integration/comments_test.dart index f6116f9..ce59c93 100644 --- a/test/integration/comments_test.dart +++ b/test/integration/comments_test.dart @@ -9,81 +9,108 @@ void main() { setUp(() async { // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Comments - Get Task Comments', () async { - final taskComments = await clickUp.comments.getTaskComments(taskID: "a1b2c3"); + final taskComments = + await clickUp.comments.getTaskComments(taskID: "a1b2c3"); expect(taskComments.containsKey("comments"), true); }); test('Comments - Create Task Comment', () async { - final createdComment = await clickUp.comments.createTaskComment(taskID: "a1b2c3", comment: { - "comment_text": "Hi I am Emre", - "assignee": 123456, - "notify_all": true - }); + final createdComment = await clickUp.comments.createTaskComment( + taskID: "a1b2c3", + comment: { + "comment_text": "Hi I am Emre", + "assignee": 123456, + "notify_all": true + }); expect(createdComment.containsKey("id"), true); }); test('Comments - Create Task Comment - Invalid Data', () async { - expect(() async => await clickUp.comments.createTaskComment(taskID: "a1b2c3", comment: {}), throwsA(isA())); + expect( + () async => await clickUp.comments + .createTaskComment(taskID: "a1b2c3", comment: {}), + throwsA(isA())); }); test('Comments - Get Chat View Comments - Last 25', () async { - final chatViewComments = await clickUp.comments.getChatViewComments(viewID: "12345"); + final chatViewComments = + await clickUp.comments.getChatViewComments(viewID: "12345"); expect(chatViewComments.containsKey("comments"), true); }); test('Comments - Get Chat View Comments - Custom Range', () async { - final chatViewComments = await clickUp.comments.getChatViewComments(viewID: "12345", start: 3, startID: "12345"); + final chatViewComments = await clickUp.comments + .getChatViewComments(viewID: "12345", start: 3, startID: "12345"); expect(chatViewComments.containsKey("comments"), true); }); test('Comments - Create Chat View Comment', () async { - final createdChatViewComment = await clickUp.comments.createChatViewComment(viewID: "12345", comment: { - "comment_text": "Hi I am Emre", - "notify_all": true - }); + final createdChatViewComment = await clickUp.comments + .createChatViewComment( + viewID: "12345", + comment: {"comment_text": "Hi I am Emre", "notify_all": true}); expect(createdChatViewComment.containsKey("id"), true); }); test('Comments - Create Chat View Comment - Invalid Data', () async { - expect(() async => await clickUp.comments.createChatViewComment(viewID: "12345", comment: {}), throwsA(isA())); + expect( + () async => await clickUp.comments + .createChatViewComment(viewID: "12345", comment: {}), + throwsA(isA())); }); test('Comments - Get List Comments - Last 25', () async { - final listComments = await clickUp.comments.getListComments(listID: 12345); + final listComments = + await clickUp.comments.getListComments(listID: 12345); expect(listComments.containsKey("comments"), true); }); test('Comments - Get List Comments - Custom Range', () async { - final listComments = await clickUp.comments.getListComments(listID: 12345, start: 2, startID: "123"); + final listComments = await clickUp.comments + .getListComments(listID: 12345, start: 2, startID: "123"); expect(listComments.containsKey("comments"), true); }); test('Comments - Create List Comment', () async { - final listComment = await clickUp.comments.createListComment(listID: "12345", comment: { - "comment_text": "Hi I am Emre", - "assignee": 123456, - "notify_all": true - }); + final listComment = await clickUp.comments.createListComment( + listID: "12345", + comment: { + "comment_text": "Hi I am Emre", + "assignee": 123456, + "notify_all": true + }); expect(listComment.containsKey("id"), true); }); test('Comments - Create List Comment - Invalid Data', () async { - expect(() async => await clickUp.comments.createListComment(listID: "12345", comment: {}), throwsA(isA())); + expect( + () async => await clickUp.comments + .createListComment(listID: "12345", comment: {}), + throwsA(isA())); }); test('Comments - Update Comment', () async { - final updatedComment = await clickUp.comments.updateComment(commentID: 1234, comment: { - "comment_text": "Hi I am Emre", - "assignee": 123456, - "resolved": true - }); + final updatedComment = await clickUp.comments.updateComment( + commentID: 1234, + comment: { + "comment_text": "Hi I am Emre", + "assignee": 123456, + "resolved": true + }); expect(updatedComment.isEmpty, true); }); test('Comments - Update Comment - Invalid Data', () async { - expect(() async => await clickUp.comments.updateComment(commentID: 1234, comment: {}), throwsA(isA())); + expect( + () async => await clickUp.comments + .updateComment(commentID: 1234, comment: {}), + throwsA(isA())); }); test('Comments - Delete Comment', () async { - final deletedComment = await clickUp.comments.deleteComment(commentID: 1234); + final deletedComment = + await clickUp.comments.deleteComment(commentID: 1234); expect(deletedComment.isEmpty, true); }); }); diff --git a/test/integration/custom_fields_test.dart b/test/integration/custom_fields_test.dart index 38bca74..8adc19c 100644 --- a/test/integration/custom_fields_test.dart +++ b/test/integration/custom_fields_test.dart @@ -10,28 +10,33 @@ void main() { setUp(() async { // Setting up the SDK with a random token and mock server. ClickUp's official mock server accepts random tokens as valid tokens. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); // Tests are run for just getting the fields and updating the URL field. Remaining field types are dependent on the model and all of the models actually return success. This means testing for only one field type should be enough. test('Custom Fields - Get Accessible Custom Fields', () async { - final customFields = await clickUp.customFields.getAccessibleCustomFields(listID: "1234"); + final customFields = + await clickUp.customFields.getAccessibleCustomFields(listID: "1234"); expect(customFields.containsKey("fields"), true); }); test('Custom Fields - Set Custom Field Value - URL Custom Field', () async { - final customField = await clickUp.customFields.setCustomFieldValue(fieldID: "1234", taskID: "1234", value: { - "value": "https://ayazemre.com" - }); + final customField = await clickUp.customFields.setCustomFieldValue( + fieldID: "1234", + taskID: "1234", + value: {"value": "https://ayazemre.com"}); print(customField); expect(customField.isEmpty, true); }); - test('Custom Fields - Set Custom Field Value - URL Custom Field - Custom Task ID', () async { + test( + 'Custom Fields - Set Custom Field Value - URL Custom Field - Custom Task ID', + () async { final customField = await clickUp.customFields.setCustomFieldValue( fieldID: "1234", taskID: "1234", - value: { - "value": "https://ayazemre.com" - }, + value: {"value": "https://ayazemre.com"}, customTaskID: true, teamID: 1234); expect(customField.isEmpty, true); @@ -41,19 +46,20 @@ void main() { () async => await clickUp.customFields.setCustomFieldValue( fieldID: "1234", taskID: "1234", - value: { - "valeu": "https://ayazemre.com" - }, + value: {"valeu": "https://ayazemre.com"}, customTaskID: true, teamID: 1234), throwsA(isA())); }); test('Custom Fields - Remove Custom Field Value', () async { - final result = await clickUp.customFields.removeCustomFieldValue(fieldID: "1234", taskID: "1234"); + final result = await clickUp.customFields + .removeCustomFieldValue(fieldID: "1234", taskID: "1234"); expect(result.isEmpty, true); }); - test('Custom Fields - Remove Custom Field Value - Custom Task ID', () async { - final result = await clickUp.customFields.removeCustomFieldValue(fieldID: "1234", taskID: "1234", customTaskID: true, teamID: 1234); + test('Custom Fields - Remove Custom Field Value - Custom Task ID', + () async { + final result = await clickUp.customFields.removeCustomFieldValue( + fieldID: "1234", taskID: "1234", customTaskID: true, teamID: 1234); expect(result.isEmpty, true); }); }); diff --git a/test/integration/folders_test.dart b/test/integration/folders_test.dart index 3df8b77..51f94ea 100644 --- a/test/integration/folders_test.dart +++ b/test/integration/folders_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Folders - Get Folders', () async { @@ -16,20 +19,28 @@ void main() { expect(folders.containsKey("folders"), true); }); test('Folders - Get Folders: Include Archived', () async { - final folders = await clickUp.folders.getFolders(spaceID: 123, includeArchived: true); + final folders = + await clickUp.folders.getFolders(spaceID: 123, includeArchived: true); expect(folders.containsKey("folders"), true); }); test('Folders - Create Folder', () async { - final folder = await clickUp.folders.createFolder(spaceID: 123, name: "Test Folder"); - expect(folder.containsKey("name") && folder.containsValue("Test Folder"), true); + final folder = + await clickUp.folders.createFolder(spaceID: 123, name: "Test Folder"); + expect(folder.containsKey("name") && folder.containsValue("Test Folder"), + true); }); test('Folders - Get Folder', () async { final folder = await clickUp.folders.getFolder(folderID: 123); expect(folder.containsKey("id"), true); }); test('Folders - Update Folder', () async { - final folder = await clickUp.folders.updateFolder(folderID: 123, name: "Test Updated Folder"); - expect(folder.containsKey("name") && folder.containsValue("Test Updated Folder") && folder.containsKey("id"), true); + final folder = await clickUp.folders + .updateFolder(folderID: 123, name: "Test Updated Folder"); + expect( + folder.containsKey("name") && + folder.containsValue("Test Updated Folder") && + folder.containsKey("id"), + true); }); test('Folders - Delete Folder', () async { final folder = await clickUp.folders.deleteFolder(folderID: 123); diff --git a/test/integration/guests_test.dart b/test/integration/guests_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/guests_test.dart +++ b/test/integration/guests_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/lists_test.dart b/test/integration/lists_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/lists_test.dart +++ b/test/integration/lists_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/members_test.dart b/test/integration/members_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/members_test.dart +++ b/test/integration/members_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/roles_test.dart b/test/integration/roles_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/roles_test.dart +++ b/test/integration/roles_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/shared_hierarchy_test.dart b/test/integration/shared_hierarchy_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/shared_hierarchy_test.dart +++ b/test/integration/shared_hierarchy_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/spaces_test.dart b/test/integration/spaces_test.dart index e664fc9..a0765f8 100644 --- a/test/integration/spaces_test.dart +++ b/test/integration/spaces_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Spaces - Get Spaces', () async { @@ -17,11 +20,13 @@ void main() { expect(spaces.containsKey("spaces"), true); }); test('Spaces - Get Spaces: Include Archived', () async { - final spaces = await clickUp.spaces.getSpaces(teamID: 123, includeArchived: true); + final spaces = + await clickUp.spaces.getSpaces(teamID: 123, includeArchived: true); expect(spaces.containsKey("spaces"), true); }); test('Spaces - Create Space', () async { - final space = await clickUp.spaces.createSpace(teamID: 123, spaceSchema: clickUp.spaces.sampleSpaceSchema); + final space = await clickUp.spaces.createSpace( + teamID: 123, spaceSchema: clickUp.spaces.sampleSpaceSchema); expect(space.containsKey("features"), true); }); test('Spaces - Get Space', () async { @@ -29,13 +34,10 @@ void main() { expect(space.containsKey("features"), true); }); test('Spaces - Update Space', () async { - final space = await clickUp.spaces.updateSpace(spaceID: 123, spaceSchema: { + final space = + await clickUp.spaces.updateSpace(spaceID: 123, spaceSchema: { ...clickUp.spaces.sampleSpaceSchema, - ...{ - "color": "blue", - "private": false, - "admin_can_manage": false - } + ...{"color": "blue", "private": false, "admin_can_manage": false} }); expect(space.containsKey("features"), true); }); diff --git a/test/integration/tags_test.dart b/test/integration/tags_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/tags_test.dart +++ b/test/integration/tags_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/task_checklists_test.dart b/test/integration/task_checklists_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/task_checklists_test.dart +++ b/test/integration/task_checklists_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/task_relationships.dart b/test/integration/task_relationships.dart index 25fbe3a..c01774d 100644 --- a/test/integration/task_relationships.dart +++ b/test/integration/task_relationships.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/task_templates_test.dart b/test/integration/task_templates_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/task_templates_test.dart +++ b/test/integration/task_templates_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/tasks_test.dart b/test/integration/tasks_test.dart index 95d59b1..9664ac6 100644 --- a/test/integration/tasks_test.dart +++ b/test/integration/tasks_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Tasks - Get Tasks', () async { @@ -56,10 +59,7 @@ void main() { "time_estimate": 0, "start_date": 0, "start_date_time": false, - "assignees": { - "add": [], - "rem": [] - }, //List of integers + "assignees": {"add": [], "rem": []}, //List of integers "archived": false }); print(task); @@ -81,10 +81,8 @@ void main() { expect(task.containsKey("current_status"), true); }); test('Tasks - Get Bulk Tasks Time In Status', () async { - final task = await clickUp.tasks.getBulkTasksTimeInStatus(taskIDs: [ - "1", - "2" - ]); + final task = + await clickUp.tasks.getBulkTasksTimeInStatus(taskIDs: ["1", "2"]); print(task); final result = task.values.first as Map; expect(result.containsKey("current_status"), true); diff --git a/test/integration/teams_test.dart b/test/integration/teams_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/teams_test.dart +++ b/test/integration/teams_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/time_tracking_legacy_test.dart b/test/integration/time_tracking_legacy_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/time_tracking_legacy_test.dart +++ b/test/integration/time_tracking_legacy_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/time_tracking_v2_test.dart b/test/integration/time_tracking_v2_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/time_tracking_v2_test.dart +++ b/test/integration/time_tracking_v2_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/users_test.dart b/test/integration/users_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/users_test.dart +++ b/test/integration/users_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/views_test.dart b/test/integration/views_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/views_test.dart +++ b/test/integration/views_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { diff --git a/test/integration/webhooks_test.dart b/test/integration/webhooks_test.dart index 25fbe3a..c01774d 100644 --- a/test/integration/webhooks_test.dart +++ b/test/integration/webhooks_test.dart @@ -8,7 +8,10 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + clickUp = ClickUp( + apiEndpoint: + "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") + ..initialize(authToken: token); }); test('Authorization - Get Authorized User', () async { From cf45b078e16d51e8d0ad4a39acae92edcd9cdefb Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Thu, 25 May 2023 13:46:56 +0300 Subject: [PATCH 13/17] pubspecfix --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 1a43124..4bca773 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 0.3.0 repository: https://github.com/ayazemre/clickup-dart-sdk environment: - sdk: '>=2.18.5 <3.0.0' + sdk: '>=2.18.5 <4.0.0' dev_dependencies: lints: ^2.0.0 From 719fa3894f700d931cd59155add66ff926ee6cdd Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Thu, 25 May 2023 13:47:45 +0300 Subject: [PATCH 14/17] version fix --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 4bca773..ab6d0c9 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: clickup_dart_sdk description: A SDK for ClickUp for integrating or creating applications on top of the product. -version: 0.3.0 +version: 0.3.2 repository: https://github.com/ayazemre/clickup-dart-sdk environment: From ec6a23296fa36521b8b506131efa34e7cbf4ff34 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Mon, 3 Jul 2023 23:50:05 +0300 Subject: [PATCH 15/17] various implementations --- CHANGELOG.md | 8 + lib/src/clickup_dart_base.dart | 73 ++---- lib/src/core/endpoints/auth.dart | 25 +- lib/src/core/endpoints/goals.dart | 222 ++++++++++++++++- lib/src/core/endpoints/guests.dart | 252 +++++++++++++++++++- lib/src/core/endpoints/lists.dart | 81 ++++++- lib/src/core/endpoints/task_checklists.dart | 138 ++++++++++- test/integration/goals_test.dart | 90 ++++++- test/integration/guests_test.dart | 68 +++++- test/integration/lists_test.dart | 24 +- test/integration/task_checklists_test.dart | 43 +++- 11 files changed, 916 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b43026d..24a9109 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.4.0 + +- Implemented endpoints for Goals, Guests and Task Checklists + +## 0.3.2 + +- Refactoring and minor fixes. + ## 0.3.0 - Implemented endpoints for Tasks. diff --git a/lib/src/clickup_dart_base.dart b/lib/src/clickup_dart_base.dart index 19dab20..e7efb4f 100644 --- a/lib/src/clickup_dart_base.dart +++ b/lib/src/clickup_dart_base.dart @@ -59,56 +59,29 @@ class ClickUp { void initialize({required String authToken}) async { httpClient = Client(); - auth = ClickUpAuth( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - attachments = ClickUpAttachments( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - comments = ClickUpComments( - endPoint: apiEndpoint, - authToken: auth.authToken, - httpClient: httpClient); - customFields = ClickUpCustomFields( - endPoint: apiEndpoint, - authToken: auth.authToken, - httpClient: httpClient); - folders = ClickUpFolders( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - goals = ClickUpGoals( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - guests = ClickUpGuests( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - lists = ClickUpLists( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - members = ClickUpMembers( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - roles = ClickUpRoles( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - sharedHierarchy = ClickUpSharedHierarchy( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - spaces = ClickUpSpaces( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - tags = ClickUpTags( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - tasks = ClickUpTasks( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - taskChecklists = ClickUpTaskChecklists( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - taskRelationships = ClickUpTaskRelationships( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - taskTemplates = ClickUpTaskTemplates( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - teams = ClickUpTeams( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - timeTrackingLegacy = ClickUpTimeTrackingLegacy( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - timeTrackingV2 = ClickUpTimeTrackingV2( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - users = ClickUpUsers( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - views = ClickUpViews( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); - webhooks = ClickUpWebhooks( - endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + auth = ClickUpAuth(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + attachments = ClickUpAttachments(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + comments = ClickUpComments(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); + customFields = ClickUpCustomFields(endPoint: apiEndpoint, authToken: auth.authToken, httpClient: httpClient); + folders = ClickUpFolders(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + goals = ClickUpGoals(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + guests = ClickUpGuests(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + lists = ClickUpLists(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + members = ClickUpMembers(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + roles = ClickUpRoles(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + sharedHierarchy = ClickUpSharedHierarchy(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + spaces = ClickUpSpaces(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + tags = ClickUpTags(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + tasks = ClickUpTasks(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskChecklists = ClickUpTaskChecklists(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskRelationships = ClickUpTaskRelationships(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + taskTemplates = ClickUpTaskTemplates(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + teams = ClickUpTeams(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + timeTrackingLegacy = ClickUpTimeTrackingLegacy(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + timeTrackingV2 = ClickUpTimeTrackingV2(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + users = ClickUpUsers(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + views = ClickUpViews(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); + webhooks = ClickUpWebhooks(endPoint: apiEndpoint, authToken: authToken, httpClient: httpClient); print("ClickUp Initialized.."); } } diff --git a/lib/src/core/endpoints/auth.dart b/lib/src/core/endpoints/auth.dart index 774e79a..32340d9 100644 --- a/lib/src/core/endpoints/auth.dart +++ b/lib/src/core/endpoints/auth.dart @@ -7,10 +7,7 @@ class ClickUpAuth { late String authToken; late Client httpClient; - ClickUpAuth( - {required this.endPoint, - required this.authToken, - required this.httpClient}); + ClickUpAuth({required this.endPoint, required this.authToken, required this.httpClient}); /// Get access token based on your credentials. // Future getAccessToken( @@ -31,32 +28,28 @@ class ClickUpAuth { /// Get the user bound to the token. Future> getAuthorizedUser() async { try { - final response = await httpClient.get(Uri.parse("$endPoint/user"), - headers: {"Authorization": authToken}); + final response = await httpClient.get(Uri.parse("$endPoint/user"), headers: { + "Authorization": authToken + }); final user = jsonDecode(response.body); return user; } catch (e) { print(e.toString()); - throw ClickUpException( - exceptionType: ClickUpExceptionType.requestError, - exceptionMessage: - "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } /// Get the teams bound to authorized user. Future> getAuthorizedTeams() async { try { - final response = await httpClient.get(Uri.parse("$endPoint/team"), - headers: {"Authorization": authToken}); + final response = await httpClient.get(Uri.parse("$endPoint/team"), headers: { + "Authorization": authToken + }); final teams = jsonDecode(response.body); return teams; } catch (e) { print(e.toString()); - throw ClickUpException( - exceptionType: ClickUpExceptionType.requestError, - exceptionMessage: - "An error occured while making the request. Error is ${e.toString()}"); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); } } } diff --git a/lib/src/core/endpoints/goals.dart b/lib/src/core/endpoints/goals.dart index c55deb7..d392e23 100644 --- a/lib/src/core/endpoints/goals.dart +++ b/lib/src/core/endpoints/goals.dart @@ -1,12 +1,226 @@ +import 'dart:convert'; + import 'package:http/http.dart'; +import '../clickup_exception.dart'; + class ClickUpGoals { late String endPoint; late String authToken; late Client httpClient; - ClickUpGoals( - {required this.endPoint, - required this.authToken, - required this.httpClient}); + ClickUpGoals({required this.endPoint, required this.authToken, required this.httpClient}); + + /// View the Goals available in a Workspace. + + Future> getGoals({required double teamID, bool includeCompleted = false}) async { + try { + final response = await httpClient.get(Uri.parse(includeCompleted ? "$endPoint/team/$teamID/goal?include_completed=true" : "$endPoint/team/$teamID/goal"), headers: { + "Authorization": authToken, + }); + final goals = jsonDecode(response.body); + return goals; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Add a new Goal to a Workspace. + + Future> createGoal({required double teamID, required String goalName, required int dueDate, required String description, required bool multipleOwners, required List owners, required String color}) async { + try { + final response = await httpClient.post(Uri.parse("$endPoint/team/$teamID/goal"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": goalName, + "due_date": dueDate, + "description": description, + "multiple_owners": multipleOwners, + "owners": owners, + "color": color + })); + final goal = jsonDecode(response.body); + return goal; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// View the details of a Goal including its Targets. + /// + /// Goal ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + + Future> getGoal({required double goalID}) async { + try { + final response = await httpClient.get(Uri.parse("$endPoint/goal/$goalID"), headers: { + "Authorization": authToken, + }); + final goal = jsonDecode(response.body); + return goal; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Rename a Goal, set the due date, replace the description, add or remove owners, and set the Goal color. + /// + /// Goal ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + Future> updateGoal({required double goalID, required String goalName, required int dueDate, required String description, required List ownersToRemove, required List ownersToAdd, required String color}) async { + try { + final response = await httpClient.put(Uri.parse("$endPoint/goal/$goalID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": goalName, + "due_date": dueDate, + "description": description, + "rem_owners": ownersToRemove, + "add_owners": ownersToAdd, + "color": color + })); + final goal = jsonDecode(response.body); + return goal; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Remove a Goal from your Workspace. + /// + /// Goal ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + Future> deleteGoal({required double goalID}) async { + try { + final response = await httpClient.delete( + Uri.parse("$endPoint/goal/$goalID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + ); + final goal = jsonDecode(response.body); + return goal; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Add a Target to a Goal. + /// + /// Goal ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + /// + /// Type should be one of the ``["number","currency","boolean","percentage","automatic"]`` + + Future> createKeyResult({required double goalID, required String goalName, required List owners, required String type, required int stepsStart, required int stepsEnd, required String unit, required List taskIDs, required List listIDs}) async { + final allowedTypes = [ + "number", + "currency", + "boolean", + "percentage", + "automatic" + ]; + + if (!allowedTypes.contains(type)) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Please use one of the available types. Check function documentation for more information"); + } + + try { + final response = await httpClient.post(Uri.parse("$endPoint/goal/$goalID/key_result"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": goalName, + "owners": owners, + "type": type, + "steps_start": stepsStart, + "steps_end": stepsEnd, + "unit": unit, + "task_ids": taskIDs, + "list_ids": listIDs + })); + final keyResult = jsonDecode(response.body); + return keyResult; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Update a Target. + /// + /// Goal ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + /// + /// Type should be one of the ``["number","currency","boolean","percentage","automatic"]`` + + Future> editKeyResult({required double keyResultID, required String goalName, required List owners, required String type, required int stepsStart, required int stepsCurrent, required int stepsEnd, required String unit, required String note, required List taskIDs, required List listIDs}) async { + final allowedTypes = [ + "number", + "currency", + "boolean", + "percentage", + "automatic" + ]; + + if (!allowedTypes.contains(type)) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "Please use one of the available types. Check function documentation for more information"); + } + + try { + final response = await httpClient.put(Uri.parse("$endPoint/key_result/$keyResultID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": goalName, + "owners": owners, + "type": type, + "steps_start": stepsStart, + "steps_end": stepsEnd, + "unit": unit, + "task_ids": taskIDs, + "list_ids": listIDs, + "steps_current": stepsCurrent, + "note": note + })); + final keyResult = jsonDecode(response.body); + return keyResult; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Update a Target. + /// + /// Goal ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + /// + /// Type should be one of the ``["number","currency","boolean","percentage","automatic"]`` + + Future> deleteKeyResult({required double keyResultID}) async { + try { + final response = await httpClient.delete( + Uri.parse("$endPoint/key_result/$keyResultID"), + headers: { + "Authorization": authToken, + }, + ); + final keyResult = jsonDecode(response.body); + return keyResult; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/lib/src/core/endpoints/guests.dart b/lib/src/core/endpoints/guests.dart index f1e4742..29d8595 100644 --- a/lib/src/core/endpoints/guests.dart +++ b/lib/src/core/endpoints/guests.dart @@ -1,12 +1,256 @@ +import 'dart:convert'; + import 'package:http/http.dart'; +import '../clickup_exception.dart'; + class ClickUpGuests { late String endPoint; late String authToken; late Client httpClient; - ClickUpGuests( - {required this.endPoint, - required this.authToken, - required this.httpClient}); + ClickUpGuests({required this.endPoint, required this.authToken, required this.httpClient}); + + /// Invite a guest to join a Workspace. To invite a member to your Workspace, use the Invite User to Workspace endpoint. + /// + /// You'll also need to grant the guest access to specific items using the following endpoints: Add Guest to Folder, Add Guest to List, or Add Guest to Task. + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> inviteGuestToWorkspace({required double teamID, required String email, required bool canEditTags, required bool canSeeTimeSpent, required bool canSeeTimeEstimated, required bool canCreateViews, required int customRoleID}) async { + try { + final response = await httpClient.post(Uri.parse("$endPoint/team/$teamID/guest"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "email": email, + "can_edit_tags": canEditTags, + "can_see_time_spent": canSeeTimeSpent, + "can_see_time_estimated": canSeeTimeEstimated, + "can_create_views": canCreateViews, + "custom_role_id": customRoleID + })); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// View information about a guest. + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> getGuest({required double teamID, required double guestID}) async { + try { + final response = await httpClient.get(Uri.parse("$endPoint/team/$teamID/guest/$guestID"), headers: { + "Authorization": authToken, + }); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Rename and configure options for a guest. + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> editGuestOnWorkspace({required double teamID, required double guestID, required String username, required bool canEditTags, required bool canSeeTimeSpent, required bool canSeeTimeEstimated, required bool canCreateViews, required int customRoleID}) async { + try { + final response = await httpClient.put(Uri.parse("$endPoint/team/$teamID/guest/$guestID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "username": username, + "can_edit_tags": canEditTags, + "can_see_time_spent": canSeeTimeSpent, + "can_see_time_estimated": canSeeTimeEstimated, + "can_create_views": canCreateViews, + "custom_role_id": customRoleID + })); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Revoke a guest's access to a Workspace. + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> removeGuestFromWorkspace({required double teamID, required double guestID}) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/team/$teamID/guest/$guestID"), headers: { + "Authorization": authToken, + }); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Share a task with a guest. + /// + /// Allowed permissions are ``["read", "comment", "edit", "create"]`` + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> addGuestToTask({required String taskID, required double guestID, required String permissionLevel, bool includeShared = true, bool useCustomTaskID = false, double teamID = 0}) async { + final allowedPermissions = [ + "read", + "comment", + "edit", + "create" + ]; + + if (!allowedPermissions.contains(permissionLevel)) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "You need to select one of the allowed permissions for the guest user."); + } + try { + final response = await httpClient.post(Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/guest/$guestID?include_shared=$includeShared&custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/guest/$guestID?include_shared=$includeShared"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "permission_level": permissionLevel + })); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Revoke a guest's access to a task. + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> removeGuestFromTask({required String taskID, required double guestID, bool includeShared = true, bool useCustomTaskID = false, double teamID = 0}) async { + try { + final response = await httpClient.delete(Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/guest/$guestID?include_shared=$includeShared&custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/guest/$guestID?include_shared=$includeShared"), headers: { + "Authorization": authToken + }); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Share a List with a guest. + /// + /// Allowed permissions are ``["read", "comment", "edit", "create"]`` + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> addGuestToList({required double listID, required double guestID, required String permissionLevel, bool includeShared = true}) async { + final allowedPermissions = [ + "read", + "comment", + "edit", + "create" + ]; + + if (!allowedPermissions.contains(permissionLevel)) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "You need to select one of the allowed permissions for the guest user."); + } + try { + final response = await httpClient.post(Uri.parse("$endPoint/list/$listID/guest/$guestID?include_shared=$includeShared"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "permission_level": permissionLevel + })); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Revoke a guest's access to a List. + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> removeGuestFromList({required double listID, required double guestID, bool includeShared = true}) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/list/$listID/guest/$guestID?include_shared=$includeShared"), headers: { + "Authorization": authToken + }); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Share a Folder with a guest. + /// + /// Allowed permissions are ``["read", "comment", "edit", "create"]`` + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> addGuestToFolder({required double folderID, required double guestID, required String permissionLevel, bool includeShared = true}) async { + final allowedPermissions = [ + "read", + "comment", + "edit", + "create" + ]; + + if (!allowedPermissions.contains(permissionLevel)) { + throw ClickUpException(exceptionType: ClickUpExceptionType.invalidModel, exceptionMessage: "You need to select one of the allowed permissions for the guest user."); + } + try { + final response = await httpClient.post(Uri.parse("$endPoint/folder/$folderID/guest/$guestID?include_shared=$includeShared"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "permission_level": permissionLevel + })); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Revoke a guest's access to a Folder. + /// + /// Note: This endpoint is only available to Workspaces on our Enterprise Plan. + + Future> removeGuestFromFolder({required double folderID, required double guestID, bool includeShared = true}) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/folder/$folderID/guest/$guestID?include_shared=$includeShared"), headers: { + "Authorization": authToken + }); + final guest = jsonDecode(response.body); + return guest; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/lib/src/core/endpoints/lists.dart b/lib/src/core/endpoints/lists.dart index 486fa6a..7ab0ed9 100644 --- a/lib/src/core/endpoints/lists.dart +++ b/lib/src/core/endpoints/lists.dart @@ -1,12 +1,85 @@ +import 'dart:convert'; + import 'package:http/http.dart'; +import '../clickup_exception.dart'; + class ClickUpLists { late String endPoint; late String authToken; late Client httpClient; - ClickUpLists( - {required this.endPoint, - required this.authToken, - required this.httpClient}); + ClickUpLists({required this.endPoint, required this.authToken, required this.httpClient}); + + /// View the Lists within a Folder. + + Future> getLists({required double folderID, bool archived = false}) async { + try { + final response = await httpClient.get(Uri.parse("$endPoint/folder/$folderID/list?archived=$archived"), headers: { + "Authorization": authToken, + }); + final goals = jsonDecode(response.body); + return goals; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Add a new List to a Folder. + /// + /// Include a ``assignee`` to assign this List. + /// + /// Status refers to the List color rather than the task Statuses available in the List. + + Future> createList({required double folderID, required String listName, String? content, int? dueDate, bool? dueDateTime, int? priority, int? assignee, String? status}) async { + Map body = { + "name": listName + }; + + content != null + ? body.addAll({ + "content": content + }) + : () => {}; + dueDate != null + ? body.addAll({ + "due_date": dueDate + }) + : () => {}; + dueDateTime != null + ? body.addAll({ + "due_date_time": dueDateTime + }) + : () => {}; + priority != null + ? body.addAll({ + "priority": priority + }) + : () => {}; + assignee != null + ? body.addAll({ + "assignee": assignee + }) + : () => {}; + status != null + ? body.addAll({ + "status": status + }) + : () => {}; + + try { + final response = await httpClient.post(Uri.parse("$endPoint/folder/$folderID/list"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode(body)); + final goals = jsonDecode(response.body); + return goals; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/lib/src/core/endpoints/task_checklists.dart b/lib/src/core/endpoints/task_checklists.dart index 051ccb9..1c68893 100644 --- a/lib/src/core/endpoints/task_checklists.dart +++ b/lib/src/core/endpoints/task_checklists.dart @@ -1,11 +1,141 @@ +import 'dart:convert'; + import 'package:http/http.dart'; +import '../clickup_exception.dart'; + class ClickUpTaskChecklists { late String endPoint; late String authToken; late Client httpClient; - ClickUpTaskChecklists( - {required this.endPoint, - required this.authToken, - required this.httpClient}); + ClickUpTaskChecklists({required this.endPoint, required this.authToken, required this.httpClient}); + + /// Adds a new checklist on a specific task in your space. + + Future> createChecklist({required String checklistName, required String taskID, bool useCustomTaskID = false, double teamID = 0}) async { + try { + final response = await httpClient.post(Uri.parse(useCustomTaskID ? "$endPoint/task/$taskID/checklist?custom_task_ids=true&team_id=$teamID" : "$endPoint/task/$taskID/checklist"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": checklistName + })); + final checklist = jsonDecode(response.body); + return checklist; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Rename a task checklist, or reorder a checklist so it appears above or below other checklists on a task. + /// + /// Checklist ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + /// + /// Position refers to the order of appearance of checklists on a task. To set a checklist to appear at the top of the checklists section of a task, use ``"position": 0``. + + Future> editChecklist({required String checklistName, required int position, required String checklistID}) async { + try { + final response = await httpClient.put(Uri.parse("$endPoint/checklist/$checklistID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": checklistName, + "position": position + })); + final checklist = jsonDecode(response.body); + return checklist; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Delete a checklist from a task. + /// + /// Checklist ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + + Future> deleteChecklist({required String checklistID}) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/checklist/$checklistID"), headers: { + "Authorization": authToken, + }); + final checklist = jsonDecode(response.body); + return checklist; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Add a line item to a task checklist. + /// + /// Checklist ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + + Future> createChecklistItem({required String checklistName, required int assignee, required String checklistID}) async { + try { + final response = await httpClient.post(Uri.parse("$endPoint/checklist/$checklistID/checklist_item"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": checklistName, + "assignee": assignee + })); + final checklist = jsonDecode(response.body); + return checklist; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Update an individual line item in a task checklist. You can rename it, set the assignee, mark it as resolved, or nest it under another checklist item. + /// + /// Checklist ID and Checklist Item ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + /// + /// To nest a checklist item under another checklist item, include the other item's ``checklistItemId``. + + Future> editChecklistItem({required String checklistName, String assignee = "null", required bool resolved, String parent = "null", required String checklistID, required String checklistItemID}) async { + try { + final response = await httpClient.put(Uri.parse("$endPoint/checklist/$checklistID/checklist_item/$checklistItemID"), + headers: { + "Authorization": authToken, + "Content-Type": "application/json" + }, + body: jsonEncode({ + "name": checklistName, + "assignee": assignee, + "resolved": resolved, + "parent": parent + })); + final checklist = jsonDecode(response.body); + return checklist; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } + + /// Delete a line item from a task checklist. + /// + /// Checklist ID and Checklist Item ID should be a valid UUID ``(b8a8-48d8-a0c6-b4200788a683)`` + + Future> deleteChecklistItem({required String checklistID, required String checklistItemID}) async { + try { + final response = await httpClient.delete(Uri.parse("$endPoint/checklist/$checklistID/checklist_item/$checklistItemID"), headers: { + "Authorization": authToken, + }); + final checklist = jsonDecode(response.body); + return checklist; + } catch (e) { + print(e.toString()); + throw ClickUpException(exceptionType: ClickUpExceptionType.requestError, exceptionMessage: "An error occured while making the request. Error is ${e.toString()}"); + } + } } diff --git a/test/integration/goals_test.dart b/test/integration/goals_test.dart index 5df8964..49da5f9 100644 --- a/test/integration/goals_test.dart +++ b/test/integration/goals_test.dart @@ -1,5 +1,93 @@ +import 'package:clickup_dart_sdk/clickup_dart_sdk.dart'; import 'package:test/test.dart'; void main() { - test('goals ...', () async {}); + late String token; + late ClickUp clickUp; + group('Goals endpoint Tests', () { + setUp(() async { + // Additional setup goes here. + token = "pk_qwerty123456"; + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); + }); + + test('Goals - Get Goals', () async { + final goals = await clickUp.goals.getGoals(teamID: 0); + print(goals); + expect(goals.containsKey("goals"), true); + }); + test('Goals - Get Goals Include Completed', () async { + final goals = await clickUp.goals.getGoals(teamID: 0, includeCompleted: true); + print(goals); + expect(goals.containsKey("goals"), true); + }); + + test('Goals - Create Goal', () async { + final goal = await clickUp.goals.createGoal(teamID: 0, color: "red", description: "Hey", dueDate: 123456, goalName: "Test", multipleOwners: true, owners: [ + 123, + 456, + 789 + ]); + print(goal); + expect(goal.containsKey("goal"), true); + }); + test('Goals - Get Goal', () async { + final goal = await clickUp.goals.getGoal(goalID: 0); + print(goal); + expect(goal.containsKey("goal"), true); + }); + + test('Goals - Update Goal', () async { + final goal = await clickUp.goals.updateGoal(goalID: 0, color: "red", description: "Hey", dueDate: 123456, goalName: "Test", ownersToRemove: [ + 123, + 456 + ], ownersToAdd: [ + 789, + 146 + ]); + print(goal); + expect(goal.containsKey("goal"), true); + }); + + test('Goals - Delete Goal', () async { + final goal = await clickUp.goals.deleteGoal(goalID: 0); + print(goal); + expect(goal.isEmpty, true); + }); + test('Goals - Create Key Result', () async { + final keyResult = await clickUp.goals.createKeyResult(goalID: 0, goalName: "test", type: "number", unit: "km", stepsStart: 0, stepsEnd: 2, owners: [ + 0, + 1 + ], taskIDs: [ + "123", + "456" + ], listIDs: [ + "369", + "741" + ]); + print(keyResult); + expect(keyResult.containsKey("key_result"), true); + }); + + test('Goals - Edit Key Result', () async { + final keyResult = await clickUp.goals.editKeyResult(keyResultID: 0, goalName: "test", type: "number", unit: "km", note: "hey", stepsStart: 0, stepsCurrent: 1, stepsEnd: 2, owners: [ + 0, + 1 + ], taskIDs: [ + "123", + "456" + ], listIDs: [ + "369", + "741" + ]); + print(keyResult); + expect(keyResult.containsKey("key_result"), true); + }); + + test('Goals - Delete Key Result', () async { + final keyResult = await clickUp.goals.deleteKeyResult(keyResultID: 0); + print(keyResult); + expect(keyResult.isEmpty, true); + }); + }); } diff --git a/test/integration/guests_test.dart b/test/integration/guests_test.dart index c01774d..5aa900a 100644 --- a/test/integration/guests_test.dart +++ b/test/integration/guests_test.dart @@ -8,16 +8,68 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp( - apiEndpoint: - "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") - ..initialize(authToken: token); + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); + test('Guests - Invite Guest To Workspace', () async { + final guest = await clickUp.guests.inviteGuestToWorkspace(teamID: 1, email: "guest@example.com", canSeeTimeSpent: false, canCreateViews: false, canEditTags: false, canSeeTimeEstimated: true, customRoleID: 12345); + print(guest); + expect(guest.containsKey("team"), true); + }); + + test('Guests - Get Guest', () async { + final guest = await clickUp.guests.getGuest(teamID: 1, guestID: 2); + print(guest); + expect(guest.isEmpty, true); + }); + test('Guests - Edit Guest On Workspace', () async { + final guest = await clickUp.guests.editGuestOnWorkspace(teamID: 1, guestID: 2, username: "guest@example.com", canSeeTimeSpent: false, canCreateViews: false, canEditTags: false, canSeeTimeEstimated: true, customRoleID: 12345); + print(guest); + expect(guest.containsKey("guest"), true); + }); + + test('Guests - Remove Guest From Workspace', () async { + final guest = await clickUp.guests.removeGuestFromWorkspace(teamID: 1, guestID: 2); + print(guest); + expect(guest.containsKey("team"), true); + }); + test('Guests - Add Guest To Task', () async { + final guest = await clickUp.guests.addGuestToTask(taskID: "1234", guestID: 2456, permissionLevel: "read"); + print(guest); + expect(guest.containsKey("guest"), true); + }); + test('Guests - Add Guest To Task with Custom Task Id', () async { + final guest = await clickUp.guests.addGuestToTask(taskID: "1", guestID: 2, permissionLevel: "edit", includeShared: false, useCustomTaskID: true); + print(guest); + expect(guest.containsKey("guest"), true); + }); + test('Guests - Remove Guest From Task', () async { + final guest = await clickUp.guests.removeGuestFromTask(taskID: "1", guestID: 2, includeShared: false, useCustomTaskID: true); + print(guest); + expect(guest.containsKey("guest"), true); + }); + + test('Guests - Add Guest To List', () async { + final guest = await clickUp.guests.addGuestToList(listID: 1, guestID: 2, includeShared: false, permissionLevel: "read"); + print(guest); + expect(guest.containsKey("guest"), true); + }); + + test('Guests - Remove Guest From List', () async { + final guest = await clickUp.guests.removeGuestFromList(listID: 1, guestID: 2, includeShared: false); + print(guest); + expect(guest.containsKey("guest"), true); + }); + + test('Guests - Add Guest To Folder', () async { + final guest = await clickUp.guests.addGuestToFolder(folderID: 1, guestID: 2, includeShared: false, permissionLevel: "read"); + print(guest); + expect(guest.containsKey("guest"), true); + }); + test('Guests - Remove Guest From Folder', () async { + final guest = await clickUp.guests.removeGuestFromFolder(folderID: 1, guestID: 2, includeShared: false); + print(guest); + expect(guest.containsKey("guest"), true); }); }); } diff --git a/test/integration/lists_test.dart b/test/integration/lists_test.dart index c01774d..015484f 100644 --- a/test/integration/lists_test.dart +++ b/test/integration/lists_test.dart @@ -8,16 +8,24 @@ void main() { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp( - apiEndpoint: - "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") - ..initialize(authToken: token); + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); + test('Lists - Get Lists', () async { + final lists = await clickUp.lists.getLists(folderID: 1, archived: false); + print(lists); + expect(lists.containsKey("lists"), true); + }); + + test('Lists - Create List', () async { + final lists = await clickUp.lists.createList(folderID: 1, listName: "test list"); + print(lists); + expect(lists.containsKey("id"), true); + }); + test('Lists - Create List with params', () async { + final lists = await clickUp.lists.createList(folderID: 1, listName: "test list", assignee: 1, content: "test"); + print(lists); + expect(lists.containsKey("id"), true); }); }); } diff --git a/test/integration/task_checklists_test.dart b/test/integration/task_checklists_test.dart index c01774d..7525fab 100644 --- a/test/integration/task_checklists_test.dart +++ b/test/integration/task_checklists_test.dart @@ -4,20 +4,45 @@ import 'package:test/test.dart'; void main() { late String token; late ClickUp clickUp; - group('API endpoint Tests', () { + group('Task Checklists endpoint Tests', () { setUp(() async { // Additional setup goes here. token = "pk_qwerty123456"; - clickUp = ClickUp( - apiEndpoint: - "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com") - ..initialize(authToken: token); + clickUp = ClickUp(apiEndpoint: "https://a00fb6e0-339c-4201-972f-503b9932d17a.remockly.com")..initialize(authToken: token); }); - test('Authorization - Get Authorized User', () async { - final user = await clickUp.auth.getAuthorizedUser(); - print(user); - expect(user.containsKey("user"), true); + test('Task Checklists - Create a checklist', () async { + final checklist = await clickUp.taskChecklists.createChecklist(checklistName: "Test", taskID: "asdf123asde"); + print(checklist); + expect(checklist.containsKey("checklist"), true); + }); + + test('Task Checklists - Edit a checklist', () async { + final checklist = await clickUp.taskChecklists.editChecklist(checklistID: "b8a8-48d8-a0c6-b4200788a683", checklistName: "New Name", position: 0); + print(checklist); + expect(checklist.isEmpty, true); + }); + + test('Task Checklists - Delete a checklist', () async { + final checklist = await clickUp.taskChecklists.deleteChecklist(checklistID: "b8a8-48d8-a0c6-b4200788a683"); + print(checklist); + expect(checklist.isEmpty, true); + }); + test('Task Checklists - Create a checklist item', () async { + final checklist = await clickUp.taskChecklists.createChecklistItem(checklistName: "New Name", assignee: 123, checklistID: "b8a8-48d8-a0c6-b4200788a683"); + print(checklist); + expect(checklist.containsKey("checklist"), true); + }); + + test('Task Checklists - Edit a checklist item', () async { + final checklist = await clickUp.taskChecklists.editChecklistItem(checklistName: "New Name", assignee: "123", resolved: false, parent: "test", checklistItemID: "b8a8-48d8-a0c6-b4200788a683", checklistID: "b8a8-48d8-a0c6-b4200788a683"); + print(checklist); + expect(checklist.containsKey("checklist"), true); + }); + test('Task Checklists - Edit a checklist item', () async { + final checklist = await clickUp.taskChecklists.deleteChecklistItem(checklistItemID: "b8a8-48d8-a0c6-b4200788a683", checklistID: "b8a8-48d8-a0c6-b4200788a683"); + print(checklist); + expect(checklist.isEmpty, true); }); }); } From 1dddccb69467e51a6874681586f4f846549ab3a8 Mon Sep 17 00:00:00 2001 From: Emre Ayaz <68122318+ayazemre@users.noreply.github.com> Date: Mon, 3 Jul 2023 23:58:38 +0300 Subject: [PATCH 16/17] Create staging-tests.yml --- .github/workflows/staging-tests.yml | 42 +++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 .github/workflows/staging-tests.yml diff --git a/.github/workflows/staging-tests.yml b/.github/workflows/staging-tests.yml new file mode 100644 index 0000000..f008ded --- /dev/null +++ b/.github/workflows/staging-tests.yml @@ -0,0 +1,42 @@ +# This workflow uses actions that are not certified by GitHub. +# They are provided by a third-party and are governed by +# separate terms of service, privacy policy, and support +# documentation. + +name: Dart run tests when activity on staging + +on: + push: + branches: [ "staging" ] + pull_request: + branches: [ "staging" ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + # Note: This workflow uses the latest stable version of the Dart SDK. + # You can specify other versions if desired, see documentation here: + # https://github.com/dart-lang/setup-dart/blob/main/README.md + # - uses: dart-lang/setup-dart@v1 + - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603 + + - name: Install dependencies + run: dart pub get + + # Uncomment this step to verify the use of 'dart format' on each commit. + # - name: Verify formatting + # run: dart format --output=none --set-exit-if-changed . + + # Consider passing '--fatal-infos' for slightly stricter analysis. + - name: Analyze project source + run: dart analyze + + # Your project will need to have tests in test/ and a dependency on + # package:test for this step to succeed. Note that Flutter projects will + # want to change this to 'flutter test'. + - name: Run tests + run: dart test From 9a2e0933b4e3d0a0a555b804fa4c9554592d5bc4 Mon Sep 17 00:00:00 2001 From: Emre Ayaz Date: Tue, 4 Jul 2023 00:01:06 +0300 Subject: [PATCH 17/17] version update --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index ab6d0c9..14eb33b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: clickup_dart_sdk description: A SDK for ClickUp for integrating or creating applications on top of the product. -version: 0.3.2 +version: 0.4.0 repository: https://github.com/ayazemre/clickup-dart-sdk environment: