9 Commits

Author SHA1 Message Date
Quentin McGaw
9da4365d96 Check accept header 2021-03-24 02:46:10 +00:00
Quentin McGaw
ade2de9fdc Get records unit tests 2021-03-24 02:35:46 +00:00
Quentin McGaw
532a096629 Settings mock 2021-03-24 02:35:38 +00:00
Quentin McGaw
18e458139c SPDyn marshal json method 2021-03-24 02:35:25 +00:00
Quentin McGaw
725b6773e1 Database mocks 2021-03-23 23:09:53 +00:00
Quentin McGaw
d2f113b832 Return an empty slice if no data is set 2021-03-23 23:09:53 +00:00
Quentin McGaw
21acfac9f0 Update new providers added 2021-03-23 23:09:53 +00:00
Quentin McGaw
916752263e GET /api/v1/records route 2021-03-23 23:09:53 +00:00
Quentin McGaw
9a69b5a23d Marshal JSON method for all record settings 2021-03-23 23:09:53 +00:00
35 changed files with 517 additions and 10 deletions

View File

@@ -8,6 +8,8 @@ import (
"github.com/qdm12/ddns-updater/internal/records"
)
//go:generate mockgen -destination=mock_$GOPACKAGE/$GOFILE . Database
type Database interface {
Close() error
Select(id int) (record records.Record, err error)

View File

@@ -18,8 +18,11 @@ func (db *database) Select(id int) (record records.Record, err error) {
return db.data[id], nil
}
func (db *database) SelectAll() (records []records.Record) {
func (db *database) SelectAll() []records.Record {
db.RLock()
defer db.RUnlock()
if db.data == nil {
db.data = make([]records.Record, 0)
}
return db.data
}

View File

@@ -0,0 +1,108 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/qdm12/ddns-updater/internal/data (interfaces: Database)
// Package mock_data is a generated GoMock package.
package mock_data
import (
reflect "reflect"
gomock "github.com/golang/mock/gomock"
models "github.com/qdm12/ddns-updater/internal/models"
records "github.com/qdm12/ddns-updater/internal/records"
)
// MockDatabase is a mock of Database interface.
type MockDatabase struct {
ctrl *gomock.Controller
recorder *MockDatabaseMockRecorder
}
// MockDatabaseMockRecorder is the mock recorder for MockDatabase.
type MockDatabaseMockRecorder struct {
mock *MockDatabase
}
// NewMockDatabase creates a new mock instance.
func NewMockDatabase(ctrl *gomock.Controller) *MockDatabase {
mock := &MockDatabase{ctrl: ctrl}
mock.recorder = &MockDatabaseMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockDatabase) EXPECT() *MockDatabaseMockRecorder {
return m.recorder
}
// Close mocks base method.
func (m *MockDatabase) Close() error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Close")
ret0, _ := ret[0].(error)
return ret0
}
// Close indicates an expected call of Close.
func (mr *MockDatabaseMockRecorder) Close() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockDatabase)(nil).Close))
}
// GetEvents mocks base method.
func (m *MockDatabase) GetEvents(arg0, arg1 string) ([]models.HistoryEvent, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetEvents", arg0, arg1)
ret0, _ := ret[0].([]models.HistoryEvent)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetEvents indicates an expected call of GetEvents.
func (mr *MockDatabaseMockRecorder) GetEvents(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEvents", reflect.TypeOf((*MockDatabase)(nil).GetEvents), arg0, arg1)
}
// Select mocks base method.
func (m *MockDatabase) Select(arg0 int) (records.Record, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Select", arg0)
ret0, _ := ret[0].(records.Record)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Select indicates an expected call of Select.
func (mr *MockDatabaseMockRecorder) Select(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Select", reflect.TypeOf((*MockDatabase)(nil).Select), arg0)
}
// SelectAll mocks base method.
func (m *MockDatabase) SelectAll() []records.Record {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SelectAll")
ret0, _ := ret[0].([]records.Record)
return ret0
}
// SelectAll indicates an expected call of SelectAll.
func (mr *MockDatabaseMockRecorder) SelectAll() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SelectAll", reflect.TypeOf((*MockDatabase)(nil).SelectAll))
}
// Update mocks base method.
func (m *MockDatabase) Update(arg0 int, arg1 records.Record) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Update", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// Update indicates an expected call of Update.
func (mr *MockDatabaseMockRecorder) Update(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockDatabase)(nil).Update), arg0, arg1)
}

View File

