Skip to content
Snippets Groups Projects
Commit e2c376b8 authored by Pavel Antonov's avatar Pavel Antonov :asterisk:
Browse files

Merge branch 'feature/PRXS-1609-AddURLStruct' into 'master'

Выделена отдельная структура и функция для работы с action URL, внесены правки в extension

See merge request perxis/perxis-go!87
parents 30b5e866 b9071ae2
No related branches found
No related tags found
No related merge requests found
package action
import (
"net/url"
"strings"
)
// URL структура для хранения данных о переданном действии.
type URL struct {
*url.URL
}
// NewURL возвращает структуру ActionURL
func NewURL(action string) (*URL, error) {
u, err := url.Parse(action)
if err != nil {
return nil, err
}
return &URL{URL: u}, nil
}
func (u *URL) actionParts() (string, string) {
if u.URL != nil && u.URL.Scheme == "grpc" {
splitPath := strings.Split(strings.TrimLeft(u.Path, "/"), "/")
if len(splitPath) >= 2 {
return splitPath[0], splitPath[1]
}
}
return "", ""
}
func (u *URL) Action() string {
_, action := u.actionParts()
return action
}
func (u *URL) Extension() string {
ext, _ := u.actionParts()
return ext
}
package action
import (
"fmt"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
)
func TestActionURL_New(t *testing.T) {
tests := []struct {
name string
action string
want *URL
url string
wantErr assert.ErrorAssertionFunc
}{
{
name: "Without action",
want: &URL{
URL: &url.URL{},
},
wantErr: assert.NoError,
},
{
name: "Without deprecated action call",
action: "build-site",
want: &URL{
URL: &url.URL{
Path: "build-site",
},
},
url: "build-site",
wantErr: assert.NoError,
},
{
name: "With grpc action",
action: "grpc:///perxisweb/build-site",
want: &URL{
URL: &url.URL{
Scheme: "grpc",
Path: "/perxisweb/build-site",
},
},
url: "grpc:///perxisweb/build-site",
wantErr: assert.NoError,
},
{
name: "With ui action",
action: "ui:///space/env/coll",
want: &URL{
URL: &url.URL{
Scheme: "ui",
Path: "/space/env/coll",
},
},
url: "ui:///space/env/coll",
wantErr: assert.NoError,
},
{
name: "With http action",
action: "https://perx.ru",
want: &URL{
URL: &url.URL{
Scheme: "https",
Host: "perx.ru",
},
},
url: "https://perx.ru",
wantErr: assert.NoError,
},
{
name: "With error in parse",
action: "grpc://user:abc{DEf1=ghi@example.com:5432/db?sslmode=require",
want: nil,
wantErr: assert.Error,
},
{
name: "With no action id",
action: "grpc:///perxisweb",
want: &URL{
URL: &url.URL{
Scheme: "grpc",
Path: "/perxisweb",
},
},
wantErr: assert.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewURL(tt.action)
if !tt.wantErr(t, err, fmt.Sprintf("NewURL(%v)", tt.action)) {
return
}
assert.Equalf(t, tt.want, got, "NewURL(%v)", tt.action)
})
}
}
func TestActionURL_String(t *testing.T) {
tests := []struct {
name string
url string
want string
}{
{
name: "GRPC action",
url: "grpc:///perxisweb/build-site",
},
{
name: "UI action #1",
url: "ui:///space/env/coll",
},
{
name: "UI action deprecated call #2",
url: "space/env/coll",
},
{
name: "Https action",
url: "https://perx.ru",
},
{
name: "With action deprecated call",
url: "extension-id",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
p, _ := NewURL(tt.url)
assert.Equalf(t, tt.url, p.String(), "String()")
})
}
}
...@@ -3,6 +3,7 @@ package extension ...@@ -3,6 +3,7 @@ package extension
import ( import (
"context" "context"
"git.perx.ru/perxis/perxis-go/pkg/action"
"git.perx.ru/perxis/perxis-go/pkg/errors" "git.perx.ru/perxis/perxis-go/pkg/errors"
pb "git.perx.ru/perxis/perxis-go/proto/extensions" pb "git.perx.ru/perxis/perxis-go/proto/extensions"
) )
...@@ -80,8 +81,19 @@ func (srv *Server) Update(ctx context.Context, request *UpdateRequest) (*UpdateR ...@@ -80,8 +81,19 @@ func (srv *Server) Update(ctx context.Context, request *UpdateRequest) (*UpdateR
} }
func (srv *Server) Action(ctx context.Context, in *pb.ActionRequest) (*pb.ActionResponse, error) { func (srv *Server) Action(ctx context.Context, in *pb.ActionRequest) (*pb.ActionResponse, error) {
actionURL, err := action.NewURL(in.Action)
if err != nil {
return nil, err
}
ext := actionURL.Extension()
if ext == "" {
ext = in.Extension
}
if ext == "" {
return nil, errors.New("extension ID required")
}
svc, ok := srv.services[in.Extension] svc, ok := srv.services[ext]
if !ok { if !ok {
return nil, ErrUnknownExtension return nil, ErrUnknownExtension
} }
......
...@@ -2,11 +2,13 @@ package extension ...@@ -2,11 +2,13 @@ package extension
import ( import (
"context" "context"
"fmt"
"reflect" "reflect"
"strings" "strings"
"testing" "testing"
"git.perx.ru/perxis/perxis-go/pkg/errors" "git.perx.ru/perxis/perxis-go/pkg/errors"
"github.com/stretchr/testify/assert"
) )
func TestGetResults(t *testing.T) { func TestGetResults(t *testing.T) {
...@@ -102,3 +104,102 @@ func (t testServerExtension) Uninstall(ctx context.Context, in *UninstallRequest ...@@ -102,3 +104,102 @@ func (t testServerExtension) Uninstall(ctx context.Context, in *UninstallRequest
func (t testServerExtension) Action(ctx context.Context, in *ActionRequest) (*ActionResponse, error) { func (t testServerExtension) Action(ctx context.Context, in *ActionRequest) (*ActionResponse, error) {
return &ActionResponse{}, t.err return &ActionResponse{}, t.err
} }
func TestServer_Action(t *testing.T) {
getDummyExtension := func(name string, wantErr ...bool) Extension {
ext := &testServerExtension{name: name}
if len(wantErr) > 0 {
ext.err = errors.WithDetail(errors.New("some err"), "Ошибка")
}
return ext
}
var tests = []struct {
name string
services map[string]Extension
in *ActionRequest
want *ActionResponse
wantErr string
}{
{
name: "GRPC",
services: map[string]Extension{"test-extension": getDummyExtension("test-extension")},
in: &ActionRequest{
Action: "grpc:///test-extension/test-action",
SpaceId: "sp",
EnvId: "env",
},
want: &ActionResponse{State: ResponseDone},
},
{
name: "invalid schema",
services: map[string]Extension{"test-extension": getDummyExtension("test-extension")},
in: &ActionRequest{
Action: "some:///space/env/coll",
SpaceId: "sp",
EnvId: "env",
},
want: &ActionResponse{State: ResponseDone},
wantErr: "extension ID required",
},
{
name: "Deprecated call",
services: map[string]Extension{"test-extension": getDummyExtension("test-extension")},
in: &ActionRequest{
Action: "test-action",
SpaceId: "sp",
EnvId: "env",
Extension: "test-extension",
},
want: &ActionResponse{State: ResponseDone},
},
{
name: "unknown extension",
services: map[string]Extension{"test-extension": getDummyExtension("test-extension")},
in: &ActionRequest{
Action: "grpc:///test-extension-2/test-action",
SpaceId: "sp",
EnvId: "env",
},
want: nil,
wantErr: ErrUnknownExtension.Error(),
},
{
name: "Deprecated call, without extension",
services: map[string]Extension{"test-extension": getDummyExtension("test-extension")},
in: &ActionRequest{
Action: "test-action",
SpaceId: "sp",
EnvId: "env",
},
want: nil,
wantErr: "extension ID required",
},
{
name: "Deprecated call, without action and extension)",
services: map[string]Extension{"test-extension": getDummyExtension("test-extension")},
in: &ActionRequest{
SpaceId: "sp",
EnvId: "env",
},
want: nil,
wantErr: "extension ID required",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
srv := &Server{
services: tt.services,
}
got, err := srv.Action(context.Background(), tt.in)
if tt.wantErr != "" {
assert.EqualErrorf(t, err, tt.wantErr, fmt.Sprintf("Action(%v)", tt.in))
return
}
assert.Equalf(t, tt.want, got, "Action(%v)", tt.in)
})
}
}
...@@ -4,6 +4,7 @@ import ( ...@@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"git.perx.ru/perxis/perxis-go/pkg/action"
"git.perx.ru/perxis/perxis-go/pkg/clients" "git.perx.ru/perxis/perxis-go/pkg/clients"
"git.perx.ru/perxis/perxis-go/pkg/content" "git.perx.ru/perxis/perxis-go/pkg/content"
"git.perx.ru/perxis/perxis-go/pkg/errors" "git.perx.ru/perxis/perxis-go/pkg/errors"
...@@ -155,7 +156,18 @@ func (s *Extension) Uninstall(ctx context.Context, in *extension.UninstallReques ...@@ -155,7 +156,18 @@ func (s *Extension) Uninstall(ctx context.Context, in *extension.UninstallReques
} }
func (s *Extension) Action(ctx context.Context, in *extension.ActionRequest) (*extension.ActionResponse, error) { func (s *Extension) Action(ctx context.Context, in *extension.ActionRequest) (*extension.ActionResponse, error) {
ok, err := extension.CheckInstalled(ctx, s.Content, in.SpaceId, in.EnvId, in.Extension) actionURL, err := action.NewURL(in.Action)
if err != nil {
return nil, err
}
ext := actionURL.Extension()
if ext == "" {
ext = in.Extension
}
if ext == "" {
return nil, errors.New("extension ID required")
}
ok, err := extension.CheckInstalled(ctx, s.Content, in.SpaceId, in.EnvId, ext)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "check extension installed") return nil, errors.Wrap(err, "check extension installed")
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment