Skip to content
Snippets Groups Projects
rootmux_test.go 8.09 KiB
Newer Older
  • Learn to ignore specific revisions
  • package rootmux
    
    import (
    	"encoding/json"
    	"net/http"
    	"net/http/cookiejar"
    	"net/http/httptest"
    	"net/url"
    	"os"
    	"testing"
    
    	"forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/auth"
    	"forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/mocks"
    
    	"forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/monthlyNews"
    
    	"forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/poll"
    
    	"forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/tester"
    	"forge.grandlyon.com/web-et-numerique/llle_project/backoffice-server/internal/tokens"
    )
    
    var (
    
    	oAuth2Server         *httptest.Server
    	newMonthlyNews       = monthlyNews.MonthlyNews{Year: 2020, Month: 0, Header: "newsHeader", Quote: "newsQuote"}
    	newMonthlyNewsStr    string
    	recentMonthlyNews    = monthlyNews.MonthlyNews{Year: 2021, Month: 0, Header: "recentNewsHeader", Quote: "recentNewsQuote"}
    	recentMonthlyNewsStr string
    	newPoll              = poll.Poll{Year: 2020, Month: 0, Question: "pollQuestion", Link: "pollLink"}
    	newPollStr           string
    	noH                  map[string]string
    
    func TestMain(m *testing.M) {
    
    	// Create the OAuth2 mock server
    	oAuth2Server = httptest.NewServer(mocks.CreateMockOAuth2())
    
    	defer oAuth2Server.Close()
    
    	// Set the constants with environment variables
    	os.Setenv("HOSTNAME", "localhost")
    	os.Setenv("ADMIN_ROLE", "ADMINS")
    	os.Setenv("CLIENT_ID", "foo")
    	os.Setenv("CLIENT_SECRET", "bar")
    	os.Setenv("TOKEN_URL", oAuth2Server.URL+"/token")
    	os.Setenv("USERINFO_URL", oAuth2Server.URL+"/userinfo")
    	os.Setenv("LOGOUT_URL", oAuth2Server.URL+"/logout")
    
    
    	// Setup the token manager to use debug mode
    	os.Setenv("DEBUG_MODE", "true")
    	tokens.Init("../configs/tokenskey.json", true)
    
    	// Convert example objects to string
    	newMonthlyNewsBytes, _ := json.Marshal(newMonthlyNews)
    	newMonthlyNewsStr = string(newMonthlyNewsBytes)
    
    	recentMonthlyNewsBytes, _ := json.Marshal(recentMonthlyNews)
    	recentMonthlyNewsStr = string(recentMonthlyNewsBytes)
    
    	newPollBytes, _ := json.Marshal(newPoll)
    	newPollStr = string(newPollBytes)
    
    
    	code := m.Run()
    	// Remove the database
    	os.Remove("backoffice.db")
    	os.Exit(code)
    }
    
    func TestAll(t *testing.T) {
    
    
    	// Set up testers
    	os.Setenv("AUTH_URL", oAuth2Server.URL+"/auth-wrong-state") // Set the server to access failing OAuth2 endpoints
    	oauth2Tests(t)
    	os.Setenv("AUTH_URL", oAuth2Server.URL+"/auth") // Set the server to access the correct OAuth2Endpoint
    	unloggedTests(t)
    
    	os.Setenv("USERINFO_URL", oAuth2Server.URL+"/admininfo")
    	adminTests(t)
    
    }
    
    /**
    SECURITY TESTS (this tests are to check that the security protections works)
    **/
    func oauth2Tests(t *testing.T) {
    	// Create the tester
    	ts, do, _ := createTester(t)
    	defer ts.Close() // Close the tester
    	// Try to login (must fail)
    	do("GET", "/OAuth2Login", noH, "", http.StatusInternalServerError, "invalid oauth state")
    }
    
    /**
    UNLOGGED USER TESTS (this tests are to check that the security protections works)
    **/
    func unloggedTests(t *testing.T) {
    	// Create the tester
    	ts, do, _ := createTester(t)
    	defer ts.Close() // Close the tester
    
    	// Try to create a monthlyNews (must fail)
    
    	do("POST", "/api/admin/monthlyNews", noH, newMonthlyNewsStr, http.StatusUnauthorized, "error extracting token")
    
    	// Try to get the most recent monthlyReport (must fail because not found)
    	do("GET", "/api/common/monthlyReport", noH, "", http.StatusNotFound, "")
    
    ADMIN TESTS (this tests are to check that an administrator can edit a newsletter's content)
    
    **/
    func adminTests(t *testing.T) {
    	// Create the tester
    	ts, do, _ := createTester(t)
    	defer ts.Close() // Close the tester
    	tests := func() {
    		// Get the XSRF Token
    		response := do("GET", "/api/common/WhoAmI", noH, "", http.StatusOK, "")
    		token := auth.TokenData{}
    		json.Unmarshal([]byte(response), &token)
    		xsrfHeader := map[string]string{"XSRF-TOKEN": token.XSRFToken}
    		// Try to create a monthly news without the XSRF-TOKEN (must fail)
    
    		do("POST", "/api/admin/monthlyNews", noH, newMonthlyNewsStr, http.StatusUnauthorized, "XSRF protection triggered")
    
    		// Try to create a monthly news without body (must fail)
    		do("POST", "/api/admin/monthlyNews", xsrfHeader, "", http.StatusBadRequest, "request body is empty")
    
    		// Try to get a monthly news before it is created (must fail because not found)
    		do("GET", "/api/admin/monthlyNews/2020/0", xsrfHeader, "", http.StatusNotFound, "")
    
    		// Try to create a monthly news (must pass)
    
    		do("PUT", "/api/admin/monthlyNews", xsrfHeader, newMonthlyNewsStr, http.StatusCreated, newMonthlyNewsStr)
    		// Try to update a monthly news (must pass)
    		do("PUT", "/api/admin/monthlyNews", xsrfHeader, newMonthlyNewsStr, http.StatusOK, newMonthlyNewsStr)
    		// Try to get the monthly news created (must pass)
    		do("GET", "/api/admin/monthlyNews/2020/0", xsrfHeader, "", http.StatusOK, newMonthlyNewsStr)
    
    		// Try to get the most recent monthlyReport (must pass)
    		do("GET", "/api/common/monthlyReport", noH, "", http.StatusOK, `{"year":2020,"month":0,"header":"newsHeader","quote":"newsQuote","question":"","link":""`)
    
    		// Try to create a poll without the XSRF-TOKEN (must fail)
    		do("POST", "/api/admin/poll", noH, newPollStr, http.StatusUnauthorized, "XSRF protection triggered")
    		// Try to create a poll without body (must fail)
    		do("POST", "/api/admin/poll", xsrfHeader, "", http.StatusBadRequest, "request body is empty")
    
    		// Try to get a poll before it is created (must fail because not found')
    		do("GET", "/api/admin/poll/2020/0", xsrfHeader, "", http.StatusNotFound, "")
    
    		// Try to create a poll (must pass)
    		do("PUT", "/api/admin/poll", xsrfHeader, newPollStr, http.StatusCreated, newPollStr)
    		// Try to update a poll (must pass)
    		do("PUT", "/api/admin/poll", xsrfHeader, newPollStr, http.StatusOK, newPollStr)
    		// Try to get the poll created (must pass)
    		do("GET", "/api/admin/poll/2020/0", xsrfHeader, "", http.StatusOK, newPollStr)
    
    		// Try to get the most recent monthlyReport (must pass)
    		do("GET", "/api/common/monthlyReport", noH, "", http.StatusOK, `{"year":2020,"month":0,"header":"newsHeader","quote":"newsQuote","question":"pollQuestion","link":"pollLink"`)
    
    		// Try to create a monthly news (must pass)
    		do("POST", "/api/admin/monthlyNews", xsrfHeader, recentMonthlyNewsStr, http.StatusCreated, recentMonthlyNewsStr)
    		// Try to get the most recent monthlyReport (must pass)
    		do("GET", "/api/common/monthlyReport", noH, "", http.StatusOK, `{"year":2021,"month":0,"header":"recentNewsHeader","quote":"recentNewsQuote","question":"","link":""`)
    
    		// Try to delete the monthly news created (must pass)
    		do("DELETE", "/api/admin/monthlyNews/2020/0", xsrfHeader, "", http.StatusOK, "successful delete")
    		// Try to get a monthly news after it is deleted (must fail because not found)
    		do("GET", "/api/admin/monthlyNews/2020/0", xsrfHeader, "", http.StatusNotFound, "")
    
    		// Try to delete the poll created (must pass)
    		do("DELETE", "/api/admin/poll/2020/0", xsrfHeader, "", http.StatusOK, "successful delete")
    
    		// Try to get a poll after it is deleted (must fail because not found)
    		do("GET", "/api/admin/poll/2020/0", xsrfHeader, "", http.StatusNotFound, "")
    
    	}
    	// Try to login (must pass)
    
    Rémi PAILHAREY's avatar
    Rémi PAILHAREY committed
    	do("GET", "/OAuth2Login", noH, "", http.StatusOK, "")
    
    	// Run the tests
    	tests()
    	// Try to logout (must pass)
    
    	do("GET", "/Logout", noH, "", http.StatusOK, "")
    	// Try to get a monthly news again (must fail)
    
    	do("GET", "/api/admin/monthlyNews", noH, "", http.StatusUnauthorized, "error extracting token")
    
    	// Try to get a poll again (must fail)
    	do("GET", "/api/admin/poll", noH, "", http.StatusUnauthorized, "error extracting token")
    
    }
    
    func createTester(t *testing.T) (*httptest.Server, tester.DoFn, tester.DoFn) {
    	// Create the server
    	mux := CreateRootMux("../../web")
    
    	ts := httptest.NewServer(mux.Router)
    
    	url, _ := url.Parse(ts.URL)
    	port := url.Port()
    	mux.Manager.Config.RedirectURL = "http://" + os.Getenv("HOSTNAME") + ":" + port + "/OAuth2Callback"
    	mux.Manager.Hostname = "http://" + os.Getenv("HOSTNAME") + ":" + port
    	// Create the cookie jar
    	jar, _ := cookiejar.New(nil)
    	// wrap the testing function
    	return ts, tester.CreateServerTester(t, port, os.Getenv("HOSTNAME"), jar), tester.CreateServerTester(t, port, os.Getenv("HOSTNAME"), nil)
    }