@@ -0,0 +1,26 @@
package server
import (
"encoding/json"
"net/http"
)
func (h *handlers) getRecords(w http.ResponseWriter, r *http.Request) {
accept := r.Header.Get("Accept")
var contentType string
switch accept {
case "", "application/json":
contentType = "application/json"
default:
httpError(w, http.StatusBadRequest, `content type "`+accept+`" is not supported`)
}
w.Header().Set("Content-Type", contentType)
records := h.db.SelectAll()
encoder := json.NewEncoder(w)
// TODO check Accept header and return Content-Type header
if err := encoder.Encode(records); err != nil {
h.logger.Error(err)
httpError(w, http.StatusInternalServerError, "")
}
}

View File

@@ -0,0 +1,90 @@
package server
import (
"net"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/qdm12/ddns-updater/internal/constants"
"github.com/qdm12/ddns-updater/internal/data/mock_data"
"github.com/qdm12/ddns-updater/internal/models"
"github.com/qdm12/ddns-updater/internal/records"
"github.com/qdm12/ddns-updater/internal/settings/mock_settings"
"github.com/stretchr/testify/assert"
)
func Test_handlers_getRecords(t *testing.T) {
t.Parallel()
exampleTime := time.Unix(1000, 0)
exampleRecord := records.Record{
History: models.History{
models.HistoryEvent{
IP: net.IP{127, 0, 0, 1},
Time: exampleTime,
},
},
Status: constants.SUCCESS,
Message: "message",
Time: exampleTime,
LastBan: &exampleTime,
}
testCases := map[string]struct {
acceptHeader string
records []records.Record
responseBody string
}{
"empty records": {
records: []records.Record{},
responseBody: "[]\n",
},
"single record": {
records: []records.Record{
exampleRecord,
},
responseBody: `[{"Settings":{"a":{}},"History":[{"ip":"127.0.0.1","time":"1970-01-01T00:16:40Z"}],"Status":"success","Message":"message","Time":"1970-01-01T00:16:40Z","LastBan":"1970-01-01T00:16:40Z"}]` + "\n", // nolint:lll
},
}
for name, testCase := range testCases {
testCase := testCase
t.Run(name, func(t *testing.T) {
t.Parallel()
ctrl := gomock.NewController(t)
// Set the settings interface on each record
for i := range testCase.records {
settings := mock_settings.NewMockSettings(ctrl)
const json = `{"a":{}}`
settings.EXPECT().MarshalJSON().Return([]byte(json), nil)
testCase.records[i].Settings = settings
}
db := mock_data.NewMockDatabase(ctrl)
db.EXPECT().SelectAll().Return(testCase.records)
handlers := &handlers{
db: db,
}
w := httptest.NewRecorder()
r := &http.Request{
Header: http.Header{
"Accept": []string{testCase.acceptHeader},
},
}
handlers.getRecords(w, r)
response := w.Result()
assert.Equal(t, http.StatusOK, response.StatusCode)
assert.Equal(t, testCase.responseBody, w.Body.String())
_ = response.Body.Close()
})
}
}

View File

