github.com/solongordon/pop@v4.10.0+incompatible/dialect_mysql_test.go (about)

     1  package pop
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/gobuffalo/fizz"
    10  	"github.com/gobuffalo/fizz/translators"
    11  	"github.com/stretchr/testify/require"
    12  )
    13  
    14  func Test_MySQL_URL_As_Is(t *testing.T) {
    15  	r := require.New(t)
    16  
    17  	cd := &ConnectionDetails{
    18  		URL: "mysql://user:pass@(host:port)/dbase?opt=value",
    19  	}
    20  	err := cd.Finalize()
    21  	r.NoError(err)
    22  
    23  	m := &mysql{commonDialect{ConnectionDetails: cd}}
    24  	r.Equal("user:pass@(host:port)/dbase?opt=value", m.URL())
    25  	r.Equal("user:pass@(host:port)/?opt=value", m.urlWithoutDb())
    26  	r.Equal("user:pass@(host:port)/dbase?opt=value", m.MigrationURL())
    27  }
    28  
    29  func Test_MySQL_URL_Override_withURL(t *testing.T) {
    30  	r := require.New(t)
    31  
    32  	cd := &ConnectionDetails{
    33  		Database: "xx",
    34  		Host:     "xx",
    35  		Port:     "xx",
    36  		User:     "xx",
    37  		Password: "xx",
    38  		URL:      "mysql://user:pass@(host:port)/dbase?opt=value",
    39  	}
    40  	err := cd.Finalize()
    41  	r.NoError(err)
    42  
    43  	m := &mysql{commonDialect{ConnectionDetails: cd}}
    44  	r.Equal("user:pass@(host:port)/dbase?opt=value", m.URL())
    45  	r.Equal("user:pass@(host:port)/?opt=value", m.urlWithoutDb())
    46  	r.Equal("user:pass@(host:port)/dbase?opt=value", m.MigrationURL())
    47  }
    48  
    49  func Test_MySQL_URL_With_Values(t *testing.T) {
    50  	r := require.New(t)
    51  	m := &mysql{commonDialect{ConnectionDetails: &ConnectionDetails{
    52  		Database: "dbase",
    53  		Host:     "host",
    54  		Port:     "port",
    55  		User:     "user",
    56  		Password: "pass",
    57  		Options:  map[string]string{"opt": "value"},
    58  	}}}
    59  	r.Equal("user:pass@(host:port)/dbase?opt=value", m.URL())
    60  	r.Equal("user:pass@(host:port)/?opt=value", m.urlWithoutDb())
    61  	r.Equal("user:pass@(host:port)/dbase?opt=value", m.MigrationURL())
    62  }
    63  
    64  func Test_MySQL_URL_Without_User(t *testing.T) {
    65  	r := require.New(t)
    66  	m := &mysql{commonDialect{ConnectionDetails: &ConnectionDetails{
    67  		Password: "pass",
    68  		Database: "dbase",
    69  	}}}
    70  	// finalizerMySQL fills address part in real world.
    71  	// without user, password cannot live alone
    72  	r.Equal("(:)/dbase?", m.URL())
    73  }
    74  
    75  func Test_MySQL_URL_Without_Password(t *testing.T) {
    76  	r := require.New(t)
    77  	m := &mysql{commonDialect{ConnectionDetails: &ConnectionDetails{
    78  		User:     "user",
    79  		Database: "dbase",
    80  	}}}
    81  	// finalizerMySQL fills address part in real world.
    82  	r.Equal("user@(:)/dbase?", m.URL())
    83  }
    84  
    85  func Test_MySQL_URL_urlParserMySQL_Standard(t *testing.T) {
    86  	r := require.New(t)
    87  	cd := &ConnectionDetails{
    88  		URL: "mysql://user:pass@(host:port)/database?collation=utf8&param2=value2",
    89  	}
    90  	err := urlParserMySQL(cd)
    91  	r.NoError(err)
    92  	r.Equal("user", cd.User)
    93  	r.Equal("pass", cd.Password)
    94  	r.Equal("host", cd.Host)
    95  	r.Equal("port", cd.Port)
    96  	r.Equal("database", cd.Database)
    97  	// only collation is stored as options by urlParserMySQL()
    98  	r.Equal("utf8", cd.Options["collation"])
    99  	r.Equal("", cd.Options["param2"])
   100  }
   101  
   102  func Test_MySQL_URL_urlParserMySQL_With_Protocol(t *testing.T) {
   103  	r := require.New(t)
   104  	cd := &ConnectionDetails{
   105  		URL: "user:pass@tcp(host:port)/dbase",
   106  	}
   107  	err := urlParserMySQL(cd)
   108  	r.NoError(err)
   109  	r.Equal("user", cd.User)
   110  	r.Equal("pass", cd.Password)
   111  	r.Equal("host", cd.Host)
   112  	r.Equal("port", cd.Port)
   113  	r.Equal("dbase", cd.Database)
   114  }
   115  
   116  func Test_MySQL_URL_urlParserMySQL_Socket(t *testing.T) {
   117  	r := require.New(t)
   118  	cd := &ConnectionDetails{
   119  		URL: "unix(/tmp/socket)/dbase",
   120  	}
   121  	err := urlParserMySQL(cd)
   122  	r.NoError(err)
   123  	r.Equal("/tmp/socket", cd.Host)
   124  	r.Equal("socket", cd.Port)
   125  
   126  	// additional test without URL
   127  	cd.URL = ""
   128  	m := &mysql{commonDialect{ConnectionDetails: cd}}
   129  	r.True(strings.HasPrefix(m.URL(), "unix(/tmp/socket)/dbase?"))
   130  	r.True(strings.HasPrefix(m.urlWithoutDb(), "unix(/tmp/socket)/?"))
   131  }
   132  
   133  func Test_MySQL_URL_urlParserMySQL_Unsupported(t *testing.T) {
   134  	r := require.New(t)
   135  	cd := &ConnectionDetails{
   136  		URL: "mysql://user:pass@host:port/dbase?opt=value",
   137  	}
   138  	err := urlParserMySQL(cd)
   139  	r.Error(err)
   140  }
   141  
   142  func Test_MySQL_Database_Open_Failure(t *testing.T) {
   143  	r := require.New(t)
   144  	m := &mysql{commonDialect{ConnectionDetails: &ConnectionDetails{}}}
   145  	err := m.CreateDB()
   146  	r.Error(err)
   147  	err = m.DropDB()
   148  	r.Error(err)
   149  }
   150  
   151  func Test_MySQL_FizzTranslator(t *testing.T) {
   152  	r := require.New(t)
   153  	cd := &ConnectionDetails{}
   154  	m := &mysql{commonDialect{ConnectionDetails: cd}}
   155  	ft := m.FizzTranslator()
   156  	r.IsType(&translators.MySQL{}, ft)
   157  	r.Implements((*fizz.Translator)(nil), ft)
   158  }
   159  
   160  func Test_MySQL_Finalizer_Default_CD(t *testing.T) {
   161  	r := require.New(t)
   162  	m := &mysql{commonDialect{ConnectionDetails: &ConnectionDetails{}}}
   163  	finalizerMySQL(m.ConnectionDetails)
   164  	r.Equal(hostMySQL, m.ConnectionDetails.Host)
   165  	r.Equal(portMySQL, m.ConnectionDetails.Port)
   166  }
   167  
   168  func Test_MySQL_Finalizer_Default_Options(t *testing.T) {
   169  	r := require.New(t)
   170  	m := &mysql{commonDialect{ConnectionDetails: &ConnectionDetails{}}}
   171  	finalizerMySQL(m.ConnectionDetails)
   172  	r.Contains(m.URL(), "multiStatements=true")
   173  	r.Contains(m.URL(), "parseTime=true")
   174  	r.Contains(m.URL(), "readTimeout=3s")
   175  	r.Contains(m.URL(), "collation=utf8mb4_general_ci")
   176  }
   177  
   178  func Test_MySQL_Finalizer_Preserve_User_Defined_Options(t *testing.T) {
   179  	r := require.New(t)
   180  	m := &mysql{commonDialect{ConnectionDetails: &ConnectionDetails{
   181  		Options: map[string]string{
   182  			"multiStatements": "false",
   183  			"parseTime":       "false",
   184  			"readTimeout":     "1h",
   185  			"collation":       "utf8",
   186  		},
   187  	}}}
   188  	finalizerMySQL(m.ConnectionDetails)
   189  	r.Contains(m.URL(), "multiStatements=false")
   190  	r.Contains(m.URL(), "parseTime=false")
   191  	r.Contains(m.URL(), "readTimeout=1h")
   192  	r.Contains(m.URL(), "collation=utf8")
   193  }
   194  
   195  func (s *MySQLSuite) Test_MySQL_DDL_Operations() {
   196  	r := s.Require()
   197  
   198  	origDatabase := PDB.Dialect.Details().Database
   199  	PDB.Dialect.Details().Database = "pop_test_mysql_extra"
   200  	defer func() {
   201  		PDB.Dialect.Details().Database = origDatabase
   202  	}()
   203  
   204  	PDB.Dialect.DropDB() // clean up
   205  	err := PDB.Dialect.CreateDB()
   206  	r.NoError(err)
   207  	err = PDB.Dialect.CreateDB()
   208  	r.Error(err)
   209  	err = PDB.Dialect.DropDB()
   210  	r.NoError(err)
   211  	err = PDB.Dialect.DropDB()
   212  	r.Error(err)
   213  }
   214  
   215  func (s *MySQLSuite) Test_MySQL_DDL_Schema() {
   216  	r := s.Require()
   217  
   218  	f, err := ioutil.TempFile(os.TempDir(), "pop_test_mysql_dump")
   219  	r.NoError(err)
   220  	defer func() {
   221  		f.Close()
   222  		os.Remove(f.Name())
   223  	}()
   224  
   225  	// do it against "pop_test"
   226  	err = PDB.Dialect.DumpSchema(f)
   227  	r.NoError(err)
   228  	_, err = f.Seek(0, 0)
   229  	r.NoError(err)
   230  	err = PDB.Dialect.LoadSchema(f)
   231  	r.NoError(err)
   232  
   233  	origDatabase := PDB.Dialect.Details().Database
   234  	PDB.Dialect.Details().Database = "pop_test_not_exist"
   235  	defer func() {
   236  		PDB.Dialect.Details().Database = origDatabase
   237  	}()
   238  
   239  	// do it against "pop_test_not_exist"
   240  	_, err = f.Seek(0, 0)
   241  	r.NoError(err)
   242  	err = PDB.Dialect.LoadSchema(f)
   243  	r.Error(err)
   244  	err = PDB.Dialect.DumpSchema(f)
   245  	r.Error(err)
   246  }
   247  
   248  //** DEPRECATED: preserve test cases below while deprecated codes alive
   249  func Test_MySQL_Deprecated_CD_Encoding(t *testing.T) {
   250  	r := require.New(t)
   251  	cd := &ConnectionDetails{Encoding: "myEncoding"}
   252  	finalizerMySQL(cd)
   253  	r.NotNil(cd.Options)
   254  	r.Equal("myEncoding", cd.Encoding)
   255  	r.Equal("myEncoding", cd.Options["collation"])
   256  }