feat: add user store tests

This commit is contained in:
Steven 2023-06-20 20:04:40 +08:00
parent 92d50eabf3
commit c3ce03ffe5
10 changed files with 118 additions and 169 deletions

2
.gitignore vendored
View File

@ -7,6 +7,8 @@ tmp
# Frontend asset
web/dist
web-r
# build folder
build

View File

@ -19,9 +19,6 @@ import (
//go:embed migration
var migrationFS embed.FS
//go:embed seed
var seedFS embed.FS
type DB struct {
profile *profile.Profile
// sqlite db connection instance
@ -122,9 +119,6 @@ func (db *DB) Open(ctx context.Context) (err error) {
if err := db.applyLatestSchema(ctx); err != nil {
return fmt.Errorf("failed to apply latest schema: %w", err)
}
if err := db.seed(ctx); err != nil {
return fmt.Errorf("failed to seed: %w", err)
}
}
}
@ -191,28 +185,6 @@ func (db *DB) applyMigrationForMinorVersion(ctx context.Context, minorVersion st
return tx.Commit()
}
func (db *DB) seed(ctx context.Context) error {
filenames, err := fs.Glob(seedFS, fmt.Sprintf("%s/*.sql", "seed"))
if err != nil {
return fmt.Errorf("failed to read seed files, err: %w", err)
}
sort.Strings(filenames)
// Loop over all seed files and execute them in order.
for _, filename := range filenames {
buf, err := seedFS.ReadFile(filename)
if err != nil {
return fmt.Errorf("failed to read seed file, filename=%s err=%w", filename, err)
}
stmt := string(buf)
if err := db.execute(ctx, stmt); err != nil {
return fmt.Errorf("seed error: statement:%s err=%w", stmt, err)
}
}
return nil
}
// execute runs a single SQL statement within a transaction.
func (db *DB) execute(ctx context.Context, stmt string) error {
tx, err := db.DBInstance.Begin()

View File

@ -1,11 +0,0 @@
DELETE FROM shortcut;
DELETE FROM workspace_user;
DELETE FROM user_setting;
DELETE FROM user;
DELETE FROM workspace_setting;
DELETE FROM workspace;

View File

@ -1,35 +0,0 @@
INSERT INTO
user (
`id`,
`username`,
`nickname`,
`email`,
`password_hash`
)
VALUES
(
11,
'frank',
'Frank',
'frank@shortify.demo',
-- raw password: secret
'$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK'
);
INSERT INTO
user (
`id`,
`username`,
`nickname`,
`email`,
`password_hash`
)
VALUES
(
12,
'bob',
'Bob',
'bob@shortify.demo',
-- raw password: secret
'$2a$14$ajq8Q7fbtFRQvXpdCq7Jcuy.Rx1h/L4J60Otx.gyNLbAYctGMJ9tK'
);

View File

@ -1,14 +0,0 @@
INSERT INTO
workspace (
`id`,
`name`,
`title`,
`description`
)
VALUES
(
1,
'minecraft',
'minecraft',
''
);

View File

@ -1,25 +0,0 @@
INSERT INTO
workspace_user (
`workspace_id`,
`user_id`,
`role`
)
VALUES
(
1,
11,
'ADMIN'
);
INSERT INTO
workspace_user (
`workspace_id`,
`user_id`,
`role`
)
VALUES
(
1,
12,
'USER'
);

View File

@ -1,56 +0,0 @@
INSERT INTO
shortcut (
`creator_id`,
`workspace_id`,
`name`,
`link`,
`description`,
`visibility`
)
VALUES
(
11,
1,
'baidu',
'https://baidu.com',
'百度搜索',
'WORKSPACE'
);
INSERT INTO
shortcut (
`creator_id`,
`workspace_id`,
`name`,
`link`,
`description`,
`visibility`
)
VALUES
(
12,
1,
'bl',
'https://bilibili.com',
'B站',
'PUBLIC'
);
INSERT INTO
shortcut (
`creator_id`,
`workspace_id`,
`name`,
`link`,
`description`,
`visibility`
)
VALUES
(
11,
1,
'ph',
'https://producthunt.com',
'PH',
'PRIVATE'
);

25
test/store/store.go Normal file
View File

@ -0,0 +1,25 @@
package teststore
import (
"context"
"fmt"
"testing"
"github.com/boojack/shortify/store"
"github.com/boojack/shortify/store/db"
test "github.com/boojack/shortify/test"
// sqlite driver.
_ "modernc.org/sqlite"
)
func NewTestingStore(ctx context.Context, t *testing.T) *store.Store {
profile := test.GetTestingProfile(t)
db := db.NewDB(profile)
if err := db.Open(ctx); err != nil {
fmt.Printf("failed to open db, error: %+v\n", err)
}
store := store.New(db.DBInstance, profile)
return store
}

54
test/store/user_test.go Normal file
View File

@ -0,0 +1,54 @@
package teststore
import (
"context"
"testing"
"github.com/boojack/shortify/store"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/bcrypt"
)
func TestUserStore(t *testing.T) {
ctx := context.Background()
ts := NewTestingStore(ctx, t)
user, err := createTestingAdminUser(ctx, ts)
require.NoError(t, err)
users, err := ts.ListUsers(ctx, &store.FindUser{})
require.NoError(t, err)
require.Equal(t, 1, len(users))
require.Equal(t, store.RoleAdmin, users[0].Role)
require.Equal(t, user, users[0])
userPatchNickname := "test_nickname_2"
user, err = ts.UpdateUser(ctx, &store.UpdateUser{
ID: user.ID,
Nickname: &userPatchNickname,
})
require.NoError(t, err)
require.Equal(t, userPatchNickname, user.Nickname)
err = ts.DeleteUser(ctx, &store.DeleteUser{
ID: user.ID,
})
require.NoError(t, err)
users, err = ts.ListUsers(ctx, &store.FindUser{})
require.NoError(t, err)
require.Equal(t, 0, len(users))
}
// createTestingAdminUser creates a testing admin user.
func createTestingAdminUser(ctx context.Context, ts *store.Store) (*store.User, error) {
userCreate := &store.User{
Role: store.RoleAdmin,
Username: "test",
Nickname: "test_nickname",
Email: "test@test.com",
}
passwordHash, err := bcrypt.GenerateFromPassword([]byte("test-password"), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
userCreate.PasswordHash = string(passwordHash)
user, err := ts.CreateUser(ctx, userCreate)
return user, err
}

37
test/test.go Normal file
View File

@ -0,0 +1,37 @@
package tests
import (
"fmt"
"net"
"testing"
"github.com/boojack/shortify/server/profile"
"github.com/boojack/shortify/server/version"
)
func getUnusedPort() int {
// Get a random unused port
listener, err := net.Listen("tcp", "localhost:0")
if err != nil {
panic(err)
}
defer listener.Close()
// Get the port number
port := listener.Addr().(*net.TCPAddr).Port
return port
}
func GetTestingProfile(t *testing.T) *profile.Profile {
// Get a temporary directory for the test data.
dir := t.TempDir()
mode := "dev"
port := getUnusedPort()
return &profile.Profile{
Mode: mode,
Port: port,
Data: dir,
DSN: fmt.Sprintf("%s/shortify_%s.db", dir, mode),
Version: version.GetCurrentVersion(mode),
}
}