Skip to content

Commit

Permalink
Merge pull request #5 from jacobbednarz/add-tests
Browse files Browse the repository at this point in the history
Add some test coverage
  • Loading branch information
jacobbednarz authored Aug 14, 2017
2 parents 36dacd7 + 11d8fa6 commit 6126bef
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist/
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
language: go
sudo: false
go:
- 1.6
- 1.7.x
- 1.8.x
- master
install:
- go get -d -v ./...
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ unactionable reports. Check out the [full list][1] if you're interested.
$ go get github.com/jacobbednarz/go-csp-collector
```

Alternatively, you can download the binaries from the [release page][2].

### Running

```sh
Expand All @@ -37,4 +39,5 @@ violation data because there are already a bunch of great solutions out
there. Once you have your violations being collected, be sure to slurp
them into your favourite log aggregation tool.

[1]: https://github.com/jacobbednarz/go-csp-collector/blob/master/csp_collector.go#L60-L81
[1]: https://github.com/jacobbednarz/go-csp-collector/blob/36dacd76a257a9863d4ffb2482b1034558752587/csp_collector.go#L86-L106
[2]: https://github.com/jacobbednarz/go-csp-collector/releases
164 changes: 164 additions & 0 deletions csp_collector_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package main

import (
"encoding/json"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"testing"
)

func TestHandlerForDisallowedMethods(t *testing.T) {
disallowedMethods := []string{"GET", "DELETE", "PUT", "TRACE", "PATCH"}
randomUrls := []string{"/", "/blah"}

for _, method := range disallowedMethods {
for _, url := range randomUrls {
t.Run(method+url, func(t *testing.T) {
request, err := http.NewRequest(method, url, nil)
if err != nil {
t.Fatalf("failed to create request: %v", err)
}
recorder := httptest.NewRecorder()
handleViolationReport(recorder, request)

response := recorder.Result()
defer response.Body.Close()

if response.StatusCode != http.StatusMethodNotAllowed {
t.Errorf("expected HTTP status %v; got %v", http.StatusMethodNotAllowed, response.StatusCode)
}
})
}
}
}

func TestHandlerForAllowingHealthcheck(t *testing.T) {
request, err := http.NewRequest("GET", "/_healthcheck", nil)
if err != nil {
t.Fatalf("failed to create request: %v", err)
}
recorder := httptest.NewRecorder()

handleViolationReport(recorder, request)

response := recorder.Result()
defer response.Body.Close()

if response.StatusCode != http.StatusOK {
t.Errorf("expected HTTP status %v; got %v", http.StatusOK, response.StatusCode)
}
}

func TestFormattedOutputIncludesTimestamp(t *testing.T) {
var rawReport = []byte(`{
"csp-report": {
"document-uri": "http://example.com/signup.html"
}
}`)

var report CSPReport
err := json.Unmarshal(rawReport, &report)
if err != nil {
fmt.Println("error:", err)
}

formattedReportOutput := formatReport(report)

if !strings.Contains(formattedReportOutput, "timestamp=") {
t.Errorf("timestamp key is expected but not found")
}
}

func TestFormattedOutputIncludesEmptyKeysForRequiredValues(t *testing.T) {
var rawReport = []byte(`{
"csp-report": {
"document-uri": "http://example.com/signup.html",
"referrer": ""
}
}`)

var report CSPReport
err := json.Unmarshal(rawReport, &report)
if err != nil {
fmt.Println("error:", err)
}

formattedReportOutput := formatReport(report)

if !strings.Contains(formattedReportOutput, "referrer=\"\"") {
t.Errorf("expected to find empty 'referrer' value but did not")
}
}

func TestValidateViolationWithInvalidBlockedURIs(t *testing.T) {
invalidBlockedURIs := []string{
"resource://",
"chromenull://",
"chrome-extension://",
"safari-extension://",
"mxjscall://",
"webviewprogressproxy://",
"res://",
"mx://",
"safari-resource://",
"chromeinvoke://",
"chromeinvokeimmediate://",
"mbinit://",
"opera://",
"localhost",
"127.0.0.1",
"none://",
"about:blank",
"android-webview",
"ms-browser-extension",
}

for _, blockedURI := range invalidBlockedURIs {
// Makes the test name more readable for the output.
testName := strings.Replace(blockedURI, "://", "", -1)

t.Run(testName, func(t *testing.T) {
var rawReport = []byte(fmt.Sprintf(`{
"csp-report": {
"blocked-uri": "%s"
}
}`, blockedURI))

var report CSPReport
jsonErr := json.Unmarshal(rawReport, &report)
if jsonErr != nil {
fmt.Println("error:", jsonErr)
}

validateErr := validateViolation(report)
if validateErr == nil {
t.Errorf("expected error to be raised but it didn't")
}

if validateErr.Error() != fmt.Sprintf("Blocked URI ('%s') is an invalid resource.", blockedURI) {
t.Errorf("expected error to include correct message string but it didn't")
}
})
}
}

func TestValidateViolationWithValidBlockedURIs(t *testing.T) {
var rawReport = []byte(`{
"csp-report": {
"blocked-uri": "https://google.com/example.css"
}
}`)

var report CSPReport
jsonErr := json.Unmarshal(rawReport, &report)
if jsonErr != nil {
fmt.Println("error:", jsonErr)
}

validateErr := validateViolation(report)
if validateErr != nil {
t.Errorf("expected error not be raised")
}
}

0 comments on commit 6126bef

Please sign in to comment.