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 }