func TestLogout(t *testing.T) { client := apptesting.NewClient() creds := url.Values{ "name": {"bert_maklin_3"}, "password": {"my_password"}, } resp, _ := client.PostForm(regServer.URL.String(), creds) resp.Body.Close() resp, err := client.PostForm(logoutServer.URL.String(), nil) if err != nil { panic(err) } resp.Body.Close() if ok || cu != nil { t.Fatal("Logout должен выполнять успешный выход") } client.ClearCookie() t.Log("Запускаю Logout с пустыми куки...") resp, err = client.PostForm(logoutServer.URL.String(), nil) if err != nil { panic(err) } resp.Body.Close() }
func TestFind(t *testing.T) { cr := cred{"find_tester", "qwerty1234567"} client := apptesting.NewClient() u := prepareTest(t, client, &cr) fu, ok := Find(cr.name) if !ok { t.Fatalf("Find не нашел существующего пользователя: %q", cr.name) } if fu == nil { t.Fatal("Find вернул nil, true") } if fu.ID != u.ID { t.Fatalf("Find нашел не того пользователя. Найден %v, ожидался %v.", fu.ID, u.ID) } cr2 := cred{"find_inexisting_tester", "qwerty1234567"} fu, ok = Find(cr2.name) if ok { t.Fatalf("Find вернул true при поиске несуществующегося пользователя: %q", cr2.name) } if fu != nil { t.Fatalf("Find вернул %#v, false", fu) } }
func TestUser_AutoLogin(t *testing.T) { // Подготовить данные для тестовых входов cr := cred{"autologin_tester", "qwerty1234567"} client := apptesting.NewClient() u := prepareTest(t, client, &cr) // Запуск AutoLogin на "чистом" клиенте client.ClearCookie() autoLoginWith(client, u) runFromContext(client) if !lastOk { t.Fatalf("AutoLogin() должно выполнять успешный вход (FromContext() вернуло false)") } if lastUser == nil { t.Fatalf("AutoLogin() должно выполнять успешный вход (FromContext() вернуло nil, true)") } if lastUser.Name != cr.name { t.Errorf("AutoLogin() должно выполнять вход с правильными данными. Ожидалось %q, получено %q.", cr.name, lastUser.Name) } // Запуск AutoLogin на "занятом" клиенте autoLoginWith(client, u) runFromContext(client) if !lastOk { t.Fatalf("AutoLogin() должно выполнять успешный вход с перезаписью (FromContext() вернуло false)") } if lastUser == nil { t.Fatalf("AutoLogin() должно выполнять успешный вход с перезаписью (FromContext() вернуло nil, true)") } if lastUser.Name != cr.name { t.Errorf("AutoLogin() должно выполнять вход с перезаписью с правильными данными. Ожидалось %q, получено %q.", cr.name, lastUser.Name) } }
func TestCookieStoring(t *testing.T) { sess := FromContext(nil) if sess != nil { t.Error("FromContext должна возвращать нулевую сессию для нулевого контекста.") } client := apptesting.NewClient() sess1 := retrieveSession(client) sess2 := retrieveSession(client) client.ClearCookie() sess3 := retrieveSession(client) // Проверки if sess1 == nil || sess3 == nil { t.Fatal("Сессия должна быть создана, если не найден ключ сессии в куки.") } if sess2 == nil { t.Fatal("Сессия должна быть получена, если ключ найден в куки.") } if sess1.ID() != sess2.ID() { t.Error("Сессии от одинаковых куки должны быть одинаковыми.") } if sess1.ID() == sess3.ID() || sess2.ID() == sess3.ID() { t.Error("Сессии от разных куки должны быть разными.") } }
func TestCountNPages(t *testing.T) { client := apptesting.NewClient() for i := 0; i < 20; i++ { cr := cred{fmt.Sprintf("pages_tester_%v", i), "qwerty12121212"} prepareTest(t, client, &cr) } n := Count() if n < 20 { t.Errorf("Count вернуло %v, хотя было создано не менее 20 пользователей", n) } p5n := Pages(5) if p5n*5 < n { t.Errorf("Pages(5) вернуло %v при %v пользователях", p5n, n) } arr := FindPage(p5n+1, 5, ByID) if len(arr) > 0 { t.Errorf("FindPage вернуло непустой слайс для несущ. страницы: %v", arr) } checkSort := func(sm SortMode, wrongOrd func(a, b *User) bool) { p := 1 if p5n > 1 { p = rand.Intn(p5n - 1) } arr = FindPage(p, 5, sm) if len(arr) < 5 { t.Errorf("FindPage(%v, 5, %q) вернуло слайс короче 5 (%v), хотя страница гарантировано заполнена", p, sm, len(arr)) } for i := 0; i < len(arr)-1; i++ { if wrongOrd(arr[i], arr[i+1]) { t.Errorf("FindPage(%v, 5, %q) вернуло неверно отсортированную страницу: %v", p, sm, arr) break } } } checkSort(ByID, func(a, b *User) bool { return a.ID > b.ID }) checkSort(ByName, func(a, b *User) bool { return a.Name > b.Name }) checkSort(ByCreatedAt, func(a, b *User) bool { return a.CreatedAt.Unix() > b.CreatedAt.Unix() }) checkSort(ByIDDesc, func(a, b *User) bool { return b.ID > a.ID }) checkSort(ByNameDesc, func(a, b *User) bool { return b.Name > a.Name }) checkSort(ByCreatedAtDesc, func(a, b *User) bool { return b.CreatedAt.Unix() > a.CreatedAt.Unix() }) }
func TestLogin(t *testing.T) { client := apptesting.NewClient() creds := url.Values{ "name": {"bert_maklin_2"}, "password": {"my_password"}, } resp, _ := client.PostForm(regServer.URL.String(), creds) resp.Body.Close() client.ClearCookie() resp, err := client.PostForm(loginServer.URL.String(), creds) if err != nil { panic(err) } resp.Body.Close() if !ok || cu == nil { t.Fatal("Login должен выполнять успешный вход") } if cu.Name != creds.Get("name") { t.Errorf("Login должен выполнять вход под правильным именем. Ожидалось %v, получено %v.", creds.Get("name"), cu.Name) } client.ClearCookie() creds2 := url.Values{ "name": {"bert_maklin_2"}, "password": {"my_passworddd"}, } resp, err = client.PostForm(loginServer.URL.String(), creds2) if err != nil { panic(err) } resp.Body.Close() if ok || cu != nil { t.Fatal("Login не должен выполнять вход с ошибочными данными") } }
func TestUser_Destroy(t *testing.T) { // Подготовить данные для тестовых входов cr := cred{"destroy_tester", "qwerty1234567"} client := apptesting.NewClient() u := prepareTest(t, client, &cr) // Проверка FromContext после удаления пользователя u.Destroy() runFromContext(client) if lastOk || lastUser != nil { t.Error("Destroy() должно делать данные об аутентификации пользователя недоступными") } // Проверка регистрации после удаления cr.pass = "******" client.ClearCookie() u, err := Register(cr.name, cr.pass) if u == nil || err != nil { t.Fatal("Перерегистрация удаленного пользователя должна проходить успешно") } // Проверка входа после удаления u.Destroy() loginWith(client, &cr) if lastOk || lastUser != nil { t.Error("Destroy() должно делать вход невозможным") } // Проверка AutoLogin после удаления client.ClearCookie() u, err = Register(cr.name, cr.pass) if u == nil || err != nil { t.Fatal("Перерегистрация удаленного пользователя должна проходить успешно") } u.Destroy() autoLoginWith(client, u) if lastOk || lastUser != nil { t.Error("Destroy() должно делать AutoLogin невозможным") } }
func TestLogout(t *testing.T) { // Подготовить данные для тестовых входов cr := cred{"logout_tester", "qwerty1234567"} client := apptesting.NewClient() prepareTest(t, client, &cr) // Вызов Logout после успешного входа runLogout(client) runFromContext(client) if lastOk || lastUser != nil { t.Error("Logout() должно стирать данные об аутентификации пользователя") } // Вызов Logout с пустыми куками client.ClearCookie() t.Log("Logout() должно корректно реагировать на отсутствие аутентификации") runLogout(client) runFromContext(client) if lastOk || lastUser != nil { t.Error("Logout() должно корректно реагировать на отсутствие аутентификации") } }
func TestDoubleFromContext(t *testing.T) { client := apptesting.NewClient() resp, err := client.Get(dsServer.URL.String()) if err != nil { panic(err) } resp.Body.Close() if session.ID() != session2.ID() { t.Error("Двойной вызов FromContext на чистом клиенте отдал разные сессии") } resp, err = client.Get(dsServer.URL.String()) if err != nil { panic(err) } resp.Body.Close() if session.ID() != session2.ID() { t.Error("Двойной вызов FromContext отдал разные сессии") } }
func TestDestroy(t *testing.T) { client := apptesting.NewClient() creds := url.Values{ "name": {"bert_maklin_4"}, "password": {"my_password"}, } resp, _ := client.PostForm(regServer.URL.String(), creds) resp.Body.Close() resp, err := client.PostForm(desServer.URL.String(), nil) if err != nil { panic(err) } resp.Body.Close() if ok || cu != nil { t.Fatal("Destroy должен стирать данные об аутентификации") } resp, _ = client.PostForm(loginServer.URL.String(), creds) resp.Body.Close() if ok || cu != nil { t.Fatal("Destroy должен делать последующий вход невозможным") } }
func TestRoles(t *testing.T) { defCr := cred{"default_role_user", "qwerty1234567"} admCr := cred{"admin_user", "qwerty1234567"} client := apptesting.NewClient() defu := prepareTest(t, client, &defCr) if defu.Admin() { t.Error("Пользователь с незаданной ролью оказался админом.") } adm := prepareTest(t, client, &admCr) adm.SetRole(AdminRole) if !adm.Admin() { t.Errorf("Admin вернуло false при вызове на админе: %#v", adm) } adm1, _ := Find(adm.Name) if adm1 == nil { t.Fatalf("Find работает некорректно") } if !adm1.Admin() { t.Error("SetRole не сохранил роль в базу") } }
func TestRegister(t *testing.T) { client := apptesting.NewClient() creds := url.Values{ "name": {"bert_maklin"}, "password": {"my_password"}, } resp, err := client.PostForm(regServer.URL.String(), creds) if err != nil { panic(err) } resp.Body.Close() if !ok || cu == nil { t.Fatal("Register должен выполнять успешную регистрацию и вход") } if cu.Name != creds.Get("name") { t.Errorf("Register должен выполнять регистрацию под правильным именем. Ожидалось %v, получено %v.", creds.Get("name"), cu.Name) } creds1 := url.Values{ "name": {"bert_maklin_rereg"}, "password": {"my_password"}, } resp, err = client.PostForm(regServer.URL.String(), creds1) if err != nil { panic(err) } resp.Body.Close() if !ok || cu == nil { t.Fatal("Register не должен перезаписывать сессию") } if cu.Name != creds.Get("name") { t.Errorf("Register не должен перезаписывать сессию. Ожидалось %v, получено %v.", creds.Get("name"), cu.Name) } client.ClearCookie() resp, _ = client.PostForm(loginServer.URL.String(), creds1) resp.Body.Close() if ok || cu != nil { t.Error("Register не должен выполнять регистрацию при попытке перезаписи сессии") } client.ClearCookie() creds2 := url.Values{ "name": {""}, "password": {""}, } resp, err = client.PostForm(regServer.URL.String(), creds2) if err != nil { panic(err) } resp.Body.Close() if ok || cu != nil { t.Fatal("Register не должен выполнять регистрацию ошибочных данных") } }
func TestLoginFromContext(t *testing.T) { // Подготовить данные для тестовых входов cr := cred{"login_tester", "qwerty1234567"} u, err := Register(cr.name, cr.pass) if u == nil || err != nil { t.Fatal("Register должно работать корректно") } cr2 := cred{"login_tester_2", "qwerty1234567"} u, err = Register(cr2.name, cr2.pass) if u == nil || err != nil { t.Fatal("Register должно работать корректно") } cr3 := cred{} client := apptesting.NewClient() // Login с корректными данными loginWith(client, &cr) if !lastOk { t.Fatalf("Login() должно сообщать об успешной авторизации при получении корректных данных для входа (%#v)", cr) } if lastUser == nil { t.Fatalf("Login() не должно возвращать нулевой указатель в случае успешного входа (%#v)", cr) } if lastUser.Name != cr.name { t.Errorf("Login() должно возвращать правильную структуру. Ожидалось %q, получено %q.", cr.name, lastUser.Name) } // FromContext после корректного входа runFromContext(client) if !lastOk { t.Fatal("FromContext() должно сообщать об успехе после Login.") } if lastUser == nil { t.Fatalf("FromContext() не должно возвращать нулевой указатель в случае успешного входа (%#v)", cr) } if lastUser.Name != cr.name { t.Errorf("FromContext() должно возвращать правильную структуру. Ожидалось %q, получено %q.", cr.name, lastUser.Name) } // FromContext при пустых куки client.ClearCookie() runFromContext(client) if lastOk { t.Fatal("FromContext() должно сообщать о неуспехе при пустых куки.") } if lastUser != nil { t.Fatalf("FromContext() не должно возвращать структуру пользователя при пустых куки") } // Login с неверным паролем cr3 = cr cr3.pass = "******" loginWith(client, &cr3) if lastOk { t.Fatal("Login() должно сообщать о неуспехе при неверном пароле.") } if lastUser != nil { t.Fatalf("Login() не должно возвращать структуру пользователя при неверном пароле") } // FromContext после неверного пароля runFromContext(client) if lastOk { t.Fatal("FromContext() должно сообщать о неуспехе после вызова Login() с неверным паролем.") } if lastUser != nil { t.Fatalf("FromContext() не должно возвращать структуру пользователя после вызова Login() с неверным паролем") } // Login с неверным никнеймом cr3 = cr cr3.name = "undefined_user" loginWith(client, &cr3) if lastOk { t.Fatal("Login() должно сообщать о неуспехе при неверном никнейме.") } if lastUser != nil { t.Fatalf("Login() не должно возвращать структуру пользователя при неверном никнейме") } // Проверка перезаписи данных Login`ом loginWith(client, &cr) loginWith(client, &cr2) if !lastOk { t.Fatalf("Login() должно сообщать об успешной авторизации после записи входа (%#v)", cr) } if lastUser == nil { t.Fatalf("Login() не должно возвращать нулевой указатель после перезаписи входа (%#v)", cr) } if lastUser.Name != cr2.name { t.Errorf("Login() должно возвращать правильную структуру после перезаписи входа. Ожидалось %q, получено %q.", cr2.name, lastUser.Name) } }
func TestDataStoring(t *testing.T) { client := apptesting.NewClient() ints := map[string]int{ "int1": 12, "second int": 34, } missingInt := "missInt" // TODO: Тесты для всех поддерживаемых типов. // floats := map[string]float64{ // "float1": 12.04, // "second float": 3.14, // } // missingFloat := "missFloat" // // bytes := map[string][]byte{ // "slice1": {1, 2, 3, 12}, // "second slice": {}, // } // missingBytes := "missBytes" // // strings := map[string]string{ // "hello": "world", // "username": "******", // } // missingString := "missString" sess := retrieveSession(client) if sess == nil { t.Fatal("Сессия не должна быть nil.") } for key, val := range ints { assertIntKey(t, "Пустая сессия не должна содержать значений int.", sess, key, 0) sess.SetInt(key, val) } sess.SetInt("", 89) sess = retrieveSession(client) if sess == nil { t.Fatal("Сессия не должна быть nil.") } for key, val := range ints { assertIntKey(t, "Сессия должна сохранять значения int.", sess, key, val) } assertIntKey(t, "Сессия должна возвращать 0 для незаданных значений.", sess, missingInt, 0) assertIntKey(t, "Значения с пустыми ключами не должны сохраняться.", sess, "", 0) // Обнуление куки. client.ClearCookie() sess = retrieveSession(client) if sess == nil { t.Fatal("Сессия не должна быть nil.") } sess.SetInt(missingInt, 12) sess = retrieveSession(client) if sess == nil { t.Fatal("Сессия не должна быть nil.") } for key := range ints { assertIntKey(t, "Сессия не должна возвращать значения чужой сессии.", sess, key, 0) } assertIntKey(t, "Сессия должна сохранять значения int.", sess, missingInt, 12) }