From 69da53e505497b5aab8345dfe8a15e2189c85a2e Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Thu, 23 Feb 2023 11:00:22 -0700 Subject: [PATCH 01/10] run all tests in parallel --- omglol/account_test.go | 8 ++++++++ omglol/address_test.go | 4 ++++ omglol/dns_test.go | 4 ++++ omglol/purl_test.go | 3 +++ 4 files changed, 19 insertions(+) diff --git a/omglol/account_test.go b/omglol/account_test.go index b97e907..06a9890 100644 --- a/omglol/account_test.go +++ b/omglol/account_test.go @@ -6,6 +6,7 @@ import ( ) func TestGetAccountInfo(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -21,6 +22,7 @@ func TestGetAccountInfo(t *testing.T) { } func TestGetAddresses(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -36,6 +38,7 @@ func TestGetAddresses(t *testing.T) { } func TestSetAccountName(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -48,6 +51,7 @@ func TestSetAccountName(t *testing.T) { } func TestGetAccountName(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -67,6 +71,7 @@ func TestGetAccountName(t *testing.T) { } func TestGetActiveSessions(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -83,6 +88,7 @@ func TestGetActiveSessions(t *testing.T) { // This test cannot currently be run automatically func TestDeleteActiveSession(t *testing.T) { + t.Parallel() sessionID := os.Getenv("OMGLOL_DELETABLE_SESSION_ID") if sessionID == "" { @@ -101,6 +107,7 @@ func TestDeleteActiveSession(t *testing.T) { } func TestGetAccountSettings(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -116,6 +123,7 @@ func TestGetAccountSettings(t *testing.T) { } func TestSetAccountSettings(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { diff --git a/omglol/address_test.go b/omglol/address_test.go index 5e5c79b..b3c9977 100644 --- a/omglol/address_test.go +++ b/omglol/address_test.go @@ -5,6 +5,7 @@ import ( ) func TestGetAddressAvailability(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -20,6 +21,7 @@ func TestGetAddressAvailability(t *testing.T) { } func TestGetAddressExpiration(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -35,6 +37,7 @@ func TestGetAddressExpiration(t *testing.T) { } func TestGetAddressInfo(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -50,6 +53,7 @@ func TestGetAddressInfo(t *testing.T) { } func TestGetAddressDirectory(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { diff --git a/omglol/dns_test.go b/omglol/dns_test.go index 10c9d80..3abfb99 100644 --- a/omglol/dns_test.go +++ b/omglol/dns_test.go @@ -5,6 +5,7 @@ import ( ) func TestListDNSRecords(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -22,6 +23,7 @@ func TestListDNSRecords(t *testing.T) { } func TestFilterDNSRecords(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -56,6 +58,7 @@ func TestFilterDNSRecords(t *testing.T) { } func TestCreateAndDeleteDNSRecord(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -78,6 +81,7 @@ func TestCreateAndDeleteDNSRecord(t *testing.T) { } func TestCreateUpdateDeleteDNSRecord(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { diff --git a/omglol/purl_test.go b/omglol/purl_test.go index d4916f2..9d84fdd 100644 --- a/omglol/purl_test.go +++ b/omglol/purl_test.go @@ -5,6 +5,7 @@ import ( ) func TestGetPersistentURL(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -20,6 +21,7 @@ func TestGetPersistentURL(t *testing.T) { } func TestListPersistentURLs(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -37,6 +39,7 @@ func TestListPersistentURLs(t *testing.T) { } func TestCreateAndDeletePersistentURL(t *testing.T) { + t.Parallel() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { From 1639f6d10db86bf109991d8c21d690b73d83f62c Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Fri, 24 Feb 2023 17:59:33 -0700 Subject: [PATCH 02/10] remove note about UpdateDNS from README --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 875ea47..5418f24 100644 --- a/README.md +++ b/README.md @@ -59,5 +59,3 @@ This project is a work-in-progress, see the following table for supported featur ||Delete|DELETE|✔️| >**Note** Features marked with a * are additional to what the API provides - ->**Note** At the time of writing, `UpdateDNSRecord` currently does not work as described in the API docs. See https://github.com/neatnik/omg.lol/issues/584. `ReplaceDNSRecord` can be used instead. From b9e2c7ee781c146bd0db2304327b56f9f8ca58f7 Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sat, 25 Feb 2023 00:30:12 -0700 Subject: [PATCH 03/10] update account_tests --- omglol/account_test.go | 57 ++++++++++++++++++++++++++++++++++++++++-- omglol/common_test.go | 36 ++++++++++++++++++++++++++ omglol/models.go | 28 ++++++++++----------- 3 files changed, 105 insertions(+), 16 deletions(-) diff --git a/omglol/account_test.go b/omglol/account_test.go index 06a9890..d641f5f 100644 --- a/omglol/account_test.go +++ b/omglol/account_test.go @@ -2,6 +2,7 @@ package omglol import ( "os" + "net" "testing" ) @@ -19,6 +20,23 @@ func TestGetAccountInfo(t *testing.T) { } t.Logf("%+v\n", *a) + + if a.APIKey != c.Auth.ApiKey { + t.Error("Incorrect API key") + } + if a.Email != c.Auth.Email { + t.Errorf("Incorrect email: %s", a.Email) + } + if a.Settings.Communication != nil && !isOneOf(*a.Settings.Communication, []string{"email_ok", "email_not_ok"}) { + t.Errorf("Invalid communication setting: %s", *a.Settings.Communication) + } + if a.Settings.DateFormat != nil && !isOneOf(*a.Settings.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { + t.Errorf("Invalid date format setting: %s", *a.Settings.DateFormat) + } + if a.Settings.Owner != nil && len(*a.Settings.Owner) <= 0 { + t.Errorf("Invalid Owner: %s", *a.Settings.Owner) + } + testTimestamps(t, a.Created.UnixEpochTime, a.Created.Iso8601Time, a.Created.Rfc2822Time, a.Created.RelativeTime) } func TestGetAddresses(t *testing.T) { @@ -35,6 +53,14 @@ func TestGetAddresses(t *testing.T) { } t.Logf("%+v\n", *a) + + for _, addr := range *a { + if len(addr.Address) <= 0 { + t.Errorf("Invalid address") + } + testTimestamps(t, addr.Expiration.UnixEpochTime, addr.Expiration.Iso8601Time, addr.Expiration.Rfc2822Time, addr.Expiration.RelativeTime) + testTimestamps(t, addr.Registration.UnixEpochTime, addr.Registration.Iso8601Time, addr.Registration.Rfc2822Time, addr.Registration.RelativeTime) + } } func TestSetAccountName(t *testing.T) { @@ -78,12 +104,28 @@ func TestGetActiveSessions(t *testing.T) { t.Errorf(err.Error()) } - a, err := c.GetActiveSessions() + s, err := c.GetActiveSessions() if err != nil { t.Errorf(err.Error()) } - t.Logf("%+v\n", a) + for _, x := range *s { + if len(x.SessionID) != 32 { + t.Errorf("Session ID %s is not expected length of 32, got length %d", x.SessionID, len(x.SessionID)) + } + if len(x.UserAgent) <= 0 { + t.Errorf("user_agent is empty") + } + if net.ParseIP(x.CreatedIP) == nil { + t.Errorf("Invalid IP address: %s", x.CreatedIP) + } + if x.CreatedOn == 0 { + t.Errorf("Created on timestamp is 0.") + } + if x.CreatedOn > x.ExpiresOn { + t.Errorf("Create date: %d, is after expire date: %d", x.CreatedOn, x.ExpiresOn) + } + } } // This test cannot currently be run automatically @@ -120,6 +162,17 @@ func TestGetAccountSettings(t *testing.T) { } t.Logf("%+v\n", s) + + if *s.Owner != testEmail { + t.Errorf("Settings.Owner %s did not match expected %s.", *s.Owner, testEmail) + } + if s.Communication != nil && !isOneOf(*s.Communication, []string{"email_ok", "email_not_ok"}){ + t.Errorf("Settings.Communication value %s is not one the expected values.", *s.Communication) + } + if s.DateFormat != nil && !isOneOf(*s.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { + t.Errorf("Settings.DateFormat value %s is not one of the expected values.", *s.DateFormat) + } + // s.WebEditor appears to be depricated } func TestSetAccountSettings(t *testing.T) { diff --git a/omglol/common_test.go b/omglol/common_test.go index 72dfd83..7035212 100644 --- a/omglol/common_test.go +++ b/omglol/common_test.go @@ -3,6 +3,7 @@ package omglol import ( "fmt" "os" + "testing" "time" ) @@ -11,6 +12,8 @@ var testKey = os.Getenv("OMGLOL_API_KEY") var testName = os.Getenv("OMGLOL_USERNAME") var testOwnedDomain = os.Getenv("OMGLOL_TEST_OWNED_DOMAIN") // some tests will only work if you own the domain you are testing against +const RFC2822 = "Mon, 02 Jan 2006 15:04:05 -0700" + func setHostURL() string { if hostURL, exists := os.LookupEnv("OMGLOL_API_HOST"); exists { return hostURL @@ -31,3 +34,36 @@ func generateRunUID() string { } var RunUID = generateRunUID() + +func isOneOf(target string, list []string) bool { + for _, s := range list { + if s == target { + return true + } + } + return false +} + +func testTimestamps(t *testing.T, unix int64, iso8601, rfc2822, relative string) { + u := time.Unix(unix, 0) + if u.IsZero() { + t.Errorf("Invalid UnixEpochTime: %d", unix) + } + i8601, err := time.Parse(time.RFC3339, iso8601) + if err != nil { + t.Errorf("Invalid Iso8601Time: %s", iso8601) + } + if u.Unix() != i8601.Unix() { + t.Errorf("UnixEpochTime: %d, does not match Iso8601Time: %d", u.Unix(), i8601.Unix()) + } + r2822, err := time.Parse(RFC2822, rfc2822) + if err != nil { + t.Errorf("Invalid Rfc2822Time: %s, %e", rfc2822, err) + } + if u.Unix() != r2822.Unix() { + t.Errorf("UnixEpochTime: %d, does not match Rfc2822Time: %d", u.Unix(), i8601.Unix()) + } + if len(relative) <= 0 { + t.Errorf("Invalid RelativeTime: %s", relative) + } +} diff --git a/omglol/models.go b/omglol/models.go index 26d2afb..11e3759 100644 --- a/omglol/models.go +++ b/omglol/models.go @@ -22,11 +22,21 @@ type Registration struct { RelativeTime string `json:"relative_time,omitempty"` } +type AddressExpiration struct { + Message string `json:"message,omitempty"` + Expired bool `json:"expired,omitempty"` + WillExpire bool `json:"will_expire,omitempty"` + UnixEpochTime int64 `json:"unix_epoch_time,omitempty"` + Iso8601Time string `json:"iso_8601_time,omitempty"` + Rfc2822Time string `json:"rfc_2822_time,omitempty"` + RelativeTime string `json:"relative_time,omitempty"` +} + type AccountSettings struct { Owner string `json:"owner,omitempty"` - Communication string `json:"communication,omitempty"` - DateFormat string `json:"date_format,omitempty"` - WebEditor string `json:"web_editor,omitempty"` + Communication *string `json:"communication,omitempty"` + DateFormat *string `json:"date_format,omitempty"` + WebEditor *string `json:"web_editor,omitempty"` } type Account struct { @@ -68,16 +78,6 @@ type AddressAvailability struct { Availability string `json:"availability"` } -type AddressExpiration struct { - Message string `json:"message,omitempty"` - Expired bool `json:"expired,omitempty"` - WillExpire bool `json:"will_expire,omitempty"` - UnixEpochTime int64 `json:"unix_epoch_time,omitempty"` - Iso8601Time string `json:"iso_8601_time,omitempty"` - Rfc2822Time string `json:"rfc_2822_time,omitempty"` - RelativeTime string `json:"relative_time,omitempty"` -} - type AddressInfo struct { Address string `json:"address"` Message string `json:"message"` @@ -122,7 +122,7 @@ type dnsRecordContent struct { Type string `json:"type"` Name string `json:"name"` Content string `json:"content"` - Priority *int64 `json:"priority"` + Priority *int64 `json:"priority"` TTL int64 `json:"ttl"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` From 6b9f16ae22753cacab544e5567c8763b952e23c1 Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sat, 25 Feb 2023 00:34:51 -0700 Subject: [PATCH 04/10] fix account tests --- omglol/account_test.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/omglol/account_test.go b/omglol/account_test.go index d641f5f..7571768 100644 --- a/omglol/account_test.go +++ b/omglol/account_test.go @@ -33,8 +33,8 @@ func TestGetAccountInfo(t *testing.T) { if a.Settings.DateFormat != nil && !isOneOf(*a.Settings.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { t.Errorf("Invalid date format setting: %s", *a.Settings.DateFormat) } - if a.Settings.Owner != nil && len(*a.Settings.Owner) <= 0 { - t.Errorf("Invalid Owner: %s", *a.Settings.Owner) + if a.Settings.Owner != testEmail { + t.Errorf("Settings.Owner %s did not match expected %s.", a.Settings.Owner, testEmail) } testTimestamps(t, a.Created.UnixEpochTime, a.Created.Iso8601Time, a.Created.Rfc2822Time, a.Created.RelativeTime) } @@ -163,14 +163,14 @@ func TestGetAccountSettings(t *testing.T) { t.Logf("%+v\n", s) - if *s.Owner != testEmail { - t.Errorf("Settings.Owner %s did not match expected %s.", *s.Owner, testEmail) - } - if s.Communication != nil && !isOneOf(*s.Communication, []string{"email_ok", "email_not_ok"}){ - t.Errorf("Settings.Communication value %s is not one the expected values.", *s.Communication) + if s.Communication != nil && !isOneOf(*s.Communication, []string{"email_ok", "email_not_ok"}) { + t.Errorf("Invalid communication setting: %s", *s.Communication) } if s.DateFormat != nil && !isOneOf(*s.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { - t.Errorf("Settings.DateFormat value %s is not one of the expected values.", *s.DateFormat) + t.Errorf("Invalid date format setting: %s", *s.DateFormat) + } + if s.Owner != testEmail { + t.Errorf("Settings.Owner %s did not match expected %s.", s.Owner, testEmail) } // s.WebEditor appears to be depricated } From f074c153016d173986a293ba98e655b114ea0525 Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sat, 25 Feb 2023 11:37:11 -0700 Subject: [PATCH 05/10] update account and address tests --- omglol/account.go | 20 ++++--- omglol/account_test.go | 128 +++++++++++++++++++++++++---------------- omglol/address.go | 15 +++-- omglol/address_test.go | 94 +++++++++++++++++++++++++++--- omglol/common_test.go | 15 ++++- omglol/models.go | 50 ++++++++-------- 6 files changed, 225 insertions(+), 97 deletions(-) diff --git a/omglol/account.go b/omglol/account.go index ed7699e..cd697f0 100644 --- a/omglol/account.go +++ b/omglol/account.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" "net/http" + "strings" ) // Get information about your account. See https://api.omg.lol/#token-get-account-retrieve-account-information @@ -118,23 +119,28 @@ func (c *Client) GetActiveSessions() (*[]ActiveSession, error) { return nil, err } + var Sessions []ActiveSession + body, err := c.doRequest(req) if err != nil { + if strings.Contains(err.Error(), "status: 404") { + return &Sessions, nil + } return nil, err } - type sessionsResponse struct { - Request request `json:"request"` - Sessions []ActiveSession `json:"response"` - } - - var r sessionsResponse + var r apiResponse if err := json.Unmarshal(body, &r); err != nil { fmt.Printf("Error unmarshalling response: %v\n", err) return nil, err + } + + if err := json.Unmarshal(r.Response, &Sessions); err != nil { + fmt.Printf("Error unmarshalling sessions: %v\n", err) + return nil, err } - return &r.Sessions, nil + return &Sessions, nil } // Delete a session. See https://api.omg.lol/#token-delete-account-remove-a-session diff --git a/omglol/account_test.go b/omglol/account_test.go index 7571768..cf27b68 100644 --- a/omglol/account_test.go +++ b/omglol/account_test.go @@ -19,24 +19,29 @@ func TestGetAccountInfo(t *testing.T) { t.Errorf(err.Error()) } - t.Logf("%+v\n", *a) + if a != nil { + t.Logf("%+v\n", *a) - if a.APIKey != c.Auth.ApiKey { - t.Error("Incorrect API key") - } - if a.Email != c.Auth.Email { - t.Errorf("Incorrect email: %s", a.Email) - } - if a.Settings.Communication != nil && !isOneOf(*a.Settings.Communication, []string{"email_ok", "email_not_ok"}) { - t.Errorf("Invalid communication setting: %s", *a.Settings.Communication) - } - if a.Settings.DateFormat != nil && !isOneOf(*a.Settings.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { - t.Errorf("Invalid date format setting: %s", *a.Settings.DateFormat) - } - if a.Settings.Owner != testEmail { - t.Errorf("Settings.Owner %s did not match expected %s.", a.Settings.Owner, testEmail) + if a.APIKey != c.Auth.ApiKey { + t.Error("Incorrect API key") + } + if a.Email != c.Auth.Email { + t.Errorf("Incorrect email: %s", a.Email) + } + if a.Settings.Communication != nil && !isOneOf(*a.Settings.Communication, []string{"email_ok", "email_not_ok"}) { + t.Errorf("Invalid communication setting: %s", *a.Settings.Communication) + } + if a.Settings.DateFormat != nil && !isOneOf(*a.Settings.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { + t.Errorf("Invalid date format setting: %s", *a.Settings.DateFormat) + } + if a.Settings.Owner != testEmail { + t.Errorf("Settings.Owner %s did not match expected %s.", a.Settings.Owner, testEmail) + } + testTimestamps(t, a.Created.UnixEpochTime, a.Created.Iso8601Time, a.Created.Rfc2822Time, a.Created.RelativeTime) + } else { + t.Error("Account Info returned 'nil'.") } - testTimestamps(t, a.Created.UnixEpochTime, a.Created.Iso8601Time, a.Created.Rfc2822Time, a.Created.RelativeTime) + } func TestGetAddresses(t *testing.T) { @@ -52,15 +57,21 @@ func TestGetAddresses(t *testing.T) { t.Errorf(err.Error()) } - t.Logf("%+v\n", *a) + if a != nil { + t.Logf("%+v\n", *a) - for _, addr := range *a { - if len(addr.Address) <= 0 { - t.Errorf("Invalid address") + for _, addr := range *a { + if len(addr.Address) <= 0 { + t.Errorf("Invalid address") + } + testTimestamps(t, addr.Expiration.UnixEpochTime, addr.Expiration.Iso8601Time, addr.Expiration.Rfc2822Time, addr.Expiration.RelativeTime) + testTimestamps(t, addr.Registration.UnixEpochTime, addr.Registration.Iso8601Time, addr.Registration.Rfc2822Time, addr.Registration.RelativeTime) } - testTimestamps(t, addr.Expiration.UnixEpochTime, addr.Expiration.Iso8601Time, addr.Expiration.Rfc2822Time, addr.Expiration.RelativeTime) - testTimestamps(t, addr.Registration.UnixEpochTime, addr.Registration.Iso8601Time, addr.Registration.Rfc2822Time, addr.Registration.RelativeTime) + } else { + t.Error("Addresses returned 'nil'.") } + + } func TestSetAccountName(t *testing.T) { @@ -89,11 +100,16 @@ func TestGetAccountName(t *testing.T) { t.Errorf(err.Error()) } - t.Logf("%+v\n", *name) + if name != nil { + t.Logf("%+v\n", *name) - if *name != testName { - t.Errorf("Expected %s, got %s", testName, *name) + if *name != testName { + t.Errorf("Expected %s, got %s", testName, *name) + } + } else { + t.Error("Account name returned 'nil'.") } + } func TestGetActiveSessions(t *testing.T) { @@ -109,23 +125,30 @@ func TestGetActiveSessions(t *testing.T) { t.Errorf(err.Error()) } - for _, x := range *s { - if len(x.SessionID) != 32 { - t.Errorf("Session ID %s is not expected length of 32, got length %d", x.SessionID, len(x.SessionID)) - } - if len(x.UserAgent) <= 0 { - t.Errorf("user_agent is empty") - } - if net.ParseIP(x.CreatedIP) == nil { - t.Errorf("Invalid IP address: %s", x.CreatedIP) - } - if x.CreatedOn == 0 { - t.Errorf("Created on timestamp is 0.") - } - if x.CreatedOn > x.ExpiresOn { - t.Errorf("Create date: %d, is after expire date: %d", x.CreatedOn, x.ExpiresOn) + if s != nil { + t.Logf("Active Sessions: %+v", *s) + for _, x := range *s { + if len(x.SessionID) != 32 { + t.Errorf("Session ID %s is not expected length of 32, got length %d", x.SessionID, len(x.SessionID)) + } + if len(x.UserAgent) <= 0 { + t.Errorf("user_agent is empty") + } + if net.ParseIP(x.CreatedIP) == nil { + t.Errorf("Invalid IP address: %s", x.CreatedIP) + } + if x.CreatedOn == 0 { + t.Errorf("Created on timestamp is 0.") + } + if x.CreatedOn > x.ExpiresOn { + t.Errorf("Create date: %d, is after expire date: %d", x.CreatedOn, x.ExpiresOn) + } } + } else { + t.Error("Active sessions returned 'nil'.") } + + } // This test cannot currently be run automatically @@ -161,18 +184,23 @@ func TestGetAccountSettings(t *testing.T) { t.Errorf(err.Error()) } - t.Logf("%+v\n", s) + if s != nil { + t.Logf("%+v\n", *s) - if s.Communication != nil && !isOneOf(*s.Communication, []string{"email_ok", "email_not_ok"}) { - t.Errorf("Invalid communication setting: %s", *s.Communication) - } - if s.DateFormat != nil && !isOneOf(*s.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { - t.Errorf("Invalid date format setting: %s", *s.DateFormat) - } - if s.Owner != testEmail { - t.Errorf("Settings.Owner %s did not match expected %s.", s.Owner, testEmail) + if s.Communication != nil && !isOneOf(*s.Communication, []string{"email_ok", "email_not_ok"}) { + t.Errorf("Invalid communication setting: %s", *s.Communication) + } + if s.DateFormat != nil && !isOneOf(*s.DateFormat, []string{"iso_8601", "dmy", "mdy"}) { + t.Errorf("Invalid date format setting: %s", *s.DateFormat) + } + if s.Owner != testEmail { + t.Errorf("Settings.Owner %s did not match expected %s.", s.Owner, testEmail) + } + // s.WebEditor appears to be depricated + } else { + t.Errorf("Account Settings returned 'nil'.") } - // s.WebEditor appears to be depricated + } func TestSetAccountSettings(t *testing.T) { diff --git a/omglol/address.go b/omglol/address.go index 32a6be5..d211e46 100644 --- a/omglol/address.go +++ b/omglol/address.go @@ -32,8 +32,8 @@ func (c *Client) GetAddressAvailability(address string) (*AddressAvailability, e return &a.Availability, nil } -// Get the expiration date for an address. See https://api.omg.lol/#noauth-get-address-retrieve-address-expiration -func (c *Client) GetAddressExpiration(address string) (*AddressExpiration, error) { +// Get the expiration data for an address. Returns `true` if expired, `false` if not. See https://api.omg.lol/#noauth-get-address-retrieve-address-expiration +func (c *Client) GetAddressExpiration(address string) (*bool, error) { req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/address/%s/expiration", c.HostURL, address), nil) if err != nil { return nil, err @@ -45,8 +45,11 @@ func (c *Client) GetAddressExpiration(address string) (*AddressExpiration, error } type expirationResponse struct { - Request request `json:"request"` - Expiration AddressExpiration `json:"response"` + Request request `json:"request"` + Response struct { + Message string `json:"message"` + Expired bool `json:"expired"` + } `json:"response"` } var e expirationResponse @@ -55,12 +58,12 @@ func (c *Client) GetAddressExpiration(address string) (*AddressExpiration, error return nil, err } - return &e.Expiration, nil + return &e.Response.Expired, nil } // Get comprehensive information about an address. See https://api.omg.lol/#token-get-address-retrieve-private-information-about-an-address func (c *Client) GetAddressInfo(address string) (*AddressInfo, error) { - req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/address/%s/availability", c.HostURL, address), nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/address/%s/info", c.HostURL, address), nil) if err != nil { return nil, err } diff --git a/omglol/address_test.go b/omglol/address_test.go index b3c9977..6d8d4b7 100644 --- a/omglol/address_test.go +++ b/omglol/address_test.go @@ -1,6 +1,7 @@ package omglol import ( + "strings" "testing" ) @@ -12,12 +13,52 @@ func TestGetAddressAvailability(t *testing.T) { t.Errorf(err.Error()) } - a, err := c.GetAddressAvailability("test") + // Test unavailable address + u, err := c.GetAddressAvailability(testOwnedDomain) if err != nil { t.Errorf(err.Error()) } - t.Logf("%+v\n", *a) + if u != nil { + t.Logf("%+v\n", *u) + + if u.Address != testOwnedDomain { + t.Errorf("Returned address: %s did not match expected address %s.", u.Address, testOwnedDomain) + } + if strings.ToLower(u.Availability) != "unavailable" { + t.Errorf("Returned availability: %s did not match expected 'unavailable'.", u.Availability) + } + if u.Available != false { + t.Errorf("Return available field was %t, expected false.", u.Available) + } + } else { + t.Error("Address Availability returned 'nil' when getting unavailable address.") + } + + // Test available address by creating a random string 32 characters long. + // If anyone *has* an address 32 characters long, there is a 1 in 6.33 x 10^49 chance that it will match and this test will fail + availableDomain := randStringBytes(32) + a, err := c.GetAddressAvailability(availableDomain) + if err != nil { + t.Errorf(err.Error()) + } + + if a != nil { + t.Logf("%+v\n", *a) + + if a.Address != availableDomain { + t.Errorf("Returned address: %s did not match expected address %s.", a.Address, availableDomain) + } + if strings.ToLower(a.Availability) != "available" { + t.Errorf("Returned availability: %s did not match expected 'available'.", u.Availability) + } + if a.Available != true { + t.Errorf("Return available field was %t, expected true.", u.Available) + } + } else { + t.Error("Address Availability returned 'nil' when getting available address.") + } + } func TestGetAddressExpiration(t *testing.T) { @@ -28,12 +69,19 @@ func TestGetAddressExpiration(t *testing.T) { t.Errorf(err.Error()) } - a, err := c.GetAddressExpiration("test") + e, err := c.GetAddressExpiration(testOwnedDomain) if err != nil { t.Errorf(err.Error()) } - t.Logf("%+v\n", *a) + if e != nil { + t.Logf("Expiration for domain: '%s' returned: '%t'.", testOwnedDomain, *e) + if *e != false { + t.Errorf("Expected expiration to be false, got %t.", *e) + } + } else { + t.Errorf("Expiration returned 'nil'.") + } } func TestGetAddressInfo(t *testing.T) { @@ -44,12 +92,37 @@ func TestGetAddressInfo(t *testing.T) { t.Errorf(err.Error()) } - i, err := c.GetAddressInfo("terraform") + i, err := c.GetAddressInfo(testOwnedDomain) if err != nil { t.Errorf(err.Error()) } - t.Logf("%+v\n", *i) + if i != nil { + t.Logf("Address Info: %+v\n", *i) + + if i.Address != testOwnedDomain { + t.Errorf("Expected Address: %s, got %s", testOwnedDomain, i.Address) + } + if len(i.Message) <= 0 { + t.Error("Expected Message to not be empty.") + } + testTimestamps(t, i.Registration.UnixEpochTime, i.Registration.Iso8601Time, i.Registration.Rfc2822Time, i.Registration.RelativeTime) + testTimestamps(t, i.Expiration.UnixEpochTime, i.Expiration.Iso8601Time, i.Expiration.Rfc2822Time, i.Expiration.RelativeTime) + if i.Verification.Verified { + if i.Verification.Message != "This address has been verified." { + t.Errorf("Unexpected message when Verified == `true`: %s", i.Verification.Message) + } + } else { + if i.Verification.Message != "This address has not been verified." { + t.Errorf("Unexpected message when Verified == `false`: %s", i.Verification.Message) + } + } + if len(i.Owner) <= 0 { + t.Error("Unexpected empty Owner.") + } + } else { + t.Error("Address info returned 'nil'.") + } } func TestGetAddressDirectory(t *testing.T) { @@ -65,5 +138,12 @@ func TestGetAddressDirectory(t *testing.T) { t.Errorf(err.Error()) } - t.Logf("%+v\n", *d) + if d != nil { + t.Logf("Address Directory: %+v\n", *d) + if len(d.Directory) <= 0 { + t.Error("Directory returned empty.") + } + } else { + t.Error("Address directory returned 'nil'.") + } } diff --git a/omglol/common_test.go b/omglol/common_test.go index 7035212..9f59cd5 100644 --- a/omglol/common_test.go +++ b/omglol/common_test.go @@ -2,6 +2,7 @@ package omglol import ( "fmt" + "math/rand" "os" "testing" "time" @@ -12,8 +13,6 @@ var testKey = os.Getenv("OMGLOL_API_KEY") var testName = os.Getenv("OMGLOL_USERNAME") var testOwnedDomain = os.Getenv("OMGLOL_TEST_OWNED_DOMAIN") // some tests will only work if you own the domain you are testing against -const RFC2822 = "Mon, 02 Jan 2006 15:04:05 -0700" - func setHostURL() string { if hostURL, exists := os.LookupEnv("OMGLOL_API_HOST"); exists { return hostURL @@ -45,6 +44,8 @@ func isOneOf(target string, list []string) bool { } func testTimestamps(t *testing.T, unix int64, iso8601, rfc2822, relative string) { + const RFC2822 = "Mon, 02 Jan 2006 15:04:05 -0700" + u := time.Unix(unix, 0) if u.IsZero() { t.Errorf("Invalid UnixEpochTime: %d", unix) @@ -67,3 +68,13 @@ func testTimestamps(t *testing.T, unix int64, iso8601, rfc2822, relative string) t.Errorf("Invalid RelativeTime: %s", relative) } } + +func randStringBytes(n int) string { + const letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789" + rand.Seed(time.Now().UnixNano()) + b := make([]byte, n) + for i := range b { + b[i] = letterBytes[rand.Intn(len(letterBytes))] + } + return string(b) +} \ No newline at end of file diff --git a/omglol/models.go b/omglol/models.go index 11e3759..49f44fb 100644 --- a/omglol/models.go +++ b/omglol/models.go @@ -14,26 +14,26 @@ type apiResponse struct { Response json.RawMessage `json:"response"` } -type Registration struct { - Message string `json:"message,omitempty"` - UnixEpochTime int64 `json:"unix_epoch_time,omitempty"` - Iso8601Time string `json:"iso_8601_time,omitempty"` - Rfc2822Time string `json:"rfc_2822_time,omitempty"` - RelativeTime string `json:"relative_time,omitempty"` +type AddressRegistration struct { + Message string `json:"message"` + UnixEpochTime int64 `json:"unix_epoch_time"` + Iso8601Time string `json:"iso_8601_time"` + Rfc2822Time string `json:"rfc_2822_time"` + RelativeTime string `json:"relative_time"` } type AddressExpiration struct { - Message string `json:"message,omitempty"` - Expired bool `json:"expired,omitempty"` - WillExpire bool `json:"will_expire,omitempty"` - UnixEpochTime int64 `json:"unix_epoch_time,omitempty"` - Iso8601Time string `json:"iso_8601_time,omitempty"` - Rfc2822Time string `json:"rfc_2822_time,omitempty"` - RelativeTime string `json:"relative_time,omitempty"` + Message string `json:"message"` + Expired bool `json:"expired"` + WillExpire bool `json:"will_expire"` + UnixEpochTime int64 `json:"unix_epoch_time"` + Iso8601Time string `json:"iso_8601_time"` + Rfc2822Time string `json:"rfc_2822_time"` + RelativeTime string `json:"relative_time"` } type AccountSettings struct { - Owner string `json:"owner,omitempty"` + Owner string `json:"owner,omitempty"` Communication *string `json:"communication,omitempty"` DateFormat *string `json:"date_format,omitempty"` WebEditor *string `json:"web_editor,omitempty"` @@ -62,13 +62,13 @@ type ActiveSession struct { } type Address struct { - Address string `json:"address"` - Message string `json:"message,omitempty"` - Punycode string `json:"punycode,omitempty"` - SeeAlso string `json:"see-also,omitempty"` - Registration Registration `json:"registration"` - Expiration AddressExpiration `json:"expiration"` - Owner string `json:"owner,omitempty"` + Address string `json:"address"` + Message string `json:"message,omitempty"` + Punycode string `json:"punycode,omitempty"` + SeeAlso string `json:"see-also,omitempty"` + Registration AddressRegistration `json:"registration"` + Expiration AddressExpiration `json:"expiration"` + Owner string `json:"owner,omitempty"` } type AddressAvailability struct { @@ -79,10 +79,10 @@ type AddressAvailability struct { } type AddressInfo struct { - Address string `json:"address"` - Message string `json:"message"` - Registration Registration `json:"registration"` - Expiration AddressExpiration `json:"expiration"` + Address string `json:"address"` + Message string `json:"message"` + Registration AddressRegistration `json:"registration"` + Expiration AddressExpiration `json:"expiration"` Verification struct { Message string `json:"message"` Verified bool `json:"verified"` From ed224fbc5f15c550216e492d573b884ba40ca98f Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sun, 26 Feb 2023 12:36:38 -0700 Subject: [PATCH 06/10] update common_test --- omglol/common_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/omglol/common_test.go b/omglol/common_test.go index 9f59cd5..f45044c 100644 --- a/omglol/common_test.go +++ b/omglol/common_test.go @@ -8,6 +8,9 @@ import ( "time" ) +// time in seconds to sleep before running each test. Avoids hitting rate limits +const initPause int64 = 1 + var testEmail = os.Getenv("OMGLOL_USER_EMAIL") var testKey = os.Getenv("OMGLOL_API_KEY") var testName = os.Getenv("OMGLOL_USERNAME") @@ -23,6 +26,11 @@ func setHostURL() string { var testHostURL = setHostURL() +// Add sleep to tests to avoid hitting rate limits when accessing the API +func sleep() { + time.Sleep(time.Duration(initPause) * time.Second) +} + // Generates a UID from the Github Workflow if present, otherwise generates a random string. This UID can then be used to prevent collision between test runs. func generateRunUID() string { RunUID := os.Getenv("GITHUB_RUN_ID") + os.Getenv("GITHUB_RUN_ATTEMPT") From dbaf413e9dc6acf17eb99ef416aff046d0e39445 Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sun, 26 Feb 2023 12:36:48 -0700 Subject: [PATCH 07/10] update account --- omglol/account_test.go | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/omglol/account_test.go b/omglol/account_test.go index cf27b68..6456c98 100644 --- a/omglol/account_test.go +++ b/omglol/account_test.go @@ -1,13 +1,13 @@ package omglol import ( - "os" "net" + "os" "testing" ) func TestGetAccountInfo(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -41,11 +41,11 @@ func TestGetAccountInfo(t *testing.T) { } else { t.Error("Account Info returned 'nil'.") } - + } func TestGetAddresses(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -71,11 +71,10 @@ func TestGetAddresses(t *testing.T) { t.Error("Addresses returned 'nil'.") } - } func TestSetAccountName(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -88,7 +87,7 @@ func TestSetAccountName(t *testing.T) { } func TestGetAccountName(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -109,11 +108,11 @@ func TestGetAccountName(t *testing.T) { } else { t.Error("Account name returned 'nil'.") } - + } func TestGetActiveSessions(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -127,7 +126,7 @@ func TestGetActiveSessions(t *testing.T) { if s != nil { t.Logf("Active Sessions: %+v", *s) - for _, x := range *s { + for _, x := range *s { if len(x.SessionID) != 32 { t.Errorf("Session ID %s is not expected length of 32, got length %d", x.SessionID, len(x.SessionID)) } @@ -148,17 +147,15 @@ func TestGetActiveSessions(t *testing.T) { t.Error("Active sessions returned 'nil'.") } - } // This test cannot currently be run automatically -func TestDeleteActiveSession(t *testing.T) { - t.Parallel() - sessionID := os.Getenv("OMGLOL_DELETABLE_SESSION_ID") - - if sessionID == "" { +func TestDeleteActiveSession(t *testing.T) { + sessionID, exists := os.LookupEnv("OMGLOL_DELETABLE_SESSION_ID") + if !exists { t.Skip() } + sleep() c, err := NewClient(testEmail, testKey, testHostURL) @@ -172,7 +169,7 @@ func TestDeleteActiveSession(t *testing.T) { } func TestGetAccountSettings(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -200,11 +197,11 @@ func TestGetAccountSettings(t *testing.T) { } else { t.Errorf("Account Settings returned 'nil'.") } - + } func TestSetAccountSettings(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { From 2cd3396697b42542f88d086852b558f5265af8eb Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sun, 26 Feb 2023 12:36:54 -0700 Subject: [PATCH 08/10] update address --- omglol/address_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/omglol/address_test.go b/omglol/address_test.go index 6d8d4b7..e6c974b 100644 --- a/omglol/address_test.go +++ b/omglol/address_test.go @@ -6,7 +6,7 @@ import ( ) func TestGetAddressAvailability(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -62,7 +62,7 @@ func TestGetAddressAvailability(t *testing.T) { } func TestGetAddressExpiration(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -85,7 +85,7 @@ func TestGetAddressExpiration(t *testing.T) { } func TestGetAddressInfo(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -126,7 +126,7 @@ func TestGetAddressInfo(t *testing.T) { } func TestGetAddressDirectory(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { From d84ce15dd5090f063c93aaa788305d8259c079c7 Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sun, 26 Feb 2023 12:37:02 -0700 Subject: [PATCH 09/10] update dns --- omglol/dns.go | 11 ++++- omglol/dns_test.go | 109 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 100 insertions(+), 20 deletions(-) diff --git a/omglol/dns.go b/omglol/dns.go index 9697819..07cef96 100644 --- a/omglol/dns.go +++ b/omglol/dns.go @@ -16,8 +16,13 @@ func (c *Client) ListDNSRecords(address string) (*[]DNSRecord, error) { return nil, err } + var d []DNSRecord + body, err := c.doRequest(req) if err != nil { + if strings.Contains(err.Error(), "status: 404") { + return &d, nil + } return nil, err } @@ -35,7 +40,9 @@ func (c *Client) ListDNSRecords(address string) (*[]DNSRecord, error) { return nil, err } - return &r.Response.DNS, nil + d = r.Response.DNS + + return &d, nil } // Find a single DNS record from its attributes. @@ -180,7 +187,7 @@ func convertRecordResponse(r dnsRecordContent) *DNSRecord { } // Returns a string representaion of a DNS record -func (d *DNSRecord) ToString() string { +func (d *DNSRecord) String() string { priority := "" if d.Priority != nil { diff --git a/omglol/dns_test.go b/omglol/dns_test.go index 3abfb99..2755b8c 100644 --- a/omglol/dns_test.go +++ b/omglol/dns_test.go @@ -2,10 +2,52 @@ package omglol import ( "testing" + "time" ) +func validateRecord(t *testing.T, r DNSRecord) { + if r.ID <= 0 { + t.Errorf("Record ID is invalid.") + } + if !isOneOf(r.Type, []string{"A", "AAAA", "CAA", "CNAME", "MX", "NS", "SRV", "TXT"}) { + t.Errorf("Unexpected record type: %s.", r.Type) + } + if len(r.Name) <= 0 { + t.Errorf("Name is empty.") + } + if len(r.Data) <= 0 { + t.Errorf("Data is empty.") + } + if r.Type == "MX" && r.Priority == nil { + t.Errorf("Priority cannot be nil for record type 'MX'.") + } + if r.Type != "MX" && r.Priority != nil { + t.Errorf("Record of type '%s' should not have a priority not equal to 'nil'.", r.Type) + } + if r.TTL <= 0 { + t.Errorf("TTL must be greater than 0, got %d", r.TTL) + } + created, err := time.Parse(time.RFC3339, r.CreatedAt) + if err != nil { + t.Error(err.Error()) + } + if created.Unix() <= 0 { + t.Error("Invalid CreatedAt timestamp.") + } + updated, err := time.Parse(time.RFC3339, r.UpdatedAt) + if err != nil { + t.Error(err.Error()) + } + if updated.Unix() <= 0 { + t.Error("Invalid UpdatedAt timestamp.") + } + if updated.Unix() < created.Unix() { + t.Errorf("Updated: %s, cannot be before Created: %s.", r.UpdatedAt, r.CreatedAt) + } +} + func TestListDNSRecords(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -17,48 +59,63 @@ func TestListDNSRecords(t *testing.T) { t.Errorf(err.Error()) } - for _, d := range *l { - t.Logf(d.ToString() + "\n") + if l != nil { + for _, d := range *l { + t.Logf(d.String() + "\n") + validateRecord(t, d) + } + } else { + t.Error("ListDNSRecords returned 'nil'.") } + } func TestFilterDNSRecords(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) - if err != nil { t.Errorf(err.Error()) } // TXT Record criteria1 := map[string]any{ - "ID": 41923511, + "Name": "testlistdns." + testOwnedDomain, "Type": "TXT", "TTL": 300, "Priority": nil, } d1, err := c.FilterDNSRecord(testOwnedDomain, criteria1) - if err != nil { t.Errorf(err.Error()) } - t.Logf(d1.ToString()) + if d1 != nil { + t.Logf(d1.String()) + validateRecord(t, *d1) + } else { + t.Errorf("FilterDNSRecord returned nil.") + } // MX Record criteria2 := map[string]any{ - "ID": int64(42197707), + "Type": "MX", + "Name": "mail." + testOwnedDomain, "Priority": int64(20), } d2, err := c.FilterDNSRecord(testOwnedDomain, criteria2) - t.Logf(d2.ToString()) + if d2 != nil { + t.Logf(d2.String()) + validateRecord(t, *d2) + } else { + t.Errorf("FilterDNSRecord returned nil.") + } } func TestCreateAndDeleteDNSRecord(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -72,7 +129,12 @@ func TestCreateAndDeleteDNSRecord(t *testing.T) { t.Errorf(err.Error()) } - t.Logf(r.ToString()) + if r != nil { + t.Logf(r.String()) + validateRecord(t, *r) + } else { + t.Error("CreateDNSRecord returned 'nil'.") + } err = c.DeleteDNSRecord(testOwnedDomain, r.ID) if err != nil { @@ -81,7 +143,7 @@ func TestCreateAndDeleteDNSRecord(t *testing.T) { } func TestCreateUpdateDeleteDNSRecord(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -97,16 +159,27 @@ func TestCreateUpdateDeleteDNSRecord(t *testing.T) { t.Errorf(err.Error()) } - t.Logf(create.ToString()) - - replace, err := c.UpdateDNSRecord(testOwnedDomain, *record2, create.ID) + if create != nil { + t.Logf(create.String()) + validateRecord(t, *create) + } else { + t.Error("CreateDNSRecord returned 'nil'.") + } + sleep() + update, err := c.UpdateDNSRecord(testOwnedDomain, *record2, create.ID) if err != nil { t.Errorf(err.Error()) } - t.Logf(replace.ToString()) + if update != nil { + t.Logf(update.String()) + validateRecord(t, *update) + } else { + t.Error("UpdateDNSRecord returned 'nil'.") + } - err = c.DeleteDNSRecord(testOwnedDomain, replace.ID) + sleep() + err = c.DeleteDNSRecord(testOwnedDomain, update.ID) if err != nil { t.Errorf(err.Error()) } From 61c9e5c907bd19f1f9055d4b07277022cc693cbf Mon Sep 17 00:00:00 2001 From: Elliott Street Date: Sun, 26 Feb 2023 12:37:07 -0700 Subject: [PATCH 10/10] update purl --- omglol/purl.go | 22 +++++++++++-------- omglol/purl_test.go | 53 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/omglol/purl.go b/omglol/purl.go index 3615434..e0b66eb 100644 --- a/omglol/purl.go +++ b/omglol/purl.go @@ -6,6 +6,7 @@ import ( "fmt" "net/http" "strconv" + "strings" ) // Create a PersistentURL object @@ -25,7 +26,7 @@ func NewPersistentURL(Name, URL string, listed bool, Counter ...*int64) *Persist } // Returns a string representaion of a PersistentURL -func (p *PersistentURL) ToString() string { +func (p *PersistentURL) String() string { counter := "" if p.Counter != nil { counter = strconv.Itoa(int(*p.Counter)) @@ -35,21 +36,21 @@ func (p *PersistentURL) ToString() string { // Create a new PersistentURL. See https://api.omg.lol/#token-post-purls-create-a-new-purl func (c *Client) CreatePersistentURL(domain string, purl PersistentURL) error { - + type purlRequest struct { - Name string `json:"name"` - URL string `json:"url"` - Listed *bool `json:"listed"` + Name string `json:"name"` + URL string `json:"url"` + Listed *bool `json:"listed"` } p := purlRequest{ Name: purl.Name, - URL: purl.URL, + URL: purl.URL, } if !purl.Listed { p.Listed = nil - } else { + } else { t := true p.Listed = &t } @@ -139,8 +140,13 @@ func (c *Client) ListPersistentURLs(address string) (*[]PersistentURL, error) { return nil, err } + var p []PersistentURL + body, err := c.doRequest(req) if err != nil { + if strings.Contains(err.Error(), "status: 404") { + return &p, nil + } return nil, err } @@ -166,8 +172,6 @@ func (c *Client) ListPersistentURLs(address string) (*[]PersistentURL, error) { return nil, err } - var p []PersistentURL - for _, purl := range r.Response.PURLs { var x PersistentURL diff --git a/omglol/purl_test.go b/omglol/purl_test.go index 9d84fdd..55fd62f 100644 --- a/omglol/purl_test.go +++ b/omglol/purl_test.go @@ -4,8 +4,20 @@ import ( "testing" ) +func validatePersistentURL(t *testing.T, p PersistentURL) { + if len(p.Name) <= 0 { + t.Error("PURL Name is empty.") + } + if len(p.URL) <= 0 { + t.Error("PURL URL is empty.") + } + if p.Counter == nil { + t.Error("PURL Counter should not be 'nil'.") + } +} + func TestGetPersistentURL(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -17,11 +29,16 @@ func TestGetPersistentURL(t *testing.T) { t.Errorf(err.Error()) } - t.Logf(p.ToString()) + if p != nil { + t.Logf(p.String()) + validatePersistentURL(t, *p) + } else { + t.Error("GetPersistentURL returned 'nil'.") + } } func TestListPersistentURLs(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -33,13 +50,19 @@ func TestListPersistentURLs(t *testing.T) { t.Errorf(err.Error()) } - for _, p := range *l { - t.Logf(p.ToString() + "\n") + if l != nil { + for _, p := range *l { + t.Logf(p.String() + "\n") + validatePersistentURL(t, p) + } + } else { + t.Error("ListPersistentURLs returned 'nil'.") } + } func TestCreateAndDeletePersistentURL(t *testing.T) { - t.Parallel() + sleep() c, err := NewClient(testEmail, testKey, testHostURL) if err != nil { @@ -55,11 +78,18 @@ func TestCreateAndDeletePersistentURL(t *testing.T) { t.Errorf(err.Error()) } - _, err = c.GetPersistentURL(testOwnedDomain, name1) + u, err := c.GetPersistentURL(testOwnedDomain, name1) if err != nil { t.Errorf(err.Error()) } + if u != nil { + t.Log(u.String()) + validatePersistentURL(t, *u) + } else { + t.Error("GetPersistentURL returned 'nil' when retrieving unlisted PURL.") + } + err = c.DeletePersistentURL(testOwnedDomain, name1) if err != nil { t.Errorf(err.Error()) @@ -74,11 +104,18 @@ func TestCreateAndDeletePersistentURL(t *testing.T) { t.Errorf(err.Error()) } - _, err = c.GetPersistentURL(testOwnedDomain, name2) + l, err := c.GetPersistentURL(testOwnedDomain, name2) if err != nil { t.Errorf(err.Error()) } + if l != nil { + t.Log(l.String()) + validatePersistentURL(t, *l) + } else { + t.Error("GetPersistentURL returned 'nil' when retrieving listed PURL.") + } + err = c.DeletePersistentURL(testOwnedDomain, name2) if err != nil { t.Errorf(err.Error())