diff --git a/internal/web/__snapshots__/web.snapshot b/internal/web/__snapshots__/web.snapshot
index 3e17bb39..1bb77d30 100644
--- a/internal/web/__snapshots__/web.snapshot
+++ b/internal/web/__snapshots__/web.snapshot
@@ -32,6 +32,15 @@ Location: /foobar/login
Temporary Redirect.
+/* snapshot: Test_createRoutes_simple_redirect */
+HTTP/1.1 307 Temporary Redirect
+Connection: close
+Content-Security-Policy: default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' gravatar.com data:; manifest-src 'self'; connect-src 'self' api.github.com;
+Content-Type: text/html; charset=utf-8
+Location: /login
+
+Temporary Redirect.
+
/* snapshot: Test_createRoutes_username_password */
HTTP/1.1 307 Temporary Redirect
Connection: close
diff --git a/internal/web/routes_simple_test.go b/internal/web/routes_simple_test.go
new file mode 100644
index 00000000..2833db2e
--- /dev/null
+++ b/internal/web/routes_simple_test.go
@@ -0,0 +1,132 @@
+package web
+
+import (
+ "bytes"
+ "io"
+ "mime/multipart"
+ "net/http"
+ "net/http/httptest"
+ "strings"
+
+ "testing"
+
+ "github.com/amir20/dozzle/internal/auth"
+ "github.com/beme/abide"
+ "github.com/magiconair/properties/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/spf13/afero"
+)
+
+func Test_createRoutes_simple_redirect(t *testing.T) {
+ fs := afero.NewMemMapFs()
+ require.NoError(t, afero.WriteFile(fs, "index.html", []byte("index page"), 0644), "WriteFile should have no error.")
+
+ handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/",
+ Authorization: Authorization{
+ Provider: SIMPLE,
+ Authorizer: auth.NewSimpleAuth(auth.UserDatabase{
+ Users: map[string]*auth.User{
+ "amir": {
+ Username: "amir",
+ Password: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
+ },
+ },
+ }),
+ },
+ })
+ req, err := http.NewRequest("GET", "/", nil)
+ require.NoError(t, err, "NewRequest should not return an error.")
+ rr := httptest.NewRecorder()
+
+ handler.ServeHTTP(rr, req)
+ abide.AssertHTTPResponse(t, t.Name(), rr.Result())
+}
+
+func Test_createRoutes_simple_valid_token(t *testing.T) {
+ fs := afero.NewMemMapFs()
+ require.NoError(t, afero.WriteFile(fs, "index.html", []byte("index page"), 0644), "WriteFile should have no error.")
+
+ handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/",
+ Authorization: Authorization{
+ Provider: SIMPLE,
+ Authorizer: auth.NewSimpleAuth(auth.UserDatabase{
+ Users: map[string]*auth.User{
+ "amir": {
+ Username: "amir",
+ Password: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
+ },
+ },
+ }),
+ },
+ })
+
+ body := &bytes.Buffer{}
+ writer := multipart.NewWriter(body)
+
+ fw, err := writer.CreateFormField("username")
+ require.NoError(t, err, "Creating field should not be error.")
+ _, err = io.Copy(fw, strings.NewReader("amir"))
+ require.NoError(t, err, "Copying field should not result in error.")
+
+ fw, err = writer.CreateFormField("password")
+ require.NoError(t, err, "Creating field should not be error.")
+ _, err = io.Copy(fw, strings.NewReader("password"))
+ require.NoError(t, err, "Copying field should not result in error.")
+
+ writer.Close()
+
+ req, err := http.NewRequest("POST", "/api/token", bytes.NewReader(body.Bytes()))
+ req.Header.Set("Content-Type", writer.FormDataContentType())
+
+ require.NoError(t, err, "NewRequest should not return an error.")
+ rr := httptest.NewRecorder()
+ handler.ServeHTTP(rr, req)
+
+ assert.Equal(t, rr.Code, 200)
+ cookie := rr.Header().Get("Set-Cookie")
+ assert.Matches(t, cookie, "jwt=.+")
+}
+
+func Test_createRoutes_simple_bad_password(t *testing.T) {
+ fs := afero.NewMemMapFs()
+ require.NoError(t, afero.WriteFile(fs, "index.html", []byte("index page"), 0644), "WriteFile should have no error.")
+
+ handler := createHandler(nil, afero.NewIOFS(fs), Config{Base: "/",
+ Authorization: Authorization{
+ Provider: SIMPLE,
+ Authorizer: auth.NewSimpleAuth(auth.UserDatabase{
+ Users: map[string]*auth.User{
+ "amir": {
+ Username: "amir",
+ Password: "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
+ },
+ },
+ }),
+ },
+ })
+
+ body := &bytes.Buffer{}
+ writer := multipart.NewWriter(body)
+
+ fw, err := writer.CreateFormField("username")
+ require.NoError(t, err, "Creating field should not be error.")
+ _, err = io.Copy(fw, strings.NewReader("amir"))
+ require.NoError(t, err, "Copying field should not result in error.")
+
+ fw, err = writer.CreateFormField("badpassword")
+ require.NoError(t, err, "Creating field should not be error.")
+ _, err = io.Copy(fw, strings.NewReader("password"))
+ require.NoError(t, err, "Copying field should not result in error.")
+
+ writer.Close()
+
+ req, err := http.NewRequest("POST", "/api/token", bytes.NewReader(body.Bytes()))
+ req.Header.Set("Content-Type", writer.FormDataContentType())
+
+ require.NoError(t, err, "NewRequest should not return an error.")
+ rr := httptest.NewRecorder()
+ handler.ServeHTTP(rr, req)
+
+ assert.Equal(t, rr.Code, 401, "Response code should be 401.")
+}