storj/satellite/console/consoleweb/consoleql/query_test.go

491 lines
14 KiB
Go
Raw Normal View History

2019-01-24 16:26:36 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
2019-01-08 14:54:35 +00:00
// See LICENSE for copying information.
2019-01-24 16:26:36 +00:00
package consoleql_test
2019-01-08 14:54:35 +00:00
import (
"fmt"
"testing"
"time"
"github.com/graphql-go/graphql"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
2019-01-31 13:01:13 +00:00
"go.uber.org/zap/zaptest"
2019-01-08 14:54:35 +00:00
"storj.io/storj/internal/testcontext"
"storj.io/storj/pkg/auth"
2019-01-24 16:26:36 +00:00
"storj.io/storj/satellite"
"storj.io/storj/satellite/console"
"storj.io/storj/satellite/console/consoleauth"
2019-01-24 16:26:36 +00:00
"storj.io/storj/satellite/console/consoleweb/consoleql"
"storj.io/storj/satellite/mailservice"
"storj.io/storj/satellite/payments/stripecoinpayments"
2019-01-24 16:26:36 +00:00
"storj.io/storj/satellite/satellitedb/satellitedbtest"
2019-01-08 14:54:35 +00:00
)
func TestGraphqlQuery(t *testing.T) {
2019-01-24 16:26:36 +00:00
satellitedbtest.Run(t, func(t *testing.T, db satellite.DB) {
ctx := testcontext.New(t)
defer ctx.Cleanup()
2019-01-08 14:54:35 +00:00
2019-01-31 13:01:13 +00:00
log := zaptest.NewLogger(t)
2019-01-08 14:54:35 +00:00
paymentsConfig := stripecoinpayments.Config{}
payments := stripecoinpayments.NewService(log, paymentsConfig, db.Customers(), db.CoinpaymentsTransactions())
2019-01-24 16:26:36 +00:00
service, err := console.NewService(
log,
&consoleauth.Hmac{Secret: []byte("my-suppa-secret-key")},
db.Console(),
db.Rewards(),
payments.Accounts(),
console.TestPasswordCost,
2019-01-24 16:26:36 +00:00
)
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
mailService, err := mailservice.New(log, &discardSender{}, "testdata")
require.NoError(t, err)
defer ctx.Check(mailService.Close)
rootObject := make(map[string]interface{})
rootObject["origin"] = "http://doesntmatter.com/"
rootObject[consoleql.ActivationPath] = "?activationToken="
rootObject[consoleql.LetUsKnowURL] = "letUsKnowURL"
rootObject[consoleql.ContactInfoURL] = "contactInfoURL"
rootObject[consoleql.TermsAndConditionsURL] = "termsAndConditionsURL"
2019-01-24 16:26:36 +00:00
creator := consoleql.TypeCreator{}
err = creator.Create(log, service, mailService)
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: creator.RootQuery(),
Mutation: creator.RootMutation(),
})
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
createUser := console.CreateUser{
FullName: "John",
ShortName: "",
Email: "mtest@mail.test",
Password: "123a123",
2019-01-24 16:26:36 +00:00
}
refUserID := ""
2019-01-08 14:54:35 +00:00
regToken, err := service.CreateRegToken(ctx, 2)
require.NoError(t, err)
rootUser, err := service.CreateUser(ctx, createUser, regToken.Secret, refUserID)
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
t.Run("Activation", func(t *testing.T) {
activationToken, err := service.GenerateActivationToken(
ctx,
rootUser.ID,
"mtest@mail.test",
)
require.NoError(t, err)
err = service.ActivateAccount(ctx, activationToken)
require.NoError(t, err)
rootUser.Email = "mtest@mail.test"
})
2019-01-24 16:26:36 +00:00
token, err := service.Token(ctx, createUser.Email, createUser.Password)
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
sauth, err := service.Authorize(auth.WithAPIKey(ctx, []byte(token)))
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
authCtx := console.WithAuth(ctx, sauth)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
testQuery := func(t *testing.T, query string) interface{} {
result := graphql.Do(graphql.Params{
Schema: schema,
Context: authCtx,
RequestString: query,
RootObject: rootObject,
2019-01-24 16:26:36 +00:00
})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
for _, err := range result.Errors {
assert.NoError(t, err)
}
require.False(t, result.HasErrors())
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
return result.Data
}
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
t.Run("User query", func(t *testing.T) {
testUser := func(t *testing.T, actual map[string]interface{}, expected *console.User) {
assert.Equal(t, expected.ID.String(), actual[consoleql.FieldID])
assert.Equal(t, expected.Email, actual[consoleql.FieldEmail])
assert.Equal(t, expected.FullName, actual[consoleql.FieldFullName])
assert.Equal(t, expected.ShortName, actual[consoleql.FieldShortName])
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(actual[consoleql.FieldCreatedAt].(string)))
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.NoError(t, err)
assert.True(t, expected.CreatedAt.Equal(createdAt))
2019-01-24 16:26:36 +00:00
}
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
t.Run("With ID", func(t *testing.T) {
query := fmt.Sprintf(
"query {user(id:\"%s\"){id,email,fullName,shortName,createdAt}}",
2019-01-24 16:26:36 +00:00
rootUser.ID.String(),
)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
result := testQuery(t, query)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
data := result.(map[string]interface{})
user := data[consoleql.UserQuery].(map[string]interface{})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
testUser(t, user, rootUser)
})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
t.Run("With AuthFallback", func(t *testing.T) {
query := "query {user{id,email,fullName,shortName,createdAt}}"
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
result := testQuery(t, query)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
data := result.(map[string]interface{})
user := data[consoleql.UserQuery].(map[string]interface{})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
testUser(t, user, rootUser)
})
})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
createdProject, err := service.CreateProject(authCtx, console.ProjectInfo{
Name: "TestProject",
2019-01-24 16:26:36 +00:00
})
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
// "query {project(id:\"%s\"){id,name,members(offset:0, limit:50){user{fullName,shortName,email}},apiKeys{name,id,createdAt,projectID}}}"
2019-01-24 16:26:36 +00:00
t.Run("Project query base info", func(t *testing.T) {
query := fmt.Sprintf(
"query {project(id:\"%s\"){id,name,description,createdAt}}",
createdProject.ID.String(),
)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
result := testQuery(t, query)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
data := result.(map[string]interface{})
project := data[consoleql.ProjectQuery].(map[string]interface{})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.Equal(t, createdProject.ID.String(), project[consoleql.FieldID])
assert.Equal(t, createdProject.Name, project[consoleql.FieldName])
assert.Equal(t, createdProject.Description, project[consoleql.FieldDescription])
2019-01-08 14:54:35 +00:00
createdAt := time.Time{}
2019-01-24 16:26:36 +00:00
err := createdAt.UnmarshalText([]byte(project[consoleql.FieldCreatedAt].(string)))
2019-01-08 14:54:35 +00:00
assert.NoError(t, err)
assert.True(t, createdProject.CreatedAt.Equal(createdAt))
2019-01-24 16:26:36 +00:00
})
regTokenUser1, err := service.CreateRegToken(ctx, 2)
require.NoError(t, err)
2019-01-24 16:26:36 +00:00
user1, err := service.CreateUser(authCtx, console.CreateUser{
FullName: "Mickey Last",
ShortName: "Last",
Password: "123a123",
Email: "muu1@mail.test",
}, regTokenUser1.Secret, refUserID)
require.NoError(t, err)
t.Run("Activation", func(t *testing.T) {
activationToken1, err := service.GenerateActivationToken(
ctx,
user1.ID,
"muu1@mail.test",
)
require.NoError(t, err)
err = service.ActivateAccount(ctx, activationToken1)
require.NoError(t, err)
user1.Email = "muu1@mail.test"
})
2019-01-08 14:54:35 +00:00
regTokenUser2, err := service.CreateRegToken(ctx, 2)
require.NoError(t, err)
2019-01-24 16:26:36 +00:00
user2, err := service.CreateUser(authCtx, console.CreateUser{
FullName: "Dubas Name",
ShortName: "Name",
Email: "muu2@mail.test",
Password: "123a123",
}, regTokenUser2.Secret, refUserID)
require.NoError(t, err)
t.Run("Activation", func(t *testing.T) {
activationToken2, err := service.GenerateActivationToken(
ctx,
user2.ID,
"muu2@mail.test",
)
require.NoError(t, err)
err = service.ActivateAccount(ctx, activationToken2)
require.NoError(t, err)
user2.Email = "muu2@mail.test"
})
2019-01-08 14:54:35 +00:00
users, err := service.AddProjectMembers(authCtx, createdProject.ID, []string{
2019-01-24 16:26:36 +00:00
user1.Email,
user2.Email,
})
require.NoError(t, err)
assert.Equal(t, 2, len(users))
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
t.Run("Project query team members", func(t *testing.T) {
query := fmt.Sprintf(
"query {project(id: \"%s\") {members( cursor: { limit: %d, search: \"%s\", page: %d, order: %d, orderDirection: %d } ) { projectMembers{ user { id, fullName, shortName, email, createdAt }, joinedAt }, search, limit, order, offset, pageCount, currentPage, totalCount } } }",
2019-01-24 16:26:36 +00:00
createdProject.ID.String(),
5,
"",
1,
1,
2)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
result := testQuery(t, query)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
data := result.(map[string]interface{})
project := data[consoleql.ProjectQuery].(map[string]interface{})
members := project[consoleql.FieldMembers].(map[string]interface{})
projectMembers := members[consoleql.FieldProjectMembers].([]interface{})
2019-01-08 14:54:35 +00:00
assert.Equal(t, 3, len(projectMembers))
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
testUser := func(t *testing.T, actual map[string]interface{}, expected *console.User) {
assert.Equal(t, expected.Email, actual[consoleql.FieldEmail])
assert.Equal(t, expected.FullName, actual[consoleql.FieldFullName])
assert.Equal(t, expected.ShortName, actual[consoleql.FieldShortName])
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(actual[consoleql.FieldCreatedAt].(string)))
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.NoError(t, err)
assert.True(t, expected.CreatedAt.Equal(createdAt))
2019-01-24 16:26:36 +00:00
}
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
var foundRoot, foundU1, foundU2 bool
for _, entry := range projectMembers {
2019-01-24 16:26:36 +00:00
member := entry.(map[string]interface{})
user := member[consoleql.UserType].(map[string]interface{})
id := user[consoleql.FieldID].(string)
switch id {
case rootUser.ID.String():
foundRoot = true
testUser(t, user, rootUser)
case user1.ID.String():
foundU1 = true
testUser(t, user, user1)
case user2.ID.String():
foundU2 = true
testUser(t, user, user2)
}
}
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.True(t, foundRoot)
assert.True(t, foundU1)
assert.True(t, foundU2)
})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
keyInfo1, _, err := service.CreateAPIKey(authCtx, createdProject.ID, "key1")
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
keyInfo2, _, err := service.CreateAPIKey(authCtx, createdProject.ID, "key2")
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
t.Run("Project query api keys", func(t *testing.T) {
query := fmt.Sprintf(
"query {project(id: \"%s\") {apiKeys( cursor: { limit: %d, search: \"%s\", page: %d, order: %d, orderDirection: %d } ) { apiKeys { id, name, createdAt, projectID }, search, limit, order, offset, pageCount, currentPage, totalCount } } }",
2019-01-24 16:26:36 +00:00
createdProject.ID.String(),
5,
"",
1,
1,
2)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
result := testQuery(t, query)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
data := result.(map[string]interface{})
project := data[consoleql.ProjectQuery].(map[string]interface{})
keys := project[consoleql.FieldAPIKeys].(map[string]interface{})
apiKeys := keys[consoleql.FieldAPIKeys].([]interface{})
2019-01-08 14:54:35 +00:00
assert.Equal(t, 2, len(apiKeys))
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
testAPIKey := func(t *testing.T, actual map[string]interface{}, expected *console.APIKeyInfo) {
assert.Equal(t, expected.Name, actual[consoleql.FieldName])
assert.Equal(t, expected.ProjectID.String(), actual[consoleql.FieldProjectID])
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(actual[consoleql.FieldCreatedAt].(string)))
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.NoError(t, err)
assert.True(t, expected.CreatedAt.Equal(createdAt))
2019-01-24 16:26:36 +00:00
}
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
var foundKey1, foundKey2 bool
2019-01-08 14:54:35 +00:00
for _, entry := range apiKeys {
2019-01-24 16:26:36 +00:00
key := entry.(map[string]interface{})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
id := key[consoleql.FieldID].(string)
switch id {
case keyInfo1.ID.String():
foundKey1 = true
testAPIKey(t, key, keyInfo1)
case keyInfo2.ID.String():
foundKey2 = true
testAPIKey(t, key, keyInfo2)
}
}
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.True(t, foundKey1)
assert.True(t, foundKey2)
})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
project2, err := service.CreateProject(authCtx, console.ProjectInfo{
Name: "Project2",
Description: "Test desc",
2019-01-24 16:26:36 +00:00
})
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
t.Run("MyProjects query", func(t *testing.T) {
query := "query {myProjects{id,name,description,createdAt}}"
result := testQuery(t, query)
data := result.(map[string]interface{})
projectsList := data[consoleql.MyProjectsQuery].([]interface{})
assert.Equal(t, 2, len(projectsList))
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
testProject := func(t *testing.T, actual map[string]interface{}, expected *console.Project) {
assert.Equal(t, expected.Name, actual[consoleql.FieldName])
assert.Equal(t, expected.Description, actual[consoleql.FieldDescription])
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
createdAt := time.Time{}
err := createdAt.UnmarshalText([]byte(actual[consoleql.FieldCreatedAt].(string)))
assert.NoError(t, err)
assert.True(t, expected.CreatedAt.Equal(createdAt))
2019-01-08 14:54:35 +00:00
}
2019-01-24 16:26:36 +00:00
var foundProj1, foundProj2 bool
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
for _, entry := range projectsList {
project := entry.(map[string]interface{})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
id := project[consoleql.FieldID].(string)
switch id {
case createdProject.ID.String():
foundProj1 = true
testProject(t, project, createdProject)
case project2.ID.String():
foundProj2 = true
testProject(t, project, project2)
}
}
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.True(t, foundProj1)
assert.True(t, foundProj2)
})
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
t.Run("Token query", func(t *testing.T) {
query := fmt.Sprintf(
"query {token(email: \"%s\", password: \"%s\"){token,user{id,email,fullName,shortName,createdAt}}}",
2019-01-24 16:26:36 +00:00
createUser.Email,
createUser.Password,
)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
result := testQuery(t, query)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
data := result.(map[string]interface{})
queryToken := data[consoleql.TokenQuery].(map[string]interface{})
token := queryToken[consoleql.TokenType].(string)
user := queryToken[consoleql.UserType].(map[string]interface{})
tauth, err := service.Authorize(auth.WithAPIKey(ctx, []byte(token)))
require.NoError(t, err)
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
assert.Equal(t, rootUser.ID, tauth.User.ID)
assert.Equal(t, rootUser.ID.String(), user[consoleql.FieldID])
assert.Equal(t, rootUser.Email, user[consoleql.FieldEmail])
assert.Equal(t, rootUser.FullName, user[consoleql.FieldFullName])
assert.Equal(t, rootUser.ShortName, user[consoleql.FieldShortName])
2019-01-08 14:54:35 +00:00
2019-01-24 16:26:36 +00:00
createdAt := time.Time{}
err = createdAt.UnmarshalText([]byte(user[consoleql.FieldCreatedAt].(string)))
assert.NoError(t, err)
assert.True(t, rootUser.CreatedAt.Equal(createdAt))
2019-01-24 16:26:36 +00:00
})
t.Run("PasswordReset query", func(t *testing.T) {
regToken, err := service.CreateRegToken(ctx, 2)
require.NoError(t, err)
user, err := service.CreateUser(authCtx, console.CreateUser{
FullName: "Example User",
ShortName: "Example",
Email: "user@mail.test",
Password: "123a123",
}, regToken.Secret, refUserID)
require.NoError(t, err)
t.Run("Activation", func(t *testing.T) {
activationToken, err := service.GenerateActivationToken(
ctx,
user.ID,
"user@mail.test",
)
require.NoError(t, err)
err = service.ActivateAccount(ctx, activationToken)
require.NoError(t, err)
user.Email = "user@mail.test"
})
rootObject[consoleql.PasswordRecoveryPath] = "?token="
rootObject[consoleql.CancelPasswordRecoveryPath] = "?token="
query := fmt.Sprintf("query {forgotPassword(email: \"%s\")}", user.Email)
result := testQuery(t, query)
assert.NotNil(t, result)
data := result.(map[string]interface{})
ok := data[consoleql.ForgotPasswordQuery].(bool)
assert.True(t, ok)
})
t.Run("Resend activation email query", func(t *testing.T) {
regToken, err := service.CreateRegToken(ctx, 2)
require.NoError(t, err)
user, err := service.CreateUser(authCtx, console.CreateUser{
FullName: "Example User",
ShortName: "Example",
Email: "user1@mail.test",
Password: "123a123",
}, regToken.Secret, refUserID)
require.NoError(t, err)
query := fmt.Sprintf("query {resendAccountActivationEmail(id: \"%s\")}", user.ID)
result := testQuery(t, query)
assert.NotNil(t, result)
data := result.(map[string]interface{})
ok := data[consoleql.ResendAccountActivationEmailQuery].(bool)
assert.True(t, ok)
})
2019-01-08 14:54:35 +00:00
})
}