diff --git a/account_oauth_client.go b/account_oauth_client.go index 6f2a57a1c..f575c41ca 100644 --- a/account_oauth_client.go +++ b/account_oauth_client.go @@ -129,3 +129,14 @@ func (c *Client) DeleteOAuthClient(ctx context.Context, clientID string) error { err := doDELETERequest(ctx, c, e) return err } + +// ResetOAuthClientSecret resets the OAuth Client secret for a client with a specified id +func (c *Client) ResetOAuthClientSecret(ctx context.Context, clientID string) (*OAuthClient, error) { + e := formatAPIPath("account/oauth-clients/%s/reset-secret", clientID) + response, err := doPOSTRequest[OAuthClient, any](ctx, c, e) + if err != nil { + return nil, err + } + + return response, nil +} diff --git a/test/integration/account_oauth_client_test.go b/test/integration/account_oauth_client_test.go index 97a51cf8e..c6712b913 100644 --- a/test/integration/account_oauth_client_test.go +++ b/test/integration/account_oauth_client_test.go @@ -2,6 +2,7 @@ package integration import ( "context" + "github.com/stretchr/testify/assert" "testing" "github.com/linode/linodego" @@ -68,6 +69,25 @@ func TestOAuthClients_List(t *testing.T) { } } +func TestOAuthClients_Reset(t *testing.T) { + createOpts := linodego.OAuthClientCreateOptions{ + Public: true, + RedirectURI: "https://example.com", + Label: "go-client-test", + } + client, oauthClient, teardown, err := setupOAuthClient(t, createOpts, "fixtures/TestOAuthClients_Reset") + defer teardown() + if err != nil { + t.Error(err) + } + oauthClientAfterReset, err := client.ResetOAuthClientSecret(context.Background(), oauthClient.ID) + if err != nil { + t.Errorf("Error resetting oauthClient secret, expected struct, got error %v", err) + } + + assert.NotEqual(t, oauthClient.Secret, oauthClientAfterReset.Secret, "Secret should have been reset") +} + func setupOAuthClient(t *testing.T, createOpts linodego.OAuthClientCreateOptions, fixturesYaml string) (*linodego.Client, *linodego.OAuthClient, func(), error) { t.Helper() client, fixtureTeardown := createTestClient(t, fixturesYaml) diff --git a/test/integration/fixtures/TestOAuthClients_Reset.yaml b/test/integration/fixtures/TestOAuthClients_Reset.yaml new file mode 100644 index 000000000..d4dce1ac8 --- /dev/null +++ b/test/integration/fixtures/TestOAuthClients_Reset.yaml @@ -0,0 +1,190 @@ +--- +version: 1 +interactions: +- request: + body: '{"redirect_uri":"https://example.com","label":"go-client-test","public":true}' + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/account/oauth-clients + method: POST + response: + body: '{"id": "757a5af92718d7369687", "redirect_uri": "https://example.com", "label": + "go-client-test", "status": "active", "secret": "1950e1df7217e8f8f1543ba8b1d12c03e6088eb1429e10549e18c650b677015f", + "thumbnail_url": null, "public": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "233" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Dec 2024 01:14:47 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - account:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1600" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/account/oauth-clients/757a5af92718d7369687/reset-secret + method: POST + response: + body: '{"id": "757a5af92718d7369687", "redirect_uri": "https://example.com", "label": + "go-client-test", "status": "active", "secret": "af3ccc4a7d881a8a858593080d0bffb1e9c6b1917cb88e28bd2b10ad885679cb", + "thumbnail_url": null, "public": true}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "233" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Dec 2024 01:14:47 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - account:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1600" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" +- request: + body: "" + form: {} + headers: + Accept: + - application/json + Content-Type: + - application/json + User-Agent: + - linodego/dev https://github.com/linode/linodego + url: https://api.linode.com/v4beta/account/oauth-clients/757a5af92718d7369687 + method: DELETE + response: + body: '{}' + headers: + Access-Control-Allow-Credentials: + - "true" + Access-Control-Allow-Headers: + - Authorization, Origin, X-Requested-With, Content-Type, Accept, X-Filter + Access-Control-Allow-Methods: + - HEAD, GET, OPTIONS, POST, PUT, DELETE + Access-Control-Allow-Origin: + - '*' + Access-Control-Expose-Headers: + - X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Status + Akamai-Internal-Account: + - '*' + Cache-Control: + - max-age=0, no-cache, no-store + Connection: + - keep-alive + Content-Length: + - "2" + Content-Security-Policy: + - default-src 'none' + Content-Type: + - application/json + Expires: + - Tue, 03 Dec 2024 01:14:48 GMT + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000 + Vary: + - Authorization, X-Filter + X-Accepted-Oauth-Scopes: + - account:read_write + X-Content-Type-Options: + - nosniff + X-Frame-Options: + - DENY + - DENY + X-Oauth-Scopes: + - '*' + X-Ratelimit-Limit: + - "1600" + X-Xss-Protection: + - 1; mode=block + status: 200 OK + code: 200 + duration: "" diff --git a/test/unit/account_availability_test.go b/test/unit/account_availability_test.go new file mode 100644 index 000000000..7baf6859a --- /dev/null +++ b/test/unit/account_availability_test.go @@ -0,0 +1,90 @@ +package unit + +import ( + "context" + "fmt" + "github.com/linode/linodego" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAccountAvailabilities_List(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_availability_list") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + base.MockGet("account/availability", fixtureData) + + availabilities, err := base.Client.ListAccountAvailabilities(context.Background(), &linodego.ListOptions{}) + assert.NoError(t, err) + + // Check specific region "us-central" + var usCentralAvailability *linodego.AccountAvailability + for _, availability := range availabilities { + if availability.Region == "us-central" { + usCentralAvailability = &availability + break + } + } + if usCentralAvailability == nil { + t.Errorf("Expected region 'us-central' to be in the response, but it was not found") + } else { + expectedAvailable := []string{"Linodes", "NodeBalancers", "Block Storage", "Kubernetes"} + if !equalSlices(usCentralAvailability.Available, expectedAvailable) { + t.Errorf("Expected available resources for 'us-central' to be %v, but got %v", expectedAvailable, usCentralAvailability.Available) + } + + if len(usCentralAvailability.Unavailable) != 0 { + t.Errorf("Expected no unavailable resources for 'us-central', but got %v", usCentralAvailability.Unavailable) + } + } + + expectedRegionsCount := 40 + if len(availabilities) != expectedRegionsCount { + t.Errorf("Expected %d regions, but got %d", expectedRegionsCount, len(availabilities)) + } +} + +func TestAccountAvailability_Get(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_availability_get") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + regionID := "us-east" + + base.MockGet(fmt.Sprintf("account/availability/%s", regionID), fixtureData) + + availability, err := base.Client.GetAccountAvailability(context.Background(), regionID) + assert.NoError(t, err) + + assert.Equal(t, "us-east", availability.Region, "Expected region to be 'us-east'") + + expectedAvailable := []string{"Linodes", "NodeBalancers"} + assert.ElementsMatch(t, expectedAvailable, availability.Available, "Available resources do not match the expected list") + + expectedUnavailable := []string{"Kubernetes", "Block Storage"} + assert.ElementsMatch(t, expectedUnavailable, availability.Unavailable, "Unavailable resources do not match the expected list") +} + +// Helper function to compare slices in assertion +func equalSlices(a, b []string) bool { + if len(a) != len(b) { + return false + } + aMap := make(map[string]bool) + for _, v := range a { + aMap[v] = true + } + for _, v := range b { + if !aMap[v] { + return false + } + } + return true +} diff --git a/test/unit/account_betas_test.go b/test/unit/account_betas_test.go new file mode 100644 index 000000000..75e532cef --- /dev/null +++ b/test/unit/account_betas_test.go @@ -0,0 +1,74 @@ +package unit + +import ( + "context" + "fmt" + "github.com/jarcoal/httpmock" + "github.com/linode/linodego" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAccountBetaProgram_List(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_beta_list") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + base.MockGet("account/betas", fixtureData) + + betaPrograms, err := base.Client.ListAccountBetaPrograms(context.Background(), &linodego.ListOptions{}) + assert.NoError(t, err) + assert.Len(t, betaPrograms, 1, "Expected exactly 1 beta program") + + betaProgram := betaPrograms[0] + + assert.Equal(t, "example_open", betaProgram.ID, "Expected beta program ID to be 'example_open'") + assert.Equal(t, "Example Open Beta", betaProgram.Label, "Expected beta program label to be 'Example Open Beta'") + assert.Equal(t, "This is an open public beta for an example feature.", betaProgram.Description, "Beta program description does not match") + assert.Equal(t, "2023-07-11 00:00:00 +0000 UTC", betaProgram.Started.String(), "Expected beta program started date to be '2023-07-11T00:00:00'") + assert.Equal(t, "2023-09-11 00:00:00 +0000 UTC", betaProgram.Enrolled.String(), "Expected beta program enrolled date to be '2023-09-11T00:00:00'") + assert.Nil(t, betaProgram.Ended, "Expected beta program ended date to be nil") +} + +func TestAccountBetaProgram_Get(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_beta_get") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + betaId := "example_open" + + base.MockGet(fmt.Sprintf("account/betas/%s", betaId), fixtureData) + + betaProgram, err := base.Client.GetAccountBetaProgram(context.Background(), betaId) + assert.NoError(t, err) + + assert.Equal(t, "example_open", betaProgram.ID, "Expected beta program ID to be 'example_open'") + assert.Equal(t, "Example Open Beta", betaProgram.Label, "Expected beta program label to be 'Example Open Beta'.") + assert.Equal(t, "This is an open public beta for an example feature.", betaProgram.Description, "Beta program description does not match") + assert.Equal(t, "2023-07-11 00:00:00 +0000 UTC", betaProgram.Started.String(), "Expected beta program started date to be '2023-07-11T00:00:00'") + assert.Equal(t, "2023-09-11 00:00:00 +0000 UTC", betaProgram.Enrolled.String(), "Expected beta program enrolled date to be '2023-09-11T00:00:00'") + assert.Nil(t, betaProgram.Ended, "Expected beta program ended date to be nil") +} + +func TestAccountBetaProgram_Join(t *testing.T) { + client := createMockClient(t) + + betaId := "global_load_balancer_beta" + + requestData := linodego.AccountBetaProgramCreateOpts{ + ID: betaId, + } + + httpmock.RegisterRegexpResponder("POST", mockRequestURL(t, "account/betas"), + mockRequestBodyValidate(t, requestData, nil)) + + if _, err := client.JoinBetaProgram(context.Background(), requestData); err != nil { + t.Fatal(err) + } +} diff --git a/test/unit/account_logins_test.go b/test/unit/account_logins_test.go new file mode 100644 index 000000000..1aa300765 --- /dev/null +++ b/test/unit/account_logins_test.go @@ -0,0 +1,55 @@ +package unit + +import ( + "context" + "fmt" + "github.com/linode/linodego" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAccountLogins_List(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_logins_list") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + base.MockGet("account/logins", fixtureData) + + logins, err := base.Client.ListLogins(context.Background(), &linodego.ListOptions{}) + assert.NoError(t, err) + + assert.Len(t, logins, 1, "Expected one login record to be returned") + + login := logins[0] + assert.Equal(t, 1234, login.ID, "Expected login ID to be 1234") + assert.Equal(t, "2018-01-01 00:01:01 +0000 UTC", login.Datetime.String(), "Expected login datetime to be '2018-01-01T00:01:01'") + assert.Equal(t, "192.0.2.0", login.IP, "Expected login IP to be '192.0.2.0'") + assert.True(t, login.Restricted, "Expected login restricted to be true.") + assert.Equal(t, "successful", login.Status, "Expected login status to be 'successful'") + assert.Equal(t, "example_user", login.Username, "Expected login username to be 'example_user'") +} + +func TestAccountLogin_Get(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_logins_get") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + loginID := 1234 + base.MockGet(fmt.Sprintf("account/logins/%d", loginID), fixtureData) + + login, err := base.Client.GetLogin(context.Background(), loginID) + assert.NoError(t, err) + + assert.Equal(t, 1234, login.ID, "Expected login ID to be 1234") + assert.Equal(t, "2018-01-01 00:01:01 +0000 UTC", login.Datetime.String(), "Expected login datetime to be '2018-01-01T00:01:01'") + assert.Equal(t, "192.0.2.0", login.IP, "Expected login IP to be '192.0.2.0'") + assert.True(t, login.Restricted, "Expected login restricted to be true") + assert.Equal(t, "successful", login.Status, "Expected login status to be 'successful'") + assert.Equal(t, "example_user", login.Username, "Expected login username to be 'example_user'") +} diff --git a/test/unit/account_notifications_test.go b/test/unit/account_notifications_test.go new file mode 100644 index 000000000..250ac19e0 --- /dev/null +++ b/test/unit/account_notifications_test.go @@ -0,0 +1,37 @@ +package unit + +import ( + "context" + "github.com/linode/linodego" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAccountNotifications_List(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_notifications_list") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + base.MockGet("account/notifications", fixtureData) + + notifications, err := base.Client.ListNotifications(context.Background(), &linodego.ListOptions{}) + assert.NoError(t, err) + + assert.NotEmpty(t, notifications, "Expected notifications to be returned.") + + // Assertions for the first notification in the list + notification := notifications[0] + assert.Equal(t, "You have an important ticket open!", notification.Label, "Expected notification label to be 'You have an important ticket open!'") + assert.Equal(t, "You have an important ticket open!", notification.Message, "Expected notification message to be 'You have an important ticket open!'") + assert.Equal(t, linodego.NotificationSeverity("major"), notification.Severity, "Expected notification severity to be 'major'") + assert.Equal(t, linodego.NotificationType("ticket_important"), notification.Type, "Expected notification type to be 'ticket_important'") + + // Validate entity within notification + assert.Equal(t, 3456, notification.Entity.ID, "Expected ticket ID to be 3456.") + assert.Equal(t, "Linode not booting.", notification.Entity.Label, "Expected entity label to be 'Linode not booting.'") + assert.Equal(t, "ticket", notification.Entity.Type, "Expected entity type to be 'ticket'.") + assert.Equal(t, "/support/tickets/3456", notification.Entity.URL, "Expected entity URL to be '/support/tickets/3456'") +} diff --git a/test/unit/account_oauth_client_test.go b/test/unit/account_oauth_client_test.go new file mode 100644 index 000000000..aad7fbdea --- /dev/null +++ b/test/unit/account_oauth_client_test.go @@ -0,0 +1,147 @@ +package unit + +import ( + "context" + "fmt" + "github.com/jarcoal/httpmock" + "github.com/linode/linodego" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestAccountOauthClient_List(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_oauth_client_list") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + base.MockGet("account/oauth-clients", fixtureData) + + oauthClients, err := base.Client.ListOAuthClients(context.Background(), &linodego.ListOptions{}) + assert.NoError(t, err) + // Assertions on the returned data + assert.Len(t, oauthClients, 1, "Expected one OAuth client") + + client := oauthClients[0] + assert.Equal(t, "2737bf16b39ab5d7b4a1", client.ID, "Unexpected ID") + assert.Equal(t, "Test_Client_1", client.Label, "Unexpected Label") + assert.False(t, client.Public, "Unexpected Public value") + assert.Equal(t, "https://example.org/oauth/callback", client.RedirectURI, "Unexpected Redirect URI") + assert.Equal(t, linodego.OAuthClientStatus("active"), client.Status, "Unexpected Status") + assert.Equal(t, "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", *client.ThumbnailURL, "Unexpected Thumbnail URL") +} + +func TestAccountOauthClient_Get(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_oauth_client_get") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + clientID := "2737bf16b39ab5d7b4a1" + base.MockGet(fmt.Sprintf("account/oauth-clients/%s", clientID), fixtureData) + + oauthClient, err := base.Client.GetOAuthClient(context.Background(), clientID) + assert.NoError(t, err) + // Assertions on the returned data + assert.Equal(t, "2737bf16b39ab5d7b4a1", oauthClient.ID, "Unexpected ID") + assert.Equal(t, "Test_Client_1", oauthClient.Label, "Unexpected Label") + assert.False(t, oauthClient.Public, "Unexpected Public value") + assert.Equal(t, "https://example.org/oauth/callback", oauthClient.RedirectURI, "Unexpected Redirect URI") + assert.Equal(t, linodego.OAuthClientStatus("active"), oauthClient.Status, "Unexpected Status") + assert.Equal(t, "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", *oauthClient.ThumbnailURL, "Unexpected Thumbnail URL") +} + +func TestAccountOauthClient_Create(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_oauth_client_create") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + requestData := linodego.OAuthClientCreateOptions{ + Label: "Test_Client_1", + RedirectURI: "https://example.org/oauth/callback", + } + + base.MockPost("account/oauth-clients", fixtureData) + + oauthClient, err := base.Client.CreateOAuthClient(context.Background(), requestData) + assert.NoError(t, err) + // Assertions on the returned data + assert.Equal(t, "2737bf16b39ab5d7b4a1", oauthClient.ID, "Unexpected ID") + assert.Equal(t, "Test_Client_1", oauthClient.Label, "Unexpected Label") + assert.False(t, oauthClient.Public, "Unexpected Public value") + assert.Equal(t, "https://example.org/oauth/callback", oauthClient.RedirectURI, "Unexpected Redirect URI") + assert.Equal(t, linodego.OAuthClientStatus("active"), oauthClient.Status, "Unexpected Status") + assert.Equal(t, "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", *oauthClient.ThumbnailURL, "Unexpected Thumbnail URL") +} + +func TestAccountOauthClient_Update(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_oauth_client_update") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + requestData := linodego.OAuthClientUpdateOptions{ + Label: "Test_Client_1_Updated", + RedirectURI: "https://example_updated.org/oauth/callback", + Public: true, + } + + clientID := "2737bf16b39ab5d7b4a1" + base.MockPut(fmt.Sprintf("account/oauth-clients/%s", clientID), fixtureData) + + oauthClient, err := base.Client.UpdateOAuthClient(context.Background(), clientID, requestData) + assert.NoError(t, err) + // Assertions on the updated data + assert.Equal(t, "2737bf16b39ab5d7b4a1", oauthClient.ID, "Unexpected ID") + assert.Equal(t, "Test_Client_1_Updated", oauthClient.Label, "Unexpected Label") + assert.True(t, oauthClient.Public, "Unexpected Public value") + assert.Equal(t, "https://example_updated.org/oauth/callback", oauthClient.RedirectURI, "Unexpected Redirect URI") + assert.Equal(t, linodego.OAuthClientStatus("active"), oauthClient.Status, "Unexpected Status") + assert.Equal(t, "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", *oauthClient.ThumbnailURL, "Unexpected Thumbnail URL") +} + +func TestAccountOauthClient_Delete(t *testing.T) { + client := createMockClient(t) + + clientID := "2737bf16b39ab5d7b4a1" + + httpmock.RegisterRegexpResponder("DELETE", mockRequestURL(t, fmt.Sprintf("account/oauth-clients/%s", clientID)), + httpmock.NewStringResponder(200, "{}")) + + if err := client.DeleteOAuthClient(context.Background(), clientID); err != nil { + t.Fatal(err) + } +} + +func TestAccountOauthClient_Reset(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_oauth_client_reset") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + clientID := "2737bf16b39ab5d7b4a1" + base.MockPost(fmt.Sprintf("account/oauth-clients/%s/reset-secret", clientID), fixtureData) + + oauthClient, err := base.Client.ResetOAuthClientSecret(context.Background(), clientID) + assert.NoError(t, err) + + assert.Equal(t, "2737bf16b39ab5d7b4a1", oauthClient.ID, "Unexpected ID") + assert.Equal(t, "Test_Client_1", oauthClient.Label, "Unexpected Label") + assert.False(t, oauthClient.Public, "Unexpected Public value") + assert.Equal(t, "https://example.org/oauth/callback", oauthClient.RedirectURI, "Unexpected Redirect URI") + assert.Equal(t, linodego.OAuthClientStatus("active"), oauthClient.Status, "Unexpected Status") + assert.Equal(t, "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail", *oauthClient.ThumbnailURL, "Unexpected Thumbnail URL") + assert.Equal(t, "", oauthClient.Secret, "Secret should have been reset") + assert.NotEmpty(t, oauthClient.Secret, "Secret should not be empty after reset") +} diff --git a/test/unit/account_settings_test.go b/test/unit/account_settings_test.go new file mode 100644 index 000000000..e1ba68837 --- /dev/null +++ b/test/unit/account_settings_test.go @@ -0,0 +1,57 @@ +package unit + +import ( + "context" + "github.com/linode/linodego" + "github.com/stretchr/testify/assert" + "testing" +) + +// Helper function to create *bool +func Bool(value bool) *bool { + return &value +} + +func TestAccountSettings_Get(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_settings_get") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + base.MockGet("account/settings", fixtureData) + + accountSettings, err := base.Client.GetAccountSettings(context.Background()) + assert.NoError(t, err) + assert.NotNil(t, accountSettings, "Account settings should not be nil") + assert.False(t, accountSettings.Managed, "Expected 'managed' to be false") + assert.True(t, accountSettings.NetworkHelper, "Expected 'network_helper' to be true") + assert.Nil(t, accountSettings.LongviewSubscription, "Expected 'longview_subscription' to be nil") + assert.True(t, accountSettings.BackupsEnabled, "Expected 'backups_enabled' to be true") + assert.Equal(t, "active", *accountSettings.ObjectStorage, "Expected 'object_storage' to be 'active'") +} + +func TestAccountSettings_Update(t *testing.T) { + fixtureData, err := fixtures.GetFixture("account_settings_update") + assert.NoError(t, err) + + var base ClientBaseCase + base.SetUp(t) + defer base.TearDown(t) + + requestData := linodego.AccountSettingsUpdateOptions{ + BackupsEnabled: Bool(true), + NetworkHelper: Bool(true), + } + base.MockPut("account/settings", fixtureData) + + accountSettings, err := base.Client.UpdateAccountSettings(context.Background(), requestData) + assert.NoError(t, err) + assert.NotNil(t, accountSettings, "Account settings should not be nil") + assert.False(t, accountSettings.Managed, "Expected 'managed' to be false") + assert.True(t, accountSettings.NetworkHelper, "Expected 'network_helper' to be true") + assert.Nil(t, accountSettings.LongviewSubscription, "Expected 'longview_subscription' to be nil") + assert.True(t, accountSettings.BackupsEnabled, "Expected 'backups_enabled' to be true") + assert.Equal(t, "active", *accountSettings.ObjectStorage, "Expected 'object_storage' to be 'active'") +} diff --git a/test/unit/fixtures/account_availability_get.json b/test/unit/fixtures/account_availability_get.json new file mode 100644 index 000000000..5f8a1be93 --- /dev/null +++ b/test/unit/fixtures/account_availability_get.json @@ -0,0 +1,11 @@ +{ + "available": [ + "Linodes", + "NodeBalancers" + ], + "region": "us-east", + "unavailable": [ + "Kubernetes", + "Block Storage" + ] +} \ No newline at end of file diff --git a/test/unit/fixtures/account_availability_list.json b/test/unit/fixtures/account_availability_list.json new file mode 100644 index 000000000..194d6a7df --- /dev/null +++ b/test/unit/fixtures/account_availability_list.json @@ -0,0 +1,207 @@ +{ + "data": [ + { + "region": "us-central", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-west", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-southeast", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-east", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "eu-west", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "ap-south", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "eu-central", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "ap-northeast", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "ap-west", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "ca-central", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "ap-southeast", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-iad", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-ord", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "fr-par", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-sea", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "br-gru", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "nl-ams", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "se-sto", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "es-mad", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "in-maa", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "jp-osa", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "it-mil", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-mia", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "id-cgk", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-lax", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "nz-akl-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-den-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "de-ham-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "fr-mrs-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "za-jnb-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "co-bog-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "mx-qro-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "us-hou-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "cl-scl-1", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "gb-lon", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "au-mel", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "in-bom-2", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "de-fra-2", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "sg-sin-2", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + }, + { + "region": "jp-tyo-3", + "available": ["Linodes", "NodeBalancers", "Block Storage", "Kubernetes"], + "unavailable": [] + } + ], + "page": 1, + "pages": 1, + "results": 40 +} \ No newline at end of file diff --git a/test/unit/fixtures/account_beta_get.json b/test/unit/fixtures/account_beta_get.json new file mode 100644 index 000000000..577544b65 --- /dev/null +++ b/test/unit/fixtures/account_beta_get.json @@ -0,0 +1,8 @@ +{ + "description": "This is an open public beta for an example feature.", + "ended": null, + "enrolled": "2023-09-11T00:00:00", + "id": "example_open", + "label": "Example Open Beta", + "started": "2023-07-11T00:00:00" +} \ No newline at end of file diff --git a/test/unit/fixtures/account_beta_list.json b/test/unit/fixtures/account_beta_list.json new file mode 100644 index 000000000..fb2a62d20 --- /dev/null +++ b/test/unit/fixtures/account_beta_list.json @@ -0,0 +1,15 @@ +{ + "data": [ + { + "description": "This is an open public beta for an example feature.", + "ended": null, + "enrolled": "2023-09-11T00:00:00", + "id": "example_open", + "label": "Example Open Beta", + "started": "2023-07-11T00:00:00" + } + ], + "page": 1, + "pages": 1, + "results": 1 +} \ No newline at end of file diff --git a/test/unit/fixtures/account_logins_get.json b/test/unit/fixtures/account_logins_get.json new file mode 100644 index 000000000..d5a9555c5 --- /dev/null +++ b/test/unit/fixtures/account_logins_get.json @@ -0,0 +1,8 @@ +{ + "datetime": "2018-01-01T00:01:01", + "id": 1234, + "ip": "192.0.2.0", + "restricted": true, + "status": "successful", + "username": "example_user" +} \ No newline at end of file diff --git a/test/unit/fixtures/account_logins_list.json b/test/unit/fixtures/account_logins_list.json new file mode 100644 index 000000000..aa65f2d41 --- /dev/null +++ b/test/unit/fixtures/account_logins_list.json @@ -0,0 +1,15 @@ +{ + "data": [ + { + "datetime": "2018-01-01T00:01:01", + "id": 1234, + "ip": "192.0.2.0", + "restricted": true, + "status": "successful", + "username": "example_user" + } + ], + "page": 1, + "pages": 1, + "results": 1 +} \ No newline at end of file diff --git a/test/unit/fixtures/account_notifications_list.json b/test/unit/fixtures/account_notifications_list.json new file mode 100644 index 000000000..935ec1099 --- /dev/null +++ b/test/unit/fixtures/account_notifications_list.json @@ -0,0 +1,22 @@ +{ + "data": [ + { + "body": null, + "entity": { + "id": 3456, + "label": "Linode not booting.", + "type": "ticket", + "url": "/support/tickets/3456" + }, + "label": "You have an important ticket open!", + "message": "You have an important ticket open!", + "severity": "major", + "type": "ticket_important", + "until": null, + "when": null + } + ], + "page": 1, + "pages": 1, + "results": 1 +} \ No newline at end of file diff --git a/test/unit/fixtures/account_oauth_client_create.json b/test/unit/fixtures/account_oauth_client_create.json new file mode 100644 index 000000000..51705d56c --- /dev/null +++ b/test/unit/fixtures/account_oauth_client_create.json @@ -0,0 +1,9 @@ +{ + "id": "2737bf16b39ab5d7b4a1", + "label": "Test_Client_1", + "public": false, + "redirect_uri": "https://example.org/oauth/callback", + "secret": "", + "status": "active", + "thumbnail_url": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail" +} \ No newline at end of file diff --git a/test/unit/fixtures/account_oauth_client_get.json b/test/unit/fixtures/account_oauth_client_get.json new file mode 100644 index 000000000..51705d56c --- /dev/null +++ b/test/unit/fixtures/account_oauth_client_get.json @@ -0,0 +1,9 @@ +{ + "id": "2737bf16b39ab5d7b4a1", + "label": "Test_Client_1", + "public": false, + "redirect_uri": "https://example.org/oauth/callback", + "secret": "", + "status": "active", + "thumbnail_url": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail" +} \ No newline at end of file diff --git a/test/unit/fixtures/account_oauth_client_list.json b/test/unit/fixtures/account_oauth_client_list.json new file mode 100644 index 000000000..488ce5266 --- /dev/null +++ b/test/unit/fixtures/account_oauth_client_list.json @@ -0,0 +1,16 @@ +{ + "data": [ + { + "id": "2737bf16b39ab5d7b4a1", + "label": "Test_Client_1", + "public": false, + "redirect_uri": "https://example.org/oauth/callback", + "secret": "", + "status": "active", + "thumbnail_url": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail" + } + ], + "page": 1, + "pages": 1, + "results": 1 +} \ No newline at end of file diff --git a/test/unit/fixtures/account_oauth_client_reset.json b/test/unit/fixtures/account_oauth_client_reset.json new file mode 100644 index 000000000..51705d56c --- /dev/null +++ b/test/unit/fixtures/account_oauth_client_reset.json @@ -0,0 +1,9 @@ +{ + "id": "2737bf16b39ab5d7b4a1", + "label": "Test_Client_1", + "public": false, + "redirect_uri": "https://example.org/oauth/callback", + "secret": "", + "status": "active", + "thumbnail_url": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail" +} \ No newline at end of file diff --git a/test/unit/fixtures/account_oauth_client_update.json b/test/unit/fixtures/account_oauth_client_update.json new file mode 100644 index 000000000..364622978 --- /dev/null +++ b/test/unit/fixtures/account_oauth_client_update.json @@ -0,0 +1,9 @@ +{ + "id": "2737bf16b39ab5d7b4a1", + "label": "Test_Client_1_Updated", + "public": true, + "redirect_uri": "https://example_updated.org/oauth/callback", + "secret": "", + "status": "active", + "thumbnail_url": "https://api.linode.com/v4/account/clients/2737bf16b39ab5d7b4a1/thumbnail" +} \ No newline at end of file diff --git a/test/unit/fixtures/account_settings_get.json b/test/unit/fixtures/account_settings_get.json new file mode 100644 index 000000000..38d5a68c9 --- /dev/null +++ b/test/unit/fixtures/account_settings_get.json @@ -0,0 +1,7 @@ +{ + "managed": false, + "network_helper": true, + "longview_subscription": null, + "backups_enabled": true, + "object_storage": "active" +} \ No newline at end of file diff --git a/test/unit/fixtures/account_settings_update.json b/test/unit/fixtures/account_settings_update.json new file mode 100644 index 000000000..38d5a68c9 --- /dev/null +++ b/test/unit/fixtures/account_settings_update.json @@ -0,0 +1,7 @@ +{ + "managed": false, + "network_helper": true, + "longview_subscription": null, + "backups_enabled": true, + "object_storage": "active" +} \ No newline at end of file