github.com/GGP1/kure@v0.8.4/commands/import/import_test.go (about)

     1  package importt
     2  
     3  import (
     4  	"os"
     5  	"runtime"
     6  	"testing"
     7  
     8  	cmdutil "github.com/GGP1/kure/commands"
     9  	"github.com/GGP1/kure/db/entry"
    10  	"github.com/GGP1/kure/pb"
    11  
    12  	"github.com/stretchr/testify/assert"
    13  	"google.golang.org/protobuf/proto"
    14  )
    15  
    16  func TestImport(t *testing.T) {
    17  	db := cmdutil.SetContext(t)
    18  
    19  	cases := []struct {
    20  		expected *pb.Entry
    21  		manager  string
    22  		path     string
    23  	}{
    24  		{
    25  			manager: "Keepass",
    26  			path:    "testdata/test_keepass",
    27  			expected: &pb.Entry{
    28  				Name:     "keepass",
    29  				Username: "test@keepass.com",
    30  				Password: "keepass123",
    31  				URL:      "https://keepass.info/",
    32  				Notes:    "Notes",
    33  				Expires:  "Never",
    34  			},
    35  		},
    36  		{
    37  			manager: "Keepassxc",
    38  			path:    "testdata/test_keepassxc",
    39  			expected: &pb.Entry{
    40  				Name:     "test/keepassxc",
    41  				Username: "test@keepassxc.com",
    42  				Password: "keepassxc123",
    43  				URL:      "https://keepassxc.org",
    44  				Notes:    "Notes",
    45  				Expires:  "Never",
    46  			},
    47  		},
    48  		{
    49  			manager: "1password",
    50  			path:    "testdata/test_1password.csv",
    51  			expected: &pb.Entry{
    52  				Name:     "1password",
    53  				Username: "test@1password.com",
    54  				Password: "1password123",
    55  				URL:      "https://1password.com/",
    56  				Notes:    "Notes.\nMember number: 1234.\nRecovery Codes: The Shire",
    57  				Expires:  "Never",
    58  			},
    59  		},
    60  		{
    61  			manager: "Lastpass",
    62  			path:    "testdata/test_lastpass.csv",
    63  			// Kure will join folders with the entry names
    64  			expected: &pb.Entry{
    65  				Name:     "test/lastpass",
    66  				Username: "test@lastpass.com",
    67  				Password: "lastpass123",
    68  				URL:      "https://lastpass.com/",
    69  				Notes:    "Notes",
    70  				Expires:  "Never",
    71  			},
    72  		},
    73  		{
    74  			manager: "Bitwarden",
    75  			path:    "testdata/test_bitwarden.csv",
    76  			// Kure will join folders with the entry names
    77  			expected: &pb.Entry{
    78  				Name:     "test/bitwarden",
    79  				Username: "test@bitwarden.com",
    80  				Password: "bitwarden123",
    81  				URL:      "https://bitwarden.com/",
    82  				Notes:    "Notes",
    83  				Expires:  "Never",
    84  			},
    85  		},
    86  	}
    87  
    88  	cmd := NewCmd(db)
    89  
    90  	for _, tc := range cases {
    91  		t.Run(tc.manager, func(t *testing.T) {
    92  			cmd.SetArgs([]string{tc.manager})
    93  			cmd.Flags().Set("path", tc.path)
    94  
    95  			err := cmd.Execute()
    96  			assert.NoError(t, err, "Failed importing entries")
    97  
    98  			got, err := entry.Get(db, tc.expected.Name)
    99  			assert.NoError(t, err, "Failed listing entry")
   100  
   101  			equal := proto.Equal(tc.expected, got)
   102  			assert.True(t, equal)
   103  		})
   104  	}
   105  }
   106  
   107  func TestInvalidImport(t *testing.T) {
   108  	db := cmdutil.SetContext(t)
   109  
   110  	cases := []struct {
   111  		desc    string
   112  		manager string
   113  		path    string
   114  	}{
   115  		{
   116  			desc:    "Invalid manager",
   117  			manager: "",
   118  			path:    "testdata/test_keepassx.csv",
   119  		},
   120  		{
   121  			desc:    "Invalid path",
   122  			manager: "keepass",
   123  			path:    "",
   124  		},
   125  		{
   126  			desc:    "Empty file",
   127  			manager: "bitwarden",
   128  			path:    "testdata/test_empty.csv",
   129  		},
   130  		{
   131  			desc:    "Non-existent file",
   132  			manager: "1password",
   133  			path:    "test.csv",
   134  		},
   135  		{
   136  			desc:    "Unsupported manager",
   137  			manager: "unsupported",
   138  			path:    "testdata/test_lastpass.csv",
   139  		},
   140  		{
   141  			desc:    "Invalid format",
   142  			manager: "lastpass",
   143  			path:    "testdata/test_invalid_format.json",
   144  		},
   145  		{
   146  			desc:    "Invalid entry",
   147  			manager: "1password",
   148  			path:    "testdata/test_invalid_entry.csv",
   149  		},
   150  	}
   151  
   152  	cmd := NewCmd(db)
   153  
   154  	for _, tc := range cases {
   155  		t.Run(tc.desc, func(t *testing.T) {
   156  			cmd.Flags().Set("path", tc.path)
   157  			cmd.SetArgs([]string{tc.manager})
   158  
   159  			err := cmd.Execute()
   160  			assert.Error(t, err)
   161  		})
   162  	}
   163  }
   164  
   165  func TestImportAndErase(t *testing.T) {
   166  	db := cmdutil.SetContext(t)
   167  
   168  	tempFile, err := os.CreateTemp("", "*.csv")
   169  	assert.NoError(t, err, "Failed creating temporary file")
   170  	tempFile.WriteString("test")
   171  	tempFile.Close()
   172  
   173  	cmd := NewCmd(db)
   174  	cmd.SetArgs([]string{"keepass"})
   175  	f := cmd.Flags()
   176  	f.Set("path", tempFile.Name())
   177  	f.Set("erase", "true")
   178  
   179  	err = cmd.Execute()
   180  	assert.NoError(t, err, "Failed importing entries")
   181  
   182  	_, err = os.Stat(tempFile.Name())
   183  	assert.Error(t, err, "The file wasn't erased correctly")
   184  }
   185  
   186  func TestImportAndEraseError(t *testing.T) {
   187  	if runtime.GOOS != "windows" {
   188  		t.SkipNow()
   189  	}
   190  	db := cmdutil.SetContext(t)
   191  
   192  	tempFile, err := os.CreateTemp("", "*.csv")
   193  	assert.NoError(t, err, "Failed creating temporary file")
   194  	tempFile.WriteString("test")
   195  
   196  	cmd := NewCmd(db)
   197  	cmd.SetArgs([]string{"lastpass"})
   198  	f := cmd.Flags()
   199  	f.Set("path", tempFile.Name())
   200  	f.Set("erase", "true")
   201  
   202  	// The file attempting to erase is currently being used by another process
   203  	err = cmd.Execute()
   204  	assert.Error(t, err)
   205  }
   206  
   207  func TestCreateTOTP(t *testing.T) {
   208  	db := cmdutil.SetContext(t)
   209  
   210  	cases := []struct {
   211  		desc string
   212  		name string
   213  		raw  string
   214  	}{
   215  		{
   216  			desc: "Create",
   217  			name: "test",
   218  			raw:  "afrtgq",
   219  		},
   220  		{
   221  			desc: "Nothing",
   222  			raw:  "",
   223  		},
   224  	}
   225  
   226  	for _, tc := range cases {
   227  		t.Run(tc.desc, func(t *testing.T) {
   228  			err := createTOTP(db, tc.name, tc.raw)
   229  			assert.NoError(t, err, "Failed creating TOTP")
   230  		})
   231  	}
   232  }
   233  
   234  func TestArgs(t *testing.T) {
   235  	db := cmdutil.SetContext(t)
   236  	cmd := NewCmd(db)
   237  
   238  	t.Run("Supported", func(t *testing.T) {
   239  		managers := []string{"1password", "bitwarden", "keepass", "keepassx", "keepassxc", "lastpass"}
   240  
   241  		for _, m := range managers {
   242  			t.Run(m, func(t *testing.T) {
   243  				err := cmd.Args(cmd, []string{m})
   244  				assert.NoError(t, err)
   245  			})
   246  		}
   247  	})
   248  
   249  	t.Run("Unsupported", func(t *testing.T) {
   250  		invalids := []string{"", "unsupported"}
   251  		for _, inv := range invalids {
   252  			err := cmd.Args(cmd, []string{inv})
   253  			assert.Error(t, err)
   254  		}
   255  	})
   256  }
   257  
   258  func TestPostRun(t *testing.T) {
   259  	NewCmd(nil).PostRun(nil, nil)
   260  }