mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-30 15:23:34 +00:00 
			
		
		
		
	Add more unit tests
This commit is contained in:
		
							
								
								
									
										136
									
								
								backend/internal/entity/auth/entity_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								backend/internal/entity/auth/entity_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,136 @@ | ||||
| package auth | ||||
|  | ||||
| import ( | ||||
| 	"regexp" | ||||
| 	"testing" | ||||
|  | ||||
| 	"npm/internal/test" | ||||
|  | ||||
| 	"github.com/DATA-DOG/go-sqlmock" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
|  | ||||
| // +------------+ | ||||
| // | Setup      | | ||||
| // +------------+ | ||||
|  | ||||
| type testsuite struct { | ||||
| 	suite.Suite | ||||
| 	mock      sqlmock.Sqlmock | ||||
| 	singleRow *sqlmock.Rows | ||||
| } | ||||
|  | ||||
| // SetupTest is executed before each test | ||||
| func (s *testsuite) SetupTest() { | ||||
| 	var err error | ||||
| 	s.mock, err = test.Setup() | ||||
| 	require.NoError(s.T(), err) | ||||
|  | ||||
| 	// These rows need to be intantiated for each test as they are | ||||
| 	// read in the db object, and their row position is not resettable | ||||
| 	// between tests. | ||||
| 	s.singleRow = sqlmock.NewRows([]string{ | ||||
| 		"id", | ||||
| 		"user_id", | ||||
| 		"type", | ||||
| 		"secret", | ||||
| 	}).AddRow( | ||||
| 		10, | ||||
| 		100, | ||||
| 		TypePassword, | ||||
| 		"abc123", | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // In order for 'go test' to run this suite, we need to create | ||||
| // a normal test function and pass our suite to suite.Run | ||||
| func TestExampleTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(testsuite)) | ||||
| } | ||||
|  | ||||
| func assertModel(t *testing.T, m Model) { | ||||
| 	assert.Equal(t, uint(10), m.ID) | ||||
| 	assert.Equal(t, uint(100), m.UserID) | ||||
| 	assert.Equal(t, TypePassword, m.Type) | ||||
| 	assert.Equal(t, "abc123", m.Secret) | ||||
| } | ||||
|  | ||||
| // +------------+ | ||||
| // | Tests      | | ||||
| // +------------+ | ||||
|  | ||||
| func (s *testsuite) TestGetByID() { | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "auth" WHERE "auth"."id" = $1 AND "auth"."is_deleted" = $2 ORDER BY "auth"."id" LIMIT 1`)). | ||||
| 		WithArgs(10, 0). | ||||
| 		WillReturnRows(s.singleRow) | ||||
|  | ||||
| 	m, err := GetByID(10) | ||||
| 	require.NoError(s.T(), err) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| 	assertModel(s.T(), m) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestGetByUserIDType() { | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "auth" WHERE user_id = $1 AND type = $2 AND "auth"."is_deleted" = $3 ORDER BY "auth"."id" LIMIT 1`)). | ||||
| 		WithArgs(100, TypePassword, 0). | ||||
| 		WillReturnRows(s.singleRow) | ||||
|  | ||||
| 	m, err := GetByUserIDType(100, TypePassword) | ||||
| 	require.NoError(s.T(), err) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| 	assertModel(s.T(), m) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestSave() { | ||||
| 	s.mock.ExpectBegin() | ||||
| 	s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "auth" ("created_at","updated_at","is_deleted","user_id","type","secret") VALUES ($1,$2,$3,$4,$5,$6) RETURNING "id"`)). | ||||
| 		WithArgs( | ||||
| 			sqlmock.AnyArg(), | ||||
| 			sqlmock.AnyArg(), | ||||
| 			0, | ||||
| 			100, | ||||
| 			TypePassword, | ||||
| 			"abc123", | ||||
| 		). | ||||
| 		WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow("11")) | ||||
| 	s.mock.ExpectCommit() | ||||
|  | ||||
| 	// New model | ||||
| 	m := Model{ | ||||
| 		UserID: 100, | ||||
| 		Type:   TypePassword, | ||||
| 		Secret: "abc123", | ||||
| 	} | ||||
| 	err := m.Save() | ||||
| 	require.NoError(s.T(), err) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestSetPassword() { | ||||
| 	m := Model{UserID: 100} | ||||
| 	err := m.SetPassword("abc123") | ||||
| 	require.NoError(s.T(), err) | ||||
| 	assert.Equal(s.T(), TypePassword, m.Type) | ||||
| 	assert.Greater(s.T(), len(m.Secret), 15) | ||||
|  | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestValidateSecret() { | ||||
| 	m := Model{UserID: 100} | ||||
| 	m.SetPassword("abc123") | ||||
|  | ||||
| 	err := m.ValidateSecret("abc123") | ||||
| 	require.NoError(s.T(), err) | ||||
| 	err = m.ValidateSecret("this is not the password") | ||||
| 	assert.NotNil(s.T(), err) | ||||
| 	assert.Equal(s.T(), "Invalid Password", err.Error()) | ||||
|  | ||||
| 	m.Type = "not a valid type" | ||||
| 	err = m.ValidateSecret("abc123") | ||||
| 	assert.NotNil(s.T(), err) | ||||
| 	assert.Equal(s.T(), "Could not validate Secret, auth type is not a Password", err.Error()) | ||||
| } | ||||
| @@ -33,28 +33,6 @@ func (m *Model) LoadByID(id int) error { | ||||
| 	return result.Error | ||||
| } | ||||
|  | ||||
| // LoadByUserIDType will load from an ID | ||||
| func (m *Model) LoadByUserIDType(userID int, authType string) error { | ||||
| 	db := database.GetDB() | ||||
| 	result := db. | ||||
| 		Where("user_id = ?", userID). | ||||
| 		Where("type = ?", authType). | ||||
| 		First(&m) | ||||
| 	return result.Error | ||||
| } | ||||
|  | ||||
| /* | ||||
| // Touch will update model's timestamp(s) | ||||
| func (m *Model) Touch(created bool) { | ||||
| 	var d types.DBDate | ||||
| 	d.Time = time.Now() | ||||
| 	if created { | ||||
| 		m.CreatedOn = d | ||||
| 	} | ||||
| 	m.ModifiedOn = d | ||||
| } | ||||
| */ | ||||
|  | ||||
| // Save will save this model to the DB | ||||
| func (m *Model) Save() error { | ||||
| 	db := database.GetDB() | ||||
|   | ||||
							
								
								
									
										217
									
								
								backend/internal/entity/certificateauthority/entity_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										217
									
								
								backend/internal/entity/certificateauthority/entity_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,217 @@ | ||||
| package certificateauthority | ||||
|  | ||||
| import ( | ||||
| 	"regexp" | ||||
| 	"testing" | ||||
|  | ||||
| 	"npm/internal/errors" | ||||
| 	"npm/internal/model" | ||||
| 	"npm/internal/test" | ||||
|  | ||||
| 	"github.com/DATA-DOG/go-sqlmock" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
|  | ||||
| // +------------+ | ||||
| // | Setup      | | ||||
| // +------------+ | ||||
|  | ||||
| type testsuite struct { | ||||
| 	suite.Suite | ||||
| 	mock          sqlmock.Sqlmock | ||||
| 	testCA        *sqlmock.Rows | ||||
| 	listCountRows *sqlmock.Rows | ||||
| 	listRows      *sqlmock.Rows | ||||
| } | ||||
|  | ||||
| // SetupTest is executed before each test | ||||
| func (s *testsuite) SetupTest() { | ||||
| 	var err error | ||||
| 	s.mock, err = test.Setup() | ||||
| 	require.NoError(s.T(), err) | ||||
|  | ||||
| 	// These rows need to be intantiated for each test as they are | ||||
| 	// read in the db object, and their row position is not resettable | ||||
| 	// between tests. | ||||
| 	s.testCA = sqlmock.NewRows([]string{ | ||||
| 		"id", | ||||
| 		"name", | ||||
| 		"acmesh_server", | ||||
| 		"ca_bundle", | ||||
| 		"is_wildcard_supported", | ||||
| 		"max_domains", | ||||
| 	}).AddRow( | ||||
| 		10, | ||||
| 		"Test CA", | ||||
| 		"https://ca.internal/acme/acme/directory", | ||||
| 		"/etc/ssl/certs/NginxProxyManager.crt", | ||||
| 		true, | ||||
| 		2, | ||||
| 	) | ||||
|  | ||||
| 	s.listCountRows = sqlmock.NewRows([]string{ | ||||
| 		"count(*)", | ||||
| 	}).AddRow( | ||||
| 		2, | ||||
| 	) | ||||
|  | ||||
| 	s.listRows = sqlmock.NewRows([]string{ | ||||
| 		"id", | ||||
| 		"name", | ||||
| 		"acmesh_server", | ||||
| 		"ca_bundle", | ||||
| 		"is_wildcard_supported", | ||||
| 		"max_domains", | ||||
| 	}).AddRow( | ||||
| 		10, | ||||
| 		"Test CA", | ||||
| 		"https://ca.internal/acme/acme/directory", | ||||
| 		"/etc/ssl/certs/NginxProxyManager.crt", | ||||
| 		true, | ||||
| 		2, | ||||
| 	).AddRow( | ||||
| 		11, | ||||
| 		"Test CA 2", | ||||
| 		"https://ca2.internal/acme/acme/directory", | ||||
| 		"/etc/ssl/certs/NginxProxyManager.crt", | ||||
| 		true, | ||||
| 		5, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // In order for 'go test' to run this suite, we need to create | ||||
| // a normal test function and pass our suite to suite.Run | ||||
| func TestExampleTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(testsuite)) | ||||
| } | ||||
|  | ||||
| func assertModel(t *testing.T, m Model) { | ||||
| 	assert.Equal(t, uint(10), m.ID) | ||||
| 	assert.Equal(t, "Test CA", m.Name) | ||||
| 	assert.Equal(t, "https://ca.internal/acme/acme/directory", m.AcmeshServer) | ||||
| 	assert.Equal(t, "/etc/ssl/certs/NginxProxyManager.crt", m.CABundle) | ||||
| 	assert.Equal(t, 2, m.MaxDomains) | ||||
| 	assert.Equal(t, true, m.IsWildcardSupported) | ||||
| 	assert.Equal(t, false, m.IsReadonly) | ||||
| } | ||||
|  | ||||
| // +------------+ | ||||
| // | Tests      | | ||||
| // +------------+ | ||||
|  | ||||
| func (s *testsuite) TestGetByID() { | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "certificate_authority" WHERE "certificate_authority"."id" = $1 AND "certificate_authority"."is_deleted" = $2 ORDER BY "certificate_authority"."id" LIMIT 1`)). | ||||
| 		WithArgs(10, 0). | ||||
| 		WillReturnRows(s.testCA) | ||||
|  | ||||
| 	m, err := GetByID(10) | ||||
| 	require.NoError(s.T(), err) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| 	assertModel(s.T(), m) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestList() { | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "certificate_authority" WHERE name LIKE $1 AND "certificate_authority"."is_deleted" = $2`)). | ||||
| 		WithArgs("%test%", 0). | ||||
| 		WillReturnRows(s.listCountRows) | ||||
|  | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "certificate_authority" WHERE name LIKE $1 AND "certificate_authority"."is_deleted" = $2 ORDER BY name asc LIMIT 8`)). | ||||
| 		WithArgs("%test%", 0). | ||||
| 		WillReturnRows(s.listRows) | ||||
|  | ||||
| 	p := model.PageInfo{ | ||||
| 		Offset: 0, | ||||
| 		Limit:  8, | ||||
| 		Sort: []model.Sort{ | ||||
| 			{ | ||||
| 				Field:     "name", | ||||
| 				Direction: "asc", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	f := []model.Filter{ | ||||
| 		{ | ||||
| 			Field:    "name", | ||||
| 			Modifier: "contains", | ||||
| 			Value:    []string{"test"}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	resp, err := List(p, f) | ||||
| 	require.NoError(s.T(), err) | ||||
| 	assert.Equal(s.T(), int64(2), resp.Total) | ||||
| 	assert.Equal(s.T(), p.Offset, resp.Offset) | ||||
| 	assert.Equal(s.T(), p.Limit, resp.Limit) | ||||
| 	assert.Equal(s.T(), p.Limit, resp.Limit) | ||||
| 	assert.Equal(s.T(), p.Sort, resp.Sort) | ||||
| 	assert.Equal(s.T(), f, resp.Filter) | ||||
|  | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestSave() { | ||||
| 	s.mock.ExpectBegin() | ||||
| 	s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "certificate_authority" ("created_at","updated_at","is_deleted","name","acmesh_server","ca_bundle","max_domains","is_wildcard_supported","is_readonly") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING "id"`)). | ||||
| 		WithArgs( | ||||
| 			sqlmock.AnyArg(), | ||||
| 			sqlmock.AnyArg(), | ||||
| 			0, | ||||
| 			"Test CA", | ||||
| 			"https://ca.internal/acme/acme/directory", | ||||
| 			"/etc/ssl/certs/NginxProxyManager.crt", | ||||
| 			2, | ||||
| 			true, | ||||
| 			false, | ||||
| 		). | ||||
| 		WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow("11")) | ||||
| 	s.mock.ExpectCommit() | ||||
|  | ||||
| 	m := Model{ | ||||
| 		Name:                "Test CA", | ||||
| 		AcmeshServer:        "https://ca.internal/acme/acme/directory", | ||||
| 		CABundle:            "/etc/ssl/certs/NginxProxyManager.crt", | ||||
| 		MaxDomains:          2, | ||||
| 		IsWildcardSupported: true, | ||||
| 	} | ||||
| 	err := m.Save() | ||||
| 	require.NoError(s.T(), err) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestDelete() { | ||||
| 	s.mock.ExpectBegin() | ||||
| 	s.mock. | ||||
| 		ExpectExec(regexp.QuoteMeta(`UPDATE "certificate_authority" SET "is_deleted"=$1 WHERE "certificate_authority"."id" = $2 AND "certificate_authority"."is_deleted" = $3`)). | ||||
| 		WithArgs(1, 10, 0). | ||||
| 		WillReturnResult(sqlmock.NewResult(0, 1)) | ||||
| 	s.mock.ExpectCommit() | ||||
|  | ||||
| 	m := Model{} | ||||
| 	err := m.Delete() | ||||
| 	assert.Equal(s.T(), "Unable to delete a new object", err.Error()) | ||||
|  | ||||
| 	m2 := Model{ | ||||
| 		ModelBase: model.ModelBase{ | ||||
| 			ID: 10, | ||||
| 		}, | ||||
| 	} | ||||
| 	err2 := m2.Delete() | ||||
| 	require.NoError(s.T(), err2) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestCheck() { | ||||
| 	m := Model{} | ||||
| 	err := m.Check() | ||||
| 	assert.Nil(s.T(), err) | ||||
|  | ||||
| 	m.CABundle = "/tmp/doesnotexist" | ||||
| 	err = m.Check() | ||||
| 	assert.Equal(s.T(), errors.ErrCABundleDoesNotExist.Error(), err.Error()) | ||||
| } | ||||
| @@ -41,15 +41,15 @@ func (m *Model) Save() error { | ||||
| 	return result.Error | ||||
| } | ||||
|  | ||||
| // Delete will mark row as deleted | ||||
| func (m *Model) Delete() bool { | ||||
| // Delete will mark a row as deleted | ||||
| func (m *Model) Delete() error { | ||||
| 	if m.ID == 0 { | ||||
| 		// Can't delete a new object | ||||
| 		return false | ||||
| 		return eris.New("Unable to delete a new object") | ||||
| 	} | ||||
| 	db := database.GetDB() | ||||
| 	result := db.Delete(m) | ||||
| 	return result.Error == nil | ||||
| 	return result.Error | ||||
| } | ||||
|  | ||||
| // Check will ensure the ca bundle path exists if it's set | ||||
|   | ||||
							
								
								
									
										290
									
								
								backend/internal/entity/dnsprovider/entity_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								backend/internal/entity/dnsprovider/entity_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,290 @@ | ||||
| package dnsprovider | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"regexp" | ||||
| 	"testing" | ||||
|  | ||||
| 	"npm/internal/model" | ||||
| 	"npm/internal/test" | ||||
| 	"npm/internal/types" | ||||
|  | ||||
| 	"github.com/DATA-DOG/go-sqlmock" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| 	"github.com/stretchr/testify/suite" | ||||
| ) | ||||
|  | ||||
| // +------------+ | ||||
| // | Setup      | | ||||
| // +------------+ | ||||
|  | ||||
| type testsuite struct { | ||||
| 	suite.Suite | ||||
| 	mock          sqlmock.Sqlmock | ||||
| 	singleRow     *sqlmock.Rows | ||||
| 	listCountRows *sqlmock.Rows | ||||
| 	listRows      *sqlmock.Rows | ||||
| } | ||||
|  | ||||
| // SetupTest is executed before each test | ||||
| func (s *testsuite) SetupTest() { | ||||
| 	var err error | ||||
| 	s.mock, err = test.Setup() | ||||
| 	require.NoError(s.T(), err) | ||||
|  | ||||
| 	// These rows need to be intantiated for each test as they are | ||||
| 	// read in the db object, and their row position is not resettable | ||||
| 	// between tests. | ||||
| 	s.singleRow = sqlmock.NewRows([]string{ | ||||
| 		"id", | ||||
| 		"user_id", | ||||
| 		"name", | ||||
| 		"acmesh_name", | ||||
| 		"dns_sleep", | ||||
| 		"meta", | ||||
| 	}).AddRow( | ||||
| 		10, | ||||
| 		100, | ||||
| 		"Route53", | ||||
| 		"dns_aws", | ||||
| 		10, | ||||
| 		getMeta().Encoded, | ||||
| 	) | ||||
|  | ||||
| 	s.listCountRows = sqlmock.NewRows([]string{ | ||||
| 		"count(*)", | ||||
| 	}).AddRow( | ||||
| 		2, | ||||
| 	) | ||||
|  | ||||
| 	s.listRows = sqlmock.NewRows([]string{ | ||||
| 		"id", | ||||
| 		"user_id", | ||||
| 		"name", | ||||
| 		"acmesh_name", | ||||
| 		"dns_sleep", | ||||
| 		"meta", | ||||
| 	}).AddRow( | ||||
| 		10, | ||||
| 		100, | ||||
| 		"Route53", | ||||
| 		"dns_aws", | ||||
| 		10, | ||||
| 		getMeta().Encoded, | ||||
| 	).AddRow( | ||||
| 		11, | ||||
| 		100, | ||||
| 		"ClouDNS", | ||||
| 		"dns_cloudns", | ||||
| 		8, | ||||
| 		types.JSONB{}, | ||||
| 	) | ||||
| } | ||||
|  | ||||
| // In order for 'go test' to run this suite, we need to create | ||||
| // a normal test function and pass our suite to suite.Run | ||||
| func TestExampleTestSuite(t *testing.T) { | ||||
| 	suite.Run(t, new(testsuite)) | ||||
| } | ||||
|  | ||||
| func getMeta() types.JSONB { | ||||
| 	m := types.JSONB{} | ||||
| 	m.UnmarshalJSON([]byte(`{"access_key_id": "BKINOTLNEREALYBL52W2I", "access_key": "NOTAREALKEY+9qSca7R9U6vUuetR8sh"}`)) | ||||
| 	return m | ||||
| } | ||||
|  | ||||
| func assertModel(t *testing.T, m Model) { | ||||
| 	assert.Equal(t, uint(10), m.ID, "ID not expected value") | ||||
| 	assert.Equal(t, uint(100), m.UserID, "UserID not expected value") | ||||
| 	assert.Equal(t, "Route53", m.Name, "Name not expected value") | ||||
| 	assert.Equal(t, "dns_aws", m.AcmeshName, "AcmeshName not expected value") | ||||
| 	assert.Equal(t, 10, m.DNSSleep, "DNSSleep not expected value") | ||||
| 	assert.Equal(t, getMeta(), m.Meta, "Meta not expected value") | ||||
| } | ||||
|  | ||||
| // +------------+ | ||||
| // | Tests      | | ||||
| // +------------+ | ||||
|  | ||||
| func (s *testsuite) TestGetByID() { | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "dns_provider" WHERE "dns_provider"."id" = $1 AND "dns_provider"."is_deleted" = $2 ORDER BY "dns_provider"."id" LIMIT 1`)). | ||||
| 		WithArgs(10, 0). | ||||
| 		WillReturnRows(s.singleRow) | ||||
|  | ||||
| 	m, err := GetByID(10) | ||||
| 	require.NoError(s.T(), err) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| 	assertModel(s.T(), m) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestGetAcmeShEnvVars() { | ||||
| 	type want struct { | ||||
| 		envs []string | ||||
| 		err  error | ||||
| 	} | ||||
|  | ||||
| 	tests := []struct { | ||||
| 		name        string | ||||
| 		dnsProvider Model | ||||
| 		metaJSON    string | ||||
| 		want        want | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "dns_aws", | ||||
| 			dnsProvider: Model{ | ||||
| 				AcmeshName: "dns_aws", | ||||
| 			}, | ||||
| 			metaJSON: `{"AWS_ACCESS_KEY_ID":"sdfsdfsdfljlbjkljlkjsdfoiwje","AWS_SECRET_ACCESS_KEY":"xxxxxxx"}`, | ||||
| 			want: want{ | ||||
| 				envs: []string{ | ||||
| 					`AWS_ACCESS_KEY_ID=sdfsdfsdfljlbjkljlkjsdfoiwje`, | ||||
| 					`AWS_SECRET_ACCESS_KEY=xxxxxxx`, | ||||
| 				}, | ||||
| 				err: nil, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "dns_cf", | ||||
| 			dnsProvider: Model{ | ||||
| 				AcmeshName: "dns_cf", | ||||
| 			}, | ||||
| 			metaJSON: `{"CF_Key":"sdfsdfsdfljlbjkljlkjsdfoiwje","CF_Email":"me@example.com","CF_Token":"dkfjghdk","CF_Account_ID":"hgbdjfg","CF_Zone_ID":"ASDASD"}`, | ||||
| 			want: want{ | ||||
| 				envs: []string{ | ||||
| 					`CF_Token=dkfjghdk`, | ||||
| 					`CF_Account_ID=hgbdjfg`, | ||||
| 					`CF_Zone_ID=ASDASD`, | ||||
| 					`CF_Key=sdfsdfsdfljlbjkljlkjsdfoiwje`, | ||||
| 					`CF_Email=me@example.com`, | ||||
| 				}, | ||||
| 				err: nil, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "dns_duckdns", | ||||
| 			dnsProvider: Model{ | ||||
| 				AcmeshName: "dns_duckdns", | ||||
| 			}, | ||||
| 			metaJSON: `{"DuckDNS_Token":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"}`, | ||||
| 			want: want{ | ||||
| 				envs: []string{ | ||||
| 					`DuckDNS_Token=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee`, | ||||
| 				}, | ||||
| 				err: nil, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tt := range tests { | ||||
| 		s.T().Run(tt.name, func(t *testing.T) { | ||||
| 			var meta types.JSONB | ||||
| 			err := json.Unmarshal([]byte(tt.metaJSON), &meta.Decoded) | ||||
| 			assert.Equal(t, nil, err) | ||||
| 			tt.dnsProvider.Meta = meta | ||||
| 			envs, err := tt.dnsProvider.GetAcmeShEnvVars() | ||||
| 			assert.Equal(t, tt.want.err, err) | ||||
| 			for _, i := range tt.want.envs { | ||||
| 				assert.Contains(t, envs, i) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestList() { | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT count(*) FROM "dns_provider" WHERE acmesh_name LIKE $1 AND "dns_provider"."is_deleted" = $2`)). | ||||
| 		WithArgs("dns%", 0). | ||||
| 		WillReturnRows(s.listCountRows) | ||||
|  | ||||
| 	s.mock. | ||||
| 		ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "dns_provider" WHERE acmesh_name LIKE $1 AND "dns_provider"."is_deleted" = $2 ORDER BY name asc LIMIT 8`)). | ||||
| 		WithArgs("dns%", 0). | ||||
| 		WillReturnRows(s.listRows) | ||||
|  | ||||
| 	p := model.PageInfo{ | ||||
| 		Offset: 0, | ||||
| 		Limit:  8, | ||||
| 		Sort: []model.Sort{ | ||||
| 			{ | ||||
| 				Field:     "name", | ||||
| 				Direction: "asc", | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	f := []model.Filter{ | ||||
| 		{ | ||||
| 			Field:    "acmesh_name", | ||||
| 			Modifier: "starts", | ||||
| 			Value:    []string{"dns"}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	resp, err := List(p, f) | ||||
| 	require.NoError(s.T(), err) | ||||
| 	assert.Equal(s.T(), int64(2), resp.Total) | ||||
| 	assert.Equal(s.T(), p.Offset, resp.Offset) | ||||
| 	assert.Equal(s.T(), p.Limit, resp.Limit) | ||||
| 	assert.Equal(s.T(), p.Limit, resp.Limit) | ||||
| 	assert.Equal(s.T(), p.Sort, resp.Sort) | ||||
| 	assert.Equal(s.T(), f, resp.Filter) | ||||
|  | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestSave() { | ||||
| 	s.mock.ExpectBegin() | ||||
| 	s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "dns_provider" ("created_at","updated_at","is_deleted","user_id","name","acmesh_name","dns_sleep","meta") VALUES ($1,$2,$3,$4,$5,$6,$7,$8) RETURNING "id"`)). | ||||
| 		WithArgs( | ||||
| 			sqlmock.AnyArg(), | ||||
| 			sqlmock.AnyArg(), | ||||
| 			0, | ||||
| 			100, | ||||
| 			"Route53", | ||||
| 			"dns_route53", | ||||
| 			10, | ||||
| 			sqlmock.AnyArg(), | ||||
| 		). | ||||
| 		WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow("11")) | ||||
| 	s.mock.ExpectCommit() | ||||
|  | ||||
| 	// New model, no user | ||||
| 	m := Model{ | ||||
| 		Name:       "Route53", | ||||
| 		AcmeshName: "dns_route53", | ||||
| 		DNSSleep:   10, | ||||
| 		Meta:       getMeta(), | ||||
| 	} | ||||
| 	err := m.Save() | ||||
| 	assert.Equal(s.T(), "User ID must be specified", err.Error()) | ||||
|  | ||||
| 	// Success | ||||
| 	m.UserID = 100 | ||||
| 	err = m.Save() | ||||
| 	require.NoError(s.T(), err) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| } | ||||
|  | ||||
| func (s *testsuite) TestDelete() { | ||||
| 	s.mock.ExpectBegin() | ||||
| 	s.mock. | ||||
| 		ExpectExec(regexp.QuoteMeta(`UPDATE "dns_provider" SET "is_deleted"=$1 WHERE "dns_provider"."id" = $2 AND "dns_provider"."is_deleted" = $3`)). | ||||
| 		WithArgs(1, 10, 0). | ||||
| 		WillReturnResult(sqlmock.NewResult(0, 1)) | ||||
| 	s.mock.ExpectCommit() | ||||
|  | ||||
| 	m := Model{} | ||||
| 	err := m.Delete() | ||||
| 	assert.Equal(s.T(), "Unable to delete a new object", err.Error()) | ||||
|  | ||||
| 	m2 := Model{ | ||||
| 		ModelBase: model.ModelBase{ | ||||
| 			ID: 10, | ||||
| 		}, | ||||
| 	} | ||||
| 	err2 := m2.Delete() | ||||
| 	require.NoError(s.T(), err2) | ||||
| 	require.NoError(s.T(), s.mock.ExpectationsWereMet()) | ||||
| } | ||||
| @@ -45,23 +45,21 @@ func (m *Model) Save() error { | ||||
| 	return result.Error | ||||
| } | ||||
|  | ||||
| // Delete will mark row as deleted | ||||
| func (m *Model) Delete() bool { | ||||
| // Delete will mark a row as deleted | ||||
| func (m *Model) Delete() error { | ||||
| 	if m.ID == 0 { | ||||
| 		// Can't delete a new object | ||||
| 		return false | ||||
| 		return eris.New("Unable to delete a new object") | ||||
| 	} | ||||
| 	db := database.GetDB() | ||||
| 	result := db.Delete(m) | ||||
| 	return result.Error == nil | ||||
| 	return result.Error | ||||
| } | ||||
|  | ||||
| // GetAcmeShEnvVars returns the env vars required for acme.sh dns cert requests | ||||
| func (m *Model) GetAcmeShEnvVars() ([]string, error) { | ||||
| 	logger.Debug("GetAcmeShEnvVars for: %s", m.AcmeshName) | ||||
| 	// First, fetch the provider obj with this AcmeShName | ||||
| 	acmeDNSProvider, err := dnsproviders.Get(m.AcmeshName) | ||||
| 	logger.Debug("acmeDNSProvider: %+v", acmeDNSProvider) | ||||
| 	_, err := dnsproviders.Get(m.AcmeshName) | ||||
| 	if err != nil { | ||||
| 		logger.Error("GetAcmeShEnvVarsError", err) | ||||
| 		return nil, err | ||||
|   | ||||
| @@ -1,82 +0,0 @@ | ||||
| package dnsprovider | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"npm/internal/types" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestModelGetAcmeShEnvVars(t *testing.T) { | ||||
| 	type want struct { | ||||
| 		envs []string | ||||
| 		err  error | ||||
| 	} | ||||
|  | ||||
| 	tests := []struct { | ||||
| 		name        string | ||||
| 		dnsProvider Model | ||||
| 		metaJSON    string | ||||
| 		want        want | ||||
| 	}{ | ||||
| 		{ | ||||
| 			name: "dns_aws", | ||||
| 			dnsProvider: Model{ | ||||
| 				AcmeshName: "dns_aws", | ||||
| 			}, | ||||
| 			metaJSON: `{"AWS_ACCESS_KEY_ID":"sdfsdfsdfljlbjkljlkjsdfoiwje","AWS_SECRET_ACCESS_KEY":"xxxxxxx"}`, | ||||
| 			want: want{ | ||||
| 				envs: []string{ | ||||
| 					`AWS_ACCESS_KEY_ID=sdfsdfsdfljlbjkljlkjsdfoiwje`, | ||||
| 					`AWS_SECRET_ACCESS_KEY=xxxxxxx`, | ||||
| 				}, | ||||
| 				err: nil, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "dns_cf", | ||||
| 			dnsProvider: Model{ | ||||
| 				AcmeshName: "dns_cf", | ||||
| 			}, | ||||
| 			metaJSON: `{"CF_Key":"sdfsdfsdfljlbjkljlkjsdfoiwje","CF_Email":"me@example.com","CF_Token":"dkfjghdk","CF_Account_ID":"hgbdjfg","CF_Zone_ID":"ASDASD"}`, | ||||
| 			want: want{ | ||||
| 				envs: []string{ | ||||
| 					`CF_Token=dkfjghdk`, | ||||
| 					`CF_Account_ID=hgbdjfg`, | ||||
| 					`CF_Zone_ID=ASDASD`, | ||||
| 					`CF_Key=sdfsdfsdfljlbjkljlkjsdfoiwje`, | ||||
| 					`CF_Email=me@example.com`, | ||||
| 				}, | ||||
| 				err: nil, | ||||
| 			}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			name: "dns_duckdns", | ||||
| 			dnsProvider: Model{ | ||||
| 				AcmeshName: "dns_duckdns", | ||||
| 			}, | ||||
| 			metaJSON: `{"DuckDNS_Token":"aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"}`, | ||||
| 			want: want{ | ||||
| 				envs: []string{ | ||||
| 					`DuckDNS_Token=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee`, | ||||
| 				}, | ||||
| 				err: nil, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, tt := range tests { | ||||
| 		t.Run(tt.name, func(t *testing.T) { | ||||
| 			var meta types.JSONB | ||||
| 			err := json.Unmarshal([]byte(tt.metaJSON), &meta.Decoded) | ||||
| 			assert.Equal(t, nil, err) | ||||
| 			tt.dnsProvider.Meta = meta | ||||
| 			envs, err := tt.dnsProvider.GetAcmeShEnvVars() | ||||
| 			assert.Equal(t, tt.want.err, err) | ||||
| 			for _, i := range tt.want.envs { | ||||
| 				assert.Contains(t, envs, i) | ||||
| 			} | ||||
| 		}) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user