@@ -10,6 +10,7 @@ import (
"github.com/go-chi/chi/middleware"
"github.com/qdm12/ddns-updater/internal/data"
"github.com/qdm12/ddns-updater/internal/update"
"github.com/qdm12/golibs/logging"
)
type handlers struct {
@@ -18,11 +19,12 @@ type handlers struct {
db data.Database
runner update.Runner
indexTemplate *template.Template
logger logging.Logger
// Mockable functions
timeNow func() time.Time
}
func newHandler(ctx context.Context, rootURL, uiDir string,
func newHandler(ctx context.Context, rootURL, uiDir string, logger logging.Logger,
db data.Database, runner update.Runner) http.Handler {
indexTemplate := template.Must(template.ParseFiles(uiDir + "/index.html"))
@@ -30,6 +32,7 @@ func newHandler(ctx context.Context, rootURL, uiDir string,
ctx: ctx,
db: db,
indexTemplate: indexTemplate,
logger: logger,
// TODO build information
timeNow: time.Now,
runner: runner,
@@ -37,9 +40,10 @@ func newHandler(ctx context.Context, rootURL, uiDir string,
router := chi.NewRouter()
router.Use(middleware.Logger, middleware.CleanPath)
router.Use(middleware.Logger, middleware.CleanPath) // TODO use custom logging middleware
router.Get(rootURL+"/", handlers.index)
router.Get(rootURL+"/api/v1/records", handlers.getRecords)
router.Get(rootURL+"/update", handlers.update)

View File

@@ -23,7 +23,7 @@ type server struct {
func New(ctx context.Context, address, rootURL, uiDir string, db data.Database, logger logging.Logger,
runner update.Runner) Server {
handler := newHandler(ctx, rootURL, uiDir, db, runner)
handler := newHandler(ctx, rootURL, uiDir, logger, db, runner)
return &server{
address: address,
logger: logger,

View File

@@ -28,7 +28,7 @@ type cloudflare struct {
zoneIdentifier string
proxied bool
ttl uint
matcher regex.Matcher
matcher regex.Matcher `json:"-"`
}
func NewCloudflare(data json.RawMessage, domain, host string, ipVersion ipversion.IPVersion,
@@ -112,6 +112,10 @@ func (c *cloudflare) BuildDomainName() string {
return buildDomainName(c.host, c.domain)
}
func (c *cloudflare) MarshalJSON() (b []byte, err error) {
return json.Marshal(c)
}
func (c *cloudflare) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", c.BuildDomainName(), c.BuildDomainName())),

View File

@@ -85,6 +85,10 @@ func (d *ddnss) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *ddnss) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *ddnss) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -73,6 +73,10 @@ func (d *digitalOcean) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *digitalOcean) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *digitalOcean) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -24,7 +24,7 @@ type dnsomatic struct {
username string
password string
useProviderIP bool
matcher regex.Matcher
matcher regex.Matcher `json:"-"`
}
func NewDNSOMatic(data json.RawMessage, domain, host string, ipVersion ipversion.IPVersion,
@@ -90,6 +90,10 @@ func (d *dnsomatic) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *dnsomatic) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *dnsomatic) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -73,6 +73,10 @@ func (d *dnspod) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *dnspod) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *dnspod) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -89,6 +89,10 @@ func (d *donDominio) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *donDominio) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *donDominio) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -21,7 +21,7 @@ type dreamhost struct {
host string
ipVersion ipversion.IPVersion
key string
matcher regex.Matcher
matcher regex.Matcher `json:"-"`
}
func NewDreamhost(data json.RawMessage, domain, host string, ipVersion ipversion.IPVersion,
@@ -82,6 +82,10 @@ func (d *dreamhost) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *dreamhost) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *dreamhost) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -21,7 +21,7 @@ type duckdns struct {
ipVersion ipversion.IPVersion
token string
useProviderIP bool
matcher regex.Matcher
matcher regex.Matcher `json:"-"`
}
func NewDuckdns(data json.RawMessage, domain, host string, ipVersion ipversion.IPVersion,
@@ -81,6 +81,10 @@ func (d *duckdns) BuildDomainName() string {
return buildDomainName(d.host, "duckdns.org")
}
func (d *duckdns) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *duckdns) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -84,6 +84,10 @@ func (d *dyn) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *dyn) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *dyn) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -77,6 +77,10 @@ func (d *dynV6) BuildDomainName() string {
return buildDomainName(d.host, d.domain)
}
func (d *dynV6) MarshalJSON() (b []byte, err error) {
return json.Marshal(d)
}
func (d *dynV6) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", d.BuildDomainName(), d.BuildDomainName())),

View File

@@ -74,6 +74,10 @@ func (f *freedns) BuildDomainName() string {
return buildDomainName(f.host, f.domain)
}
func (f *freedns) MarshalJSON() (b []byte, err error) {
return json.Marshal(f)
}
func (f *freedns) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", f.BuildDomainName(), f.BuildDomainName())),

View File

@@ -76,6 +76,10 @@ func (g *gandi) BuildDomainName() string {
return buildDomainName(g.host, g.domain)
}
func (g *gandi) MarshalJSON() (b []byte, err error) {
return json.Marshal(g)
}
func (g *gandi) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", g.BuildDomainName(), g.BuildDomainName())),

View File

