mirror of
				https://github.com/NginxProxyManager/nginx-proxy-manager.git
				synced 2025-10-30 23:33:34 +00:00 
			
		
		
		
	Add more unit tests
This commit is contained in:
		
							
								
								
									
										220
									
								
								backend/internal/entity/host/entity_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										220
									
								
								backend/internal/entity/host/entity_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,220 @@ | |||||||
|  | package host | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"regexp" | ||||||
|  | 	"testing" | ||||||
|  | 	"time" | ||||||
|  |  | ||||||
|  | 	"npm/internal/model" | ||||||
|  | 	"npm/internal/status" | ||||||
|  | 	"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 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func makeJSONB(str string) types.JSONB { | ||||||
|  | 	m := types.JSONB{} | ||||||
|  | 	m.UnmarshalJSON([]byte(str)) | ||||||
|  | 	return m | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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", | ||||||
|  | 		"nginx_template_id", | ||||||
|  | 		"listen_interface", | ||||||
|  | 		"domain_names", | ||||||
|  | 		"upstream_id", | ||||||
|  | 		"proxy_scheme", | ||||||
|  | 		"proxy_host", | ||||||
|  | 		"proxy_port", | ||||||
|  | 		"certificate_id", | ||||||
|  | 		"access_list_id", | ||||||
|  | 		"ssl_forced", | ||||||
|  | 		"caching_enabled", | ||||||
|  | 		"block_exploits", | ||||||
|  | 		"allow_websocket_upgrade", | ||||||
|  | 		"http2_support", | ||||||
|  | 		"hsts_enabled", | ||||||
|  | 		"hsts_subdomains", | ||||||
|  | 		"paths", | ||||||
|  | 		"advanced_config", | ||||||
|  | 		"status", | ||||||
|  | 		"error_message", | ||||||
|  | 		"is_disabled", | ||||||
|  | 	}).AddRow( | ||||||
|  | 		10,                             // ID | ||||||
|  | 		100,                            // UserID | ||||||
|  | 		"proxy",                        // Type | ||||||
|  | 		20,                             // NginxTemplateID | ||||||
|  | 		"",                             // ListenInterface | ||||||
|  | 		makeJSONB("[\"example.com\"]"), // DomainNames | ||||||
|  | 		0,                              // UpstreamID | ||||||
|  | 		"http",                         // ProxyScheme | ||||||
|  | 		"127.0.0.1",                    // ProxyHost | ||||||
|  | 		3000,                           // ProxyPort | ||||||
|  | 		types.NullableDBUint{Uint: 0},  // CertificateID | ||||||
|  | 		types.NullableDBUint{Uint: 0},  // AccessListID | ||||||
|  | 		false,                          // SSLForced | ||||||
|  | 		false,                          // CachingEnabled | ||||||
|  | 		false,                          // BlockExploits | ||||||
|  | 		false,                          // AllowWebsocketUpgrade | ||||||
|  | 		false,                          // HTTP2Support | ||||||
|  | 		false,                          // HSTSEnabled | ||||||
|  | 		false,                          // HSTSSubdomains | ||||||
|  | 		"",                             // Paths | ||||||
|  | 		"",                             // AdvancedConfig | ||||||
|  | 		status.StatusReady,             // Status | ||||||
|  | 		"",                             // ErrorMessage | ||||||
|  | 		false,                          // IsDisabled | ||||||
|  | 	) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // 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)) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // +------------+ | ||||||
|  | // | Tests      | | ||||||
|  | // +------------+ | ||||||
|  |  | ||||||
|  | func (s *testsuite) TestGetByID() { | ||||||
|  | 	s.mock. | ||||||
|  | 		ExpectQuery(regexp.QuoteMeta(`SELECT * FROM "host" WHERE "host"."id" = $1 AND "host"."is_deleted" = $2 ORDER BY "host"."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()) | ||||||
|  | 	assert.Equal(s.T(), uint(10), m.ID) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (s *testsuite) TestSave() { | ||||||
|  | 	s.mock.ExpectBegin() | ||||||
|  | 	s.mock.ExpectQuery(regexp.QuoteMeta(`INSERT INTO "host" ("created_at","updated_at","is_deleted","user_id","type","nginx_template_id","listen_interface","domain_names","upstream_id","proxy_scheme","proxy_host","proxy_port","certificate_id","access_list_id","ssl_forced","caching_enabled","block_exploits","allow_websocket_upgrade","http2_support","hsts_enabled","hsts_subdomains","paths","advanced_config","status","error_message","is_disabled") VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$20,$21,$22,$23,$24,$25,$26) RETURNING "id"`)). | ||||||
|  | 		WithArgs( | ||||||
|  | 			sqlmock.AnyArg(), | ||||||
|  | 			sqlmock.AnyArg(), | ||||||
|  | 			0, | ||||||
|  | 			100, | ||||||
|  | 			"proxy", | ||||||
|  | 			20, | ||||||
|  | 			"", | ||||||
|  | 			"[\"example.com\"]", | ||||||
|  | 			nil, | ||||||
|  | 			"http", | ||||||
|  | 			"127.0.0.1", | ||||||
|  | 			3000, // proxy_port | ||||||
|  | 			nil, | ||||||
|  | 			nil, | ||||||
|  | 			false, | ||||||
|  | 			false, | ||||||
|  | 			false, | ||||||
|  | 			false, | ||||||
|  | 			false, | ||||||
|  | 			false, | ||||||
|  | 			false, | ||||||
|  | 			"", | ||||||
|  | 			"", | ||||||
|  | 			status.StatusReady, | ||||||
|  | 			"", | ||||||
|  | 			false, | ||||||
|  | 		). | ||||||
|  | 		WillReturnRows(sqlmock.NewRows([]string{"id"}).AddRow("11")) | ||||||
|  | 	s.mock.ExpectCommit() | ||||||
|  |  | ||||||
|  | 	// New model, as system | ||||||
|  | 	m := Model{ | ||||||
|  | 		UserID:          100, | ||||||
|  | 		Type:            "proxy", | ||||||
|  | 		NginxTemplateID: 20, | ||||||
|  | 		DomainNames:     makeJSONB("[\"example.com\"]"), | ||||||
|  | 		ProxyScheme:     "http", | ||||||
|  | 		ProxyHost:       "127.0.0.1", | ||||||
|  | 		ProxyPort:       3000, | ||||||
|  | 		Status:          status.StatusReady, | ||||||
|  | 	} | ||||||
|  | 	err := m.Save(true) | ||||||
|  | 	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 "host" SET "is_deleted"=$1 WHERE "host"."id" = $2 AND "host"."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) TestGetTemplate() { | ||||||
|  | 	m := Model{ | ||||||
|  | 		ModelBase: model.ModelBase{ | ||||||
|  | 			ID:        10, | ||||||
|  | 			CreatedAt: time.Date(2018, 1, 1, 0, 0, 0, 0, time.UTC).UnixMilli(), | ||||||
|  | 			UpdatedAt: time.Date(2018, 8, 12, 7, 30, 24, 16, time.UTC).UnixMilli(), | ||||||
|  | 		}, | ||||||
|  | 		UserID:          100, | ||||||
|  | 		Type:            "proxy", | ||||||
|  | 		NginxTemplateID: 20, | ||||||
|  | 		DomainNames:     makeJSONB("[\"example.com\"]"), | ||||||
|  | 		ProxyScheme:     "http", | ||||||
|  | 		ProxyHost:       "127.0.0.1", | ||||||
|  | 		ProxyPort:       3000, | ||||||
|  | 		Status:          status.StatusReady, | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	t := m.GetTemplate() | ||||||
|  | 	assert.Equal(s.T(), uint(10), t.ID) | ||||||
|  | 	assert.Equal(s.T(), "Mon, 01 Jan 2018 10:00:00 AEST", t.CreatedAt) | ||||||
|  | 	assert.Equal(s.T(), "Sun, 12 Aug 2018 17:30:24 AEST", t.UpdatedAt) | ||||||
|  | 	assert.Equal(s.T(), uint(100), t.UserID) | ||||||
|  | 	assert.Equal(s.T(), "proxy", t.Type) | ||||||
|  | 	assert.Equal(s.T(), uint(20), t.NginxTemplateID) | ||||||
|  | 	assert.Equal(s.T(), "http", t.ProxyScheme) | ||||||
|  | 	assert.Equal(s.T(), "127.0.0.1", t.ProxyHost) | ||||||
|  | 	assert.Equal(s.T(), 3000, t.ProxyPort) | ||||||
|  | 	assert.Equal(s.T(), []string{"example.com"}, t.DomainNames) | ||||||
|  | 	assert.Equal(s.T(), status.StatusReady, t.Status) | ||||||
|  | } | ||||||
| @@ -1,7 +1,8 @@ | |||||||
| package host | package host | ||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"time" | ||||||
|  |  | ||||||
| 	"npm/internal/database" | 	"npm/internal/database" | ||||||
| 	"npm/internal/entity/certificate" | 	"npm/internal/entity/certificate" | ||||||
| 	"npm/internal/entity/nginxtemplate" | 	"npm/internal/entity/nginxtemplate" | ||||||
| @@ -85,15 +86,15 @@ func (m *Model) Save(skipConfiguration bool) error { | |||||||
| 	return result.Error | 	return result.Error | ||||||
| } | } | ||||||
|  |  | ||||||
| // Delete will mark row as deleted | // Delete will mark a row as deleted | ||||||
| func (m *Model) Delete() bool { | func (m *Model) Delete() error { | ||||||
| 	if m.ID == 0 { | 	if m.ID == 0 { | ||||||
| 		// Can't delete a new object | 		// Can't delete a new object | ||||||
| 		return false | 		return eris.New("Unable to delete a new object") | ||||||
| 	} | 	} | ||||||
| 	db := database.GetDB() | 	db := database.GetDB() | ||||||
| 	result := db.Delete(m) | 	result := db.Delete(m) | ||||||
| 	return result.Error == nil | 	return result.Error | ||||||
| } | } | ||||||
|  |  | ||||||
| // Expand will fill in more properties | // Expand will fill in more properties | ||||||
| @@ -140,8 +141,8 @@ func (m *Model) GetTemplate() Template { | |||||||
|  |  | ||||||
| 	t := Template{ | 	t := Template{ | ||||||
| 		ID:                    m.ID, | 		ID:                    m.ID, | ||||||
| 		CreatedAt:             fmt.Sprintf("%d", m.CreatedAt), // todo: format as nice string | 		CreatedAt:             time.UnixMilli(m.CreatedAt).Format(time.RFC1123), | ||||||
| 		UpdatedAt:             fmt.Sprintf("%d", m.UpdatedAt), // todo: format as nice string | 		UpdatedAt:             time.UnixMilli(m.UpdatedAt).Format(time.RFC1123), | ||||||
| 		UserID:                m.UserID, | 		UserID:                m.UserID, | ||||||
| 		Type:                  m.Type, | 		Type:                  m.Type, | ||||||
| 		NginxTemplateID:       m.NginxTemplateID, | 		NginxTemplateID:       m.NginxTemplateID, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user