5 "github.com/jhalter/mobius/hotline"
6 "github.com/stretchr/testify/mock"
14 // loadFromYAMLFile loads data from a YAML file into the provided data structure.
15 func loadFromYAMLFile(path string, data interface{}) error {
16 fh, err := os.Open(path)
22 decoder := yaml.NewDecoder(fh)
23 return decoder.Decode(data)
26 type YAMLAccountManager struct {
27 accounts map[string]hotline.Account
33 func NewYAMLAccountManager(accountDir string) (*YAMLAccountManager, error) {
34 accountMgr := YAMLAccountManager{
35 accountDir: accountDir,
36 accounts: make(map[string]hotline.Account),
39 matches, err := filepath.Glob(filepath.Join(accountDir, "*.yaml"))
41 return nil, fmt.Errorf("list account files: %w", err)
44 if len(matches) == 0 {
45 return nil, fmt.Errorf("no accounts found in directory: %s", accountDir)
48 for _, file := range matches {
49 var account hotline.Account
50 if err = loadFromYAMLFile(file, &account); err != nil {
51 return nil, fmt.Errorf("error loading account %s: %w", file, err)
53 accountMgr.accounts[account.Login] = account
56 return &accountMgr, nil
59 func (am *YAMLAccountManager) Create(account hotline.Account) error {
63 // Create account file, returning an error if one already exists.
64 file, err := os.OpenFile(
65 filepath.Join(am.accountDir, path.Join("/", account.Login+".yaml")),
66 os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0644,
69 return fmt.Errorf("create account file: %w", err)
73 b, err := yaml.Marshal(account)
75 return fmt.Errorf("marshal account to YAML: %v", err)
78 _, err = file.Write(b)
80 return fmt.Errorf("write account file: %w", err)
83 am.accounts[account.Login] = account
88 func (am *YAMLAccountManager) Update(account hotline.Account, newLogin string) error {
92 // If the login has changed, rename the account file.
93 if account.Login != newLogin {
95 filepath.Join(am.accountDir, path.Join("/", account.Login)+".yaml"),
96 filepath.Join(am.accountDir, path.Join("/", newLogin)+".yaml"),
99 return fmt.Errorf("error renaming account file: %w", err)
102 account.Login = newLogin
103 am.accounts[newLogin] = account
105 delete(am.accounts, account.Login)
108 out, err := yaml.Marshal(&account)
113 if err := os.WriteFile(filepath.Join(am.accountDir, newLogin+".yaml"), out, 0644); err != nil {
114 return fmt.Errorf("error writing account file: %w", err)
117 am.accounts[account.Login] = account
122 func (am *YAMLAccountManager) Get(login string) *hotline.Account {
126 account, ok := am.accounts[login]
134 func (am *YAMLAccountManager) List() []hotline.Account {
138 var accounts []hotline.Account
139 for _, account := range am.accounts {
140 accounts = append(accounts, account)
146 func (am *YAMLAccountManager) Delete(login string) error {
150 err := os.Remove(filepath.Join(am.accountDir, path.Join("/", login+".yaml")))
152 return fmt.Errorf("delete account file: %v", err)
155 delete(am.accounts, login)
160 type MockAccountManager struct {
164 func (m *MockAccountManager) Create(account hotline.Account) error {
165 args := m.Called(account)
170 func (m *MockAccountManager) Update(account hotline.Account, newLogin string) error {
171 args := m.Called(account, newLogin)
176 func (m *MockAccountManager) Get(login string) *hotline.Account {
177 args := m.Called(login)
179 return args.Get(0).(*hotline.Account)
182 func (m *MockAccountManager) List() []hotline.Account {
185 return args.Get(0).([]hotline.Account)
188 func (m *MockAccountManager) Delete(login string) error {
189 args := m.Called(login)