2017-04-25 10:24:51 +03:00
// Copyright 2017 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package integrations
import (
"bytes"
2017-04-30 09:30:12 +03:00
"database/sql"
2017-04-25 10:24:51 +03:00
"fmt"
"io"
2017-04-30 09:30:12 +03:00
"log"
2017-04-25 10:24:51 +03:00
"net/http"
2017-05-02 03:49:55 +03:00
"net/http/cookiejar"
"net/url"
2017-04-25 10:24:51 +03:00
"os"
2017-06-09 21:13:46 +03:00
"path"
2017-05-02 03:49:55 +03:00
"strings"
2017-04-25 10:24:51 +03:00
"testing"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/routers"
"code.gitea.io/gitea/routers/routes"
2017-04-28 16:23:28 +03:00
"github.com/Unknwon/com"
"github.com/stretchr/testify/assert"
2017-04-25 10:24:51 +03:00
"gopkg.in/macaron.v1"
"gopkg.in/testfixtures.v2"
)
var mac * macaron . Macaron
func TestMain ( m * testing . M ) {
2017-04-30 09:30:12 +03:00
initIntegrationTest ( )
2017-04-25 10:24:51 +03:00
mac = routes . NewMacaron ( )
routes . RegisterRoutes ( mac )
var helper testfixtures . Helper
if setting . UseMySQL {
helper = & testfixtures . MySQL { }
} else if setting . UsePostgreSQL {
helper = & testfixtures . PostgreSQL { }
} else if setting . UseSQLite3 {
helper = & testfixtures . SQLite { }
} else {
fmt . Println ( "Unsupported RDBMS for integration tests" )
os . Exit ( 1 )
}
err := models . InitFixtures (
helper ,
2017-04-28 16:23:28 +03:00
"models/fixtures/" ,
2017-04-25 10:24:51 +03:00
)
if err != nil {
fmt . Printf ( "Error initializing test database: %v\n" , err )
os . Exit ( 1 )
}
os . Exit ( m . Run ( ) )
}
2017-04-30 09:30:12 +03:00
func initIntegrationTest ( ) {
2017-06-10 05:27:13 +03:00
giteaRoot := os . Getenv ( "GITEA_ROOT" )
if giteaRoot == "" {
fmt . Println ( "Environment variable $GITEA_ROOT not set" )
2017-04-30 09:30:12 +03:00
os . Exit ( 1 )
}
2017-06-10 05:27:13 +03:00
setting . AppPath = path . Join ( giteaRoot , "gitea" )
giteaConf := os . Getenv ( "GITEA_CONF" )
if giteaConf == "" {
fmt . Println ( "Environment variable $GITEA_CONF not set" )
2017-05-02 03:49:55 +03:00
os . Exit ( 1 )
2017-06-10 05:27:13 +03:00
} else if ! path . IsAbs ( giteaConf ) {
setting . CustomConf = path . Join ( giteaRoot , giteaConf )
2017-06-09 21:13:46 +03:00
} else {
2017-06-10 05:27:13 +03:00
setting . CustomConf = giteaConf
2017-05-02 03:49:55 +03:00
}
2017-04-30 09:30:12 +03:00
setting . NewContext ( )
models . LoadConfigs ( )
switch {
case setting . UseMySQL :
db , err := sql . Open ( "mysql" , fmt . Sprintf ( "%s:%s@tcp(%s)/" ,
models . DbCfg . User , models . DbCfg . Passwd , models . DbCfg . Host ) )
defer db . Close ( )
if err != nil {
log . Fatalf ( "sql.Open: %v" , err )
}
if _ , err = db . Exec ( "CREATE DATABASE IF NOT EXISTS testgitea" ) ; err != nil {
log . Fatalf ( "db.Exec: %v" , err )
}
case setting . UsePostgreSQL :
db , err := sql . Open ( "postgres" , fmt . Sprintf ( "postgres://%s:%s@%s/?sslmode=%s" ,
models . DbCfg . User , models . DbCfg . Passwd , models . DbCfg . Host , models . DbCfg . SSLMode ) )
defer db . Close ( )
if err != nil {
log . Fatalf ( "sql.Open: %v" , err )
}
rows , err := db . Query ( fmt . Sprintf ( "SELECT 1 FROM pg_database WHERE datname = '%s'" ,
models . DbCfg . Name ) )
if err != nil {
log . Fatalf ( "db.Query: %v" , err )
}
2017-05-08 05:55:27 +03:00
defer rows . Close ( )
2017-05-09 16:42:55 +03:00
if rows . Next ( ) {
2017-05-11 18:32:43 +03:00
break
2017-04-30 09:30:12 +03:00
}
2017-05-09 16:42:55 +03:00
if _ , err = db . Exec ( "CREATE DATABASE testgitea" ) ; err != nil {
log . Fatalf ( "db.Exec: %v" , err )
}
2017-04-30 09:30:12 +03:00
}
routers . GlobalInit ( )
}
2017-04-28 16:23:28 +03:00
func prepareTestEnv ( t * testing . T ) {
assert . NoError ( t , models . LoadFixtures ( ) )
assert . NoError ( t , os . RemoveAll ( "integrations/gitea-integration" ) )
assert . NoError ( t , com . CopyDir ( "integrations/gitea-integration-meta" , "integrations/gitea-integration" ) )
}
2017-05-02 03:49:55 +03:00
type TestSession struct {
jar http . CookieJar
}
func ( s * TestSession ) GetCookie ( name string ) * http . Cookie {
baseURL , err := url . Parse ( setting . AppURL )
if err != nil {
return nil
}
for _ , c := range s . jar . Cookies ( baseURL ) {
if c . Name == name {
return c
}
}
return nil
}
func ( s * TestSession ) MakeRequest ( t * testing . T , req * http . Request ) * TestResponse {
baseURL , err := url . Parse ( setting . AppURL )
assert . NoError ( t , err )
for _ , c := range s . jar . Cookies ( baseURL ) {
req . AddCookie ( c )
}
resp := MakeRequest ( req )
ch := http . Header { }
ch . Add ( "Cookie" , strings . Join ( resp . Headers [ "Set-Cookie" ] , ";" ) )
cr := http . Request { Header : ch }
s . jar . SetCookies ( baseURL , cr . Cookies ( ) )
return resp
}
func loginUser ( t * testing . T , userName , password string ) * TestSession {
req , err := http . NewRequest ( "GET" , "/user/login" , nil )
assert . NoError ( t , err )
resp := MakeRequest ( req )
assert . EqualValues ( t , http . StatusOK , resp . HeaderCode )
doc , err := NewHtmlParser ( resp . Body )
assert . NoError ( t , err )
req , err = http . NewRequest ( "POST" , "/user/login" ,
bytes . NewBufferString ( url . Values {
"_csrf" : [ ] string { doc . GetInputValueByName ( "_csrf" ) } ,
"user_name" : [ ] string { userName } ,
"password" : [ ] string { password } ,
} . Encode ( ) ) ,
)
assert . NoError ( t , err )
req . Header . Add ( "Content-Type" , "application/x-www-form-urlencoded" )
resp = MakeRequest ( req )
assert . EqualValues ( t , http . StatusFound , resp . HeaderCode )
ch := http . Header { }
ch . Add ( "Cookie" , strings . Join ( resp . Headers [ "Set-Cookie" ] , ";" ) )
cr := http . Request { Header : ch }
jar , err := cookiejar . New ( nil )
assert . NoError ( t , err )
baseURL , err := url . Parse ( setting . AppURL )
assert . NoError ( t , err )
jar . SetCookies ( baseURL , cr . Cookies ( ) )
return & TestSession { jar : jar }
}
2017-04-25 10:24:51 +03:00
type TestResponseWriter struct {
HeaderCode int
Writer io . Writer
2017-05-02 03:49:55 +03:00
Headers http . Header
2017-04-25 10:24:51 +03:00
}
func ( w * TestResponseWriter ) Header ( ) http . Header {
2017-05-02 03:49:55 +03:00
return w . Headers
2017-04-25 10:24:51 +03:00
}
func ( w * TestResponseWriter ) Write ( b [ ] byte ) ( int , error ) {
return w . Writer . Write ( b )
}
func ( w * TestResponseWriter ) WriteHeader ( n int ) {
w . HeaderCode = n
}
type TestResponse struct {
HeaderCode int
Body [ ] byte
2017-05-02 03:49:55 +03:00
Headers http . Header
2017-04-25 10:24:51 +03:00
}
func MakeRequest ( req * http . Request ) * TestResponse {
buffer := bytes . NewBuffer ( nil )
respWriter := & TestResponseWriter {
2017-05-02 03:49:55 +03:00
Writer : buffer ,
Headers : make ( map [ string ] [ ] string ) ,
2017-04-25 10:24:51 +03:00
}
mac . ServeHTTP ( respWriter , req )
return & TestResponse {
HeaderCode : respWriter . HeaderCode ,
Body : buffer . Bytes ( ) ,
2017-05-02 03:49:55 +03:00
Headers : respWriter . Headers ,
2017-04-25 10:24:51 +03:00
}
}