Refactor folder structure
This commit is contained in:
parent
7e9a205d53
commit
c7cca02ca7
30 changed files with 610 additions and 933 deletions
30
tests/html_test.go
Normal file
30
tests/html_test.go
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/TheLovinator1/FeedVault/pkg/html"
|
||||
"github.com/TheLovinator1/FeedVault/pkg/models"
|
||||
)
|
||||
|
||||
// Displays error messages if there are any parse errors
|
||||
func TestErrorMessages(t *testing.T) {
|
||||
// Initialize test data
|
||||
parseResult := []models.ParseResult{
|
||||
{IsError: true, Msg: "Error 1"},
|
||||
{IsError: true, Msg: "Error 2"},
|
||||
}
|
||||
|
||||
h := html.HTMLData{
|
||||
ParseResult: parseResult,
|
||||
}
|
||||
|
||||
// Invoke function under test
|
||||
result := html.FullHTML(h)
|
||||
|
||||
// Assert that the result contains the error messages
|
||||
if !strings.Contains(result, "Error 1") || !strings.Contains(result, "Error 2") {
|
||||
t.Errorf("Expected error messages, but got: %s", result)
|
||||
}
|
||||
}
|
||||
111
tests/opml_test.go
Normal file
111
tests/opml_test.go
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/TheLovinator1/FeedVault/pkg/opml"
|
||||
)
|
||||
|
||||
var opmlExample = `<?xml version="1.0" encoding="utf-8"?>
|
||||
<opml version="1.0">
|
||||
<head>
|
||||
<title>My Feeds</title>
|
||||
</head>
|
||||
<body>
|
||||
<outline text="24 ways" htmlUrl="http://24ways.org/" type="rss" xmlUrl="http://feeds.feedburner.com/24ways"/>
|
||||
<outline text="Writing — by Jan" htmlUrl="http://writing.jan.io/" type="rss" xmlUrl="http://writing.jan.io/feed.xml"/>
|
||||
</body>
|
||||
</opml>
|
||||
`
|
||||
|
||||
var secondOpmlExample = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<opml version="1.0">
|
||||
<head>
|
||||
<title>Engineering Blogs</title>
|
||||
</head>
|
||||
<body>
|
||||
<outline text="Engineering Blogs" title="Engineering Blogs">
|
||||
<outline type="rss" text="8th Light" title="8th Light" xmlUrl="https://8thlight.com/blog/feed/atom.xml" htmlUrl="https://8thlight.com/blog/"/>
|
||||
<outline type="rss" text="A" title="A" xmlUrl="http://www.vertabelo.com/_rss/blog.xml" htmlUrl="http://www.vertabelo.com/blog"/>
|
||||
</outline>
|
||||
</body>
|
||||
</opml>
|
||||
`
|
||||
|
||||
// Test the opml parser
|
||||
func TestParseOpml(t *testing.T) {
|
||||
links, err := opml.ParseOpml(opmlExample)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(links.XMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.XMLLinks))
|
||||
}
|
||||
if len(links.HTMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.HTMLLinks))
|
||||
}
|
||||
|
||||
// Test that the links are unique
|
||||
links.XMLLinks = opml.RemoveDuplicates(links.XMLLinks)
|
||||
links.HTMLLinks = opml.RemoveDuplicates(links.HTMLLinks)
|
||||
if len(links.XMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.XMLLinks))
|
||||
}
|
||||
if len(links.HTMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.HTMLLinks))
|
||||
}
|
||||
|
||||
// Test that the links are correct
|
||||
if links.XMLLinks[0] != "http://feeds.feedburner.com/24ways" {
|
||||
t.Errorf("Expected http://feeds.feedburner.com/24ways, got %s", links.XMLLinks[0])
|
||||
}
|
||||
if links.XMLLinks[1] != "http://writing.jan.io/feed.xml" {
|
||||
t.Errorf("Expected http://writing.jan.io/feed.xml, got %s", links.XMLLinks[1])
|
||||
}
|
||||
if links.HTMLLinks[0] != "http://24ways.org/" {
|
||||
t.Errorf("Expected http://24ways.org/, got %s", links.HTMLLinks[0])
|
||||
}
|
||||
if links.HTMLLinks[1] != "http://writing.jan.io/" {
|
||||
t.Errorf("Expected http://writing.jan.io/, got %s", links.HTMLLinks[1])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test the opml parser with nested outlines
|
||||
func TestParseOpmlNested(t *testing.T) {
|
||||
links, err := opml.ParseOpml(secondOpmlExample)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(links.XMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.XMLLinks))
|
||||
}
|
||||
if len(links.HTMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.HTMLLinks))
|
||||
}
|
||||
|
||||
// Test that the links are unique
|
||||
links.XMLLinks = opml.RemoveDuplicates(links.XMLLinks)
|
||||
links.HTMLLinks = opml.RemoveDuplicates(links.HTMLLinks)
|
||||
if len(links.XMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.XMLLinks))
|
||||
}
|
||||
if len(links.HTMLLinks) != 2 {
|
||||
t.Errorf("Expected 2 links, got %d", len(links.HTMLLinks))
|
||||
}
|
||||
|
||||
// Test that the links are correct
|
||||
if links.XMLLinks[0] != "https://8thlight.com/blog/feed/atom.xml" {
|
||||
t.Errorf("Expected https://8thlight.com/blog/feed/atom.xml, got %s", links.XMLLinks[0])
|
||||
}
|
||||
if links.XMLLinks[1] != "http://www.vertabelo.com/_rss/blog.xml" {
|
||||
t.Errorf("Expected http://www.vertabelo.com/_rss/blog.xml, got %s", links.XMLLinks[1])
|
||||
}
|
||||
if links.HTMLLinks[0] != "https://8thlight.com/blog/" {
|
||||
t.Errorf("Expected https://8thlight.com/blog/, got %s", links.HTMLLinks[0])
|
||||
}
|
||||
if links.HTMLLinks[1] != "http://www.vertabelo.com/blog" {
|
||||
t.Errorf("Expected http://www.vertabelo.com/blog, got %s", links.HTMLLinks[1])
|
||||
}
|
||||
|
||||
}
|
||||
248
tests/validate_test.go
Normal file
248
tests/validate_test.go
Normal file
|
|
@ -0,0 +1,248 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/TheLovinator1/FeedVault/pkg/validate"
|
||||
)
|
||||
|
||||
// URL starts with http://
|
||||
func TestURLStartsWithHTTP(t *testing.T) {
|
||||
url := "http://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// URL starts with https://
|
||||
func TestURLStartsWithHTTPS(t *testing.T) {
|
||||
url := "https://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// URL contains a valid domain
|
||||
func TestURLContainsValidDomain(t *testing.T) {
|
||||
url := "http://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// URL is empty
|
||||
func TestURLEmpty(t *testing.T) {
|
||||
url := ""
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URL must start with http:// or https://" {
|
||||
t.Errorf("Expected error message 'URL must start with http:// or https://', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL does not contain a domain
|
||||
func TestURLNotNumbers(t *testing.T) {
|
||||
url := "12345"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URL must start with http:// or https://" {
|
||||
t.Errorf("Expected error message 'URL must start with http:// or https://', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL is not a valid URL
|
||||
func TestURLNotValidURL(t *testing.T) {
|
||||
url := "example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URL must start with http:// or https://" {
|
||||
t.Errorf("Expected error message 'URL must start with http:// or https://', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Domain is resolvable
|
||||
func TestDomainIsResolvable(t *testing.T) {
|
||||
url := "http://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Domain does not end with .local
|
||||
func TestDomainDoesNotEndWithLocal(t *testing.T) {
|
||||
url := "http://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Domain is not localhost
|
||||
func TestDomainIsNotLocalhost(t *testing.T) {
|
||||
url := "http://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Domain is not an IP address
|
||||
func TestDomainIsNotIPAddress(t *testing.T) {
|
||||
url := "http://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err != nil {
|
||||
t.Errorf("Expected no error, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// URL is a file path
|
||||
func TestURLIsFilePath(t *testing.T) {
|
||||
url := "/path/to/file"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URL must start with http:// or https://" {
|
||||
t.Errorf("Expected error message 'URL must start with http:// or https://', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL is a relative path
|
||||
func TestURLIsRelativePath(t *testing.T) {
|
||||
url := "/path/to/resource"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URL must start with http:// or https://" {
|
||||
t.Errorf("Expected error message 'URL must start with http:// or https://', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL is a non-existent domain
|
||||
func TestNonExistentDomainURL(t *testing.T) {
|
||||
url := "http://jfsalksajlkfsajklfsajklfllfjffffkfsklslsksassflfskjlfjlfsjkalfsaf.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "failed to resolve domain" {
|
||||
t.Errorf("Expected error message 'failed to resolve domain', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL is a malformed URL
|
||||
func TestMalformedURL(t *testing.T) {
|
||||
url := "malformedurl"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URL must start with http:// or https://" {
|
||||
t.Errorf("Expected error message 'URL must start with http:// or https://', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL is a domain that does not support HTTP/HTTPS
|
||||
func TestURLDomainNotSupportHTTP(t *testing.T) {
|
||||
url := "ftp://example.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URL must start with http:// or https://" {
|
||||
t.Errorf("Expected error message 'URL must start with http:// or https://', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL is an unreachable domain
|
||||
func TestUnreachableDomain(t *testing.T) {
|
||||
url := "http://fafsffsfsfsfsafsasafassfs.com"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "failed to resolve domain" {
|
||||
t.Errorf("Expected error message 'failed to resolve domain', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL is an IP address
|
||||
func TestURLIsIPAddress(t *testing.T) {
|
||||
url := "http://84.55.107.42"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "IP address URLs are not allowed" {
|
||||
t.Errorf("Expected error message 'IP address URLs are not allowed', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// URL ends with .local
|
||||
func TestURLEndsWithLocal(t *testing.T) {
|
||||
url := "http://example.local"
|
||||
err := validate.ValidateFeedURL(url)
|
||||
if err == nil {
|
||||
t.Error("Expected an error, got nil")
|
||||
} else if err.Error() != "URLs ending with .local are not allowed" {
|
||||
t.Errorf("Expected error message 'URLs ending with .local are not allowed', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocalURLs(t *testing.T) {
|
||||
localURLs := []string{
|
||||
"https://localhost",
|
||||
"https://home.arpa",
|
||||
"https://airbox.home",
|
||||
"https://airport",
|
||||
"https://arcor.easybox",
|
||||
"https://aterm.me",
|
||||
"https://bthub.home",
|
||||
"https://bthomehub.home",
|
||||
"https://congstar.box",
|
||||
"https://connect.box",
|
||||
"https://console.gl-inet.com",
|
||||
"https://easy.box",
|
||||
"https://etxr",
|
||||
"https://fire.walla",
|
||||
"https://fritz.box",
|
||||
"https://fritz.nas",
|
||||
"https://fritz.repeater",
|
||||
"https://giga.cube",
|
||||
"https://hi.link",
|
||||
"https://hitronhub.home",
|
||||
"https://homerouter.cpe",
|
||||
"https://huaweimobilewifi.com",
|
||||
"https://localbattle.net",
|
||||
"https://myfritz.box",
|
||||
"https://mobile.hotspot",
|
||||
"https://ntt.setup",
|
||||
"https://pi.hole",
|
||||
"https://plex.direct",
|
||||
"https://repeater.asus.com",
|
||||
"https://router.asus.com",
|
||||
"https://routerlogin.com",
|
||||
"https://routerlogin.net",
|
||||
"https://samsung.router",
|
||||
"https://speedport.ip",
|
||||
"https://steamloopback.host",
|
||||
"https://tplinkap.net",
|
||||
"https://tplinkeap.net",
|
||||
"https://tplinkmodem.net",
|
||||
"https://tplinkplclogin.net",
|
||||
"https://tplinkrepeater.net",
|
||||
"https://tplinkwifi.net",
|
||||
"https://web.setup",
|
||||
"https://web.setup.home",
|
||||
}
|
||||
|
||||
for _, localURL := range localURLs {
|
||||
err := validate.ValidateFeedURL(localURL)
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error for local URL %s, got nil", localURL)
|
||||
} else if err.Error() != "local URLs are not allowed" {
|
||||
t.Errorf("Expected error message 'local URLs are not allowed', got '%v'", err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
70
tests/views_test.go
Normal file
70
tests/views_test.go
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/TheLovinator1/FeedVault/pkg/handlers"
|
||||
)
|
||||
|
||||
func TestIndexHandler(t *testing.T) {
|
||||
// Create a request to pass to our handler.
|
||||
req, err := http.NewRequest("GET", "/", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(handlers.IndexHandler)
|
||||
|
||||
// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
|
||||
// directly and pass in our Request and ResponseRecorder.
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
// Check the status code is what we expect.
|
||||
if status := rr.Code; status != http.StatusOK {
|
||||
t.Errorf("handler returned wrong status code: got %v want %v",
|
||||
status, http.StatusOK)
|
||||
}
|
||||
|
||||
// Check the response contains the expected string.
|
||||
shouldContain := "Input the URLs of the feeds you wish to archive below. You can add as many as needed, and access them through the website or API. Alternatively, include links to .opml files, and the feeds within will be archived."
|
||||
body := rr.Body.String()
|
||||
if !strings.Contains(body, shouldContain) {
|
||||
t.Errorf("handler returned unexpected body: got %v want %v",
|
||||
body, shouldContain)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApiHandler(t *testing.T) {
|
||||
// Create a request to pass to our handler.
|
||||
req, err := http.NewRequest("GET", "/api", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// We create a ResponseRecorder (which satisfies http.ResponseWriter) to record the response.
|
||||
rr := httptest.NewRecorder()
|
||||
handler := http.HandlerFunc(handlers.ApiHandler)
|
||||
|
||||
// Our handlers satisfy http.Handler, so we can call their ServeHTTP method
|
||||
// directly and pass in our Request and ResponseRecorder.
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
// Check the status code is what we expect.
|
||||
if status := rr.Code; status != http.StatusOK {
|
||||
t.Errorf("handler returned wrong status code: got %v want %v",
|
||||
status, http.StatusOK)
|
||||
}
|
||||
|
||||
// Check the response contains the expected string.
|
||||
shouldContain := "Here be dragons."
|
||||
body := rr.Body.String()
|
||||
if !strings.Contains(body, shouldContain) {
|
||||
t.Errorf("handler returned unexpected body: got %v want %v",
|
||||
body, shouldContain)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue