From 5015e049b267dc7565e8701666ce4f91e1a32607 Mon Sep 17 00:00:00 2001 From: Vitaly Mosin <73104048+beevital@users.noreply.github.com> Date: Mon, 2 Oct 2023 12:44:36 +0200 Subject: [PATCH] Package refactoring (#92) * move helpers to utils package * testutils * group common types * connector config moved * connector common responses * common response in connector setup tests * test fix * connector schema common types * dbt refactoring * fix examples * destinations common parts * external logging common parts * users common types * webhooks common types * teams common types * fix json marshalling * http utils package * http service base --- certificate_connector_certificate_approve.go | 22 +- ...cate_connector_certificate_approve_test.go | 14 +- certificate_connector_fingerprint_approve.go | 22 +- ...cate_connector_fingerprint_approve_test.go | 10 +- ...ificate_destination_certificate_approve.go | 22 +- ...te_destination_certificate_approve_test.go | 14 +- ...ificate_destination_fingerprint_approve.go | 22 +- ...te_destination_fingerprint_approve_test.go | 10 +- client.go | 31 +- common/common_types.go | 32 + connector_create.go | 127 +--- connector_create_test.go | 61 +- connector_delete.go | 32 +- connector_delete_test.go | 12 +- connector_details.go | 98 +-- connector_details_test.go | 62 +- connector_modify.go | 126 +--- connector_modify_test.go | 61 +- connector_resync_table.go | 32 +- connector_schema_details.go | 36 +- connector_schema_reload.go | 27 +- connector_schema_update.go | 43 +- connector_setup_tests.go | 100 ++- connector_setup_tests_test.go | 60 +- connector_sync.go | 70 +- connector_sync_test.go | 12 +- connectors/common_types.go | 97 +++ .../connector_auth.go | 14 +- .../connector_auth_client_access.go | 6 +- .../connector_config.go | 14 +- ...or_config_adobe_analytics_configuration.go | 6 +- .../connector_config_custom_tables.go | 6 +- .../connector_config_project_credentials.go | 6 +- .../connector_config_reports.go | 6 +- .../connector_schema_config_column.go | 6 +- .../connector_schema_config_schema.go | 12 +- .../connector_schema_config_table.go | 6 +- .../function_secret.go | 6 +- connectors_source_metadata.go | 28 +- connectors_source_metadata_test.go | 18 +- creators.go | 68 ++ dbt/common_types.go | 78 ++ .../dbt_project_config.go | 10 +- .../dbt_transformation_schedule.go | 8 +- dbt_model_details.go | 37 +- dbt_models_list.go | 40 +- dbt_project_create.go | 51 +- dbt_project_create_test.go | 39 +- dbt_project_delete.go | 32 +- dbt_project_delete_test.go | 22 +- dbt_project_details.go | 25 +- dbt_project_modify.go | 45 +- dbt_project_response.go | 26 - dbt_projects_list.go | 41 +- dbt_transformation_create.go | 43 +- dbt_transformation_create_test.go | 43 +- dbt_transformation_delete.go | 32 +- dbt_transformation_delete_test.go | 12 +- dbt_transformation_details.go | 47 +- dbt_transformation_details_test.go | 36 +- dbt_transformation_modify.go | 41 +- dbt_transformation_modify_test.go | 37 +- destination_create.go | 71 +- destination_create_test.go | 33 +- destination_delete.go | 32 +- destination_delete_test.go | 12 +- destination_details.go | 41 +- destination_details_test.go | 30 +- destination_modify.go | 66 +- destination_modify_test.go | 29 +- destination_setup_tests.go | 46 +- destination_setup_tests_test.go | 22 +- destinations/common_types.go | 27 + .../destination_config.go | 8 +- examples/connectorCreate-2/main.go | 9 +- examples/connectorModify/main.go | 6 +- external_logging/common_types.go | 35 + external_logging/external_logging_config.go | 153 ++++ external_logging_config.go | 155 ---- external_logging_create.go | 256 +++---- external_logging_create_test.go | 47 +- external_logging_delete.go | 82 +-- external_logging_delete_test.go | 26 +- external_logging_details.go | 118 +-- external_logging_details_test.go | 30 +- external_logging_modify.go | 260 +++---- external_logging_modify_test.go | 19 +- external_logging_setup_tests.go | 35 +- external_logging_setup_tests_test.go | 10 +- fivetran_test.go | 684 +----------------- group_add_user.go | 32 +- group_add_user_test.go | 14 +- group_create.go | 38 +- group_create_test.go | 12 +- group_delete.go | 32 +- group_delete_test.go | 12 +- group_details.go | 38 +- group_details_test.go | 12 +- group_list_connectors.go | 70 +- group_list_connectors_test.go | 52 +- group_list_users.go | 47 +- group_list_users_test.go | 30 +- group_modify.go | 38 +- group_modify_test.go | 14 +- group_remove_user.go | 32 +- group_remove_user_test.go | 16 +- groups/common_types.go | 18 + groups_list.go | 38 +- groups_list_test.go | 18 +- http_request.go | 124 ---- http_utils/http_client.go | 9 + http_utils/http_request.go | 124 ++++ http_utils/http_service.go | 61 ++ metadata_columns_list.go | 146 ++-- metadata_columns_list_test.go | 40 +- metadata_schemas_list.go | 136 ++-- metadata_schemas_list_test.go | 30 +- metadata_tables_list.go | 138 ++-- metadata_tables_list_test.go | 32 +- roles_list.go | 110 +-- roles_list_test.go | 14 +- team_connector_membership_create.go | 139 ++-- team_connector_membership_create_test.go | 50 +- team_connector_membership_delete.go | 94 +-- team_connector_membership_delete_test.go | 40 +- team_connector_membership_details.go | 116 +-- team_connector_membership_details_test.go | 46 +- team_connector_membership_modify.go | 140 ++-- team_connector_membership_modify_test.go | 46 +- team_connector_memberships_list.go | 135 ++-- team_connector_memberships_list_test.go | 40 +- team_group_membership_create.go | 139 ++-- team_group_membership_create_test.go | 50 +- team_group_membership_delete.go | 94 +-- team_group_membership_delete_test.go | 40 +- team_group_membership_details.go | 116 +-- team_group_membership_details_test.go | 46 +- team_group_membership_modify.go | 140 ++-- team_group_membership_modify_test.go | 46 +- team_group_memberships_list.go | 135 ++-- team_group_memberships_list_test.go | 40 +- team_user_membership_create.go | 138 ++-- team_user_membership_create_test.go | 44 +- team_user_membership_delete.go | 94 +-- team_user_membership_delete_test.go | 38 +- team_user_membership_details.go | 115 +-- team_user_membership_details_test.go | 42 +- team_user_membership_modify.go | 140 ++-- team_user_membership_modify_test.go | 44 +- team_user_memberships_list.go | 134 ++-- team_user_memberships_list_test.go | 38 +- teams/common_types.go | 28 + teams_create.go | 134 ++-- teams_create_test.go | 40 +- teams_delete.go | 82 +-- teams_delete_role_in_account.go | 82 +-- teams_delete_role_in_account_test.go | 24 +- teams_delete_test.go | 22 +- teams_details.go | 87 +-- teams_details_test.go | 20 +- teams_list.go | 122 ++-- teams_list_test.go | 30 +- teams_modify.go | 150 ++-- teams_modify_test.go | 44 +- test_utils/test_utils.go | 679 +++++++++++++++++ tests/connector_create_mock_test.go | 13 +- tests/connector_delete_mock_test.go | 4 +- tests/connector_details_mock_test.go | 8 +- tests/connector_resync_table_mock_test.go | 10 +- tests/connector_schema_update_mock_test.go | 3 +- tests/connector_setup_tests_test.go | 4 +- tests/connector_update_mock_test.go | 19 +- tests/dbt_project_create_mock_test.go | 2 +- tests/dbt_project_delete_mock_test.go | 4 +- tests/dbt_project_details_mock_test.go | 2 +- tests/dbt_project_modify_mock_test.go | 2 +- tests/dbt_transformation_create_mock_test.go | 3 +- tests/dbt_transformation_delete_mock_test.go | 4 +- tests/dbt_transformation_details_mock_test.go | 4 +- tests/dbt_transformation_modify_mock_test.go | 3 +- tests/destination_create_mock_test.go | 5 +- tests/destination_delete_mock_test.go | 4 +- tests/destination_details_mock_test.go | 4 +- tests/destination_modify_mock_test.go | 3 +- tests/external_logging_create_mock_test.go | 382 +++++----- tests/external_logging_delete_mock_test.go | 4 +- tests/external_logging_modify_mock_test.go | 239 +++--- tests/group_add_mock_test.go | 4 +- tests/group_create_mock_test.go | 4 +- tests/group_delete_mock_test.go | 9 +- tests/group_details_mock_test.go | 4 +- tests/group_list_connectors_mock_test.go | 5 +- tests/group_modify_mock_test.go | 4 +- tests/group_remove_user_mock_test.go | 4 +- tests/helpers_test.go | 6 +- tests/team_connector_delete_mock_test.go | 4 +- tests/team_connector_modify_mock_test.go | 88 +-- .../team_delete_role_in_account_mock_test.go | 4 +- tests/team_group_delete_mock_test.go | 4 +- tests/team_group_modify_mock_test.go | 88 +-- tests/team_user_delete_mock_tests.go | 4 +- tests/team_user_modify_mock_test.go | 88 +-- tests/teams_delete_mock_test.go | 4 +- tests/teams_list_mock_test.go | 2 +- tests/user_delete_mock_test.go | 4 +- tests/user_details_mock_test.go | 19 +- tests/user_invite_mock_test.go | 17 +- tests/user_list_mock_test.go | 93 +-- tests/webhook_create_mock_test.go | 230 +++--- tests/webhook_delete_mock_test.go | 4 +- tests/webhook_details_mock_test.go | 38 +- tests/webhook_modify_mock_test.go | 50 +- types.go | 21 - user_delete.go | 32 +- user_delete_test.go | 12 +- user_details.go | 48 +- user_details_test.go | 28 +- user_invite.go | 46 +- user_invite_test.go | 30 +- user_modify.go | 67 +- user_modify_test.go | 32 +- users/common_types.go | 35 + users_list.go | 49 +- users_list_test.go | 32 +- helpers.go => utils/helpers.go | 2 +- webhook_account_create.go | 151 ++-- webhook_account_create_test.go | 52 +- webhook_delete.go | 82 +-- webhook_delete_test.go | 26 +- webhook_details.go | 95 ++- webhook_details_test.go | 30 +- webhook_group_create.go | 169 ++--- webhook_group_create_test.go | 56 +- webhook_list.go | 113 ++- webhook_list_test.go | 24 +- webhook_modify.go | 176 +++-- webhook_modify_test.go | 41 +- webhook_tests.go | 40 +- webhook_tests_test.go | 18 +- webhooks/common_types.go | 30 + 240 files changed, 6635 insertions(+), 6543 deletions(-) create mode 100644 common/common_types.go create mode 100644 connectors/common_types.go rename connector_auth.go => connectors/connector_auth.go (84%) rename connector_auth_client_access.go => connectors/connector_auth_client_access.go (93%) rename connector_config.go => connectors/connector_config.go (99%) rename connector_config_adobe_analytics_configuration.go => connectors/connector_config_adobe_analytics_configuration.go (94%) rename connector_config_custom_tables.go => connectors/connector_config_custom_tables.go (97%) rename connector_config_project_credentials.go => connectors/connector_config_project_credentials.go (91%) rename connector_config_reports.go => connectors/connector_config_reports.go (96%) rename connector_schema_config_column.go => connectors/connector_schema_config_column.go (89%) rename connector_schema_config_schema.go => connectors/connector_schema_config_schema.go (81%) rename connector_schema_config_table.go => connectors/connector_schema_config_table.go (94%) rename function_secret.go => connectors/function_secret.go (87%) create mode 100644 creators.go create mode 100644 dbt/common_types.go rename dbt_project_config.go => dbt/dbt_project_config.go (84%) rename dbt_transformation_schedule.go => dbt/dbt_transformation_schedule.go (90%) delete mode 100644 dbt_project_response.go create mode 100644 destinations/common_types.go rename destination_config.go => destinations/destination_config.go (98%) create mode 100644 external_logging/common_types.go create mode 100644 external_logging/external_logging_config.go delete mode 100644 external_logging_config.go create mode 100644 groups/common_types.go delete mode 100644 http_request.go create mode 100644 http_utils/http_client.go create mode 100644 http_utils/http_request.go create mode 100644 http_utils/http_service.go create mode 100644 teams/common_types.go create mode 100644 test_utils/test_utils.go delete mode 100644 types.go create mode 100644 users/common_types.go rename helpers.go => utils/helpers.go (98%) create mode 100644 webhooks/common_types.go diff --git a/certificate_connector_certificate_approve.go b/certificate_connector_certificate_approve.go index da7ef044..203142da 100644 --- a/certificate_connector_certificate_approve.go +++ b/certificate_connector_certificate_approve.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // CertificateConnectorCertificateApproveService implements the Certificate Management, Approve a connector certificate API. @@ -66,18 +68,18 @@ func (s *CertificateConnectorCertificateApproveService) Do(ctx context.Context) return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/certificate_connector_certificate_approve_test.go b/certificate_connector_certificate_approve_test.go index 73066822..5e0aa684 100644 --- a/certificate_connector_certificate_approve_test.go +++ b/certificate_connector_certificate_approve_test.go @@ -3,14 +3,16 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewCertificateConnectorCertificateApproveE2E(t *testing.T) { - connectorId := CreateTempConnector(t) - response, err := Client.NewCertificateConnectorCertificateApprove(). + connectorId := testutils.CreateTempConnector(t) + response, err := testutils.Client.NewCertificateConnectorCertificateApprove(). ConnectorID(connectorId). - Hash(CertificateHash). - EncodedCert(EncodedCertificate). + Hash(testutils.CertificateHash). + EncodedCert(testutils.EncodedCertificate). Do(context.Background()) if err != nil { @@ -18,6 +20,6 @@ func TestNewCertificateConnectorCertificateApproveE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, response.Code, "Success") - AssertNotEmpty(t, response.Message) + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertNotEmpty(t, response.Message) } diff --git a/certificate_connector_fingerprint_approve.go b/certificate_connector_fingerprint_approve.go index 54c8df3c..b97e3e98 100644 --- a/certificate_connector_fingerprint_approve.go +++ b/certificate_connector_fingerprint_approve.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // CertificateConnectorFingerprintApproveService implements the Certificate Management, Approve a connector fingerprint API. @@ -66,18 +68,18 @@ func (s *CertificateConnectorFingerprintApproveService) Do(ctx context.Context) return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/certificate_connector_fingerprint_approve_test.go b/certificate_connector_fingerprint_approve_test.go index dd6590f1..ad4f0c2f 100644 --- a/certificate_connector_fingerprint_approve_test.go +++ b/certificate_connector_fingerprint_approve_test.go @@ -3,11 +3,13 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewCertificateConnectorFingerprintApproveE2E(t *testing.T) { - connectorId := CreateTempConnector(t) - response, err := Client.NewCertificateConnectorFingerprintApprove(). + connectorId := testutils.CreateTempConnector(t) + response, err := testutils.Client.NewCertificateConnectorFingerprintApprove(). ConnectorID(connectorId). Hash("test_hash"). PublicKey("test_public_key"). @@ -18,6 +20,6 @@ func TestNewCertificateConnectorFingerprintApproveE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, response.Code, "Success") - AssertNotEmpty(t, response.Message) + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertNotEmpty(t, response.Message) } diff --git a/certificate_destination_certificate_approve.go b/certificate_destination_certificate_approve.go index c743275f..5dd56cd6 100644 --- a/certificate_destination_certificate_approve.go +++ b/certificate_destination_certificate_approve.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // CertificateDestinationCertificateApproveService implements the Certificate Management, Approve a destination certificate API. @@ -66,18 +68,18 @@ func (s *CertificateDestinationCertificateApproveService) Do(ctx context.Context return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/certificate_destination_certificate_approve_test.go b/certificate_destination_certificate_approve_test.go index 19f8b5f9..07de1e1e 100644 --- a/certificate_destination_certificate_approve_test.go +++ b/certificate_destination_certificate_approve_test.go @@ -3,14 +3,16 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewCertificateDestinationCertificateApproveE2E(t *testing.T) { - destinationId := CreateTempDestination(t) - response, err := Client.NewCertificateDestinationCertificateApprove(). + destinationId := testutils.CreateTempDestination(t) + response, err := testutils.Client.NewCertificateDestinationCertificateApprove(). DestinationID(destinationId). - Hash(CertificateHash). - EncodedCert(EncodedCertificate). + Hash(testutils.CertificateHash). + EncodedCert(testutils.EncodedCertificate). Do(context.Background()) if err != nil { @@ -18,6 +20,6 @@ func TestNewCertificateDestinationCertificateApproveE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, response.Code, "Success") - AssertNotEmpty(t, response.Message) + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertNotEmpty(t, response.Message) } diff --git a/certificate_destination_fingerprint_approve.go b/certificate_destination_fingerprint_approve.go index d85d2cfb..2080b752 100644 --- a/certificate_destination_fingerprint_approve.go +++ b/certificate_destination_fingerprint_approve.go @@ -4,6 +4,8 @@ import ( "context" "encoding/json" "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // CertificateDestinationFingerprintApproveService implements the Certificate Management, Approve a destination fingerprint API. @@ -66,18 +68,18 @@ func (s *CertificateDestinationFingerprintApproveService) Do(ctx context.Context return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/certificate_destination_fingerprint_approve_test.go b/certificate_destination_fingerprint_approve_test.go index 28c4cc10..f54b6436 100644 --- a/certificate_destination_fingerprint_approve_test.go +++ b/certificate_destination_fingerprint_approve_test.go @@ -3,11 +3,13 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewCertificateDestinationFingerprintApproveE2E(t *testing.T) { - destinationId := CreateTempDestination(t) - response, err := Client.NewCertificateDestinationFingerprintApprove(). + destinationId := testutils.CreateTempDestination(t) + response, err := testutils.Client.NewCertificateDestinationFingerprintApprove(). DestinationID(destinationId). Hash("test_hash"). PublicKey("test_public_key"). @@ -18,6 +20,6 @@ func TestNewCertificateDestinationFingerprintApproveE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, response.Code, "Success") - AssertNotEmpty(t, response.Message) + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertNotEmpty(t, response.Message) } diff --git a/client.go b/client.go index 469e07f2..fded0f1d 100644 --- a/client.go +++ b/client.go @@ -4,20 +4,16 @@ import ( "encoding/base64" "fmt" "net/http" -) -// HttpClient performs an HTTP request. Can be implemented by mocks -// to perform convenient unit tests -type HttpClient interface { - Do(req *http.Request) (*http.Response, error) -} + httputils "github.com/fivetran/go-fivetran/http_utils" +) // Client holds client configuration type Client struct { baseURL string authorization string customUserAgent string - httpClient HttpClient + httpClient httputils.HttpClient handleRateLimits bool maxRetryAttempts int } @@ -52,7 +48,7 @@ func (c *Client) CustomUserAgent(customUserAgent string) { } // SetHttpClient sets custom HTTP client to perform requests with -func (c *Client) SetHttpClient(httpClient HttpClient) { +func (c *Client) SetHttpClient(httpClient httputils.HttpClient) { c.httpClient = httpClient } @@ -78,3 +74,22 @@ func (c *Client) commonHeaders() map[string]string { "User-Agent": userAgent, } } + +func (c *Client) commonHeadersByMethod(method string) map[string]string { + userAgent := defaultUserAgent + + if c.customUserAgent != "" { + userAgent += " " + c.customUserAgent + } + + result := map[string]string{ + "Authorization": c.authorization, + "User-Agent": userAgent, + } + + if method == "POST" || method == "PATCH" { + result["Content-Type"] = "application/json" + } + + return result +} diff --git a/common/common_types.go b/common/common_types.go new file mode 100644 index 00000000..9a47a90b --- /dev/null +++ b/common/common_types.go @@ -0,0 +1,32 @@ +package common + +import "encoding/json" + +type CommonResponse struct { + Code string `json:"code"` + Message string `json:"message"` +} + +type SetupTestResponse struct { + Title string `json:"title"` + Status string `json:"status"` + Message string `json:"message"` +} + +type NullableString struct { + value *string +} + +func (n *NullableString) MarshalJSON() ([]byte, error) { + return json.Marshal(n.value) +} + +func NewNullableString(s *string, clear bool) *NullableString { + if s == nil && !clear { + return nil + } + + return &NullableString{ + value: s, + } +} diff --git a/connector_create.go b/connector_create.go index 8352d377..ade26f61 100644 --- a/connector_create.go +++ b/connector_create.go @@ -4,7 +4,10 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/utils" ) // ConnectorCreateService implements the Connector Management, Create a Connector API. @@ -21,8 +24,8 @@ type ConnectorCreateService struct { syncFrequency *int dailySyncTime *string pauseAfterTrial *bool - config *ConnectorConfig - auth *ConnectorAuth + config *connectors.ConnectorConfig + auth *connectors.ConnectorAuth configCustom *map[string]interface{} authCustom *map[string]interface{} } @@ -41,8 +44,8 @@ type connectorCreateRequestBase struct { type connectorCreateRequest struct { connectorCreateRequestBase - Config *connectorConfigRequest `json:"config,omitempty"` - Auth *connectorAuthRequest `json:"auth,omitempty"` + Config any `json:"config,omitempty"` + Auth any `json:"auth,omitempty"` } type connectorCustomCreateRequest struct { @@ -51,70 +54,6 @@ type connectorCustomCreateRequest struct { Auth *map[string]interface{} `json:"auth,omitempty"` } -type ConnectorCreateResponseDataBase struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - ServiceVersion *int `json:"service_version"` - Schema string `json:"schema"` - ConnectedBy string `json:"connected_by"` - CreatedAt time.Time `json:"created_at"` - SucceededAt time.Time `json:"succeeded_at"` - FailedAt time.Time `json:"failed_at"` - SyncFrequency *int `json:"sync_frequency"` - ScheduleType string `json:"schedule_type"` - Paused *bool `json:"paused"` - PauseAfterTrial *bool `json:"pause_after_trial"` - DailySyncTime string `json:"daily_sync_time"` - Status struct { - SetupState string `json:"setup_state"` - SyncState string `json:"sync_state"` - UpdateState string `json:"update_state"` - IsHistoricalSync *bool `json:"is_historical_sync"` - Tasks []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"tasks"` - Warnings []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"warnings"` - } `json:"status"` - SetupTests []struct { - Title string `json:"title"` - Status string `json:"status"` - Message string `json:"message"` - } `json:"setup_tests"` -} - -type ConnectorCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorCreateResponseDataBase - Config ConnectorConfigResponse `json:"config"` - } `json:"data"` -} - -type ConnectorCustomCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorCreateResponseDataBase - Config map[string]interface{} `json:"config"` - } `json:"data"` -} - -type ConnectorCustomMergedCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorCreateResponseDataBase - CustomConfig map[string]interface{} `json:"config"` - Config ConnectorConfigResponse // no mapping here - } `json:"data"` -} - func (c *Client) NewConnectorCreate() *ConnectorCreateService { return &ConnectorCreateService{c: c} } @@ -134,14 +73,14 @@ func (s *ConnectorCreateService) requestBase() connectorCreateRequestBase { } func (s *ConnectorCreateService) request() *connectorCreateRequest { - var config *connectorConfigRequest + var config interface{} if s.config != nil { - config = s.config.request() + config = s.config.Request() } - var auth *connectorAuthRequest + var auth interface{} if s.auth != nil { - auth = s.auth.request() + auth = s.auth.Request() } r := &connectorCreateRequest{ @@ -166,7 +105,7 @@ func (s *ConnectorCreateService) requestCustomMerged() (*connectorCustomCreateRe if s.config != nil { var err error - currentConfig, err = s.config.merge(currentConfig) + currentConfig, err = s.config.Merge(currentConfig) if err != nil { return nil, err } @@ -175,7 +114,7 @@ func (s *ConnectorCreateService) requestCustomMerged() (*connectorCustomCreateRe currentAuth := s.authCustom if s.auth != nil { var err error - currentAuth, err = s.auth.merge(currentAuth) + currentAuth, err = s.auth.Merge(currentAuth) if err != nil { return nil, err } @@ -233,7 +172,7 @@ func (s *ConnectorCreateService) PauseAfterTrial(value bool) *ConnectorCreateSer return s } -func (s *ConnectorCreateService) Config(value *ConnectorConfig) *ConnectorCreateService { +func (s *ConnectorCreateService) Config(value *connectors.ConnectorConfig) *ConnectorCreateService { s.config = value return s } @@ -243,7 +182,7 @@ func (s *ConnectorCreateService) ConfigCustom(value *map[string]interface{}) *Co return s } -func (s *ConnectorCreateService) Auth(value *ConnectorAuth) *ConnectorCreateService { +func (s *ConnectorCreateService) Auth(value *connectors.ConnectorAuth) *ConnectorCreateService { s.auth = value return s } @@ -266,18 +205,18 @@ func (s *ConnectorCreateService) do(ctx context.Context, req, response any) erro return err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return err } @@ -294,24 +233,24 @@ func (s *ConnectorCreateService) do(ctx context.Context, req, response any) erro return nil } -func (s *ConnectorCreateService) Do(ctx context.Context) (ConnectorCreateResponse, error) { - var response ConnectorCreateResponse +func (s *ConnectorCreateService) Do(ctx context.Context) (connectors.DetailsWithConfigResponse, error) { + var response connectors.DetailsWithConfigResponse err := s.do(ctx, s.request(), &response) return response, err } -func (s *ConnectorCreateService) DoCustom(ctx context.Context) (ConnectorCustomCreateResponse, error) { - var response ConnectorCustomCreateResponse +func (s *ConnectorCreateService) DoCustom(ctx context.Context) (connectors.DetailsWithCustomConfigResponse, error) { + var response connectors.DetailsWithCustomConfigResponse err := s.do(ctx, s.requestCustom(), &response) return response, err } -func (s *ConnectorCreateService) DoCustomMerged(ctx context.Context) (ConnectorCustomMergedCreateResponse, error) { - var response ConnectorCustomMergedCreateResponse +func (s *ConnectorCreateService) DoCustomMerged(ctx context.Context) (connectors.DetailsWithCustomMergedConfigResponse, error) { + var response connectors.DetailsWithCustomMergedConfigResponse req, err := s.requestCustomMerged() @@ -322,7 +261,7 @@ func (s *ConnectorCreateService) DoCustomMerged(ctx context.Context) (ConnectorC err = s.do(ctx, req, &response) if err == nil { - err = FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) + err = utils.FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) } return response, err diff --git a/connector_create_test.go b/connector_create_test.go index 3c0bcc46..22f3bf4f 100644 --- a/connector_create_test.go +++ b/connector_create_test.go @@ -5,11 +5,12 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewConnectorCreateE2E(t *testing.T) { - created, err := Client.NewConnectorCreate(). - GroupID(PredefinedGroupId). + created, err := testutils.Client.NewConnectorCreate(). + GroupID(testutils.PredefinedGroupId). Service("itunes_connect"). RunSetupTests(false). Config(fivetran.NewConnectorConfig(). @@ -23,34 +24,34 @@ func TestNewConnectorCreateE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertNotEmpty(t, created.Data.ID) - AssertEqual(t, created.Data.GroupID, PredefinedGroupId) - AssertEqual(t, created.Data.Service, "itunes_connect") - AssertEqual(t, *created.Data.ServiceVersion, 1) - AssertEqual(t, created.Data.Schema, "itunes_e2e_connect") - AssertEqual(t, created.Data.ConnectedBy, PredefinedUserId) - AssertEqual(t, created.Data.CreatedAt.IsZero(), false) - AssertEqual(t, created.Data.SucceededAt.IsZero(), true) - AssertEqual(t, created.Data.FailedAt.IsZero(), true) - AssertEqual(t, *created.Data.Paused, false) - AssertEqual(t, *created.Data.PauseAfterTrial, false) - AssertEqual(t, *created.Data.SyncFrequency, 360) - AssertEqual(t, created.Data.ScheduleType, "auto") + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertNotEmpty(t, created.Data.ID) + testutils.AssertEqual(t, created.Data.GroupID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, created.Data.Service, "itunes_connect") + testutils.AssertEqual(t, *created.Data.ServiceVersion, 1) + testutils.AssertEqual(t, created.Data.Schema, "itunes_e2e_connect") + testutils.AssertEqual(t, created.Data.ConnectedBy, testutils.PredefinedUserId) + testutils.AssertEqual(t, created.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, created.Data.SucceededAt.IsZero(), true) + testutils.AssertEqual(t, created.Data.FailedAt.IsZero(), true) + testutils.AssertEqual(t, *created.Data.Paused, false) + testutils.AssertEqual(t, *created.Data.PauseAfterTrial, false) + testutils.AssertEqual(t, *created.Data.SyncFrequency, 360) + testutils.AssertEqual(t, created.Data.ScheduleType, "auto") - AssertEqual(t, created.Data.Status.SetupState, "incomplete") - AssertEqual(t, created.Data.Status.SyncState, "scheduled") - AssertEqual(t, created.Data.Status.UpdateState, "on_schedule") - AssertEqual(t, *created.Data.Status.IsHistoricalSync, true) - AssertHasLength(t, created.Data.Status.Tasks, 0) - AssertHasLength(t, created.Data.Status.Warnings, 0) + testutils.AssertEqual(t, created.Data.Status.SetupState, "incomplete") + testutils.AssertEqual(t, created.Data.Status.SyncState, "scheduled") + testutils.AssertEqual(t, created.Data.Status.UpdateState, "on_schedule") + testutils.AssertEqual(t, *created.Data.Status.IsHistoricalSync, true) + testutils.AssertHasLength(t, created.Data.Status.Tasks, 0) + testutils.AssertHasLength(t, created.Data.Status.Warnings, 0) - AssertEqual(t, created.Data.Config.Password, "******") - AssertEqual(t, created.Data.Config.TimeframeMonths, "TWELVE") - AssertEqual(t, created.Data.Config.AppSyncMode, "AllApps") - AssertEqual(t, created.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") - AssertEqual(t, created.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") - AssertEqual(t, created.Data.Config.Username, "fivetran") - t.Cleanup(func() { DeleteConnector(t, created.Data.ID) }) + testutils.AssertEqual(t, created.Data.Config.Password, "******") + testutils.AssertEqual(t, created.Data.Config.TimeframeMonths, "TWELVE") + testutils.AssertEqual(t, created.Data.Config.AppSyncMode, "AllApps") + testutils.AssertEqual(t, created.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") + testutils.AssertEqual(t, created.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") + testutils.AssertEqual(t, created.Data.Config.Username, "fivetran") + t.Cleanup(func() { testutils.DeleteConnector(t, created.Data.ID) }) } diff --git a/connector_delete.go b/connector_delete.go index 0637f973..99d75d18 100644 --- a/connector_delete.go +++ b/connector_delete.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ConnectorDeleteService implements the Connector Management, Delete a Connector API. @@ -13,11 +16,6 @@ type ConnectorDeleteService struct { connectorID *string } -type ConnectorDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewConnectorDelete() *ConnectorDeleteService { return &ConnectorDeleteService{c: c} } @@ -27,8 +25,8 @@ func (s *ConnectorDeleteService) ConnectorID(connectorID string) *ConnectorDelet return s } -func (s *ConnectorDeleteService) Do(ctx context.Context) (ConnectorDeleteResponse, error) { - var response ConnectorDeleteResponse +func (s *ConnectorDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.connectorID == nil { return response, fmt.Errorf("missing required ConnectorID") @@ -39,18 +37,18 @@ func (s *ConnectorDeleteService) Do(ctx context.Context) (ConnectorDeleteRespons headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/connector_delete_test.go b/connector_delete_test.go index a948d875..835ff772 100644 --- a/connector_delete_test.go +++ b/connector_delete_test.go @@ -4,18 +4,20 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewConnectorDeleteE2E(t *testing.T) { - connectorId := CreateConnector(t) - deleted, err := Client.NewConnectorDelete().ConnectorID(connectorId).Do(context.Background()) + connectorId := testutils.CreateConnector(t) + deleted, err := testutils.Client.NewConnectorDelete().ConnectorID(connectorId).Do(context.Background()) if err != nil { t.Logf("%+v\n", deleted) t.Error(err) } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, connectorId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, connectorId), true) } diff --git a/connector_details.go b/connector_details.go index e1ca6474..258a8a3b 100644 --- a/connector_details.go +++ b/connector_details.go @@ -4,7 +4,10 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/utils" ) // ConnectorDetailsService implements the Connector Management, Retrieve Connector Details API. @@ -14,65 +17,6 @@ type ConnectorDetailsService struct { connectorID *string } -type ConnectorDetailsdataBase struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - ServiceVersion *int `json:"service_version"` - Schema string `json:"schema"` - ConnectedBy string `json:"connected_by"` - CreatedAt time.Time `json:"created_at"` - SucceededAt time.Time `json:"succeeded_at"` - FailedAt time.Time `json:"failed_at"` - Paused *bool `json:"paused"` - PauseAfterTrial *bool `json:"pause_after_trial"` - DailySyncTime string `json:"daily_sync_time"` - SyncFrequency *int `json:"sync_frequency"` - ScheduleType string `json:"schedule_type"` - Status struct { - SetupState string `json:"setup_state"` - SyncState string `json:"sync_state"` - UpdateState string `json:"update_state"` - IsHistoricalSync *bool `json:"is_historical_sync"` - Tasks []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"tasks"` - Warnings []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"warnings"` - } `json:"status"` -} - -type ConnectorDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorDetailsdataBase - Config ConnectorConfigResponse `json:"config"` - } `json:"data"` -} - -type ConnectorCustomDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorDetailsdataBase - Config map[string]interface{} `json:"config"` - } `json:"data"` -} - -type ConnectorCustomMergedDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorDetailsdataBase - CustomConfig map[string]interface{} `json:"config"` - Config ConnectorConfigResponse // no mapping here - } `json:"data"` -} - func (c *Client) NewConnectorDetails() *ConnectorDetailsService { return &ConnectorDetailsService{c: c} } @@ -93,18 +37,18 @@ func (s *ConnectorDetailsService) do(ctx context.Context, response any) error { headers := s.c.commonHeaders() headers["Accept"] = restAPIv2 - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return err @@ -122,29 +66,29 @@ func (s *ConnectorDetailsService) do(ctx context.Context, response any) error { return nil } -func (s *ConnectorDetailsService) Do(ctx context.Context) (ConnectorDetailsResponse, error) { - var response ConnectorDetailsResponse +func (s *ConnectorDetailsService) Do(ctx context.Context) (connectors.DetailsWithConfigNoTestsResponse, error) { + var response connectors.DetailsWithConfigNoTestsResponse err := s.do(ctx, &response) return response, err } -func (s *ConnectorDetailsService) DoCustom(ctx context.Context) (ConnectorCustomDetailsResponse, error) { - var response ConnectorCustomDetailsResponse +func (s *ConnectorDetailsService) DoCustom(ctx context.Context) (connectors.DetailsWithCustomConfigNoTestsResponse, error) { + var response connectors.DetailsWithCustomConfigNoTestsResponse err := s.do(ctx, &response) return response, err } -func (s *ConnectorDetailsService) DoCustomMerged(ctx context.Context) (ConnectorCustomMergedDetailsResponse, error) { - var response ConnectorCustomMergedDetailsResponse +func (s *ConnectorDetailsService) DoCustomMerged(ctx context.Context) (connectors.DetailsWithCustomMergedConfigNoTestsResponse, error) { + var response connectors.DetailsWithCustomMergedConfigNoTestsResponse err := s.do(ctx, &response) if err == nil { - err = FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) + err = utils.FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) } return response, err diff --git a/connector_details_test.go b/connector_details_test.go index 7327222b..e134f53f 100644 --- a/connector_details_test.go +++ b/connector_details_test.go @@ -3,44 +3,46 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewConnectorDetailsE2E(t *testing.T) { - connectorId := CreateTempConnector(t) - details, err := Client.NewConnectorDetails().ConnectorID(connectorId).Do(context.Background()) + connectorId := testutils.CreateTempConnector(t) + details, err := testutils.Client.NewConnectorDetails().ConnectorID(connectorId).Do(context.Background()) if err != nil { t.Logf("%+v\n", details) t.Error(err) } - AssertEqual(t, details.Code, "Success") - AssertEqual(t, details.Data.ID, connectorId) - AssertEqual(t, details.Data.GroupID, PredefinedGroupId) - AssertEqual(t, details.Data.Service, "itunes_connect") - AssertEqual(t, *details.Data.ServiceVersion, 1) - AssertEqual(t, details.Data.Schema, "itunes_e2e_connect") - AssertEqual(t, details.Data.ConnectedBy, PredefinedUserId) - AssertEqual(t, details.Data.CreatedAt.IsZero(), false) - AssertEqual(t, details.Data.SucceededAt.IsZero(), true) - AssertEqual(t, details.Data.FailedAt.IsZero(), true) - AssertEqual(t, *details.Data.Paused, false) - AssertEqual(t, *details.Data.PauseAfterTrial, false) - AssertEqual(t, *details.Data.SyncFrequency, 360) - AssertEqual(t, details.Data.ScheduleType, "auto") - - AssertEqual(t, details.Data.Status.SetupState, "incomplete") - AssertEqual(t, details.Data.Status.SyncState, "scheduled") - AssertEqual(t, details.Data.Status.UpdateState, "on_schedule") - AssertEqual(t, *details.Data.Status.IsHistoricalSync, true) - AssertHasLength(t, details.Data.Status.Tasks, 0) - AssertHasLength(t, details.Data.Status.Warnings, 0) - - AssertEqual(t, details.Data.Config.Password, "******") - AssertEqual(t, details.Data.Config.TimeframeMonths, "TWELVE") - AssertEqual(t, details.Data.Config.AppSyncMode, "AllApps") - AssertEqual(t, details.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") - AssertEqual(t, details.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") - AssertEqual(t, details.Data.Config.Username, "fivetran") + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertEqual(t, details.Data.ID, connectorId) + testutils.AssertEqual(t, details.Data.GroupID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, details.Data.Service, "itunes_connect") + testutils.AssertEqual(t, *details.Data.ServiceVersion, 1) + testutils.AssertEqual(t, details.Data.Schema, "itunes_e2e_connect") + testutils.AssertEqual(t, details.Data.ConnectedBy, testutils.PredefinedUserId) + testutils.AssertEqual(t, details.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, details.Data.SucceededAt.IsZero(), true) + testutils.AssertEqual(t, details.Data.FailedAt.IsZero(), true) + testutils.AssertEqual(t, *details.Data.Paused, false) + testutils.AssertEqual(t, *details.Data.PauseAfterTrial, false) + testutils.AssertEqual(t, *details.Data.SyncFrequency, 360) + testutils.AssertEqual(t, details.Data.ScheduleType, "auto") + + testutils.AssertEqual(t, details.Data.Status.SetupState, "incomplete") + testutils.AssertEqual(t, details.Data.Status.SyncState, "scheduled") + testutils.AssertEqual(t, details.Data.Status.UpdateState, "on_schedule") + testutils.AssertEqual(t, *details.Data.Status.IsHistoricalSync, true) + testutils.AssertHasLength(t, details.Data.Status.Tasks, 0) + testutils.AssertHasLength(t, details.Data.Status.Warnings, 0) + + testutils.AssertEqual(t, details.Data.Config.Password, "******") + testutils.AssertEqual(t, details.Data.Config.TimeframeMonths, "TWELVE") + testutils.AssertEqual(t, details.Data.Config.AppSyncMode, "AllApps") + testutils.AssertEqual(t, details.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") + testutils.AssertEqual(t, details.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") + testutils.AssertEqual(t, details.Data.Config.Username, "fivetran") } diff --git a/connector_modify.go b/connector_modify.go index fa4a81e1..7ae60931 100644 --- a/connector_modify.go +++ b/connector_modify.go @@ -4,7 +4,10 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/utils" ) // ConnectorModifyService implements the Connector Management, Modify a Connector API. @@ -21,8 +24,8 @@ type ConnectorModifyService struct { scheduleType *string runSetupTests *bool pauseAfterTrial *bool - config *ConnectorConfig - auth *ConnectorAuth + config *connectors.ConnectorConfig + auth *connectors.ConnectorAuth configCustom *map[string]interface{} authCustom *map[string]interface{} } @@ -41,8 +44,8 @@ type connectorModifyRequestBase struct { type connectorModifyRequest struct { connectorModifyRequestBase - Config *connectorConfigRequest `json:"config,omitempty"` - Auth *connectorAuthRequest `json:"auth,omitempty"` + Config any `json:"config,omitempty"` + Auth any `json:"auth,omitempty"` } type connectorCustomModifyRequest struct { @@ -51,69 +54,6 @@ type connectorCustomModifyRequest struct { Auth *map[string]interface{} `json:"auth,omitempty"` } -type ConnectorModifyResponseDataBase struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - ServiceVersion *int `json:"service_version"` - Schema string `json:"schema"` - ConnectedBy string `json:"connected_by"` - CreatedAt time.Time `json:"created_at"` - SucceededAt time.Time `json:"succeeded_at"` - FailedAt time.Time `json:"failed_at"` - SyncFrequency *int `json:"sync_frequency"` - Paused *bool `json:"paused"` - PauseAfterTrial *bool `json:"pause_after_trial"` - ScheduleType string `json:"schedule_type"` - Status struct { - SetupState string `json:"setup_state"` - SyncState string `json:"sync_state"` - UpdateState string `json:"update_state"` - IsHistoricalSync *bool `json:"is_historical_sync"` - Tasks []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"tasks"` - Warnings []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"warnings"` - } `json:"status"` - SetupTests []struct { - Title string `json:"title"` - Status string `json:"status"` - Message string `json:"message"` - } `json:"setup_tests"` -} - -type ConnectorModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorModifyResponseDataBase - Config ConnectorConfigResponse `json:"config"` - } `json:"data"` -} - -type ConnectorCustomModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorModifyResponseDataBase - Config map[string]interface{} `json:"config"` - } `json:"data"` -} - -type ConnectorCustomMergedModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorModifyResponseDataBase - CustomConfig map[string]interface{} `json:"config"` - Config ConnectorConfigResponse // no mapping here - } `json:"data"` -} - func (c *Client) NewConnectorModify() *ConnectorModifyService { return &ConnectorModifyService{c: c} } @@ -133,14 +73,14 @@ func (s *ConnectorModifyService) requestBase() connectorModifyRequestBase { } func (s *ConnectorModifyService) request() *connectorModifyRequest { - var config *connectorConfigRequest + var config interface{} if s.config != nil { - config = s.config.request() + config = s.config.Request() } - var auth *connectorAuthRequest + var auth interface{} if s.auth != nil { - auth = s.auth.request() + auth = s.auth.Request() } return &connectorModifyRequest{ @@ -163,7 +103,7 @@ func (s *ConnectorModifyService) requestCustomMerged() (*connectorCustomModifyRe if s.config != nil { var err error - currentConfig, err = s.config.merge(currentConfig) + currentConfig, err = s.config.Merge(currentConfig) if err != nil { return nil, err } @@ -172,7 +112,7 @@ func (s *ConnectorModifyService) requestCustomMerged() (*connectorCustomModifyRe currentAuth := s.authCustom if s.auth != nil { var err error - currentAuth, err = s.auth.merge(currentAuth) + currentAuth, err = s.auth.Merge(currentAuth) if err != nil { return nil, err } @@ -205,12 +145,12 @@ func (s *ConnectorModifyService) DailySyncTime(value string) *ConnectorModifySer return s } -func (s *ConnectorModifyService) Config(value *ConnectorConfig) *ConnectorModifyService { +func (s *ConnectorModifyService) Config(value *connectors.ConnectorConfig) *ConnectorModifyService { s.config = value return s } -func (s *ConnectorModifyService) Auth(value *ConnectorAuth) *ConnectorModifyService { +func (s *ConnectorModifyService) Auth(value *connectors.ConnectorAuth) *ConnectorModifyService { s.auth = value return s } @@ -273,18 +213,18 @@ func (s *ConnectorModifyService) do(ctx context.Context, req, response any) erro return err } - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return err } @@ -301,24 +241,24 @@ func (s *ConnectorModifyService) do(ctx context.Context, req, response any) erro return nil } -func (s *ConnectorModifyService) Do(ctx context.Context) (ConnectorModifyResponse, error) { - var response ConnectorModifyResponse +func (s *ConnectorModifyService) Do(ctx context.Context) (connectors.DetailsWithConfigResponse, error) { + var response connectors.DetailsWithConfigResponse err := s.do(ctx, s.request(), &response) return response, err } -func (s *ConnectorModifyService) DoCustom(ctx context.Context) (ConnectorCustomModifyResponse, error) { - var response ConnectorCustomModifyResponse +func (s *ConnectorModifyService) DoCustom(ctx context.Context) (connectors.DetailsWithCustomConfigResponse, error) { + var response connectors.DetailsWithCustomConfigResponse err := s.do(ctx, s.requestCustom(), &response) return response, err } -func (s *ConnectorModifyService) DoCustomMerged(ctx context.Context) (ConnectorCustomMergedModifyResponse, error) { - var response ConnectorCustomMergedModifyResponse +func (s *ConnectorModifyService) DoCustomMerged(ctx context.Context) (connectors.DetailsWithCustomMergedConfigResponse, error) { + var response connectors.DetailsWithCustomMergedConfigResponse req, err := s.requestCustomMerged() @@ -329,7 +269,7 @@ func (s *ConnectorModifyService) DoCustomMerged(ctx context.Context) (ConnectorC err = s.do(ctx, req, &response) if err == nil { - err = FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) + err = utils.FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) } return response, err diff --git a/connector_modify_test.go b/connector_modify_test.go index 5c3c66fc..57cd8496 100644 --- a/connector_modify_test.go +++ b/connector_modify_test.go @@ -5,12 +5,13 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewConnectorModifyE2E(t *testing.T) { - connectorId := CreateTempConnector(t) + connectorId := testutils.CreateTempConnector(t) - updated, err := Client.NewConnectorModify().ConnectorID(connectorId). + updated, err := testutils.Client.NewConnectorModify().ConnectorID(connectorId). Paused(true). PauseAfterTrial(true). //IsHistoricalSync(false). @@ -27,33 +28,33 @@ func TestNewConnectorModifyE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, updated.Code, "Success") - AssertEqual(t, updated.Data.ID, connectorId) - AssertEqual(t, updated.Data.GroupID, PredefinedGroupId) - AssertEqual(t, updated.Data.Service, "itunes_connect") - AssertEqual(t, *updated.Data.ServiceVersion, 1) - AssertEqual(t, updated.Data.Schema, "itunes_e2e_connect") - AssertEqual(t, updated.Data.ConnectedBy, PredefinedUserId) - AssertEqual(t, updated.Data.CreatedAt.IsZero(), false) - AssertEqual(t, updated.Data.SucceededAt.IsZero(), true) - AssertEqual(t, updated.Data.FailedAt.IsZero(), true) - AssertEqual(t, *updated.Data.Paused, true) - AssertEqual(t, *updated.Data.PauseAfterTrial, true) - AssertEqual(t, *updated.Data.SyncFrequency, 1440) - AssertEqual(t, updated.Data.ScheduleType, "auto") - - AssertNotEmpty(t, updated.Data.Status.SetupState) - AssertEqual(t, updated.Data.Status.SyncState, "paused") - AssertEqual(t, updated.Data.Status.UpdateState, "on_schedule") + testutils.AssertEqual(t, updated.Code, "Success") + testutils.AssertEqual(t, updated.Data.ID, connectorId) + testutils.AssertEqual(t, updated.Data.GroupID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, updated.Data.Service, "itunes_connect") + testutils.AssertEqual(t, *updated.Data.ServiceVersion, 1) + testutils.AssertEqual(t, updated.Data.Schema, "itunes_e2e_connect") + testutils.AssertEqual(t, updated.Data.ConnectedBy, testutils.PredefinedUserId) + testutils.AssertEqual(t, updated.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, updated.Data.SucceededAt.IsZero(), true) + testutils.AssertEqual(t, updated.Data.FailedAt.IsZero(), true) + testutils.AssertEqual(t, *updated.Data.Paused, true) + testutils.AssertEqual(t, *updated.Data.PauseAfterTrial, true) + testutils.AssertEqual(t, *updated.Data.SyncFrequency, 1440) + testutils.AssertEqual(t, updated.Data.ScheduleType, "auto") + + testutils.AssertNotEmpty(t, updated.Data.Status.SetupState) + testutils.AssertEqual(t, updated.Data.Status.SyncState, "paused") + testutils.AssertEqual(t, updated.Data.Status.UpdateState, "on_schedule") //todo: check after fix - //AssertEqual(t, *updated.Data.Status.IsHistoricalSync, false) - AssertHasLength(t, updated.Data.Status.Tasks, 0) - AssertHasLength(t, updated.Data.Status.Warnings, 0) - - AssertEqual(t, updated.Data.Config.Password, "******") - AssertEqual(t, updated.Data.Config.TimeframeMonths, "SIX") - AssertEqual(t, updated.Data.Config.AppSyncMode, "AllApps") - AssertEqual(t, updated.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") - AssertEqual(t, updated.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") - AssertEqual(t, updated.Data.Config.Username, "fivetran_updated") + //testutils.AssertEqual(t, *updated.Data.Status.IsHistoricalSync, false) + testutils.AssertHasLength(t, updated.Data.Status.Tasks, 0) + testutils.AssertHasLength(t, updated.Data.Status.Warnings, 0) + + testutils.AssertEqual(t, updated.Data.Config.Password, "******") + testutils.AssertEqual(t, updated.Data.Config.TimeframeMonths, "SIX") + testutils.AssertEqual(t, updated.Data.Config.AppSyncMode, "AllApps") + testutils.AssertEqual(t, updated.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") + testutils.AssertEqual(t, updated.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") + testutils.AssertEqual(t, updated.Data.Config.Username, "fivetran_updated") } diff --git a/connector_resync_table.go b/connector_resync_table.go index 414aa37d..2f454b1d 100644 --- a/connector_resync_table.go +++ b/connector_resync_table.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ConnectorReSyncTableService implements the Connector Management, Re-sync Connector Table Data API. @@ -15,11 +18,6 @@ type ConnectorReSyncTableService struct { table *string } -type ConnectorReSyncTableResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewConnectorReSyncTable() *ConnectorReSyncTableService { return &ConnectorReSyncTableService{c: c} } @@ -39,8 +37,8 @@ func (s *ConnectorReSyncTableService) Table(value string) *ConnectorReSyncTableS return s } -func (s *ConnectorReSyncTableService) Do(ctx context.Context) (ConnectorReSyncTableResponse, error) { - var response ConnectorReSyncTableResponse +func (s *ConnectorReSyncTableService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.connectorID == nil { return response, fmt.Errorf("missing required ConnectorID") @@ -57,18 +55,18 @@ func (s *ConnectorReSyncTableService) Do(ctx context.Context) (ConnectorReSyncTa headers := s.c.commonHeaders() - r := request{ - method: "POST", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/connector_schema_details.go b/connector_schema_details.go index 999326a6..a6b144ce 100644 --- a/connector_schema_details.go +++ b/connector_schema_details.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ConnectorSchemaDetailsService implements the Connector Management, Retrieve a Connector Schema Config API. @@ -13,15 +16,6 @@ type ConnectorSchemaDetailsService struct { connectorID *string } -type ConnectorSchemaDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - SchemaChangeHandling string `json:"schema_change_handling"` - Schemas map[string]*ConnectorSchemaConfigSchemaResponse `json:"schemas"` - } `json:"data"` -} - func (c *Client) NewConnectorSchemaDetails() *ConnectorSchemaDetailsService { return &ConnectorSchemaDetailsService{c: c} } @@ -31,8 +25,8 @@ func (s *ConnectorSchemaDetailsService) ConnectorID(value string) *ConnectorSche return s } -func (s *ConnectorSchemaDetailsService) Do(ctx context.Context) (ConnectorSchemaDetailsResponse, error) { - var response ConnectorSchemaDetailsResponse +func (s *ConnectorSchemaDetailsService) Do(ctx context.Context) (connectors.ConnectorSchemaDetailsResponse, error) { + var response connectors.ConnectorSchemaDetailsResponse if s.connectorID == nil { return response, fmt.Errorf("missing required ConnectorID") @@ -44,18 +38,18 @@ func (s *ConnectorSchemaDetailsService) Do(ctx context.Context) (ConnectorSchema headers := s.c.commonHeaders() headers["Accept"] = restAPIv2 - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/connector_schema_reload.go b/connector_schema_reload.go index e470f77c..bc36692c 100644 --- a/connector_schema_reload.go +++ b/connector_schema_reload.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ConnectorSchemaReloadService implements the Connector Management, Reload a Connector Schema Config API. @@ -40,8 +43,8 @@ func (s *ConnectorSchemaReloadService) ExcludeMode(value string) *ConnectorSchem return s } -func (s *ConnectorSchemaReloadService) Do(ctx context.Context) (ConnectorSchemaDetailsResponse, error) { - var response ConnectorSchemaDetailsResponse +func (s *ConnectorSchemaReloadService) Do(ctx context.Context) (connectors.ConnectorSchemaDetailsResponse, error) { + var response connectors.ConnectorSchemaDetailsResponse if s.connectorID == nil { return response, fmt.Errorf("missing required ConnectorID") @@ -59,18 +62,18 @@ func (s *ConnectorSchemaReloadService) Do(ctx context.Context) (ConnectorSchemaD headers["Content-Type"] = "application/json" headers["Accept"] = restAPIv2 - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/connector_schema_update.go b/connector_schema_update.go index 4f57c565..aff1208d 100644 --- a/connector_schema_update.go +++ b/connector_schema_update.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ConnectorSchemaConfigUpdateService implements the Connector Management, Modify a Connector Schema Config API. @@ -12,12 +15,12 @@ type ConnectorSchemaConfigUpdateService struct { c *Client connectorID *string schemaChangeHandling *string - schemas map[string]*ConnectorSchemaConfigSchema + schemas map[string]*connectors.ConnectorSchemaConfigSchema } type connectorSchemaConfigUpdateRequest struct { - SchemaChangeHandling *string `json:"schema_change_handling,omitempty"` - Schemas map[string]*connectorSchemaConfigSchemaRequest `json:"schemas,omitempty"` + SchemaChangeHandling *string `json:"schema_change_handling,omitempty"` + Schemas map[string]*connectors.ConnectorSchemaConfigSchemaRequest `json:"schemas,omitempty"` } func (c *Client) NewConnectorSchemaUpdateService() *ConnectorSchemaConfigUpdateService { @@ -25,11 +28,11 @@ func (c *Client) NewConnectorSchemaUpdateService() *ConnectorSchemaConfigUpdateS } func (csu *ConnectorSchemaConfigUpdateService) request() *connectorSchemaConfigUpdateRequest { - var schemas map[string]*connectorSchemaConfigSchemaRequest + var schemas map[string]*connectors.ConnectorSchemaConfigSchemaRequest if csu.schemas != nil && len(csu.schemas) != 0 { - schemas = make(map[string]*connectorSchemaConfigSchemaRequest) + schemas = make(map[string]*connectors.ConnectorSchemaConfigSchemaRequest) for k, v := range csu.schemas { - schemas[k] = v.request() + schemas[k] = v.Request() } } @@ -49,16 +52,16 @@ func (csu *ConnectorSchemaConfigUpdateService) SchemaChangeHandling(value string return csu } -func (csu *ConnectorSchemaConfigUpdateService) Schema(name string, schema *ConnectorSchemaConfigSchema) *ConnectorSchemaConfigUpdateService { +func (csu *ConnectorSchemaConfigUpdateService) Schema(name string, schema *connectors.ConnectorSchemaConfigSchema) *ConnectorSchemaConfigUpdateService { if csu.schemas == nil { - csu.schemas = make(map[string]*ConnectorSchemaConfigSchema) + csu.schemas = make(map[string]*connectors.ConnectorSchemaConfigSchema) } csu.schemas[name] = schema return csu } -func (csu *ConnectorSchemaConfigUpdateService) Do(ctx context.Context) (ConnectorSchemaDetailsResponse, error) { - var response ConnectorSchemaDetailsResponse +func (csu *ConnectorSchemaConfigUpdateService) Do(ctx context.Context) (connectors.ConnectorSchemaDetailsResponse, error) { + var response connectors.ConnectorSchemaDetailsResponse if csu.connectorID == nil { return response, fmt.Errorf("missing required ConnectorID") @@ -76,18 +79,18 @@ func (csu *ConnectorSchemaConfigUpdateService) Do(ctx context.Context) (Connecto headers["Content-Type"] = "application/json" headers["Accept"] = restAPIv2 - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: csu.c.httpClient, - handleRateLimits: csu.c.handleRateLimits, - maxRetryAttempts: csu.c.maxRetryAttempts, + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: csu.c.httpClient, + HandleRateLimits: csu.c.handleRateLimits, + MaxRetryAttempts: csu.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/connector_setup_tests.go b/connector_setup_tests.go index b62e260d..8dc6916b 100644 --- a/connector_setup_tests.go +++ b/connector_setup_tests.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ConnectorSetupTestsService implements the Connector Management, Run connector setup tests API. @@ -21,44 +23,6 @@ type connectorSetupTestsRequest struct { TrustFingerprints *bool `json:"trust_fingerprints,omitempty"` } -type ConnectorSetupTestsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - ServiceVersion *int `json:"service_version"` - Schema string `json:"schema"` - ConnectedBy string `json:"connected_by"` - CreatedAt time.Time `json:"created_at"` - SucceededAt time.Time `json:"succeeded_at"` - FailedAt time.Time `json:"failed_at"` - SyncFrequency *int `json:"sync_frequency"` - ScheduleType string `json:"schedule_type"` - Status struct { - SetupState string `json:"setup_state"` - SyncState string `json:"sync_state"` - UpdateState string `json:"update_state"` - IsHistoricalSync *bool `json:"is_historical_sync"` - Tasks []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"tasks"` - Warnings []struct { - Code string `json:"code"` - Message string `json:"message"` - } `json:"warnings"` - } `json:"status"` - SetupTests []struct { - Title string `json:"title"` - Status string `json:"status"` - Message string `json:"message"` - } `json:"setup_tests"` - Config ConnectorConfigResponse `json:"config"` - } `json:"data"` -} - func (c *Client) NewConnectorSetupTests() *ConnectorSetupTestsService { return &ConnectorSetupTestsService{c: c} } @@ -85,11 +49,33 @@ func (s *ConnectorSetupTestsService) TrustFingerprints(value bool) *ConnectorSet return s } -func (s *ConnectorSetupTestsService) Do(ctx context.Context) (ConnectorSetupTestsResponse, error) { - var response ConnectorSetupTestsResponse +func (s *ConnectorSetupTestsService) Do(ctx context.Context) (connectors.DetailsWithConfigResponse, error) { + var response connectors.DetailsWithConfigResponse + + err := s.do(ctx, &response) + + return response, err +} + +func (s *ConnectorSetupTestsService) DoCustom(ctx context.Context) (connectors.DetailsWithCustomConfigResponse, error) { + var response connectors.DetailsWithCustomConfigResponse + + err := s.do(ctx, &response) + + return response, err +} + +func (s *ConnectorSetupTestsService) DoCustomMerged(ctx context.Context) (connectors.DetailsWithCustomMergedConfigResponse, error) { + var response connectors.DetailsWithCustomMergedConfigResponse + + err := s.do(ctx, &response) + + return response, err +} +func (s *ConnectorSetupTestsService) do(ctx context.Context, response any) error { if s.connectorID == nil { - return response, fmt.Errorf("missing required ConnectorID") + return fmt.Errorf("missing required ConnectorID") } url := fmt.Sprintf("%v/connectors/%v/test", s.c.baseURL, *s.connectorID) @@ -101,33 +87,33 @@ func (s *ConnectorSetupTestsService) Do(ctx context.Context) (ConnectorSetupTest reqBody, err := json.Marshal(s.request()) if err != nil { - return response, err + return err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { - return response, err + return err } if err := json.Unmarshal(respBody, &response); err != nil { - return response, err + return err } if respStatus != expectedStatus { err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err + return err } - return response, nil + return nil } diff --git a/connector_setup_tests_test.go b/connector_setup_tests_test.go index e7df4526..58e664e4 100644 --- a/connector_setup_tests_test.go +++ b/connector_setup_tests_test.go @@ -3,12 +3,14 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewConnectorSetupTestsE2E(t *testing.T) { - connectorId := CreateTempConnector(t) + connectorId := testutils.CreateTempConnector(t) - details, err := Client.NewConnectorSetupTests(). + details, err := testutils.Client.NewConnectorSetupTests(). ConnectorID(connectorId). TrustCertificates(true). TrustFingerprints(false). @@ -19,31 +21,31 @@ func TestNewConnectorSetupTestsE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, details.Code, "Success") - AssertEqual(t, details.Data.ID, connectorId) - AssertEqual(t, details.Data.GroupID, PredefinedGroupId) - AssertEqual(t, details.Data.Service, "itunes_connect") - AssertEqual(t, *details.Data.ServiceVersion, 1) - AssertEqual(t, details.Data.Schema, "itunes_e2e_connect") - AssertEqual(t, details.Data.ConnectedBy, PredefinedUserId) - AssertEqual(t, details.Data.CreatedAt.IsZero(), false) - AssertEqual(t, details.Data.SucceededAt.IsZero(), true) - AssertEqual(t, details.Data.FailedAt.IsZero(), true) - - AssertEqual(t, *details.Data.SyncFrequency, 360) - AssertEqual(t, details.Data.ScheduleType, "auto") - - AssertEqual(t, details.Data.Status.SetupState, "incomplete") - AssertEqual(t, details.Data.Status.SyncState, "scheduled") - AssertEqual(t, details.Data.Status.UpdateState, "on_schedule") - AssertEqual(t, *details.Data.Status.IsHistoricalSync, true) - AssertHasLength(t, details.Data.Status.Tasks, 0) - AssertHasLength(t, details.Data.Status.Warnings, 0) - - AssertEqual(t, details.Data.Config.Password, "******") - AssertEqual(t, details.Data.Config.TimeframeMonths, "TWELVE") - AssertEqual(t, details.Data.Config.AppSyncMode, "AllApps") - AssertEqual(t, details.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") - AssertEqual(t, details.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") - AssertEqual(t, details.Data.Config.Username, "fivetran") + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertEqual(t, details.Data.ID, connectorId) + testutils.AssertEqual(t, details.Data.GroupID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, details.Data.Service, "itunes_connect") + testutils.AssertEqual(t, *details.Data.ServiceVersion, 1) + testutils.AssertEqual(t, details.Data.Schema, "itunes_e2e_connect") + testutils.AssertEqual(t, details.Data.ConnectedBy, testutils.PredefinedUserId) + testutils.AssertEqual(t, details.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, details.Data.SucceededAt.IsZero(), true) + testutils.AssertEqual(t, details.Data.FailedAt.IsZero(), true) + + testutils.AssertEqual(t, *details.Data.SyncFrequency, 360) + testutils.AssertEqual(t, details.Data.ScheduleType, "auto") + + testutils.AssertEqual(t, details.Data.Status.SetupState, "incomplete") + testutils.AssertEqual(t, details.Data.Status.SyncState, "scheduled") + testutils.AssertEqual(t, details.Data.Status.UpdateState, "on_schedule") + testutils.AssertEqual(t, *details.Data.Status.IsHistoricalSync, true) + testutils.AssertHasLength(t, details.Data.Status.Tasks, 0) + testutils.AssertHasLength(t, details.Data.Status.Warnings, 0) + + testutils.AssertEqual(t, details.Data.Config.Password, "******") + testutils.AssertEqual(t, details.Data.Config.TimeframeMonths, "TWELVE") + testutils.AssertEqual(t, details.Data.Config.AppSyncMode, "AllApps") + testutils.AssertEqual(t, details.Data.Config.SalesAccountSyncMode, "AllSalesAccounts") + testutils.AssertEqual(t, details.Data.Config.FinanceAccountSyncMode, "AllFinanceAccounts") + testutils.AssertEqual(t, details.Data.Config.Username, "fivetran") } diff --git a/connector_sync.go b/connector_sync.go index 048e41f3..55952681 100644 --- a/connector_sync.go +++ b/connector_sync.go @@ -2,24 +2,35 @@ package fivetran import ( "context" - "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) -// ConnectorSyncService implements the Connector Management, Sync Connector Data API. -// Ref. https://fivetran.com/docs/rest-api/connectors#syncconnectordata -type ConnectorSyncService struct { - c *Client - connectorID *string +func (c *Client) NewHttpService() httputils.HttpService { + return httputils.HttpService{ + Method: "POST", + CommonHeaders: c.commonHeadersByMethod("POST"), + BaseUrl: c.baseURL, + MaxRetryAttempts: c.maxRetryAttempts, + HandleRateLimits: c.handleRateLimits, + Client: c.httpClient, + ExpectedStatus: 200, + } } -type ConnectorSyncResponse struct { - Code string `json:"code"` - Message string `json:"message"` +func (c *Client) NewConnectorSync() *ConnectorSyncService { + return &ConnectorSyncService{ + HttpService: c.NewHttpService(), + } } -func (c *Client) NewConnectorSync() *ConnectorSyncService { - return &ConnectorSyncService{c: c} +// ConnectorSyncService implements the Connector Management, Sync Connector Data API. +// Ref. https://fivetran.com/docs/rest-api/connectors#syncconnectordata +type ConnectorSyncService struct { + connectorID *string + httputils.HttpService } func (s *ConnectorSyncService) ConnectorID(connectorID string) *ConnectorSyncService { @@ -27,43 +38,14 @@ func (s *ConnectorSyncService) ConnectorID(connectorID string) *ConnectorSyncSer return s } -func (s *ConnectorSyncService) Do(ctx context.Context) (ConnectorSyncResponse, error) { - var response ConnectorSyncResponse +func (s *ConnectorSyncService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.connectorID == nil { return response, fmt.Errorf("missing required ConnectorID") } - url := fmt.Sprintf("%v/connectors/%v/force", s.c.baseURL, *s.connectorID) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - - r := request{ - method: "POST", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + err := s.HttpService.Do(ctx, fmt.Sprintf("/connectors/%v/force", *s.connectorID), nil, nil, &response) - return response, nil + return response, err } diff --git a/connector_sync_test.go b/connector_sync_test.go index 2a13f59a..e565608f 100644 --- a/connector_sync_test.go +++ b/connector_sync_test.go @@ -4,11 +4,13 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewConnectorSyncE2E(t *testing.T) { - connectorId := CreateTempConnector(t) - sync, err := Client.NewConnectorSync(). + connectorId := testutils.CreateTempConnector(t) + sync, err := testutils.Client.NewConnectorSync(). ConnectorID(connectorId). Do(context.Background()) @@ -17,7 +19,7 @@ func TestNewConnectorSyncE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, sync.Code, "Success") - AssertNotEmpty(t, sync.Message) - AssertEqual(t, strings.Contains(sync.Message, connectorId), true) + testutils.AssertEqual(t, sync.Code, "Success") + testutils.AssertNotEmpty(t, sync.Message) + testutils.AssertEqual(t, strings.Contains(sync.Message, connectorId), true) } diff --git a/connectors/common_types.go b/connectors/common_types.go new file mode 100644 index 00000000..cfbff96f --- /dev/null +++ b/connectors/common_types.go @@ -0,0 +1,97 @@ +package connectors + +import ( + "time" + + "github.com/fivetran/go-fivetran/common" +) + +type DetailsResponseDataCommon struct { + ID string `json:"id"` + GroupID string `json:"group_id"` + Service string `json:"service"` + ServiceVersion *int `json:"service_version"` + Schema string `json:"schema"` + ConnectedBy string `json:"connected_by"` + CreatedAt time.Time `json:"created_at"` + SucceededAt time.Time `json:"succeeded_at"` + FailedAt time.Time `json:"failed_at"` + SyncFrequency *int `json:"sync_frequency"` + ScheduleType string `json:"schedule_type"` + Paused *bool `json:"paused"` + PauseAfterTrial *bool `json:"pause_after_trial"` + DailySyncTime string `json:"daily_sync_time"` + Status StatusResponse `json:"status"` +} + +type DetailsAndSetupTestsResponseDataCommon struct { + DetailsResponseDataCommon + SetupTests []common.SetupTestResponse `json:"setup_tests"` +} + +type StatusResponse struct { + SetupState string `json:"setup_state"` + SyncState string `json:"sync_state"` + UpdateState string `json:"update_state"` + IsHistoricalSync *bool `json:"is_historical_sync"` + Tasks []common.CommonResponse `json:"tasks"` + Warnings []common.CommonResponse `json:"warnings"` +} + +type DetailsWithConfigResponse struct { + common.CommonResponse + Data struct { + DetailsAndSetupTestsResponseDataCommon + Config ConnectorConfigResponse `json:"config"` + } `json:"data"` +} + +type DetailsWithCustomConfigResponse struct { + common.CommonResponse + Data struct { + DetailsAndSetupTestsResponseDataCommon + Config map[string]interface{} `json:"config"` + } `json:"data"` +} + +type DetailsWithCustomMergedConfigResponse struct { + common.CommonResponse + Data struct { + DetailsAndSetupTestsResponseDataCommon + CustomConfig map[string]interface{} `json:"config"` + Config ConnectorConfigResponse // no mapping here + } `json:"data"` +} + +type DetailsWithConfigNoTestsResponse struct { + common.CommonResponse + Data struct { + DetailsResponseDataCommon + Config ConnectorConfigResponse `json:"config"` + } `json:"data"` +} + +type DetailsWithCustomConfigNoTestsResponse struct { + common.CommonResponse + Data struct { + DetailsResponseDataCommon + Config map[string]interface{} `json:"config"` + } `json:"data"` +} + +type DetailsWithCustomMergedConfigNoTestsResponse struct { + common.CommonResponse + Data struct { + DetailsResponseDataCommon + CustomConfig map[string]interface{} `json:"config"` + Config ConnectorConfigResponse // no mapping here + } `json:"data"` +} + +type ConnectorSchemaDetailsResponse struct { + common.CommonResponse + Data struct { + SchemaChangeHandling string `json:"schema_change_handling"` + Schemas map[string]*ConnectorSchemaConfigSchemaResponse `json:"schemas"` + } `json:"data"` +} diff --git a/connector_auth.go b/connectors/connector_auth.go similarity index 84% rename from connector_auth.go rename to connectors/connector_auth.go index 8a62d7fb..0643009e 100644 --- a/connector_auth.go +++ b/connectors/connector_auth.go @@ -1,4 +1,6 @@ -package fivetran +package connectors + +import "github.com/fivetran/go-fivetran/utils" // ConnectorAuth builds Connector Management, Auth. // Ref. https://fivetran.com/docs/rest-api/connectors @@ -16,19 +18,15 @@ type connectorAuthRequest struct { RealmID *string `json:"realm_id,omitempty"` } -func NewConnectorAuth() *ConnectorAuth { - return &ConnectorAuth{} -} - -func (ca *ConnectorAuth) merge(customAuth *map[string]interface{}) (*map[string]interface{}, error) { - err := MergeIntoMap(ca.request(), customAuth) +func (ca *ConnectorAuth) Merge(customAuth *map[string]interface{}) (*map[string]interface{}, error) { + err := utils.MergeIntoMap(ca.Request(), customAuth) if err != nil { return nil, err } return customAuth, nil } -func (ca *ConnectorAuth) request() *connectorAuthRequest { +func (ca *ConnectorAuth) Request() *connectorAuthRequest { var clientAccess *connectorAuthClientAccessRequest if ca.clientAccess != nil { clientAccess = ca.clientAccess.request() diff --git a/connector_auth_client_access.go b/connectors/connector_auth_client_access.go similarity index 93% rename from connector_auth_client_access.go rename to connectors/connector_auth_client_access.go index 91b8eac9..a0b5a670 100644 --- a/connector_auth_client_access.go +++ b/connectors/connector_auth_client_access.go @@ -1,4 +1,4 @@ -package fivetran +package connectors // ConnectorAuthClientAccess builds Connector Management, Auth Client Access. // Ref. https://fivetran.com/docs/rest-api/connectors @@ -16,10 +16,6 @@ type connectorAuthClientAccessRequest struct { DeveloperToken *string `json:"developer_token,omitempty"` } -func NewConnectorAuthClientAccess() *ConnectorAuthClientAccess { - return &ConnectorAuthClientAccess{} -} - func (ca *ConnectorAuthClientAccess) request() *connectorAuthClientAccessRequest { var clientID *string if ca.clientID != nil { diff --git a/connector_config.go b/connectors/connector_config.go similarity index 99% rename from connector_config.go rename to connectors/connector_config.go index 42ee8c47..9c037a2d 100644 --- a/connector_config.go +++ b/connectors/connector_config.go @@ -1,4 +1,6 @@ -package fivetran +package connectors + +import "github.com/fivetran/go-fivetran/utils" // ConnectorConfig builds Connector Management, Connector Config. // Ref. https://fivetran.com/docs/rest-api/connectors/config @@ -636,19 +638,15 @@ type ConnectorConfigResponse struct { ShareURL string `json:"share_url"` } -func NewConnectorConfig() *ConnectorConfig { - return &ConnectorConfig{} -} - -func (cc *ConnectorConfig) merge(customConfig *map[string]interface{}) (*map[string]interface{}, error) { - err := MergeIntoMap(cc.request(), customConfig) +func (cc *ConnectorConfig) Merge(customConfig *map[string]interface{}) (*map[string]interface{}, error) { + err := utils.MergeIntoMap(cc.Request(), customConfig) if err != nil { return nil, err } return customConfig, nil } -func (cc *ConnectorConfig) request() *connectorConfigRequest { +func (cc *ConnectorConfig) Request() *connectorConfigRequest { var projectCredentials []*connectorConfigProjectCredentialsRequest if cc.projectCredentials != nil { for _, pc := range cc.projectCredentials { diff --git a/connector_config_adobe_analytics_configuration.go b/connectors/connector_config_adobe_analytics_configuration.go similarity index 94% rename from connector_config_adobe_analytics_configuration.go rename to connectors/connector_config_adobe_analytics_configuration.go index 7988f9bf..a239cfeb 100644 --- a/connector_config_adobe_analytics_configuration.go +++ b/connectors/connector_config_adobe_analytics_configuration.go @@ -1,4 +1,4 @@ -package fivetran +package connectors type ConnectorConfigAdobeAnalyticsConfiguration struct { syncMode *string @@ -27,10 +27,6 @@ type ConnectorConfigAdobeAnalyticsConfigurationResponse struct { Segments []string `json:"segments"` } -func NewConnectorConfigAdobeAnalyticsConfiguration() *ConnectorConfigAdobeAnalyticsConfiguration { - return &ConnectorConfigAdobeAnalyticsConfiguration{} -} - func (c *ConnectorConfigAdobeAnalyticsConfiguration) request() *connectorConfigAdobeAnalyticsConfigurationRequest { var syncMode *string if c.syncMode != nil { diff --git a/connector_config_custom_tables.go b/connectors/connector_config_custom_tables.go similarity index 97% rename from connector_config_custom_tables.go rename to connectors/connector_config_custom_tables.go index 7a753a63..3942a6d2 100644 --- a/connector_config_custom_tables.go +++ b/connectors/connector_config_custom_tables.go @@ -1,4 +1,4 @@ -package fivetran +package connectors // ConnectorConfigCustomTables builds Connector Management, Connector Config Custom Tables. // Ref. https://fivetran.com/docs/rest-api/connectors/config @@ -41,10 +41,6 @@ type ConnectorConfigCustomTablesResponse struct { PrebuiltReportName string `json:"prebuilt_report_name"` } -func NewConnectorConfigCustomTables() *ConnectorConfigCustomTables { - return &ConnectorConfigCustomTables{} -} - func (ct *ConnectorConfigCustomTables) request() *connectorConfigCustomTablesRequest { var tableName *string if ct.tableName != nil { diff --git a/connector_config_project_credentials.go b/connectors/connector_config_project_credentials.go similarity index 91% rename from connector_config_project_credentials.go rename to connectors/connector_config_project_credentials.go index ce135fcb..a039cd8c 100644 --- a/connector_config_project_credentials.go +++ b/connectors/connector_config_project_credentials.go @@ -1,4 +1,4 @@ -package fivetran +package connectors // ConnectorConfigProjectCredentials builds Connector Management, Connector Config Project Credentials. // Ref. https://fivetran.com/docs/rest-api/connectors/config @@ -20,10 +20,6 @@ type ConnectorConfigProjectCredentialsResponse struct { SecretKey string `json:"secret_key"` } -func NewConnectorConfigProjectCredentials() *ConnectorConfigProjectCredentials { - return &ConnectorConfigProjectCredentials{} -} - func (pc *ConnectorConfigProjectCredentials) request() *connectorConfigProjectCredentialsRequest { var project *string if pc.project != nil { diff --git a/connector_config_reports.go b/connectors/connector_config_reports.go similarity index 96% rename from connector_config_reports.go rename to connectors/connector_config_reports.go index 1b1ff888..070c36fc 100644 --- a/connector_config_reports.go +++ b/connectors/connector_config_reports.go @@ -1,4 +1,4 @@ -package fivetran +package connectors // ConnectorConfigReports builds Connector Management, Connector Config Reports. // Ref. https://fivetran.com/docs/rest-api/connectors/config @@ -38,10 +38,6 @@ type ConnectorConfigReportsResponse struct { Filter string `json:"filter"` } -func NewConnectorConfigReports() *ConnectorConfigReports { - return &ConnectorConfigReports{} -} - func (r *ConnectorConfigReports) request() *connectorConfigReportsRequest { var table *string if r.table != nil { diff --git a/connector_schema_config_column.go b/connectors/connector_schema_config_column.go similarity index 89% rename from connector_schema_config_column.go rename to connectors/connector_schema_config_column.go index 2bf8adfb..b4b2b4fe 100644 --- a/connector_schema_config_column.go +++ b/connectors/connector_schema_config_column.go @@ -1,4 +1,4 @@ -package fivetran +package connectors type ConnectorSchemaConfigColumn struct { enabled *bool @@ -21,10 +21,6 @@ type ConnectorSchemaConfigColumnResponse struct { } `json:"enabled_patch_settings"` } -func NewConnectorSchemaConfigColumn() *ConnectorSchemaConfigColumn { - return &ConnectorSchemaConfigColumn{} -} - func (csc *ConnectorSchemaConfigColumn) request() *connectorSchemaConfigColumnRequest { return &connectorSchemaConfigColumnRequest{ Enabled: csc.enabled, diff --git a/connector_schema_config_schema.go b/connectors/connector_schema_config_schema.go similarity index 81% rename from connector_schema_config_schema.go rename to connectors/connector_schema_config_schema.go index 541e523c..94288df3 100644 --- a/connector_schema_config_schema.go +++ b/connectors/connector_schema_config_schema.go @@ -1,11 +1,11 @@ -package fivetran +package connectors type ConnectorSchemaConfigSchema struct { enabled *bool tables map[string]*ConnectorSchemaConfigTable } -type connectorSchemaConfigSchemaRequest struct { +type ConnectorSchemaConfigSchemaRequest struct { Enabled *bool `json:"enabled,omitempty"` Tables map[string]*connectorSchemaConfigTableRequest `json:"tables,omitempty"` } @@ -16,11 +16,7 @@ type ConnectorSchemaConfigSchemaResponse struct { Tables map[string]*ConnectorSchemaConfigTableResponse `json:"tables"` } -func NewConnectorSchemaConfigSchema() *ConnectorSchemaConfigSchema { - return &ConnectorSchemaConfigSchema{} -} - -func (css *ConnectorSchemaConfigSchema) request() *connectorSchemaConfigSchemaRequest { +func (css *ConnectorSchemaConfigSchema) Request() *ConnectorSchemaConfigSchemaRequest { var tables map[string]*connectorSchemaConfigTableRequest if css.tables != nil && len(css.tables) != 0 { tables = make(map[string]*connectorSchemaConfigTableRequest) @@ -29,7 +25,7 @@ func (css *ConnectorSchemaConfigSchema) request() *connectorSchemaConfigSchemaRe } } - return &connectorSchemaConfigSchemaRequest{ + return &ConnectorSchemaConfigSchemaRequest{ Enabled: css.enabled, Tables: tables, } diff --git a/connector_schema_config_table.go b/connectors/connector_schema_config_table.go similarity index 94% rename from connector_schema_config_table.go rename to connectors/connector_schema_config_table.go index 86514468..d5c7fe28 100644 --- a/connector_schema_config_table.go +++ b/connectors/connector_schema_config_table.go @@ -1,4 +1,4 @@ -package fivetran +package connectors type ConnectorSchemaConfigTable struct { enabled *bool @@ -24,10 +24,6 @@ type ConnectorSchemaConfigTableResponse struct { } `json:"enabled_patch_settings"` } -func NewConnectorSchemaConfigTable() *ConnectorSchemaConfigTable { - return &ConnectorSchemaConfigTable{} -} - func (cst *ConnectorSchemaConfigTable) request() *connectorSchemaConfigTableRequest { var columns map[string]*connectorSchemaConfigColumnRequest if cst.columns != nil && len(cst.columns) != 0 { diff --git a/function_secret.go b/connectors/function_secret.go similarity index 87% rename from function_secret.go rename to connectors/function_secret.go index ed85ab0f..107f46f5 100644 --- a/function_secret.go +++ b/connectors/function_secret.go @@ -1,4 +1,4 @@ -package fivetran +package connectors type FunctionSecret struct { key *string @@ -15,10 +15,6 @@ type FunctionSecretResponse struct { Value string `json:"value"` } -func NewFunctionSecret() *FunctionSecret { - return &FunctionSecret{} -} - func (fs *FunctionSecret) request() *functionSecretRequest { return &functionSecretRequest{ Key: fs.key, diff --git a/connectors_source_metadata.go b/connectors_source_metadata.go index 437ace98..30ace942 100644 --- a/connectors_source_metadata.go +++ b/connectors_source_metadata.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ConnectorsSourceMetadataService implements the Connector Management, Retrieve source metadata API. @@ -15,9 +18,8 @@ type ConnectorsSourceMetadataService struct { } type ConnectorsSourceMetadataResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { + common.CommonResponse + Data struct { Items []struct { ID string `json:"id"` Name string `json:"name"` @@ -60,18 +62,18 @@ func (s *ConnectorsSourceMetadataService) Do(ctx context.Context) (ConnectorsSou queries["limit"] = fmt.Sprint(*s.limit) } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/connectors_source_metadata_test.go b/connectors_source_metadata_test.go index 84b49b50..646c47a8 100644 --- a/connectors_source_metadata_test.go +++ b/connectors_source_metadata_test.go @@ -3,21 +3,23 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewConnectorsSourceMetadataE2E(t *testing.T) { - meta, err := Client.NewConnectorsSourceMetadata().Do(context.Background()) + meta, err := testutils.Client.NewConnectorsSourceMetadata().Do(context.Background()) if err != nil { t.Logf("%+v\n", meta) t.Error(err) } - AssertEqual(t, meta.Code, "Success") - AssertNotEmpty(t, meta.Data.Items) - AssertNotEmpty(t, meta.Data.Items[0].ID) - AssertNotEmpty(t, meta.Data.Items[0].Name) - AssertNotEmpty(t, meta.Data.Items[0].Type) - AssertNotEmpty(t, meta.Data.Items[0].Description) - AssertNotEmpty(t, meta.Data.Items[0].IconURL) + testutils.AssertEqual(t, meta.Code, "Success") + testutils.AssertNotEmpty(t, meta.Data.Items) + testutils.AssertNotEmpty(t, meta.Data.Items[0].ID) + testutils.AssertNotEmpty(t, meta.Data.Items[0].Name) + testutils.AssertNotEmpty(t, meta.Data.Items[0].Type) + testutils.AssertNotEmpty(t, meta.Data.Items[0].Description) + testutils.AssertNotEmpty(t, meta.Data.Items[0].IconURL) } diff --git a/creators.go b/creators.go new file mode 100644 index 00000000..a1a5ca3d --- /dev/null +++ b/creators.go @@ -0,0 +1,68 @@ +package fivetran + +import ( + "github.com/fivetran/go-fivetran/connectors" + "github.com/fivetran/go-fivetran/dbt" + "github.com/fivetran/go-fivetran/destinations" + externallogging "github.com/fivetran/go-fivetran/external_logging" +) + +func NewFunctionSecret() *connectors.FunctionSecret { + return &connectors.FunctionSecret{} +} + +func NewConnectorConfig() *connectors.ConnectorConfig { + return &connectors.ConnectorConfig{} +} + +func NewConnectorAuth() *connectors.ConnectorAuth { + return &connectors.ConnectorAuth{} +} + +func NewConnectorConfigReports() *connectors.ConnectorConfigReports { + return &connectors.ConnectorConfigReports{} +} + +func NewConnectorConfigProjectCredentials() *connectors.ConnectorConfigProjectCredentials { + return &connectors.ConnectorConfigProjectCredentials{} +} + +func NewConnectorConfigCustomTables() *connectors.ConnectorConfigCustomTables { + return &connectors.ConnectorConfigCustomTables{} +} + +func NewConnectorConfigAdobeAnalyticsConfiguration() *connectors.ConnectorConfigAdobeAnalyticsConfiguration { + return &connectors.ConnectorConfigAdobeAnalyticsConfiguration{} +} + +func NewConnectorAuthClientAccess() *connectors.ConnectorAuthClientAccess { + return &connectors.ConnectorAuthClientAccess{} +} + +func NewConnectorSchemaConfigColumn() *connectors.ConnectorSchemaConfigColumn { + return &connectors.ConnectorSchemaConfigColumn{} +} + +func NewConnectorSchemaConfigSchema() *connectors.ConnectorSchemaConfigSchema { + return &connectors.ConnectorSchemaConfigSchema{} +} + +func NewConnectorSchemaConfigTable() *connectors.ConnectorSchemaConfigTable { + return &connectors.ConnectorSchemaConfigTable{} +} + +func NewDbtProjectConfig() *dbt.DbtProjectConfig { + return &dbt.DbtProjectConfig{} +} + +func NewDbtTransformationSchedule() *dbt.DbtTransformationSchedule { + return &dbt.DbtTransformationSchedule{} +} + +func NewDestinationConfig() *destinations.DestinationConfig { + return &destinations.DestinationConfig{} +} + +func NewExternalLoggingConfig() *externallogging.ExternalLoggingConfig { + return &externallogging.ExternalLoggingConfig{} +} diff --git a/dbt/common_types.go b/dbt/common_types.go new file mode 100644 index 00000000..5a3a5a0a --- /dev/null +++ b/dbt/common_types.go @@ -0,0 +1,78 @@ +package dbt + +import "github.com/fivetran/go-fivetran/common" + +type DbtModelItem struct { + ID string `json:"id"` + ModelName string `json:"model_name"` + Scheduled bool `json:"scheduled"` +} + +type DbtModelDetailsResponse struct { + common.CommonResponse + Data DbtModelItem `json:"data"` +} + +type DbtModelsListResponse struct { + common.CommonResponse + Data struct { + Items []DbtModelItem `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` +} + +type DbtProjectItem struct { + ID string `json:"id"` + GroupId string `json:"group_id"` + CreatedAt string `json:"created_at"` + CreatedById string `json:"created_by_id"` +} + +type DbtTransformationResponse struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ID string `json:"id"` + Status string `json:"status"` + Schedule DbtTransformationScheduleResponse `json:"schedule"` + LastRun string `json:"last_run"` + OutputModelName string `json:"output_model_name"` + DbtProjectId string `json:"dbt_project_id"` + DbtModelId string `json:"dbt_model_id"` + NextRun string `json:"next_run"` + CreatedAt string `json:"created_at"` + ModelIds []string `json:"model_ids"` + ConnectorIds []string `json:"connector_ids"` + RunTests bool `json:"run_tests"` + Paused bool `json:"paused"` + } `json:"data"` +} + +type DbtProjectDetailsData struct { + DbtProjectItem + DbtVersion string `json:"dbt_version"` + PublicKey string `json:"public_key"` + DefaultSchema string `json:"default_schema"` + TargetName string `json:"target_name"` + Threads int `json:"threads"` + EnvironmentVars []string `json:"environment_vars"` + Type string `json:"type"` + ProjectConfig DbtProjectConfigResponse `json:"project_config"` + Status string `json:"status"` + Errors []string `json:"errors"` +} + +type DbtProjectDetailsResponse struct { + common.CommonResponse + Data struct { + DbtProjectDetailsData + } `json:"data"` +} + +type DbtProjectsListResponse struct { + common.CommonResponse + Data struct { + Items []DbtProjectItem `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` +} diff --git a/dbt_project_config.go b/dbt/dbt_project_config.go similarity index 84% rename from dbt_project_config.go rename to dbt/dbt_project_config.go index 1b9b60d8..e48cc4e2 100644 --- a/dbt_project_config.go +++ b/dbt/dbt_project_config.go @@ -1,4 +1,4 @@ -package fivetran +package dbt type DbtProjectConfig struct { gitRemoteUrl *string @@ -23,11 +23,7 @@ type DbtProjectConfigResponse struct { FolderPath string `json:"folder_path"` } -func NewDbtProjectConfig() *DbtProjectConfig { - return &DbtProjectConfig{} -} - -func (dc *DbtProjectConfig) request() *dbtProjectConfigRequest { +func (dc *DbtProjectConfig) Request() *dbtProjectConfigRequest { return &dbtProjectConfigRequest{ GitRemoteUrl: dc.gitRemoteUrl, GitBranch: dc.gitBranch, @@ -35,7 +31,7 @@ func (dc *DbtProjectConfig) request() *dbtProjectConfigRequest { } } -func (dc *DbtProjectConfig) updateRequest() *updateDbtProjectConfigRequest { +func (dc *DbtProjectConfig) UpdateRequest() *updateDbtProjectConfigRequest { return &updateDbtProjectConfigRequest{ GitBranch: dc.gitBranch, FolderPath: dc.folderPath, diff --git a/dbt_transformation_schedule.go b/dbt/dbt_transformation_schedule.go similarity index 90% rename from dbt_transformation_schedule.go rename to dbt/dbt_transformation_schedule.go index 9001eea5..79b31e89 100644 --- a/dbt_transformation_schedule.go +++ b/dbt/dbt_transformation_schedule.go @@ -1,4 +1,4 @@ -package fivetran +package dbt type DbtTransformationSchedule struct { scheduleType *string @@ -21,11 +21,7 @@ type DbtTransformationScheduleResponse struct { TimeOfDay string `json:"time_of_day"` } -func NewDbtTransformationSchedule() *DbtTransformationSchedule { - return &DbtTransformationSchedule{} -} - -func (dbtTransformationSchedule *DbtTransformationSchedule) request() *dbtTransformationScheduleRequest { +func (dbtTransformationSchedule *DbtTransformationSchedule) Request() *dbtTransformationScheduleRequest { return &dbtTransformationScheduleRequest{ ScheduleType: dbtTransformationSchedule.scheduleType, DaysOfWeek: dbtTransformationSchedule.daysOfWeek, diff --git a/dbt_model_details.go b/dbt_model_details.go index 3b402465..ed711f82 100644 --- a/dbt_model_details.go +++ b/dbt_model_details.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtModelDetailsService struct { @@ -11,16 +14,6 @@ type DbtModelDetailsService struct { modelId *string } -type DbtModelDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - ModelName string `json:"model_name"` - Scheduled bool `json:"scheduled"` - } `json:"data"` -} - func (c *Client) NewDbtModelDetails() *DbtModelDetailsService { return &DbtModelDetailsService{c: c} } @@ -30,8 +23,8 @@ func (s *DbtModelDetailsService) ModelId(value string) *DbtModelDetailsService { return s } -func (s *DbtModelDetailsService) Do(ctx context.Context) (DbtModelDetailsResponse, error) { - var response DbtModelDetailsResponse +func (s *DbtModelDetailsService) Do(ctx context.Context) (dbt.DbtModelDetailsResponse, error) { + var response dbt.DbtModelDetailsResponse if s.modelId == nil { return response, fmt.Errorf("missing required ModelId") @@ -42,18 +35,18 @@ func (s *DbtModelDetailsService) Do(ctx context.Context) (DbtModelDetailsRespons headers := s.c.commonHeaders() - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_models_list.go b/dbt_models_list.go index 9681895c..e2a9b268 100644 --- a/dbt_models_list.go +++ b/dbt_models_list.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtModelsListService struct { @@ -13,19 +16,6 @@ type DbtModelsListService struct { cursor *string } -type DbtModelsListResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Items []struct { - ID string `json:"id"` - ModelName string `json:"model_name"` - Scheduled bool `json:"scheduled"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` -} - func (c *Client) NewDbtModelsList() *DbtModelsListService { return &DbtModelsListService{c: c} } @@ -45,8 +35,8 @@ func (s *DbtModelsListService) Cursor(value string) *DbtModelsListService { return s } -func (s *DbtModelsListService) Do(ctx context.Context) (DbtModelsListResponse, error) { - var response DbtModelsListResponse +func (s *DbtModelsListService) Do(ctx context.Context) (dbt.DbtModelsListResponse, error) { + var response dbt.DbtModelsListResponse url := fmt.Sprintf("%v/dbt/models", s.c.baseURL) expectedStatus := 200 @@ -63,18 +53,18 @@ func (s *DbtModelsListService) Do(ctx context.Context) (DbtModelsListResponse, e queries["project_id"] = *s.projectId } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_project_create.go b/dbt_project_create.go index a45f39c4..4f5417b3 100644 --- a/dbt_project_create.go +++ b/dbt_project_create.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtProjectCreateService struct { @@ -15,18 +18,18 @@ type DbtProjectCreateService struct { threads *int projectType *string environmentVars *[]string - projectConfig *DbtProjectConfig + projectConfig *dbt.DbtProjectConfig } type dbtProjectCreateRequest struct { - GroupID *string `json:"group_id,omitempty"` - DbtVersion *string `json:"dbt_version,omitempty"` - DefaultSchema *string `json:"default_schema,omitempty"` - TargetName *string `json:"target_name,omitempty"` - Threads *int `json:"threads,omitempty"` - EnvironmentVars *[]string `json:"environment_vars,omitempty"` - Type *string `json:"type,omitempty"` - ProjectConfig *dbtProjectConfigRequest `json:"project_config,omitempty"` + GroupID *string `json:"group_id,omitempty"` + DbtVersion *string `json:"dbt_version,omitempty"` + DefaultSchema *string `json:"default_schema,omitempty"` + TargetName *string `json:"target_name,omitempty"` + Threads *int `json:"threads,omitempty"` + EnvironmentVars *[]string `json:"environment_vars,omitempty"` + Type *string `json:"type,omitempty"` + ProjectConfig any `json:"project_config,omitempty"` } func (c *Client) NewDbtProjectCreate() *DbtProjectCreateService { @@ -34,10 +37,10 @@ func (c *Client) NewDbtProjectCreate() *DbtProjectCreateService { } func (s *DbtProjectCreateService) request() *dbtProjectCreateRequest { - var config *dbtProjectConfigRequest + var config interface{} if s.projectConfig != nil { - config = s.projectConfig.request() + config = s.projectConfig.Request() } return &dbtProjectCreateRequest{ @@ -82,7 +85,7 @@ func (s *DbtProjectCreateService) EnvironmentVars(value []string) *DbtProjectCre return s } -func (s *DbtProjectCreateService) ProjectConfig(value *DbtProjectConfig) *DbtProjectCreateService { +func (s *DbtProjectCreateService) ProjectConfig(value *dbt.DbtProjectConfig) *DbtProjectCreateService { s.projectConfig = value return s } @@ -92,8 +95,8 @@ func (s *DbtProjectCreateService) Type(value string) *DbtProjectCreateService { return s } -func (s *DbtProjectCreateService) Do(ctx context.Context) (DbtProjectDetailsResponse, error) { - var response DbtProjectDetailsResponse +func (s *DbtProjectCreateService) Do(ctx context.Context) (dbt.DbtProjectDetailsResponse, error) { + var response dbt.DbtProjectDetailsResponse url := fmt.Sprintf("%v/dbt/projects", s.c.baseURL) expectedStatus := 201 @@ -105,18 +108,18 @@ func (s *DbtProjectCreateService) Do(ctx context.Context) (DbtProjectDetailsResp return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_project_create_test.go b/dbt_project_create_test.go index 9b7c6839..d07d9fa2 100644 --- a/dbt_project_create_test.go +++ b/dbt_project_create_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDbtProjectCreateE2E(t *testing.T) { @@ -18,10 +19,10 @@ func TestNewDbtProjectCreateE2E(t *testing.T) { variable := "DBT_VARIABLE=VALUE" projectType := "GIT" - CreateDbtDestination(t) + testutils.CreateDbtDestination(t) - created, err := Client.NewDbtProjectCreate(). - GroupID(PredefinedGroupId). + created, err := testutils.Client.NewDbtProjectCreate(). + GroupID(testutils.PredefinedGroupId). DbtVersion(dbtVersion). ProjectConfig(fivetran.NewDbtProjectConfig(). GitRemoteUrl(gitRemoteUrl). @@ -39,27 +40,27 @@ func TestNewDbtProjectCreateE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertNotEmpty(t, created.Data.ID) + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertNotEmpty(t, created.Data.ID) - AssertEqual(t, created.Data.GroupID, PredefinedGroupId) - AssertNotEmpty(t, created.Data.CreatedAt) + testutils.AssertEqual(t, created.Data.GroupId, testutils.PredefinedGroupId) + testutils.AssertNotEmpty(t, created.Data.CreatedAt) - AssertEqual(t, created.Data.TargetName, targetName) - AssertEqual(t, created.Data.DefaultSchema, defaultSchema) - AssertNotEmpty(t, created.Data.PublicKey) - AssertEqual(t, created.Data.CreatedById, PredefinedUserId) + testutils.AssertEqual(t, created.Data.TargetName, targetName) + testutils.AssertEqual(t, created.Data.DefaultSchema, defaultSchema) + testutils.AssertNotEmpty(t, created.Data.PublicKey) + testutils.AssertEqual(t, created.Data.CreatedById, testutils.PredefinedUserId) - AssertEqual(t, created.Data.ProjectConfig.GitRemoteUrl, gitRemoteUrl) - AssertEqual(t, created.Data.ProjectConfig.GitBranch, gitBranch) - AssertEqual(t, created.Data.ProjectConfig.FolderPath, folderPath) + testutils.AssertEqual(t, created.Data.ProjectConfig.GitRemoteUrl, gitRemoteUrl) + testutils.AssertEqual(t, created.Data.ProjectConfig.GitBranch, gitBranch) + testutils.AssertEqual(t, created.Data.ProjectConfig.FolderPath, folderPath) - AssertEqual(t, len(created.Data.EnvironmentVars), 1) - AssertEqual(t, created.Data.EnvironmentVars[0], variable) + testutils.AssertEqual(t, len(created.Data.EnvironmentVars), 1) + testutils.AssertEqual(t, created.Data.EnvironmentVars[0], variable) t.Cleanup(func() { - cleanupDbtProjects() - deleteDbtDestination() + testutils.CleanupDbtProjects() + testutils.DeleteDbtDestination() }) } diff --git a/dbt_project_delete.go b/dbt_project_delete.go index 9b0be00e..b8899b59 100644 --- a/dbt_project_delete.go +++ b/dbt_project_delete.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ProjectDeleteService implements the Project Management, Delete a project API. @@ -13,11 +16,6 @@ type DbtProjectDeleteService struct { dbtProjectID *string } -type DbtProjectDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewDbtProjectDelete() *DbtProjectDeleteService { return &DbtProjectDeleteService{c: c} } @@ -27,8 +25,8 @@ func (s *DbtProjectDeleteService) DbtProjectID(value string) *DbtProjectDeleteSe return s } -func (s *DbtProjectDeleteService) Do(ctx context.Context) (DbtProjectDeleteResponse, error) { - var response DbtProjectDeleteResponse +func (s *DbtProjectDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.dbtProjectID == nil { return response, fmt.Errorf("missing required dbtProjectID") @@ -39,18 +37,18 @@ func (s *DbtProjectDeleteService) Do(ctx context.Context) (DbtProjectDeleteRespo headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_project_delete_test.go b/dbt_project_delete_test.go index 11681fd2..265dbe64 100644 --- a/dbt_project_delete_test.go +++ b/dbt_project_delete_test.go @@ -4,26 +4,28 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewProjectDeleteE2E(t *testing.T) { - projectId := CreateDbtProject(t) - deleted, err := Client.NewDbtProjectDelete().DbtProjectID(projectId).Do(context.Background()) + projectId := testutils.CreateDbtProject(t) + deleted, err := testutils.Client.NewDbtProjectDelete().DbtProjectID(projectId).Do(context.Background()) if err != nil { t.Logf("%+v\n", deleted) t.Error(err) } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, projectId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, projectId), true) - resp, err := Client.NewDbtProjectDetails().DbtProjectID(projectId).Do(context.Background()) + resp, err := testutils.Client.NewDbtProjectDetails().DbtProjectID(projectId).Do(context.Background()) - AssertEqual(t, err.Error(), "status code: 404; expected: 200") - AssertEqual(t, strings.HasPrefix(resp.Code, "NotFound"), true) + testutils.AssertEqual(t, err.Error(), "status code: 404; expected: 200") + testutils.AssertEqual(t, strings.HasPrefix(resp.Code, "NotFound"), true) t.Cleanup(func() { - cleanupDbtProjects() - deleteDbtDestination() + testutils.CleanupDbtProjects() + testutils.DeleteDbtDestination() }) } diff --git a/dbt_project_details.go b/dbt_project_details.go index 97db81be..dd713f55 100644 --- a/dbt_project_details.go +++ b/dbt_project_details.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtProjectDetailsService struct { @@ -20,8 +23,8 @@ func (s *DbtProjectDetailsService) DbtProjectID(value string) *DbtProjectDetails return s } -func (s *DbtProjectDetailsService) Do(ctx context.Context) (DbtProjectDetailsResponse, error) { - var response DbtProjectDetailsResponse +func (s *DbtProjectDetailsService) Do(ctx context.Context) (dbt.DbtProjectDetailsResponse, error) { + var response dbt.DbtProjectDetailsResponse if s.dbtProjectID == nil { return response, fmt.Errorf("missing required DbtProjectId") @@ -33,16 +36,18 @@ func (s *DbtProjectDetailsService) Do(ctx context.Context) (DbtProjectDetailsRes headers := s.c.commonHeaders() headers["Accept"] = restAPIv2 - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err diff --git a/dbt_project_modify.go b/dbt_project_modify.go index 17cf51d3..99363d2b 100644 --- a/dbt_project_modify.go +++ b/dbt_project_modify.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtProjectModifyService struct { @@ -14,15 +17,15 @@ type DbtProjectModifyService struct { targetName *string threads *int environmentVars *[]string - projectConfig *DbtProjectConfig + projectConfig *dbt.DbtProjectConfig } type dbtProjectModifyRequest struct { - DbtVersion *string `json:"dbt_version,omitempty"` - TargetName *string `json:"target_name,omitempty"` - Threads *int `json:"threads,omitempty"` - EnvironmentVars *[]string `json:"environment_vars,omitempty"` - ProjectConfig *updateDbtProjectConfigRequest `json:"project_config,omitempty"` + DbtVersion *string `json:"dbt_version,omitempty"` + TargetName *string `json:"target_name,omitempty"` + Threads *int `json:"threads,omitempty"` + EnvironmentVars *[]string `json:"environment_vars,omitempty"` + ProjectConfig any `json:"project_config,omitempty"` } func (c *Client) NewDbtProjectModify() *DbtProjectModifyService { @@ -49,7 +52,7 @@ func (s *DbtProjectModifyService) EnvironmentVars(value []string) *DbtProjectMod return s } -func (s *DbtProjectModifyService) ProjectConfig(value *DbtProjectConfig) *DbtProjectModifyService { +func (s *DbtProjectModifyService) ProjectConfig(value *dbt.DbtProjectConfig) *DbtProjectModifyService { s.projectConfig = value return s } @@ -60,10 +63,10 @@ func (s *DbtProjectModifyService) DbtVersion(value string) *DbtProjectModifyServ } func (s *DbtProjectModifyService) request() *dbtProjectModifyRequest { - var config *updateDbtProjectConfigRequest + var config interface{} if s.projectConfig != nil { - config = s.projectConfig.updateRequest() + config = s.projectConfig.UpdateRequest() } return &dbtProjectModifyRequest{ @@ -75,8 +78,8 @@ func (s *DbtProjectModifyService) request() *dbtProjectModifyRequest { } } -func (s *DbtProjectModifyService) Do(ctx context.Context) (DbtProjectDetailsResponse, error) { - var response DbtProjectDetailsResponse +func (s *DbtProjectModifyService) Do(ctx context.Context) (dbt.DbtProjectDetailsResponse, error) { + var response dbt.DbtProjectDetailsResponse if s.dbtProjectID == nil { return response, fmt.Errorf("missing required dbt project ID") @@ -92,18 +95,18 @@ func (s *DbtProjectModifyService) Do(ctx context.Context) (DbtProjectDetailsResp return response, err } - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_project_response.go b/dbt_project_response.go deleted file mode 100644 index 649420d4..00000000 --- a/dbt_project_response.go +++ /dev/null @@ -1,26 +0,0 @@ -package fivetran - -type DbtProjectDetailsData struct { - ID string `json:"id"` - DbtVersion string `json:"dbt_version"` - GroupID string `json:"group_id"` - CreatedAt string `json:"created_at"` - CreatedById string `json:"created_by_id"` - PublicKey string `json:"public_key"` - DefaultSchema string `json:"default_schema"` - TargetName string `json:"target_name"` - Threads int `json:"threads"` - EnvironmentVars []string `json:"environment_vars"` - Type string `json:"type"` - ProjectConfig DbtProjectConfigResponse `json:"project_config"` - Status string `json:"status"` - Errors []string `json:"errors"` -} - -type DbtProjectDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - DbtProjectDetailsData - } `json:"data"` -} diff --git a/dbt_projects_list.go b/dbt_projects_list.go index 7e397abf..5342be9d 100644 --- a/dbt_projects_list.go +++ b/dbt_projects_list.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtProjectsListService struct { @@ -12,20 +15,6 @@ type DbtProjectsListService struct { cursor *string } -type DbtProjectsListResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Items []struct { - ID string `json:"id"` - GroupId string `json:"group_id"` - CreatedAt string `json:"created_at"` - CreatedById string `json:"created_by_id"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` -} - func (c *Client) NewDbtProjectsList() *DbtProjectsListService { return &DbtProjectsListService{c: c} } @@ -40,8 +29,8 @@ func (s *DbtProjectsListService) Cursor(value string) *DbtProjectsListService { return s } -func (s *DbtProjectsListService) Do(ctx context.Context) (DbtProjectsListResponse, error) { - var response DbtProjectsListResponse +func (s *DbtProjectsListService) Do(ctx context.Context) (dbt.DbtProjectsListResponse, error) { + var response dbt.DbtProjectsListResponse url := fmt.Sprintf("%v/dbt/projects", s.c.baseURL) expectedStatus := 200 @@ -55,18 +44,18 @@ func (s *DbtProjectsListService) Do(ctx context.Context) (DbtProjectsListRespons queries["limit"] = fmt.Sprint(*s.limit) } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_transformation_create.go b/dbt_transformation_create.go index cabf91a8..df63ed30 100644 --- a/dbt_transformation_create.go +++ b/dbt_transformation_create.go @@ -4,21 +4,24 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtTransformationCreateService struct { c *Client dbtModelId *string - schedule *DbtTransformationSchedule + schedule *dbt.DbtTransformationSchedule runTests *bool paused *bool } type dbtTransformationCreateRequest struct { - DbtModelId *string `json:"dbt_model_id,omitempty"` - Schedule *dbtTransformationScheduleRequest `json:"schedule,omitempty"` - RunTests *bool `json:"run_tests,omitempty"` - Paused *bool `json:"paused,omitempty"` + DbtModelId *string `json:"dbt_model_id,omitempty"` + Schedule any `json:"schedule,omitempty"` + RunTests *bool `json:"run_tests,omitempty"` + Paused *bool `json:"paused,omitempty"` } func (c *Client) NewDbtTransformationCreateService() *DbtTransformationCreateService { @@ -26,10 +29,10 @@ func (c *Client) NewDbtTransformationCreateService() *DbtTransformationCreateSer } func (s *DbtTransformationCreateService) request() *dbtTransformationCreateRequest { - var schedule *dbtTransformationScheduleRequest + var schedule interface{} if s.schedule != nil { - schedule = s.schedule.request() + schedule = s.schedule.Request() } return &dbtTransformationCreateRequest{ @@ -45,7 +48,7 @@ func (s *DbtTransformationCreateService) DbtModelId(value string) *DbtTransforma return s } -func (s *DbtTransformationCreateService) Schedule(value *DbtTransformationSchedule) *DbtTransformationCreateService { +func (s *DbtTransformationCreateService) Schedule(value *dbt.DbtTransformationSchedule) *DbtTransformationCreateService { s.schedule = value return s } @@ -60,8 +63,8 @@ func (s *DbtTransformationCreateService) Paused(value bool) *DbtTransformationCr return s } -func (s *DbtTransformationCreateService) Do(ctx context.Context) (DbtTransformationResponse, error) { - var response DbtTransformationResponse +func (s *DbtTransformationCreateService) Do(ctx context.Context) (dbt.DbtTransformationResponse, error) { + var response dbt.DbtTransformationResponse url := fmt.Sprintf("%v/dbt/transformations", s.c.baseURL) expectedStatus := 201 @@ -73,18 +76,18 @@ func (s *DbtTransformationCreateService) Do(ctx context.Context) (DbtTransformat return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_transformation_create_test.go b/dbt_transformation_create_test.go index 900b2169..4a1c8272 100644 --- a/dbt_transformation_create_test.go +++ b/dbt_transformation_create_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) const ( @@ -15,7 +16,7 @@ const ( func TestNewDbtTransformationCreateE2E(t *testing.T) { t.Skip("Skipping test until we get more info on dbt transformations data which can be used for testing") - created, err := Client.NewDbtTransformationCreateService(). + created, err := testutils.Client.NewDbtTransformationCreateService(). DbtModelId(dbtModelId). Schedule(fivetran.NewDbtTransformationSchedule(). ScheduleType("INTEGRATED"). @@ -31,28 +32,28 @@ func TestNewDbtTransformationCreateE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertNotEmpty(t, created.Data.ID) + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertNotEmpty(t, created.Data.ID) // check managable fields - AssertEmpty(t, created.Data.Schedule.DaysOfWeek) - AssertEqual(t, created.Data.DbtModelId, dbtModelId) - AssertEqual(t, created.Data.Schedule.Interval, 0) - AssertEqual(t, created.Data.Schedule.ScheduleType, "INTEGRATED") - AssertEqual(t, created.Data.Schedule.TimeOfDay, "") - AssertEqual(t, created.Data.RunTests, true) - AssertEqual(t, created.Data.Paused, true) + testutils.AssertEmpty(t, created.Data.Schedule.DaysOfWeek) + testutils.AssertEqual(t, created.Data.DbtModelId, dbtModelId) + testutils.AssertEqual(t, created.Data.Schedule.Interval, 0) + testutils.AssertEqual(t, created.Data.Schedule.ScheduleType, "INTEGRATED") + testutils.AssertEqual(t, created.Data.Schedule.TimeOfDay, "") + testutils.AssertEqual(t, created.Data.RunTests, true) + testutils.AssertEqual(t, created.Data.Paused, true) // check readonly fields - AssertEqual(t, created.Data.Status, "PAUSED") - AssertNotEmpty(t, created.Data.CreatedAt) - AssertEmpty(t, created.Data.LastRun) - AssertNotEmpty(t, created.Data.OutputModelName) - AssertEqual(t, created.Data.DbtProjectId, dbtProjectId) - AssertNotEmpty(t, created.Data.NextRun) - AssertNotEmpty(t, created.Data.ModelIds) - AssertEmpty(t, created.Data.ConnectorIds) - - t.Cleanup(func() { DeleteDbtTransformation(t, created.Data.ID) }) + testutils.AssertEqual(t, created.Data.Status, "PAUSED") + testutils.AssertNotEmpty(t, created.Data.CreatedAt) + testutils.AssertEmpty(t, created.Data.LastRun) + testutils.AssertNotEmpty(t, created.Data.OutputModelName) + testutils.AssertEqual(t, created.Data.DbtProjectId, dbtProjectId) + testutils.AssertNotEmpty(t, created.Data.NextRun) + testutils.AssertNotEmpty(t, created.Data.ModelIds) + testutils.AssertEmpty(t, created.Data.ConnectorIds) + + t.Cleanup(func() { testutils.DeleteDbtTransformation(t, created.Data.ID) }) } diff --git a/dbt_transformation_delete.go b/dbt_transformation_delete.go index 0eb82f95..d33a2533 100644 --- a/dbt_transformation_delete.go +++ b/dbt_transformation_delete.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtTransformationDeleteService struct { @@ -11,11 +14,6 @@ type DbtTransformationDeleteService struct { transformationId *string } -type DbtTransformationDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewDbtTransformationDeleteService() *DbtTransformationDeleteService { return &DbtTransformationDeleteService{c: c} } @@ -25,8 +23,8 @@ func (s *DbtTransformationDeleteService) TransformationId(value string) *DbtTran return s } -func (s *DbtTransformationDeleteService) Do(ctx context.Context) (DbtTransformationDeleteResponse, error) { - var response DbtTransformationDeleteResponse +func (s *DbtTransformationDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.transformationId == nil { return response, fmt.Errorf("missing required transformation id") @@ -37,18 +35,18 @@ func (s *DbtTransformationDeleteService) Do(ctx context.Context) (DbtTransformat headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_transformation_delete_test.go b/dbt_transformation_delete_test.go index d2e7eaab..7cb89bae 100644 --- a/dbt_transformation_delete_test.go +++ b/dbt_transformation_delete_test.go @@ -4,13 +4,15 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDbtTransformationDeleteE2E(t *testing.T) { t.Skip("Skipping test until we get more info on dbt transformations data which can be used for testing") - dbtTransformationId := CreateDbtTransformation(t) - deleted, err := Client.NewDestinationDelete(). + dbtTransformationId := testutils.CreateDbtTransformation(t) + deleted, err := testutils.Client.NewDestinationDelete(). DestinationID(dbtTransformationId). Do(context.Background()) @@ -19,7 +21,7 @@ func TestNewDbtTransformationDeleteE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, dbtTransformationId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, dbtTransformationId), true) } diff --git a/dbt_transformation_details.go b/dbt_transformation_details.go index 6bba23a0..47736ade 100644 --- a/dbt_transformation_details.go +++ b/dbt_transformation_details.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtTransformationDetailsService struct { @@ -11,26 +14,6 @@ type DbtTransformationDetailsService struct { transformationId *string } -type DbtTransformationResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - Status string `json:"status"` - Schedule DbtTransformationScheduleResponse `json:"schedule"` - LastRun string `json:"last_run"` - OutputModelName string `json:"output_model_name"` - DbtProjectId string `json:"dbt_project_id"` - DbtModelId string `json:"dbt_model_id"` - NextRun string `json:"next_run"` - CreatedAt string `json:"created_at"` - ModelIds []string `json:"model_ids"` - ConnectorIds []string `json:"connector_ids"` - RunTests bool `json:"run_tests"` - Paused bool `json:"paused"` - } `json:"data"` -} - func (c *Client) NewDbtTransformationDetailsService() *DbtTransformationDetailsService { return &DbtTransformationDetailsService{c: c} } @@ -40,8 +23,8 @@ func (s *DbtTransformationDetailsService) TransformationId(value string) *DbtTra return s } -func (s *DbtTransformationDetailsService) Do(ctx context.Context) (DbtTransformationResponse, error) { - var response DbtTransformationResponse +func (s *DbtTransformationDetailsService) Do(ctx context.Context) (dbt.DbtTransformationResponse, error) { + var response dbt.DbtTransformationResponse if s.transformationId == nil { return response, fmt.Errorf("missing required transformation id") @@ -52,18 +35,18 @@ func (s *DbtTransformationDetailsService) Do(ctx context.Context) (DbtTransforma headers := s.c.commonHeaders() - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_transformation_details_test.go b/dbt_transformation_details_test.go index be8e6895..611230a3 100644 --- a/dbt_transformation_details_test.go +++ b/dbt_transformation_details_test.go @@ -3,14 +3,16 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDbtTransformationDetailsE2E(t *testing.T) { t.Skip("Skipping test until we get more info on dbt transformations data which can be used for testing") - dbtTransformationId := CreateTempDbtTransformation(t) + dbtTransformationId := testutils.CreateTempDbtTransformation(t) - details, err := Client.NewDbtTransformationDetailsService(). + details, err := testutils.Client.NewDbtTransformationDetailsService(). TransformationId(dbtTransformationId). Do(context.Background()) @@ -19,19 +21,19 @@ func TestNewDbtTransformationDetailsE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, details.Code, "Success") - AssertNotEmpty(t, details.Data.ID) - AssertEqual(t, details.Data.Status, "PAUSED") - AssertEmpty(t, details.Data.Schedule.DaysOfWeek) - AssertEqual(t, details.Data.Schedule.Interval, 0) - AssertEqual(t, details.Data.Schedule.ScheduleType, "INTEGRATED") - AssertEmpty(t, details.Data.Schedule.TimeOfDay) - AssertEmpty(t, details.Data.LastRun) - AssertNotEmpty(t, details.Data.OutputModelName) - AssertNotEmpty(t, details.Data.DbtProjectId) - AssertNotEmpty(t, details.Data.DbtModelId) - AssertNotEmpty(t, details.Data.NextRun) - AssertNotEmpty(t, details.Data.CreatedAt) - AssertNotEmpty(t, details.Data.ModelIds) - AssertEmpty(t, details.Data.ConnectorIds) + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Data.ID) + testutils.AssertEqual(t, details.Data.Status, "PAUSED") + testutils.AssertEmpty(t, details.Data.Schedule.DaysOfWeek) + testutils.AssertEqual(t, details.Data.Schedule.Interval, 0) + testutils.AssertEqual(t, details.Data.Schedule.ScheduleType, "INTEGRATED") + testutils.AssertEmpty(t, details.Data.Schedule.TimeOfDay) + testutils.AssertEmpty(t, details.Data.LastRun) + testutils.AssertNotEmpty(t, details.Data.OutputModelName) + testutils.AssertNotEmpty(t, details.Data.DbtProjectId) + testutils.AssertNotEmpty(t, details.Data.DbtModelId) + testutils.AssertNotEmpty(t, details.Data.NextRun) + testutils.AssertNotEmpty(t, details.Data.CreatedAt) + testutils.AssertNotEmpty(t, details.Data.ModelIds) + testutils.AssertEmpty(t, details.Data.ConnectorIds) } diff --git a/dbt_transformation_modify.go b/dbt_transformation_modify.go index a1086a8e..bfad549a 100644 --- a/dbt_transformation_modify.go +++ b/dbt_transformation_modify.go @@ -4,20 +4,23 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/dbt" + httputils "github.com/fivetran/go-fivetran/http_utils" ) type DbtTransformationModifyService struct { c *Client dbtTransformationId *string - schedule *DbtTransformationSchedule + schedule *dbt.DbtTransformationSchedule runTests *bool paused *bool } type dbtTransformationModifyRequest struct { - Schedule *dbtTransformationScheduleRequest `json:"schedule,omitempty"` - RunTests *bool `json:"run_tests,omitempty"` - Paused *bool `json:"paused,omitempty"` + Schedule any `json:"schedule,omitempty"` + RunTests *bool `json:"run_tests,omitempty"` + Paused *bool `json:"paused,omitempty"` } func (c *Client) NewDbtTransformationModifyService() *DbtTransformationModifyService { @@ -25,10 +28,10 @@ func (c *Client) NewDbtTransformationModifyService() *DbtTransformationModifySer } func (s *DbtTransformationModifyService) request() *dbtTransformationModifyRequest { - var schedule *dbtTransformationScheduleRequest + var schedule interface{} if s.schedule != nil { - schedule = s.schedule.request() + schedule = s.schedule.Request() } return &dbtTransformationModifyRequest{ @@ -43,7 +46,7 @@ func (s *DbtTransformationModifyService) DbtTransformationId(value string) *DbtT return s } -func (s *DbtTransformationModifyService) Schedule(value *DbtTransformationSchedule) *DbtTransformationModifyService { +func (s *DbtTransformationModifyService) Schedule(value *dbt.DbtTransformationSchedule) *DbtTransformationModifyService { s.schedule = value return s } @@ -58,8 +61,8 @@ func (s *DbtTransformationModifyService) Paused(value bool) *DbtTransformationMo return s } -func (s *DbtTransformationModifyService) Do(ctx context.Context) (DbtTransformationResponse, error) { - var response DbtTransformationResponse +func (s *DbtTransformationModifyService) Do(ctx context.Context) (dbt.DbtTransformationResponse, error) { + var response dbt.DbtTransformationResponse if s.dbtTransformationId == nil { return response, fmt.Errorf("missing required dbt transformation ID") @@ -76,18 +79,18 @@ func (s *DbtTransformationModifyService) Do(ctx context.Context) (DbtTransformat return response, err } - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/dbt_transformation_modify_test.go b/dbt_transformation_modify_test.go index f90a5e19..0c534a68 100644 --- a/dbt_transformation_modify_test.go +++ b/dbt_transformation_modify_test.go @@ -5,13 +5,14 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDbtTransformationModifyE2E(t *testing.T) { t.Skip("Skipping test until we get more info on dbt transformations data which can be used for testing") - dbtTransformationId := CreateTempDbtTransformation(t) - details, err := Client.NewDbtTransformationModifyService(). + dbtTransformationId := testutils.CreateTempDbtTransformation(t) + details, err := testutils.Client.NewDbtTransformationModifyService(). DbtTransformationId(dbtTransformationId). Schedule(fivetran.NewDbtTransformationSchedule(). ScheduleType("INTEGRATED"). @@ -27,20 +28,20 @@ func TestNewDbtTransformationModifyE2E(t *testing.T) { } // These checks are inconsistent currently, will update it when enable the test - AssertEqual(t, details.Code, "Success") - AssertNotEmpty(t, details.Message) - AssertNotEmpty(t, details.Data.ID) - AssertEqual(t, details.Data.Status, "") - AssertEmpty(t, details.Data.Schedule.DaysOfWeek) - AssertEqual(t, details.Data.Schedule.Interval, "") - AssertEqual(t, details.Data.Schedule.ScheduleType, "") - AssertEqual(t, details.Data.Schedule.TimeOfDay, "") - AssertEqual(t, details.Data.LastRun, "") - AssertEqual(t, details.Data.OutputModelName, "") - AssertEqual(t, details.Data.DbtProjectId, "") - AssertEqual(t, details.Data.DbtModelId, "") - AssertEqual(t, details.Data.NextRun, "") - AssertEqual(t, details.Data.CreatedAt, "") - AssertNotEmpty(t, details.Data.ModelIds) - AssertEmpty(t, details.Data.ConnectorIds) + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Message) + testutils.AssertNotEmpty(t, details.Data.ID) + testutils.AssertEqual(t, details.Data.Status, "") + testutils.AssertEmpty(t, details.Data.Schedule.DaysOfWeek) + testutils.AssertEqual(t, details.Data.Schedule.Interval, "") + testutils.AssertEqual(t, details.Data.Schedule.ScheduleType, "") + testutils.AssertEqual(t, details.Data.Schedule.TimeOfDay, "") + testutils.AssertEqual(t, details.Data.LastRun, "") + testutils.AssertEqual(t, details.Data.OutputModelName, "") + testutils.AssertEqual(t, details.Data.DbtProjectId, "") + testutils.AssertEqual(t, details.Data.DbtModelId, "") + testutils.AssertEqual(t, details.Data.NextRun, "") + testutils.AssertEqual(t, details.Data.CreatedAt, "") + testutils.AssertNotEmpty(t, details.Data.ModelIds) + testutils.AssertEmpty(t, details.Data.ConnectorIds) } diff --git a/destination_create.go b/destination_create.go index 900a5467..710dad1c 100644 --- a/destination_create.go +++ b/destination_create.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/destinations" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // DestinationCreateService implements the Destination Management, Create a Destination API. @@ -14,40 +17,21 @@ type DestinationCreateService struct { service *string region *string timeZoneOffset *string - config *DestinationConfig + config *destinations.DestinationConfig trustCertificates *bool trustFingerprints *bool runSetupTests *bool } type destinationCreateRequest struct { - GroupID *string `json:"group_id,omitempty"` - Service *string `json:"service,omitempty"` - Region *string `json:"region,omitempty"` - TimeZoneOffset *string `json:"time_zone_offset,omitempty"` - Config *destinationConfigRequest `json:"config,omitempty"` - TrustCertificates *bool `json:"trust_certificates,omitempty"` - TrustFingerprints *bool `json:"trust_fingerprints,omitempty"` - RunSetupTests *bool `json:"run_setup_tests,omitempty"` -} - -type DestinationCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - Region string `json:"region"` - TimeZoneOffset string `json:"time_zone_offset"` - SetupStatus string `json:"setup_status"` - SetupTests []struct { - Title string `json:"title"` - Status string `json:"status"` - Message string `json:"message"` - } `json:"setup_tests"` - Config DestinationConfigResponse `json:"config"` - } `json:"data"` + GroupID *string `json:"group_id,omitempty"` + Service *string `json:"service,omitempty"` + Region *string `json:"region,omitempty"` + TimeZoneOffset *string `json:"time_zone_offset,omitempty"` + Config any `json:"config,omitempty"` + TrustCertificates *bool `json:"trust_certificates,omitempty"` + TrustFingerprints *bool `json:"trust_fingerprints,omitempty"` + RunSetupTests *bool `json:"run_setup_tests,omitempty"` } func (c *Client) NewDestinationCreate() *DestinationCreateService { @@ -55,10 +39,9 @@ func (c *Client) NewDestinationCreate() *DestinationCreateService { } func (s *DestinationCreateService) request() *destinationCreateRequest { - var config *destinationConfigRequest - + var config interface{} if s.config != nil { - config = s.config.request() + config = s.config.Request() } return &destinationCreateRequest{ @@ -93,7 +76,7 @@ func (s *DestinationCreateService) TimeZoneOffset(value string) *DestinationCrea return s } -func (s *DestinationCreateService) Config(value *DestinationConfig) *DestinationCreateService { +func (s *DestinationCreateService) Config(value *destinations.DestinationConfig) *DestinationCreateService { s.config = value return s } @@ -113,8 +96,8 @@ func (s *DestinationCreateService) RunSetupTests(value bool) *DestinationCreateS return s } -func (s *DestinationCreateService) Do(ctx context.Context) (DestinationCreateResponse, error) { - var response DestinationCreateResponse +func (s *DestinationCreateService) Do(ctx context.Context) (destinations.DestinationDetailsWithSetupTestsResponse, error) { + var response destinations.DestinationDetailsWithSetupTestsResponse url := fmt.Sprintf("%v/destinations", s.c.baseURL) expectedStatus := 201 @@ -127,18 +110,18 @@ func (s *DestinationCreateService) Do(ctx context.Context) (DestinationCreateRes return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/destination_create_test.go b/destination_create_test.go index 93c215ff..89af2980 100644 --- a/destination_create_test.go +++ b/destination_create_test.go @@ -5,11 +5,12 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDestinationCreateE2E(t *testing.T) { - created, err := Client.NewDestinationCreate(). - GroupID(PredefinedGroupId). + created, err := testutils.Client.NewDestinationCreate(). + GroupID(testutils.PredefinedGroupId). Service("snowflake"). TimeZoneOffset("+10"). RunSetupTests(false). @@ -27,19 +28,19 @@ func TestNewDestinationCreateE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertEqual(t, created.Data.ID, PredefinedGroupId) - AssertEqual(t, created.Data.Service, "snowflake") - AssertEqual(t, created.Data.Region, "GCP_US_EAST4") - AssertEqual(t, created.Data.TimeZoneOffset, "+10") - AssertEqual(t, created.Data.SetupStatus, "incomplete") - AssertEqual(t, created.Data.Config.Host, "your-account.snowflakecomputing.com") - AssertEqual(t, created.Data.Config.Port, "443") - AssertEqual(t, created.Data.Config.Database, "fivetran") - AssertEqual(t, created.Data.Config.Auth, "PASSWORD") - AssertEqual(t, created.Data.Config.User, "fivetran_user") - AssertEqual(t, created.Data.Config.Password, "******") + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertEqual(t, created.Data.ID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, created.Data.Service, "snowflake") + testutils.AssertEqual(t, created.Data.Region, "GCP_US_EAST4") + testutils.AssertEqual(t, created.Data.TimeZoneOffset, "+10") + testutils.AssertEqual(t, created.Data.SetupStatus, "incomplete") + testutils.AssertEqual(t, created.Data.Config.Host, "your-account.snowflakecomputing.com") + testutils.AssertEqual(t, created.Data.Config.Port, "443") + testutils.AssertEqual(t, created.Data.Config.Database, "fivetran") + testutils.AssertEqual(t, created.Data.Config.Auth, "PASSWORD") + testutils.AssertEqual(t, created.Data.Config.User, "fivetran_user") + testutils.AssertEqual(t, created.Data.Config.Password, "******") - t.Cleanup(func() { DeleteDestination(t, PredefinedGroupId) }) + t.Cleanup(func() { testutils.DeleteDestination(t, testutils.PredefinedGroupId) }) } diff --git a/destination_delete.go b/destination_delete.go index 11393e43..1ed21349 100644 --- a/destination_delete.go +++ b/destination_delete.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // DestinationDeleteService implements the Destination Management, Delete a destination API. @@ -13,11 +16,6 @@ type DestinationDeleteService struct { destinationID *string } -type DestinationDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewDestinationDelete() *DestinationDeleteService { return &DestinationDeleteService{c: c} } @@ -27,8 +25,8 @@ func (s *DestinationDeleteService) DestinationID(value string) *DestinationDelet return s } -func (s *DestinationDeleteService) Do(ctx context.Context) (DestinationDeleteResponse, error) { - var response DestinationDeleteResponse +func (s *DestinationDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.destinationID == nil { return response, fmt.Errorf("missing required DestinationID") @@ -39,18 +37,18 @@ func (s *DestinationDeleteService) Do(ctx context.Context) (DestinationDeleteRes headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/destination_delete_test.go b/destination_delete_test.go index 47604b88..96010edf 100644 --- a/destination_delete_test.go +++ b/destination_delete_test.go @@ -4,18 +4,20 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDestinationDeleteE2E(t *testing.T) { - destinationId := CreateDestination(t) - deleted, err := Client.NewDestinationDelete().DestinationID(destinationId).Do(context.Background()) + destinationId := testutils.CreateDestination(t) + deleted, err := testutils.Client.NewDestinationDelete().DestinationID(destinationId).Do(context.Background()) if err != nil { t.Logf("%+v\n", deleted) t.Error(err) } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, destinationId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, destinationId), true) } diff --git a/destination_details.go b/destination_details.go index f21df31e..e0e252a0 100644 --- a/destination_details.go +++ b/destination_details.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/destinations" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // DestinationDetailsService implements the Destination Management, Retrieve destination details API. @@ -13,20 +16,6 @@ type DestinationDetailsService struct { destinationID *string } -type DestinationDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - Region string `json:"region"` - TimeZoneOffset string `json:"time_zone_offset"` - SetupStatus string `json:"setup_status"` - Config DestinationConfigResponse `json:"config"` - } `json:"data"` -} - func (c *Client) NewDestinationDetails() *DestinationDetailsService { return &DestinationDetailsService{c: c} } @@ -36,8 +25,8 @@ func (s *DestinationDetailsService) DestinationID(value string) *DestinationDeta return s } -func (s *DestinationDetailsService) Do(ctx context.Context) (DestinationDetailsResponse, error) { - var response DestinationDetailsResponse +func (s *DestinationDetailsService) Do(ctx context.Context) (destinations.DestinationDetailsResponse, error) { + var response destinations.DestinationDetailsResponse if s.destinationID == nil { return response, fmt.Errorf("missing required DestinationID") @@ -49,18 +38,18 @@ func (s *DestinationDetailsService) Do(ctx context.Context) (DestinationDetailsR headers := s.c.commonHeaders() headers["Accept"] = restAPIv2 - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/destination_details_test.go b/destination_details_test.go index 7463761d..1da747df 100644 --- a/destination_details_test.go +++ b/destination_details_test.go @@ -3,28 +3,30 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDestinationDetailsE2E(t *testing.T) { - destinationId := CreateTempDestination(t) + destinationId := testutils.CreateTempDestination(t) - details, err := Client.NewDestinationDetails().DestinationID(destinationId).Do(context.Background()) + details, err := testutils.Client.NewDestinationDetails().DestinationID(destinationId).Do(context.Background()) if err != nil { t.Logf("%+v\n", details) t.Error(err) } - AssertEqual(t, details.Code, "Success") - AssertEqual(t, details.Data.ID, PredefinedGroupId) - AssertEqual(t, details.Data.GroupID, PredefinedGroupId) - AssertEqual(t, details.Data.Service, "snowflake") - AssertEqual(t, details.Data.Region, "GCP_US_EAST4") - AssertEqual(t, details.Data.TimeZoneOffset, "+10") - AssertEqual(t, details.Data.SetupStatus, "incomplete") - AssertEqual(t, details.Data.Config.Database, "fivetran") - AssertEqual(t, details.Data.Config.Password, "******") - AssertEqual(t, details.Data.Config.Port, "443") - AssertEqual(t, details.Data.Config.Host, "your-account.snowflakecomputing.com") - AssertEqual(t, details.Data.Config.User, "fivetran_user") + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertEqual(t, details.Data.ID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, details.Data.GroupID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, details.Data.Service, "snowflake") + testutils.AssertEqual(t, details.Data.Region, "GCP_US_EAST4") + testutils.AssertEqual(t, details.Data.TimeZoneOffset, "+10") + testutils.AssertEqual(t, details.Data.SetupStatus, "incomplete") + testutils.AssertEqual(t, details.Data.Config.Database, "fivetran") + testutils.AssertEqual(t, details.Data.Config.Password, "******") + testutils.AssertEqual(t, details.Data.Config.Port, "443") + testutils.AssertEqual(t, details.Data.Config.Host, "your-account.snowflakecomputing.com") + testutils.AssertEqual(t, details.Data.Config.User, "fivetran_user") } diff --git a/destination_modify.go b/destination_modify.go index 1b89a1bd..cfef1fc8 100644 --- a/destination_modify.go +++ b/destination_modify.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/destinations" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // DestinationModifyService implements the Destination Management, Modify a Destination API. @@ -13,38 +16,19 @@ type DestinationModifyService struct { destinationID *string region *string timeZoneOffset *string - config *DestinationConfig + config *destinations.DestinationConfig trustCertificates *bool trustFingerprints *bool runSetupTests *bool } type destinationModifyRequest struct { - Region *string `json:"region,omitempty"` - TimeZoneOffset *string `json:"time_zone_offset,omitempty"` - Config *destinationConfigRequest `json:"config,omitempty"` - TrustCertificates *bool `json:"trust_certificates,omitempty"` - TrustFingerprints *bool `json:"trust_fingerprints,omitempty"` - RunSetupTests *bool `json:"run_setup_tests,omitempty"` -} - -type DestinationModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - Region string `json:"region"` - TimeZoneOffset string `json:"time_zone_offset"` - SetupStatus string `json:"setup_status"` - SetupTests []struct { - Title string `json:"title"` - Status string `json:"status"` - Message string `json:"message"` - } `json:"setup_tests"` - Config DestinationConfigResponse `json:"config"` - } `json:"data"` + Region *string `json:"region,omitempty"` + TimeZoneOffset *string `json:"time_zone_offset,omitempty"` + Config any `json:"config,omitempty"` + TrustCertificates *bool `json:"trust_certificates,omitempty"` + TrustFingerprints *bool `json:"trust_fingerprints,omitempty"` + RunSetupTests *bool `json:"run_setup_tests,omitempty"` } func (c *Client) NewDestinationModify() *DestinationModifyService { @@ -52,10 +36,10 @@ func (c *Client) NewDestinationModify() *DestinationModifyService { } func (s *DestinationModifyService) request() *destinationModifyRequest { - var config *destinationConfigRequest + var config interface{} if s.config != nil { - config = s.config.request() + config = s.config.Request() } return &destinationModifyRequest{ @@ -83,7 +67,7 @@ func (s *DestinationModifyService) TimeZoneOffset(value string) *DestinationModi return s } -func (s *DestinationModifyService) Config(value *DestinationConfig) *DestinationModifyService { +func (s *DestinationModifyService) Config(value *destinations.DestinationConfig) *DestinationModifyService { s.config = value return s } @@ -103,8 +87,8 @@ func (s *DestinationModifyService) RunSetupTests(value bool) *DestinationModifyS return s } -func (s *DestinationModifyService) Do(ctx context.Context) (DestinationModifyResponse, error) { - var response DestinationModifyResponse +func (s *DestinationModifyService) Do(ctx context.Context) (destinations.DestinationDetailsWithSetupTestsResponse, error) { + var response destinations.DestinationDetailsWithSetupTestsResponse if s.destinationID == nil { return response, fmt.Errorf("missing required DestinationID") @@ -122,18 +106,18 @@ func (s *DestinationModifyService) Do(ctx context.Context) (DestinationModifyRes return response, err } - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/destination_modify_test.go b/destination_modify_test.go index 0cd9c472..67b7a040 100644 --- a/destination_modify_test.go +++ b/destination_modify_test.go @@ -5,11 +5,12 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDestinationModifyE2E(t *testing.T) { - destinationId := CreateTempDestination(t) - details, err := Client.NewDestinationModify().DestinationID(destinationId). + destinationId := testutils.CreateTempDestination(t) + details, err := testutils.Client.NewDestinationModify().DestinationID(destinationId). Region("GCP_AUSTRALIA_SOUTHEAST1"). TimeZoneOffset("+10"). RunSetupTests(false). @@ -27,16 +28,16 @@ func TestNewDestinationModifyE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, details.Code, "Success") - AssertNotEmpty(t, details.Message) - AssertEqual(t, details.Data.ID, destinationId) - AssertEqual(t, details.Data.GroupID, destinationId) - AssertEqual(t, details.Data.Service, "snowflake") - AssertEqual(t, details.Data.Region, "GCP_AUSTRALIA_SOUTHEAST1") - AssertEqual(t, details.Data.TimeZoneOffset, "+10") - AssertEqual(t, details.Data.Config.Host, "updated_host.snowflakecomputing.com") - AssertEqual(t, details.Data.Config.Port, "444") - AssertEqual(t, details.Data.Config.Database, "fivetran_updated") - AssertEqual(t, details.Data.Config.User, "fivetran_user_updated") - AssertEqual(t, details.Data.Config.Password, "******") + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Message) + testutils.AssertEqual(t, details.Data.ID, destinationId) + testutils.AssertEqual(t, details.Data.GroupID, destinationId) + testutils.AssertEqual(t, details.Data.Service, "snowflake") + testutils.AssertEqual(t, details.Data.Region, "GCP_AUSTRALIA_SOUTHEAST1") + testutils.AssertEqual(t, details.Data.TimeZoneOffset, "+10") + testutils.AssertEqual(t, details.Data.Config.Host, "updated_host.snowflakecomputing.com") + testutils.AssertEqual(t, details.Data.Config.Port, "444") + testutils.AssertEqual(t, details.Data.Config.Database, "fivetran_updated") + testutils.AssertEqual(t, details.Data.Config.User, "fivetran_user_updated") + testutils.AssertEqual(t, details.Data.Config.Password, "******") } diff --git a/destination_setup_tests.go b/destination_setup_tests.go index c92c6d50..8d5384f4 100644 --- a/destination_setup_tests.go +++ b/destination_setup_tests.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/destinations" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // DestinationSetupTestsService implements the Destination Management, Run destination setup tests API. @@ -20,25 +23,6 @@ type destinationSetupTestsRequest struct { TrustFingerprints *bool `json:"trust_fingerprints,omitempty"` } -type DestinationSetupTestsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - Region string `json:"region"` - TimeZoneOffset string `json:"time_zone_offset"` - SetupStatus string `json:"setup_status"` - SetupTests []struct { - Title string `json:"title"` - Status string `json:"status"` - Message string `json:"message"` - } `json:"setup_tests"` - Config DestinationConfigResponse `json:"config"` - } `json:"data"` -} - func (c *Client) NewDestinationSetupTests() *DestinationSetupTestsService { return &DestinationSetupTestsService{c: c} } @@ -65,8 +49,8 @@ func (s *DestinationSetupTestsService) TrustFingerprints(value bool) *Destinatio return s } -func (s *DestinationSetupTestsService) Do(ctx context.Context) (DestinationSetupTestsResponse, error) { - var response DestinationSetupTestsResponse +func (s *DestinationSetupTestsService) Do(ctx context.Context) (destinations.DestinationDetailsWithSetupTestsResponse, error) { + var response destinations.DestinationDetailsWithSetupTestsResponse if s.destinationID == nil { return response, fmt.Errorf("missing required DestinationID") @@ -84,18 +68,18 @@ func (s *DestinationSetupTestsService) Do(ctx context.Context) (DestinationSetup return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/destination_setup_tests_test.go b/destination_setup_tests_test.go index 501668bd..4a43164f 100644 --- a/destination_setup_tests_test.go +++ b/destination_setup_tests_test.go @@ -3,11 +3,13 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewDestinationSetupTestsE2E(t *testing.T) { - destinationId := CreateTempDestination(t) - response, err := Client.NewDestinationSetupTests().DestinationID(destinationId). + destinationId := testutils.CreateTempDestination(t) + response, err := testutils.Client.NewDestinationSetupTests().DestinationID(destinationId). TrustCertificates(true). TrustFingerprints(true). Do(context.Background()) @@ -17,12 +19,12 @@ func TestNewDestinationSetupTestsE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, response.Code, "Success") - AssertNotEmpty(t, response.Message) - AssertEqual(t, response.Data.ID, destinationId) - AssertEqual(t, response.Data.GroupID, destinationId) - AssertEqual(t, response.Data.Service, "snowflake") - AssertEqual(t, response.Data.Region, "GCP_US_EAST4") - AssertEqual(t, response.Data.TimeZoneOffset, "+10") - AssertEqual(t, response.Data.SetupStatus, "incomplete") + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertNotEmpty(t, response.Message) + testutils.AssertEqual(t, response.Data.ID, destinationId) + testutils.AssertEqual(t, response.Data.GroupID, destinationId) + testutils.AssertEqual(t, response.Data.Service, "snowflake") + testutils.AssertEqual(t, response.Data.Region, "GCP_US_EAST4") + testutils.AssertEqual(t, response.Data.TimeZoneOffset, "+10") + testutils.AssertEqual(t, response.Data.SetupStatus, "incomplete") } diff --git a/destinations/common_types.go b/destinations/common_types.go new file mode 100644 index 00000000..438a50f2 --- /dev/null +++ b/destinations/common_types.go @@ -0,0 +1,27 @@ +package destinations + +import "github.com/fivetran/go-fivetran/common" + +type DestinationDetailsBase struct { + ID string `json:"id"` + GroupID string `json:"group_id"` + Service string `json:"service"` + Region string `json:"region"` + TimeZoneOffset string `json:"time_zone_offset"` + SetupStatus string `json:"setup_status"` + Config DestinationConfigResponse `json:"config"` +} + +type DestinationDetailsWithSetupTestsResponse struct { + common.CommonResponse + Data struct { + DestinationDetailsBase + SetupTests []common.SetupTestResponse `json:"setup_tests"` + } `json:"data"` +} + +type DestinationDetailsResponse struct { + Code string `json:"code"` + Message string `json:"message"` + Data DestinationDetailsBase `json:"data"` +} diff --git a/destination_config.go b/destinations/destination_config.go similarity index 98% rename from destination_config.go rename to destinations/destination_config.go index 48a192e3..6c6a48de 100644 --- a/destination_config.go +++ b/destinations/destination_config.go @@ -1,4 +1,4 @@ -package fivetran +package destinations // DestinationConfig builds Destination Management, Destination Config. // Ref. https://fivetran.com/docs/rest-api/destinations/config @@ -106,11 +106,7 @@ type DestinationConfigResponse struct { Region string `json:"region"` } -func NewDestinationConfig() *DestinationConfig { - return &DestinationConfig{} -} - -func (dc *DestinationConfig) request() *destinationConfigRequest { +func (dc *DestinationConfig) Request() *destinationConfigRequest { return &destinationConfigRequest{ Host: dc.host, Port: dc.port, diff --git a/examples/connectorCreate-2/main.go b/examples/connectorCreate-2/main.go index fcea5fee..95066a57 100644 --- a/examples/connectorCreate-2/main.go +++ b/examples/connectorCreate-2/main.go @@ -7,6 +7,7 @@ import ( "os" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/connectors" ) func main() { @@ -21,19 +22,19 @@ func main() { connConfigReport := fivetran.NewConnectorConfigReports().ConfigType("cType1").Filter("filter1") connConfigReport2 := fivetran.NewConnectorConfigReports().ConfigType("cType2") - connConfig.Reports([]*fivetran.ConnectorConfigReports{connConfigReport, connConfigReport2}) + connConfig.Reports([]*connectors.ConnectorConfigReports{connConfigReport, connConfigReport2}) pCred1 := fivetran.NewConnectorConfigProjectCredentials().APIKey("myApiKEY1").Project("myProject1") pCred2 := fivetran.NewConnectorConfigProjectCredentials().APIKey("myApiKEY2").Project("myProject2").SecretKey("TheSecretKEY2") pCred3 := fivetran.NewConnectorConfigProjectCredentials().APIKey("myApiKEY3").Project("myProject3").SecretKey("YASK3") - connConfig.ProjectCredentials([]*fivetran.ConnectorConfigProjectCredentials{pCred1, pCred2, pCred3}) + connConfig.ProjectCredentials([]*connectors.ConnectorConfigProjectCredentials{pCred1, pCred2, pCred3}) cTables1 := fivetran.NewConnectorConfigCustomTables().Aggregation("aggregation1").TableName("TableNAME1") cTables2 := fivetran.NewConnectorConfigCustomTables().TableName("TableNAME2") - connConfig.CustomTables([]*fivetran.ConnectorConfigCustomTables{cTables1, cTables2}) + connConfig.CustomTables([]*connectors.ConnectorConfigCustomTables{cTables1, cTables2}) adobeAnalyticsConfig1 := fivetran.NewConnectorConfigAdobeAnalyticsConfiguration().SyncMode("syncMode").Elements([]string{"elemet1", "element2"}) - connConfig.AdobeAnalyticsConfigurations([]*fivetran.ConnectorConfigAdobeAnalyticsConfiguration{adobeAnalyticsConfig1}) + connConfig.AdobeAnalyticsConfigurations([]*connectors.ConnectorConfigAdobeAnalyticsConfiguration{adobeAnalyticsConfig1}) connConfig.Schema("google_sheets5959"). Table("table"). diff --git a/examples/connectorModify/main.go b/examples/connectorModify/main.go index e0697368..4e63a734 100644 --- a/examples/connectorModify/main.go +++ b/examples/connectorModify/main.go @@ -7,6 +7,7 @@ import ( "os" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/connectors" ) func main() { @@ -23,10 +24,11 @@ func main() { cTables1 := fivetran.NewConnectorConfigCustomTables().Aggregation("aggregation1").TableName("theName") cTables2 := fivetran.NewConnectorConfigCustomTables().TableName("theName").Fields([]string{"FIELD ONE", "FIELD TWO"}) - connConfig.CustomTables([]*fivetran.ConnectorConfigCustomTables{cTables1, cTables2}) + + connConfig.CustomTables([]*connectors.ConnectorConfigCustomTables{cTables1, cTables2}) adobeAnalyticsConfig1 := fivetran.NewConnectorConfigAdobeAnalyticsConfiguration().SyncMode("syncMode").Elements([]string{"elemet1", "element2"}) - connConfig.AdobeAnalyticsConfigurations([]*fivetran.ConnectorConfigAdobeAnalyticsConfiguration{adobeAnalyticsConfig1}) + connConfig.AdobeAnalyticsConfigurations([]*connectors.ConnectorConfigAdobeAnalyticsConfiguration{adobeAnalyticsConfig1}) svc.ConnectorID("grateful_vertices") svc.Paused(true) diff --git a/external_logging/common_types.go b/external_logging/common_types.go new file mode 100644 index 00000000..99e5405e --- /dev/null +++ b/external_logging/common_types.go @@ -0,0 +1,35 @@ +package externallogging + +type ExternalLoggingResponseBase struct { + Id string `json:"id"` + Service string `json:"service"` + Enabled bool `json:"enabled"` +} + +type ExternalLoggingResponse struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ExternalLoggingResponseBase + Config ExternalLoggingConfigResponse `json:"config"` + } `json:"data"` +} + +type ExternalLoggingCustomResponse struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ExternalLoggingResponseBase + Config map[string]interface{} `json:"config"` + } `json:"data"` +} + +type ExternalLoggingCustomMergedResponse struct { + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ExternalLoggingResponseBase + CustomConfig map[string]interface{} `json:"config"` + Config ExternalLoggingConfigResponse // no mapping here + } `json:"data"` +} diff --git a/external_logging/external_logging_config.go b/external_logging/external_logging_config.go new file mode 100644 index 00000000..153c5b2b --- /dev/null +++ b/external_logging/external_logging_config.go @@ -0,0 +1,153 @@ +package externallogging + +import "github.com/fivetran/go-fivetran/utils" + +// ExternalLoggingConfig builds Log Management, Log Config. +// Ref. https://fivetran.com/docs/rest-api/log-service-management#logservicesetupconfigurations +type ExternalLoggingConfig struct { + workspaceId *string + primaryKey *string + logGroupName *string + roleArn *string + externalId *string + region *string + apiKey *string + subDomain *string + host *string + hostname *string + channel *string + enableSsl *bool + token *string + port *int +} + +type externalLoggingConfigRequest struct { + WorkspaceId *string `json:"workspace_id,omitempty"` + PrimaryKey *string `json:"primary_key,omitempty"` + LogGroupName *string `json:"log_group_name,omitempty"` + RoleArn *string `json:"role_arn,omitempty"` + ExternalId *string `json:"external_id,omitempty"` + Region *string `json:"region,omitempty"` + ApiKey *string `json:"api_key,omitempty"` + SubDomain *string `json:"sub_domain,omitempty"` + Host *string `json:"host,omitempty"` + Hostname *string `json:"hostname,omitempty"` + Channel *string `json:"channel,omitempty"` + EnableSsl *bool `json:"enable_ssl,omitempty"` + Token *string `json:"token,omitempty"` + Port *int `json:"port,omitempty"` +} + +type ExternalLoggingConfigResponse struct { + WorkspaceId string `json:"workspace_id"` + PrimaryKey string `json:"primary_key"` + LogGroupName string `json:"log_group_name"` + RoleArn string `json:"role_arn"` + ExternalId string `json:"external_id"` + Region string `json:"region"` + ApiKey string `json:"api_key"` + SubDomain string `json:"sub_domain"` + Host string `json:"host"` + Hostname string `json:"hostname"` + Channel string `json:"channel"` + EnableSsl bool `json:"enable_ssl"` + Token string `json:"token"` + Port int `json:"port"` +} + +func (elc *ExternalLoggingConfig) Request() *externalLoggingConfigRequest { + return &externalLoggingConfigRequest{ + WorkspaceId: elc.workspaceId, + PrimaryKey: elc.primaryKey, + LogGroupName: elc.logGroupName, + RoleArn: elc.roleArn, + ExternalId: elc.externalId, + Region: elc.region, + ApiKey: elc.apiKey, + SubDomain: elc.subDomain, + Host: elc.host, + Hostname: elc.hostname, + Channel: elc.channel, + EnableSsl: elc.enableSsl, + Token: elc.token, + Port: elc.port, + } +} + +func (cc *ExternalLoggingConfig) Merge(customConfig *map[string]interface{}) (*map[string]interface{}, error) { + err := utils.MergeIntoMap(cc.Request(), customConfig) + if err != nil { + return nil, err + } + return customConfig, nil +} + +func (elc *ExternalLoggingConfig) WorkspaceId(value string) *ExternalLoggingConfig { + elc.workspaceId = &value + return elc +} + +func (elc *ExternalLoggingConfig) PrimaryKey(value string) *ExternalLoggingConfig { + elc.primaryKey = &value + return elc +} + +func (elc *ExternalLoggingConfig) LogGroupName(value string) *ExternalLoggingConfig { + elc.logGroupName = &value + return elc +} + +func (elc *ExternalLoggingConfig) RoleArn(value string) *ExternalLoggingConfig { + elc.roleArn = &value + return elc +} + +func (elc *ExternalLoggingConfig) ExternalId(value string) *ExternalLoggingConfig { + elc.externalId = &value + return elc +} + +func (elc *ExternalLoggingConfig) Region(value string) *ExternalLoggingConfig { + elc.region = &value + return elc +} + +func (elc *ExternalLoggingConfig) ApiKey(value string) *ExternalLoggingConfig { + elc.apiKey = &value + return elc +} + +func (elc *ExternalLoggingConfig) SubDomain(value string) *ExternalLoggingConfig { + elc.subDomain = &value + return elc +} + +func (elc *ExternalLoggingConfig) Host(value string) *ExternalLoggingConfig { + elc.host = &value + return elc +} + +func (elc *ExternalLoggingConfig) Hostname(value string) *ExternalLoggingConfig { + elc.hostname = &value + return elc +} + +func (elc *ExternalLoggingConfig) Channel(value string) *ExternalLoggingConfig { + elc.channel = &value + return elc +} + +func (elc *ExternalLoggingConfig) EnableSsl(value bool) *ExternalLoggingConfig { + elc.enableSsl = &value + return elc +} + +func (elc *ExternalLoggingConfig) Token(value string) *ExternalLoggingConfig { + elc.token = &value + return elc +} + +func (elc *ExternalLoggingConfig) Port(value int) *ExternalLoggingConfig { + elc.port = &value + return elc +} diff --git a/external_logging_config.go b/external_logging_config.go deleted file mode 100644 index 5ec42117..00000000 --- a/external_logging_config.go +++ /dev/null @@ -1,155 +0,0 @@ -package fivetran - -// ExternalLoggingConfig builds Log Management, Log Config. -// Ref. https://fivetran.com/docs/rest-api/log-service-management#logservicesetupconfigurations -type ExternalLoggingConfig struct { - workspaceId *string - primaryKey *string - logGroupName *string - roleArn *string - externalId *string - region *string - apiKey *string - subDomain *string - host *string - hostname *string - channel *string - enableSsl *bool - token *string - port *int -} - -type externalLoggingConfigRequest struct { - WorkspaceId *string `json:"workspace_id,omitempty"` - PrimaryKey *string `json:"primary_key,omitempty"` - LogGroupName *string `json:"log_group_name,omitempty"` - RoleArn *string `json:"role_arn,omitempty"` - ExternalId *string `json:"external_id,omitempty"` - Region *string `json:"region,omitempty"` - ApiKey *string `json:"api_key,omitempty"` - SubDomain *string `json:"sub_domain,omitempty"` - Host *string `json:"host,omitempty"` - Hostname *string `json:"hostname,omitempty"` - Channel *string `json:"channel,omitempty"` - EnableSsl *bool `json:"enable_ssl,omitempty"` - Token *string `json:"token,omitempty"` - Port *int `json:"port,omitempty"` -} - -type ExternalLoggingConfigResponse struct { - WorkspaceId string `json:"workspace_id"` - PrimaryKey string `json:"primary_key"` - LogGroupName string `json:"log_group_name"` - RoleArn string `json:"role_arn"` - ExternalId string `json:"external_id"` - Region string `json:"region"` - ApiKey string `json:"api_key"` - SubDomain string `json:"sub_domain"` - Host string `json:"host"` - Hostname string `json:"hostname"` - Channel string `json:"channel"` - EnableSsl bool `json:"enable_ssl"` - Token string `json:"token"` - Port int `json:"port"` -} - -func NewExternalLoggingConfig() *ExternalLoggingConfig { - return &ExternalLoggingConfig{} -} - -func (elc *ExternalLoggingConfig) request() *externalLoggingConfigRequest { - return &externalLoggingConfigRequest{ - WorkspaceId: elc.workspaceId, - PrimaryKey: elc.primaryKey, - LogGroupName: elc.logGroupName, - RoleArn: elc.roleArn, - ExternalId: elc.externalId, - Region: elc.region, - ApiKey: elc.apiKey, - SubDomain: elc.subDomain, - Host: elc.host, - Hostname: elc.hostname, - Channel: elc.channel, - EnableSsl: elc.enableSsl, - Token: elc.token, - Port: elc.port, - } -} - -func (cc *ExternalLoggingConfig) merge(customConfig *map[string]interface{}) (*map[string]interface{}, error) { - err := MergeIntoMap(cc.request(), customConfig) - if err != nil { - return nil, err - } - return customConfig, nil -} - -func (elc *ExternalLoggingConfig) WorkspaceId(value string) *ExternalLoggingConfig { - elc.workspaceId = &value - return elc -} - -func (elc *ExternalLoggingConfig) PrimaryKey(value string) *ExternalLoggingConfig { - elc.primaryKey = &value - return elc -} - -func (elc *ExternalLoggingConfig) LogGroupName(value string) *ExternalLoggingConfig { - elc.logGroupName = &value - return elc -} - -func (elc *ExternalLoggingConfig) RoleArn(value string) *ExternalLoggingConfig { - elc.roleArn = &value - return elc -} - -func (elc *ExternalLoggingConfig) ExternalId(value string) *ExternalLoggingConfig { - elc.externalId = &value - return elc -} - -func (elc *ExternalLoggingConfig) Region(value string) *ExternalLoggingConfig { - elc.region = &value - return elc -} - -func (elc *ExternalLoggingConfig) ApiKey(value string) *ExternalLoggingConfig { - elc.apiKey = &value - return elc -} - -func (elc *ExternalLoggingConfig) SubDomain(value string) *ExternalLoggingConfig { - elc.subDomain = &value - return elc -} - -func (elc *ExternalLoggingConfig) Host(value string) *ExternalLoggingConfig { - elc.host = &value - return elc -} - -func (elc *ExternalLoggingConfig) Hostname(value string) *ExternalLoggingConfig { - elc.hostname = &value - return elc -} - -func (elc *ExternalLoggingConfig) Channel(value string) *ExternalLoggingConfig { - elc.channel = &value - return elc -} - -func (elc *ExternalLoggingConfig) EnableSsl(value bool) *ExternalLoggingConfig { - elc.enableSsl = &value - return elc -} - -func (elc *ExternalLoggingConfig) Token(value string) *ExternalLoggingConfig { - elc.token = &value - return elc -} - -func (elc *ExternalLoggingConfig) Port(value int) *ExternalLoggingConfig { - elc.port = &value - return elc -} diff --git a/external_logging_create.go b/external_logging_create.go index 65d4767b..916863a6 100644 --- a/external_logging_create.go +++ b/external_logging_create.go @@ -1,220 +1,192 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + externallogging "github.com/fivetran/go-fivetran/external_logging" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/utils" ) // ExternalLoggingCreateService implements the Log Management, Create a Log Service API. // Ref. https://fivetran.com/docs/rest-api/log-service-management#createalogservice type ExternalLoggingCreateService struct { - c *Client - groupId *string - service *string - enabled *bool - config *ExternalLoggingConfig - configCustom *map[string]interface{} + c *Client + groupId *string + service *string + enabled *bool + config *externallogging.ExternalLoggingConfig + configCustom *map[string]interface{} } /* requests */ type externalLoggingCreateRequestBase struct { - Id *string `json:"id,omitempty"` - GroupId *string `json:"group_id,omitempty"` - Service *string `json:"service,omitempty"` - Enabled *bool `json:"enabled,omitempty"` + Id *string `json:"id,omitempty"` + GroupId *string `json:"group_id,omitempty"` + Service *string `json:"service,omitempty"` + Enabled *bool `json:"enabled,omitempty"` } type externalLoggingCreateRequest struct { - externalLoggingCreateRequestBase - Config *externalLoggingConfigRequest `json:"config,omitempty"` + externalLoggingCreateRequestBase + Config any `json:"config,omitempty"` } type externalLoggingCustomCreateRequest struct { - externalLoggingCreateRequestBase - Config *map[string]interface{} `json:"config,omitempty"` + externalLoggingCreateRequestBase + Config *map[string]interface{} `json:"config,omitempty"` } /* responses */ -type ExternalLoggingCreateResponseBase struct { - Id string `json:"id"` - Service string `json:"service"` - Enabled bool `json:"enabled"` -} - -type ExternalLoggingCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ExternalLoggingCreateResponseBase - Config ExternalLoggingConfigResponse `json:"config"` - } `json:"data"` -} - -type ExternalLoggingCustomCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ExternalLoggingCreateResponseBase - Config ExternalLoggingConfigResponse `json:"config"` - } `json:"data"` -} - -type ExternalLoggingCustomMergedCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ExternalLoggingCreateResponseBase - CustomConfig map[string]interface{} `json:"config"` - Config ExternalLoggingConfigResponse // no mapping here - } `json:"data"` -} - func (c *Client) NewExternalLoggingCreate() *ExternalLoggingCreateService { - return &ExternalLoggingCreateService{c: c} + return &ExternalLoggingCreateService{c: c} } func (s *ExternalLoggingCreateService) requestBase() externalLoggingCreateRequestBase { - return externalLoggingCreateRequestBase{ - GroupId: s.groupId, - Service: s.service, - Enabled: s.enabled, - } + return externalLoggingCreateRequestBase{ + GroupId: s.groupId, + Service: s.service, + Enabled: s.enabled, + } } func (s *ExternalLoggingCreateService) request() *externalLoggingCreateRequest { - var config *externalLoggingConfigRequest - if s.config != nil { - config = s.config.request() - } + var config interface{} + if s.config != nil { + config = s.config.Request() + } - r := &externalLoggingCreateRequest{ - externalLoggingCreateRequestBase: s.requestBase(), - Config: config, - } + r := &externalLoggingCreateRequest{ + externalLoggingCreateRequestBase: s.requestBase(), + Config: config, + } - return r + return r } func (s *ExternalLoggingCreateService) requestCustom() *externalLoggingCustomCreateRequest { - return &externalLoggingCustomCreateRequest{ - externalLoggingCreateRequestBase: s.requestBase(), - Config: s.configCustom, - } + return &externalLoggingCustomCreateRequest{ + externalLoggingCreateRequestBase: s.requestBase(), + Config: s.configCustom, + } } func (s *ExternalLoggingCreateService) requestCustomMerged() (*externalLoggingCustomCreateRequest, error) { - currentConfig := s.configCustom + currentConfig := s.configCustom - if s.config != nil { - var err error - currentConfig, err = s.config.merge(currentConfig) - if err != nil { - return nil, err - } - } + if s.config != nil { + var err error + currentConfig, err = s.config.Merge(currentConfig) + if err != nil { + return nil, err + } + } - return &externalLoggingCustomCreateRequest{ - externalLoggingCreateRequestBase: s.requestBase(), - Config: currentConfig, - }, nil + return &externalLoggingCustomCreateRequest{ + externalLoggingCreateRequestBase: s.requestBase(), + Config: currentConfig, + }, nil } func (s *ExternalLoggingCreateService) GroupId(value string) *ExternalLoggingCreateService { - s.groupId = &value - return s + s.groupId = &value + return s } func (s *ExternalLoggingCreateService) Service(value string) *ExternalLoggingCreateService { - s.service = &value - return s + s.service = &value + return s } func (s *ExternalLoggingCreateService) Enabled(value bool) *ExternalLoggingCreateService { - s.enabled = &value - return s + s.enabled = &value + return s } -func (s *ExternalLoggingCreateService) Config(value *ExternalLoggingConfig) *ExternalLoggingCreateService { - s.config = value - return s +func (s *ExternalLoggingCreateService) Config(value *externallogging.ExternalLoggingConfig) *ExternalLoggingCreateService { + s.config = value + return s } func (s *ExternalLoggingCreateService) ConfigCustom(value *map[string]interface{}) *ExternalLoggingCreateService { - s.configCustom = value - return s + s.configCustom = value + return s } func (s *ExternalLoggingCreateService) do(ctx context.Context, req, response any) error { - url := fmt.Sprintf("%v/external-logging", s.c.baseURL) - expectedStatus := 201 + url := fmt.Sprintf("%v/external-logging", s.c.baseURL) + expectedStatus := 201 - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 - reqBody, err := json.Marshal(req) - if err != nil { - return err - } + reqBody, err := json.Marshal(req) + if err != nil { + return err + } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return err + } - return nil + return nil } -func (s *ExternalLoggingCreateService) Do(ctx context.Context) (ExternalLoggingCreateResponse, error) { - var response ExternalLoggingCreateResponse +func (s *ExternalLoggingCreateService) Do(ctx context.Context) (externallogging.ExternalLoggingResponse, error) { + var response externallogging.ExternalLoggingResponse - err := s.do(ctx, s.request(), &response) + err := s.do(ctx, s.request(), &response) - return response, err + return response, err } -func (s *ExternalLoggingCreateService) DoCustom(ctx context.Context) (ExternalLoggingCustomCreateResponse, error) { - var response ExternalLoggingCustomCreateResponse +func (s *ExternalLoggingCreateService) DoCustom(ctx context.Context) (externallogging.ExternalLoggingCustomResponse, error) { + var response externallogging.ExternalLoggingCustomResponse + + err := s.do(ctx, s.requestCustom(), &response) - err := s.do(ctx, s.requestCustom(), &response) - - return response, err + return response, err } -func (s *ExternalLoggingCreateService) DoCustomMerged(ctx context.Context) (ExternalLoggingCustomMergedCreateResponse, error) { - var response ExternalLoggingCustomMergedCreateResponse +func (s *ExternalLoggingCreateService) DoCustomMerged(ctx context.Context) (externallogging.ExternalLoggingCustomMergedResponse, error) { + var response externallogging.ExternalLoggingCustomMergedResponse - req, err := s.requestCustomMerged() + req, err := s.requestCustomMerged() - if err != nil { - return response, err - } + if err != nil { + return response, err + } - err = s.do(ctx, req, &response) + err = s.do(ctx, req, &response) - if err == nil { - err = FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) - } + if err == nil { + err = utils.FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) + } - return response, err + return response, err } diff --git a/external_logging_create_test.go b/external_logging_create_test.go index 3b587b5d..2ba45aa2 100644 --- a/external_logging_create_test.go +++ b/external_logging_create_test.go @@ -1,34 +1,35 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewExternalLoggingCreateE2E(t *testing.T) { - created, err := Client.NewExternalLoggingCreate(). - GroupId(PredefinedGroupId). - Service("azure_monitor_log"). - Enabled(true). - Config(fivetran.NewExternalLoggingConfig(). - WorkspaceId("workspace_id"). - PrimaryKey("PASSWORD")). - Do(context.Background()) + created, err := testutils.Client.NewExternalLoggingCreate(). + GroupId(testutils.PredefinedGroupId). + Service("azure_monitor_log"). + Enabled(true). + Config(fivetran.NewExternalLoggingConfig(). + WorkspaceId("workspace_id"). + PrimaryKey("PASSWORD")). + Do(context.Background()) - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertEqual(t, created.Data.Id, PredefinedGroupId) - AssertEqual(t, created.Data.Service, "azure_monitor_log") - AssertEqual(t, created.Data.Enabled, true) - AssertEqual(t, created.Data.Config.WorkspaceId, "workspace_id") - AssertEqual(t, created.Data.Config.PrimaryKey, "******") + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertEqual(t, created.Data.Id, testutils.PredefinedGroupId) + testutils.AssertEqual(t, created.Data.Service, "azure_monitor_log") + testutils.AssertEqual(t, created.Data.Enabled, true) + testutils.AssertEqual(t, created.Data.Config.WorkspaceId, "workspace_id") + testutils.AssertEqual(t, created.Data.Config.PrimaryKey, "******") - t.Cleanup(func() { DeleteExternalLogging(t, PredefinedGroupId) }) + t.Cleanup(func() { testutils.DeleteExternalLogging(t, testutils.PredefinedGroupId) }) } diff --git a/external_logging_delete.go b/external_logging_delete.go index b5fef297..3ef5d82e 100644 --- a/external_logging_delete.go +++ b/external_logging_delete.go @@ -1,66 +1,66 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ExternalLoggingDeleteService implements the Log Management, Delete a Log Service API. // Ref. https://fivetran.com/docs/rest-api/log-service-management#deletealogservice type ExternalLoggingDeleteService struct { - c *Client - externalLoggingId *string -} - -type ExternalLoggingDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` + c *Client + externalLoggingId *string } func (c *Client) NewExternalLoggingDelete() *ExternalLoggingDeleteService { - return &ExternalLoggingDeleteService{c: c} + return &ExternalLoggingDeleteService{c: c} } func (s *ExternalLoggingDeleteService) ExternalLoggingId(value string) *ExternalLoggingDeleteService { - s.externalLoggingId = &value - return s + s.externalLoggingId = &value + return s } -func (s *ExternalLoggingDeleteService) Do(ctx context.Context) (ExternalLoggingDeleteResponse, error) { - var response ExternalLoggingDeleteResponse +func (s *ExternalLoggingDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse - if s.externalLoggingId == nil { - return response, fmt.Errorf("missing required ExternalLoggingId") - } + if s.externalLoggingId == nil { + return response, fmt.Errorf("missing required ExternalLoggingId") + } - url := fmt.Sprintf("%v/external-logging/%v", s.c.baseURL, *s.externalLoggingId) - expectedStatus := 200 + url := fmt.Sprintf("%v/external-logging/%v", s.c.baseURL, *s.externalLoggingId) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/external_logging_delete_test.go b/external_logging_delete_test.go index d615e7df..b638578d 100644 --- a/external_logging_delete_test.go +++ b/external_logging_delete_test.go @@ -1,21 +1,23 @@ package fivetran_test import ( - "context" - "strings" - "testing" + "context" + "strings" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewExternalLoggingDeleteE2E(t *testing.T) { - externalLoggingId := CreateExternalLogging(t) - deleted, err := Client.NewExternalLoggingDelete().ExternalLoggingId(externalLoggingId).Do(context.Background()) + externalLoggingId := testutils.CreateExternalLogging(t) + deleted, err := testutils.Client.NewExternalLoggingDelete().ExternalLoggingId(externalLoggingId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, externalLoggingId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, externalLoggingId), true) } diff --git a/external_logging_details.go b/external_logging_details.go index 1640d979..b1d163fa 100644 --- a/external_logging_details.go +++ b/external_logging_details.go @@ -1,73 +1,95 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + externallogging "github.com/fivetran/go-fivetran/external_logging" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/utils" ) // ExternalLoggingDetailsService implements the Log Management, Retrieve Log Service details API. // Ref. https://fivetran.com/docs/rest-api/log-service-management#retrievelogservicedetails type ExternalLoggingDetailsService struct { - c *Client - externalLoggingId *string -} - -type ExternalLoggingDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Id string `json:"id"` - Service string `json:"service"` - Enabled bool `json:"enabled"` - Config ExternalLoggingConfigResponse `json:"config"` - } `json:"data"` + c *Client + externalLoggingId *string } func (c *Client) NewExternalLoggingDetails() *ExternalLoggingDetailsService { - return &ExternalLoggingDetailsService{c: c} + return &ExternalLoggingDetailsService{c: c} } func (s *ExternalLoggingDetailsService) ExternalLoggingId(value string) *ExternalLoggingDetailsService { - s.externalLoggingId = &value - return s + s.externalLoggingId = &value + return s +} + +func (s *ExternalLoggingDetailsService) Do(ctx context.Context) (externallogging.ExternalLoggingResponse, error) { + var response externallogging.ExternalLoggingResponse + + err := s.do(ctx, &response) + + return response, err +} + +func (s *ExternalLoggingDetailsService) DoCustom(ctx context.Context) (externallogging.ExternalLoggingCustomResponse, error) { + var response externallogging.ExternalLoggingCustomResponse + + err := s.do(ctx, &response) + + return response, err +} + +func (s *ExternalLoggingDetailsService) DoCustomMerged(ctx context.Context) (externallogging.ExternalLoggingCustomMergedResponse, error) { + var response externallogging.ExternalLoggingCustomMergedResponse + + err := s.do(ctx, &response) + + if err == nil { + err = utils.FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) + } + + return response, err } -func (s *ExternalLoggingDetailsService) Do(ctx context.Context) (ExternalLoggingDetailsResponse, error) { - var response ExternalLoggingDetailsResponse +func (s *ExternalLoggingDetailsService) do(ctx context.Context, response any) error { - if s.externalLoggingId == nil { - return response, fmt.Errorf("missing required ExternalLoggingId") - } + if s.externalLoggingId == nil { + return fmt.Errorf("missing required ExternalLoggingId") + } - url := fmt.Sprintf("%v/external-logging/%v", s.c.baseURL, *s.externalLoggingId) - expectedStatus := 200 + url := fmt.Sprintf("%v/external-logging/%v", s.c.baseURL, *s.externalLoggingId) + expectedStatus := 200 - headers := s.c.commonHeaders() - headers["Accept"] = restAPIv2 + headers := s.c.commonHeaders() + headers["Accept"] = restAPIv2 - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return err + } - return response, nil + return nil } diff --git a/external_logging_details_test.go b/external_logging_details_test.go index be2ee8fe..5d85c7f0 100644 --- a/external_logging_details_test.go +++ b/external_logging_details_test.go @@ -1,24 +1,26 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewExternalLoggingDetailsE2E(t *testing.T) { - externalLoggingId := CreateTempExternalLogging(t) + externalLoggingId := testutils.CreateTempExternalLogging(t) - details, err := Client.NewExternalLoggingDetails().ExternalLoggingId(externalLoggingId).Do(context.Background()) + details, err := testutils.Client.NewExternalLoggingDetails().ExternalLoggingId(externalLoggingId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", details) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", details) + t.Error(err) + } - AssertEqual(t, details.Code, "Success") - AssertEqual(t, details.Data.Id, PredefinedGroupId) - AssertEqual(t, details.Data.Service, "azure_monitor_log") - AssertEqual(t, details.Data.Enabled, true) - AssertEqual(t, details.Data.Config.WorkspaceId, "workspace_id") - AssertEqual(t, details.Data.Config.PrimaryKey, "******") + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertEqual(t, details.Data.Id, testutils.PredefinedGroupId) + testutils.AssertEqual(t, details.Data.Service, "azure_monitor_log") + testutils.AssertEqual(t, details.Data.Enabled, true) + testutils.AssertEqual(t, details.Data.Config.WorkspaceId, "workspace_id") + testutils.AssertEqual(t, details.Data.Config.PrimaryKey, "******") } diff --git a/external_logging_modify.go b/external_logging_modify.go index d4e8fb0e..76c8c79e 100644 --- a/external_logging_modify.go +++ b/external_logging_modify.go @@ -1,216 +1,222 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + externallogging "github.com/fivetran/go-fivetran/external_logging" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/utils" ) // ExternalLoggingModifyService implements the Log Management, Modify a Log Service API. // Ref. https://fivetran.com/docs/rest-api/log-service-management#updatealogservice type ExternalLoggingModifyService struct { - c *Client - externalLoggingId *string - enabled *bool - runSetupTests *bool - config *ExternalLoggingConfig - configCustom *map[string]interface{} + c *Client + externalLoggingId *string + enabled *bool + runSetupTests *bool + config *externallogging.ExternalLoggingConfig + configCustom *map[string]interface{} } type externalLoggingModifyRequestBase struct { - Enabled *bool `json:"enabled,omitempty"` - RunSetupTests *bool `json:"run_setup_tests,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + RunSetupTests *bool `json:"run_setup_tests,omitempty"` } type externalLoggingModifyRequest struct { - externalLoggingModifyRequestBase - Config *externalLoggingConfigRequest `json:"config,omitempty"` + externalLoggingModifyRequestBase + Config any `json:"config,omitempty"` } type externalLoggingCustomModifyRequest struct { - externalLoggingModifyRequestBase - Config *map[string]interface{} `json:"config,omitempty"` + externalLoggingModifyRequestBase + Config *map[string]interface{} `json:"config,omitempty"` } type ExternalLoggingModifyResponseDataBased struct { - Id string `json:"id"` - Service string `json:"service"` - Enabled bool `json:"enabled"` + Id string `json:"id"` + Service string `json:"service"` + Enabled bool `json:"enabled"` } type ExternalLoggingModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ExternalLoggingModifyResponseDataBased - Config ExternalLoggingConfigResponse `json:"config"` - } `json:"data"` + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ExternalLoggingModifyResponseDataBased + Config externallogging.ExternalLoggingConfigResponse `json:"config"` + } `json:"data"` } type ExternalLoggingModifyCustomResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ExternalLoggingModifyResponseDataBased - Config map[string]interface{} `json:"config"` - } `json:"data"` + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ExternalLoggingModifyResponseDataBased + Config map[string]interface{} `json:"config"` + } `json:"data"` } type ExternalLoggingModifyCustomMergedResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ExternalLoggingModifyResponseDataBased - CustomConfig map[string]interface{} `json:"config"` - Config ExternalLoggingConfigResponse // no mapping here - } `json:"data"` + Code string `json:"code"` + Message string `json:"message"` + Data struct { + ExternalLoggingModifyResponseDataBased + CustomConfig map[string]interface{} `json:"config"` + Config externallogging.ExternalLoggingConfigResponse // no mapping here + } `json:"data"` } func (c *Client) NewExternalLoggingModify() *ExternalLoggingModifyService { - return &ExternalLoggingModifyService{c: c} + return &ExternalLoggingModifyService{c: c} } func (s *ExternalLoggingModifyService) requestBase() externalLoggingModifyRequestBase { - return externalLoggingModifyRequestBase{ - Enabled: s.enabled, - } + return externalLoggingModifyRequestBase{ + Enabled: s.enabled, + } } func (s *ExternalLoggingModifyService) request() *externalLoggingModifyRequest { - var config *externalLoggingConfigRequest + var config interface{} - if s.config != nil { - config = s.config.request() - } + if s.config != nil { + config = s.config.Request() + } - return &externalLoggingModifyRequest{ - externalLoggingModifyRequestBase: s.requestBase(), - Config: config, - } + return &externalLoggingModifyRequest{ + externalLoggingModifyRequestBase: s.requestBase(), + Config: config, + } } func (s *ExternalLoggingModifyService) requestCustom() *externalLoggingCustomModifyRequest { - return &externalLoggingCustomModifyRequest{ - externalLoggingModifyRequestBase: s.requestBase(), - Config: s.configCustom, - } + return &externalLoggingCustomModifyRequest{ + externalLoggingModifyRequestBase: s.requestBase(), + Config: s.configCustom, + } } func (s *ExternalLoggingModifyService) requestCustomMerged() (*externalLoggingCustomModifyRequest, error) { - currentConfig := s.configCustom + currentConfig := s.configCustom - if s.config != nil { - var err error - currentConfig, err = s.config.merge(currentConfig) - if err != nil { - return nil, err - } - } + if s.config != nil { + var err error + currentConfig, err = s.config.Merge(currentConfig) + if err != nil { + return nil, err + } + } - return &externalLoggingCustomModifyRequest{ - externalLoggingModifyRequestBase: s.requestBase(), - Config: currentConfig, - }, nil + return &externalLoggingCustomModifyRequest{ + externalLoggingModifyRequestBase: s.requestBase(), + Config: currentConfig, + }, nil } func (s *ExternalLoggingModifyService) ExternalLoggingId(value string) *ExternalLoggingModifyService { - s.externalLoggingId = &value - return s + s.externalLoggingId = &value + return s } func (s *ExternalLoggingModifyService) Enabled(value bool) *ExternalLoggingModifyService { - s.enabled = &value - return s + s.enabled = &value + return s } -func (s *ExternalLoggingModifyService) Config(value *ExternalLoggingConfig) *ExternalLoggingModifyService { - s.config = value - return s +func (s *ExternalLoggingModifyService) Config(value *externallogging.ExternalLoggingConfig) *ExternalLoggingModifyService { + s.config = value + return s } func (s *ExternalLoggingModifyService) ConfigCustom(value *map[string]interface{}) *ExternalLoggingModifyService { - s.configCustom = value - return s + s.configCustom = value + return s } func (s *ExternalLoggingModifyService) RunSetupTests(value bool) *ExternalLoggingModifyService { - s.runSetupTests = &value - return s + s.runSetupTests = &value + return s } func (s *ExternalLoggingModifyService) do(ctx context.Context, req, response any) error { - if s.externalLoggingId == nil { - return fmt.Errorf("missing required externalLoggingId") - } + if s.externalLoggingId == nil { + return fmt.Errorf("missing required externalLoggingId") + } - url := fmt.Sprintf("%v/external-logging/%v", s.c.baseURL, *s.externalLoggingId) - expectedStatus := 200 + url := fmt.Sprintf("%v/external-logging/%v", s.c.baseURL, *s.externalLoggingId) + expectedStatus := 200 - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 - reqBody, err := json.Marshal(req) - if err != nil { - return err - } + reqBody, err := json.Marshal(req) + if err != nil { + return err + } - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return err + } - return nil + return nil } -func (s *ExternalLoggingModifyService) Do(ctx context.Context) (ExternalLoggingModifyResponse, error) { - var response ExternalLoggingModifyResponse +func (s *ExternalLoggingModifyService) Do(ctx context.Context) (externallogging.ExternalLoggingResponse, error) { + var response externallogging.ExternalLoggingResponse - err := s.do(ctx, s.request(), &response) + err := s.do(ctx, s.request(), &response) - return response, err + return response, err } -func (s *ExternalLoggingModifyService) DoCustom(ctx context.Context) (ExternalLoggingModifyCustomResponse, error) { - var response ExternalLoggingModifyCustomResponse +func (s *ExternalLoggingModifyService) DoCustom(ctx context.Context) (externallogging.ExternalLoggingCustomResponse, error) { + var response externallogging.ExternalLoggingCustomResponse - err := s.do(ctx, s.requestCustom(), &response) + err := s.do(ctx, s.requestCustom(), &response) - return response, err + return response, err } -func (s *ExternalLoggingModifyService) DoCustomMerged(ctx context.Context) (ExternalLoggingModifyCustomMergedResponse, error) { - var response ExternalLoggingModifyCustomMergedResponse +func (s *ExternalLoggingModifyService) DoCustomMerged(ctx context.Context) (externallogging.ExternalLoggingCustomMergedResponse, error) { + var response externallogging.ExternalLoggingCustomMergedResponse - req, err := s.requestCustomMerged() + req, err := s.requestCustomMerged() - if err != nil { - return response, err - } + if err != nil { + return response, err + } - err = s.do(ctx, req, &response) + err = s.do(ctx, req, &response) - if err == nil { - err = FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) - } + if err == nil { + err = utils.FetchFromMap(&response.Data.CustomConfig, &response.Data.Config) + } - return response, err + return response, err } diff --git a/external_logging_modify_test.go b/external_logging_modify_test.go index 3353c7b2..994a243b 100644 --- a/external_logging_modify_test.go +++ b/external_logging_modify_test.go @@ -5,11 +5,12 @@ import ( "testing" "github.com/fivetran/go-fivetran" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewExternalLoggingModifyE2E(t *testing.T) { - externalLoggingId := CreateTempExternalLogging(t) - details, err := Client.NewExternalLoggingModify().ExternalLoggingId(externalLoggingId). + externalLoggingId := testutils.CreateTempExternalLogging(t) + details, err := testutils.Client.NewExternalLoggingModify().ExternalLoggingId(externalLoggingId). Enabled(true). Config(fivetran.NewExternalLoggingConfig(). WorkspaceId("test"). @@ -21,11 +22,11 @@ func TestNewExternalLoggingModifyE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, details.Code, "Success") - AssertNotEmpty(t, details.Message) - AssertEqual(t, details.Data.Id, externalLoggingId) - AssertEqual(t, details.Data.Enabled, true) - AssertEqual(t, details.Data.Service, "azure_monitor_log") - AssertEqual(t, details.Data.Config.WorkspaceId, "test") - AssertEqual(t, details.Data.Config.PrimaryKey, "******") + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Message) + testutils.AssertEqual(t, details.Data.Id, externalLoggingId) + testutils.AssertEqual(t, details.Data.Enabled, true) + testutils.AssertEqual(t, details.Data.Service, "azure_monitor_log") + testutils.AssertEqual(t, details.Data.Config.WorkspaceId, "test") + testutils.AssertEqual(t, details.Data.Config.PrimaryKey, "******") } diff --git a/external_logging_setup_tests.go b/external_logging_setup_tests.go index 6d1534c3..72f6ab0a 100644 --- a/external_logging_setup_tests.go +++ b/external_logging_setup_tests.go @@ -4,24 +4,22 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // ExternalLoggingSetupTestsService implements the Log Management, Run Log service setup tests API. // Ref. https://fivetran.com/docs/rest-api/log-service-management#runlogservicesetuptests type ExternalLoggingSetupTestsService struct { - c *Client - externalLoggingId *string + c *Client + externalLoggingId *string } type ExternalLoggingSetupTestsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - SetupTests []struct { - Title string `json:"title"` - Status string `json:"status"` - Message string `json:"message"` - } `json:"setup_tests"` + common.CommonResponse + Data struct { + SetupTests []common.SetupTestResponse `json:"setup_tests"` } `json:"data"` } @@ -48,15 +46,18 @@ func (s *ExternalLoggingSetupTestsService) Do(ctx context.Context) (ExternalLogg headers["Content-Type"] = "application/json" headers["Accept"] = restAPIv2 - r := request{ - method: "POST", - url: url, - queries: nil, - headers: headers, - client: s.c.httpClient, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/external_logging_setup_tests_test.go b/external_logging_setup_tests_test.go index 21831cfa..17284bbe 100644 --- a/external_logging_setup_tests_test.go +++ b/external_logging_setup_tests_test.go @@ -3,11 +3,13 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewExternalLoggingSetupTestsE2E(t *testing.T) { - externalLoggingId := CreateTempExternalLogging(t) - response, err := Client.NewExternalLoggingSetupTests().ExternalLoggingId(externalLoggingId). + externalLoggingId := testutils.CreateTempExternalLogging(t) + response, err := testutils.Client.NewExternalLoggingSetupTests().ExternalLoggingId(externalLoggingId). Do(context.Background()) if err != nil { @@ -15,6 +17,6 @@ func TestNewExternalLoggingSetupTestsE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, response.Code, "Success") - AssertNotEmpty(t, response.Message) + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertNotEmpty(t, response.Message) } diff --git a/fivetran_test.go b/fivetran_test.go index 3d8c6800..5fb59b00 100644 --- a/fivetran_test.go +++ b/fivetran_test.go @@ -1,35 +1,11 @@ package fivetran_test import ( - "context" - "fmt" "log" "os" - "reflect" - "testing" "github.com/fivetran/go-fivetran" -) - -var Client *fivetran.Client - -var CertificateHash string -var EncodedCertificate string - -// Tests should be re-written to not use a pre-defined user and group -const ( - PredefinedGroupName = "GoSdkTesting" - PredefinedUserEmail = "dev-markov+go-fivetran-sdk@fivetran.com" - PredefinedUserGivenName = "Go" - PredefinedUserFamilyName = "5Tran" - PredefinedUserPhone = "+1234567890" - BqProjectId = "dulcet-yew-246109" - - // ! WARNING ! - // ! Do not change these values on production ones ! - // ! When running e2e tests locally endure you're using BLANK ACCOUNT credentials ! - PredefinedGroupId = "sepulchre_settlement" - PredefinedUserId = "recoup_befell" + testutils "github.com/fivetran/go-fivetran/test_utils" ) func init() { @@ -41,8 +17,8 @@ func init() { "FIVETRAN_API_URL": &apiUrl, "FIVETRAN_APIKEY": &apiKey, "FIVETRAN_APISECRET": &apiSecret, - "FIVETRAN_TEST_CERTIFICATE_HASH": &CertificateHash, - "FIVETRAN_TEST_CERTIFICATE": &EncodedCertificate, + "FIVETRAN_TEST_CERTIFICATE_HASH": &testutils.CertificateHash, + "FIVETRAN_TEST_CERTIFICATE": &testutils.EncodedCertificate, } for name, value := range valuesToLoad { @@ -52,657 +28,11 @@ func init() { } } - Client = fivetran.New(apiKey, apiSecret) - Client.BaseURL(apiUrl) - if isPredefinedUserExist() && isPredefinedGroupExist() { - cleanupAccount() + testutils.Client = fivetran.New(apiKey, apiSecret) + testutils.Client.BaseURL(apiUrl) + if testutils.IsPredefinedUserExist() && testutils.IsPredefinedGroupExist() { + testutils.CleanupAccount() } else { log.Fatalln("The predefined user doesn't belong to the Testing account. Make sure that credentials are using in the tests belong to the Testing account.") } } - -func CreateDbtDestination(t *testing.T) { - t.Helper() - destination, err := Client.NewDestinationCreate(). - GroupID(PredefinedGroupId). - Service("big_query"). - Region("US"). - RunSetupTests(true). - TimeZoneOffset("-5"). - Config( - fivetran.NewDestinationConfig(). - ProjectID(BqProjectId). - DataSetLocation("US")). - Do(context.Background()) - if err != nil { - t.Logf("%+v\n", destination) - t.Error(err) - } -} - -func deleteDbtDestination() { - resp, err := Client.NewDestinationDelete().DestinationID(PredefinedGroupId).Do(context.Background()) - if err != nil { - log.Fatal(resp, err) - } -} - -func CreateUser(t *testing.T) string { - t.Helper() - user, err := Client.NewUserInvite(). - Email("william_addison.@fivetran.com"). - GivenName("William"). - FamilyName("Addison"). - Phone("+19876543210"). - Role("Account Reviewer"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", user) - t.Error(err) - } - return user.Data.ID -} - -func CreateTempUser(t *testing.T) string { - t.Helper() - userId := CreateUser(t) - t.Cleanup(func() { DeleteUser(t, userId) }) - return userId -} - -func DeleteUser(t *testing.T, id string) { - t.Helper() - user, err := Client.NewUserDelete().UserID(id).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", user) - t.Error(err) - } -} - -func CreateGroup(t *testing.T) string { - t.Helper() - created, err := Client.NewGroupCreate().Name("test").Do(context.Background()) - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - return created.Data.ID -} - -func CreateDbtProject(t *testing.T) string { - t.Helper() - CreateDbtDestination(t) - created, err := Client.NewDbtProjectCreate(). - GroupID(PredefinedGroupId). - DbtVersion("1.3.1"). - ProjectConfig(fivetran.NewDbtProjectConfig(). - GitRemoteUrl("https://github.com/fivetran/dbt_demo"). - FolderPath(""). - GitBranch("main")). - DefaultSchema(""). - TargetName(""). - Threads(4). - Do(context.Background()) - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - return created.Data.ID -} - -func cleanupDbtProjects() { - projects, err := Client.NewDbtProjectsList().Do(context.Background()) - if err != nil { - log.Fatal(err) - } - for _, project := range projects.Data.Items { - cleanupDbtTransformations(project.ID, "") - _, err := Client.NewDbtProjectDelete().DbtProjectID(project.ID).Do(context.Background()) - if err != nil && err.Error() != "status code: 404; expected: 200" { - log.Fatal(err) - } - } - if projects.Data.NextCursor != "" { - cleanupDbtProjects() - } -} - -func cleanupDbtTransformations(projectId, nextCursor string) { - svc := Client.NewDbtModelsList().ProjectId(projectId) - - if nextCursor != "" { - svc.Cursor(nextCursor) - } - - models, err := svc.Do(context.Background()) - if err != nil { - log.Fatal(err) - } - - for _, model := range models.Data.Items { - if model.Scheduled { - _, err := Client.NewDbtTransformationDeleteService().TransformationId(model.ID).Do(context.Background()) - if err != nil && err.Error() != "status code: 404; expected: 200" { - log.Fatal(err) - } - } - } - - if models.Data.NextCursor != "" { - cleanupDbtTransformations(projectId, models.Data.NextCursor) - } -} - -func CreateTempGroup(t *testing.T) string { - t.Helper() - groupId := CreateGroup(t) - t.Cleanup(func() { DeleteGroup(t, groupId) }) - return groupId -} - -func DeleteGroup(t *testing.T, id string) { - t.Helper() - deleted, err := Client.NewGroupDelete().GroupID(id).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func AddUserToGroup(t *testing.T, groupId string, email string) { - t.Helper() - created, err := Client.NewGroupAddUser().GroupID(groupId).Email(email).Role("Destination Administrator").Do(context.Background()) - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } -} - -func RemoveUserFromGroup(t *testing.T, groupId string, userId string) { - t.Helper() - deleted, err := Client.NewGroupRemoveUser().GroupID(groupId).UserID(userId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func DeleteDestination(t *testing.T, id string) { - t.Helper() - deleted, err := Client.NewDestinationDelete().DestinationID(id).Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func CreateDestination(t *testing.T) string { - t.Helper() - created, err := Client.NewDestinationCreate(). - GroupID(PredefinedGroupId). - Service("snowflake"). - TimeZoneOffset("+10"). - RunSetupTests(false). - Config(fivetran.NewDestinationConfig(). - Host("your-account.snowflakecomputing.com"). - Port(443). - Database("fivetran"). - Auth("PASSWORD"). - User("fivetran_user"). - Password("123456")). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - return created.Data.ID -} - -func CreateTempDestination(t *testing.T) string { - t.Helper() - destinationId := CreateDestination(t) - t.Cleanup(func() { DeleteDestination(t, destinationId) }) - return destinationId -} - -func CreateDbtTransformation(t *testing.T) string { - t.Helper() - created, err := Client.NewDbtTransformationCreateService(). - DbtModelId(""). - Schedule(fivetran.NewDbtTransformationSchedule(). - ScheduleType("INTEGRATED"). - DaysOfWeek([]string{}). - Interval(0). - TimeOfDay("")). - RunTests(true). - Paused(true). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - return created.Data.ID -} - -func CreateTempDbtTransformation(t *testing.T) string { - t.Helper() - dbtTransformationId := CreateDbtTransformation(t) - t.Cleanup(func() { DeleteDbtTransformation(t, dbtTransformationId) }) - return dbtTransformationId -} - -func DeleteDbtTransformation(t *testing.T, id string) { - t.Helper() - deleted, err := Client.NewDbtTransformationDeleteService(). - TransformationId(id). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func CreateConnector(t *testing.T) string { - t.Helper() - created, err := Client.NewConnectorCreate(). - GroupID(PredefinedGroupId). - Service("itunes_connect"). - RunSetupTests(false). - Config(fivetran.NewConnectorConfig(). - Schema("itunes_e2e_connect"). - Username("fivetran"). - Password("fivetran-api-e2e")). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - - return created.Data.ID -} - -func CreateTempConnector(t *testing.T) string { - t.Helper() - connectorId := CreateConnector(t) - t.Cleanup(func() { DeleteConnector(t, connectorId) }) - return connectorId -} - -func DeleteConnector(t *testing.T, id string) { - t.Helper() - deleted, err := Client.NewConnectorDelete().ConnectorID(id).Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func printError(t *testing.T, actual interface{}, expected interface{}) { - t.Helper() - t.Errorf("Expected: %s"+ - "\n but: <%s>\n", - fmt.Sprintf("value equal to <%v>", expected), - fmt.Sprintf("%v", actual), - ) -} - -func AssertHasLength(t *testing.T, actual interface{}, expected int) { - t.Helper() - - if actual == nil { - printError(t, actual, fmt.Sprintf("value with length %v", expected)) - } else { - lenOfActual := reflect.ValueOf(actual).Len() - if lenOfActual != expected { - printError(t, fmt.Sprintf("length was %d", lenOfActual), fmt.Sprintf("value with length %v", expected)) - } - } -} - -func AssertEqual(t *testing.T, actual interface{}, expected interface{}) { - t.Helper() - - if !reflect.DeepEqual(expected, actual) { - printError(t, actual, expected) - } -} - -func AssertEmpty(t *testing.T, actual interface{}) { - t.Helper() - - var isEmpty bool = isEmpty(actual) - - if !isEmpty { - printError(t, actual, "empty value") - } -} - -func AssertNotEmpty(t *testing.T, actual interface{}) { - t.Helper() - - var isEmpty bool = isEmpty(actual) - - if isEmpty { - printError(t, actual, "none-empty value") - } -} - -func isEmpty(actual interface{}) bool { - var isEmpty bool = false - - if actual == nil { - isEmpty = true - } else if actualValue, ok := actual.(string); ok { - isEmpty = actualValue == "" - } else if reflect.ValueOf(actual).Len() == 0 { - isEmpty = true - } - return isEmpty -} - -func cleanupAccount() { - cleanupUsers() - cleanupDestinations() - cleanupDbtProjects() - cleanupGroups() - cleanupExternalLogging() - cleanupWebhooks() - cleanupTeams() -} - -func isPredefinedUserExist() bool { - user, err := Client.NewUserDetails().UserID(PredefinedUserId).Do(context.Background()) - if err != nil { - return false - } - return user.Data.GivenName == PredefinedUserGivenName -} - -func isPredefinedGroupExist() bool { - group, err := Client.NewGroupDetails().GroupID(PredefinedGroupId).Do(context.Background()) - if err != nil { - return false - } - return group.Data.Name == PredefinedGroupName -} - -func cleanupUsers() { - users, err := Client.NewUsersList().Do(context.Background()) - if err != nil { - log.Fatal(err) - } - for _, user := range users.Data.Items { - if user.ID != PredefinedUserId { - _, err := Client.NewUserDelete().UserID(user.ID).Do(context.Background()) - if err != nil { - log.Fatal(err) - } - } - } -} - -func cleanupDestinations() { - groups, err := Client.NewGroupsList().Do(context.Background()) - if err != nil { - log.Fatal(err) - } - for _, group := range groups.Data.Items { - _, err := Client.NewDestinationDelete().DestinationID(group.ID).Do(context.Background()) - if err != nil && err.Error() != "status code: 404; expected: 200" { - log.Fatal(err) - } - } -} - -func cleanupGroups() { - groups, err := Client.NewGroupsList().Do(context.Background()) - if err != nil { - log.Fatal(err) - } - for _, group := range groups.Data.Items { - cleanupConnectors(group.ID) - if group.ID != PredefinedGroupId { - _, err := Client.NewGroupDelete().GroupID(group.ID).Do(context.Background()) - if err != nil { - log.Fatal(err) - } - } - } -} - -func cleanupConnectors(groupId string) { - connectors, err := Client.NewGroupListConnectors().GroupID(groupId).Do(context.Background()) - if err != nil { - log.Fatal(err) - } - for _, connector := range connectors.Data.Items { - _, err := Client.NewConnectorDelete().ConnectorID(connector.ID).Do(context.Background()) - if err != nil { - log.Fatal(err) - } - } -} - -func cleanupExternalLogging() { - groups, err := Client.NewGroupsList().Do(context.Background()) - if err != nil { - log.Fatal(err) - } - for _, group := range groups.Data.Items { - _, err := Client.NewExternalLoggingDelete().ExternalLoggingId(group.ID).Do(context.Background()) - if err != nil && err.Error() != "status code: 404; expected: 200" { - log.Fatal(err) - } - } -} - -func cleanupWebhooks() { - list, err := Client.NewWebhookList().Do(context.Background()) - if err != nil { - log.Fatal(err) - } - for _, webhook := range list.Data.Items { - _, err := Client.NewWebhookDelete().WebhookId(webhook.Id).Do(context.Background()) - if err != nil && err.Error() != "status code: 404; expected: 200" { - log.Fatal(err) - } - } -} - -func cleanupTeams() { - list, err := Client.NewTeamsList().Do(context.Background()) - if err != nil { - log.Fatal(err) - } - - for _, team := range list.Data.Items { - _, err := Client.NewTeamsDelete().TeamId(team.Id).Do(context.Background()) - if err != nil && err.Error() != "status code: 404; expected: 200" { - log.Fatal(err) - } - } - - if list.Data.NextCursor != "" { - cleanupTeams() - } -} - -func CreateTempExternalLogging(t *testing.T) string { - t.Helper() - externalLoggingId := CreateExternalLogging(t) - t.Cleanup(func() { DeleteExternalLogging(t, externalLoggingId) }) - return externalLoggingId -} - -func DeleteExternalLogging(t *testing.T, id string) { - t.Helper() - deleted, err := Client.NewExternalLoggingDelete().ExternalLoggingId(id).Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func CreateExternalLogging(t *testing.T) string { - t.Helper() - created, err := Client.NewExternalLoggingCreate(). - GroupId(PredefinedGroupId). - Service("azure_monitor_log"). - Enabled(true). - Config(fivetran.NewExternalLoggingConfig(). - WorkspaceId("workspace_id"). - PrimaryKey("PASSWORD")). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - return created.Data.Id -} - -func CreateTempWebhook(t *testing.T) string { - t.Helper() - webhookId := CreateWebhookAccount(t) - t.Cleanup(func() { DeleteWebhook(t, webhookId) }) - return webhookId -} - -func DeleteWebhook(t *testing.T, id string) { - t.Helper() - deleted, err := Client.NewWebhookDelete().WebhookId(id).Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func CreateWebhookAccount(t *testing.T) string { - t.Helper() - created, err := Client.NewWebhookAccountCreate(). - Url("https://localhost:12345"). - Secret("my_secret"). - Active(false). - Events([]string{"sync_start", "sync_end"}). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - return created.Data.Id -} - -/* Begin Team Management */ -func CreateTeam(t *testing.T) string { - t.Helper() - created, err := Client.NewTeamsCreate(). - Name("test_team"). - Description("test_description"). - Role("Account Reviewer"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } - return created.Data.Id -} - -func DeleteTeamConnector(t *testing.T, teamId string, connectorId string) { - t.Helper() - deleted, err := Client.NewTeamConnectorMembershipDelete().TeamId(teamId).ConnectorId(connectorId).Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func CreateTeamConnector(t *testing.T, teamId string, connectorId string) { - t.Helper() - created, err := Client.NewTeamConnectorMembershipCreate(). - TeamId(teamId). - ConnectorId(connectorId). - Role("Connector Administrator"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } -} - -func DeleteTeamUser(t *testing.T, teamId string, userId string) { - t.Helper() - deleted, err := Client.NewTeamUserMembershipDelete(). - TeamId(teamId). - UserId(userId). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func CreateTeamUser(t *testing.T, teamId string, userId string) { - t.Helper() - created, err := Client.NewTeamUserMembershipCreate(). - TeamId(teamId). - UserId(userId). - Role("Team Member"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } -} - -func DeleteTeamGroup(t *testing.T, teamId string, groupId string) { - t.Helper() - deleted, err := Client.NewTeamGroupMembershipDelete(). - TeamId(teamId). - GroupId(groupId). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} - -func CreateTeamGroup(t *testing.T, teamId string, groupId string) { - t.Helper() - created, err := Client.NewTeamGroupMembershipCreate(). - TeamId(teamId). - GroupId(groupId). - Role("Destination Analyst"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } -} - -func DeleteTeam(t *testing.T, id string) { - t.Helper() - deleted, err := Client.NewTeamsDelete().TeamId(id).Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } -} -/* End Team Management */ \ No newline at end of file diff --git a/group_add_user.go b/group_add_user.go index 40256b52..033e73f8 100644 --- a/group_add_user.go +++ b/group_add_user.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupAddUserService implements the Group Management, Add a User to a Group API. @@ -20,11 +23,6 @@ type groupAddUserRequest struct { Role *string `json:"role,omitempty"` } -type GroupAddUserResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewGroupAddUser() *GroupAddUserService { return &GroupAddUserService{c: c} } @@ -51,8 +49,8 @@ func (s *GroupAddUserService) Role(value string) *GroupAddUserService { return s } -func (s *GroupAddUserService) Do(ctx context.Context) (GroupAddUserResponse, error) { - var response GroupAddUserResponse +func (s *GroupAddUserService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.groupID == nil { return response, fmt.Errorf("missing required GroupID") @@ -69,18 +67,18 @@ func (s *GroupAddUserService) Do(ctx context.Context) (GroupAddUserResponse, err return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_add_user_test.go b/group_add_user_test.go index 211089b7..2f53faaf 100644 --- a/group_add_user_test.go +++ b/group_add_user_test.go @@ -3,12 +3,14 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupAddUserE2E(t *testing.T) { - userId := CreateUser(t) + userId := testutils.CreateUser(t) - created, err := Client.NewGroupAddUser().GroupID(PredefinedGroupId). + created, err := testutils.Client.NewGroupAddUser().GroupID(testutils.PredefinedGroupId). Email("william_addison.@fivetran.com"). Role("Destination Administrator"). Do(context.Background()) @@ -18,11 +20,11 @@ func TestNewGroupAddUserE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) t.Cleanup(func() { - RemoveUserFromGroup(t, PredefinedGroupId, userId) - DeleteUser(t, userId) + testutils.RemoveUserFromGroup(t, testutils.PredefinedGroupId, userId) + testutils.DeleteUser(t, userId) }) } diff --git a/group_create.go b/group_create.go index 51cd06b1..6f25893a 100644 --- a/group_create.go +++ b/group_create.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/groups" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupCreateService implements the Group Management, Create a Group API. @@ -18,16 +20,6 @@ type groupCreateRequest struct { Name *string `json:"name,omitempty"` } -type GroupCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - Name string `json:"name"` - CreatedAt time.Time `json:"created_at"` - } `json:"data"` -} - func (c *Client) NewGroupCreate() *GroupCreateService { return &GroupCreateService{c: c} } @@ -43,8 +35,8 @@ func (s *GroupCreateService) Name(value string) *GroupCreateService { return s } -func (s *GroupCreateService) Do(ctx context.Context) (GroupCreateResponse, error) { - var response GroupCreateResponse +func (s *GroupCreateService) Do(ctx context.Context) (groups.GroupDetailsResponse, error) { + var response groups.GroupDetailsResponse url := fmt.Sprintf("%v/groups", s.c.baseURL) expectedStatus := 201 @@ -56,18 +48,18 @@ func (s *GroupCreateService) Do(ctx context.Context) (GroupCreateResponse, error return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_create_test.go b/group_create_test.go index ec4beb49..cb166510 100644 --- a/group_create_test.go +++ b/group_create_test.go @@ -3,18 +3,20 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupCreateE2E(t *testing.T) { - created, err := Client.NewGroupCreate().Name("test").Do(context.Background()) + created, err := testutils.Client.NewGroupCreate().Name("test").Do(context.Background()) if err != nil { t.Logf("%+v\n", created) t.Error(err) } - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Data.ID) - AssertEqual(t, created.Data.Name, "test") + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Data.ID) + testutils.AssertEqual(t, created.Data.Name, "test") - t.Cleanup(func() { DeleteGroup(t, created.Data.ID) }) + t.Cleanup(func() { testutils.DeleteGroup(t, created.Data.ID) }) } diff --git a/group_delete.go b/group_delete.go index 00c6cdd7..955cb16f 100644 --- a/group_delete.go +++ b/group_delete.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupDeleteService implements the Group Management, Delete a group API. @@ -13,11 +16,6 @@ type GroupDeleteService struct { groupID *string } -type GroupDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewGroupDelete() *GroupDeleteService { return &GroupDeleteService{c: c} } @@ -27,8 +25,8 @@ func (s *GroupDeleteService) GroupID(value string) *GroupDeleteService { return s } -func (s *GroupDeleteService) Do(ctx context.Context) (GroupDeleteResponse, error) { - var response GroupDeleteResponse +func (s *GroupDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.groupID == nil { return response, fmt.Errorf("missing required GroupID") @@ -39,18 +37,18 @@ func (s *GroupDeleteService) Do(ctx context.Context) (GroupDeleteResponse, error headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_delete_test.go b/group_delete_test.go index c51451d0..6a708f7e 100644 --- a/group_delete_test.go +++ b/group_delete_test.go @@ -4,16 +4,18 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupDeleteE2E(t *testing.T) { - groupId := CreateGroup(t) - deleted, err := Client.NewGroupDelete().GroupID(groupId).Do(context.Background()) + groupId := testutils.CreateGroup(t) + deleted, err := testutils.Client.NewGroupDelete().GroupID(groupId).Do(context.Background()) if err != nil { t.Logf("%+v\n", deleted) t.Error(err) } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, groupId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, groupId), true) } diff --git a/group_details.go b/group_details.go index c853793f..b07739cd 100644 --- a/group_details.go +++ b/group_details.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/groups" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupDetailsService implements the Group Management, Retrieve Group Details API. @@ -14,16 +16,6 @@ type GroupDetailsService struct { groupID *string } -type GroupDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - Name string `json:"name"` - CreatedAt time.Time `json:"created_at"` - } `json:"data"` -} - func (c *Client) NewGroupDetails() *GroupDetailsService { return &GroupDetailsService{c: c} } @@ -33,8 +25,8 @@ func (s *GroupDetailsService) GroupID(value string) *GroupDetailsService { return s } -func (s *GroupDetailsService) Do(ctx context.Context) (GroupDetailsResponse, error) { - var response GroupDetailsResponse +func (s *GroupDetailsService) Do(ctx context.Context) (groups.GroupDetailsResponse, error) { + var response groups.GroupDetailsResponse if s.groupID == nil { return response, fmt.Errorf("missing required GroupID") @@ -45,18 +37,18 @@ func (s *GroupDetailsService) Do(ctx context.Context) (GroupDetailsResponse, err headers := s.c.commonHeaders() - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_details_test.go b/group_details_test.go index 2cc5dd71..993b0ee7 100644 --- a/group_details_test.go +++ b/group_details_test.go @@ -3,17 +3,19 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupDetailsE2E(t *testing.T) { - result, err := Client.NewGroupDetails().GroupID(PredefinedGroupId).Do(context.Background()) + result, err := testutils.Client.NewGroupDetails().GroupID(testutils.PredefinedGroupId).Do(context.Background()) if err != nil { t.Logf("%+v\n", result) t.Error(err) } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.ID, PredefinedGroupId) - AssertEqual(t, result.Data.Name, PredefinedGroupName) - AssertEqual(t, result.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.ID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, result.Data.Name, testutils.PredefinedGroupName) + testutils.AssertEqual(t, result.Data.CreatedAt.IsZero(), false) } diff --git a/group_list_connectors.go b/group_list_connectors.go index 2c8f4405..e5b2eaea 100644 --- a/group_list_connectors.go +++ b/group_list_connectors.go @@ -4,7 +4,10 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/common" + "github.com/fivetran/go-fivetran/connectors" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupListConnectorsService implements the Group Management, List All Connectors within a Group API. @@ -17,45 +20,20 @@ type GroupListConnectorsService struct { schema *string } -type ConnectorTasks struct { - Code string `json:"code"` - Message string `json:"message"` -} - -type ConnectorWarning struct { - Code string `json:"code"` - Message string `json:"message"` -} - type ConnectorsStatus struct { - SetupState string `json:"setup_state"` - SyncState string `json:"sync_state"` - UpdateState string `json:"update_state"` - IsHistoricalSync *bool `json:"is_historical_sync"` - Tasks []ConnectorTasks `json:"tasks"` - Warnings []ConnectorWarning `json:"warnings"` + SetupState string `json:"setup_state"` + SyncState string `json:"sync_state"` + UpdateState string `json:"update_state"` + IsHistoricalSync *bool `json:"is_historical_sync"` + Tasks []common.CommonResponse `json:"tasks"` + Warnings []common.CommonResponse `json:"warnings"` } type GroupListConnectorsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Items []struct { - ID string `json:"id"` - GroupID string `json:"group_id"` - Service string `json:"service"` - ServiceVersion *int `json:"service_version"` - Schema string `json:"schema"` - ConnectedBy string `json:"connected_by"` - CreatedAt time.Time `json:"created_at"` - SucceededAt time.Time `json:"succeeded_at"` - FailedAt time.Time `json:"failed_at"` - SyncFrequency *int `json:"sync_frequency"` - ScheduleType string `json:"schedule_type"` - Status ConnectorsStatus `json:"status"` - DailySyncTime string `json:"daily_sync_time"` - } `json:"items"` - NextCursor string `json:"next_cursor"` + common.CommonResponse + Data struct { + Items []connectors.DetailsResponseDataCommon `json:"items"` + NextCursor string `json:"next_cursor"` } `json:"data"` } @@ -106,18 +84,18 @@ func (s *GroupListConnectorsService) Do(ctx context.Context) (GroupListConnector queries["schema"] = *s.schema } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_list_connectors_test.go b/group_list_connectors_test.go index 0f1e814e..3a336f3c 100644 --- a/group_list_connectors_test.go +++ b/group_list_connectors_test.go @@ -3,41 +3,43 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupListConnectorsE2E(t *testing.T) { - connectorId := CreateTempConnector(t) - connectors, err := Client.NewGroupListConnectors().GroupID(PredefinedGroupId).Do(context.Background()) + connectorId := testutils.CreateTempConnector(t) + connectors, err := testutils.Client.NewGroupListConnectors().GroupID(testutils.PredefinedGroupId).Do(context.Background()) if err != nil { t.Logf("%+v\n", connectors) t.Error(err) } - AssertEqual(t, connectors.Code, "Success") - AssertHasLength(t, connectors.Data.Items, 1) + testutils.AssertEqual(t, connectors.Code, "Success") + testutils.AssertHasLength(t, connectors.Data.Items, 1) - AssertEqual(t, connectors.Data.Items[0].ID, connectorId) - AssertEqual(t, connectors.Data.Items[0].GroupID, PredefinedGroupId) - AssertEqual(t, connectors.Data.Items[0].Service, "itunes_connect") - AssertEqual(t, *connectors.Data.Items[0].ServiceVersion, 1) - AssertEqual(t, connectors.Data.Items[0].Schema, "itunes_e2e_connect") - AssertEqual(t, connectors.Data.Items[0].ConnectedBy, PredefinedUserId) - AssertEqual(t, connectors.Data.Items[0].CreatedAt.IsZero(), false) - AssertEqual(t, connectors.Data.Items[0].SucceededAt.IsZero(), true) - AssertEqual(t, connectors.Data.Items[0].FailedAt.IsZero(), true) + testutils.AssertEqual(t, connectors.Data.Items[0].ID, connectorId) + testutils.AssertEqual(t, connectors.Data.Items[0].GroupID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, connectors.Data.Items[0].Service, "itunes_connect") + testutils.AssertEqual(t, *connectors.Data.Items[0].ServiceVersion, 1) + testutils.AssertEqual(t, connectors.Data.Items[0].Schema, "itunes_e2e_connect") + testutils.AssertEqual(t, connectors.Data.Items[0].ConnectedBy, testutils.PredefinedUserId) + testutils.AssertEqual(t, connectors.Data.Items[0].CreatedAt.IsZero(), false) + testutils.AssertEqual(t, connectors.Data.Items[0].SucceededAt.IsZero(), true) + testutils.AssertEqual(t, connectors.Data.Items[0].FailedAt.IsZero(), true) //todo: map Paused and PauseAfterTrial - //AssertEqual(t, *connectors.Data.Items[0].Paused, false) - //AssertEqual(t, *connectors.Data.Items[0].PauseAfterTrial, false) - - AssertEqual(t, *connectors.Data.Items[0].SyncFrequency, 360) - AssertEqual(t, connectors.Data.Items[0].ScheduleType, "auto") - - AssertEqual(t, connectors.Data.Items[0].Status.SetupState, "incomplete") - AssertEqual(t, connectors.Data.Items[0].Status.SyncState, "scheduled") - AssertEqual(t, connectors.Data.Items[0].Status.UpdateState, "on_schedule") - AssertEqual(t, *connectors.Data.Items[0].Status.IsHistoricalSync, true) - AssertHasLength(t, connectors.Data.Items[0].Status.Tasks, 0) - AssertHasLength(t, connectors.Data.Items[0].Status.Warnings, 0) + //testutils.AssertEqual(t, *connectors.Data.Items[0].Paused, false) + //testutils.AssertEqual(t, *connectors.Data.Items[0].PauseAfterTrial, false) + + testutils.AssertEqual(t, *connectors.Data.Items[0].SyncFrequency, 360) + testutils.AssertEqual(t, connectors.Data.Items[0].ScheduleType, "auto") + + testutils.AssertEqual(t, connectors.Data.Items[0].Status.SetupState, "incomplete") + testutils.AssertEqual(t, connectors.Data.Items[0].Status.SyncState, "scheduled") + testutils.AssertEqual(t, connectors.Data.Items[0].Status.UpdateState, "on_schedule") + testutils.AssertEqual(t, *connectors.Data.Items[0].Status.IsHistoricalSync, true) + testutils.AssertHasLength(t, connectors.Data.Items[0].Status.Tasks, 0) + testutils.AssertHasLength(t, connectors.Data.Items[0].Status.Warnings, 0) } diff --git a/group_list_users.go b/group_list_users.go index 9ae704db..64f81f3e 100644 --- a/group_list_users.go +++ b/group_list_users.go @@ -4,7 +4,10 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/users" ) // GroupListUsersService implements the Group Management, List All Users within a Group API. @@ -17,24 +20,10 @@ type GroupListUsersService struct { } type GroupListUsersResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Items []struct { - ID string `json:"id"` - Email string `json:"email"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Verified *bool `json:"verified"` - Invited *bool `json:"invited"` - Picture string `json:"picture"` - Phone string `json:"phone"` - Role string `json:"role"` - LoggedInAt time.Time `json:"logged_in_at"` - CreatedAt time.Time `json:"created_at"` - Active *bool `json:"active"` - } `json:"items"` - NextCursor string `json:"next_cursor"` + common.CommonResponse + Data struct { + Items []users.UserDetailsData `json:"items"` + NextCursor string `json:"next_cursor"` } `json:"data"` } @@ -77,18 +66,18 @@ func (s *GroupListUsersService) Do(ctx context.Context) (GroupListUsersResponse, queries["limit"] = fmt.Sprint(*s.limit) } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_list_users_test.go b/group_list_users_test.go index 574ae337..f2785790 100644 --- a/group_list_users_test.go +++ b/group_list_users_test.go @@ -3,27 +3,29 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupListUsersE2E(t *testing.T) { - users, err := Client.NewGroupListUsers().GroupID(PredefinedGroupId).Do(context.Background()) + users, err := testutils.Client.NewGroupListUsers().GroupID(testutils.PredefinedGroupId).Do(context.Background()) if err != nil { t.Logf("%+v\n", users) t.Error(err) } - AssertEqual(t, users.Code, "Success") - AssertHasLength(t, users.Data.Items, 1) - AssertEqual(t, users.Data.Items[0].ID, PredefinedUserId) - AssertEqual(t, users.Data.Items[0].Email, PredefinedUserEmail) - AssertEqual(t, users.Data.Items[0].GivenName, PredefinedUserGivenName) - AssertEqual(t, users.Data.Items[0].FamilyName, PredefinedUserFamilyName) - AssertEqual(t, *users.Data.Items[0].Verified, true) - AssertEqual(t, *users.Data.Items[0].Invited, false) - AssertEmpty(t, users.Data.Items[0].Picture) - AssertEqual(t, users.Data.Items[0].Phone, PredefinedUserPhone) - AssertEqual(t, users.Data.Items[0].LoggedInAt.IsZero(), false) - AssertEqual(t, users.Data.Items[0].CreatedAt.IsZero(), false) - AssertEmpty(t, users.Data.NextCursor) + testutils.AssertEqual(t, users.Code, "Success") + testutils.AssertHasLength(t, users.Data.Items, 1) + testutils.AssertEqual(t, users.Data.Items[0].ID, testutils.PredefinedUserId) + testutils.AssertEqual(t, users.Data.Items[0].Email, testutils.PredefinedUserEmail) + testutils.AssertEqual(t, users.Data.Items[0].GivenName, testutils.PredefinedUserGivenName) + testutils.AssertEqual(t, users.Data.Items[0].FamilyName, testutils.PredefinedUserFamilyName) + testutils.AssertEqual(t, *users.Data.Items[0].Verified, true) + testutils.AssertEqual(t, *users.Data.Items[0].Invited, false) + testutils.AssertEmpty(t, users.Data.Items[0].Picture) + testutils.AssertEqual(t, users.Data.Items[0].Phone, testutils.PredefinedUserPhone) + testutils.AssertEqual(t, users.Data.Items[0].LoggedInAt.IsZero(), false) + testutils.AssertEqual(t, users.Data.Items[0].CreatedAt.IsZero(), false) + testutils.AssertEmpty(t, users.Data.NextCursor) } diff --git a/group_modify.go b/group_modify.go index 6cf68fe2..551c598a 100644 --- a/group_modify.go +++ b/group_modify.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/groups" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupModifyService implements the Group Management, Modify a Group API. @@ -19,16 +21,6 @@ type groupModifyRequest struct { Name *string `json:"name,omitempty"` } -type GroupModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - Name string `json:"name"` - CreatedAt time.Time `json:"created_at"` - } `json:"data"` -} - func (c *Client) NewGroupModify() *GroupModifyService { return &GroupModifyService{c: c} } @@ -49,8 +41,8 @@ func (s *GroupModifyService) Name(value string) *GroupModifyService { return s } -func (s *GroupModifyService) Do(ctx context.Context) (GroupModifyResponse, error) { - var response GroupModifyResponse +func (s *GroupModifyService) Do(ctx context.Context) (groups.GroupDetailsResponse, error) { + var response groups.GroupDetailsResponse if s.groupID == nil { return response, fmt.Errorf("missing required GroupID") @@ -67,18 +59,18 @@ func (s *GroupModifyService) Do(ctx context.Context) (GroupModifyResponse, error return response, err } - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_modify_test.go b/group_modify_test.go index cec85270..31acb832 100644 --- a/group_modify_test.go +++ b/group_modify_test.go @@ -3,19 +3,21 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupModifyE2E(t *testing.T) { - groupId := CreateTempGroup(t) + groupId := testutils.CreateTempGroup(t) - updated, err := Client.NewGroupModify().GroupID(groupId).Name("test_updated").Do(context.Background()) + updated, err := testutils.Client.NewGroupModify().GroupID(groupId).Name("test_updated").Do(context.Background()) if err != nil { t.Logf("%+v\n", updated) t.Error(err) } - AssertEqual(t, updated.Code, "Success") - AssertEqual(t, updated.Data.ID, groupId) - AssertEqual(t, updated.Data.Name, "test_updated") - AssertEqual(t, updated.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, updated.Code, "Success") + testutils.AssertEqual(t, updated.Data.ID, groupId) + testutils.AssertEqual(t, updated.Data.Name, "test_updated") + testutils.AssertEqual(t, updated.Data.CreatedAt.IsZero(), false) } diff --git a/group_remove_user.go b/group_remove_user.go index 1ff184b1..d6e4e4cd 100644 --- a/group_remove_user.go +++ b/group_remove_user.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupRemoveUserService implements the Group Management, Remove a User from a Group API. @@ -14,11 +17,6 @@ type GroupRemoveUserService struct { userID *string } -type GroupRemoveUserResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewGroupRemoveUser() *GroupRemoveUserService { return &GroupRemoveUserService{c: c} } @@ -33,8 +31,8 @@ func (s *GroupRemoveUserService) UserID(value string) *GroupRemoveUserService { return s } -func (s *GroupRemoveUserService) Do(ctx context.Context) (GroupRemoveUserResponse, error) { - var response GroupRemoveUserResponse +func (s *GroupRemoveUserService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.groupID == nil { return response, fmt.Errorf("missing required GroupID") @@ -48,18 +46,18 @@ func (s *GroupRemoveUserService) Do(ctx context.Context) (GroupRemoveUserRespons headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/group_remove_user_test.go b/group_remove_user_test.go index dc1fcc8d..8a20172f 100644 --- a/group_remove_user_test.go +++ b/group_remove_user_test.go @@ -4,23 +4,25 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupRemoveUserE2E(t *testing.T) { - userId := CreateUser(t) - AddUserToGroup(t, PredefinedGroupId, "william_addison.@fivetran.com") + userId := testutils.CreateUser(t) + testutils.AddUserToGroup(t, testutils.PredefinedGroupId, "william_addison.@fivetran.com") - deleted, err := Client.NewGroupRemoveUser().GroupID(PredefinedGroupId).UserID(userId).Do(context.Background()) + deleted, err := testutils.Client.NewGroupRemoveUser().GroupID(testutils.PredefinedGroupId).UserID(userId).Do(context.Background()) if err != nil { t.Logf("%+v\n", deleted) t.Error(err) } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, userId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, userId), true) t.Cleanup(func() { - DeleteUser(t, userId) + testutils.DeleteUser(t, userId) }) } diff --git a/groups/common_types.go b/groups/common_types.go new file mode 100644 index 00000000..2f8a1afe --- /dev/null +++ b/groups/common_types.go @@ -0,0 +1,18 @@ +package groups + +import ( + "time" + + "github.com/fivetran/go-fivetran/common" +) + +type GroupItem struct { + ID string `json:"id"` + Name string `json:"name"` + CreatedAt time.Time `json:"created_at"` +} + +type GroupDetailsResponse struct { + common.CommonResponse + Data GroupItem `json:"data"` +} diff --git a/groups_list.go b/groups_list.go index bac8edad..1082484d 100644 --- a/groups_list.go +++ b/groups_list.go @@ -4,7 +4,10 @@ import ( "context" "encoding/json" "fmt" - "time" + + "github.com/fivetran/go-fivetran/common" + "github.com/fivetran/go-fivetran/groups" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // GroupsListService implements the Group Management, List All Groups API. @@ -16,15 +19,10 @@ type GroupsListService struct { } type GroupsListResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Items []struct { - ID string `json:"id"` - Name string `json:"name"` - CreatedAt time.Time `json:"created_at"` - } `json:"items"` - NextCursor string `json:"next_cursor"` + common.CommonResponse + Data struct { + Items []groups.GroupItem `json:"items"` + NextCursor string `json:"next_cursor"` } `json:"data"` } @@ -57,18 +55,18 @@ func (s *GroupsListService) Do(ctx context.Context) (GroupsListResponse, error) queries["limit"] = fmt.Sprint(*s.limit) } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/groups_list_test.go b/groups_list_test.go index 8d259cf4..cb703c50 100644 --- a/groups_list_test.go +++ b/groups_list_test.go @@ -3,20 +3,22 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewGroupsListE2E(t *testing.T) { - result, err := Client.NewGroupsList().Do(context.Background()) + result, err := testutils.Client.NewGroupsList().Do(context.Background()) if err != nil { t.Logf("%+v\n", result) t.Error(err) } - AssertEqual(t, result.Code, "Success") - AssertHasLength(t, result.Data.Items, 1) - AssertEmpty(t, result.Message) - AssertEqual(t, result.Data.Items[0].ID, PredefinedGroupId) - AssertEqual(t, result.Data.Items[0].Name, PredefinedGroupName) - AssertEqual(t, result.Data.Items[0].CreatedAt.IsZero(), false) - AssertEmpty(t, result.Data.NextCursor) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertHasLength(t, result.Data.Items, 1) + testutils.AssertEmpty(t, result.Message) + testutils.AssertEqual(t, result.Data.Items[0].ID, testutils.PredefinedGroupId) + testutils.AssertEqual(t, result.Data.Items[0].Name, testutils.PredefinedGroupName) + testutils.AssertEqual(t, result.Data.Items[0].CreatedAt.IsZero(), false) + testutils.AssertEmpty(t, result.Data.NextCursor) } diff --git a/http_request.go b/http_request.go deleted file mode 100644 index db31f7c0..00000000 --- a/http_request.go +++ /dev/null @@ -1,124 +0,0 @@ -package fivetran - -import ( - "bytes" - "context" - "errors" - "fmt" - "io" - "net/http" - "strconv" - "time" -) - -type request struct { - method string - url string - body []byte - queries map[string]string - headers map[string]string - client HttpClient - - handleRateLimits bool - maxRetryAttempts int -} - -func (req *request) httpRequest(ctx context.Context) ([]byte, int, error) { - return req.httpRequestImpl(ctx, 0) -} - -func (req *request) httpRequestImpl(ctx context.Context, attempt int) ([]byte, int, error) { - if req.client == nil { - return nil, 0, errors.New("HTTP client is not provided") - } - - newReq, err := http.NewRequestWithContext(ctx, req.method, req.url, bytes.NewReader(req.body)) - if err != nil { - return nil, 0, err - } - - if len(req.queries) > 0 { - query := newReq.URL.Query() - for k, v := range req.queries { - query.Add(k, v) - } - newReq.URL.RawQuery = query.Encode() - } - - for k, v := range req.headers { - newReq.Header.Add(k, v) - } - - if debug.enable { - fmt.Printf("---\nDebug:\n - HTTP Request:\n") - fmt.Printf(" - Method: %v\n", req.method) - fmt.Printf(" - URL: %v\n", newReq.URL.String()) - fmt.Printf(" - Body: %s\n", req.body) - fmt.Printf(" - Headers:\n") - for k, v := range req.headers { - if k == "Authorization" { - if debug.authEnable { - fmt.Printf(" - %v: %v\n", k, v) - } - if !debug.authEnable { - fmt.Printf(" - %v: \n", k) - } - continue - } - fmt.Printf(" - %v: %v\n", k, v) - } - } - - resp, err := req.client.Do(newReq) - if err != nil { - return nil, 0, err - } - defer resp.Body.Close() - - if resp.StatusCode == 429 && req.handleRateLimits { - if attempt > req.maxRetryAttempts { - return nil, resp.StatusCode, fmt.Errorf("rate limit retry max attempts count reached") - } - fmt.Println(resp) - retryAfterSeconds, err := strconv.Atoi(resp.Header.Get("Retry-After")) - if err != nil { - return nil, 0, err - } - if debug.enable { - fmt.Printf("\n\t- Waiting for retry: %v seconds left", retryAfterSeconds) - } - err = contextDelay(ctx, time.Duration(retryAfterSeconds)*time.Second) - if err != nil { - return nil, 0, err - } - if debug.enable { - fmt.Printf("\n\t- Retry attempt: %v", attempt) - } - return req.httpRequestImpl(ctx, attempt+1) - } - - respBody, err := io.ReadAll(resp.Body) - - if err != nil { - return nil, resp.StatusCode, err - } - - if debug.enable { - fmt.Printf(" - HTTP Response:\n") - fmt.Printf(" - Status Code: %v\n", resp.StatusCode) - fmt.Printf(" - Body: %s\n---\n", respBody) - } - - return respBody, resp.StatusCode, nil -} - -func contextDelay(ctx context.Context, d time.Duration) error { - t := time.NewTimer(d) - select { - case <-ctx.Done(): - t.Stop() - return fmt.Errorf("interrupted: context deadline exceeded") - case <-t.C: - } - return nil -} diff --git a/http_utils/http_client.go b/http_utils/http_client.go new file mode 100644 index 00000000..57cfaf1a --- /dev/null +++ b/http_utils/http_client.go @@ -0,0 +1,9 @@ +package httputils + +import "net/http" + +// HttpClient performs an HTTP request. Can be implemented by mocks +// to perform convenient unit tests +type HttpClient interface { + Do(req *http.Request) (*http.Response, error) +} diff --git a/http_utils/http_request.go b/http_utils/http_request.go new file mode 100644 index 00000000..29f0b802 --- /dev/null +++ b/http_utils/http_request.go @@ -0,0 +1,124 @@ +package httputils + +import ( + "bytes" + "context" + "errors" + "fmt" + "io" + "net/http" + "strconv" + "time" +) + +type Request struct { + Method string + Url string + Body []byte + Queries map[string]string + Headers map[string]string + Client HttpClient + + HandleRateLimits bool + MaxRetryAttempts int +} + +func (req *Request) Do(ctx context.Context) ([]byte, int, error) { + return req.do(ctx, 0) +} + +func (req *Request) do(ctx context.Context, attempt int) ([]byte, int, error) { + if req.Client == nil { + return nil, 0, errors.New("HTTP client is not provided") + } + + newReq, err := http.NewRequestWithContext(ctx, req.Method, req.Url, bytes.NewReader(req.Body)) + if err != nil { + return nil, 0, err + } + + if len(req.Queries) > 0 { + query := newReq.URL.Query() + for k, v := range req.Queries { + query.Add(k, v) + } + newReq.URL.RawQuery = query.Encode() + } + + for k, v := range req.Headers { + newReq.Header.Add(k, v) + } + + // if debug.enable { + // fmt.Printf("---\nDebug:\n - HTTP Request:\n") + // fmt.Printf(" - Method: %v\n", req.method) + // fmt.Printf(" - URL: %v\n", newReq.URL.String()) + // fmt.Printf(" - Body: %s\n", req.body) + // fmt.Printf(" - Headers:\n") + // for k, v := range req.headers { + // if k == "Authorization" { + // // if debug.authEnable { + // // fmt.Printf(" - %v: %v\n", k, v) + // // } + // // if !debug.authEnable { + // // fmt.Printf(" - %v: \n", k) + // // } + // continue + // } + // fmt.Printf(" - %v: %v\n", k, v) + // } + // } + + resp, err := req.Client.Do(newReq) + if err != nil { + return nil, 0, err + } + defer resp.Body.Close() + + if resp.StatusCode == 429 && req.HandleRateLimits { + if attempt > req.MaxRetryAttempts { + return nil, resp.StatusCode, fmt.Errorf("rate limit retry max attempts count reached") + } + fmt.Println(resp) + retryAfterSeconds, err := strconv.Atoi(resp.Header.Get("Retry-After")) + if err != nil { + return nil, 0, err + } + // if debug.enable { + // fmt.Printf("\n\t- Waiting for retry: %v seconds left", retryAfterSeconds) + // } + err = contextDelay(ctx, time.Duration(retryAfterSeconds)*time.Second) + if err != nil { + return nil, 0, err + } + // if debug.enable { + // fmt.Printf("\n\t- Retry attempt: %v", attempt) + // } + return req.do(ctx, attempt+1) + } + + respBody, err := io.ReadAll(resp.Body) + + if err != nil { + return nil, resp.StatusCode, err + } + + // if debug.enable { + // fmt.Printf(" - HTTP Response:\n") + // fmt.Printf(" - Status Code: %v\n", resp.StatusCode) + // fmt.Printf(" - Body: %s\n---\n", respBody) + // } + + return respBody, resp.StatusCode, nil +} + +func contextDelay(ctx context.Context, d time.Duration) error { + t := time.NewTimer(d) + select { + case <-ctx.Done(): + t.Stop() + return fmt.Errorf("interrupted: context deadline exceeded") + case <-t.C: + } + return nil +} diff --git a/http_utils/http_service.go b/http_utils/http_service.go new file mode 100644 index 00000000..1373576c --- /dev/null +++ b/http_utils/http_service.go @@ -0,0 +1,61 @@ +package httputils + +import ( + "context" + "encoding/json" + "fmt" +) + +type HttpService struct { + Method string + BaseUrl string + CommonHeaders map[string]string + Client HttpClient + HandleRateLimits bool + MaxRetryAttempts int + ExpectedStatus int +} + +func (s HttpService) Do( + ctx context.Context, + url string, + requestBody any, + queries map[string]string, + response any) error { + + var body []byte = nil + var err error = nil + + if requestBody != nil { + body, err = json.Marshal(requestBody) + if err != nil { + return err + } + } + + r := Request{ + Method: s.Method, + Url: s.BaseUrl + url, + Body: body, + Queries: queries, + Headers: s.CommonHeaders, + Client: s.Client, + HandleRateLimits: s.HandleRateLimits, + MaxRetryAttempts: s.MaxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return err + } + + if respStatus != s.ExpectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, s.ExpectedStatus) + return err + } + return nil +} diff --git a/metadata_columns_list.go b/metadata_columns_list.go index bb56fa02..706bacbb 100644 --- a/metadata_columns_list.go +++ b/metadata_columns_list.go @@ -1,99 +1,101 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // MetadataColumnsListService implements the Metadata Management, Retrieve Column metadata // Ref. https://fivetran.com/docs/rest-api/metadata#retrievecolumnmetadata type MetadataColumnsListService struct { - c *Client - limit *int - cursor *string - connectorId *string + c *Client + limit *int + cursor *string + connectorId *string } type MetadataColumnsListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - Id string `json:"id"` - ParentId string `json:"parent_id"` - NameInSource string `json:"name_in_source"` - NameInDestination string `json:"name_in_destination"` - TypeInSource string `json:"type_in_source"` - TypeInDestination string `json:"type_in_destination"` - IsPrimaryKey *bool `json:"is_primary_key"` - IsForeignKey *bool `json:"is_foreign_key"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []struct { + Id string `json:"id"` + ParentId string `json:"parent_id"` + NameInSource string `json:"name_in_source"` + NameInDestination string `json:"name_in_destination"` + TypeInSource string `json:"type_in_source"` + TypeInDestination string `json:"type_in_destination"` + IsPrimaryKey *bool `json:"is_primary_key"` + IsForeignKey *bool `json:"is_foreign_key"` + } `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewMetadataColumnsList() *MetadataColumnsListService { - return &MetadataColumnsListService{c: c} + return &MetadataColumnsListService{c: c} } func (s *MetadataColumnsListService) ConnectorId(value string) *MetadataColumnsListService { - s.connectorId = &value - return s + s.connectorId = &value + return s } func (s *MetadataColumnsListService) Limit(value int) *MetadataColumnsListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *MetadataColumnsListService) Cursor(value string) *MetadataColumnsListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *MetadataColumnsListService) Do(ctx context.Context) (MetadataColumnsListResponse, error) { - var response MetadataColumnsListResponse - url := fmt.Sprintf("%v/metadata/connectors/%v/columns", s.c.baseURL, *s.connectorId) - expectedStatus := 200 - - if s.connectorId == nil { - return response, fmt.Errorf("missing required connectorId") - } - - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } - - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response MetadataColumnsListResponse + url := fmt.Sprintf("%v/metadata/connectors/%v/columns", s.c.baseURL, *s.connectorId) + expectedStatus := 200 + + if s.connectorId == nil { + return response, fmt.Errorf("missing required connectorId") + } + + headers := s.c.commonHeaders() + + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/metadata_columns_list_test.go b/metadata_columns_list_test.go index df31b63c..e834e012 100644 --- a/metadata_columns_list_test.go +++ b/metadata_columns_list_test.go @@ -1,30 +1,32 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewMetadataColumnsE2E(t *testing.T) { - t.Skip("Skipping test until we will get more information about the status of this API") + t.Skip("Skipping test until we will get more information about the status of this API") - connectorId := CreateConnector(t) - details, err := Client.NewMetadataColumnsList().ConnectorId(connectorId).Do(context.Background()) + connectorId := testutils.CreateConnector(t) + details, err := testutils.Client.NewMetadataColumnsList().ConnectorId(connectorId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", details) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", details) + t.Error(err) + } - AssertEqual(t, details.Code, "Success") - AssertNotEmpty(t, details.Data.Items[0].Id) - AssertNotEmpty(t, details.Data.Items[0].ParentId) - AssertNotEmpty(t, details.Data.Items[0].NameInSource) - AssertNotEmpty(t, details.Data.Items[0].NameInDestination) - AssertNotEmpty(t, details.Data.Items[0].TypeInSource) - AssertNotEmpty(t, details.Data.Items[0].TypeInDestination) - AssertNotEmpty(t, details.Data.Items[0].IsPrimaryKey) - AssertNotEmpty(t, details.Data.Items[0].IsForeignKey) + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Data.Items[0].Id) + testutils.AssertNotEmpty(t, details.Data.Items[0].ParentId) + testutils.AssertNotEmpty(t, details.Data.Items[0].NameInSource) + testutils.AssertNotEmpty(t, details.Data.Items[0].NameInDestination) + testutils.AssertNotEmpty(t, details.Data.Items[0].TypeInSource) + testutils.AssertNotEmpty(t, details.Data.Items[0].TypeInDestination) + testutils.AssertNotEmpty(t, details.Data.Items[0].IsPrimaryKey) + testutils.AssertNotEmpty(t, details.Data.Items[0].IsForeignKey) - t.Cleanup(func() { DeleteConnector(t, connectorId) }) + t.Cleanup(func() { testutils.DeleteConnector(t, connectorId) }) } diff --git a/metadata_schemas_list.go b/metadata_schemas_list.go index a4c982d6..b5021560 100644 --- a/metadata_schemas_list.go +++ b/metadata_schemas_list.go @@ -1,94 +1,96 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // MetadataSchemasListService implements the Metadata Management, Retrieve schema metadata // Ref. https://fivetran.com/docs/rest-api/metadata#retrieveschemametadata type MetadataSchemasListService struct { - c *Client - limit *int - cursor *string - connectorId *string + c *Client + limit *int + cursor *string + connectorId *string } type MetadataSchemasListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - Id string `json:"id"` - NameInSource string `json:"name_in_source"` - NameInDestination string `json:"name_in_destination"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []struct { + Id string `json:"id"` + NameInSource string `json:"name_in_source"` + NameInDestination string `json:"name_in_destination"` + } `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewMetadataSchemasList() *MetadataSchemasListService { - return &MetadataSchemasListService{c: c} + return &MetadataSchemasListService{c: c} } func (s *MetadataSchemasListService) ConnectorId(value string) *MetadataSchemasListService { - s.connectorId = &value - return s + s.connectorId = &value + return s } func (s *MetadataSchemasListService) Limit(value int) *MetadataSchemasListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *MetadataSchemasListService) Cursor(value string) *MetadataSchemasListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *MetadataSchemasListService) Do(ctx context.Context) (MetadataSchemasListResponse, error) { - var response MetadataSchemasListResponse - url := fmt.Sprintf("%v/metadata/connectors/%v/schemas", s.c.baseURL, *s.connectorId) - expectedStatus := 200 - - if s.connectorId == nil { - return response, fmt.Errorf("missing required connectorId") - } - - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } - - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response MetadataSchemasListResponse + url := fmt.Sprintf("%v/metadata/connectors/%v/schemas", s.c.baseURL, *s.connectorId) + expectedStatus := 200 + + if s.connectorId == nil { + return response, fmt.Errorf("missing required connectorId") + } + + headers := s.c.commonHeaders() + + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/metadata_schemas_list_test.go b/metadata_schemas_list_test.go index e65babf1..4b163d09 100644 --- a/metadata_schemas_list_test.go +++ b/metadata_schemas_list_test.go @@ -1,25 +1,27 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewMetadataSchemasE2E(t *testing.T) { - t.Skip("Skipping test until we will get more information about the status of this API") + t.Skip("Skipping test until we will get more information about the status of this API") - connectorId := CreateConnector(t) - details, err := Client.NewMetadataSchemasList().ConnectorId(connectorId).Do(context.Background()) + connectorId := testutils.CreateConnector(t) + details, err := testutils.Client.NewMetadataSchemasList().ConnectorId(connectorId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", details) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", details) + t.Error(err) + } - AssertEqual(t, details.Code, "Success") - AssertNotEmpty(t, details.Data.Items[0].Id) - AssertNotEmpty(t, details.Data.Items[0].NameInSource) - AssertNotEmpty(t, details.Data.Items[0].NameInDestination) + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Data.Items[0].Id) + testutils.AssertNotEmpty(t, details.Data.Items[0].NameInSource) + testutils.AssertNotEmpty(t, details.Data.Items[0].NameInDestination) - t.Cleanup(func() { DeleteConnector(t, connectorId) }) + t.Cleanup(func() { testutils.DeleteConnector(t, connectorId) }) } diff --git a/metadata_tables_list.go b/metadata_tables_list.go index 031169ff..6a876ab2 100644 --- a/metadata_tables_list.go +++ b/metadata_tables_list.go @@ -1,95 +1,97 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // MetadataTableListService implements the Metadata Management, Retrieve table metadata // Ref. https://fivetran.com/docs/rest-api/metadata#retrievetablemetadata type MetadataTablesListService struct { - c *Client - limit *int - cursor *string - connectorId *string + c *Client + limit *int + cursor *string + connectorId *string } type MetadataTablesListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - Id string `json:"id"` - ParentId string `json:"parent_id"` - NameInSource string `json:"name_in_source"` - NameInDestination string `json:"name_in_destination"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []struct { + Id string `json:"id"` + ParentId string `json:"parent_id"` + NameInSource string `json:"name_in_source"` + NameInDestination string `json:"name_in_destination"` + } `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewMetadataTablesList() *MetadataTablesListService { - return &MetadataTablesListService{c: c} + return &MetadataTablesListService{c: c} } func (s *MetadataTablesListService) ConnectorId(value string) *MetadataTablesListService { - s.connectorId = &value - return s + s.connectorId = &value + return s } func (s *MetadataTablesListService) Limit(value int) *MetadataTablesListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *MetadataTablesListService) Cursor(value string) *MetadataTablesListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *MetadataTablesListService) Do(ctx context.Context) (MetadataTablesListResponse, error) { - var response MetadataTablesListResponse - url := fmt.Sprintf("%v/metadata/connectors/%v/tables", s.c.baseURL, *s.connectorId) - expectedStatus := 200 - - if s.connectorId == nil { - return response, fmt.Errorf("missing required connectorId") - } - - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } - - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response MetadataTablesListResponse + url := fmt.Sprintf("%v/metadata/connectors/%v/tables", s.c.baseURL, *s.connectorId) + expectedStatus := 200 + + if s.connectorId == nil { + return response, fmt.Errorf("missing required connectorId") + } + + headers := s.c.commonHeaders() + + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/metadata_tables_list_test.go b/metadata_tables_list_test.go index 5e2bc3b7..c3239166 100644 --- a/metadata_tables_list_test.go +++ b/metadata_tables_list_test.go @@ -1,26 +1,28 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewMetadataTableE2E(t *testing.T) { - t.Skip("Skipping test until we will get more information about the status of this API") + t.Skip("Skipping test until we will get more information about the status of this API") - connectorId := CreateConnector(t) - details, err := Client.NewMetadataTablesList().ConnectorId(connectorId).Do(context.Background()) + connectorId := testutils.CreateConnector(t) + details, err := testutils.Client.NewMetadataTablesList().ConnectorId(connectorId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", details) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", details) + t.Error(err) + } - AssertEqual(t, details.Code, "Success") - AssertNotEmpty(t, details.Data.Items[0].Id) - AssertNotEmpty(t, details.Data.Items[0].ParentId) - AssertNotEmpty(t, details.Data.Items[0].NameInSource) - AssertNotEmpty(t, details.Data.Items[0].NameInDestination) + testutils.AssertEqual(t, details.Code, "Success") + testutils.AssertNotEmpty(t, details.Data.Items[0].Id) + testutils.AssertNotEmpty(t, details.Data.Items[0].ParentId) + testutils.AssertNotEmpty(t, details.Data.Items[0].NameInSource) + testutils.AssertNotEmpty(t, details.Data.Items[0].NameInDestination) - t.Cleanup(func() { DeleteConnector(t, connectorId) }) + t.Cleanup(func() { testutils.DeleteConnector(t, connectorId) }) } diff --git a/roles_list.go b/roles_list.go index e8d2a204..0a12dedf 100644 --- a/roles_list.go +++ b/roles_list.go @@ -1,85 +1,87 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // RolesListService implements the Group Management, List All Roles API. // Ref. https://fivetran.com/docs/rest-api/roles type RolesListService struct { - c *Client - limit *int - cursor *string + c *Client + limit *int + cursor *string } type RolesListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - Name string `json:"name"` - Description string `json:"description"` - IsCustom *bool `json:"is_custom"` - Scope []string `json:"scope"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []struct { + Name string `json:"name"` + Description string `json:"description"` + IsCustom *bool `json:"is_custom"` + Scope []string `json:"scope"` + } `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewRolesList() *RolesListService { - return &RolesListService{c: c} + return &RolesListService{c: c} } func (s *RolesListService) Limit(value int) *RolesListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *RolesListService) Cursor(value string) *RolesListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *RolesListService) Do(ctx context.Context) (RolesListResponse, error) { - var response RolesListResponse - url := fmt.Sprintf("%v/roles", s.c.baseURL) - expectedStatus := 200 + var response RolesListResponse + url := fmt.Sprintf("%v/roles", s.c.baseURL) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/roles_list_test.go b/roles_list_test.go index 06caaba8..9e943fc5 100644 --- a/roles_list_test.go +++ b/roles_list_test.go @@ -3,17 +3,19 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewRolesListE2E(t *testing.T) { - result, err := Client.NewRolesList().Do(context.Background()) + result, err := testutils.Client.NewRolesList().Do(context.Background()) if err != nil { t.Logf("%+v\n", result) t.Error(err) } - AssertEqual(t, result.Code, "Success") - AssertNotEmpty(t, result.Data.Items[0].Name) - AssertNotEmpty(t, result.Data.Items[0].Description) - AssertNotEmpty(t, result.Data.Items[0].Scope) -} \ No newline at end of file + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertNotEmpty(t, result.Data.Items[0].Name) + testutils.AssertNotEmpty(t, result.Data.Items[0].Description) + testutils.AssertNotEmpty(t, result.Data.Items[0].Scope) +} diff --git a/team_connector_membership_create.go b/team_connector_membership_create.go index 43d16ba9..d9696d76 100644 --- a/team_connector_membership_create.go +++ b/team_connector_membership_create.go @@ -1,102 +1,103 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamConnectorsCreateService implements the Team Management, Add connector membership // Ref. https://fivetran.com/docs/rest-api/teams#addconnectormembership type TeamConnectorMembershipCreateService struct { - c *Client - teamId *string - connectorId *string - role *string + c *Client + teamId *string + connectorId *string + role *string } type teamConnectorMembershipCreateRequest struct { - ConnectorId *string `json:"id,omitempty"` - Role *string `json:"role,omitempty"` + ConnectorId *string `json:"id,omitempty"` + Role *string `json:"role,omitempty"` } type TeamConnectorMembershipCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ConnectorId string `json:"id"` - Role string `json:"role"` - CreatedAt string `json:"created_at"` - } `json:"data"` + common.CommonResponse + Data teams.TeamConnectorMembership `json:"data"` } func (c *Client) NewTeamConnectorMembershipCreate() *TeamConnectorMembershipCreateService { - return &TeamConnectorMembershipCreateService{c: c} + return &TeamConnectorMembershipCreateService{c: c} } func (s *TeamConnectorMembershipCreateService) request() *teamConnectorMembershipCreateRequest { - return &teamConnectorMembershipCreateRequest{ - ConnectorId: s.connectorId, - Role: s.role, - } + return &teamConnectorMembershipCreateRequest{ + ConnectorId: s.connectorId, + Role: s.role, + } } func (s *TeamConnectorMembershipCreateService) TeamId(value string) *TeamConnectorMembershipCreateService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamConnectorMembershipCreateService) ConnectorId(value string) *TeamConnectorMembershipCreateService { - s.connectorId = &value - return s + s.connectorId = &value + return s } func (s *TeamConnectorMembershipCreateService) Role(value string) *TeamConnectorMembershipCreateService { - s.role = &value - return s + s.role = &value + return s } func (s *TeamConnectorMembershipCreateService) Do(ctx context.Context) (TeamConnectorMembershipCreateResponse, error) { - var response TeamConnectorMembershipCreateResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - url := fmt.Sprintf("%v/teams/%v/connectors", s.c.baseURL, *s.teamId) - expectedStatus := 201 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamConnectorMembershipCreateResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + url := fmt.Sprintf("%v/teams/%v/connectors", s.c.baseURL, *s.teamId) + expectedStatus := 201 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_connector_membership_create_test.go b/team_connector_membership_create_test.go index 73fbae96..a1e471de 100644 --- a/team_connector_membership_create_test.go +++ b/team_connector_membership_create_test.go @@ -1,34 +1,36 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamConnectorMembershipCreateE2E(t *testing.T) { - teamId := CreateTeam(t) - connectorId := CreateConnector(t) + teamId := testutils.CreateTeam(t) + connectorId := testutils.CreateConnector(t) + + created, err := testutils.Client.NewTeamConnectorMembershipCreate(). + TeamId(teamId). + ConnectorId(connectorId). + Role("Connector Administrator"). + Do(context.Background()) - created, err := Client.NewTeamConnectorMembershipCreate(). - TeamId(teamId). - ConnectorId(connectorId). - Role("Connector Administrator"). - Do(context.Background()) + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertEqual(t, created.Message, "Connector membership has been created") + testutils.AssertEqual(t, created.Data.ConnectorId, connectorId) + testutils.AssertEqual(t, created.Data.Role, "Connector Administrator") + testutils.AssertNotEmpty(t, created.Data.CreatedAt) - AssertEqual(t, created.Code, "Success") - AssertEqual(t, created.Message, "Connector membership has been created") - AssertEqual(t, created.Data.ConnectorId, connectorId) - AssertEqual(t, created.Data.Role, "Connector Administrator") - AssertNotEmpty(t, created.Data.CreatedAt) - - t.Cleanup(func() { - DeleteTeamConnector(t, teamId, connectorId) - DeleteConnector(t, connectorId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamConnector(t, teamId, connectorId) + testutils.DeleteConnector(t, connectorId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_connector_membership_delete.go b/team_connector_membership_delete.go index dd39de1f..818123cb 100644 --- a/team_connector_membership_delete.go +++ b/team_connector_membership_delete.go @@ -1,76 +1,76 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamConnectorMembershipDeleteService implements the Team Management, Delete connector membership // Ref. https://fivetran.com/docs/rest-api/teams#deleteconnectormembership type TeamConnectorMembershipDeleteService struct { - c *Client - teamId *string - connectorId *string -} - -type TeamConnectorMembershipDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` + c *Client + teamId *string + connectorId *string } func (c *Client) NewTeamConnectorMembershipDelete() *TeamConnectorMembershipDeleteService { - return &TeamConnectorMembershipDeleteService{c: c} + return &TeamConnectorMembershipDeleteService{c: c} } func (s *TeamConnectorMembershipDeleteService) TeamId(value string) *TeamConnectorMembershipDeleteService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamConnectorMembershipDeleteService) ConnectorId(value string) *TeamConnectorMembershipDeleteService { - s.connectorId = &value - return s + s.connectorId = &value + return s } -func (s *TeamConnectorMembershipDeleteService) Do(ctx context.Context) (TeamConnectorMembershipDeleteResponse, error) { - var response TeamConnectorMembershipDeleteResponse +func (s *TeamConnectorMembershipDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } - if s.connectorId == nil { - return response, fmt.Errorf("missing required connectorId") - } + if s.connectorId == nil { + return response, fmt.Errorf("missing required connectorId") + } - url := fmt.Sprintf("%v/teams/%v/connectors/%v", s.c.baseURL, *s.teamId, *s.connectorId) - expectedStatus := 200 + url := fmt.Sprintf("%v/teams/%v/connectors/%v", s.c.baseURL, *s.teamId, *s.connectorId) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/team_connector_membership_delete_test.go b/team_connector_membership_delete_test.go index d074875b..ce8b0c36 100644 --- a/team_connector_membership_delete_test.go +++ b/team_connector_membership_delete_test.go @@ -1,30 +1,32 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamConnectorMebershipDeleteE2E(t *testing.T) { - teamId := CreateTeam(t) - connectorId := CreateConnector(t) - CreateTeamConnector(t, teamId, connectorId) + teamId := testutils.CreateTeam(t) + connectorId := testutils.CreateConnector(t) + testutils.CreateTeamConnector(t, teamId, connectorId) - deleted, err := Client.NewTeamConnectorMembershipDelete(). - TeamId(teamId). - ConnectorId(connectorId). - Do(context.Background()) + deleted, err := testutils.Client.NewTeamConnectorMembershipDelete(). + TeamId(teamId). + ConnectorId(connectorId). + Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } - AssertEqual(t, deleted.Code, "Success") - AssertEqual(t, deleted.Message, "Connector membership has been deleted") + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertEqual(t, deleted.Message, "Connector membership has been deleted") - t.Cleanup(func() { - DeleteConnector(t, connectorId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteConnector(t, connectorId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_connector_membership_details.go b/team_connector_membership_details.go index 71d429bb..5990fb82 100644 --- a/team_connector_membership_details.go +++ b/team_connector_membership_details.go @@ -1,81 +1,83 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamConnectorMembershipDetailsService implements the Team Management, Retrieve connector membership // Ref. https://fivetran.com/docs/rest-api/teams#retrieveconnectormembership type TeamConnectorMembershipDetailsService struct { - c *Client - teamId *string - connectorId *string + c *Client + teamId *string + connectorId *string } type TeamConnectorMembershipDetailsResponse struct { - Code string `json:"code"` - Data struct { - ConnectorId string `json:"id"` - Role string `json:"role"` - CreatedAt string `json:"created_at"` - } `json:"data"` + Code string `json:"code"` + Data teams.TeamConnectorMembership `json:"data"` } func (c *Client) NewTeamConnectorMembershipDetails() *TeamConnectorMembershipDetailsService { - return &TeamConnectorMembershipDetailsService{c: c} + return &TeamConnectorMembershipDetailsService{c: c} } func (s *TeamConnectorMembershipDetailsService) TeamId(value string) *TeamConnectorMembershipDetailsService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamConnectorMembershipDetailsService) ConnectorId(value string) *TeamConnectorMembershipDetailsService { - s.connectorId = &value - return s + s.connectorId = &value + return s } func (s *TeamConnectorMembershipDetailsService) Do(ctx context.Context) (TeamConnectorMembershipDetailsResponse, error) { - var response TeamConnectorMembershipDetailsResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - if s.connectorId == nil { - return response, fmt.Errorf("missing required connectorId") - } - - url := fmt.Sprintf("%v/teams/%v/connectors/%v", s.c.baseURL, *s.teamId, *s.connectorId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - r := request{ - method: "GET", - url: url, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamConnectorMembershipDetailsResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + if s.connectorId == nil { + return response, fmt.Errorf("missing required connectorId") + } + + url := fmt.Sprintf("%v/teams/%v/connectors/%v", s.c.baseURL, *s.teamId, *s.connectorId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_connector_membership_details_test.go b/team_connector_membership_details_test.go index 973096ef..da55993e 100644 --- a/team_connector_membership_details_test.go +++ b/team_connector_membership_details_test.go @@ -1,32 +1,34 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamConnectorMembershipDetailsE2E(t *testing.T) { - teamId := CreateTeam(t) - connectorId := CreateConnector(t) - CreateTeamConnector(t, teamId, connectorId) + teamId := testutils.CreateTeam(t) + connectorId := testutils.CreateConnector(t) + testutils.CreateTeamConnector(t, teamId, connectorId) - result, err := Client.NewTeamConnectorMembershipDetails(). - TeamId(teamId). - ConnectorId(connectorId). - Do(context.Background()) - if err != nil { - t.Logf("%+v\n", result) - t.Error(err) - } + result, err := testutils.Client.NewTeamConnectorMembershipDetails(). + TeamId(teamId). + ConnectorId(connectorId). + Do(context.Background()) + if err != nil { + t.Logf("%+v\n", result) + t.Error(err) + } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.ConnectorId, connectorId) - AssertEqual(t, result.Data.Role, "Connector Administrator") - AssertNotEmpty(t, result.Data.CreatedAt) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.ConnectorId, connectorId) + testutils.AssertEqual(t, result.Data.Role, "Connector Administrator") + testutils.AssertNotEmpty(t, result.Data.CreatedAt) - t.Cleanup(func() { - DeleteTeamConnector(t, teamId, connectorId) - DeleteConnector(t, connectorId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamConnector(t, teamId, connectorId) + testutils.DeleteConnector(t, connectorId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_connector_membership_modify.go b/team_connector_membership_modify.go index 6f33e6a1..4e0fbaf1 100644 --- a/team_connector_membership_modify.go +++ b/team_connector_membership_modify.go @@ -1,99 +1,99 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamConnectorMembershipModifyService implements the Team Management, Update connector membership // Ref. https://fivetran.com/docs/rest-api/teams#updateconnectormembership type TeamConnectorMembershipModifyService struct { - c *Client - teamId *string - connectorId *string - role *string + c *Client + teamId *string + connectorId *string + role *string } type teamConnectorMembershipModifyRequest struct { - Role *string `json:"role,omitempty"` -} - -type TeamConnectorMembershipModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` + Role *string `json:"role,omitempty"` } func (c *Client) NewTeamConnectorMembershipModify() *TeamConnectorMembershipModifyService { - return &TeamConnectorMembershipModifyService{c: c} + return &TeamConnectorMembershipModifyService{c: c} } func (s *TeamConnectorMembershipModifyService) request() *teamConnectorMembershipModifyRequest { - return &teamConnectorMembershipModifyRequest{ - Role: s.role, - } + return &teamConnectorMembershipModifyRequest{ + Role: s.role, + } } func (s *TeamConnectorMembershipModifyService) TeamId(value string) *TeamConnectorMembershipModifyService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamConnectorMembershipModifyService) ConnectorId(value string) *TeamConnectorMembershipModifyService { - s.connectorId = &value - return s + s.connectorId = &value + return s } func (s *TeamConnectorMembershipModifyService) Role(value string) *TeamConnectorMembershipModifyService { - s.role = &value - return s + s.role = &value + return s } -func (s *TeamConnectorMembershipModifyService) Do(ctx context.Context) (TeamConnectorMembershipModifyResponse, error) { - var response TeamConnectorMembershipModifyResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - if s.connectorId == nil { - return response, fmt.Errorf("missing required connectorId") - } - - url := fmt.Sprintf("%v/teams/%v/connectors/%v", s.c.baseURL, *s.teamId, *s.connectorId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil +func (s *TeamConnectorMembershipModifyService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + if s.connectorId == nil { + return response, fmt.Errorf("missing required connectorId") + } + + url := fmt.Sprintf("%v/teams/%v/connectors/%v", s.c.baseURL, *s.teamId, *s.connectorId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_connector_membership_modify_test.go b/team_connector_membership_modify_test.go index 40fab13e..2669210d 100644 --- a/team_connector_membership_modify_test.go +++ b/team_connector_membership_modify_test.go @@ -1,32 +1,34 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamConnectorMembershipModifyE2E(t *testing.T) { - teamId := CreateTeam(t) - connectorId := CreateConnector(t) - CreateTeamConnector(t, teamId, connectorId) + teamId := testutils.CreateTeam(t) + connectorId := testutils.CreateConnector(t) + testutils.CreateTeamConnector(t, teamId, connectorId) + + modified, err := testutils.Client.NewTeamConnectorMembershipModify(). + TeamId(teamId). + ConnectorId(connectorId). + Role("Connector Collaborator"). + Do(context.Background()) - modified, err := Client.NewTeamConnectorMembershipModify(). - TeamId(teamId). - ConnectorId(connectorId). - Role("Connector Collaborator"). - Do(context.Background()) + if err != nil { + t.Logf("%+v\n", modified) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", modified) - t.Error(err) - } + testutils.AssertEqual(t, modified.Code, "Success") + testutils.AssertEqual(t, modified.Message, "Connector membership has been updated") - AssertEqual(t, modified.Code, "Success") - AssertEqual(t, modified.Message, "Connector membership has been updated") - - t.Cleanup(func() { - DeleteTeamConnector(t, teamId, connectorId) - DeleteConnector(t, connectorId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamConnector(t, teamId, connectorId) + testutils.DeleteConnector(t, connectorId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_connector_memberships_list.go b/team_connector_memberships_list.go index 12205a23..91d505c7 100644 --- a/team_connector_memberships_list.go +++ b/team_connector_memberships_list.go @@ -1,95 +1,94 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamConnectorMembershipsListService implements the Team Management, List all connector memberships // Ref. https://fivetran.com/docs/rest-api/teams#listallconnectormemberships type TeamConnectorMembershipsListService struct { - c *Client - teamId *string - limit *int - cursor *string + c *Client + teamId *string + limit *int + cursor *string } type TeamConnectorMembershipsListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - ConnectorId string `json:"id"` - Role string `json:"role"` - CreatedAt string `json:"created_at"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []teams.TeamConnectorMembership `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewTeamConnectorMembershipsList() *TeamConnectorMembershipsListService { - return &TeamConnectorMembershipsListService{c: c} + return &TeamConnectorMembershipsListService{c: c} } func (s *TeamConnectorMembershipsListService) TeamId(value string) *TeamConnectorMembershipsListService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamConnectorMembershipsListService) Limit(value int) *TeamConnectorMembershipsListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *TeamConnectorMembershipsListService) Cursor(value string) *TeamConnectorMembershipsListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *TeamConnectorMembershipsListService) Do(ctx context.Context) (TeamConnectorMembershipsListResponse, error) { - var response TeamConnectorMembershipsListResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - url := fmt.Sprintf("%v/teams/%v/connectors", s.c.baseURL, *s.teamId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } - - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamConnectorMembershipsListResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + url := fmt.Sprintf("%v/teams/%v/connectors", s.c.baseURL, *s.teamId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_connector_memberships_list_test.go b/team_connector_memberships_list_test.go index 0776f1a4..ef681ff9 100644 --- a/team_connector_memberships_list_test.go +++ b/team_connector_memberships_list_test.go @@ -1,29 +1,31 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamConnectorMembershipsListE2E(t *testing.T) { - teamId := CreateTeam(t) - connectorId := CreateConnector(t) - CreateTeamConnector(t, teamId, connectorId) + teamId := testutils.CreateTeam(t) + connectorId := testutils.CreateConnector(t) + testutils.CreateTeamConnector(t, teamId, connectorId) - result, err := Client.NewTeamConnectorMembershipsList().TeamId(teamId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", result) - t.Error(err) - } + result, err := testutils.Client.NewTeamConnectorMembershipsList().TeamId(teamId).Do(context.Background()) + if err != nil { + t.Logf("%+v\n", result) + t.Error(err) + } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.Items[0].ConnectorId, connectorId) - AssertEqual(t, result.Data.Items[0].Role, "Connector Administrator") - AssertNotEmpty(t, result.Data.Items[0].CreatedAt) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.Items[0].ConnectorId, connectorId) + testutils.AssertEqual(t, result.Data.Items[0].Role, "Connector Administrator") + testutils.AssertNotEmpty(t, result.Data.Items[0].CreatedAt) - t.Cleanup(func() { - DeleteTeamConnector(t, teamId, connectorId) - DeleteConnector(t, connectorId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamConnector(t, teamId, connectorId) + testutils.DeleteConnector(t, connectorId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_group_membership_create.go b/team_group_membership_create.go index b0fc12e3..e2f7c6c5 100644 --- a/team_group_membership_create.go +++ b/team_group_membership_create.go @@ -1,102 +1,103 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamGroupMembershipCreateService implements the Team Management, Add group membership // Ref. https://fivetran.com/docs/rest-api/teams#addgroupmembership type TeamGroupMembershipCreateService struct { - c *Client - teamId *string - groupId *string - role *string + c *Client + teamId *string + groupId *string + role *string } type teamGroupMembershipCreateRequest struct { - GroupId *string `json:"id,omitempty"` - Role *string `json:"role,omitempty"` + GroupId *string `json:"id,omitempty"` + Role *string `json:"role,omitempty"` } type TeamGroupMembershipCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - GroupId string `json:"id"` - Role string `json:"role"` - CreatedAt string `json:"created_at"` - } `json:"data"` + common.CommonResponse + Data teams.TeamGroupMembership `json:"data"` } func (c *Client) NewTeamGroupMembershipCreate() *TeamGroupMembershipCreateService { - return &TeamGroupMembershipCreateService{c: c} + return &TeamGroupMembershipCreateService{c: c} } func (s *TeamGroupMembershipCreateService) request() *teamGroupMembershipCreateRequest { - return &teamGroupMembershipCreateRequest{ - GroupId: s.groupId, - Role: s.role, - } + return &teamGroupMembershipCreateRequest{ + GroupId: s.groupId, + Role: s.role, + } } func (s *TeamGroupMembershipCreateService) TeamId(value string) *TeamGroupMembershipCreateService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamGroupMembershipCreateService) GroupId(value string) *TeamGroupMembershipCreateService { - s.groupId = &value - return s + s.groupId = &value + return s } func (s *TeamGroupMembershipCreateService) Role(value string) *TeamGroupMembershipCreateService { - s.role = &value - return s + s.role = &value + return s } func (s *TeamGroupMembershipCreateService) Do(ctx context.Context) (TeamGroupMembershipCreateResponse, error) { - var response TeamGroupMembershipCreateResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - url := fmt.Sprintf("%v/teams/%v/groups", s.c.baseURL, *s.teamId) - expectedStatus := 201 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamGroupMembershipCreateResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + url := fmt.Sprintf("%v/teams/%v/groups", s.c.baseURL, *s.teamId) + expectedStatus := 201 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_group_membership_create_test.go b/team_group_membership_create_test.go index 50a8c3b8..7fc0ab53 100644 --- a/team_group_membership_create_test.go +++ b/team_group_membership_create_test.go @@ -1,34 +1,36 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamGroupMembershipCreateE2E(t *testing.T) { - groupId := CreateGroup(t) - teamId := CreateTeam(t) + groupId := testutils.CreateGroup(t) + teamId := testutils.CreateTeam(t) + + created, err := testutils.Client.NewTeamGroupMembershipCreate(). + TeamId(teamId). + GroupId(groupId). + Role("Destination Administrator"). + Do(context.Background()) - created, err := Client.NewTeamGroupMembershipCreate(). - TeamId(teamId). - GroupId(groupId). - Role("Destination Administrator"). - Do(context.Background()) + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertEqual(t, created.Message, "Group membership has been created") + testutils.AssertEqual(t, created.Data.GroupId, groupId) + testutils.AssertEqual(t, created.Data.Role, "Destination Administrator") + testutils.AssertNotEmpty(t, created.Data.CreatedAt) - AssertEqual(t, created.Code, "Success") - AssertEqual(t, created.Message, "Group membership has been created") - AssertEqual(t, created.Data.GroupId, groupId) - AssertEqual(t, created.Data.Role, "Destination Administrator") - AssertNotEmpty(t, created.Data.CreatedAt) - - t.Cleanup(func() { - DeleteTeamGroup(t, teamId, groupId) - DeleteGroup(t, groupId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamGroup(t, teamId, groupId) + testutils.DeleteGroup(t, groupId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_group_membership_delete.go b/team_group_membership_delete.go index b7a0997d..5a2dbf2d 100644 --- a/team_group_membership_delete.go +++ b/team_group_membership_delete.go @@ -1,76 +1,76 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamGroupMembershipDeleteService implements the Team Management, Delete group membership // Ref. https://fivetran.com/docs/rest-api/teams#deletegroupmembership type TeamGroupMembershipDeleteService struct { - c *Client - teamId *string - groupId *string -} - -type TeamGroupMembershipDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` + c *Client + teamId *string + groupId *string } func (c *Client) NewTeamGroupMembershipDelete() *TeamGroupMembershipDeleteService { - return &TeamGroupMembershipDeleteService{c: c} + return &TeamGroupMembershipDeleteService{c: c} } func (s *TeamGroupMembershipDeleteService) TeamId(value string) *TeamGroupMembershipDeleteService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamGroupMembershipDeleteService) GroupId(value string) *TeamGroupMembershipDeleteService { - s.groupId = &value - return s + s.groupId = &value + return s } -func (s *TeamGroupMembershipDeleteService) Do(ctx context.Context) (TeamGroupMembershipDeleteResponse, error) { - var response TeamGroupMembershipDeleteResponse +func (s *TeamGroupMembershipDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } - if s.groupId == nil { - return response, fmt.Errorf("missing required groupId") - } + if s.groupId == nil { + return response, fmt.Errorf("missing required groupId") + } - url := fmt.Sprintf("%v/teams/%v/groups/%v", s.c.baseURL, *s.teamId, *s.groupId) - expectedStatus := 200 + url := fmt.Sprintf("%v/teams/%v/groups/%v", s.c.baseURL, *s.teamId, *s.groupId) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/team_group_membership_delete_test.go b/team_group_membership_delete_test.go index 0987700e..b8e38912 100644 --- a/team_group_membership_delete_test.go +++ b/team_group_membership_delete_test.go @@ -1,30 +1,32 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamGroupMembershipDeleteE2E(t *testing.T) { - groupId := CreateGroup(t) - teamId := CreateTeam(t) - CreateTeamGroup(t, teamId,groupId) + groupId := testutils.CreateGroup(t) + teamId := testutils.CreateTeam(t) + testutils.CreateTeamGroup(t, teamId, groupId) - deleted, err := Client.NewTeamGroupMembershipDelete(). - TeamId(teamId). - GroupId(groupId). - Do(context.Background()) + deleted, err := testutils.Client.NewTeamGroupMembershipDelete(). + TeamId(teamId). + GroupId(groupId). + Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } - AssertEqual(t, deleted.Code, "Success") - AssertEqual(t, deleted.Message, "Group membership has been deleted") + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertEqual(t, deleted.Message, "Group membership has been deleted") - t.Cleanup(func() { - DeleteGroup(t, groupId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteGroup(t, groupId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_group_membership_details.go b/team_group_membership_details.go index f91077f0..610e6f41 100644 --- a/team_group_membership_details.go +++ b/team_group_membership_details.go @@ -1,81 +1,83 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamGroupMembershipDetailsService implements the Team Management, Retrieve group membership // Ref. https://fivetran.com/docs/rest-api/teams#retrievegroupmembership type TeamGroupMembershipDetailsService struct { - c *Client - teamId *string - groupId *string + c *Client + teamId *string + groupId *string } type TeamGroupMembershipDetailsResponse struct { - Code string `json:"code"` - Data struct { - GroupId string `json:"id"` - Role string `json:"role"` - CreatedAt string `json:"created_at"` - } `json:"data"` + Code string `json:"code"` + Data teams.TeamGroupMembership `json:"data"` } func (c *Client) NewTeamGroupMembershipDetails() *TeamGroupMembershipDetailsService { - return &TeamGroupMembershipDetailsService{c: c} + return &TeamGroupMembershipDetailsService{c: c} } func (s *TeamGroupMembershipDetailsService) TeamId(value string) *TeamGroupMembershipDetailsService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamGroupMembershipDetailsService) GroupId(value string) *TeamGroupMembershipDetailsService { - s.groupId = &value - return s + s.groupId = &value + return s } func (s *TeamGroupMembershipDetailsService) Do(ctx context.Context) (TeamGroupMembershipDetailsResponse, error) { - var response TeamGroupMembershipDetailsResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - if s.groupId == nil { - return response, fmt.Errorf("missing required groupId") - } - - url := fmt.Sprintf("%v/teams/%v/groups/%v", s.c.baseURL, *s.teamId, *s.groupId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - r := request{ - method: "GET", - url: url, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamGroupMembershipDetailsResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + if s.groupId == nil { + return response, fmt.Errorf("missing required groupId") + } + + url := fmt.Sprintf("%v/teams/%v/groups/%v", s.c.baseURL, *s.teamId, *s.groupId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_group_membership_details_test.go b/team_group_membership_details_test.go index 47ef9b44..23f64f64 100644 --- a/team_group_membership_details_test.go +++ b/team_group_membership_details_test.go @@ -1,32 +1,34 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamGroupMembershipDetailsE2E(t *testing.T) { - groupId := CreateGroup(t) - teamId := CreateTeam(t) - CreateTeamGroup(t, teamId, groupId) + groupId := testutils.CreateGroup(t) + teamId := testutils.CreateTeam(t) + testutils.CreateTeamGroup(t, teamId, groupId) - result, err := Client.NewTeamGroupMembershipDetails(). - TeamId(teamId). - GroupId(groupId). - Do(context.Background()) - if err != nil { - t.Logf("%+v\n", result) - t.Error(err) - } + result, err := testutils.Client.NewTeamGroupMembershipDetails(). + TeamId(teamId). + GroupId(groupId). + Do(context.Background()) + if err != nil { + t.Logf("%+v\n", result) + t.Error(err) + } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.GroupId, groupId) - AssertEqual(t, result.Data.Role, "Destination Analyst") - AssertNotEmpty(t, result.Data.CreatedAt) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.GroupId, groupId) + testutils.AssertEqual(t, result.Data.Role, "Destination Analyst") + testutils.AssertNotEmpty(t, result.Data.CreatedAt) - t.Cleanup(func() { - DeleteTeamGroup(t, teamId, groupId) - DeleteGroup(t, groupId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamGroup(t, teamId, groupId) + testutils.DeleteGroup(t, groupId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_group_membership_modify.go b/team_group_membership_modify.go index 004698ef..12383842 100644 --- a/team_group_membership_modify.go +++ b/team_group_membership_modify.go @@ -1,99 +1,99 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamGroupMembershipModifyService implements the Team Management, Update group membership // Ref. https://fivetran.com/docs/rest-api/teams#updategroupmembership type TeamGroupMembershipModifyService struct { - c *Client - teamId *string - groupId *string - role *string + c *Client + teamId *string + groupId *string + role *string } type teamGroupMembershipModifyRequest struct { - Role *string `json:"role,omitempty"` -} - -type TeamGroupMembershipModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` + Role *string `json:"role,omitempty"` } func (c *Client) NewTeamGroupMembershipModify() *TeamGroupMembershipModifyService { - return &TeamGroupMembershipModifyService{c: c} + return &TeamGroupMembershipModifyService{c: c} } func (s *TeamGroupMembershipModifyService) request() *teamGroupMembershipModifyRequest { - return &teamGroupMembershipModifyRequest{ - Role: s.role, - } + return &teamGroupMembershipModifyRequest{ + Role: s.role, + } } func (s *TeamGroupMembershipModifyService) TeamId(value string) *TeamGroupMembershipModifyService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamGroupMembershipModifyService) GroupId(value string) *TeamGroupMembershipModifyService { - s.groupId = &value - return s + s.groupId = &value + return s } func (s *TeamGroupMembershipModifyService) Role(value string) *TeamGroupMembershipModifyService { - s.role = &value - return s + s.role = &value + return s } -func (s *TeamGroupMembershipModifyService) Do(ctx context.Context) (TeamGroupMembershipModifyResponse, error) { - var response TeamGroupMembershipModifyResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - if s.groupId == nil { - return response, fmt.Errorf("missing required groupId") - } - - url := fmt.Sprintf("%v/teams/%v/groups/%v", s.c.baseURL, *s.teamId, *s.groupId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil +func (s *TeamGroupMembershipModifyService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + if s.groupId == nil { + return response, fmt.Errorf("missing required groupId") + } + + url := fmt.Sprintf("%v/teams/%v/groups/%v", s.c.baseURL, *s.teamId, *s.groupId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_group_membership_modify_test.go b/team_group_membership_modify_test.go index 54e02525..69a570c3 100644 --- a/team_group_membership_modify_test.go +++ b/team_group_membership_modify_test.go @@ -1,32 +1,34 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamGroupMembershipModifyE2E(t *testing.T) { - teamId := CreateTeam(t) - groupId := CreateGroup(t) - CreateTeamGroup(t, teamId, groupId) + teamId := testutils.CreateTeam(t) + groupId := testutils.CreateGroup(t) + testutils.CreateTeamGroup(t, teamId, groupId) + + modified, err := testutils.Client.NewTeamGroupMembershipModify(). + TeamId(teamId). + GroupId(groupId). + Role("Destination Reviewer"). + Do(context.Background()) - modified, err := Client.NewTeamGroupMembershipModify(). - TeamId(teamId). - GroupId(groupId). - Role("Destination Reviewer"). - Do(context.Background()) + if err != nil { + t.Logf("%+v\n", modified) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", modified) - t.Error(err) - } + testutils.AssertEqual(t, modified.Code, "Success") + testutils.AssertEqual(t, modified.Message, "Group membership has been updated") - AssertEqual(t, modified.Code, "Success") - AssertEqual(t, modified.Message, "Group membership has been updated") - - t.Cleanup(func() { - DeleteTeamGroup(t, teamId, groupId) - DeleteGroup(t, groupId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamGroup(t, teamId, groupId) + testutils.DeleteGroup(t, groupId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_group_memberships_list.go b/team_group_memberships_list.go index 5988a7ea..07807b28 100644 --- a/team_group_memberships_list.go +++ b/team_group_memberships_list.go @@ -1,95 +1,94 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamListGroupsService implements the Team Management, List all group memberships // Ref. https://fivetran.com/docs/rest-api/teams#listallgroupmemberships type TeamGroupMembershipsListService struct { - c *Client - teamId *string - limit *int - cursor *string + c *Client + teamId *string + limit *int + cursor *string } type TeamGroupMembershipsListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - GroupId string `json:"id"` - Role string `json:"role"` - CreatedAt string `json:"created_at"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []teams.TeamGroupMembership `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewTeamGroupMembershipsList() *TeamGroupMembershipsListService { - return &TeamGroupMembershipsListService{c: c} + return &TeamGroupMembershipsListService{c: c} } func (s *TeamGroupMembershipsListService) TeamId(value string) *TeamGroupMembershipsListService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamGroupMembershipsListService) Limit(value int) *TeamGroupMembershipsListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *TeamGroupMembershipsListService) Cursor(value string) *TeamGroupMembershipsListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *TeamGroupMembershipsListService) Do(ctx context.Context) (TeamGroupMembershipsListResponse, error) { - var response TeamGroupMembershipsListResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - url := fmt.Sprintf("%v/teams/%v/groups", s.c.baseURL, *s.teamId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } - - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamGroupMembershipsListResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + url := fmt.Sprintf("%v/teams/%v/groups", s.c.baseURL, *s.teamId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_group_memberships_list_test.go b/team_group_memberships_list_test.go index cdcdf874..c6816eeb 100644 --- a/team_group_memberships_list_test.go +++ b/team_group_memberships_list_test.go @@ -1,29 +1,31 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamGroupMembershipsistE2E(t *testing.T) { - groupId := CreateGroup(t) - teamId := CreateTeam(t) - CreateTeamGroup(t, teamId, groupId) + groupId := testutils.CreateGroup(t) + teamId := testutils.CreateTeam(t) + testutils.CreateTeamGroup(t, teamId, groupId) - result, err := Client.NewTeamGroupMembershipsList().TeamId(teamId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", result) - t.Error(err) - } + result, err := testutils.Client.NewTeamGroupMembershipsList().TeamId(teamId).Do(context.Background()) + if err != nil { + t.Logf("%+v\n", result) + t.Error(err) + } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.Items[0].GroupId, groupId) - AssertEqual(t, result.Data.Items[0].Role, "Destination Analyst") - AssertNotEmpty(t, result.Data.Items[0].CreatedAt) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.Items[0].GroupId, groupId) + testutils.AssertEqual(t, result.Data.Items[0].Role, "Destination Analyst") + testutils.AssertNotEmpty(t, result.Data.Items[0].CreatedAt) - t.Cleanup(func() { - DeleteTeamGroup(t, teamId, groupId) - DeleteGroup(t, groupId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamGroup(t, teamId, groupId) + testutils.DeleteGroup(t, groupId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_user_membership_create.go b/team_user_membership_create.go index 9455fce8..aa6d804e 100644 --- a/team_user_membership_create.go +++ b/team_user_membership_create.go @@ -1,101 +1,103 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamUserMembershipCreateService implements the Team Management, Add a user to a team // Ref. https://fivetran.com/docs/rest-api/teams#addausertoateam type TeamUserMembershipCreateService struct { - c *Client - teamId *string - userId *string - role *string + c *Client + teamId *string + userId *string + role *string } type teamUserMembershipCreateRequest struct { - UserId *string `json:"user_id,omitempty"` - Role *string `json:"role,omitempty"` + UserId *string `json:"user_id,omitempty"` + Role *string `json:"role,omitempty"` } type TeamUserMembershipCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - UserId string `json:"user_id"` - Role string `json:"role"` - } `json:"data"` + common.CommonResponse + Data teams.TeamUserMembership `json:"data"` } func (c *Client) NewTeamUserMembershipCreate() *TeamUserMembershipCreateService { - return &TeamUserMembershipCreateService{c: c} + return &TeamUserMembershipCreateService{c: c} } func (s *TeamUserMembershipCreateService) request() *teamUserMembershipCreateRequest { - return &teamUserMembershipCreateRequest{ - UserId: s.userId, - Role: s.role, - } + return &teamUserMembershipCreateRequest{ + UserId: s.userId, + Role: s.role, + } } func (s *TeamUserMembershipCreateService) TeamId(value string) *TeamUserMembershipCreateService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamUserMembershipCreateService) UserId(value string) *TeamUserMembershipCreateService { - s.userId = &value - return s + s.userId = &value + return s } func (s *TeamUserMembershipCreateService) Role(value string) *TeamUserMembershipCreateService { - s.role = &value - return s + s.role = &value + return s } func (s *TeamUserMembershipCreateService) Do(ctx context.Context) (TeamUserMembershipCreateResponse, error) { - var response TeamUserMembershipCreateResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - url := fmt.Sprintf("%v/teams/%v/users", s.c.baseURL, *s.teamId) - expectedStatus := 201 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamUserMembershipCreateResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + url := fmt.Sprintf("%v/teams/%v/users", s.c.baseURL, *s.teamId) + expectedStatus := 201 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_user_membership_create_test.go b/team_user_membership_create_test.go index c025174b..c53c474e 100644 --- a/team_user_membership_create_test.go +++ b/team_user_membership_create_test.go @@ -1,31 +1,33 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamUserMembershipCreateE2E(t *testing.T) { - teamId := CreateTeam(t) + teamId := testutils.CreateTeam(t) + + created, err := testutils.Client.NewTeamUserMembershipCreate(). + TeamId(teamId). + UserId(testutils.PredefinedUserId). + Role("Team Member"). + Do(context.Background()) - created, err := Client.NewTeamUserMembershipCreate(). - TeamId(teamId). - UserId(PredefinedUserId). - Role("Team Member"). - Do(context.Background()) + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertEqual(t, created.Message, "User has been added to the team") + testutils.AssertEqual(t, created.Data.UserId, testutils.PredefinedUserId) + testutils.AssertEqual(t, created.Data.Role, "Team Member") - AssertEqual(t, created.Code, "Success") - AssertEqual(t, created.Message, "User has been added to the team") - AssertEqual(t, created.Data.UserId, PredefinedUserId) - AssertEqual(t, created.Data.Role, "Team Member") - - t.Cleanup(func() { - DeleteTeamUser(t, teamId, PredefinedUserId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamUser(t, teamId, testutils.PredefinedUserId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/team_user_membership_delete.go b/team_user_membership_delete.go index d4eaa1f6..b33469fb 100644 --- a/team_user_membership_delete.go +++ b/team_user_membership_delete.go @@ -1,76 +1,76 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamUserMembershipDeleteService implements the Team Management, Delete a user from a team // Ref. https://fivetran.com/docs/rest-api/teams#deleteauserfromateam type TeamUserMembershipDeleteService struct { - c *Client - teamId *string - userId *string -} - -type TeamUserMembershipDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` + c *Client + teamId *string + userId *string } func (c *Client) NewTeamUserMembershipDelete() *TeamUserMembershipDeleteService { - return &TeamUserMembershipDeleteService{c: c} + return &TeamUserMembershipDeleteService{c: c} } func (s *TeamUserMembershipDeleteService) TeamId(value string) *TeamUserMembershipDeleteService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamUserMembershipDeleteService) UserId(value string) *TeamUserMembershipDeleteService { - s.userId = &value - return s + s.userId = &value + return s } -func (s *TeamUserMembershipDeleteService) Do(ctx context.Context) (TeamUserMembershipDeleteResponse, error) { - var response TeamUserMembershipDeleteResponse +func (s *TeamUserMembershipDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } - if s.userId == nil { - return response, fmt.Errorf("missing required userId") - } + if s.userId == nil { + return response, fmt.Errorf("missing required userId") + } - url := fmt.Sprintf("%v/teams/%v/users/%v", s.c.baseURL, *s.teamId, *s.userId) - expectedStatus := 200 + url := fmt.Sprintf("%v/teams/%v/users/%v", s.c.baseURL, *s.teamId, *s.userId) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/team_user_membership_delete_test.go b/team_user_membership_delete_test.go index 9f6daa4c..027faf64 100644 --- a/team_user_membership_delete_test.go +++ b/team_user_membership_delete_test.go @@ -1,28 +1,30 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamUserMembershipDeleteE2E(t *testing.T) { - teamId := CreateTeam(t) - CreateTeamUser(t, teamId, PredefinedUserId) + teamId := testutils.CreateTeam(t) + testutils.CreateTeamUser(t, teamId, testutils.PredefinedUserId) - deleted, err := Client.NewTeamUserMembershipDelete(). - TeamId(teamId). - UserId(PredefinedUserId). - Do(context.Background()) + deleted, err := testutils.Client.NewTeamUserMembershipDelete(). + TeamId(teamId). + UserId(testutils.PredefinedUserId). + Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } - AssertEqual(t, deleted.Code, "Success") - AssertEqual(t, deleted.Message, "User has been removed from the team") + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertEqual(t, deleted.Message, "User has been removed from the team") - t.Cleanup(func() { - DeleteTeam(t, teamId) - }) -} \ No newline at end of file + t.Cleanup(func() { + testutils.DeleteTeam(t, teamId) + }) +} diff --git a/team_user_membership_details.go b/team_user_membership_details.go index 26f5082c..1eb76c8d 100644 --- a/team_user_membership_details.go +++ b/team_user_membership_details.go @@ -1,80 +1,83 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamUserMembershipDetailsService implements the Team Management, retrieve Team Details. // Ref. https://fivetran.com/docs/rest-api/teams#retrieveusermembershipinateam type TeamUserMembershipDetailsService struct { - c *Client - teamId *string - userId *string + c *Client + teamId *string + userId *string } type TeamUserMembershipDetailsResponse struct { - Code string `json:"code"` - Data struct { - UserId string `json:"user_id"` - Role string `json:"role"` - } `json:"data"` + Code string `json:"code"` + Data teams.TeamUserMembership `json:"data"` } func (c *Client) NewTeamUserMembershipDetails() *TeamUserMembershipDetailsService { - return &TeamUserMembershipDetailsService{c: c} + return &TeamUserMembershipDetailsService{c: c} } func (s *TeamUserMembershipDetailsService) TeamId(value string) *TeamUserMembershipDetailsService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamUserMembershipDetailsService) UserId(value string) *TeamUserMembershipDetailsService { - s.userId = &value - return s + s.userId = &value + return s } func (s *TeamUserMembershipDetailsService) Do(ctx context.Context) (TeamUserMembershipDetailsResponse, error) { - var response TeamUserMembershipDetailsResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - if s.userId == nil { - return response, fmt.Errorf("missing required userId") - } - - url := fmt.Sprintf("%v/teams/%v/users/%v", s.c.baseURL, *s.teamId, *s.userId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - r := request{ - method: "GET", - url: url, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamUserMembershipDetailsResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + if s.userId == nil { + return response, fmt.Errorf("missing required userId") + } + + url := fmt.Sprintf("%v/teams/%v/users/%v", s.c.baseURL, *s.teamId, *s.userId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_user_membership_details_test.go b/team_user_membership_details_test.go index 723c71cb..73bd20a4 100644 --- a/team_user_membership_details_test.go +++ b/team_user_membership_details_test.go @@ -1,30 +1,32 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamUserMembershipDetailsE2E(t *testing.T) { - teamId := CreateTeam(t) - CreateTeamUser(t, teamId, PredefinedUserId) + teamId := testutils.CreateTeam(t) + testutils.CreateTeamUser(t, teamId, testutils.PredefinedUserId) - result, err := Client.NewTeamUserMembershipDetails(). - TeamId(teamId). - UserId(PredefinedUserId). - Do(context.Background()) + result, err := testutils.Client.NewTeamUserMembershipDetails(). + TeamId(teamId). + UserId(testutils.PredefinedUserId). + Do(context.Background()) - if err != nil { - t.Logf("%+v\n", result) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", result) + t.Error(err) + } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.UserId, PredefinedUserId) - AssertEqual(t, result.Data.Role, "Team Member") + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.UserId, testutils.PredefinedUserId) + testutils.AssertEqual(t, result.Data.Role, "Team Member") - t.Cleanup(func() { - DeleteTeamUser(t, teamId, PredefinedUserId) - DeleteTeam(t, teamId) - }) -} \ No newline at end of file + t.Cleanup(func() { + testutils.DeleteTeamUser(t, teamId, testutils.PredefinedUserId) + testutils.DeleteTeam(t, teamId) + }) +} diff --git a/team_user_membership_modify.go b/team_user_membership_modify.go index 9b3b39ce..9588885c 100644 --- a/team_user_membership_modify.go +++ b/team_user_membership_modify.go @@ -1,99 +1,99 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamUsersModifyService implements the Team Management, Modify a user membership // Ref. https://fivetran.com/docs/rest-api/teams#modifyausermembership type TeamUserMembershipModifyService struct { - c *Client - teamId *string - userId *string - role *string + c *Client + teamId *string + userId *string + role *string } type teamUserMembershipModifyRequest struct { - Role *string `json:"role,omitempty"` -} - -type TeamUserMembershipModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` + Role *string `json:"role,omitempty"` } func (c *Client) NewTeamUserMembershipModify() *TeamUserMembershipModifyService { - return &TeamUserMembershipModifyService{c: c} + return &TeamUserMembershipModifyService{c: c} } func (s *TeamUserMembershipModifyService) request() *teamUserMembershipModifyRequest { - return &teamUserMembershipModifyRequest{ - Role: s.role, - } + return &teamUserMembershipModifyRequest{ + Role: s.role, + } } func (s *TeamUserMembershipModifyService) TeamId(value string) *TeamUserMembershipModifyService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamUserMembershipModifyService) UserId(value string) *TeamUserMembershipModifyService { - s.userId = &value - return s + s.userId = &value + return s } func (s *TeamUserMembershipModifyService) Role(value string) *TeamUserMembershipModifyService { - s.role = &value - return s + s.role = &value + return s } -func (s *TeamUserMembershipModifyService) Do(ctx context.Context) (TeamUserMembershipModifyResponse, error) { - var response TeamUserMembershipModifyResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - if s.userId == nil { - return response, fmt.Errorf("missing required userId") - } - - url := fmt.Sprintf("%v/teams/%v/users/%v", s.c.baseURL, *s.teamId, *s.userId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil +func (s *TeamUserMembershipModifyService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + if s.userId == nil { + return response, fmt.Errorf("missing required userId") + } + + url := fmt.Sprintf("%v/teams/%v/users/%v", s.c.baseURL, *s.teamId, *s.userId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_user_membership_modify_test.go b/team_user_membership_modify_test.go index 3acf9a4b..918df052 100644 --- a/team_user_membership_modify_test.go +++ b/team_user_membership_modify_test.go @@ -1,30 +1,32 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamUserMembershipModifyE2E(t *testing.T) { - teamId := CreateTeam(t) - CreateTeamUser(t, teamId, PredefinedUserId) + teamId := testutils.CreateTeam(t) + testutils.CreateTeamUser(t, teamId, testutils.PredefinedUserId) + + modified, err := testutils.Client.NewTeamUserMembershipModify(). + TeamId(teamId). + UserId(testutils.PredefinedUserId). + Role("Team Manager"). + Do(context.Background()) - modified, err := Client.NewTeamUserMembershipModify(). - TeamId(teamId). - UserId(PredefinedUserId). - Role("Team Manager"). - Do(context.Background()) + if err != nil { + t.Logf("%+v\n", modified) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", modified) - t.Error(err) - } + testutils.AssertEqual(t, modified.Code, "Success") + testutils.AssertEqual(t, modified.Message, "User role has been updated") - AssertEqual(t, modified.Code, "Success") - AssertEqual(t, modified.Message, "User role has been updated") - - t.Cleanup(func() { - DeleteTeamUser(t, teamId, PredefinedUserId) - DeleteTeam(t, teamId) - }) -} \ No newline at end of file + t.Cleanup(func() { + testutils.DeleteTeamUser(t, teamId, testutils.PredefinedUserId) + testutils.DeleteTeam(t, teamId) + }) +} diff --git a/team_user_memberships_list.go b/team_user_memberships_list.go index d10f9a69..dd85e94a 100644 --- a/team_user_memberships_list.go +++ b/team_user_memberships_list.go @@ -1,94 +1,94 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamUserMembershipsListService implements the Team Management, List all user memberships // Ref. https://fivetran.com/docs/rest-api/teams#listallusermemberships type TeamUserMembershipsListService struct { - c *Client - teamId *string - limit *int - cursor *string + c *Client + teamId *string + limit *int + cursor *string } type TeamUserMembershipsListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - UserId string `json:"user_id"` - Role string `json:"role"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []teams.TeamUserMembership `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewTeamUserMembershipsList() *TeamUserMembershipsListService { - return &TeamUserMembershipsListService{c: c} + return &TeamUserMembershipsListService{c: c} } func (s *TeamUserMembershipsListService) TeamId(value string) *TeamUserMembershipsListService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamUserMembershipsListService) Limit(value int) *TeamUserMembershipsListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *TeamUserMembershipsListService) Cursor(value string) *TeamUserMembershipsListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *TeamUserMembershipsListService) Do(ctx context.Context) (TeamUserMembershipsListResponse, error) { - var response TeamUserMembershipsListResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - url := fmt.Sprintf("%v/teams/%v/users", s.c.baseURL, *s.teamId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } - - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamUserMembershipsListResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + url := fmt.Sprintf("%v/teams/%v/users", s.c.baseURL, *s.teamId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/team_user_memberships_list_test.go b/team_user_memberships_list_test.go index ad51350b..5ef42182 100644 --- a/team_user_memberships_list_test.go +++ b/team_user_memberships_list_test.go @@ -1,28 +1,30 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamUserMembershipsListE2E(t *testing.T) { - teamId := CreateTeam(t) - CreateTeamUser(t, teamId, PredefinedUserId) + teamId := testutils.CreateTeam(t) + testutils.CreateTeamUser(t, teamId, testutils.PredefinedUserId) - result, err := Client.NewTeamUserMembershipsList(). - TeamId(teamId). - Do(context.Background()) - if err != nil { - t.Logf("%+v\n", result) - t.Error(err) - } + result, err := testutils.Client.NewTeamUserMembershipsList(). + TeamId(teamId). + Do(context.Background()) + if err != nil { + t.Logf("%+v\n", result) + t.Error(err) + } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.Items[0].UserId, PredefinedUserId) - AssertEqual(t, result.Data.Items[0].Role, "Team Member") + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.Items[0].UserId, testutils.PredefinedUserId) + testutils.AssertEqual(t, result.Data.Items[0].Role, "Team Member") - t.Cleanup(func() { - DeleteTeamUser(t, teamId, PredefinedUserId) - DeleteTeam(t, teamId) - }) + t.Cleanup(func() { + testutils.DeleteTeamUser(t, teamId, testutils.PredefinedUserId) + testutils.DeleteTeam(t, teamId) + }) } diff --git a/teams/common_types.go b/teams/common_types.go new file mode 100644 index 00000000..211806f5 --- /dev/null +++ b/teams/common_types.go @@ -0,0 +1,28 @@ +package teams + +type TeamData struct { + Id string `json:"id"` + Name string `json:"name"` + Description string `json:"description"` + Role string `json:"role"` +} + +type TeamMembership struct { + Role string `json:"role"` + CreatedAt string `json:"created_at"` +} + +type TeamConnectorMembership struct { + ConnectorId string `json:"id"` + TeamMembership +} + +type TeamGroupMembership struct { + GroupId string `json:"id"` + TeamMembership +} + +type TeamUserMembership struct { + UserId string `json:"user_id"` + TeamMembership +} diff --git a/teams_create.go b/teams_create.go index 7beb90bb..992051c1 100644 --- a/teams_create.go +++ b/teams_create.go @@ -1,100 +1,100 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamsCreateService implements the Team Management, Create a Team. // Ref. https://fivetran.com/docs/rest-api/teams#createateam type TeamsCreateService struct { - c *Client - name *string - description *string - role *string + c *Client + name *string + description *string + role *string } type teamsCreateRequest struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Role *string `json:"role,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Role *string `json:"role,omitempty"` } type TeamsCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Id string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Role string `json:"role"` - } `json:"data"` + common.CommonResponse + Data teams.TeamData `json:"data"` } func (c *Client) NewTeamsCreate() *TeamsCreateService { - return &TeamsCreateService{c: c} + return &TeamsCreateService{c: c} } func (s *TeamsCreateService) request() *teamsCreateRequest { - return &teamsCreateRequest{ - Name: s.name, - Description: s.description, - Role: s.role, - } + return &teamsCreateRequest{ + Name: s.name, + Description: s.description, + Role: s.role, + } } func (s *TeamsCreateService) Name(value string) *TeamsCreateService { - s.name = &value - return s + s.name = &value + return s } func (s *TeamsCreateService) Role(value string) *TeamsCreateService { - s.role = &value - return s + s.role = &value + return s } func (s *TeamsCreateService) Description(value string) *TeamsCreateService { - s.description = &value - return s + s.description = &value + return s } func (s *TeamsCreateService) Do(ctx context.Context) (TeamsCreateResponse, error) { - var response TeamsCreateResponse - url := fmt.Sprintf("%v/teams", s.c.baseURL) - expectedStatus := 201 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamsCreateResponse + url := fmt.Sprintf("%v/teams", s.c.baseURL) + expectedStatus := 201 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/teams_create_test.go b/teams_create_test.go index 3c4b05ca..f3bda002 100644 --- a/teams_create_test.go +++ b/teams_create_test.go @@ -1,28 +1,30 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamsCreateE2E(t *testing.T) { - created, err := Client.NewTeamsCreate(). - Name("test_team"). - Description("test_description"). - Role("Account Reviewer"). - Do(context.Background()) + created, err := testutils.Client.NewTeamsCreate(). + Name("test_team"). + Description("test_description"). + Role("Account Reviewer"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertNotEmpty(t, created.Data.Id) + testutils.AssertEqual(t, created.Data.Name, "test_team") + testutils.AssertEqual(t, created.Data.Description, "test_description") + testutils.AssertEqual(t, created.Data.Role, "Account Reviewer") - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertNotEmpty(t, created.Data.Id) - AssertEqual(t, created.Data.Name, "test_team") - AssertEqual(t, created.Data.Description, "test_description") - AssertEqual(t, created.Data.Role, "Account Reviewer") - - t.Cleanup(func() { DeleteTeam(t, created.Data.Id) }) + t.Cleanup(func() { testutils.DeleteTeam(t, created.Data.Id) }) } diff --git a/teams_delete.go b/teams_delete.go index 925e2a0a..d4a5df05 100644 --- a/teams_delete.go +++ b/teams_delete.go @@ -1,66 +1,66 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamsDeleteService implements the Team Management, Delete a Team. // Ref. https://fivetran.com/docs/rest-api/teams#deleteateam type TeamsDeleteService struct { - c *Client - teamId *string -} - -type TeamsDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` + c *Client + teamId *string } func (c *Client) NewTeamsDelete() *TeamsDeleteService { - return &TeamsDeleteService{c: c} + return &TeamsDeleteService{c: c} } func (s *TeamsDeleteService) TeamId(value string) *TeamsDeleteService { - s.teamId = &value - return s + s.teamId = &value + return s } -func (s *TeamsDeleteService) Do(ctx context.Context) (TeamsDeleteResponse, error) { - var response TeamsDeleteResponse +func (s *TeamsDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } - url := fmt.Sprintf("%v/teams/%v", s.c.baseURL, *s.teamId) - expectedStatus := 200 + url := fmt.Sprintf("%v/teams/%v", s.c.baseURL, *s.teamId) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/teams_delete_role_in_account.go b/teams_delete_role_in_account.go index 502f0a9d..8020f048 100644 --- a/teams_delete_role_in_account.go +++ b/teams_delete_role_in_account.go @@ -1,66 +1,66 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // TeamRoleDeleteService implements the Team Management, Delete team role in account // Ref. https://fivetran.com/docs/rest-api/teams#deleteteamroleinaccount type TeamsDeleteRoleInAccountService struct { - c *Client - teamId *string -} - -type TeamsDeleteRoleInAccountResponse struct { - Code string `json:"code"` - Message string `json:"message"` + c *Client + teamId *string } func (c *Client) NewTeamsDeleteRoleInAccount() *TeamsDeleteRoleInAccountService { - return &TeamsDeleteRoleInAccountService{c: c} + return &TeamsDeleteRoleInAccountService{c: c} } func (s *TeamsDeleteRoleInAccountService) TeamId(value string) *TeamsDeleteRoleInAccountService { - s.teamId = &value - return s + s.teamId = &value + return s } -func (s *TeamsDeleteRoleInAccountService) Do(ctx context.Context) (TeamsDeleteRoleInAccountResponse, error) { - var response TeamsDeleteRoleInAccountResponse +func (s *TeamsDeleteRoleInAccountService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } - url := fmt.Sprintf("%v/teams/%v/role", s.c.baseURL, *s.teamId) - expectedStatus := 200 + url := fmt.Sprintf("%v/teams/%v/role", s.c.baseURL, *s.teamId) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/teams_delete_role_in_account_test.go b/teams_delete_role_in_account_test.go index de2fd8f0..3be2c99f 100644 --- a/teams_delete_role_in_account_test.go +++ b/teams_delete_role_in_account_test.go @@ -1,22 +1,24 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamRoleDeleteE2E(t *testing.T) { - teamId := CreateTeam(t) + teamId := testutils.CreateTeam(t) - deleted, err := Client.NewTeamsDeleteRoleInAccount().TeamId(teamId).Do(context.Background()) + deleted, err := testutils.Client.NewTeamsDeleteRoleInAccount().TeamId(teamId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } - AssertEqual(t, deleted.Code, "Success") - AssertEqual(t, deleted.Message, "Team role in account has been removed") + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertEqual(t, deleted.Message, "Team role in account has been removed") - t.Cleanup(func() { DeleteTeam(t, teamId) }) + t.Cleanup(func() { testutils.DeleteTeam(t, teamId) }) } diff --git a/teams_delete_test.go b/teams_delete_test.go index 91272234..ca289ebe 100644 --- a/teams_delete_test.go +++ b/teams_delete_test.go @@ -1,20 +1,22 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamsDeleteE2E(t *testing.T) { - teamId := CreateTeam(t) + teamId := testutils.CreateTeam(t) - deleted, err := Client.NewTeamsDelete().TeamId(teamId).Do(context.Background()) + deleted, err := testutils.Client.NewTeamsDelete().TeamId(teamId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } - AssertEqual(t, deleted.Code, "Success") - AssertEqual(t, deleted.Message, "Team has been deleted") + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertEqual(t, deleted.Message, "Team has been deleted") } diff --git a/teams_details.go b/teams_details.go index 83867542..bfee35d7 100644 --- a/teams_details.go +++ b/teams_details.go @@ -1,72 +1,73 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamsDetailsService implements the Team Management, retrieve Team Details. // Ref. https://fivetran.com/docs/rest-api/teams#retrieveteamdetails type TeamsDetailsService struct { - c *Client - teamId *string + c *Client + teamId *string } type TeamsDetailsResponse struct { - Code string `json:"code"` - Data struct { - Id string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Role string `json:"role"` - } `json:"data"` + Code string `json:"code"` + Data teams.TeamData `json:"data"` } func (c *Client) NewTeamsDetails() *TeamsDetailsService { - return &TeamsDetailsService{c: c} + return &TeamsDetailsService{c: c} } func (s *TeamsDetailsService) TeamId(value string) *TeamsDetailsService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamsDetailsService) Do(ctx context.Context) (TeamsDetailsResponse, error) { - var response TeamsDetailsResponse + var response TeamsDetailsResponse - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } - url := fmt.Sprintf("%v/teams/%v", s.c.baseURL, *s.teamId) - expectedStatus := 200 + url := fmt.Sprintf("%v/teams/%v", s.c.baseURL, *s.teamId) + expectedStatus := 200 - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 - r := request{ - method: "GET", - url: url, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/teams_details_test.go b/teams_details_test.go index 0f3554a1..42aeda9b 100644 --- a/teams_details_test.go +++ b/teams_details_test.go @@ -3,22 +3,24 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamsDetailsE2E(t *testing.T) { - teamId := CreateTeam(t) + teamId := testutils.CreateTeam(t) - result, err := Client.NewTeamsDetails().TeamId(teamId).Do(context.Background()) + result, err := testutils.Client.NewTeamsDetails().TeamId(teamId).Do(context.Background()) if err != nil { t.Logf("%+v\n", result) t.Error(err) } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.Id, teamId) - AssertEqual(t, result.Data.Name, "test_team") - AssertEqual(t, result.Data.Description, "test_description") - AssertEqual(t, result.Data.Role, "Account Reviewer") + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.Id, teamId) + testutils.AssertEqual(t, result.Data.Name, "test_team") + testutils.AssertEqual(t, result.Data.Description, "test_description") + testutils.AssertEqual(t, result.Data.Role, "Account Reviewer") - t.Cleanup(func() { DeleteTeam(t, teamId) }) -} \ No newline at end of file + t.Cleanup(func() { testutils.DeleteTeam(t, teamId) }) +} diff --git a/teams_list.go b/teams_list.go index b7286b30..bd317d33 100644 --- a/teams_list.go +++ b/teams_list.go @@ -1,86 +1,84 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamsListService implements the Team Management, retrieve List all Teams. // Ref. https://fivetran.com/docs/rest-api/teams#listallteams type TeamsListService struct { - c *Client - limit *int - cursor *string + c *Client + limit *int + cursor *string } type TeamsListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - Id string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Role string `json:"role"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + Code string `json:"code"` + Data struct { + Items []teams.TeamData `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` } func (c *Client) NewTeamsList() *TeamsListService { - return &TeamsListService{c: c} + return &TeamsListService{c: c} } func (s *TeamsListService) Limit(value int) *TeamsListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *TeamsListService) Cursor(value string) *TeamsListService { - s.cursor = &value - return s + s.cursor = &value + return s } func (s *TeamsListService) Do(ctx context.Context) (TeamsListResponse, error) { - var response TeamsListResponse - - url := fmt.Sprintf("%v/teams", s.c.baseURL) - expectedStatus := 200 - - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } - - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamsListResponse + + url := fmt.Sprintf("%v/teams", s.c.baseURL) + expectedStatus := 200 + + headers := s.c.commonHeaders() + + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } + + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/teams_list_test.go b/teams_list_test.go index f1fb90b4..c040d07b 100644 --- a/teams_list_test.go +++ b/teams_list_test.go @@ -1,24 +1,26 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestTeamsListE2E(t *testing.T) { - teamId := CreateTeam(t) + teamId := testutils.CreateTeam(t) - result, err := Client.NewTeamsList().Do(context.Background()) - if err != nil { - t.Logf("%+v\n", result) - t.Error(err) - } + result, err := testutils.Client.NewTeamsList().Do(context.Background()) + if err != nil { + t.Logf("%+v\n", result) + t.Error(err) + } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.Items[0].Id, teamId) - AssertEqual(t, result.Data.Items[0].Name, "test_team") - AssertEqual(t, result.Data.Items[0].Description, "test_description") - AssertEqual(t, result.Data.Items[0].Role, "Account Reviewer") + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.Items[0].Id, teamId) + testutils.AssertEqual(t, result.Data.Items[0].Name, "test_team") + testutils.AssertEqual(t, result.Data.Items[0].Description, "test_description") + testutils.AssertEqual(t, result.Data.Items[0].Role, "Account Reviewer") - t.Cleanup(func() { DeleteTeam(t, teamId) }) + t.Cleanup(func() { testutils.DeleteTeam(t, teamId) }) } diff --git a/teams_modify.go b/teams_modify.go index 5b98fbbc..10dd4bbe 100644 --- a/teams_modify.go +++ b/teams_modify.go @@ -1,111 +1,111 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/teams" ) // TeamsModifyService implements the Team Management, Modify a Team. // Ref. https://fivetran.com/docs/rest-api/teams#modifyateam type TeamsModifyService struct { - c *Client - teamId *string - name *string - description *string - role *string + c *Client + teamId *string + name *string + description *string + role *string } type teamsModifyRequest struct { - Name *string `json:"name,omitempty"` - Description *string `json:"description,omitempty"` - Role *string `json:"role,omitempty"` + Name *string `json:"name,omitempty"` + Description *string `json:"description,omitempty"` + Role *string `json:"role,omitempty"` } type TeamsModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Id string `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Role string `json:"role"` - } `json:"data"` + common.CommonResponse + Data teams.TeamData `json:"data"` } func (c *Client) NewTeamsModify() *TeamsModifyService { - return &TeamsModifyService{c: c} + return &TeamsModifyService{c: c} } func (s *TeamsModifyService) request() *teamsModifyRequest { - return &teamsModifyRequest{ - Name: s.name, - Description: s.description, - Role: s.role, - } + return &teamsModifyRequest{ + Name: s.name, + Description: s.description, + Role: s.role, + } } func (s *TeamsModifyService) TeamId(value string) *TeamsModifyService { - s.teamId = &value - return s + s.teamId = &value + return s } func (s *TeamsModifyService) Name(value string) *TeamsModifyService { - s.name = &value - return s + s.name = &value + return s } func (s *TeamsModifyService) Role(value string) *TeamsModifyService { - s.role = &value - return s + s.role = &value + return s } func (s *TeamsModifyService) Description(value string) *TeamsModifyService { - s.description = &value - return s + s.description = &value + return s } func (s *TeamsModifyService) Do(ctx context.Context) (TeamsModifyResponse, error) { - var response TeamsModifyResponse - - if s.teamId == nil { - return response, fmt.Errorf("missing required teamId") - } - - url := fmt.Sprintf("%v/teams/%v", s.c.baseURL, *s.teamId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil + var response TeamsModifyResponse + + if s.teamId == nil { + return response, fmt.Errorf("missing required teamId") + } + + url := fmt.Sprintf("%v/teams/%v", s.c.baseURL, *s.teamId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/teams_modify_test.go b/teams_modify_test.go index fa90a489..d27ce545 100644 --- a/teams_modify_test.go +++ b/teams_modify_test.go @@ -1,31 +1,33 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewTeamsModifyE2E(t *testing.T) { - teamId := CreateTeam(t) + teamId := testutils.CreateTeam(t) + + modified, err := testutils.Client.NewTeamsModify(). + TeamId(teamId). + Name("test_team"). + Description("test_description_2"). + Role("Account Reviewer"). + Do(context.Background()) - modified, err := Client.NewTeamsModify(). - TeamId(teamId). - Name("test_team"). - Description("test_description_2"). - Role("Account Reviewer"). - Do(context.Background()) + if err != nil { + t.Logf("%+v\n", modified) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", modified) - t.Error(err) - } + testutils.AssertEqual(t, modified.Code, "Success") + testutils.AssertNotEmpty(t, modified.Message) + testutils.AssertNotEmpty(t, modified.Data.Id) + testutils.AssertEqual(t, modified.Data.Name, "test_team") + testutils.AssertEqual(t, modified.Data.Description, "test_description_2") + testutils.AssertEqual(t, modified.Data.Role, "Account Reviewer") - AssertEqual(t, modified.Code, "Success") - AssertNotEmpty(t, modified.Message) - AssertNotEmpty(t, modified.Data.Id) - AssertEqual(t, modified.Data.Name, "test_team") - AssertEqual(t, modified.Data.Description, "test_description_2") - AssertEqual(t, modified.Data.Role, "Account Reviewer") - - t.Cleanup(func() { DeleteTeam(t, modified.Data.Id) }) + t.Cleanup(func() { testutils.DeleteTeam(t, modified.Data.Id) }) } diff --git a/test_utils/test_utils.go b/test_utils/test_utils.go new file mode 100644 index 00000000..8d749366 --- /dev/null +++ b/test_utils/test_utils.go @@ -0,0 +1,679 @@ +package testutils + +import ( + "context" + "fmt" + "log" + "reflect" + "testing" + + "github.com/fivetran/go-fivetran" +) + +var Client *fivetran.Client + +var CertificateHash string +var EncodedCertificate string + +// Tests should be re-written to not use a pre-defined user and group +const ( + PredefinedGroupName = "GoSdkTesting" + PredefinedUserEmail = "dev-markov+go-fivetran-sdk@fivetran.com" + PredefinedUserGivenName = "Go" + PredefinedUserFamilyName = "5Tran" + PredefinedUserPhone = "+1234567890" + BqProjectId = "dulcet-yew-246109" + + // ! WARNING ! + // ! Do not change these values on production ones ! + // ! When running e2e tests locally endure you're using BLANK ACCOUNT credentials ! + PredefinedGroupId = "sepulchre_settlement" + PredefinedUserId = "recoup_befell" +) + +func CreateDbtDestination(t *testing.T) { + t.Helper() + destination, err := Client.NewDestinationCreate(). + GroupID(PredefinedGroupId). + Service("big_query"). + Region("US"). + RunSetupTests(true). + TimeZoneOffset("-5"). + Config( + fivetran.NewDestinationConfig(). + ProjectID(BqProjectId). + DataSetLocation("US")). + Do(context.Background()) + if err != nil { + t.Logf("%+v\n", destination) + t.Error(err) + } +} + +func DeleteDbtDestination() { + resp, err := Client.NewDestinationDelete().DestinationID(PredefinedGroupId).Do(context.Background()) + if err != nil { + log.Fatal(resp, err) + } +} + +func CreateUser(t *testing.T) string { + t.Helper() + user, err := Client.NewUserInvite(). + Email("william_addison.@fivetran.com"). + GivenName("William"). + FamilyName("Addison"). + Phone("+19876543210"). + Role("Account Reviewer"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", user) + t.Error(err) + } + return user.Data.ID +} + +func CreateTempUser(t *testing.T) string { + t.Helper() + userId := CreateUser(t) + t.Cleanup(func() { DeleteUser(t, userId) }) + return userId +} + +func DeleteUser(t *testing.T, id string) { + t.Helper() + user, err := Client.NewUserDelete().UserID(id).Do(context.Background()) + if err != nil { + t.Logf("%+v\n", user) + t.Error(err) + } +} + +func CreateGroup(t *testing.T) string { + t.Helper() + created, err := Client.NewGroupCreate().Name("test").Do(context.Background()) + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + return created.Data.ID +} + +func CreateDbtProject(t *testing.T) string { + t.Helper() + CreateDbtDestination(t) + created, err := Client.NewDbtProjectCreate(). + GroupID(PredefinedGroupId). + DbtVersion("1.3.1"). + ProjectConfig(fivetran.NewDbtProjectConfig(). + GitRemoteUrl("https://github.com/fivetran/dbt_demo"). + FolderPath(""). + GitBranch("main")). + DefaultSchema(""). + TargetName(""). + Threads(4). + Do(context.Background()) + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + return created.Data.ID +} + +func CleanupDbtProjects() { + projects, err := Client.NewDbtProjectsList().Do(context.Background()) + if err != nil { + log.Fatal(err) + } + for _, project := range projects.Data.Items { + CleanupDbtTransformations(project.ID, "") + _, err := Client.NewDbtProjectDelete().DbtProjectID(project.ID).Do(context.Background()) + if err != nil && err.Error() != "status code: 404; expected: 200" { + log.Fatal(err) + } + } + if projects.Data.NextCursor != "" { + CleanupDbtProjects() + } +} + +func CleanupDbtTransformations(projectId, nextCursor string) { + svc := Client.NewDbtModelsList().ProjectId(projectId) + + if nextCursor != "" { + svc.Cursor(nextCursor) + } + + models, err := svc.Do(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, model := range models.Data.Items { + if model.Scheduled { + _, err := Client.NewDbtTransformationDeleteService().TransformationId(model.ID).Do(context.Background()) + if err != nil && err.Error() != "status code: 404; expected: 200" { + log.Fatal(err) + } + } + } + + if models.Data.NextCursor != "" { + CleanupDbtTransformations(projectId, models.Data.NextCursor) + } +} + +func CreateTempGroup(t *testing.T) string { + t.Helper() + groupId := CreateGroup(t) + t.Cleanup(func() { DeleteGroup(t, groupId) }) + return groupId +} + +func DeleteGroup(t *testing.T, id string) { + t.Helper() + deleted, err := Client.NewGroupDelete().GroupID(id).Do(context.Background()) + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func AddUserToGroup(t *testing.T, groupId string, email string) { + t.Helper() + created, err := Client.NewGroupAddUser().GroupID(groupId).Email(email).Role("Destination Administrator").Do(context.Background()) + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } +} + +func RemoveUserFromGroup(t *testing.T, groupId string, userId string) { + t.Helper() + deleted, err := Client.NewGroupRemoveUser().GroupID(groupId).UserID(userId).Do(context.Background()) + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func DeleteDestination(t *testing.T, id string) { + t.Helper() + deleted, err := Client.NewDestinationDelete().DestinationID(id).Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func CreateDestination(t *testing.T) string { + t.Helper() + created, err := Client.NewDestinationCreate(). + GroupID(PredefinedGroupId). + Service("snowflake"). + TimeZoneOffset("+10"). + RunSetupTests(false). + Config(fivetran.NewDestinationConfig(). + Host("your-account.snowflakecomputing.com"). + Port(443). + Database("fivetran"). + Auth("PASSWORD"). + User("fivetran_user"). + Password("123456")). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + return created.Data.ID +} + +func CreateTempDestination(t *testing.T) string { + t.Helper() + destinationId := CreateDestination(t) + t.Cleanup(func() { DeleteDestination(t, destinationId) }) + return destinationId +} + +func CreateDbtTransformation(t *testing.T) string { + t.Helper() + created, err := Client.NewDbtTransformationCreateService(). + DbtModelId(""). + Schedule(fivetran.NewDbtTransformationSchedule(). + ScheduleType("INTEGRATED"). + DaysOfWeek([]string{}). + Interval(0). + TimeOfDay("")). + RunTests(true). + Paused(true). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + return created.Data.ID +} + +func CreateTempDbtTransformation(t *testing.T) string { + t.Helper() + dbtTransformationId := CreateDbtTransformation(t) + t.Cleanup(func() { DeleteDbtTransformation(t, dbtTransformationId) }) + return dbtTransformationId +} + +func DeleteDbtTransformation(t *testing.T, id string) { + t.Helper() + deleted, err := Client.NewDbtTransformationDeleteService(). + TransformationId(id). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func CreateConnector(t *testing.T) string { + t.Helper() + created, err := Client.NewConnectorCreate(). + GroupID(PredefinedGroupId). + Service("itunes_connect"). + RunSetupTests(false). + Config(fivetran.NewConnectorConfig(). + Schema("itunes_e2e_connect"). + Username("fivetran"). + Password("fivetran-api-e2e")). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + + return created.Data.ID +} + +func CreateTempConnector(t *testing.T) string { + t.Helper() + connectorId := CreateConnector(t) + t.Cleanup(func() { DeleteConnector(t, connectorId) }) + return connectorId +} + +func DeleteConnector(t *testing.T, id string) { + t.Helper() + deleted, err := Client.NewConnectorDelete().ConnectorID(id).Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func printError(t *testing.T, actual interface{}, expected interface{}) { + t.Helper() + t.Errorf("Expected: %s"+ + "\n but: <%s>\n", + fmt.Sprintf("value equal to <%v>", expected), + fmt.Sprintf("%v", actual), + ) +} + +func AssertHasLength(t *testing.T, actual interface{}, expected int) { + t.Helper() + + if actual == nil { + printError(t, actual, fmt.Sprintf("value with length %v", expected)) + } else { + lenOfActual := reflect.ValueOf(actual).Len() + if lenOfActual != expected { + printError(t, fmt.Sprintf("length was %d", lenOfActual), fmt.Sprintf("value with length %v", expected)) + } + } +} + +func AssertEqual(t *testing.T, actual interface{}, expected interface{}) { + t.Helper() + + if !reflect.DeepEqual(expected, actual) { + printError(t, actual, expected) + } +} + +func AssertEmpty(t *testing.T, actual interface{}) { + t.Helper() + + var isEmpty bool = isEmpty(actual) + + if !isEmpty { + printError(t, actual, "empty value") + } +} + +func AssertNotEmpty(t *testing.T, actual interface{}) { + t.Helper() + + var isEmpty bool = isEmpty(actual) + + if isEmpty { + printError(t, actual, "none-empty value") + } +} + +func isEmpty(actual interface{}) bool { + var isEmpty bool = false + + if actual == nil { + isEmpty = true + } else if actualValue, ok := actual.(string); ok { + isEmpty = actualValue == "" + } else if reflect.ValueOf(actual).Len() == 0 { + isEmpty = true + } + return isEmpty +} + +func CleanupAccount() { + CleanupUsers() + CleanupDestinations() + CleanupDbtProjects() + CleanupGroups() + CleanupExternalLogging() + CleanupWebhooks() + CleanupTeams() +} + +func IsPredefinedUserExist() bool { + user, err := Client.NewUserDetails().UserID(PredefinedUserId).Do(context.Background()) + if err != nil { + return false + } + return user.Data.GivenName == PredefinedUserGivenName +} + +func IsPredefinedGroupExist() bool { + group, err := Client.NewGroupDetails().GroupID(PredefinedGroupId).Do(context.Background()) + if err != nil { + return false + } + return group.Data.Name == PredefinedGroupName +} + +func CleanupUsers() { + users, err := Client.NewUsersList().Do(context.Background()) + if err != nil { + log.Fatal(err) + } + for _, user := range users.Data.Items { + if user.ID != PredefinedUserId { + _, err := Client.NewUserDelete().UserID(user.ID).Do(context.Background()) + if err != nil { + log.Fatal(err) + } + } + } +} + +func CleanupDestinations() { + groups, err := Client.NewGroupsList().Do(context.Background()) + if err != nil { + log.Fatal(err) + } + for _, group := range groups.Data.Items { + _, err := Client.NewDestinationDelete().DestinationID(group.ID).Do(context.Background()) + if err != nil && err.Error() != "status code: 404; expected: 200" { + log.Fatal(err) + } + } +} + +func CleanupGroups() { + groups, err := Client.NewGroupsList().Do(context.Background()) + if err != nil { + log.Fatal(err) + } + for _, group := range groups.Data.Items { + CleanupConnectors(group.ID) + if group.ID != PredefinedGroupId { + _, err := Client.NewGroupDelete().GroupID(group.ID).Do(context.Background()) + if err != nil { + log.Fatal(err) + } + } + } +} + +func CleanupConnectors(groupId string) { + connectors, err := Client.NewGroupListConnectors().GroupID(groupId).Do(context.Background()) + if err != nil { + log.Fatal(err) + } + for _, connector := range connectors.Data.Items { + _, err := Client.NewConnectorDelete().ConnectorID(connector.ID).Do(context.Background()) + if err != nil { + log.Fatal(err) + } + } +} + +func CleanupExternalLogging() { + groups, err := Client.NewGroupsList().Do(context.Background()) + if err != nil { + log.Fatal(err) + } + for _, group := range groups.Data.Items { + _, err := Client.NewExternalLoggingDelete().ExternalLoggingId(group.ID).Do(context.Background()) + if err != nil && err.Error() != "status code: 404; expected: 200" { + log.Fatal(err) + } + } +} + +func CleanupWebhooks() { + list, err := Client.NewWebhookList().Do(context.Background()) + if err != nil { + log.Fatal(err) + } + for _, webhook := range list.Data.Items { + _, err := Client.NewWebhookDelete().WebhookId(webhook.Id).Do(context.Background()) + if err != nil && err.Error() != "status code: 404; expected: 200" { + log.Fatal(err) + } + } +} + +func CleanupTeams() { + list, err := Client.NewTeamsList().Do(context.Background()) + if err != nil { + log.Fatal(err) + } + + for _, team := range list.Data.Items { + _, err := Client.NewTeamsDelete().TeamId(team.Id).Do(context.Background()) + if err != nil && err.Error() != "status code: 404; expected: 200" { + log.Fatal(err) + } + } + + if list.Data.NextCursor != "" { + CleanupTeams() + } +} + +func CreateTempExternalLogging(t *testing.T) string { + t.Helper() + externalLoggingId := CreateExternalLogging(t) + t.Cleanup(func() { DeleteExternalLogging(t, externalLoggingId) }) + return externalLoggingId +} + +func DeleteExternalLogging(t *testing.T, id string) { + t.Helper() + deleted, err := Client.NewExternalLoggingDelete().ExternalLoggingId(id).Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func CreateExternalLogging(t *testing.T) string { + t.Helper() + created, err := Client.NewExternalLoggingCreate(). + GroupId(PredefinedGroupId). + Service("azure_monitor_log"). + Enabled(true). + Config(fivetran.NewExternalLoggingConfig(). + WorkspaceId("workspace_id"). + PrimaryKey("PASSWORD")). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + return created.Data.Id +} + +func CreateTempWebhook(t *testing.T) string { + t.Helper() + webhookId := CreateWebhookAccount(t) + t.Cleanup(func() { DeleteWebhook(t, webhookId) }) + return webhookId +} + +func DeleteWebhook(t *testing.T, id string) { + t.Helper() + deleted, err := Client.NewWebhookDelete().WebhookId(id).Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func CreateWebhookAccount(t *testing.T) string { + t.Helper() + created, err := Client.NewWebhookAccountCreate(). + Url("https://localhost:12345"). + Secret("my_secret"). + Active(false). + Events([]string{"sync_start", "sync_end"}). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + return created.Data.Id +} + +/* Begin Team Management */ +func CreateTeam(t *testing.T) string { + t.Helper() + created, err := Client.NewTeamsCreate(). + Name("test_team"). + Description("test_description"). + Role("Account Reviewer"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } + return created.Data.Id +} + +func DeleteTeamConnector(t *testing.T, teamId string, connectorId string) { + t.Helper() + deleted, err := Client.NewTeamConnectorMembershipDelete().TeamId(teamId).ConnectorId(connectorId).Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func CreateTeamConnector(t *testing.T, teamId string, connectorId string) { + t.Helper() + created, err := Client.NewTeamConnectorMembershipCreate(). + TeamId(teamId). + ConnectorId(connectorId). + Role("Connector Administrator"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } +} + +func DeleteTeamUser(t *testing.T, teamId string, userId string) { + t.Helper() + deleted, err := Client.NewTeamUserMembershipDelete(). + TeamId(teamId). + UserId(userId). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func CreateTeamUser(t *testing.T, teamId string, userId string) { + t.Helper() + created, err := Client.NewTeamUserMembershipCreate(). + TeamId(teamId). + UserId(userId). + Role("Team Member"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } +} + +func DeleteTeamGroup(t *testing.T, teamId string, groupId string) { + t.Helper() + deleted, err := Client.NewTeamGroupMembershipDelete(). + TeamId(teamId). + GroupId(groupId). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +func CreateTeamGroup(t *testing.T, teamId string, groupId string) { + t.Helper() + created, err := Client.NewTeamGroupMembershipCreate(). + TeamId(teamId). + GroupId(groupId). + Role("Destination Analyst"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } +} + +func DeleteTeam(t *testing.T, id string) { + t.Helper() + deleted, err := Client.NewTeamsDelete().TeamId(id).Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } +} + +/* End Team Management */ diff --git a/tests/connector_create_mock_test.go b/tests/connector_create_mock_test.go index 0baea34e..c630a60a 100644 --- a/tests/connector_create_mock_test.go +++ b/tests/connector_create_mock_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/connectors" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -211,15 +212,15 @@ func prepareConnectorCustomMergedCreateResponse() string { }` } -func prepareConnectorConfig() *fivetran.ConnectorConfig { +func prepareConnectorConfig() *connectors.ConnectorConfig { config := fivetran.NewConnectorConfig() - secretsList := make([]*fivetran.FunctionSecret, 0) + secretsList := make([]*connectors.FunctionSecret, 0) secretsList = append(secretsList, fivetran.NewFunctionSecret().Key("key").Value("value")) config.SecretsList(secretsList) return config } -func prepareConnectorAuth() *fivetran.ConnectorAuth { +func prepareConnectorAuth() *connectors.ConnectorAuth { auth := fivetran.NewConnectorAuth() clientAccess := fivetran.NewConnectorAuthClientAccess().ClientID("client_id").ClientSecret("client_secret") @@ -300,7 +301,7 @@ func assertConnectorRequest(t *testing.T, request map[string]interface{}) { assertKey(t, "client_secret", clientAccess, "client_secret") } -func assertConnectorResponse(t *testing.T, response fivetran.ConnectorCreateResponse) { +func assertConnectorResponse(t *testing.T, response connectors.DetailsWithConfigResponse) { assertEqual(t, response.Code, "Success") assertNotEmpty(t, response.Message) @@ -309,7 +310,7 @@ func assertConnectorResponse(t *testing.T, response fivetran.ConnectorCreateResp assertEqual(t, response.Data.Config.SecretsList[0].Value, "value") } -func assertConnectorCustomResponse(t *testing.T, response fivetran.ConnectorCustomCreateResponse) { +func assertConnectorCustomResponse(t *testing.T, response connectors.DetailsWithCustomConfigResponse) { assertEqual(t, response.Code, "Success") assertNotEmpty(t, response.Message) @@ -317,7 +318,7 @@ func assertConnectorCustomResponse(t *testing.T, response fivetran.ConnectorCust assertKey(t, "value", response.Data.Config["secrets_list"].([]interface{})[0].(map[string]interface{}), "value") } -func assertConnectorCustomMergedResponse(t *testing.T, response fivetran.ConnectorCustomMergedCreateResponse) { +func assertConnectorCustomMergedResponse(t *testing.T, response connectors.DetailsWithCustomMergedConfigResponse) { assertEqual(t, response.Code, "Success") assertNotEmpty(t, response.Message) diff --git a/tests/connector_delete_mock_test.go b/tests/connector_delete_mock_test.go index 5cbb8d3a..1905853f 100644 --- a/tests/connector_delete_mock_test.go +++ b/tests/connector_delete_mock_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -66,7 +66,7 @@ func prepareConnectorDeleteResponse(code string, message string) string { return s } -func assertConnectorDeleteResponse(t *testing.T, response fivetran.ConnectorDeleteResponse, expectCode string, expectMessage string) { +func assertConnectorDeleteResponse(t *testing.T, response common.CommonResponse, expectCode string, expectMessage string) { assertEqual(t, response.Code, expectCode) if response.Message != expectMessage { t.Errorf("expected message '%s', got '%s'", expectMessage, response.Message) diff --git a/tests/connector_details_mock_test.go b/tests/connector_details_mock_test.go index 7602da68..ebfa31a8 100644 --- a/tests/connector_details_mock_test.go +++ b/tests/connector_details_mock_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/connectors" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -135,7 +135,7 @@ func prepareConnectorDetailsResponse() string { }` } -func assertConnectorDetailsResponse(t *testing.T, response fivetran.ConnectorDetailsResponse) { +func assertConnectorDetailsResponse(t *testing.T, response connectors.DetailsWithConfigNoTestsResponse) { assertEqual(t, response.Code, "Success") @@ -145,7 +145,7 @@ func assertConnectorDetailsResponse(t *testing.T, response fivetran.ConnectorDet assertEqual(t, *response.Data.Config.IsKeypair, true) } -func assertCustomConnectorDetailsResponse(t *testing.T, response fivetran.ConnectorCustomDetailsResponse) { +func assertCustomConnectorDetailsResponse(t *testing.T, response connectors.DetailsWithCustomConfigNoTestsResponse) { assertEqual(t, response.Code, "Success") @@ -163,7 +163,7 @@ func assertCustomConnectorDetailsResponse(t *testing.T, response fivetran.Connec assertKey(t, "value", secret, "value") } -func assertCustomMergedConnectorDetailsResponse(t *testing.T, response fivetran.ConnectorCustomMergedDetailsResponse) { +func assertCustomMergedConnectorDetailsResponse(t *testing.T, response connectors.DetailsWithCustomMergedConfigNoTestsResponse) { assertEqual(t, response.Code, "Success") diff --git a/tests/connector_resync_table_mock_test.go b/tests/connector_resync_table_mock_test.go index c077b6db..6ed309d3 100644 --- a/tests/connector_resync_table_mock_test.go +++ b/tests/connector_resync_table_mock_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -52,7 +52,7 @@ func TestConnectorReSyncTableWithNilConnectorID(t *testing.T) { // assert interactions := mockClient.Interactions() assertEqual(t, len(interactions), 0) - assertEqual(t, response, fivetran.ConnectorReSyncTableResponse{}) + assertEqual(t, response, common.CommonResponse{}) assertIsNotNil(t, err) assertEqual(t, err.Error(), "missing required ConnectorID") } @@ -69,7 +69,7 @@ func TestConnectorReSyncTableWithNilSchema(t *testing.T) { // assert interactions := mockClient.Interactions() assertEqual(t, len(interactions), 0) - assertEqual(t, response, fivetran.ConnectorReSyncTableResponse{}) + assertEqual(t, response, common.CommonResponse{}) assertIsNotNil(t, err) assertEqual(t, err.Error(), "missing required Schema") } @@ -86,7 +86,7 @@ func TestConnectorReSyncTableWithNilTable(t *testing.T) { // assert interactions := mockClient.Interactions() assertEqual(t, len(interactions), 0) - assertEqual(t, response, fivetran.ConnectorReSyncTableResponse{}) + assertEqual(t, response, common.CommonResponse{}) assertIsNotNil(t, err) assertEqual(t, err.Error(), "missing required Table") } @@ -126,7 +126,7 @@ func prepareConnectorReSyncTableResponse(code string, message string) string { }` } -func assertConnectorReSyncTableResponse(t *testing.T, response fivetran.ConnectorReSyncTableResponse, code string, message string) { +func assertConnectorReSyncTableResponse(t *testing.T, response common.CommonResponse, code string, message string) { assertEqual(t, response.Code, code) if response.Message != message { t.Errorf("expected message `%s` , got '%s'", message, response.Message) diff --git a/tests/connector_schema_update_mock_test.go b/tests/connector_schema_update_mock_test.go index 4afcd0be..9d9d58df 100644 --- a/tests/connector_schema_update_mock_test.go +++ b/tests/connector_schema_update_mock_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/connectors" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -80,7 +81,7 @@ func assertSchemaRequest(t *testing.T, request map[string]interface{}) { assertKey(t, "hashed", column, true) } -func assertSchemaResponse(t *testing.T, response fivetran.ConnectorSchemaDetailsResponse) { +func assertSchemaResponse(t *testing.T, response connectors.ConnectorSchemaDetailsResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Data.SchemaChangeHandling, "BLOCK_ALL") assertEqual(t, len(response.Data.Schemas), 1) diff --git a/tests/connector_setup_tests_test.go b/tests/connector_setup_tests_test.go index 6facbb2c..1773ef4a 100644 --- a/tests/connector_setup_tests_test.go +++ b/tests/connector_setup_tests_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/connectors" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -63,7 +63,7 @@ func TestConnectorSetupTestsServiceBadRequest(t *testing.T) { assertEqual(t, response.Code, "BadRequest") } -func assertConnectorSetupTestsResponse(t *testing.T, response fivetran.ConnectorSetupTestsResponse) { +func assertConnectorSetupTestsResponse(t *testing.T, response connectors.DetailsWithConfigResponse) { assertEqual(t, response.Code, "Success") assertNotEmpty(t, response.Message) diff --git a/tests/connector_update_mock_test.go b/tests/connector_update_mock_test.go index 3a9e4bac..9d57e01a 100644 --- a/tests/connector_update_mock_test.go +++ b/tests/connector_update_mock_test.go @@ -6,6 +6,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/connectors" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -152,7 +153,7 @@ func prepareCustomUpdateConfig() *map[string]interface{} { return &config } -func prepareCustomMergedAuth() *fivetran.ConnectorAuth { +func prepareCustomMergedAuth() *connectors.ConnectorAuth { auth := fivetran.NewConnectorAuth() clientAccess := fivetran.NewConnectorAuthClientAccess().ClientID("client_id").ClientSecret("client_secret") @@ -170,9 +171,9 @@ func prepareCustomMergedUpdateConfigMap() *map[string]interface{} { return &config } -func prepareCustomMergedConfigUpdate() *fivetran.ConnectorConfig { +func prepareCustomMergedConfigUpdate() *connectors.ConnectorConfig { config := fivetran.NewConnectorConfig() - secretsList := make([]*fivetran.FunctionSecret, 0) + secretsList := make([]*connectors.FunctionSecret, 0) secretsList = append(secretsList, fivetran.NewFunctionSecret().Key("key").Value("value")) config. SecretsList(secretsList). @@ -181,9 +182,9 @@ func prepareCustomMergedConfigUpdate() *fivetran.ConnectorConfig { return config } -func prepareConfigUpdate() *fivetran.ConnectorConfig { +func prepareConfigUpdate() *connectors.ConnectorConfig { config := fivetran.NewConnectorConfig() - secretsList := make([]*fivetran.FunctionSecret, 0) + secretsList := make([]*connectors.FunctionSecret, 0) secretsList = append(secretsList, fivetran.NewFunctionSecret().Key("key").Value("value")) config. SecretsList(secretsList). @@ -238,21 +239,21 @@ func prepareConnectorUpdateResponse() string { }` } -func assertConnectorConfig(t *testing.T, config fivetran.ConnectorConfigResponse) { +func assertConnectorConfig(t *testing.T, config connectors.ConnectorConfigResponse) { assertEqual(t, config.SecretsList[0].Key, "key") assertEqual(t, config.SecretsList[0].Value, "value") assertEqual(t, config.ShareURL, "share_url") assertEqual(t, *config.IsKeypair, true) } -func assertConnectorUpdateResponse(t *testing.T, response fivetran.ConnectorModifyResponse) { +func assertConnectorUpdateResponse(t *testing.T, response connectors.DetailsWithConfigResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, *response.Data.Paused, false) assertConnectorConfig(t, response.Data.Config) } -func assertCustomConnectorUpdateResponse(t *testing.T, response fivetran.ConnectorCustomModifyResponse) { +func assertCustomConnectorUpdateResponse(t *testing.T, response connectors.DetailsWithCustomConfigResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, *response.Data.Paused, false) @@ -271,7 +272,7 @@ func assertCustomConnectorUpdateResponse(t *testing.T, response fivetran.Connect assertKey(t, "value", secret, "value") } -func assertCustomMergedConnectorUpdateResponse(t *testing.T, response fivetran.ConnectorCustomMergedModifyResponse) { +func assertCustomMergedConnectorUpdateResponse(t *testing.T, response connectors.DetailsWithCustomMergedConfigResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, *response.Data.Paused, false) diff --git a/tests/dbt_project_create_mock_test.go b/tests/dbt_project_create_mock_test.go index 84aff745..80913ea9 100644 --- a/tests/dbt_project_create_mock_test.go +++ b/tests/dbt_project_create_mock_test.go @@ -127,7 +127,7 @@ func TestNewDbtProjectCreateFullMappingMock(t *testing.T) { assertEqual(t, response.Data.ID, dbtProjectID) assertEqual(t, response.Data.TargetName, targetName) assertEqual(t, response.Data.DefaultSchema, defaultSchema) - assertEqual(t, response.Data.GroupID, groupID) + assertEqual(t, response.Data.GroupId, groupID) assertEqual(t, response.Data.CreatedAt, createdAt) assertEqual(t, response.Data.CreatedById, createdByID) assertEqual(t, response.Data.PublicKey, publicKey) diff --git a/tests/dbt_project_delete_mock_test.go b/tests/dbt_project_delete_mock_test.go index f0a10340..a53fc861 100644 --- a/tests/dbt_project_delete_mock_test.go +++ b/tests/dbt_project_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -47,7 +47,7 @@ func prepareProjectDeleteResponse() string { }` } -func assertProjectDeleteResponse(t *testing.T, response fivetran.DbtProjectDeleteResponse) { +func assertProjectDeleteResponse(t *testing.T, response common.CommonResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "Project has been deleted") } diff --git a/tests/dbt_project_details_mock_test.go b/tests/dbt_project_details_mock_test.go index 407fe23d..87398e46 100644 --- a/tests/dbt_project_details_mock_test.go +++ b/tests/dbt_project_details_mock_test.go @@ -99,7 +99,7 @@ func TestDbtProjectDetailsService(t *testing.T) { // Check individual fields of the response assertEqual(t, response.Data.ID, dbtProjectID) - assertEqual(t, response.Data.GroupID, groupID) + assertEqual(t, response.Data.GroupId, groupID) assertEqual(t, response.Data.CreatedAt, createdAt) assertEqual(t, response.Data.DefaultSchema, defaultSchema) assertEqual(t, response.Data.TargetName, targetName) diff --git a/tests/dbt_project_modify_mock_test.go b/tests/dbt_project_modify_mock_test.go index 2dd3c688..1228531d 100644 --- a/tests/dbt_project_modify_mock_test.go +++ b/tests/dbt_project_modify_mock_test.go @@ -122,7 +122,7 @@ func TestNewDbtProjectUpdateFullMappingMock(t *testing.T) { assertEqual(t, response.Data.ID, dbtProjectID) assertEqual(t, response.Data.TargetName, targetName) assertEqual(t, response.Data.DefaultSchema, defaultSchema) - assertEqual(t, response.Data.GroupID, groupID) + assertEqual(t, response.Data.GroupId, groupID) assertEqual(t, response.Data.CreatedAt, createdAt) assertEqual(t, response.Data.CreatedById, createdByID) assertEqual(t, response.Data.PublicKey, publicKey) diff --git a/tests/dbt_transformation_create_mock_test.go b/tests/dbt_transformation_create_mock_test.go index 89d095e7..a9529446 100644 --- a/tests/dbt_transformation_create_mock_test.go +++ b/tests/dbt_transformation_create_mock_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/dbt" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -141,7 +142,7 @@ func assertDbtTransformationRequest(t *testing.T, request map[string]interface{} assertKey(t, "time_of_day", schedule, TIME_OF_DAY) } -func assertDbtTransformationResponse(t *testing.T, response fivetran.DbtTransformationResponse) { +func assertDbtTransformationResponse(t *testing.T, response dbt.DbtTransformationResponse) { assertEqual(t, response.Code, "Created") assertNotEmpty(t, response.Message) diff --git a/tests/dbt_transformation_delete_mock_test.go b/tests/dbt_transformation_delete_mock_test.go index 72121c8a..1ab91617 100644 --- a/tests/dbt_transformation_delete_mock_test.go +++ b/tests/dbt_transformation_delete_mock_test.go @@ -5,7 +5,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -67,7 +67,7 @@ func prepareDbtTransformationDeleteResponse(code string, message string) string return s } -func assertDbtTransformationDeleteResponse(t *testing.T, response fivetran.DbtTransformationDeleteResponse, expectCode string, expectMessage string) { +func assertDbtTransformationDeleteResponse(t *testing.T, response common.CommonResponse, expectCode string, expectMessage string) { assertEqual(t, response.Code, expectCode) if response.Message != expectMessage { t.Errorf("expected message '%s', got '%s'", expectMessage, response.Message) diff --git a/tests/dbt_transformation_details_mock_test.go b/tests/dbt_transformation_details_mock_test.go index b68add0d..6588d1ee 100644 --- a/tests/dbt_transformation_details_mock_test.go +++ b/tests/dbt_transformation_details_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/dbt" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -86,7 +86,7 @@ func TestDbtTransformationDetailsService(t *testing.T) { assertDbtTransformationDetailsResponse(t, response) } -func assertDbtTransformationDetailsResponse(t *testing.T, response fivetran.DbtTransformationResponse) { +func assertDbtTransformationDetailsResponse(t *testing.T, response dbt.DbtTransformationResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Data.ID, TRANSFORMATION_ID) diff --git a/tests/dbt_transformation_modify_mock_test.go b/tests/dbt_transformation_modify_mock_test.go index bf074754..6cba0d53 100644 --- a/tests/dbt_transformation_modify_mock_test.go +++ b/tests/dbt_transformation_modify_mock_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/dbt" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -127,7 +128,7 @@ func prepareDbtTransformationModifyResponse() string { ) } -func assertDbtTransformationModifyResponse(t *testing.T, response fivetran.DbtTransformationResponse) { +func assertDbtTransformationModifyResponse(t *testing.T, response dbt.DbtTransformationResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "Dbt transformation has been updated") diff --git a/tests/destination_create_mock_test.go b/tests/destination_create_mock_test.go index 46414074..cb3201f4 100644 --- a/tests/destination_create_mock_test.go +++ b/tests/destination_create_mock_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/destinations" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -196,7 +197,7 @@ func prepareDestinationResponse() string { ) } -func prepareConfig() *fivetran.DestinationConfig { +func prepareConfig() *destinations.DestinationConfig { config := fivetran.NewDestinationConfig() config.Host(HOST) config.Port(PORT) @@ -277,7 +278,7 @@ func assertRequest(t *testing.T, request map[string]interface{}) { assertKey(t, "region", config, REGION) } -func assertResponse(t *testing.T, response fivetran.DestinationCreateResponse) { +func assertResponse(t *testing.T, response destinations.DestinationDetailsWithSetupTestsResponse) { assertEqual(t, response.Code, "Created") assertNotEmpty(t, response.Message) diff --git a/tests/destination_delete_mock_test.go b/tests/destination_delete_mock_test.go index efd648c5..1c22751b 100644 --- a/tests/destination_delete_mock_test.go +++ b/tests/destination_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -54,7 +54,7 @@ func TestDestinationDeleteServiceDoMissingDestinationID(t *testing.T) { assertEqual(t, err, expectedError) } -func assertDestinationDeleteResponse(t *testing.T, response fivetran.DestinationDeleteResponse, code string, massage string) { +func assertDestinationDeleteResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/destination_details_mock_test.go b/tests/destination_details_mock_test.go index 0ba1a084..6192583d 100644 --- a/tests/destination_details_mock_test.go +++ b/tests/destination_details_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/destinations" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -84,7 +84,7 @@ func prepareDestinationDetailsResponse() string { DESTINATION_DETAILS_MASKED_PASSWORD) } -func assertDestinationDetailsResponse(t *testing.T, response fivetran.DestinationDetailsResponse) { +func assertDestinationDetailsResponse(t *testing.T, response destinations.DestinationDetailsResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Data.ID, DESTINATION_DETAILS_ID) assertEqual(t, response.Data.GroupID, DESTINATION_DETAILS_ID) diff --git a/tests/destination_modify_mock_test.go b/tests/destination_modify_mock_test.go index c5882eab..0c613abe 100644 --- a/tests/destination_modify_mock_test.go +++ b/tests/destination_modify_mock_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/destinations" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -131,7 +132,7 @@ func prepareDestinationModifyResponse() string { DESTINATION_MODIFY_MASKED) } -func assertDestinationModifyResponse(t *testing.T, response fivetran.DestinationModifyResponse) { +func assertDestinationModifyResponse(t *testing.T, response destinations.DestinationDetailsWithSetupTestsResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "Destination has been updated") assertEqual(t, response.Data.ID, DESTINATION_MODIFY_ID) diff --git a/tests/external_logging_create_mock_test.go b/tests/external_logging_create_mock_test.go index da655888..075f582a 100644 --- a/tests/external_logging_create_mock_test.go +++ b/tests/external_logging_create_mock_test.go @@ -1,141 +1,142 @@ package tests import ( - "context" - "fmt" - "net/http" - "testing" - - "github.com/fivetran/go-fivetran" - "github.com/fivetran/go-fivetran/tests/mock" + "context" + "fmt" + "net/http" + "testing" + + "github.com/fivetran/go-fivetran" + externallogging "github.com/fivetran/go-fivetran/external_logging" + "github.com/fivetran/go-fivetran/tests/mock" ) const ( - EXTLOG_GROUPID = "group_id" - EXTLOG_SERVICE = "service" - EXTLOG_ENABLED = true - - EXTLOG_WORKSPACEID = "workspace_id" - EXTLOG_PRIMARYKEY = "primary_key" - EXTLOG_LOGGROUPNAME = "log_group_name" - EXTLOG_ROLEARN = "role_arn" - EXTLOG_EXTERNALID = "external_id" - EXTLOG_REGION = "region" - EXTLOG_APIKEY = "api_key" - EXTLOG_SUBDOMAIN = "sub_domain" - EXTLOG_HOST = "host" - EXTLOG_HOSTNAME = "hostname" - EXTLOG_CHANNEL = "channel" - EXTLOG_ENABLESSL = false - EXTLOG_TOKEN = "token" - EXTLOG_PORT = 443 + EXTLOG_GROUPID = "group_id" + EXTLOG_SERVICE = "service" + EXTLOG_ENABLED = true + + EXTLOG_WORKSPACEID = "workspace_id" + EXTLOG_PRIMARYKEY = "primary_key" + EXTLOG_LOGGROUPNAME = "log_group_name" + EXTLOG_ROLEARN = "role_arn" + EXTLOG_EXTERNALID = "external_id" + EXTLOG_REGION = "region" + EXTLOG_APIKEY = "api_key" + EXTLOG_SUBDOMAIN = "sub_domain" + EXTLOG_HOST = "host" + EXTLOG_HOSTNAME = "hostname" + EXTLOG_CHANNEL = "channel" + EXTLOG_ENABLESSL = false + EXTLOG_TOKEN = "token" + EXTLOG_PORT = 443 ) func TestNewExternalLoggingCreateFullMappingMock(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPost, "/v1/external-logging").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertExternalLoggingFullRequest(t, body) - response := mock.NewResponse(req, http.StatusCreated, prepareExternalLoggingResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewExternalLoggingCreate(). - GroupId(EXTLOG_GROUPID). - Service(EXTLOG_SERVICE). - Enabled(EXTLOG_ENABLED). - Config(prepareExternalLoggingConfig()). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertExternalLoggingResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPost, "/v1/external-logging").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertExternalLoggingFullRequest(t, body) + response := mock.NewResponse(req, http.StatusCreated, prepareExternalLoggingResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewExternalLoggingCreate(). + GroupId(EXTLOG_GROUPID). + Service(EXTLOG_SERVICE). + Enabled(EXTLOG_ENABLED). + Config(prepareExternalLoggingConfig()). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertExternalLoggingResponse(t, response) } func TestNewExternalLoggingCustomMappingMock(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPost, "/v1/external-logging").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertExternalLoggingCustomRequest(t, body) - response := mock.NewResponse(req, http.StatusCreated, prepareExternalLoggingResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewExternalLoggingCreate(). - GroupId(EXTLOG_GROUPID). - Service(EXTLOG_SERVICE). - Enabled(EXTLOG_ENABLED). - ConfigCustom(prepareExternalLoggingCustomMergedConfig()). - DoCustom(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertExternalLoggingCustomResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPost, "/v1/external-logging").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertExternalLoggingCustomRequest(t, body) + response := mock.NewResponse(req, http.StatusCreated, prepareExternalLoggingResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewExternalLoggingCreate(). + GroupId(EXTLOG_GROUPID). + Service(EXTLOG_SERVICE). + Enabled(EXTLOG_ENABLED). + ConfigCustom(prepareExternalLoggingCustomMergedConfig()). + DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertExternalLoggingCustomResponse(t, response) } func TestNewExternalLoggingCustomMergedMappingMock(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPost, "/v1/external-logging").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertExternalLoggingCustomRequest(t, body) - response := mock.NewResponse(req, http.StatusCreated, prepareExternalLoggingMergedResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewExternalLoggingCreate(). - GroupId(EXTLOG_GROUPID). - Service(EXTLOG_SERVICE). - Enabled(EXTLOG_ENABLED). - Config(prepareExternalLoggingConfig()). - ConfigCustom(prepareExternalLoggingCustomMergedConfig()). - DoCustomMerged(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - assertExternalLoggingCustomMergedResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPost, "/v1/external-logging").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertExternalLoggingCustomMergedRequest(t, body) + response := mock.NewResponse(req, http.StatusCreated, prepareExternalLoggingMergedResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewExternalLoggingCreate(). + GroupId(EXTLOG_GROUPID). + Service(EXTLOG_SERVICE). + Enabled(EXTLOG_ENABLED). + Config(prepareExternalLoggingConfig()). + ConfigCustom(prepareExternalLoggingCustomMergedConfig()). + DoCustomMerged(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + assertExternalLoggingCustomMergedResponse(t, response) } func prepareExternalLoggingResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code":"Created", "message":"External logging service has been added", "data":{ @@ -148,17 +149,17 @@ func prepareExternalLoggingResponse() string { } } }`, - EXTLOG_GROUPID, - EXTLOG_SERVICE, - EXTLOG_ENABLED, - EXTLOG_WORKSPACEID, - EXTLOG_PRIMARYKEY, - ) + EXTLOG_GROUPID, + EXTLOG_SERVICE, + EXTLOG_ENABLED, + EXTLOG_WORKSPACEID, + EXTLOG_PRIMARYKEY, + ) } func prepareExternalLoggingMergedResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code":"Created", "message":"External logging service has been added", "data":{ @@ -172,102 +173,101 @@ func prepareExternalLoggingMergedResponse() string { } } }`, - EXTLOG_GROUPID, - EXTLOG_SERVICE, - EXTLOG_ENABLED, - EXTLOG_WORKSPACEID, - EXTLOG_PRIMARYKEY, - ) + EXTLOG_GROUPID, + EXTLOG_SERVICE, + EXTLOG_ENABLED, + EXTLOG_WORKSPACEID, + EXTLOG_PRIMARYKEY, + ) } +func prepareExternalLoggingConfig() *externallogging.ExternalLoggingConfig { + config := fivetran.NewExternalLoggingConfig() + config.WorkspaceId(EXTLOG_WORKSPACEID) + config.PrimaryKey(EXTLOG_PRIMARYKEY) -func prepareExternalLoggingConfig() *fivetran.ExternalLoggingConfig { - config := fivetran.NewExternalLoggingConfig() - config.WorkspaceId(EXTLOG_WORKSPACEID) - config.PrimaryKey(EXTLOG_PRIMARYKEY) - - return config + return config } func prepareExternalLoggingCustomMergedConfig() *map[string]interface{} { - config := make(map[string]interface{}) + config := make(map[string]interface{}) - config["fake_field"] = "unmapped-value" + config["fake_field"] = "unmapped-value" - return &config + return &config } func assertExternalLoggingFullRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "service", request, EXTLOG_SERVICE) - assertKey(t, "group_id", request, EXTLOG_GROUPID) - assertKey(t, "enabled", request, EXTLOG_ENABLED) + assertKey(t, "service", request, EXTLOG_SERVICE) + assertKey(t, "group_id", request, EXTLOG_GROUPID) + assertKey(t, "enabled", request, EXTLOG_ENABLED) - config, ok := request["config"].(map[string]interface{}) - assertEqual(t, ok, true) + config, ok := request["config"].(map[string]interface{}) + assertEqual(t, ok, true) - assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) - assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) + assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) + assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) } func assertExternalLoggingCustomRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "service", request, EXTLOG_SERVICE) - assertKey(t, "group_id", request, EXTLOG_GROUPID) - assertKey(t, "enabled", request, EXTLOG_ENABLED) + assertKey(t, "service", request, EXTLOG_SERVICE) + assertKey(t, "group_id", request, EXTLOG_GROUPID) + assertKey(t, "enabled", request, EXTLOG_ENABLED) - config, ok := request["config"].(map[string]interface{}) - - assertEqual(t, ok, true) + config, ok := request["config"].(map[string]interface{}) - assertKey(t, "fake_field", config, "unmapped-value") + assertEqual(t, ok, true) + + assertKey(t, "fake_field", config, "unmapped-value") } func assertExternalLoggingCustomMergedRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "service", request, EXTLOG_SERVICE) - assertKey(t, "group_id", request, EXTLOG_GROUPID) - assertKey(t, "enabled", request, EXTLOG_ENABLED) + assertKey(t, "service", request, EXTLOG_SERVICE) + assertKey(t, "group_id", request, EXTLOG_GROUPID) + assertKey(t, "enabled", request, EXTLOG_ENABLED) + + config, ok := request["config"].(map[string]interface{}) - config, ok := request["config"].(map[string]interface{}) - - assertEqual(t, ok, true) + assertEqual(t, ok, true) - assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) - assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) - assertKey(t, "fake_field", config, "unmapped-value") + assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) + assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) + assertKey(t, "fake_field", config, "unmapped-value") } -func assertExternalLoggingResponse(t *testing.T, response fivetran.ExternalLoggingCreateResponse) { - assertEqual(t, response.Code, "Created") - assertNotEmpty(t, response.Message) +func assertExternalLoggingResponse(t *testing.T, response externallogging.ExternalLoggingResponse) { + assertEqual(t, response.Code, "Created") + assertNotEmpty(t, response.Message) - assertEqual(t, response.Data.Id, EXTLOG_GROUPID) - assertEqual(t, response.Data.Service, EXTLOG_SERVICE) - assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) + assertEqual(t, response.Data.Id, EXTLOG_GROUPID) + assertEqual(t, response.Data.Service, EXTLOG_SERVICE) + assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) - assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) - assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) + assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) + assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) } -func assertExternalLoggingCustomResponse(t *testing.T, response fivetran.ExternalLoggingCustomCreateResponse) { - assertEqual(t, response.Code, "Created") - assertNotEmpty(t, response.Message) +func assertExternalLoggingCustomResponse(t *testing.T, response externallogging.ExternalLoggingCustomResponse) { + assertEqual(t, response.Code, "Created") + assertNotEmpty(t, response.Message) - assertEqual(t, response.Data.Id, EXTLOG_GROUPID) - assertEqual(t, response.Data.Service, EXTLOG_SERVICE) - assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) + assertEqual(t, response.Data.Id, EXTLOG_GROUPID) + assertEqual(t, response.Data.Service, EXTLOG_SERVICE) + assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) - assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) - assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) + assertEqual(t, response.Data.Config["workspace_id"], EXTLOG_WORKSPACEID) + assertEqual(t, response.Data.Config["primary_key"], EXTLOG_PRIMARYKEY) } -func assertExternalLoggingCustomMergedResponse(t *testing.T, response fivetran.ExternalLoggingCustomMergedCreateResponse) { - assertEqual(t, response.Code, "Created") - assertNotEmpty(t, response.Message) +func assertExternalLoggingCustomMergedResponse(t *testing.T, response externallogging.ExternalLoggingCustomMergedResponse) { + assertEqual(t, response.Code, "Created") + assertNotEmpty(t, response.Message) - assertEqual(t, response.Data.Id, EXTLOG_GROUPID) - assertEqual(t, response.Data.Service, EXTLOG_SERVICE) - assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) + assertEqual(t, response.Data.Id, EXTLOG_GROUPID) + assertEqual(t, response.Data.Service, EXTLOG_SERVICE) + assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) - assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) - assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) - assertKey(t, "fake_field", response.Data.CustomConfig, "unmapped-value") + assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) + assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) + assertKey(t, "fake_field", response.Data.CustomConfig, "unmapped-value") } diff --git a/tests/external_logging_delete_mock_test.go b/tests/external_logging_delete_mock_test.go index e4faf7c3..58d6ecb1 100644 --- a/tests/external_logging_delete_mock_test.go +++ b/tests/external_logging_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -54,7 +54,7 @@ func TestExternalLoggingDeleteServiceDoMissingExternalLoggingID(t *testing.T) { assertEqual(t, err, expectedError) } -func assertExternalLoggingDeleteResponse(t *testing.T, response fivetran.ExternalLoggingDeleteResponse, code string, massage string) { +func assertExternalLoggingDeleteResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/external_logging_modify_mock_test.go b/tests/external_logging_modify_mock_test.go index c90eee27..433a5351 100644 --- a/tests/external_logging_modify_mock_test.go +++ b/tests/external_logging_modify_mock_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + externallogging "github.com/fivetran/go-fivetran/external_logging" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -21,12 +22,12 @@ func TestExternalLoggingModifyService(t *testing.T) { return response, nil }) - // act - response, err := ftClient.NewExternalLoggingModify(). - ExternalLoggingId("log_id"). - Enabled(EXTLOG_ENABLED). - Config(prepareExternalLoggingModifyConfig()). - Do(context.Background()) + // act + response, err := ftClient.NewExternalLoggingModify(). + ExternalLoggingId("log_id"). + Enabled(EXTLOG_ENABLED). + Config(prepareExternalLoggingModifyConfig()). + Do(context.Background()) if err != nil { t.Logf("%+v\n", response) @@ -42,9 +43,8 @@ func TestExternalLoggingModifyService(t *testing.T) { assertExternalLoggingModifyResponse(t, response) } - func TestExternalLoggingCustomModifyService(t *testing.T) { - // arrange + // arrange // arrange ftClient, mockClient := CreateTestClient() handler := mockClient.When(http.MethodPatch, "/v1/external-logging/log_id").ThenCall( @@ -55,64 +55,64 @@ func TestExternalLoggingCustomModifyService(t *testing.T) { return response, nil }) - // act - response, err := ftClient.NewExternalLoggingModify(). - ExternalLoggingId("log_id"). - Enabled(EXTLOG_ENABLED). - ConfigCustom(prepareExternalLoggingCustomMergedConfig()). - DoCustom(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertExternalLoggingModifyCustomResponse(t, response) + // act + response, err := ftClient.NewExternalLoggingModify(). + ExternalLoggingId("log_id"). + Enabled(EXTLOG_ENABLED). + ConfigCustom(prepareExternalLoggingCustomConfig()). + DoCustom(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertExternalLoggingModifyCustomResponse(t, response) } func TestExternalLoggingCustomMergedModifyService(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPatch, "/v1/external-logging/log_id").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertExternalLoggingModifyCustomMergedRequest(t, body) - response := mock.NewResponse(req, http.StatusOK, prepareExternalLoggingModifyMergedResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewExternalLoggingModify(). - ExternalLoggingId("log_id"). - Enabled(EXTLOG_ENABLED). - Config(prepareExternalLoggingModifyConfig()). - ConfigCustom(prepareExternalLoggingCustomMergedConfig()). - DoCustomMerged(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertExternalLoggingModifyCustomMergedResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPatch, "/v1/external-logging/log_id").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertExternalLoggingModifyCustomMergedRequest(t, body) + response := mock.NewResponse(req, http.StatusOK, prepareExternalLoggingModifyMergedResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewExternalLoggingModify(). + ExternalLoggingId("log_id"). + Enabled(EXTLOG_ENABLED). + Config(prepareExternalLoggingModifyConfig()). + ConfigCustom(prepareExternalLoggingCustomMergedConfig()). + DoCustomMerged(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertExternalLoggingModifyCustomMergedResponse(t, response) } func prepareExternalLoggingModifyResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "External logging service has been updated", "data":{ @@ -125,17 +125,17 @@ func prepareExternalLoggingModifyResponse() string { } } }`, - EXTLOG_GROUPID, - EXTLOG_SERVICE, - EXTLOG_ENABLED, - EXTLOG_WORKSPACEID, - EXTLOG_PRIMARYKEY, - ) + EXTLOG_GROUPID, + EXTLOG_SERVICE, + EXTLOG_ENABLED, + EXTLOG_WORKSPACEID, + EXTLOG_PRIMARYKEY, + ) } func prepareExternalLoggingModifyMergedResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "External logging service has been updated", "data":{ @@ -149,94 +149,93 @@ func prepareExternalLoggingModifyMergedResponse() string { } } }`, - EXTLOG_GROUPID, - EXTLOG_SERVICE, - EXTLOG_ENABLED, - EXTLOG_WORKSPACEID, - EXTLOG_PRIMARYKEY, - ) + EXTLOG_GROUPID, + EXTLOG_SERVICE, + EXTLOG_ENABLED, + EXTLOG_WORKSPACEID, + EXTLOG_PRIMARYKEY, + ) } -func prepareExternalLoggingModifyConfig() *fivetran.ExternalLoggingConfig { - config := fivetran.NewExternalLoggingConfig() - config.WorkspaceId(EXTLOG_WORKSPACEID) - config.PrimaryKey(EXTLOG_PRIMARYKEY) +func prepareExternalLoggingModifyConfig() *externallogging.ExternalLoggingConfig { + config := fivetran.NewExternalLoggingConfig() + config.WorkspaceId(EXTLOG_WORKSPACEID) + config.PrimaryKey(EXTLOG_PRIMARYKEY) - return config + return config } func prepareExternalLoggingCustomConfig() *map[string]interface{} { - config := make(map[string]interface{}) + config := make(map[string]interface{}) - config["fake_field"] = "unmapped-value" + config["fake_field"] = "unmapped-value" - return &config + return &config } // assert Requests func assertExternalLoggingModifyRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "enabled", request, EXTLOG_ENABLED) + assertKey(t, "enabled", request, EXTLOG_ENABLED) - config, ok := request["config"].(map[string]interface{}) - assertEqual(t, ok, true) + config, ok := request["config"].(map[string]interface{}) + assertEqual(t, ok, true) - assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) - assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) + assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) + assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) } func assertExternalLoggingModifyCustomRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "enabled", request, EXTLOG_ENABLED) + assertKey(t, "enabled", request, EXTLOG_ENABLED) - config, ok := request["config"].(map[string]interface{}) - - assertEqual(t, ok, true) + config, ok := request["config"].(map[string]interface{}) - assertKey(t, "fake_field", config, "unmapped-value") + assertEqual(t, ok, true) + + assertKey(t, "fake_field", config, "unmapped-value") } func assertExternalLoggingModifyCustomMergedRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "enabled", request, EXTLOG_ENABLED) + assertKey(t, "enabled", request, EXTLOG_ENABLED) - config, ok := request["config"].(map[string]interface{}) - - assertEqual(t, ok, true) + config, ok := request["config"].(map[string]interface{}) - assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) - assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) - assertKey(t, "fake_field", config, "unmapped-value") -} + assertEqual(t, ok, true) + assertKey(t, "workspace_id", config, EXTLOG_WORKSPACEID) + assertKey(t, "primary_key", config, EXTLOG_PRIMARYKEY) + assertKey(t, "fake_field", config, "unmapped-value") +} // assert Response -func assertExternalLoggingModifyResponse(t *testing.T, response fivetran.ExternalLoggingModifyResponse) { +func assertExternalLoggingModifyResponse(t *testing.T, response externallogging.ExternalLoggingResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "External logging service has been updated") - assertEqual(t, response.Data.Id, EXTLOG_GROUPID) - assertEqual(t, response.Data.Service, EXTLOG_SERVICE) - assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) + assertEqual(t, response.Data.Id, EXTLOG_GROUPID) + assertEqual(t, response.Data.Service, EXTLOG_SERVICE) + assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) - assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) - assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) + assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) + assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) } -func assertExternalLoggingModifyCustomResponse(t *testing.T, response fivetran.ExternalLoggingModifyCustomResponse) { +func assertExternalLoggingModifyCustomResponse(t *testing.T, response externallogging.ExternalLoggingCustomResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "External logging service has been updated") - assertEqual(t, response.Data.Id, EXTLOG_GROUPID) - assertEqual(t, response.Data.Service, EXTLOG_SERVICE) - assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) + assertEqual(t, response.Data.Id, EXTLOG_GROUPID) + assertEqual(t, response.Data.Service, EXTLOG_SERVICE) + assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) - assertKey(t, "fake_field", response.Data.Config, "unmapped-value") + assertKey(t, "fake_field", response.Data.Config, "unmapped-value") } -func assertExternalLoggingModifyCustomMergedResponse(t *testing.T, response fivetran.ExternalLoggingModifyCustomMergedResponse) { +func assertExternalLoggingModifyCustomMergedResponse(t *testing.T, response externallogging.ExternalLoggingCustomMergedResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "External logging service has been updated") - assertEqual(t, response.Data.Id, EXTLOG_GROUPID) - assertEqual(t, response.Data.Service, EXTLOG_SERVICE) - assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) - - assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) - assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) - assertKey(t, "fake_field", response.Data.CustomConfig, "unmapped-value") -} \ No newline at end of file + assertEqual(t, response.Data.Id, EXTLOG_GROUPID) + assertEqual(t, response.Data.Service, EXTLOG_SERVICE) + assertEqual(t, response.Data.Enabled, EXTLOG_ENABLED) + + assertEqual(t, response.Data.Config.WorkspaceId, EXTLOG_WORKSPACEID) + assertEqual(t, response.Data.Config.PrimaryKey, EXTLOG_PRIMARYKEY) + assertKey(t, "fake_field", response.Data.CustomConfig, "unmapped-value") +} diff --git a/tests/group_add_mock_test.go b/tests/group_add_mock_test.go index 4a2f857a..0bebffa8 100644 --- a/tests/group_add_mock_test.go +++ b/tests/group_add_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -56,7 +56,7 @@ func assertGroupAddUserRequest(t *testing.T, assertKey(t, "role", body, expectedRole) } -func assertGroupAddUserResponse(t *testing.T, response fivetran.GroupAddUserResponse) { +func assertGroupAddUserResponse(t *testing.T, response common.CommonResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "User has been added to the group") } diff --git a/tests/group_create_mock_test.go b/tests/group_create_mock_test.go index 995f174e..402c4f0c 100644 --- a/tests/group_create_mock_test.go +++ b/tests/group_create_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/groups" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -68,7 +68,7 @@ func prepareGroupCreateResponse() string { ) } -func assertGroupCreateResponse(t *testing.T, response fivetran.GroupCreateResponse) { +func assertGroupCreateResponse(t *testing.T, response groups.GroupDetailsResponse) { assertEqual(t, response.Code, ExpectedGroupCreateCode) assertEqual(t, response.Message, ExpectedGroupCreateMessage) diff --git a/tests/group_delete_mock_test.go b/tests/group_delete_mock_test.go index 5ccf3820..be603b6e 100644 --- a/tests/group_delete_mock_test.go +++ b/tests/group_delete_mock_test.go @@ -2,11 +2,10 @@ package tests import ( "context" - "fmt" "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -41,13 +40,13 @@ func TestGroupDeleteServiceDo(t *testing.T) { } func prepareGroupDeleteResponse() string { - return fmt.Sprintf(`{ + return `{ "code": "Success", "message": "Group has been deleted" - }`) + }` } -func assertGroupDeleteResponse(t *testing.T, response fivetran.GroupDeleteResponse) { +func assertGroupDeleteResponse(t *testing.T, response common.CommonResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "Group has been deleted") } diff --git a/tests/group_details_mock_test.go b/tests/group_details_mock_test.go index 3968871f..3e464a34 100644 --- a/tests/group_details_mock_test.go +++ b/tests/group_details_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/groups" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -57,7 +57,7 @@ func prepareGroupDetailsResponse() string { EXPECTED_CREATED_AT) } -func assertGroupDetailsResponse(t *testing.T, response fivetran.GroupDetailsResponse, expectedID, expectedName string, expectedCreatedAt string) { +func assertGroupDetailsResponse(t *testing.T, response groups.GroupDetailsResponse, expectedID, expectedName string, expectedCreatedAt string) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Data.ID, expectedID) assertEqual(t, response.Data.Name, expectedName) diff --git a/tests/group_list_connectors_mock_test.go b/tests/group_list_connectors_mock_test.go index b00326a6..017a6b04 100644 --- a/tests/group_list_connectors_mock_test.go +++ b/tests/group_list_connectors_mock_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -127,7 +128,7 @@ func assertGroupListConnectorsResponse(t *testing.T, response fivetran.GroupList assertEqual(t, *item.Status.IsHistoricalSync, LIST_CONNECTORS_IS_HISTORICAL_SYNC) assertEqual(t, item.Status.SetupState, LIST_CONNECTORS_SETUP_STATE) assertEqual(t, item.Status.SyncState, LIST_CONNECTORS_SYNC_STATE) - assertEqual(t, item.Status.Tasks, []fivetran.ConnectorTasks{}) + assertEqual(t, item.Status.Tasks, []common.CommonResponse{}) assertEqual(t, item.Status.UpdateState, LIST_CONNECTORS_UPDATE_STATE) - assertEqual(t, item.Status.Warnings, []fivetran.ConnectorWarning{}) + assertEqual(t, item.Status.Warnings, []common.CommonResponse{}) } diff --git a/tests/group_modify_mock_test.go b/tests/group_modify_mock_test.go index 836e709b..8e3f9dc5 100644 --- a/tests/group_modify_mock_test.go +++ b/tests/group_modify_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/groups" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -64,7 +64,7 @@ func assertGroupModifyRequest(t *testing.T, request map[string]interface{}) { assertKey(t, "name", request, GROUP_MODIFY_EXPECTED_GROUP_NAME) } -func assertGroupModifyResponse(t *testing.T, response fivetran.GroupModifyResponse) { +func assertGroupModifyResponse(t *testing.T, response groups.GroupDetailsResponse) { assertEqual(t, response.Code, "Success") assertEqual(t, response.Message, "Group has been updated") assertEqual(t, response.Data.ID, GROUP_MODIFY_GROUP_ID) diff --git a/tests/group_remove_user_mock_test.go b/tests/group_remove_user_mock_test.go index 7c74b582..2c22c051 100644 --- a/tests/group_remove_user_mock_test.go +++ b/tests/group_remove_user_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -47,7 +47,7 @@ func prepareGroupRemoveUserResponse(expectedUserID string) string { }`, expectedUserID) } -func assertGroupRemoveUserResponse(t *testing.T, response fivetran.GroupRemoveUserResponse, expectedUserID string) { +func assertGroupRemoveUserResponse(t *testing.T, response common.CommonResponse, expectedUserID string) { assertEqual(t, response.Code, "Success") expectedMessage := fmt.Sprintf("User with id '%v' has been removed from the group", expectedUserID) assertEqual(t, response.Message, expectedMessage) diff --git a/tests/helpers_test.go b/tests/helpers_test.go index 5936a6a2..2183c2c8 100644 --- a/tests/helpers_test.go +++ b/tests/helpers_test.go @@ -3,7 +3,7 @@ package tests import ( "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/utils" ) type testStruct struct { @@ -20,7 +20,7 @@ func TestMergeIntoMap(t *testing.T) { } testMap := make(map[string]interface{}) testMap["some_key"] = "someKeyValue" - fivetran.MergeIntoMap(testValue, &testMap) + utils.MergeIntoMap(testValue, &testMap) assertKeyValue(t, testMap, "some_field", someFieldValue) assertKeyValue(t, testMap, "another_field", anotherFieldValue) assertKeyValue(t, testMap, "some_key", "someKeyValue") @@ -33,7 +33,7 @@ func TestFetchFromMap(t *testing.T) { testMap["another_field"] = "anotherFieldValue" var testValue testStruct - err := fivetran.FetchFromMap(&testMap, &testValue) + err := utils.FetchFromMap(&testMap, &testValue) assertIsNil(t, err) assertIsNotNil(t, testValue) diff --git a/tests/team_connector_delete_mock_test.go b/tests/team_connector_delete_mock_test.go index 4ad0b3e6..7f30ca43 100644 --- a/tests/team_connector_delete_mock_test.go +++ b/tests/team_connector_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -68,7 +68,7 @@ func TestTeamConnectorDeleteServiceDoMissingConnectorId(t *testing.T) { assertEqual(t, err, expectedError) } -func assertTeamConnectorDeleteResponse(t *testing.T, response fivetran.TeamConnectorMembershipDeleteResponse, code string, massage string) { +func assertTeamConnectorDeleteResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/team_connector_modify_mock_test.go b/tests/team_connector_modify_mock_test.go index 52ef3b54..7ff166ce 100644 --- a/tests/team_connector_modify_mock_test.go +++ b/tests/team_connector_modify_mock_test.go @@ -1,62 +1,62 @@ package tests import ( - "context" - "fmt" - "net/http" - "testing" + "context" + "fmt" + "net/http" + "testing" - "github.com/fivetran/go-fivetran" - "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/common" + "github.com/fivetran/go-fivetran/tests/mock" ) func TestNewTeamConnectorModify(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPatch, "/v1/teams/team_id/connectors/connector_id").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertTeamConnectorModifyRequest(t, body) - response := mock.NewResponse(req, http.StatusOK, prepareTeamConnectorModifyResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewTeamConnectorMembershipModify(). - TeamId("team_id"). - ConnectorId("connector_id"). - Role("Changed role"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertTeamConnectorModifyResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPatch, "/v1/teams/team_id/connectors/connector_id").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertTeamConnectorModifyRequest(t, body) + response := mock.NewResponse(req, http.StatusOK, prepareTeamConnectorModifyResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewTeamConnectorMembershipModify(). + TeamId("team_id"). + ConnectorId("connector_id"). + Role("Changed role"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertTeamConnectorModifyResponse(t, response) } func prepareTeamConnectorModifyResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "Connector membership has been updated" }`, - ) + ) } func assertTeamConnectorModifyRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "role", request, "Changed role") + assertKey(t, "role", request, "Changed role") } -func assertTeamConnectorModifyResponse(t *testing.T, response fivetran.TeamConnectorMembershipModifyResponse) { - assertEqual(t, response.Code, "Success") - assertNotEmpty(t, response.Message) -} \ No newline at end of file +func assertTeamConnectorModifyResponse(t *testing.T, response common.CommonResponse) { + assertEqual(t, response.Code, "Success") + assertNotEmpty(t, response.Message) +} diff --git a/tests/team_delete_role_in_account_mock_test.go b/tests/team_delete_role_in_account_mock_test.go index 96bf2f1a..a9a19497 100644 --- a/tests/team_delete_role_in_account_mock_test.go +++ b/tests/team_delete_role_in_account_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -54,7 +54,7 @@ func TestTeamDeleteRoleInAccountServiceDoMissingId(t *testing.T) { assertEqual(t, err, expectedError) } -func assertTeamDeleteRoleInAccountResponse(t *testing.T, response fivetran.TeamsDeleteRoleInAccountResponse, code string, massage string) { +func assertTeamDeleteRoleInAccountResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/team_group_delete_mock_test.go b/tests/team_group_delete_mock_test.go index 580ac98e..33a8dd21 100644 --- a/tests/team_group_delete_mock_test.go +++ b/tests/team_group_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -68,7 +68,7 @@ func TestTeamGroupDeleteServiceDoMissingConnectorId(t *testing.T) { assertEqual(t, err, expectedError) } -func assertTeamGroupDeleteResponse(t *testing.T, response fivetran.TeamGroupMembershipDeleteResponse, code string, massage string) { +func assertTeamGroupDeleteResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/team_group_modify_mock_test.go b/tests/team_group_modify_mock_test.go index 0521f7ab..221263d3 100644 --- a/tests/team_group_modify_mock_test.go +++ b/tests/team_group_modify_mock_test.go @@ -1,62 +1,62 @@ package tests import ( - "context" - "fmt" - "net/http" - "testing" + "context" + "fmt" + "net/http" + "testing" - "github.com/fivetran/go-fivetran" - "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/common" + "github.com/fivetran/go-fivetran/tests/mock" ) func TestNewTeamGroupModify(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPatch, "/v1/teams/team_id/groups/group_id").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertTeamGroupModifyRequest(t, body) - response := mock.NewResponse(req, http.StatusOK, prepareTeamGroupModifyResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewTeamGroupMembershipModify(). - TeamId("team_id"). - GroupId("group_id"). - Role("Changed role"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertTeamGroupModifyResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPatch, "/v1/teams/team_id/groups/group_id").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertTeamGroupModifyRequest(t, body) + response := mock.NewResponse(req, http.StatusOK, prepareTeamGroupModifyResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewTeamGroupMembershipModify(). + TeamId("team_id"). + GroupId("group_id"). + Role("Changed role"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertTeamGroupModifyResponse(t, response) } func prepareTeamGroupModifyResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "Group membership has been updated" }`, - ) + ) } func assertTeamGroupModifyRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "role", request, "Changed role") + assertKey(t, "role", request, "Changed role") } -func assertTeamGroupModifyResponse(t *testing.T, response fivetran.TeamGroupMembershipModifyResponse) { - assertEqual(t, response.Code, "Success") - assertNotEmpty(t, response.Message) -} \ No newline at end of file +func assertTeamGroupModifyResponse(t *testing.T, response common.CommonResponse) { + assertEqual(t, response.Code, "Success") + assertNotEmpty(t, response.Message) +} diff --git a/tests/team_user_delete_mock_tests.go b/tests/team_user_delete_mock_tests.go index 30060999..9ebde18a 100644 --- a/tests/team_user_delete_mock_tests.go +++ b/tests/team_user_delete_mock_tests.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -68,7 +68,7 @@ func TestTeamUserDeleteServiceDoMissingConnectorId(t *testing.T) { assertEqual(t, err, expectedError) } -func assertTeamUserDeleteResponse(t *testing.T, response fivetran.TeamUserMembershipDeleteResponse, code string, massage string) { +func assertTeamUserDeleteResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/team_user_modify_mock_test.go b/tests/team_user_modify_mock_test.go index e98c10ea..ccd78464 100644 --- a/tests/team_user_modify_mock_test.go +++ b/tests/team_user_modify_mock_test.go @@ -1,62 +1,62 @@ package tests import ( - "context" - "fmt" - "net/http" - "testing" + "context" + "fmt" + "net/http" + "testing" - "github.com/fivetran/go-fivetran" - "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/common" + "github.com/fivetran/go-fivetran/tests/mock" ) func TestNewTeamUserModify(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPatch, "/v1/teams/team_id/users/user_id").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertTeamUserModifyRequest(t, body) - response := mock.NewResponse(req, http.StatusOK, prepareTeamUserModifyResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewTeamUserMembershipModify(). - TeamId("team_id"). - UserId("user_id"). - Role("Changed role"). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertTeamUserModifyResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPatch, "/v1/teams/team_id/users/user_id").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertTeamUserModifyRequest(t, body) + response := mock.NewResponse(req, http.StatusOK, prepareTeamUserModifyResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewTeamUserMembershipModify(). + TeamId("team_id"). + UserId("user_id"). + Role("Changed role"). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertTeamUserModifyResponse(t, response) } func prepareTeamUserModifyResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "User role has been updated" }`, - ) + ) } func assertTeamUserModifyRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "role", request, "Changed role") + assertKey(t, "role", request, "Changed role") } -func assertTeamUserModifyResponse(t *testing.T, response fivetran.TeamUserMembershipModifyResponse) { - assertEqual(t, response.Code, "Success") - assertNotEmpty(t, response.Message) -} \ No newline at end of file +func assertTeamUserModifyResponse(t *testing.T, response common.CommonResponse) { + assertEqual(t, response.Code, "Success") + assertNotEmpty(t, response.Message) +} diff --git a/tests/teams_delete_mock_test.go b/tests/teams_delete_mock_test.go index 2c97285a..058a71d7 100644 --- a/tests/teams_delete_mock_test.go +++ b/tests/teams_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -54,7 +54,7 @@ func TestTeamDeleteServiceDoMissingId(t *testing.T) { assertEqual(t, err, expectedError) } -func assertTeamDeleteResponse(t *testing.T, response fivetran.TeamsDeleteResponse, code string, massage string) { +func assertTeamDeleteResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/teams_list_mock_test.go b/tests/teams_list_mock_test.go index 56c3aec6..97bef184 100644 --- a/tests/teams_list_mock_test.go +++ b/tests/teams_list_mock_test.go @@ -68,4 +68,4 @@ func assertTeamListResponse(t *testing.T, response fivetran.TeamsListResponse) { assertEqual(t, response.Data.Items[1].Name, "Finance Team") assertEqual(t, response.Data.Items[1].Description, "Finance Team description") assertEqual(t, response.Data.Items[1].Role, "Account Reviewer") -} \ No newline at end of file +} diff --git a/tests/user_delete_mock_test.go b/tests/user_delete_mock_test.go index e0efaaff..f96fe660 100644 --- a/tests/user_delete_mock_test.go +++ b/tests/user_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -57,7 +57,7 @@ func prepareUserDeleteResponse() string { return fmt.Sprintf(`{"code": "%s", "message": "User has been deleted"}`, EXPECTED_USER_DELETE_RESPONSE_CODE) } -func assertUserDeleteResponse(t *testing.T, actual fivetran.UserDeleteResponse, code string, message string) { +func assertUserDeleteResponse(t *testing.T, actual common.CommonResponse, code string, message string) { assertEqual(t, actual.Code, code) assertEqual(t, actual.Message, message) } diff --git a/tests/user_details_mock_test.go b/tests/user_details_mock_test.go index b8576e5a..604515f5 100644 --- a/tests/user_details_mock_test.go +++ b/tests/user_details_mock_test.go @@ -7,8 +7,9 @@ import ( "testing" "time" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/users" ) const ( @@ -98,12 +99,14 @@ func prepareUserDetailsResponse() string { true) } -func prepareExpectedUserDetailsResponse() fivetran.UserDetailsResponse { +func prepareExpectedUserDetailsResponse() users.UserDetailsResponse { var flag = true - return fivetran.UserDetailsResponse{ - Code: EXPECTED_USER_RESPONSE_CODE, - Message: "", - Data: fivetran.UserDetailsData{ + return users.UserDetailsResponse{ + CommonResponse: common.CommonResponse{ + Code: EXPECTED_USER_RESPONSE_CODE, + Message: "", + }, + Data: users.UserDetailsData{ ID: EXPECTED_USER_ID, Email: EXPECTED_USER_EMAIL, GivenName: EXPECTED_USER_GIVEN_NAME, @@ -120,8 +123,8 @@ func prepareExpectedUserDetailsResponse() fivetran.UserDetailsResponse { } func assertUserDetailsResponse(t *testing.T, - actual fivetran.UserDetailsResponse, - expected fivetran.UserDetailsResponse, + actual users.UserDetailsResponse, + expected users.UserDetailsResponse, code string, massage string) { assertEqual(t, actual.Code, code) diff --git a/tests/user_invite_mock_test.go b/tests/user_invite_mock_test.go index 0fa3b10a..e25c777e 100644 --- a/tests/user_invite_mock_test.go +++ b/tests/user_invite_mock_test.go @@ -6,8 +6,9 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/users" ) const ( @@ -82,12 +83,14 @@ func prepareUserModifyResponse() string { EXPECTED_USER_MODIFY_ROLE) } -func prepareExpectedUserModifyResponse() fivetran.UserModifyResponse { +func prepareExpectedUserModifyResponse() users.UserDetailsResponse { var verifyFlag = false - return fivetran.UserModifyResponse{ - Code: EXPECTED_USER_MODIFY_RESPONSE_CODE, - Message: "User has been invited to the account", - Data: fivetran.UserModifyData{ + return users.UserDetailsResponse{ + CommonResponse: common.CommonResponse{ + Code: EXPECTED_USER_MODIFY_RESPONSE_CODE, + Message: "User has been invited to the account", + }, + Data: users.UserDetailsData{ ID: EXPECTED_USER_MODIFY_USER_ID, Email: EXPECTED_USER_MODIFY_EMAIL, GivenName: EXPECTED_USER_MODIFY_GIVEN_NAME, @@ -101,7 +104,7 @@ func prepareExpectedUserModifyResponse() fivetran.UserModifyResponse { } } -func assertUserModifyResponse(t *testing.T, actual, expected fivetran.UserModifyResponse) { +func assertUserModifyResponse(t *testing.T, actual, expected users.UserDetailsResponse) { assertEqual(t, actual.Code, expected.Code) assertEqual(t, actual.Message, expected.Message) assertEqual(t, actual.Data.ID, expected.Data.ID) diff --git a/tests/user_list_mock_test.go b/tests/user_list_mock_test.go index 5b66115f..8fdc9cf0 100644 --- a/tests/user_list_mock_test.go +++ b/tests/user_list_mock_test.go @@ -6,8 +6,9 @@ import ( "testing" "time" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/users" ) func TestUsersListServiceDo(t *testing.T) { @@ -65,65 +66,37 @@ func TestUsersListServiceDo(t *testing.T) { } flag := true - expectedResponse := fivetran.UsersListResponse{ + expectedResponse := users.UsersListResponse{} + expectedResponse.Data.NextCursor = "eyJza2lwIjoyfQ" + expectedResponse.CommonResponse = common.CommonResponse{ Code: "Success", - Data: struct { - Items []struct { - ID string `json:"id"` - Email string `json:"email"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Verified *bool `json:"verified"` - Invited *bool `json:"invited"` - Picture string `json:"picture"` - Phone string `json:"phone"` - Role string `json:"role"` - LoggedInAt time.Time `json:"logged_in_at"` - CreatedAt time.Time `json:"created_at"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - }{ - Items: []struct { - ID string `json:"id"` - Email string `json:"email"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Verified *bool `json:"verified"` - Invited *bool `json:"invited"` - Picture string `json:"picture"` - Phone string `json:"phone"` - Role string `json:"role"` - LoggedInAt time.Time `json:"logged_in_at"` - CreatedAt time.Time `json:"created_at"` - }{ - { - ID: "nozzle_eat", - Email: "john@mycompany.com", - GivenName: "John", - FamilyName: "White", - Verified: &flag, - Invited: &flag, - Picture: "", - Phone: "", - Role: "Account Administrator", - LoggedInAt: parseTime("2019-01-03T08:44:45.369Z"), - CreatedAt: parseTime("2018-01-15T11:00:27.329220Z"), - }, - { - ID: "prophecies_falsely", - Email: "robert@mycompany.com", - GivenName: "Robert", - FamilyName: "Brown", - Verified: &flag, - Invited: &flag, - Picture: "", - Phone: "", - Role: "", - LoggedInAt: parseTime("2018-12-12T12:06:15.337Z"), - CreatedAt: parseTime("2018-01-24T20:43:32.963843Z"), - }, - }, - NextCursor: "eyJza2lwIjoyfQ", + } + expectedResponse.Data.Items = []users.UserDetailsData{ + { + ID: "nozzle_eat", + Email: "john@mycompany.com", + GivenName: "John", + FamilyName: "White", + Verified: &flag, + Invited: &flag, + Picture: "", + Phone: "", + Role: "Account Administrator", + LoggedInAt: parseTime("2019-01-03T08:44:45.369Z"), + CreatedAt: parseTime("2018-01-15T11:00:27.329220Z"), + }, + { + ID: "prophecies_falsely", + Email: "robert@mycompany.com", + GivenName: "Robert", + FamilyName: "Brown", + Verified: &flag, + Invited: &flag, + Picture: "", + Phone: "", + Role: "", + LoggedInAt: parseTime("2018-12-12T12:06:15.337Z"), + CreatedAt: parseTime("2018-01-24T20:43:32.963843Z"), }, } @@ -136,7 +109,7 @@ func TestUsersListServiceDo(t *testing.T) { } -func assertUsersListResponse(t *testing.T, response fivetran.UsersListResponse, expected fivetran.UsersListResponse) { +func assertUsersListResponse(t *testing.T, response, expected users.UsersListResponse) { assertEqual(t, response.Code, expected.Code) assertEqual(t, response.Data.NextCursor, expected.Data.NextCursor) diff --git a/tests/webhook_create_mock_test.go b/tests/webhook_create_mock_test.go index 220a652d..b2bd6f05 100644 --- a/tests/webhook_create_mock_test.go +++ b/tests/webhook_create_mock_test.go @@ -1,94 +1,94 @@ package tests import ( - "context" - "fmt" - "net/http" - "testing" + "context" + "fmt" + "net/http" + "testing" - "github.com/fivetran/go-fivetran" - "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/webhooks" ) const ( - WEBHOOK_URL = "https://localhost:12345" - WEBHOOK_EVENT = "sync_start" - WEBHOOK_ACTIVE = false - WEBHOOK_SECRET = "my_secret" - WEBHOOK_GROUP = "test_group" + WEBHOOK_URL = "https://localhost:12345" + WEBHOOK_EVENT = "sync_start" + WEBHOOK_ACTIVE = false + WEBHOOK_SECRET = "my_secret" + WEBHOOK_GROUP = "test_group" ) func TestNewWebhookAccountCreate(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPost, "/v1/webhooks/account").ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertWebhookAccountRequest(t, body) - response := mock.NewResponse(req, http.StatusOK, prepareWebhookAccountResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewWebhookAccountCreate(). - Url(WEBHOOK_URL). - Secret(WEBHOOK_SECRET). - Active(WEBHOOK_ACTIVE). - Events([]string{WEBHOOK_EVENT}). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - - assertWebhookAccountResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPost, "/v1/webhooks/account").ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertWebhookAccountRequest(t, body) + response := mock.NewResponse(req, http.StatusOK, prepareWebhookAccountResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewWebhookAccountCreate(). + Url(WEBHOOK_URL). + Secret(WEBHOOK_SECRET). + Active(WEBHOOK_ACTIVE). + Events([]string{WEBHOOK_EVENT}). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + + assertWebhookAccountResponse(t, response) } func TestNewWebhookGroupCreate(t *testing.T) { - // arrange - ftClient, mockClient := CreateTestClient() - handler := mockClient.When(http.MethodPost, "/v1/webhooks/group/" + WEBHOOK_GROUP).ThenCall( - - func(req *http.Request) (*http.Response, error) { - body := requestBodyToJson(t, req) - assertWebhookGroupRequest(t, body) - response := mock.NewResponse(req, http.StatusOK, prepareWebhookGroupResponse()) - return response, nil - }) - - // act - response, err := ftClient.NewWebhookGroupCreate(). - Url(WEBHOOK_URL). - Secret(WEBHOOK_SECRET). - Active(WEBHOOK_ACTIVE). - GroupId(WEBHOOK_GROUP). - Events([]string{WEBHOOK_EVENT}). - Do(context.Background()) - - if err != nil { - t.Logf("%+v\n", response) - t.Error(err) - } - - // assert - interactions := mockClient.Interactions() - assertEqual(t, len(interactions), 1) - assertEqual(t, interactions[0].Handler, handler) - assertEqual(t, handler.Interactions, 1) - assertWebhookGroupResponse(t, response) + // arrange + ftClient, mockClient := CreateTestClient() + handler := mockClient.When(http.MethodPost, "/v1/webhooks/group/"+WEBHOOK_GROUP).ThenCall( + + func(req *http.Request) (*http.Response, error) { + body := requestBodyToJson(t, req) + assertWebhookGroupRequest(t, body) + response := mock.NewResponse(req, http.StatusOK, prepareWebhookGroupResponse()) + return response, nil + }) + + // act + response, err := ftClient.NewWebhookGroupCreate(). + Url(WEBHOOK_URL). + Secret(WEBHOOK_SECRET). + Active(WEBHOOK_ACTIVE). + GroupId(WEBHOOK_GROUP). + Events([]string{WEBHOOK_EVENT}). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", response) + t.Error(err) + } + + // assert + interactions := mockClient.Interactions() + assertEqual(t, len(interactions), 1) + assertEqual(t, interactions[0].Handler, handler) + assertEqual(t, handler.Interactions, 1) + assertWebhookGroupResponse(t, response) } func prepareWebhookGroupResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "Group webhook has been created", "data": { @@ -105,16 +105,16 @@ func prepareWebhookGroupResponse() string { "created_by": "_airworthy" } }`, - WEBHOOK_GROUP, - WEBHOOK_URL, - WEBHOOK_EVENT, - WEBHOOK_ACTIVE, - ) + WEBHOOK_GROUP, + WEBHOOK_URL, + WEBHOOK_EVENT, + WEBHOOK_ACTIVE, + ) } func prepareWebhookAccountResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "Account webhook has been created", "data": { @@ -130,48 +130,48 @@ func prepareWebhookAccountResponse() string { "created_by": "_airworthy" } }`, - WEBHOOK_URL, // id - WEBHOOK_EVENT, - WEBHOOK_ACTIVE, - ) + WEBHOOK_URL, // id + WEBHOOK_EVENT, + WEBHOOK_ACTIVE, + ) } func assertWebhookAccountRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "url", request, WEBHOOK_URL) - assertKey(t, "active", request, WEBHOOK_ACTIVE) + assertKey(t, "url", request, WEBHOOK_URL) + assertKey(t, "active", request, WEBHOOK_ACTIVE) } func assertWebhookGroupRequest(t *testing.T, request map[string]interface{}) { - assertKey(t, "url", request, WEBHOOK_URL) - assertKey(t, "active", request, WEBHOOK_ACTIVE) + assertKey(t, "url", request, WEBHOOK_URL) + assertKey(t, "active", request, WEBHOOK_ACTIVE) } -func assertWebhookAccountResponse(t *testing.T, response fivetran.WebhookAccountCreateResponse) { - assertEqual(t, response.Code, "Success") - assertNotEmpty(t, response.Message) +func assertWebhookAccountResponse(t *testing.T, response webhooks.WebhookResponse) { + assertEqual(t, response.Code, "Success") + assertNotEmpty(t, response.Message) - assertNotEmpty(t, response.Data.Id) - assertNotEmpty(t, response.Data.CreatedAt) - assertNotEmpty(t, response.Data.CreatedBy) + assertNotEmpty(t, response.Data.Id) + assertNotEmpty(t, response.Data.CreatedAt) + assertNotEmpty(t, response.Data.CreatedBy) - assertEqual(t, response.Data.Events, []string{WEBHOOK_EVENT}) - assertEqual(t, response.Data.Url, WEBHOOK_URL) - assertEqual(t, response.Data.Secret, "******") - assertEqual(t, response.Data.Type, "account") + assertEqual(t, response.Data.Events, []string{WEBHOOK_EVENT}) + assertEqual(t, response.Data.Url, WEBHOOK_URL) + assertEqual(t, response.Data.Secret, "******") + assertEqual(t, response.Data.Type, "account") } -func assertWebhookGroupResponse(t *testing.T, response fivetran.WebhookGroupCreateResponse) { - assertEqual(t, response.Code, "Success") - assertNotEmpty(t, response.Message) - - assertNotEmpty(t, response.Data.Id) - assertNotEmpty(t, response.Data.CreatedAt) - assertNotEmpty(t, response.Data.CreatedBy) - - assertEqual(t, response.Data.Url, WEBHOOK_URL) - assertEqual(t, response.Data.Active, WEBHOOK_ACTIVE) - assertEqual(t, response.Data.GroupId, WEBHOOK_GROUP) - assertEqual(t, response.Data.Secret, "******") - assertEqual(t, response.Data.Type, "group") - assertEqual(t, response.Data.Events, []string{WEBHOOK_EVENT}) -} \ No newline at end of file +func assertWebhookGroupResponse(t *testing.T, response webhooks.WebhookResponse) { + assertEqual(t, response.Code, "Success") + assertNotEmpty(t, response.Message) + + assertNotEmpty(t, response.Data.Id) + assertNotEmpty(t, response.Data.CreatedAt) + assertNotEmpty(t, response.Data.CreatedBy) + + assertEqual(t, response.Data.Url, WEBHOOK_URL) + assertEqual(t, response.Data.Active, WEBHOOK_ACTIVE) + assertEqual(t, response.Data.GroupId, WEBHOOK_GROUP) + assertEqual(t, response.Data.Secret, "******") + assertEqual(t, response.Data.Type, "group") + assertEqual(t, response.Data.Events, []string{WEBHOOK_EVENT}) +} diff --git a/tests/webhook_delete_mock_test.go b/tests/webhook_delete_mock_test.go index 27819009..311f5c1c 100644 --- a/tests/webhook_delete_mock_test.go +++ b/tests/webhook_delete_mock_test.go @@ -6,7 +6,7 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" + "github.com/fivetran/go-fivetran/common" "github.com/fivetran/go-fivetran/tests/mock" ) @@ -54,7 +54,7 @@ func TestWebhookDeleteServiceDoMissingId(t *testing.T) { assertEqual(t, err, expectedError) } -func assertWebhookDeleteResponse(t *testing.T, response fivetran.WebhookDeleteResponse, code string, massage string) { +func assertWebhookDeleteResponse(t *testing.T, response common.CommonResponse, code string, massage string) { assertEqual(t, response.Code, code) assertEqual(t, response.Message, massage) } diff --git a/tests/webhook_details_mock_test.go b/tests/webhook_details_mock_test.go index 780c79ea..28da90be 100644 --- a/tests/webhook_details_mock_test.go +++ b/tests/webhook_details_mock_test.go @@ -6,8 +6,8 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/webhooks" ) func TestWebhookDetailsService(t *testing.T) { @@ -39,8 +39,8 @@ func TestWebhookDetailsService(t *testing.T) { } func prepareWebhookDetailsResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "Webhook has been updated", "data": { @@ -57,24 +57,24 @@ func prepareWebhookDetailsResponse() string { "created_by": "_airworthy" } }`, - WEBHOOK_GROUP, - WEBHOOK_URL, - WEBHOOK_EVENT, - WEBHOOK_ACTIVE, - ) + WEBHOOK_GROUP, + WEBHOOK_URL, + WEBHOOK_EVENT, + WEBHOOK_ACTIVE, + ) } -func assertWebhookDetailsResponse(t *testing.T, response fivetran.WebhookDetailsResponse) { - assertEqual(t, response.Code, "Success") +func assertWebhookDetailsResponse(t *testing.T, response webhooks.WebhookResponse) { + assertEqual(t, response.Code, "Success") - assertNotEmpty(t, response.Data.Id) - assertNotEmpty(t, response.Data.CreatedAt) - assertNotEmpty(t, response.Data.CreatedBy) + assertNotEmpty(t, response.Data.Id) + assertNotEmpty(t, response.Data.CreatedAt) + assertNotEmpty(t, response.Data.CreatedBy) - assertEqual(t, response.Data.Url, WEBHOOK_URL) - assertEqual(t, response.Data.Active, WEBHOOK_ACTIVE) - assertEqual(t, response.Data.GroupId, WEBHOOK_GROUP) - assertEqual(t, response.Data.Secret, "******") - assertEqual(t, response.Data.Type, "account") - assertEqual(t, response.Data.Events[0], WEBHOOK_EVENT) + assertEqual(t, response.Data.Url, WEBHOOK_URL) + assertEqual(t, response.Data.Active, WEBHOOK_ACTIVE) + assertEqual(t, response.Data.GroupId, WEBHOOK_GROUP) + assertEqual(t, response.Data.Secret, "******") + assertEqual(t, response.Data.Type, "account") + assertEqual(t, response.Data.Events[0], WEBHOOK_EVENT) } diff --git a/tests/webhook_modify_mock_test.go b/tests/webhook_modify_mock_test.go index 49d2d3f8..2b1295d6 100644 --- a/tests/webhook_modify_mock_test.go +++ b/tests/webhook_modify_mock_test.go @@ -6,8 +6,8 @@ import ( "net/http" "testing" - "github.com/fivetran/go-fivetran" "github.com/fivetran/go-fivetran/tests/mock" + "github.com/fivetran/go-fivetran/webhooks" ) func TestWebhookModifyService(t *testing.T) { @@ -20,11 +20,11 @@ func TestWebhookModifyService(t *testing.T) { }) service := ftClient.NewWebhookModify(). - WebhookId("webhook_id"). - Url(WEBHOOK_URL). - Secret(WEBHOOK_SECRET). - Active(WEBHOOK_ACTIVE). - Events([]string{WEBHOOK_EVENT}) + WebhookId("webhook_id"). + Url(WEBHOOK_URL). + Secret(WEBHOOK_SECRET). + Active(WEBHOOK_ACTIVE). + Events([]string{WEBHOOK_EVENT}) // act response, err := service.Do(context.Background()) @@ -44,8 +44,8 @@ func TestWebhookModifyService(t *testing.T) { } func prepareWebhookModifyResponse() string { - return fmt.Sprintf( - `{ + return fmt.Sprintf( + `{ "code": "Success", "message": "Webhook has been updated", "data": { @@ -62,25 +62,25 @@ func prepareWebhookModifyResponse() string { "created_by": "_airworthy" } }`, - WEBHOOK_GROUP, - WEBHOOK_URL, - WEBHOOK_EVENT, - WEBHOOK_ACTIVE, - ) + WEBHOOK_GROUP, + WEBHOOK_URL, + WEBHOOK_EVENT, + WEBHOOK_ACTIVE, + ) } -func assertWebhookModifyResponse(t *testing.T, response fivetran.WebhookModifyResponse) { - assertEqual(t, response.Code, "Success") - assertNotEmpty(t, response.Message) +func assertWebhookModifyResponse(t *testing.T, response webhooks.WebhookResponse) { + assertEqual(t, response.Code, "Success") + assertNotEmpty(t, response.Message) - assertNotEmpty(t, response.Data.Id) - assertNotEmpty(t, response.Data.CreatedAt) - assertNotEmpty(t, response.Data.CreatedBy) + assertNotEmpty(t, response.Data.Id) + assertNotEmpty(t, response.Data.CreatedAt) + assertNotEmpty(t, response.Data.CreatedBy) - assertEqual(t, response.Data.Url, WEBHOOK_URL) - assertEqual(t, response.Data.Active, WEBHOOK_ACTIVE) - assertEqual(t, response.Data.GroupId, WEBHOOK_GROUP) - assertEqual(t, response.Data.Secret, "******") - assertEqual(t, response.Data.Type, "account") - assertEqual(t, response.Data.Events, []string{WEBHOOK_EVENT}) + assertEqual(t, response.Data.Url, WEBHOOK_URL) + assertEqual(t, response.Data.Active, WEBHOOK_ACTIVE) + assertEqual(t, response.Data.GroupId, WEBHOOK_GROUP) + assertEqual(t, response.Data.Secret, "******") + assertEqual(t, response.Data.Type, "account") + assertEqual(t, response.Data.Events, []string{WEBHOOK_EVENT}) } diff --git a/types.go b/types.go deleted file mode 100644 index 1b593efb..00000000 --- a/types.go +++ /dev/null @@ -1,21 +0,0 @@ -package fivetran - -import "encoding/json" - -type nullableString struct { - value *string -} - -func newNullableString(s *string, clear bool) *nullableString { - if s == nil && !clear { - return nil - } - - return &nullableString{ - value: s, - } -} - -func (n *nullableString) MarshalJSON() ([]byte, error) { - return json.Marshal(n.value) -} diff --git a/user_delete.go b/user_delete.go index f2ae3833..eee19656 100644 --- a/user_delete.go +++ b/user_delete.go @@ -4,6 +4,9 @@ import ( "context" "encoding/json" "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // UserDeleteService implements the User Management, Delete a user API. @@ -13,11 +16,6 @@ type UserDeleteService struct { userID *string } -type UserDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` -} - func (c *Client) NewUserDelete() *UserDeleteService { return &UserDeleteService{c: c} } @@ -27,8 +25,8 @@ func (s *UserDeleteService) UserID(value string) *UserDeleteService { return s } -func (s *UserDeleteService) Do(ctx context.Context) (UserDeleteResponse, error) { - var response UserDeleteResponse +func (s *UserDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse if s.userID == nil { return response, fmt.Errorf("missing required UserId") @@ -39,18 +37,18 @@ func (s *UserDeleteService) Do(ctx context.Context) (UserDeleteResponse, error) headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/user_delete_test.go b/user_delete_test.go index 0e194ac1..2892a875 100644 --- a/user_delete_test.go +++ b/user_delete_test.go @@ -4,17 +4,19 @@ import ( "context" "strings" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewUserDeleteE2E(t *testing.T) { - userId := CreateUser(t) - deleted, err := Client.NewUserDelete().UserID(userId).Do(context.Background()) + userId := testutils.CreateUser(t) + deleted, err := testutils.Client.NewUserDelete().UserID(userId).Do(context.Background()) if err != nil { t.Logf("%+v\n", deleted) t.Error(err) } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, userId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, userId), true) } diff --git a/user_details.go b/user_details.go index dd6f1640..dad1fd47 100644 --- a/user_details.go +++ b/user_details.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" - "time" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/users" ) // UserDetailsService implements the User Management, Retrieve user details API. @@ -14,26 +16,6 @@ type UserDetailsService struct { userID *string } -type UserDetailsData struct { - ID string `json:"id"` - Email string `json:"email"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Verified *bool `json:"verified"` - Invited *bool `json:"invited"` - Picture string `json:"picture"` - Phone string `json:"phone"` - LoggedInAt time.Time `json:"logged_in_at"` - CreatedAt time.Time `json:"created_at"` - Role string `json:"role"` -} - -type UserDetailsResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data UserDetailsData `json:"data"` -} - func (c *Client) NewUserDetails() *UserDetailsService { return &UserDetailsService{c: c} } @@ -43,8 +25,8 @@ func (s *UserDetailsService) UserID(value string) *UserDetailsService { return s } -func (s *UserDetailsService) Do(ctx context.Context) (UserDetailsResponse, error) { - var response UserDetailsResponse +func (s *UserDetailsService) Do(ctx context.Context) (users.UserDetailsResponse, error) { + var response users.UserDetailsResponse if s.userID == nil { return response, fmt.Errorf("missing required UserId") @@ -55,18 +37,18 @@ func (s *UserDetailsService) Do(ctx context.Context) (UserDetailsResponse, error headers := s.c.commonHeaders() - r := request{ - method: "GET", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/user_details_test.go b/user_details_test.go index e7c73d0d..4f70ea50 100644 --- a/user_details_test.go +++ b/user_details_test.go @@ -3,25 +3,27 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewUserDetailsE2E(t *testing.T) { - user, err := Client.NewUserDetails().UserID(PredefinedUserId).Do(context.Background()) + user, err := testutils.Client.NewUserDetails().UserID(testutils.PredefinedUserId).Do(context.Background()) if err != nil { t.Logf("%+v\n", user) t.Error(err) } - AssertEqual(t, user.Code, "Success") - AssertEqual(t, user.Data.ID, PredefinedUserId) - AssertEqual(t, user.Data.Email, PredefinedUserEmail) - AssertEqual(t, user.Data.GivenName, PredefinedUserGivenName) - AssertEqual(t, user.Data.FamilyName, PredefinedUserFamilyName) - AssertEqual(t, *user.Data.Verified, true) - AssertEqual(t, *user.Data.Invited, false) - AssertEmpty(t, user.Data.Picture) - AssertEqual(t, user.Data.Phone, PredefinedUserPhone) - AssertEqual(t, user.Data.Role, "Account Administrator") - AssertEqual(t, user.Data.LoggedInAt.IsZero(), false) - AssertEqual(t, user.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, user.Code, "Success") + testutils.AssertEqual(t, user.Data.ID, testutils.PredefinedUserId) + testutils.AssertEqual(t, user.Data.Email, testutils.PredefinedUserEmail) + testutils.AssertEqual(t, user.Data.GivenName, testutils.PredefinedUserGivenName) + testutils.AssertEqual(t, user.Data.FamilyName, testutils.PredefinedUserFamilyName) + testutils.AssertEqual(t, *user.Data.Verified, true) + testutils.AssertEqual(t, *user.Data.Invited, false) + testutils.AssertEmpty(t, user.Data.Picture) + testutils.AssertEqual(t, user.Data.Phone, testutils.PredefinedUserPhone) + testutils.AssertEqual(t, user.Data.Role, "Account Administrator") + testutils.AssertEqual(t, user.Data.LoggedInAt.IsZero(), false) + testutils.AssertEqual(t, user.Data.CreatedAt.IsZero(), false) } diff --git a/user_invite.go b/user_invite.go index 8cd27b67..70668b45 100644 --- a/user_invite.go +++ b/user_invite.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" - "time" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/users" ) // UserInviteService implements the User Management, Invite a User API. @@ -28,24 +30,6 @@ type userInviteRequest struct { Role *string `json:"role,omitempty"` } -type UserInviteResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - ID string `json:"id"` - Email string `json:"email"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Verified *bool `json:"verified"` - Invited *bool `json:"invited"` - Picture string `json:"picture"` - Phone string `json:"phone"` - LoggedInAt time.Time `json:"logged_in_at"` - CreatedAt time.Time `json:"created_at"` - Role string `json:"role"` - } `json:"data"` -} - func (c *Client) NewUserInvite() *UserInviteService { return &UserInviteService{c: c} } @@ -91,8 +75,8 @@ func (s *UserInviteService) Role(value string) *UserInviteService { return s } -func (s *UserInviteService) Do(ctx context.Context) (UserInviteResponse, error) { - var response UserInviteResponse +func (s *UserInviteService) Do(ctx context.Context) (users.UserDetailsResponse, error) { + var response users.UserDetailsResponse url := fmt.Sprintf("%v/users", s.c.baseURL) expectedStatus := 201 @@ -104,18 +88,18 @@ func (s *UserInviteService) Do(ctx context.Context) (UserInviteResponse, error) return response, err } - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/user_invite_test.go b/user_invite_test.go index 6cb066dd..3caa4f96 100644 --- a/user_invite_test.go +++ b/user_invite_test.go @@ -3,10 +3,12 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewUserInviteE2E(t *testing.T) { - user, err := Client.NewUserInvite(). + user, err := testutils.Client.NewUserInvite(). Email("william_addison.@fivetran.com"). GivenName("William"). FamilyName("Addison"). @@ -20,17 +22,17 @@ func TestNewUserInviteE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, user.Code, "Success") - AssertNotEmpty(t, user.Message) - AssertNotEmpty(t, user.Data.ID) - AssertEqual(t, user.Data.Email, "william_addison.@fivetran.com") - AssertEqual(t, user.Data.GivenName, "William") - AssertEqual(t, user.Data.FamilyName, "Addison") - AssertEqual(t, *user.Data.Verified, false) - AssertEqual(t, *user.Data.Invited, true) - AssertEqual(t, user.Data.Picture, "http://picture.com") - AssertEqual(t, user.Data.Phone, "+19876543210") - AssertEqual(t, user.Data.LoggedInAt.IsZero(), true) - AssertEqual(t, user.Data.CreatedAt.IsZero(), false) - t.Cleanup(func() { DeleteUser(t, user.Data.ID) }) + testutils.AssertEqual(t, user.Code, "Success") + testutils.AssertNotEmpty(t, user.Message) + testutils.AssertNotEmpty(t, user.Data.ID) + testutils.AssertEqual(t, user.Data.Email, "william_addison.@fivetran.com") + testutils.AssertEqual(t, user.Data.GivenName, "William") + testutils.AssertEqual(t, user.Data.FamilyName, "Addison") + testutils.AssertEqual(t, *user.Data.Verified, false) + testutils.AssertEqual(t, *user.Data.Invited, true) + testutils.AssertEqual(t, user.Data.Picture, "http://picture.com") + testutils.AssertEqual(t, user.Data.Phone, "+19876543210") + testutils.AssertEqual(t, user.Data.LoggedInAt.IsZero(), true) + testutils.AssertEqual(t, user.Data.CreatedAt.IsZero(), false) + t.Cleanup(func() { testutils.DeleteUser(t, user.Data.ID) }) } diff --git a/user_modify.go b/user_modify.go index da8037b7..c089b208 100644 --- a/user_modify.go +++ b/user_modify.go @@ -5,7 +5,10 @@ import ( "encoding/json" "errors" "fmt" - "time" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/users" ) // UserModifyService implements the User Management, Modify a User API. @@ -23,31 +26,11 @@ type UserModifyService struct { } type userModifyRequest struct { - GivenName *string `json:"given_name,omitempty"` - FamilyName *string `json:"family_name,omitempty"` - Phone *nullableString `json:"phone,omitempty"` - Picture *nullableString `json:"picture,omitempty"` - Role *string `json:"role,omitempty"` -} - -type UserModifyData struct { - ID string `json:"id"` - Email string `json:"email"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Verified *bool `json:"verified"` - Invited *bool `json:"invited"` - Picture string `json:"picture"` - Phone string `json:"phone"` - LoggedInAt time.Time `json:"logged_in_at"` - CreatedAt time.Time `json:"created_at"` - Role string `json:"role"` -} - -type UserModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data UserModifyData `json:"data"` + GivenName *string `json:"given_name,omitempty"` + FamilyName *string `json:"family_name,omitempty"` + Phone *common.NullableString `json:"phone,omitempty"` + Picture *common.NullableString `json:"picture,omitempty"` + Role *string `json:"role,omitempty"` } func (c *Client) NewUserModify() *UserModifyService { @@ -55,13 +38,15 @@ func (c *Client) NewUserModify() *UserModifyService { } func (s *UserModifyService) request() *userModifyRequest { - return &userModifyRequest{ + result := userModifyRequest{ GivenName: s.givenName, FamilyName: s.familyName, - Phone: newNullableString(s.phone, s.clearPhone), - Picture: newNullableString(s.picture, s.clearPicture), + Phone: common.NewNullableString(s.phone, s.clearPhone), + Picture: common.NewNullableString(s.picture, s.clearPicture), Role: s.role, } + + return &result } func (s *UserModifyService) UserID(value string) *UserModifyService { @@ -104,8 +89,8 @@ func (s *UserModifyService) Role(value string) *UserModifyService { return s } -func (s *UserModifyService) Do(ctx context.Context) (UserModifyResponse, error) { - var response UserModifyResponse +func (s *UserModifyService) Do(ctx context.Context) (users.UserDetailsResponse, error) { + var response users.UserDetailsResponse if s.userID == nil { return response, fmt.Errorf("missing required UserID") @@ -129,18 +114,18 @@ func (s *UserModifyService) Do(ctx context.Context) (UserModifyResponse, error) headers := s.c.commonHeaders() headers["Content-Type"] = "application/json" - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/user_modify_test.go b/user_modify_test.go index d6bd5587..7a0775f1 100644 --- a/user_modify_test.go +++ b/user_modify_test.go @@ -3,11 +3,13 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewUserModifyE2E(t *testing.T) { - userId := CreateTempUser(t) - user, err := Client.NewUserModify(). + userId := testutils.CreateTempUser(t) + user, err := testutils.Client.NewUserModify(). UserID(userId). FamilyName("Gerrard"). GivenName("Steven"). @@ -21,17 +23,17 @@ func TestNewUserModifyE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, user.Code, "Success") - AssertNotEmpty(t, user.Message) - AssertEqual(t, user.Data.ID, userId) - AssertEqual(t, user.Data.Email, "william_addison.@fivetran.com") - AssertEqual(t, user.Data.GivenName, "Steven") - AssertEqual(t, user.Data.FamilyName, "Gerrard") - AssertEqual(t, *user.Data.Verified, false) - AssertEqual(t, *user.Data.Invited, true) - AssertEqual(t, user.Data.Phone, "+19876543210") - AssertEqual(t, user.Data.Picture, "http://picture.com") - //todo: incomment when role field will be mapped then.AssertThat(t, user.Data.Role, is.EqualTo("Owner")) - AssertEqual(t, user.Data.LoggedInAt.IsZero(), true) - AssertEqual(t, user.Data.CreatedAt.IsZero(), false) + testutils.AssertEqual(t, user.Code, "Success") + testutils.AssertNotEmpty(t, user.Message) + testutils.AssertEqual(t, user.Data.ID, userId) + testutils.AssertEqual(t, user.Data.Email, "william_addison.@fivetran.com") + testutils.AssertEqual(t, user.Data.GivenName, "Steven") + testutils.AssertEqual(t, user.Data.FamilyName, "Gerrard") + testutils.AssertEqual(t, *user.Data.Verified, false) + testutils.AssertEqual(t, *user.Data.Invited, true) + testutils.AssertEqual(t, user.Data.Phone, "+19876543210") + testutils.AssertEqual(t, user.Data.Picture, "http://picture.com") + //todo: incomment when role field will be mapped then.testutils.AssertThat(t, user.Data.Role, is.EqualTo("Owner")) + testutils.AssertEqual(t, user.Data.LoggedInAt.IsZero(), true) + testutils.AssertEqual(t, user.Data.CreatedAt.IsZero(), false) } diff --git a/users/common_types.go b/users/common_types.go new file mode 100644 index 00000000..8a0ea307 --- /dev/null +++ b/users/common_types.go @@ -0,0 +1,35 @@ +package users + +import ( + "time" + + "github.com/fivetran/go-fivetran/common" +) + +type UserDetailsData struct { + ID string `json:"id"` + Email string `json:"email"` + GivenName string `json:"given_name"` + FamilyName string `json:"family_name"` + Verified *bool `json:"verified"` + Invited *bool `json:"invited"` + Picture string `json:"picture"` + Phone string `json:"phone"` + LoggedInAt time.Time `json:"logged_in_at"` + CreatedAt time.Time `json:"created_at"` + Role string `json:"role"` + Active *bool `json:"active"` +} + +type UserDetailsResponse struct { + common.CommonResponse + Data UserDetailsData `json:"data"` +} + +type UsersListResponse struct { + common.CommonResponse + Data struct { + Items []UserDetailsData `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` +} diff --git a/users_list.go b/users_list.go index 999c5a43..913077db 100644 --- a/users_list.go +++ b/users_list.go @@ -4,7 +4,9 @@ import ( "context" "encoding/json" "fmt" - "time" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/users" ) // UsersListService implements the User Management, List All Users API. @@ -15,27 +17,6 @@ type UsersListService struct { cursor *string } -type UsersListResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Items []struct { - ID string `json:"id"` - Email string `json:"email"` - GivenName string `json:"given_name"` - FamilyName string `json:"family_name"` - Verified *bool `json:"verified"` - Invited *bool `json:"invited"` - Picture string `json:"picture"` - Phone string `json:"phone"` - Role string `json:"role"` - LoggedInAt time.Time `json:"logged_in_at"` - CreatedAt time.Time `json:"created_at"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` -} - func (c *Client) NewUsersList() *UsersListService { return &UsersListService{c: c} } @@ -50,8 +31,8 @@ func (s *UsersListService) Cursor(value string) *UsersListService { return s } -func (s *UsersListService) Do(ctx context.Context) (UsersListResponse, error) { - var response UsersListResponse +func (s *UsersListService) Do(ctx context.Context) (users.UsersListResponse, error) { + var response users.UsersListResponse url := fmt.Sprintf("%v/users", s.c.baseURL) expectedStatus := 200 @@ -65,18 +46,18 @@ func (s *UsersListService) Do(ctx context.Context) (UsersListResponse, error) { queries["limit"] = fmt.Sprint(*s.limit) } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/users_list_test.go b/users_list_test.go index df923a44..0c718185 100644 --- a/users_list_test.go +++ b/users_list_test.go @@ -3,27 +3,29 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewUsersListE2E(t *testing.T) { - users, err := Client.NewUsersList().Do(context.Background()) + users, err := testutils.Client.NewUsersList().Do(context.Background()) if err != nil { t.Logf("%+v\n", users) t.Error(err) } - AssertEqual(t, users.Code, "Success") - AssertHasLength(t, users.Data.Items, 1) - AssertEqual(t, users.Data.Items[0].ID, PredefinedUserId) - AssertEqual(t, users.Data.Items[0].Email, PredefinedUserEmail) - AssertEqual(t, users.Data.Items[0].GivenName, PredefinedUserGivenName) - AssertEqual(t, users.Data.Items[0].FamilyName, PredefinedUserFamilyName) - AssertEqual(t, *users.Data.Items[0].Verified, true) - AssertEqual(t, *users.Data.Items[0].Invited, false) - AssertEmpty(t, users.Data.Items[0].Picture) - AssertEqual(t, users.Data.Items[0].Phone, PredefinedUserPhone) - AssertEqual(t, users.Data.Items[0].Role, "Account Administrator") - AssertEqual(t, users.Data.Items[0].LoggedInAt.IsZero(), false) - AssertEqual(t, users.Data.Items[0].CreatedAt.IsZero(), false) - AssertEmpty(t, users.Data.NextCursor) + testutils.AssertEqual(t, users.Code, "Success") + testutils.AssertHasLength(t, users.Data.Items, 1) + testutils.AssertEqual(t, users.Data.Items[0].ID, testutils.PredefinedUserId) + testutils.AssertEqual(t, users.Data.Items[0].Email, testutils.PredefinedUserEmail) + testutils.AssertEqual(t, users.Data.Items[0].GivenName, testutils.PredefinedUserGivenName) + testutils.AssertEqual(t, users.Data.Items[0].FamilyName, testutils.PredefinedUserFamilyName) + testutils.AssertEqual(t, *users.Data.Items[0].Verified, true) + testutils.AssertEqual(t, *users.Data.Items[0].Invited, false) + testutils.AssertEmpty(t, users.Data.Items[0].Picture) + testutils.AssertEqual(t, users.Data.Items[0].Phone, testutils.PredefinedUserPhone) + testutils.AssertEqual(t, users.Data.Items[0].Role, "Account Administrator") + testutils.AssertEqual(t, users.Data.Items[0].LoggedInAt.IsZero(), false) + testutils.AssertEqual(t, users.Data.Items[0].CreatedAt.IsZero(), false) + testutils.AssertEmpty(t, users.Data.NextCursor) } diff --git a/helpers.go b/utils/helpers.go similarity index 98% rename from helpers.go rename to utils/helpers.go index e5eba0ec..764a31d5 100644 --- a/helpers.go +++ b/utils/helpers.go @@ -1,4 +1,4 @@ -package fivetran +package utils import "encoding/json" diff --git a/webhook_account_create.go b/webhook_account_create.go index b4ada528..674a81c5 100644 --- a/webhook_account_create.go +++ b/webhook_account_create.go @@ -1,113 +1,102 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/webhooks" ) // WebhookAccountCreateService implements the Webhook Management, Create a Account Webhook. // Ref. https://fivetran.com/docs/rest-api/webhooks#createaccountwebhook type WebhookAccountCreateService struct { - c *Client - url *string - events *[]string - active *bool - secret *string + c *Client + url *string + events *[]string + active *bool + secret *string } type webhookAccountCreateRequest struct { - Url *string `json:"url,omitempty"` - Events *[]string `json:"events,omitempty"` - Active *bool `json:"active,omitempty"` - Secret *string `json:"secret,omitempty"` -} - - -type WebhookAccountCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Id string `json:"id"` - Type string `json:"type"` - Url string `json:"url"` - Events []string `json:"events"` - Active bool `json:"active"` - Secret string `json:"secret"` - CreatedAt string `json:"created_at"` - CreatedBy string `json:"created_by"` - } `json:"data"` + Url *string `json:"url,omitempty"` + Events *[]string `json:"events,omitempty"` + Active *bool `json:"active,omitempty"` + Secret *string `json:"secret,omitempty"` } func (c *Client) NewWebhookAccountCreate() *WebhookAccountCreateService { - return &WebhookAccountCreateService{c: c} + return &WebhookAccountCreateService{c: c} } func (s *WebhookAccountCreateService) request() *webhookAccountCreateRequest { - return &webhookAccountCreateRequest{ - Url: s.url, - Events: s.events, - Active: s.active, - Secret: s.secret, - } + return &webhookAccountCreateRequest{ + Url: s.url, + Events: s.events, + Active: s.active, + Secret: s.secret, + } } func (s *WebhookAccountCreateService) Url(value string) *WebhookAccountCreateService { - s.url = &value - return s + s.url = &value + return s } func (s *WebhookAccountCreateService) Secret(value string) *WebhookAccountCreateService { - s.secret = &value - return s + s.secret = &value + return s } func (s *WebhookAccountCreateService) Active(value bool) *WebhookAccountCreateService { - s.active = &value - return s + s.active = &value + return s } func (s *WebhookAccountCreateService) Events(value []string) *WebhookAccountCreateService { - s.events = &value - return s + s.events = &value + return s } -func (s *WebhookAccountCreateService) Do(ctx context.Context) (WebhookAccountCreateResponse, error) { - var response WebhookAccountCreateResponse - url := fmt.Sprintf("%v/webhooks/account", s.c.baseURL) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil +func (s *WebhookAccountCreateService) Do(ctx context.Context) (webhooks.WebhookResponse, error) { + var response webhooks.WebhookResponse + url := fmt.Sprintf("%v/webhooks/account", s.c.baseURL) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/webhook_account_create_test.go b/webhook_account_create_test.go index e0858a23..829df075 100644 --- a/webhook_account_create_test.go +++ b/webhook_account_create_test.go @@ -1,34 +1,36 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewWebhookAccountCreateE2E(t *testing.T) { - created, err := Client.NewWebhookAccountCreate(). - Url("https://localhost:12345"). - Secret("my_secret"). - Active(false). - Events([]string{"sync_start","sync_end"}). - Do(context.Background()) + created, err := testutils.Client.NewWebhookAccountCreate(). + Url("https://localhost:12345"). + Secret("my_secret"). + Active(false). + Events([]string{"sync_start", "sync_end"}). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertNotEmpty(t, created.Data.Id) + testutils.AssertNotEmpty(t, created.Data.Events) + testutils.AssertNotEmpty(t, created.Data.CreatedAt) + testutils.AssertNotEmpty(t, created.Data.CreatedBy) + testutils.AssertEqual(t, created.Data.Type, "account") + testutils.AssertEqual(t, created.Data.Active, false) + testutils.AssertEqual(t, created.Data.Secret, "******") + testutils.AssertEqual(t, created.Data.Url, "https://localhost:12345") + testutils.AssertEqual(t, created.Data.Events, []string{"sync_start", "sync_end"}) - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertNotEmpty(t, created.Data.Id) - AssertNotEmpty(t, created.Data.Events) - AssertNotEmpty(t, created.Data.CreatedAt) - AssertNotEmpty(t, created.Data.CreatedBy) - AssertEqual(t, created.Data.Type, "account") - AssertEqual(t, created.Data.Active, false) - AssertEqual(t, created.Data.Secret, "******") - AssertEqual(t, created.Data.Url, "https://localhost:12345") - AssertEqual(t, created.Data.Events, []string{"sync_start","sync_end"}) - - t.Cleanup(func() { DeleteWebhook(t, created.Data.Id) }) + t.Cleanup(func() { testutils.DeleteWebhook(t, created.Data.Id) }) } diff --git a/webhook_delete.go b/webhook_delete.go index bd5897fa..f5e79aec 100644 --- a/webhook_delete.go +++ b/webhook_delete.go @@ -1,66 +1,66 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + "github.com/fivetran/go-fivetran/common" + httputils "github.com/fivetran/go-fivetran/http_utils" ) // WebhookDeleteService implements the Webhook Management, Delete a Webhook. // Ref. https://fivetran.com/docs/rest-api/webhooks#deletewebhook type WebhookDeleteService struct { - c *Client - webhookId *string -} - -type WebhookDeleteResponse struct { - Code string `json:"code"` - Message string `json:"message"` + c *Client + webhookId *string } func (c *Client) NewWebhookDelete() *WebhookDeleteService { - return &WebhookDeleteService{c: c} + return &WebhookDeleteService{c: c} } func (s *WebhookDeleteService) WebhookId(value string) *WebhookDeleteService { - s.webhookId = &value - return s + s.webhookId = &value + return s } -func (s *WebhookDeleteService) Do(ctx context.Context) (WebhookDeleteResponse, error) { - var response WebhookDeleteResponse +func (s *WebhookDeleteService) Do(ctx context.Context) (common.CommonResponse, error) { + var response common.CommonResponse - if s.webhookId == nil { - return response, fmt.Errorf("missing required WebhookId") - } + if s.webhookId == nil { + return response, fmt.Errorf("missing required WebhookId") + } - url := fmt.Sprintf("%v/webhooks/%v", s.c.baseURL, *s.webhookId) - expectedStatus := 200 + url := fmt.Sprintf("%v/webhooks/%v", s.c.baseURL, *s.webhookId) + expectedStatus := 200 - headers := s.c.commonHeaders() + headers := s.c.commonHeaders() - r := request{ - method: "DELETE", - url: url, - body: nil, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "DELETE", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/webhook_delete_test.go b/webhook_delete_test.go index c7a09888..b5e55b4f 100644 --- a/webhook_delete_test.go +++ b/webhook_delete_test.go @@ -1,22 +1,24 @@ package fivetran_test import ( - "context" - "strings" - "testing" + "context" + "strings" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewWebhookDeleteE2E(t *testing.T) { - webhookId := CreateWebhookAccount(t) + webhookId := testutils.CreateWebhookAccount(t) - deleted, err := Client.NewWebhookDelete().WebhookId(webhookId).Do(context.Background()) + deleted, err := testutils.Client.NewWebhookDelete().WebhookId(webhookId).Do(context.Background()) - if err != nil { - t.Logf("%+v\n", deleted) - t.Error(err) - } + if err != nil { + t.Logf("%+v\n", deleted) + t.Error(err) + } - AssertEqual(t, deleted.Code, "Success") - AssertNotEmpty(t, deleted.Message) - AssertEqual(t, strings.Contains(deleted.Message, webhookId), true) + testutils.AssertEqual(t, deleted.Code, "Success") + testutils.AssertNotEmpty(t, deleted.Message) + testutils.AssertEqual(t, strings.Contains(deleted.Message, webhookId), true) } diff --git a/webhook_details.go b/webhook_details.go index c7ad4248..c93e3117 100644 --- a/webhook_details.go +++ b/webhook_details.go @@ -1,77 +1,68 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/webhooks" ) // WebhookDetailsService implements the Webhook Management, retrieve Webhook Details. // Ref. https://fivetran.com/docs/rest-api/webhooks#retrievewebhookdetails type WebhookDetailsService struct { - c *Client - webhookId *string -} - -type WebhookDetailsResponse struct { - Code string `json:"code"` - Data struct { - Id string `json:"id"` - Type string `json:"type"` - Url string `json:"url"` - GroupId string `json:"group_id"` - Events []string `json:"events"` - Active bool `json:"active"` - Secret string `json:"secret"` - CreatedAt string `json:"created_at"` - CreatedBy string `json:"created_by"` - } `json:"data"` + c *Client + webhookId *string } func (c *Client) NewWebhookDetails() *WebhookDetailsService { - return &WebhookDetailsService{c: c} + return &WebhookDetailsService{c: c} } func (s *WebhookDetailsService) WebhookId(value string) *WebhookDetailsService { - s.webhookId = &value - return s + s.webhookId = &value + return s } -func (s *WebhookDetailsService) Do(ctx context.Context) (WebhookDetailsResponse, error) { - var response WebhookDetailsResponse +func (s *WebhookDetailsService) Do(ctx context.Context) (webhooks.WebhookResponse, error) { + var response webhooks.WebhookResponse - if s.webhookId == nil { - return response, fmt.Errorf("missing required webhookId") - } + if s.webhookId == nil { + return response, fmt.Errorf("missing required webhookId") + } - url := fmt.Sprintf("%v/webhooks/%v", s.c.baseURL, *s.webhookId) - expectedStatus := 200 + url := fmt.Sprintf("%v/webhooks/%v", s.c.baseURL, *s.webhookId) + expectedStatus := 200 - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 - r := request{ - method: "GET", - url: url, - queries: nil, - headers: headers, - client: s.c.httpClient, - } + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/webhook_details_test.go b/webhook_details_test.go index 431117b4..4281ba2e 100644 --- a/webhook_details_test.go +++ b/webhook_details_test.go @@ -3,27 +3,29 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestWebhookDetailsE2E(t *testing.T) { - webhookId := CreateWebhookAccount(t) + webhookId := testutils.CreateWebhookAccount(t) - result, err := Client.NewWebhookDetails().WebhookId(webhookId).Do(context.Background()) + result, err := testutils.Client.NewWebhookDetails().WebhookId(webhookId).Do(context.Background()) if err != nil { t.Logf("%+v\n", result) t.Error(err) } - AssertEqual(t, result.Code, "Success") - AssertEqual(t, result.Data.Id, webhookId) - AssertNotEmpty(t, result.Data.CreatedAt) - AssertNotEmpty(t, result.Data.CreatedBy) - AssertEmpty(t, result.Data.GroupId) - AssertEqual(t, result.Data.Type, "account") - AssertEqual(t, result.Data.Secret, "******") - AssertEqual(t, result.Data.Url, "https://localhost:12345") - AssertEqual(t, result.Data.Events, []string{"sync_start","sync_end"}) - AssertEqual(t, result.Data.Active, false) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertEqual(t, result.Data.Id, webhookId) + testutils.AssertNotEmpty(t, result.Data.CreatedAt) + testutils.AssertNotEmpty(t, result.Data.CreatedBy) + testutils.AssertEmpty(t, result.Data.GroupId) + testutils.AssertEqual(t, result.Data.Type, "account") + testutils.AssertEqual(t, result.Data.Secret, "******") + testutils.AssertEqual(t, result.Data.Url, "https://localhost:12345") + testutils.AssertEqual(t, result.Data.Events, []string{"sync_start", "sync_end"}) + testutils.AssertEqual(t, result.Data.Active, false) - t.Cleanup(func() { DeleteWebhook(t, webhookId) }) -} \ No newline at end of file + t.Cleanup(func() { testutils.DeleteWebhook(t, webhookId) }) +} diff --git a/webhook_group_create.go b/webhook_group_create.go index 7db192d3..f4f1ab1e 100644 --- a/webhook_group_create.go +++ b/webhook_group_create.go @@ -1,126 +1,113 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/webhooks" ) // WebhookGroupCreateService implements the Webhook Management, Create a Group Webhook. // Ref. https://fivetran.com/docs/rest-api/webhooks#creategroupwebhook type WebhookGroupCreateService struct { - c *Client - groupId *string - url *string - events *[]string - active *bool - secret *string + c *Client + groupId *string + url *string + events *[]string + active *bool + secret *string } type webhookGroupCreateRequest struct { - Url *string `json:"url,omitempty"` - Events *[]string `json:"events,omitempty"` - Active *bool `json:"active,omitempty"` - Secret *string `json:"secret,omitempty"` -} - - -type WebhookGroupCreateResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Id string `json:"id"` - Type string `json:"type"` - Url string `json:"url"` - GroupId string `json:"group_id"` - Events []string `json:"events"` - Active bool `json:"active"` - Secret string `json:"secret"` - CreatedAt string `json:"created_at"` - CreatedBy string `json:"created_by"` - } `json:"data"` + Url *string `json:"url,omitempty"` + Events *[]string `json:"events,omitempty"` + Active *bool `json:"active,omitempty"` + Secret *string `json:"secret,omitempty"` } func (c *Client) NewWebhookGroupCreate() *WebhookGroupCreateService { - return &WebhookGroupCreateService{c: c} + return &WebhookGroupCreateService{c: c} } func (s *WebhookGroupCreateService) request() *webhookGroupCreateRequest { - return &webhookGroupCreateRequest{ - Url: s.url, - Events: s.events, - Active: s.active, - Secret: s.secret, - } + return &webhookGroupCreateRequest{ + Url: s.url, + Events: s.events, + Active: s.active, + Secret: s.secret, + } } func (s *WebhookGroupCreateService) Url(value string) *WebhookGroupCreateService { - s.url = &value - return s + s.url = &value + return s } func (s *WebhookGroupCreateService) Secret(value string) *WebhookGroupCreateService { - s.secret = &value - return s + s.secret = &value + return s } func (s *WebhookGroupCreateService) Active(value bool) *WebhookGroupCreateService { - s.active = &value - return s + s.active = &value + return s } func (s *WebhookGroupCreateService) Events(value []string) *WebhookGroupCreateService { - s.events = &value - return s + s.events = &value + return s } func (s *WebhookGroupCreateService) GroupId(value string) *WebhookGroupCreateService { - s.groupId = &value - return s + s.groupId = &value + return s } -func (s *WebhookGroupCreateService) Do(ctx context.Context) (WebhookGroupCreateResponse, error) { - var response WebhookGroupCreateResponse - - if s.groupId == nil { - return response, fmt.Errorf("missing required groupId") - } - - - url := fmt.Sprintf("%v/webhooks/group/%v", s.c.baseURL, *s.groupId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "POST", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil +func (s *WebhookGroupCreateService) Do(ctx context.Context) (webhooks.WebhookResponse, error) { + var response webhooks.WebhookResponse + + if s.groupId == nil { + return response, fmt.Errorf("missing required groupId") + } + + url := fmt.Sprintf("%v/webhooks/group/%v", s.c.baseURL, *s.groupId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/webhook_group_create_test.go b/webhook_group_create_test.go index 1779592a..43a7e7ab 100644 --- a/webhook_group_create_test.go +++ b/webhook_group_create_test.go @@ -1,36 +1,38 @@ package fivetran_test import ( - "context" - "testing" + "context" + "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestNewWebhookGroupCreateE2E(t *testing.T) { - created, err := Client.NewWebhookGroupCreate(). - Url("https://localhost:12345"). - Secret("my_secret"). - GroupId(PredefinedGroupId). - Active(false). - Events([]string{"sync_start","sync_end"}). - Do(context.Background()) + created, err := testutils.Client.NewWebhookGroupCreate(). + Url("https://localhost:12345"). + Secret("my_secret"). + GroupId(testutils.PredefinedGroupId). + Active(false). + Events([]string{"sync_start", "sync_end"}). + Do(context.Background()) + + if err != nil { + t.Logf("%+v\n", created) + t.Error(err) + } - if err != nil { - t.Logf("%+v\n", created) - t.Error(err) - } + testutils.AssertEqual(t, created.Code, "Success") + testutils.AssertNotEmpty(t, created.Message) + testutils.AssertNotEmpty(t, created.Data.Id) + testutils.AssertNotEmpty(t, created.Data.Events) + testutils.AssertNotEmpty(t, created.Data.CreatedAt) + testutils.AssertNotEmpty(t, created.Data.CreatedBy) + testutils.AssertEqual(t, created.Data.Type, "group") + testutils.AssertEqual(t, created.Data.Active, false) + testutils.AssertEqual(t, created.Data.GroupId, testutils.PredefinedGroupId) + testutils.AssertEqual(t, created.Data.Secret, "******") + testutils.AssertEqual(t, created.Data.Url, "https://localhost:12345") + testutils.AssertEqual(t, created.Data.Events, []string{"sync_start", "sync_end"}) - AssertEqual(t, created.Code, "Success") - AssertNotEmpty(t, created.Message) - AssertNotEmpty(t, created.Data.Id) - AssertNotEmpty(t, created.Data.Events) - AssertNotEmpty(t, created.Data.CreatedAt) - AssertNotEmpty(t, created.Data.CreatedBy) - AssertEqual(t, created.Data.Type, "group") - AssertEqual(t, created.Data.Active, false) - AssertEqual(t, created.Data.GroupId, PredefinedGroupId) - AssertEqual(t, created.Data.Secret, "******") - AssertEqual(t, created.Data.Url, "https://localhost:12345") - AssertEqual(t, created.Data.Events, []string{"sync_start","sync_end"}) - - t.Cleanup(func() { DeleteWebhook(t, created.Data.Id) }) + t.Cleanup(func() { testutils.DeleteWebhook(t, created.Data.Id) }) } diff --git a/webhook_list.go b/webhook_list.go index 42361028..a01a80f2 100644 --- a/webhook_list.go +++ b/webhook_list.go @@ -1,91 +1,76 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/webhooks" ) // WebhookListService implements the Webhook Management, retrieve List Webhook. // Ref. https://fivetran.com/docs/rest-api/webhooks#retrievethelistofwebhooks type WebhookListService struct { - c *Client - limit *int - cursor *string -} - -type WebhookListResponse struct { - Code string `json:"code"` - Data struct { - Items []struct { - Id string `json:"id"` - Type string `json:"type"` - Url string `json:"url"` - GroupId string `json:"group_id"` - Events []string `json:"events"` - Active bool `json:"active"` - Secret string `json:"secret"` - CreatedAt string `json:"created_at"` - CreatedBy string `json:"created_by"` - } `json:"items"` - NextCursor string `json:"next_cursor"` - } `json:"data"` + c *Client + limit *int + cursor *string } func (c *Client) NewWebhookList() *WebhookListService { - return &WebhookListService{c: c} + return &WebhookListService{c: c} } func (s *WebhookListService) Limit(value int) *WebhookListService { - s.limit = &value - return s + s.limit = &value + return s } func (s *WebhookListService) Cursor(value string) *WebhookListService { - s.cursor = &value - return s + s.cursor = &value + return s } -func (s *WebhookListService) Do(ctx context.Context) (WebhookListResponse, error) { - var response WebhookListResponse +func (s *WebhookListService) Do(ctx context.Context) (webhooks.WebhookListResponse, error) { + var response webhooks.WebhookListResponse + + url := fmt.Sprintf("%v/webhooks", s.c.baseURL) + expectedStatus := 200 - url := fmt.Sprintf("%v/webhooks", s.c.baseURL) - expectedStatus := 200 + headers := s.c.commonHeaders() - headers := s.c.commonHeaders() - - queries := make(map[string]string) - if s.cursor != nil { - queries["cursor"] = *s.cursor - } - if s.limit != nil { - queries["limit"] = fmt.Sprint(*s.limit) - } + queries := make(map[string]string) + if s.cursor != nil { + queries["cursor"] = *s.cursor + } + if s.limit != nil { + queries["limit"] = fmt.Sprint(*s.limit) + } - r := request{ - method: "GET", - url: url, - body: nil, - queries: queries, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, - } + r := httputils.Request{ + Method: "GET", + Url: url, + Body: nil, + Queries: queries, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } - return response, nil + return response, nil } diff --git a/webhook_list_test.go b/webhook_list_test.go index 197c2dc9..5e94afaa 100644 --- a/webhook_list_test.go +++ b/webhook_list_test.go @@ -3,25 +3,27 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestWebhookListE2E(t *testing.T) { - webhookId := CreateWebhookAccount(t) + webhookId := testutils.CreateWebhookAccount(t) - result, err := Client.NewWebhookList().Do(context.Background()) + result, err := testutils.Client.NewWebhookList().Do(context.Background()) if err != nil { t.Logf("%+v\n", result) t.Error(err) } - AssertEqual(t, result.Code, "Success") - AssertNotEmpty(t, result.Data.Items[0].Id) - AssertNotEmpty(t, result.Data.Items[0].Events) - AssertNotEmpty(t, result.Data.Items[0].CreatedAt) - AssertNotEmpty(t, result.Data.Items[0].CreatedBy) - AssertNotEmpty(t, result.Data.Items[0].Type) - AssertNotEmpty(t, result.Data.Items[0].Secret) - AssertNotEmpty(t, result.Data.Items[0].Url) + testutils.AssertEqual(t, result.Code, "Success") + testutils.AssertNotEmpty(t, result.Data.Items[0].Id) + testutils.AssertNotEmpty(t, result.Data.Items[0].Events) + testutils.AssertNotEmpty(t, result.Data.Items[0].CreatedAt) + testutils.AssertNotEmpty(t, result.Data.Items[0].CreatedBy) + testutils.AssertNotEmpty(t, result.Data.Items[0].Type) + testutils.AssertNotEmpty(t, result.Data.Items[0].Secret) + testutils.AssertNotEmpty(t, result.Data.Items[0].Url) - t.Cleanup(func() { DeleteWebhook(t, webhookId) }) + t.Cleanup(func() { testutils.DeleteWebhook(t, webhookId) }) } diff --git a/webhook_modify.go b/webhook_modify.go index 22a5d629..25acf02f 100644 --- a/webhook_modify.go +++ b/webhook_modify.go @@ -1,132 +1,120 @@ package fivetran import ( - "context" - "encoding/json" - "fmt" + "context" + "encoding/json" + "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" + "github.com/fivetran/go-fivetran/webhooks" ) // WebhookModifyService implements the Webhook Management, Modify a Webhook. // Ref. https://fivetran.com/docs/rest-api/webhooks#updatewebhook type WebhookModifyService struct { - c *Client - webhookId *string - url *string - events *[]string - active *bool - secret *string - runTests *bool + c *Client + webhookId *string + url *string + events *[]string + active *bool + secret *string + runTests *bool } type webhookModifyRequest struct { - Url *string `json:"url,omitempty"` - Events *[]string `json:"events,omitempty"` - Active *bool `json:"active,omitempty"` - Secret *string `json:"secret,omitempty"` - RunTests *bool `json:"run_tests,omitempty"` -} - - -type WebhookModifyResponse struct { - Code string `json:"code"` - Message string `json:"message"` - Data struct { - Id string `json:"id"` - Type string `json:"type"` - Url string `json:"url"` - GroupId string `json:"group_id"` - Events []string `json:"events"` - Active bool `json:"active"` - Secret string `json:"secret"` - CreatedAt string `json:"created_at"` - CreatedBy string `json:"created_by"` - } `json:"data"` + Url *string `json:"url,omitempty"` + Events *[]string `json:"events,omitempty"` + Active *bool `json:"active,omitempty"` + Secret *string `json:"secret,omitempty"` + RunTests *bool `json:"run_tests,omitempty"` } func (c *Client) NewWebhookModify() *WebhookModifyService { - return &WebhookModifyService{c: c} + return &WebhookModifyService{c: c} } func (s *WebhookModifyService) request() *webhookModifyRequest { - return &webhookModifyRequest{ - Url: s.url, - Events: s.events, - Active: s.active, - Secret: s.secret, - } + return &webhookModifyRequest{ + Url: s.url, + Events: s.events, + Active: s.active, + Secret: s.secret, + } } func (s *WebhookModifyService) Url(value string) *WebhookModifyService { - s.url = &value - return s + s.url = &value + return s } func (s *WebhookModifyService) Secret(value string) *WebhookModifyService { - s.secret = &value - return s + s.secret = &value + return s } func (s *WebhookModifyService) Active(value bool) *WebhookModifyService { - s.active = &value - return s + s.active = &value + return s } func (s *WebhookModifyService) Events(value []string) *WebhookModifyService { - s.events = &value - return s + s.events = &value + return s } func (s *WebhookModifyService) WebhookId(value string) *WebhookModifyService { - s.webhookId = &value - return s + s.webhookId = &value + return s } func (s *WebhookModifyService) RunTests(value bool) *WebhookModifyService { - s.runTests = &value - return s + s.runTests = &value + return s } -func (s *WebhookModifyService) Do(ctx context.Context) (WebhookModifyResponse, error) { - var response WebhookModifyResponse - - if s.webhookId == nil { - return response, fmt.Errorf("missing required webhookId") - } - - url := fmt.Sprintf("%v/webhooks/%v", s.c.baseURL, *s.webhookId) - expectedStatus := 200 - - headers := s.c.commonHeaders() - headers["Content-Type"] = "application/json" - headers["Accept"] = restAPIv2 - - reqBody, err := json.Marshal(s.request()) - if err != nil { - return response, err - } - - r := request{ - method: "PATCH", - url: url, - body: reqBody, - queries: nil, - headers: headers, - client: s.c.httpClient, - } - - respBody, respStatus, err := r.httpRequest(ctx) - if err != nil { - return response, err - } - - if err := json.Unmarshal(respBody, &response); err != nil { - return response, err - } - - if respStatus != expectedStatus { - err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) - return response, err - } - - return response, nil +func (s *WebhookModifyService) Do(ctx context.Context) (webhooks.WebhookResponse, error) { + var response webhooks.WebhookResponse + + if s.webhookId == nil { + return response, fmt.Errorf("missing required webhookId") + } + + url := fmt.Sprintf("%v/webhooks/%v", s.c.baseURL, *s.webhookId) + expectedStatus := 200 + + headers := s.c.commonHeaders() + headers["Content-Type"] = "application/json" + headers["Accept"] = restAPIv2 + + reqBody, err := json.Marshal(s.request()) + if err != nil { + return response, err + } + + r := httputils.Request{ + Method: "PATCH", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, + } + + respBody, respStatus, err := r.Do(ctx) + if err != nil { + return response, err + } + + if err := json.Unmarshal(respBody, &response); err != nil { + return response, err + } + + if respStatus != expectedStatus { + err := fmt.Errorf("status code: %v; expected: %v", respStatus, expectedStatus) + return response, err + } + + return response, nil } diff --git a/webhook_modify_test.go b/webhook_modify_test.go index 137d4ea2..e9d94133 100644 --- a/webhook_modify_test.go +++ b/webhook_modify_test.go @@ -3,35 +3,36 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestWebhookModifyE2E(t *testing.T) { - webhookId := CreateWebhookAccount(t) + webhookId := testutils.CreateWebhookAccount(t) - updated, err := Client.NewWebhookModify(). - WebhookId(webhookId). - Url("https://localhost:12345"). - Secret("my_secret"). - Active(false). - Events([]string{"sync_start","sync_end"}). + updated, err := testutils.Client.NewWebhookModify(). + WebhookId(webhookId). + Url("https://localhost:12345"). + Secret("my_secret"). + Active(false). + Events([]string{"sync_start", "sync_end"}). Do(context.Background()) - if err != nil { t.Logf("%+v\n", updated) t.Error(err) } - AssertEqual(t, updated.Code, "Success") - AssertNotEmpty(t, updated.Message) - AssertEqual(t, updated.Data.Id, webhookId) - AssertNotEmpty(t, updated.Data.CreatedAt) - AssertNotEmpty(t, updated.Data.CreatedBy) - AssertNotEmpty(t, updated.Data.Type) - AssertEqual(t, updated.Data.Active, false) - AssertEqual(t, updated.Data.Secret, "******") - AssertEqual(t, updated.Data.Url, "https://localhost:12345") - AssertEqual(t, updated.Data.Events, []string{"sync_start","sync_end"}) + testutils.AssertEqual(t, updated.Code, "Success") + testutils.AssertNotEmpty(t, updated.Message) + testutils.AssertEqual(t, updated.Data.Id, webhookId) + testutils.AssertNotEmpty(t, updated.Data.CreatedAt) + testutils.AssertNotEmpty(t, updated.Data.CreatedBy) + testutils.AssertNotEmpty(t, updated.Data.Type) + testutils.AssertEqual(t, updated.Data.Active, false) + testutils.AssertEqual(t, updated.Data.Secret, "******") + testutils.AssertEqual(t, updated.Data.Url, "https://localhost:12345") + testutils.AssertEqual(t, updated.Data.Events, []string{"sync_start", "sync_end"}) - t.Cleanup(func() { DeleteWebhook(t, webhookId) }) -} \ No newline at end of file + t.Cleanup(func() { testutils.DeleteWebhook(t, webhookId) }) +} diff --git a/webhook_tests.go b/webhook_tests.go index 9d70d606..7bef76ab 100644 --- a/webhook_tests.go +++ b/webhook_tests.go @@ -4,26 +4,28 @@ import ( "context" "encoding/json" "fmt" + + httputils "github.com/fivetran/go-fivetran/http_utils" ) // WebhookTestService implements the test method for Webhook Management API. // Ref. https://fivetran.com/docs/rest-api/webhooks#testwebhook type WebhookTestService struct { - c *Client - webhookId *string - event *string + c *Client + webhookId *string + event *string } type webhookTestRequest struct { - Event *string `json:"event,omitempty"` + Event *string `json:"event,omitempty"` } type WebhookTestResponse struct { - Code string `json:"code"` - Data struct { - Succeed bool `json:"succeed"` - Status int `json:"status"` - Message string `json:"message"` + Code string `json:"code"` + Data struct { + Succeed bool `json:"succeed"` + Status int `json:"status"` + Message string `json:"message"` } `json:"data"` } @@ -66,18 +68,18 @@ func (s *WebhookTestService) Do(ctx context.Context) (WebhookTestResponse, error return response, err } - r := request{ - method: "POST", - url: url, - queries: nil, - body: reqBody, - headers: headers, - client: s.c.httpClient, - handleRateLimits: s.c.handleRateLimits, - maxRetryAttempts: s.c.maxRetryAttempts, + r := httputils.Request{ + Method: "POST", + Url: url, + Body: reqBody, + Queries: nil, + Headers: headers, + Client: s.c.httpClient, + HandleRateLimits: s.c.handleRateLimits, + MaxRetryAttempts: s.c.maxRetryAttempts, } - respBody, respStatus, err := r.httpRequest(ctx) + respBody, respStatus, err := r.Do(ctx) if err != nil { return response, err } diff --git a/webhook_tests_test.go b/webhook_tests_test.go index 985a1b93..ff8c70b7 100644 --- a/webhook_tests_test.go +++ b/webhook_tests_test.go @@ -3,14 +3,16 @@ package fivetran_test import ( "context" "testing" + + testutils "github.com/fivetran/go-fivetran/test_utils" ) func TestWebhookTestE2E(t *testing.T) { - webhookId := CreateWebhookAccount(t) - - response, err := Client.NewWebhookTest(). - WebhookId(webhookId). - Event("sync_start"). + webhookId := testutils.CreateWebhookAccount(t) + + response, err := testutils.Client.NewWebhookTest(). + WebhookId(webhookId). + Event("sync_start"). Do(context.Background()) if err != nil { @@ -18,8 +20,8 @@ func TestWebhookTestE2E(t *testing.T) { t.Error(err) } - AssertEqual(t, response.Code, "Success") - AssertEqual(t, response.Data.Succeed, false) + testutils.AssertEqual(t, response.Code, "Success") + testutils.AssertEqual(t, response.Data.Succeed, false) - t.Cleanup(func() { DeleteWebhook(t, webhookId) }) + t.Cleanup(func() { testutils.DeleteWebhook(t, webhookId) }) } diff --git a/webhooks/common_types.go b/webhooks/common_types.go new file mode 100644 index 00000000..528ef2ac --- /dev/null +++ b/webhooks/common_types.go @@ -0,0 +1,30 @@ +package webhooks + +import "github.com/fivetran/go-fivetran/common" + +type WebhookCommonData struct { + Id string `json:"id"` + Type string `json:"type"` + Url string `json:"url"` + Events []string `json:"events"` + Active bool `json:"active"` + Secret string `json:"secret"` + GroupId string `json:"group_id"` + CreatedAt string `json:"created_at"` + CreatedBy string `json:"created_by"` +} + +type WebhookResponse struct { + common.CommonResponse + Data struct { + WebhookCommonData + } `json:"data"` +} + +type WebhookListResponse struct { + Code string `json:"code"` + Data struct { + Items []WebhookCommonData `json:"items"` + NextCursor string `json:"next_cursor"` + } `json:"data"` +}