Skip to content
Snippets Groups Projects
Commit dae5af79 authored by ko_oler's avatar ko_oler
Browse files

правки по ПР:

- переименован тип с parsedActionURL -> ActionURL
- вынесен в отдельный файл, переименованы методы, изменен конструктор
- добавлены тесты
parent 10f2d733
No related branches found
No related tags found
No related merge requests found
package extension
import (
"net/url"
"strings"
"git.perx.ru/perxis/perxis-go/pkg/errors"
)
// ActionURL структура для хранения данных о переданном действии
type ActionURL struct {
actionURL string
actionID string
extensionID string
scheme string
url *url.URL
}
// NewActionURL возвращает пустую структуру ActionURL, если передано пустое действие
// при передаче в функцию действия - заполняет структуру
func NewActionURL(action string) (*ActionURL, error) {
if action != "" {
parsedURL, err := parseActionURL(action)
if err != nil {
return nil, err
}
return parsedURL, nil
}
return &ActionURL{}, nil
}
// ID возвращает сохраненный в ActionURL id действия
func (p *ActionURL) ID() string {
return p.actionID
}
// ExtensionID возвращает сохраненный в ActionURL id расширения
func (p *ActionURL) ExtensionID() string {
return p.extensionID
}
// Scheme возвращает сохраненную в ActionURL схему
func (p *ActionURL) Scheme() string {
return p.scheme
}
// parseActionURL функция для заполнения структуры ActionURL из переданного действия
func parseActionURL(action string) (*ActionURL, error) {
u, err := url.Parse(action)
if err != nil {
return nil, err
}
parsed := &ActionURL{}
parsed.actionURL = action
parsed.url = u
parsed.scheme = u.Scheme
if parsed.Scheme() == "grpc" {
path := u.Path
if strings.HasPrefix(u.Path, "/") {
path = u.Path[1:]
}
splitPath := strings.Split(path, "/")
if len(splitPath) < 2 {
return nil, errors.Errorf("incorrect action URL, no action id: '%s'", action)
}
parsed.extensionID = splitPath[0]
parsed.actionID = splitPath[1]
}
return parsed, nil
}
package extension
import (
"fmt"
"net/url"
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewActionURL(t *testing.T) {
u1, _ := url.Parse("build-site")
u2, _ := url.Parse("grpc:///perxisweb/build-site")
u3, _ := url.Parse("ui:///space/env/coll")
u4, _ := url.Parse("https://perx.ru")
tests := []struct {
name string
action string
want *ActionURL
wantErr assert.ErrorAssertionFunc
}{
{
"Without action",
"",
&ActionURL{},
assert.NoError,
},
{
"Without deprecated action call",
"build-site",
&ActionURL{
actionURL: "build-site",
url: u1,
},
assert.NoError,
},
{
name: "With grpc action",
action: "grpc:///perxisweb/build-site",
want: &ActionURL{
actionURL: "grpc:///perxisweb/build-site",
actionID: "build-site",
extensionID: "perxisweb",
scheme: "grpc",
url: u2,
},
wantErr: assert.NoError,
},
{
name: "With ui action",
action: "ui:///space/env/coll",
want: &ActionURL{
actionURL: "ui:///space/env/coll",
actionID: "",
extensionID: "",
scheme: "ui",
url: u3,
},
wantErr: assert.NoError,
},
{
name: "With http action",
action: "https://perx.ru",
want: &ActionURL{
actionURL: "https://perx.ru",
scheme: "https",
url: u4,
},
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,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewActionURL(tt.action)
if !tt.wantErr(t, err, fmt.Sprintf("NewActionURL(%v)", tt.action)) {
return
}
assert.Equalf(t, tt.want, got, "NewActionURL(%v)", tt.action)
})
}
}
......@@ -3,8 +3,6 @@ package extension
import (
"context"
"fmt"
"net/url"
"strings"
"git.perx.ru/perxis/perxis-go/pkg/content"
"git.perx.ru/perxis/perxis-go/pkg/errors"
......@@ -107,48 +105,3 @@ func ExtensionFromError(err error) string {
ext, _ := v.(string)
return ext
}
type ParsedActionURL struct {
actionID string
extensionID string
scheme string
}
func (p *ParsedActionURL) New() *ParsedActionURL {
return &ParsedActionURL{}
}
func (p *ParsedActionURL) GetActionID() string {
return p.actionID
}
func (p *ParsedActionURL) GetExtensionID() string {
return p.extensionID
}
func (p *ParsedActionURL) GetScheme() string {
return p.scheme
}
func ParseActionURL(action string) (*ParsedActionURL, error) {
u, err := url.Parse(action)
if err != nil {
return nil, err
}
parsed := &ParsedActionURL{}
parsed.scheme = u.Scheme
if parsed.GetScheme() == "grpc" {
path := u.Path
if strings.HasPrefix(u.Path, "/") {
path = u.Path[1:]
}
splitPath := strings.Split(path, "/")
if len(splitPath) < 2 {
return nil, errors.Errorf("incorrect action URL, no action id: '%s'", action)
}
parsed.extensionID = splitPath[0]
parsed.actionID = splitPath[1]
}
return parsed, nil
}
......@@ -80,13 +80,16 @@ func (srv *Server) Update(ctx context.Context, request *UpdateRequest) (*UpdateR
}
func (srv *Server) Action(ctx context.Context, in *pb.ActionRequest) (*pb.ActionResponse, error) {
parsed, err := ParseActionURL(in.Action)
extensionID := in.Extension
if extensionID == "" {
actionURL, err := NewActionURL(in.Action)
if err != nil {
return nil, err
}
extensionID = actionURL.extensionID
}
svc, ok := srv.services[parsed.GetExtensionID()]
svc, ok := srv.services[extensionID]
if !ok {
return nil, ErrUnknownExtension
}
......
......@@ -2,11 +2,13 @@ package extension
import (
"context"
"fmt"
"reflect"
"strings"
"testing"
"git.perx.ru/perxis/perxis-go/pkg/errors"
"github.com/stretchr/testify/assert"
)
func TestGetResults(t *testing.T) {
......@@ -102,3 +104,82 @@ func (t testServerExtension) Uninstall(ctx context.Context, in *UninstallRequest
func (t testServerExtension) Action(ctx context.Context, in *ActionRequest) (*ActionResponse, error) {
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 assert.ErrorAssertionFunc
}{
{
name: "OK (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},
wantErr: assert.NoError,
},
{
name: "OK (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},
wantErr: assert.NoError,
},
{
name: "Error (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: assert.Error,
},
{
name: "Error (deprecated call, no extension)",
services: map[string]Extension{"test-extension": getDummyExtension("test-extension")},
in: &ActionRequest{
Action: "test-action",
SpaceId: "sp",
EnvId: "env",
},
want: nil,
wantErr: assert.Error,
},
}
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(t, err, fmt.Sprintf("Action(%v)", tt.in)) {
return
}
assert.Equalf(t, tt.want, got, "Action(%v)", tt.in)
})
}
}
......@@ -155,11 +155,15 @@ func (s *Extension) Uninstall(ctx context.Context, in *extension.UninstallReques
}
func (s *Extension) Action(ctx context.Context, in *extension.ActionRequest) (*extension.ActionResponse, error) {
parsed, err := extension.ParseActionURL(in.Action)
extensionID := in.Extension
if extensionID == "" {
actionURL, err := extension.NewActionURL(in.Action)
if err != nil {
return nil, err
}
ok, err := extension.CheckInstalled(ctx, s.Content, in.SpaceId, in.EnvId, parsed.GetExtensionID())
extensionID = actionURL.ExtensionID()
}
ok, err := extension.CheckInstalled(ctx, s.Content, in.SpaceId, in.EnvId, extensionID)
if err != nil {
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