Newer
Older
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/models"
"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
monthlyInfo = models.MonthlyInfo{Year: 2021, Month: 0, Info: "Informations du mois", Image: "imagebase64"}
monthlyInfoStr string
monthlyNews = models.MonthlyNews{Year: 2021, Month: 0, Title: "", Content: "Nouvelles fonctionnalités"}
monthlyNewsStr string
newPoll = models.Poll{Year: 2021, Month: 0, Question: "pollQuestion", Link: "pollLink"}
newPollStr string
partnersInfo = models.PartnersInfo{ID: 1, Message: "EGL est down", GRDFFailure: false, EnedisFailure: false, EGLFailure: true, NotificationActivated: true}
partnersInfoStr string
noH map[string]string
// Create the OAuth2 mock server
oAuth2Server = httptest.NewServer(mocks.CreateMockOAuth2())
// 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
monthlyNewsBytes, _ := json.Marshal(monthlyNews)
monthlyNewsStr = string(monthlyNewsBytes)
monthlyInfoBytes, _ := json.Marshal(monthlyInfo)
monthlyInfoStr = string(monthlyInfoBytes)
partnersInfoBytes, _ := json.Marshal(partnersInfo)
partnersInfoStr = string(partnersInfoBytes)
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("PUT", "/api/admin/monthlyNews", noH, monthlyNewsStr, http.StatusUnauthorized, "error extracting token")
// Try to get a monthlyReport (must fail because no parameters are given)
do("GET", "/api/common/monthlyReport", noH, "", http.StatusBadRequest, "")
// Try to get a monthlyReport (must fail because not found)
do("GET", "/api/common/monthlyReport?year=2021&month=12", noH, "", http.StatusNotFound, "")
// Try to get partnersInfo (must pass)
do("GET", "/api/common/partnersInfo", noH, "", http.StatusOK, `{"ID":1,"message":"","grdf_failure":false,"enedis_failure":false,"egl_failure":false,"notification_activated":false}`)
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 monthlyNews without the XSRF-TOKEN (must fail)
do("PUT", "/api/admin/monthlyNews", noH, monthlyNewsStr, http.StatusUnauthorized, "XSRF protection triggered")
// Try to create a monthlyNews without body (must fail)
do("PUT", "/api/admin/monthlyNews", xsrfHeader, "", http.StatusBadRequest, "request body is empty")
// Try to get a monthlyNews before it is created (must fail because not found)
do("GET", "/api/admin/monthlyNews/2021/0", xsrfHeader, "", http.StatusNotFound, "")
// Try to create a monthlyNews (must pass)
do("PUT", "/api/admin/monthlyNews", xsrfHeader, monthlyNewsStr, http.StatusCreated, `{"year":2021,"month":0,"title":"Les nouveautés du service","content":"Nouvelles fonctionnalités"`)
// Try to update a monthlyNews (must pass)
do("PUT", "/api/admin/monthlyNews", xsrfHeader, monthlyNewsStr, http.StatusOK, `{"year":2021,"month":0,"title":"Les nouveautés du service","content":"Nouvelles fonctionnalités"`)
// Try to get the monthlyNews created (must pass)
do("GET", "/api/admin/monthlyNews/2021/0", xsrfHeader, "", http.StatusOK, `{"year":2021,"month":0,"title":"Les nouveautés du service","content":"Nouvelles fonctionnalités"`)
// Try to get the monthlyReport (must fail because monthlyInfo not found)
do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusNotFound, "")
// Try to create a poll without the XSRF-TOKEN (must fail)
do("PUT", "/api/admin/poll", noH, newPollStr, http.StatusUnauthorized, "XSRF protection triggered")
// Try to create a poll without body (must fail)
do("PUT", "/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/2021/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/2021/0", xsrfHeader, "", http.StatusOK, newPollStr)
// Try to get the monthlyReport (must fail because monthlyInfo not found)
do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusNotFound, "")
// Try to create a monthlyInfo without the XSRF-TOKEN (must fail)
do("PUT", "/api/admin/monthlyInfo", noH, monthlyInfoStr, http.StatusUnauthorized, "XSRF protection triggered")
// Try to create a monthlyInfo without body (must fail)
do("PUT", "/api/admin/monthlyInfo", xsrfHeader, "", http.StatusBadRequest, "request body is empty")
// Try to get a monthlyInfo before it is created (must fail because not found)
do("GET", "/api/admin/monthlyInfo/2021/0", xsrfHeader, "", http.StatusNotFound, "")
// Try to create a monthlyInfo (must pass)
do("PUT", "/api/admin/monthlyInfo", xsrfHeader, monthlyInfoStr, http.StatusCreated, monthlyInfoStr)
// Try to update a monthlyInfo (must pass)
do("PUT", "/api/admin/monthlyInfo", xsrfHeader, monthlyInfoStr, http.StatusOK, monthlyInfoStr)
// Try to get the monthlyInfo created (must pass)
do("GET", "/api/admin/monthlyInfo/2021/0", xsrfHeader, "", http.StatusOK, monthlyInfoStr)
// Try to get the monthlyReport (must pass)
do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","image":"imagebase64","newsTitle":"Les nouveautés du service","newsContent":"Nouvelles fonctionnalités","question":"pollQuestion","link":"pollLink"`)
// Try to update the partnersInfo (must pass)
do("PUT", "/api/admin/partnersInfo", xsrfHeader, partnersInfoStr, http.StatusOK, partnersInfoStr)
// Try to get the monthlyInfo created (must pass)
do("GET", "/api/common/partnersInfo", xsrfHeader, "", http.StatusOK, partnersInfoStr)
// Try to delete the monthlyNews created (must pass)
do("DELETE", "/api/admin/monthlyNews/2021/0", xsrfHeader, "", http.StatusOK, "successful delete")
// Try to get a monthlyNews after it is deleted (must fail because not found)
do("GET", "/api/admin/monthlyNews/2021/0", xsrfHeader, "", http.StatusNotFound, "")
// Try to get the monthlyReport (must pass)
do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","image":"imagebase64","newsTitle":"","newsContent":"","question":"pollQuestion","link":"pollLink"`)
// Try to delete the poll created (must pass)
do("DELETE", "/api/admin/poll/2021/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/2021/0", xsrfHeader, "", http.StatusNotFound, "")
// Try to get the monthlyReport (must pass)
do("GET", "/api/common/monthlyReport/2021/0", noH, "", http.StatusOK, `{"year":2021,"month":0,"info":"Informations du mois","image":"imagebase64","newsTitle":"","newsContent":"","question":"","link":""`)
// Run the tests
tests()
// Try to logout (must pass)
do("GET", "/Logout", noH, "", http.StatusOK, "")
// Try to get a monthlyNews 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
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)
}