diff --git a/persistence/profile.go b/persistence/profile.go index efbb067..893e449 100644 --- a/persistence/profile.go +++ b/persistence/profile.go @@ -24,10 +24,32 @@ type Profile struct { DB *sql.DB } +/** + * Custom error + */ +type ErrTargetAlreadyExists struct { + target string +} +func (err ErrTargetAlreadyExists) Error() string { + return fmt.Sprintf("Target already exists: %s", err.target) +} -// Create a new profile in the given location. -// `path` is a directory + +/** + * Create a new profile in the given location. + * Fails if target location already exists (i.e., is a file or directory). + * + * args: + * - target_dir: location to create the new profile directory + * + * returns: + * - the newly created Profile + */ func NewProfile(target_dir string) (Profile, error) { + if file_exists(target_dir) { + return Profile{}, ErrTargetAlreadyExists{target_dir} + } + user_list_file := path.Join(target_dir, "users.txt") settings_file := path.Join(target_dir, "settings.yaml") sqlite_file := path.Join(target_dir, "twitter.db") @@ -35,23 +57,16 @@ func NewProfile(target_dir string) (Profile, error) { images_dir := path.Join(target_dir, "images") videos_dir := path.Join(target_dir, "videos") - - for _, file := range []string{ - user_list_file, - settings_file, - sqlite_file, - profile_images_dir, - images_dir, - videos_dir, - } { - if file_exists(file) { - return Profile{}, fmt.Errorf("File already exists: %s", file) - } + // Create the directory + fmt.Printf("Creating new profile: %s\n", target_dir) + err := os.Mkdir(target_dir, os.FileMode(0755)) + if err != nil { + return Profile{}, err } // Create `twitter.db` - fmt.Printf("Creating %s\n", sqlite_file) - db, err := sql.Open("sqlite3", sqlite_file) + fmt.Printf("Creating............. %s\n", sqlite_file) + db, err := sql.Open("sqlite3", sqlite_file + "?_foreign_keys=on") if err != nil { return Profile{}, err } @@ -61,14 +76,14 @@ func NewProfile(target_dir string) (Profile, error) { } // Create `users.txt` - fmt.Printf("Creating %s\n", user_list_file) + fmt.Printf("Creating............. %s\n", user_list_file) err = os.WriteFile(user_list_file, []byte{}, os.FileMode(0644)) if err != nil { return Profile{}, err } // Create `settings.yaml` - fmt.Printf("Creating %s\n", settings_file) + fmt.Printf("Creating............. %s\n", settings_file) settings := Settings{} data, err := yaml.Marshal(&settings) if err != nil { @@ -80,21 +95,21 @@ func NewProfile(target_dir string) (Profile, error) { } // Create `profile_images` - fmt.Printf("Creating %s/\n", profile_images_dir) + fmt.Printf("Creating............. %s/\n", profile_images_dir) err = os.Mkdir(profile_images_dir, os.FileMode(0755)) if err != nil { return Profile{}, err } // Create `images` - fmt.Printf("Creating %s/\n", images_dir) + fmt.Printf("Creating............. %s/\n", images_dir) err = os.Mkdir(images_dir, os.FileMode(0755)) if err != nil { return Profile{}, err } // Create `videos` - fmt.Printf("Creating %s/\n", videos_dir) + fmt.Printf("Creating............. %s/\n", videos_dir) err = os.Mkdir(videos_dir, os.FileMode(0755)) if err != nil { return Profile{}, err @@ -104,6 +119,15 @@ func NewProfile(target_dir string) (Profile, error) { } +/** + * Loads the profile at the given location. Fails if the given directory is not a Profile. + * + * args: + * - profile_dir: location to check for the profile + * + * returns: + * - the loaded Profile + */ func LoadProfile(profile_dir string) (Profile, error) { user_list_file := path.Join(profile_dir, "users.txt") settings_file := path.Join(profile_dir, "settings.yaml") diff --git a/persistence/profile_test.go b/persistence/profile_test.go index 896d3d2..a9b7efa 100644 --- a/persistence/profile_test.go +++ b/persistence/profile_test.go @@ -29,21 +29,41 @@ func isdir_map(is_dir bool) string { } -func TestNewProfile(t *testing.T) { - profile_path := "test_profiles/TestNewProfile" - if !file_exists(profile_path) { - err := os.Mkdir(profile_path, 0755) +/** + * Should refuse to create a Profile if the target already exists (i.e., is a file or directory). + */ +func TestNewProfileInvalidPath(t *testing.T) { + gibberish_path := "test_profiles/fjlwrefuvaaw23efwm" + if file_exists(gibberish_path) { + err := os.RemoveAll(gibberish_path) if err != nil { panic(err) } } - - contents, err := os.ReadDir(profile_path) + err := os.Mkdir(gibberish_path, 0755) if err != nil { panic(err) } - if len(contents) != 0 { - t.Fatalf("test_profile not empty at start of test!") + _, err = persistence.NewProfile(gibberish_path) + if err == nil { + t.Errorf("Should have failed to create a profile in an already existing directory!") + } + if _, is_right_type := err.(persistence.ErrTargetAlreadyExists); !is_right_type { + t.Errorf("Expected 'ErrTargetAlreadyExists' error, got %T instead", err) + } +} + + +/** + * Should correctly create a new Profile + */ +func TestNewProfile(t *testing.T) { + profile_path := "test_profiles/TestNewProfile" + if file_exists(profile_path) { + err := os.RemoveAll(profile_path) + if err != nil { + panic(err) + } } profile, err := persistence.NewProfile(profile_path) @@ -59,7 +79,7 @@ func TestNewProfile(t *testing.T) { } // Check files were created - contents, err = os.ReadDir(profile_path) + contents, err := os.ReadDir(profile_path) if err != nil { panic(err) } @@ -86,24 +106,20 @@ func TestNewProfile(t *testing.T) { } } + +/** + * Should correctly load the Profile + */ func TestLoadProfile(t *testing.T) { profile_path := "test_profiles/TestLoadProfile" - if !file_exists(profile_path) { - err := os.Mkdir(profile_path, 0755) + if file_exists(profile_path) { + err := os.RemoveAll(profile_path) if err != nil { panic(err) } } - contents, err := os.ReadDir(profile_path) - if err != nil { - panic(err) - } - if len(contents) != 0 { - t.Fatalf("test_profile not empty at start of test!") - } - - _, err = persistence.NewProfile(profile_path) + _, err := persistence.NewProfile(profile_path) if err != nil { t.Fatalf(err.Error()) } @@ -126,5 +142,4 @@ func TestLoadProfile(t *testing.T) { if len(profile.UsersList) != 2 { t.Errorf("Expected 2 users, got %v", profile.UsersList) } - }