From d9be5a78c8c1b6940e1a5daeb3362a1d6adf5f2b Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Sun, 9 Feb 2025 00:25:41 -0500 Subject: [PATCH 1/5] Add validation package --- .gitea/workflows/tests.yml | 21 +++++++++++++ Makefile | 3 ++ pkg/validation/validation.go | 46 +++++++++++++++++++++++++++ pkg/validation/validation_test.go | 52 +++++++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 .gitea/workflows/tests.yml create mode 100644 Makefile create mode 100644 pkg/validation/validation.go create mode 100644 pkg/validation/validation_test.go diff --git a/.gitea/workflows/tests.yml b/.gitea/workflows/tests.yml new file mode 100644 index 0000000..c1ee431 --- /dev/null +++ b/.gitea/workflows/tests.yml @@ -0,0 +1,21 @@ +name: Run Go Tests + +on: + pull_request: + branches: [master] + +jobs: + test: + name: Run Tests + runs-on: ubuntu-latest + steps: + - name: Checkout Code + uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.22' + + - name: Run Tests + run: make test \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..8bb3093 --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +test: + @echo "Running tests for main and all packages" + go test ./... \ No newline at end of file diff --git a/pkg/validation/validation.go b/pkg/validation/validation.go new file mode 100644 index 0000000..58b9b80 --- /dev/null +++ b/pkg/validation/validation.go @@ -0,0 +1,46 @@ +package validation + +import ( + "errors" + neturl "net/url" + "strings" +) + +// Errors +var ( + ErrNotAUrl = errors.New("not a URL") + ErrIncorrectProtocol = errors.New("incorrect url protocol") + ErrServiceUnsupported = errors.New("not a URL") +) + +// Music hosts that we support +var musicHosts = []string{ + "youtube.com", +} + +func IsUrl(url string) (bool, *neturl.URL) { + parsed, err := neturl.ParseRequestURI(url) + + return (err == nil), parsed +} + +func IsMusicUrl(url string) (bool, error) { + isUrl, parsed := IsUrl(url) + + if !isUrl { + return false, ErrNotAUrl + } + + // If we have a scheme and it's not http/https we fail + if parsed.Scheme != "" && !strings.Contains(parsed.Scheme, "http") { + return false, ErrIncorrectProtocol + } + + for _, host := range musicHosts { + if host == parsed.Host { + return true, nil + } + } + + return false, ErrServiceUnsupported +} \ No newline at end of file diff --git a/pkg/validation/validation_test.go b/pkg/validation/validation_test.go new file mode 100644 index 0000000..3c7c762 --- /dev/null +++ b/pkg/validation/validation_test.go @@ -0,0 +1,52 @@ +package validation + +import "testing" + +func TestIsUrl(t *testing.T) { + is, _ := IsUrl("definitely not a url") + + if is { + t.Error("Non-url text detected as URL") + } + + is, _ = IsUrl("https://example.com") + + if !is { + t.Error("URL not detected as URL") + } +} + +func TestIsMusicUrlErrors(t *testing.T) { + // Not a URL + is, err := IsMusicUrl("not a url") + + if is { + t.Error("Non-URL was detected as url") + } + + if err != ErrNotAUrl { + t.Error("Incorrect error returned for Non-url link") + } + + // Incorrect protocol + is, err = IsMusicUrl("ssh://youtube.com") + + if is { + t.Error("Incorrect protocol was not caught") + } + + if err != ErrIncorrectProtocol { + t.Error("Incorrect error returned for incorrect protocol") + } + + // Unsupported service + is, err = IsMusicUrl("https://www.deezer.com/") + + if is { + t.Error("Unsupported service was not caught") + } + + if err != ErrServiceUnsupported { + t.Error("Unsupported service did not return the correct error") + } +} \ No newline at end of file -- 2.47.1 From 999758c7909daba47281299bc45bc012feaa333c Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Sun, 9 Feb 2025 00:49:46 -0500 Subject: [PATCH 2/5] Update readme --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 7965f61..7d1753d 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Currently in development. - `ffmpeg` make sure libopus is included - `yt-dlp` -## Current testing steps +## Running locally Copy .env.example to .env @@ -14,4 +14,8 @@ Populate the discord bot keys `go run .` -type `!` in any channel in the discord while you're in a voice channel. \ No newline at end of file +type `!` in any channel in the discord while you're in a voice channel. + +## Running tests locally + +`make test` \ No newline at end of file -- 2.47.1 From e5aa8fe18798f4c3946fe2fc02610b39bb34d1c9 Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Thu, 13 Feb 2025 23:55:18 -0500 Subject: [PATCH 3/5] Small fixes --- pkg/validation/validation.go | 10 +++++++++ pkg/validation/validation_test.go | 37 ++++++++++++++++++++++++++++++- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/pkg/validation/validation.go b/pkg/validation/validation.go index 58b9b80..11497da 100644 --- a/pkg/validation/validation.go +++ b/pkg/validation/validation.go @@ -2,6 +2,8 @@ package validation import ( "errors" + "fmt" + "log" neturl "net/url" "strings" ) @@ -16,9 +18,16 @@ var ( // Music hosts that we support var musicHosts = []string{ "youtube.com", + "www.youtube.com", } func IsUrl(url string) (bool, *neturl.URL) { + // If a URL has no scheme, this will fail. + // So we'll add one if not present + if !strings.Contains(url, "://") { + url = fmt.Sprintf("https://%s", url) + } + parsed, err := neturl.ParseRequestURI(url) return (err == nil), parsed @@ -37,6 +46,7 @@ func IsMusicUrl(url string) (bool, error) { } for _, host := range musicHosts { + log.Println(parsed.Host) if host == parsed.Host { return true, nil } diff --git a/pkg/validation/validation_test.go b/pkg/validation/validation_test.go index 3c7c762..43c4214 100644 --- a/pkg/validation/validation_test.go +++ b/pkg/validation/validation_test.go @@ -1,6 +1,9 @@ package validation -import "testing" +import ( + "log" + "testing" +) func TestIsUrl(t *testing.T) { is, _ := IsUrl("definitely not a url") @@ -16,6 +19,38 @@ func TestIsUrl(t *testing.T) { } } +func TestSchemeHandling(t *testing.T) { + // No scheme but valid url + is, _ := IsUrl("youtube.com") + + if !is { + t.Error("URL without scheme came back as not a url") + } + + // Preserve scheme + is, parsed := IsUrl("ftp://youtube.com") + + if !is { + t.Error("URL without scheme came back as not a url") + } + + if parsed.Scheme != "ftp" { + t.Error("URL scheme was replaced incorrectly") + } +} + +func TestSupportedMusicUrls(t *testing.T) { + // Test actual music url + for _, url := range musicHosts { + log.Println(url) + is, _ := IsMusicUrl(url) + + if !is { + t.Error("Supported service was detected as unsupported") + } + } +} + func TestIsMusicUrlErrors(t *testing.T) { // Not a URL is, err := IsMusicUrl("not a url") -- 2.47.1 From b6b6db6457140ebabf45967fbcf10e6c84d0e2cb Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Thu, 13 Feb 2025 23:56:06 -0500 Subject: [PATCH 4/5] Remove log --- pkg/validation/validation.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/validation/validation.go b/pkg/validation/validation.go index 11497da..60a7787 100644 --- a/pkg/validation/validation.go +++ b/pkg/validation/validation.go @@ -3,7 +3,6 @@ package validation import ( "errors" "fmt" - "log" neturl "net/url" "strings" ) @@ -46,7 +45,6 @@ func IsMusicUrl(url string) (bool, error) { } for _, host := range musicHosts { - log.Println(parsed.Host) if host == parsed.Host { return true, nil } -- 2.47.1 From 69f8a58f372c0e4408910b1070444476aaea86d0 Mon Sep 17 00:00:00 2001 From: Javier Feliz Date: Thu, 13 Feb 2025 23:57:03 -0500 Subject: [PATCH 5/5] Remove log --- pkg/validation/validation_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkg/validation/validation_test.go b/pkg/validation/validation_test.go index 43c4214..519d0cc 100644 --- a/pkg/validation/validation_test.go +++ b/pkg/validation/validation_test.go @@ -1,7 +1,6 @@ package validation import ( - "log" "testing" ) @@ -42,7 +41,6 @@ func TestSchemeHandling(t *testing.T) { func TestSupportedMusicUrls(t *testing.T) { // Test actual music url for _, url := range musicHosts { - log.Println(url) is, _ := IsMusicUrl(url) if !is { -- 2.47.1