@@ -22,7 +22,7 @@ type godaddy struct {
ipVersion ipversion.IPVersion
key string
secret string
matcher regex.Matcher
matcher regex.Matcher `json:"-"`
}
func NewGodaddy(data json.RawMessage, domain, host string, ipVersion ipversion.IPVersion,
@@ -82,6 +82,10 @@ func (g *godaddy) BuildDomainName() string {
return buildDomainName(g.host, g.domain)
}
func (g *godaddy) MarshalJSON() (b []byte, err error) {
return json.Marshal(g)
}
func (g *godaddy) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", g.BuildDomainName(), g.BuildDomainName())),

View File

@@ -84,6 +84,10 @@ func (g *google) BuildDomainName() string {
return buildDomainName(g.host, g.domain)
}
func (g *google) MarshalJSON() (b []byte, err error) {
return json.Marshal(g)
}
func (g *google) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", g.BuildDomainName(), g.BuildDomainName())),

View File

@@ -78,6 +78,10 @@ func (h *he) BuildDomainName() string {
return buildDomainName(h.host, h.domain)
}
func (h *he) MarshalJSON() (b []byte, err error) {
return json.Marshal(h)
}
func (h *he) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", h.BuildDomainName(), h.BuildDomainName())),

View File

@@ -85,6 +85,10 @@ func (i *infomaniak) BuildDomainName() string {
return buildDomainName(i.host, i.domain)
}
func (i *infomaniak) MarshalJSON() (b []byte, err error) {
return json.Marshal(i)
}
func (i *infomaniak) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", i.BuildDomainName(), i.BuildDomainName())),

View File

@@ -77,6 +77,10 @@ func (l *linode) BuildDomainName() string {
return buildDomainName(l.host, l.domain)
}
func (l *linode) MarshalJSON() (b []byte, err error) {
return json.Marshal(l)
}
func (l *linode) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", l.BuildDomainName(), l.BuildDomainName())),

View File

@@ -81,6 +81,10 @@ func (l *luaDNS) BuildDomainName() string {
return buildDomainName(l.host, l.domain)
}
func (l *luaDNS) MarshalJSON() (b []byte, err error) {
return json.Marshal(l)
}
func (l *luaDNS) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", l.BuildDomainName(), l.BuildDomainName())),

View File

@@ -0,0 +1,167 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/qdm12/ddns-updater/internal/settings (interfaces: Settings)
// Package mock_settings is a generated GoMock package.
package mock_settings
import (
context "context"
net "net"
http "net/http"
reflect "reflect"
gomock "github.com/golang/mock/gomock"
models "github.com/qdm12/ddns-updater/internal/models"
ipversion "github.com/qdm12/ddns-updater/pkg/publicip/ipversion"
)
// MockSettings is a mock of Settings interface.
type MockSettings struct {
ctrl *gomock.Controller
recorder *MockSettingsMockRecorder
}
// MockSettingsMockRecorder is the mock recorder for MockSettings.
type MockSettingsMockRecorder struct {
mock *MockSettings
}
// NewMockSettings creates a new mock instance.
func NewMockSettings(ctrl *gomock.Controller) *MockSettings {
mock := &MockSettings{ctrl: ctrl}
mock.recorder = &MockSettingsMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockSettings) EXPECT() *MockSettingsMockRecorder {
return m.recorder
}
// BuildDomainName mocks base method.
func (m *MockSettings) BuildDomainName() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BuildDomainName")
ret0, _ := ret[0].(string)
return ret0
}
// BuildDomainName indicates an expected call of BuildDomainName.
func (mr *MockSettingsMockRecorder) BuildDomainName() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildDomainName", reflect.TypeOf((*MockSettings)(nil).BuildDomainName))
}
// Domain mocks base method.
func (m *MockSettings) Domain() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Domain")
ret0, _ := ret[0].(string)
return ret0
}
// Domain indicates an expected call of Domain.
func (mr *MockSettingsMockRecorder) Domain() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Domain", reflect.TypeOf((*MockSettings)(nil).Domain))
}
// HTML mocks base method.
func (m *MockSettings) HTML() models.HTMLRow {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "HTML")
ret0, _ := ret[0].(models.HTMLRow)
return ret0
}
// HTML indicates an expected call of HTML.
func (mr *MockSettingsMockRecorder) HTML() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HTML", reflect.TypeOf((*MockSettings)(nil).HTML))
}
// Host mocks base method.
func (m *MockSettings) Host() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Host")
ret0, _ := ret[0].(string)
return ret0
}
// Host indicates an expected call of Host.
func (mr *MockSettingsMockRecorder) Host() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Host", reflect.TypeOf((*MockSettings)(nil).Host))
}
// IPVersion mocks base method.
func (m *MockSettings) IPVersion() ipversion.IPVersion {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "IPVersion")
ret0, _ := ret[0].(ipversion.IPVersion)
return ret0
}
// IPVersion indicates an expected call of IPVersion.
func (mr *MockSettingsMockRecorder) IPVersion() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IPVersion", reflect.TypeOf((*MockSettings)(nil).IPVersion))
}
// MarshalJSON mocks base method.
func (m *MockSettings) MarshalJSON() ([]byte, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "MarshalJSON")
ret0, _ := ret[0].([]byte)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// MarshalJSON indicates an expected call of MarshalJSON.
func (mr *MockSettingsMockRecorder) MarshalJSON() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "MarshalJSON", reflect.TypeOf((*MockSettings)(nil).MarshalJSON))
}
// Proxied mocks base method.
func (m *MockSettings) Proxied() bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Proxied")
ret0, _ := ret[0].(bool)
return ret0
}
// Proxied indicates an expected call of Proxied.
func (mr *MockSettingsMockRecorder) Proxied() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Proxied", reflect.TypeOf((*MockSettings)(nil).Proxied))
}
// String mocks base method.
func (m *MockSettings) String() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "String")
ret0, _ := ret[0].(string)
return ret0
}
// String indicates an expected call of String.
func (mr *MockSettingsMockRecorder) String() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "String", reflect.TypeOf((*MockSettings)(nil).String))
}
// Update mocks base method.
func (m *MockSettings) Update(arg0 context.Context, arg1 *http.Client, arg2 net.IP) (net.IP, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Update", arg0, arg1, arg2)
ret0, _ := ret[0].(net.IP)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// Update indicates an expected call of Update.
func (mr *MockSettingsMockRecorder) Update(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Update", reflect.TypeOf((*MockSettings)(nil).Update), arg0, arg1, arg2)
}

View File

@@ -21,7 +21,7 @@ type namecheap struct {
ipVersion ipversion.IPVersion
password string
useProviderIP bool
matcher regex.Matcher
matcher regex.Matcher `json:"-"`
}
func NewNamecheap(data json.RawMessage, domain, host string, ipVersion ipversion.IPVersion,
@@ -81,6 +81,10 @@ func (n *namecheap) BuildDomainName() string {
return buildDomainName(n.host, n.domain)
}
func (n *namecheap) MarshalJSON() (b []byte, err error) {
return json.Marshal(n)
}
func (n *namecheap) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", n.BuildDomainName(), n.BuildDomainName())),

View File

@@ -75,6 +75,10 @@ func (n *njalla) BuildDomainName() string {
return buildDomainName(n.host, n.domain)
}
func (n *njalla) MarshalJSON() (b []byte, err error) {
return json.Marshal(n)
}
func (n *njalla) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", n.BuildDomainName(), n.BuildDomainName())),

View File

@@ -89,6 +89,10 @@ func (n *noip) BuildDomainName() string {
return buildDomainName(n.host, n.domain)
}
func (n *noip) MarshalJSON() (b []byte, err error) {
return json.Marshal(n)
}
func (n *noip) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", n.BuildDomainName(), n.BuildDomainName())),

View File

@@ -84,6 +84,10 @@ func (o *opendns) BuildDomainName() string {
return buildDomainName(o.host, o.domain)
}
func (o *opendns) MarshalJSON() (b []byte, err error) {
return json.Marshal(o)
}
func (o *opendns) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", o.BuildDomainName(), o.BuildDomainName())),

View File

@@ -111,6 +111,10 @@ func (o *ovh) BuildDomainName() string {
return buildDomainName(o.host, o.domain)
}
func (o *ovh) MarshalJSON() (b []byte, err error) {
return json.Marshal(o)
}
func (o *ovh) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", o.BuildDomainName(), o.BuildDomainName())),

View File

@@ -84,6 +84,10 @@ func (sd *selfhostde) BuildDomainName() string {
return buildDomainName(sd.host, sd.domain)
}
func (sd *selfhostde) MarshalJSON() (b []byte, err error) {
return json.Marshal(sd)
}
func (sd *selfhostde) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", sd.BuildDomainName(), sd.BuildDomainName())),

View File

@@ -15,6 +15,8 @@ import (
"github.com/qdm12/ddns-updater/pkg/publicip/ipversion"
)
//go:generate mockgen -destination=mock_$GOPACKAGE/$GOFILE . Settings
type Settings interface {
String() string
Domain() string
@@ -24,6 +26,7 @@ type Settings interface {
Proxied() bool
IPVersion() ipversion.IPVersion
Update(ctx context.Context, client *http.Client, ip net.IP) (newIP net.IP, err error)
MarshalJSON() (b []byte, err error)
}
type Constructor func(data json.RawMessage, domain string, host string, ipVersion ipversion.IPVersion,

View File

@@ -89,6 +89,10 @@ func (s *spdyn) BuildDomainName() string {
return buildDomainName(s.host, s.domain)
}
func (s *spdyn) MarshalJSON() (b []byte, err error) {
return json.Marshal(s)
}
func (s *spdyn) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", s.BuildDomainName(), s.BuildDomainName())),

View File

@@ -79,6 +79,10 @@ func (s *strato) BuildDomainName() string {
return buildDomainName(s.host, s.domain)
}
func (s *strato) MarshalJSON() (b []byte, err error) {
return json.Marshal(s)
}
func (s *strato) HTML() models.HTMLRow {
return models.HTMLRow{
Domain: models.HTML(fmt.Sprintf("<a href=\"http://%s\">%s</a>", s.BuildDomainName(), s.BuildDomainName())),