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