Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat-46: add Workflow Groups endpoints #58

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions lib/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,36 @@ type MxRecordConfiguredStatus struct {
type InboundParserResponse struct {
Data MxRecordConfiguredStatus `json:"data"`
}

type CreateWorkflowGroupRequest struct {
Name string
}

type UpdateWorkflowGroupRequest struct {
Name string `json:"name"`
}

type ListWorkflowGroupsResponse struct {
Data []WorkflowGroup `json:"data"`
}

type WorkflowGroup struct {
Id string `json:"_id"`
Name string `json:"name"`
EnvironmentId string `json:"_environmentId"`
OrganizationId string `json:"_organizationId"`
ParentId string `json:"_parentId"`
}

type GetWorkflowResponse struct {
Data WorkflowGroup `json:"data"`
}

type DeleteWorkflowGroupResponse struct {
Data DeleteWorkflowGroup `json:"data"`
}

type DeleteWorkflowGroup struct {
Acknowledged bool `json:"acknowledged"`
Status string `json:"status"`
}
3 changes: 2 additions & 1 deletion lib/novu.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type APIClient struct {
TopicsApi *TopicService
IntegrationsApi *IntegrationService
InboundParserApi *InboundParserService
WorkflowGroupApi *WorkflowGroupService
}

type service struct {
Expand All @@ -62,6 +63,7 @@ func NewAPIClient(apiKey string, cfg *Config) *APIClient {
c.TopicsApi = (*TopicService)(&c.common)
c.IntegrationsApi = (*IntegrationService)(&c.common)
c.InboundParserApi = (*InboundParserService)(&c.common)
c.WorkflowGroupApi = (*WorkflowGroupService)(&c.common)
return c
}

Expand Down Expand Up @@ -117,7 +119,6 @@ func (c APIClient) decode(v interface{}, b []byte) (err error) {
}

func buildBackendURL(cfg *Config) *url.URL {

if cfg.BackendURL == nil {
rawURL := fmt.Sprintf("%s/%s", NovuURL, NovuVersion)
return MustParseURL(rawURL)
Expand Down
120 changes: 120 additions & 0 deletions lib/workflow_groups.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package lib

import (
"bytes"
"context"
"encoding/json"
"net/http"

"github.com/pkg/errors"
)

type IWorkflowGroup interface {
Create(ctx context.Context, name string) (*GetWorkflowResponse, error)
Get(ctx context.Context, workflowGroupID string) (*GetWorkflowResponse, error)
List(ctx context.Context) (*ListWorkflowGroupsResponse, error)
Delete(ctx context.Context, workflowGroupID string) (*DeleteWorkflowGroupResponse, error)
Update(ctx context.Context, workflowGroupID string, request UpdateWorkflowGroupRequest) (*GetWorkflowResponse, error)
}

type WorkflowGroupService service

const WORKFLOW_GROUP_PATH = "notification-groups"

func (t *WorkflowGroupService) Create(ctx context.Context, name string) (*GetWorkflowResponse, error) {
var resp GetWorkflowResponse

URL := t.client.config.BackendURL.JoinPath(WORKFLOW_GROUP_PATH)
reqBody := CreateWorkflowGroupRequest{
Name: name,
}

jsonBody, _ := json.Marshal(reqBody)

req, err := http.NewRequestWithContext(ctx, http.MethodPost, URL.String(), bytes.NewBuffer(jsonBody))
if err != nil {
return nil, err
}

httpResponse, err := t.client.sendRequest(req, &resp)
if err != nil {
return nil, err
}

if httpResponse.StatusCode != HTTPStatusCreated {
return nil, errors.Wrap(err, "unable to create workflow group")
}

return &resp, nil
}

func (t *WorkflowGroupService) List(ctx context.Context) (*ListWorkflowGroupsResponse, error) {
var resp ListWorkflowGroupsResponse
URL := t.client.config.BackendURL.JoinPath(WORKFLOW_GROUP_PATH)

req, err := http.NewRequestWithContext(ctx, http.MethodGet, URL.String(), http.NoBody)
if err != nil {
return nil, err
}

_, err = t.client.sendRequest(req, &resp)
if err != nil {
return nil, err
}

return &resp, nil
}

func (t *WorkflowGroupService) Get(ctx context.Context, workflowGroupID string) (*GetWorkflowResponse, error) {
var resp GetWorkflowResponse

URL := t.client.config.BackendURL.JoinPath(WORKFLOW_GROUP_PATH, workflowGroupID)

req, err := http.NewRequestWithContext(ctx, http.MethodGet, URL.String(), bytes.NewBuffer([]byte{}))
if err != nil {
return nil, err
}

_, err = t.client.sendRequest(req, &resp)
if err != nil {
return nil, err
}

return &resp, nil
}

func (t *WorkflowGroupService) Delete(ctx context.Context, workflowGroupID string) (*DeleteWorkflowGroupResponse, error) {
var resp DeleteWorkflowGroupResponse
URL := t.client.config.BackendURL.JoinPath(WORKFLOW_GROUP_PATH, workflowGroupID)

req, err := http.NewRequestWithContext(ctx, http.MethodDelete, URL.String(), http.NoBody)
if err != nil {
return nil, err
}

_, err = t.client.sendRequest(req, &resp)
if err != nil {
return nil, err
}

return &resp, nil
}

func (t *WorkflowGroupService) Update(ctx context.Context, workflowGroupID string, request UpdateWorkflowGroupRequest) (*GetWorkflowResponse, error) {
var resp GetWorkflowResponse

URL := t.client.config.BackendURL.JoinPath(WORKFLOW_GROUP_PATH, workflowGroupID)
jsonBody, _ := json.Marshal(request)

req, err := http.NewRequestWithContext(ctx, http.MethodPatch, URL.String(), bytes.NewBuffer(jsonBody))
if err != nil {
return nil, err
}

_, err = t.client.sendRequest(req, &resp)
if err != nil {
return nil, err
}

return &resp, nil
}
112 changes: 112 additions & 0 deletions lib/workflow_groups_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package lib_test

import (
"context"
"net/http"
"path/filepath"
"testing"

"github.com/novuhq/go-novu/lib"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

const WORKFLOW_GROUP_PATH = "/v1/notification-groups"

var ctx = context.Background()

func TestCreateWorkflowGroup_Success(t *testing.T) {
var response *lib.GetWorkflowResponse
fileToStruct(filepath.Join("../testdata", "create_workflow_group_response.json"), &response)
name := "workflow-group-name"
httpServer := createTestServer(t, TestServerOptions[lib.CreateWorkflowGroupRequest, *lib.GetWorkflowResponse]{
expectedURLPath: WORKFLOW_GROUP_PATH,
expectedSentMethod: http.MethodPost,
expectedSentBody: lib.CreateWorkflowGroupRequest{
Name: name,
},
responseStatusCode: http.StatusCreated,
responseBody: response,
})

c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
res, err := c.WorkflowGroupApi.Create(ctx, name)

assert.Equal(t, response, res)
require.NoError(t, err)
}

func TestGetWorkflowGroup_Success(t *testing.T) {
var response *lib.GetWorkflowResponse
fileToStruct(filepath.Join("../testdata", "get_workflow_group_response.json"), &response)
workflowId := "6425cb064a2a919bc61b0365"
httpServer := createTestServer(t, TestServerOptions[lib.CreateWorkflowGroupRequest, *lib.GetWorkflowResponse]{
expectedURLPath: WORKFLOW_GROUP_PATH + "/" + workflowId,
expectedSentMethod: http.MethodGet,
responseStatusCode: http.StatusOK,
responseBody: response,
})

c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
res, err := c.WorkflowGroupApi.Get(ctx, workflowId)

assert.Equal(t, response, res)
require.NoError(t, err)
}

func TestListWorkflowGroup_Success(t *testing.T) {
var response *lib.ListWorkflowGroupsResponse
fileToStruct(filepath.Join("../testdata", "list_workflow_groups_response.json"), &response)
httpServer := createTestServer(t, TestServerOptions[lib.CreateWorkflowGroupRequest, *lib.ListWorkflowGroupsResponse]{
expectedURLPath: WORKFLOW_GROUP_PATH,
expectedSentMethod: http.MethodGet,
responseStatusCode: http.StatusOK,
responseBody: response,
})

c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
res, err := c.WorkflowGroupApi.List(ctx)

assert.Equal(t, response, res)
require.NoError(t, err)
}

func TestDeleteWorkflowGroup_Success(t *testing.T) {
var response *lib.DeleteWorkflowGroupResponse
fileToStruct(filepath.Join("../testdata", "delete_workflow_group_response.json"), &response)
workflowId := "6425cb064a2a919bc61b0365"
httpServer := createTestServer(t, TestServerOptions[any, *lib.DeleteWorkflowGroupResponse]{
expectedURLPath: WORKFLOW_GROUP_PATH + "/" + workflowId,
expectedSentMethod: http.MethodDelete,
responseStatusCode: http.StatusOK,
responseBody: response,
})

c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
res, err := c.WorkflowGroupApi.Delete(ctx, workflowId)

assert.Equal(t, response, res)
require.NoError(t, err)
}

func TestUpdateWorkflowGroup_Success(t *testing.T) {
var response *lib.GetWorkflowResponse
fileToStruct(filepath.Join("../testdata", "update_workflow_group_response.json"), &response)
workflowId := "6425cb064a2a919bc61b0365"
updatedRequest := lib.UpdateWorkflowGroupRequest{
Name: "updated-name",
}
httpServer := createTestServer(t, TestServerOptions[lib.UpdateWorkflowGroupRequest, *lib.GetWorkflowResponse]{
expectedURLPath: WORKFLOW_GROUP_PATH + "/" + workflowId,
expectedSentMethod: http.MethodPatch,
expectedSentBody: updatedRequest,
responseStatusCode: http.StatusOK,
responseBody: response,
})

c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
res, err := c.WorkflowGroupApi.Update(ctx, workflowId, updatedRequest)

assert.Equal(t, response, res)
require.NoError(t, err)
}
9 changes: 9 additions & 0 deletions testdata/create_workflow_group_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"data": {
"_id": "6425cb064a2a919bc61b0365",
"name": "workflow-group-name",
"_environmentId": "6425cb40d22507199a000003",
"_organizationId": "7425cb40d22507199a000009",
"_parentId": "8495cb40d82507199a000002"
}
}
6 changes: 6 additions & 0 deletions testdata/delete_workflow_group_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"data": {
"acknowledged": true,
"status": "deleted"
}
}
9 changes: 9 additions & 0 deletions testdata/get_workflow_group_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"data": {
"_id": "6425cb064a2a919bc61b0365",
"name": "name",
"_environmentId": "6425cb40d22507199a000003",
"_organizationId": "7425cb40d22507199a000009",
"_parentId": "8495cb40d82507199a000002"
}
}
11 changes: 11 additions & 0 deletions testdata/list_workflow_groups_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"data": [
{
"_id": "6425cb064a2a919bc61b0365",
"name": "name",
"_environmentId": "6425cb40d22507199a000003",
"_organizationId": "7425cb40d22507199a000009",
"_parentId": "8495cb40d82507199a000002"
}
]
}
9 changes: 9 additions & 0 deletions testdata/update_workflow_group_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"data": {
"_id": "6425cb064a2a919bc61b0365",
"name": "updated-name",
"_environmentId": "6425cb40d22507199a000003",
"_organizationId": "7425cb40d22507199a000009",
"_parentId": "8495cb40d82507199a000002"
}
}