github.com/saadullahsaeed/fragmenta-cms@v1.5.4/src/users/actions/actions_test.go (about)

     1  package useractions
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"net/url"
     8  	"strings"
     9  	"testing"
    10  
    11  	"github.com/fragmenta/auth"
    12  	"github.com/fragmenta/mux"
    13  	"github.com/fragmenta/query"
    14  
    15  	"github.com/fragmenta/fragmenta-cms/src/lib/resource"
    16  	"github.com/fragmenta/fragmenta-cms/src/users"
    17  )
    18  
    19  // names is used to test setting and getting the first string field of the user.
    20  var names = []string{"foo", "bar"}
    21  
    22  // testSetup performs setup for integration tests
    23  // using the test database, real views, and mock authorisation
    24  // If we can run this once for global tests it might be more efficient?
    25  func TestSetup(t *testing.T) {
    26  	err := resource.SetupTestDatabase(3)
    27  	if err != nil {
    28  		fmt.Printf("users: Setup db failed %s", err)
    29  	}
    30  
    31  	// Set up mock auth
    32  	resource.SetupAuthorisation()
    33  
    34  	// Load templates for rendering
    35  	resource.SetupView(3)
    36  
    37  	router := mux.New()
    38  	mux.SetDefault(router)
    39  
    40  	// FIXME - would prefer to load real routes from app pkg
    41  	router.Add("/users", nil)
    42  	router.Add("/users/create", nil)
    43  	router.Add("/users/create", nil).Post()
    44  	router.Add("/users/login", nil)
    45  	router.Add("/users/login", nil).Post()
    46  	router.Add("/users/login", nil).Post()
    47  	router.Add("/users/logout", nil).Post()
    48  	router.Add("/users/{id:\\d+}/update", nil)
    49  	router.Add("/users/{id:\\d+}/update", nil).Post()
    50  	router.Add("/users/{id:\\d+}/destroy", nil).Post()
    51  	router.Add("/users/{id:\\d+}", nil)
    52  
    53  	// Delete all users to ensure we get consistent results?
    54  	_, err = query.ExecSQL("delete from users;")
    55  	if err != nil {
    56  		t.Fatalf("error setting up:%s", err)
    57  	}
    58  	// Insert a test admin user for checking logins - never delete as will
    59  	// be required for other resources testing
    60  	_, err = query.ExecSQL("INSERT INTO users (id,email,name,status,role,password_hash) VALUES(1,'example@example.com','test',100,100,'$2a$10$2IUzpI/yH0Xc.qs9Z5UUL.3f9bqi0ThvbKs6Q91UOlyCEGY8hdBw6');")
    61  	if err != nil {
    62  		t.Fatalf("error setting up:%s", err)
    63  	}
    64  	// Insert user to delete
    65  	_, err = query.ExecSQL("INSERT INTO users (id,email,name,status,role,password_hash) VALUES(2,'example@example.com','test',100,0,'$2a$10$2IUzpI/yH0Xc.qs9Z5UUL.3f9bqi0ThvbKs6Q91UOlyCEGY8hdBw6');")
    66  	if err != nil {
    67  		t.Fatalf("error setting up:%s", err)
    68  	}
    69  	_, err = query.ExecSQL("ALTER SEQUENCE users_id_seq RESTART WITH 3;")
    70  	if err != nil {
    71  		t.Fatalf("error setting up:%s", err)
    72  	}
    73  }
    74  
    75  // Test GET /users/create
    76  func TestShowCreateUser(t *testing.T) {
    77  
    78  	// Setup request and recorder
    79  	r := httptest.NewRequest("GET", "/users/create", nil)
    80  	w := httptest.NewRecorder()
    81  
    82  	// Set up user session cookie for admin user above
    83  	err := resource.AddUserSessionCookie(w, r, 1)
    84  	if err != nil {
    85  		t.Errorf("useractions: error setting session %s", err)
    86  	}
    87  
    88  	// Run the handler
    89  	err = HandleCreateShow(w, r)
    90  
    91  	// Test the error response
    92  	if err != nil || w.Code != http.StatusOK {
    93  		t.Errorf("useractions: error handling HandleCreateShow %s", err)
    94  	}
    95  
    96  	// Test the body for a known pattern
    97  	pattern := "resource-update-form"
    98  	if !strings.Contains(w.Body.String(), pattern) {
    99  		t.Errorf("useractions: unexpected response for HandleCreateShow expected:%s got:%s", pattern, w.Body.String())
   100  	}
   101  
   102  }
   103  
   104  // Test POST /users/create
   105  func TestCreateUser(t *testing.T) {
   106  
   107  	form := url.Values{}
   108  	form.Add("name", names[0])
   109  	body := strings.NewReader(form.Encode())
   110  
   111  	r := httptest.NewRequest("POST", "/users/create", body)
   112  	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
   113  	w := httptest.NewRecorder()
   114  
   115  	// Set up user session cookie for admin user
   116  	err := resource.AddUserSessionCookie(w, r, 1)
   117  	if err != nil {
   118  		t.Errorf("useractions: error setting session %s", err)
   119  	}
   120  
   121  	// Run the handler to update the user
   122  	err = HandleCreate(w, r)
   123  	if err != nil {
   124  		t.Errorf("useractions: error handling HandleCreate %s", err)
   125  	}
   126  
   127  	// Test we get a redirect after update (to the user concerned)
   128  	if w.Code != http.StatusFound {
   129  		t.Errorf("useractions: unexpected response code for HandleCreate expected:%d got:%d", http.StatusFound, w.Code)
   130  	}
   131  
   132  	// Check the user name is in now value names[1]
   133  	allUsers, err := users.FindAll(users.Query().Order("id desc"))
   134  	if err != nil || len(allUsers) == 0 {
   135  		t.Fatalf("useractions: error finding created user %s", err)
   136  	}
   137  	newUser := allUsers[0]
   138  	if newUser.ID < 2 || newUser.Name != names[0] {
   139  		t.Errorf("useractions: error with created user values: %v %s", newUser.ID, newUser.Name)
   140  	}
   141  }
   142  
   143  // Test GET /users
   144  func TestListUsers(t *testing.T) {
   145  
   146  	// Setup request and recorder
   147  	r := httptest.NewRequest("GET", "/users", nil)
   148  	w := httptest.NewRecorder()
   149  
   150  	// Set up user session cookie for admin user above
   151  	err := resource.AddUserSessionCookie(w, r, 1)
   152  	if err != nil {
   153  		t.Errorf("useractions: error setting session %s", err)
   154  	}
   155  
   156  	// Run the handler
   157  	err = HandleIndex(w, r)
   158  
   159  	// Test the error response
   160  	if err != nil || w.Code != http.StatusOK {
   161  		t.Errorf("useractions: error handling HandleIndex %s", err)
   162  	}
   163  
   164  	// Test the body for a known pattern
   165  	pattern := "data-table-head"
   166  	if !strings.Contains(w.Body.String(), pattern) {
   167  		t.Errorf("useractions: unexpected response for HandleIndex expected:%s got:%s", pattern, w.Body.String())
   168  	}
   169  
   170  }
   171  
   172  // Test of GET /users/1
   173  func TestShowUser(t *testing.T) {
   174  
   175  	// Setup request and recorder
   176  	r := httptest.NewRequest("GET", "/users/1", nil)
   177  	w := httptest.NewRecorder()
   178  
   179  	// Set up user session cookie for admin user above
   180  	err := resource.AddUserSessionCookie(w, r, 1)
   181  	if err != nil {
   182  		t.Errorf("useractions: error setting session %s", err)
   183  	}
   184  
   185  	// Run the handler
   186  	err = HandleShow(w, r)
   187  
   188  	// Test the error response
   189  	if err != nil || w.Code != http.StatusOK {
   190  		t.Errorf("useractions: error handling HandleShow %s", err)
   191  	}
   192  
   193  	// Test the body for a known pattern
   194  	pattern := names[0]
   195  	if !strings.Contains(w.Body.String(), names[0]) {
   196  		t.Errorf("useractions: unexpected response for HandleShow expected:%s got:%s", pattern, w.Body.String())
   197  	}
   198  }
   199  
   200  // Test GET /users/123/update
   201  func TestShowUpdateUser(t *testing.T) {
   202  
   203  	// Setup request and recorder
   204  	r := httptest.NewRequest("GET", "/users/1/update", nil)
   205  	w := httptest.NewRecorder()
   206  
   207  	// Set up user session cookie for admin user above
   208  	err := resource.AddUserSessionCookie(w, r, 1)
   209  	if err != nil {
   210  		t.Errorf("useractions: error setting session %s", err)
   211  	}
   212  
   213  	// Run the handler
   214  	err = HandleUpdateShow(w, r)
   215  
   216  	// Test the error response
   217  	if err != nil || w.Code != http.StatusOK {
   218  		t.Errorf("useractions: error handling HandleCreateShow %s", err)
   219  	}
   220  
   221  	// Test the body for a known pattern
   222  	pattern := "resource-update-form"
   223  	if !strings.Contains(w.Body.String(), pattern) {
   224  		t.Errorf("useractions: unexpected response for HandleCreateShow expected:%s got:%s", pattern, w.Body.String())
   225  	}
   226  
   227  }
   228  
   229  // Test POST /users/123/update
   230  func TestUpdateUser(t *testing.T) {
   231  
   232  	form := url.Values{}
   233  	form.Add("name", names[1])
   234  	body := strings.NewReader(form.Encode())
   235  
   236  	r := httptest.NewRequest("POST", "/users/1/update", body)
   237  	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
   238  	w := httptest.NewRecorder()
   239  
   240  	// Set up user session cookie for admin user
   241  	err := resource.AddUserSessionCookie(w, r, 1)
   242  	if err != nil {
   243  		t.Errorf("useractions: error setting session %s", err)
   244  	}
   245  
   246  	// Run the handler to update the user
   247  	err = HandleUpdate(w, r)
   248  	if err != nil {
   249  		t.Errorf("useractions: error handling HandleUpdateUser %s", err)
   250  	}
   251  
   252  	// Test we get a redirect after update (to the user concerned)
   253  	if w.Code != http.StatusFound {
   254  		t.Errorf("useractions: unexpected response code for HandleUpdateUser expected:%d got:%d", http.StatusFound, w.Code)
   255  	}
   256  
   257  	// Check the user name is in now value names[1]
   258  	user, err := users.Find(1)
   259  	if err != nil {
   260  		t.Fatalf("useractions: error finding updated user %s", err)
   261  	}
   262  	if user.ID != 1 || user.Name != names[1] {
   263  		t.Errorf("useractions: error with updated user values: %v", user)
   264  	}
   265  
   266  }
   267  
   268  // Test of POST /users/123/destroy
   269  func TestDeleteUser(t *testing.T) {
   270  
   271  	body := strings.NewReader(``)
   272  
   273  	// Now test deleting the user created above as admin
   274  	r := httptest.NewRequest("POST", "/users/2/destroy", body)
   275  	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
   276  	w := httptest.NewRecorder()
   277  
   278  	// Set up user session cookie for admin user
   279  	err := resource.AddUserSessionCookie(w, r, 1)
   280  	if err != nil {
   281  		t.Errorf("useractions: error setting session %s", err)
   282  	}
   283  
   284  	// Run the handler
   285  	err = HandleDestroy(w, r)
   286  
   287  	// Test the error response is 302 StatusFound
   288  	if err != nil {
   289  		t.Errorf("useractions: error handling HandleDestroy %s", err)
   290  	}
   291  
   292  	// Test we get a redirect after delete
   293  	if w.Code != http.StatusFound {
   294  		t.Errorf("useractions: unexpected response code for HandleDestroy expected:%d got:%d", http.StatusFound, w.Code)
   295  	}
   296  	// Now test as anon
   297  	r = httptest.NewRequest("POST", "/users/2/destroy", body)
   298  	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
   299  	w = httptest.NewRecorder()
   300  
   301  	// Run the handler to test failure as anon
   302  	err = HandleDestroy(w, r)
   303  	if err == nil { // failure expected
   304  		t.Errorf("useractions: unexpected response for HandleDestroy as anon, expected failure")
   305  	}
   306  
   307  }
   308  
   309  // Test GET /users/login
   310  func TestShowLogin(t *testing.T) {
   311  
   312  	// Setup request and recorder
   313  	r := httptest.NewRequest("GET", "/users/login", nil)
   314  	w := httptest.NewRecorder()
   315  
   316  	// Set up user session cookie for admin user above
   317  	err := resource.AddUserSessionCookie(w, r, 1)
   318  	if err != nil {
   319  		t.Errorf("useractions: error setting session %s", err)
   320  	}
   321  
   322  	// Run the handler
   323  	err = HandleLoginShow(w, r)
   324  
   325  	// Check for redirect as they are considered logged in
   326  	if err != nil || w.Code != http.StatusFound {
   327  		t.Errorf("useractions: error handling HandleLoginShow %s %d", err, w.Code)
   328  	}
   329  
   330  	// Setup new request and recorder with no session
   331  	r = httptest.NewRequest("GET", "/users/login", nil)
   332  	w = httptest.NewRecorder()
   333  
   334  	// Run the handler
   335  	err = HandleLoginShow(w, r)
   336  
   337  	// Test the error response
   338  	if err != nil || w.Code != http.StatusOK {
   339  		t.Errorf("useractions: error handling HandleLoginShow %s", err)
   340  	}
   341  
   342  	// Test the body for a known pattern
   343  	pattern := "password"
   344  	if !strings.Contains(w.Body.String(), pattern) {
   345  		t.Errorf("useractions: unexpected response for HandleLoginShow expected:%s got:%s", pattern, w.Body.String())
   346  	}
   347  
   348  }
   349  
   350  // Test POST /users/login
   351  func TestLogin(t *testing.T) {
   352  
   353  	// These need to match entries in the test db for this to work
   354  	form := url.Values{}
   355  	form.Add("email", "example@example.com")
   356  	form.Add("password", "Hunter2")
   357  	body := strings.NewReader(form.Encode())
   358  
   359  	// Test posting to the login link,
   360  	// we expect success as setup inserts this user
   361  	r := httptest.NewRequest("POST", "/users/login", body)
   362  	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
   363  	w := httptest.NewRecorder()
   364  
   365  	// Set up user session cookie for anon user (for the CSRF cookie token)
   366  	err := resource.AddUserSessionCookie(w, r, 0)
   367  	if err != nil {
   368  		t.Errorf("useractions: error setting session %s", err)
   369  	}
   370  
   371  	// Run the handler
   372  	err = HandleLogin(w, r)
   373  	if err != nil || w.Code != http.StatusFound {
   374  		t.Errorf("useractions: error on HandleLogin %s", err)
   375  	}
   376  
   377  }
   378  
   379  // Test POST /users/logout
   380  func TestLogout(t *testing.T) {
   381  
   382  	r := httptest.NewRequest("POST", "/users/logout", nil)
   383  	r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
   384  	w := httptest.NewRecorder()
   385  
   386  	// Set up user session cookie for admin user
   387  	err := resource.AddUserSessionCookie(w, r, 1)
   388  	if err != nil {
   389  		t.Errorf("useractions: error setting session %s", err)
   390  	}
   391  
   392  	// Run the handler
   393  	err = HandleLogout(w, r)
   394  	if err != nil {
   395  		t.Errorf("useractions: error on HandleLogout %s", err)
   396  	}
   397  
   398  	t.Logf("SESSION CLEAR: %s", w.Header().Get("Set-Cookie"))
   399  
   400  	t.Logf("SESSION AFTER: %s", w.Header())
   401  
   402  	// Check we've set an empty session on this outgoing writer
   403  	if !strings.Contains(string(w.Header().Get("Set-Cookie")), auth.SessionName+"=;") {
   404  		t.Errorf("useractions: error on HandleLogout - session not cleared")
   405  	}
   406  
   407  	// TODO - to better test this we should have an integration test with a server
   408  
   409  }