From d9be5a78c8c1b6940e1a5daeb3362a1d6adf5f2b Mon Sep 17 00:00:00 2001 From: Javier Feliz <me@javierfeliz.com> Date: Sun, 9 Feb 2025 00:25:41 -0500 Subject: [PATCH] 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