Skip to content

Commit

Permalink
Merge pull request #65 from srikanth597/srikanth597-feat-layout-api
Browse files Browse the repository at this point in the history
feat: layout api implementation
  • Loading branch information
Cliftonz authored Oct 12, 2023
2 parents 1b4e5c9 + 7336c82 commit 8f79e77
Show file tree
Hide file tree
Showing 4 changed files with 387 additions and 1 deletion.
133 changes: 133 additions & 0 deletions lib/layout.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package lib

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

type LayoutService service

func (l *LayoutService) Create(ctx context.Context, request CreateLayoutRequest) (*CreateLayoutResponse, error) {
var resp CreateLayoutResponse
URL := l.client.config.BackendURL.JoinPath("layouts")

requestBody := CreateLayoutRequest{
Name: request.Name,
Identifier: request.Identifier,
Description: request.Description,
Content: request.Content,
Variables: request.Variables,
IsDefault: request.IsDefault,
}

jsonBody, _ := json.Marshal(requestBody)
b := bytes.NewBuffer(jsonBody)

req, err := http.NewRequestWithContext(ctx, http.MethodPost, URL.String(), b)
if err != nil {
return nil, err
}
_, err = l.client.sendRequest(req, &resp)
if err != nil {
return nil, err
}
return &resp, nil
}

func (l *LayoutService) List(ctx context.Context, options *LayoutRequestOptions) (*LayoutsResponse, error) {
var resp LayoutsResponse
URL := l.client.config.BackendURL.JoinPath("layouts")
if options == nil {
options = &LayoutRequestOptions{}
}
queryParams, _ := json.Marshal(options)

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

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

func (l *LayoutService) Get(ctx context.Context, key string) (*LayoutResponse, error) {
var resp LayoutResponse
URL := l.client.config.BackendURL.JoinPath("layouts", key)

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

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

func (l *LayoutService) Delete(ctx context.Context, key string) error {
var resp interface{}
URL := l.client.config.BackendURL.JoinPath("layouts", key)

req, err := http.NewRequestWithContext(ctx, http.MethodDelete, URL.String(), http.NoBody)
if err != nil {
return err
}
_, err = l.client.sendRequest(req, &resp)
if err != nil {
return err
}
return nil
}

func (l *LayoutService) Update(ctx context.Context, key string, request CreateLayoutRequest) (*LayoutResponse, error) {
var resp LayoutResponse
URL := l.client.config.BackendURL.JoinPath("layouts", key)

requestBody := CreateLayoutRequest{
Name: request.Name,
Identifier: request.Identifier,
Description: request.Description,
Content: request.Content,
Variables: request.Variables,
IsDefault: request.IsDefault,
}

jsonBody, _ := json.Marshal(requestBody)

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

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

return &resp, nil
}

func (l *LayoutService) SetDefault(ctx context.Context, key string) error {
var resp interface{}
URL := l.client.config.BackendURL.JoinPath("layouts", key, "default")

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

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

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

import (
"context"
"encoding/json"
"fmt"
"net/http"
"testing"

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

const LayoutId = "2222"

func TestLayoutService_Create_Layout_Success(t *testing.T) {
var createLayoutRequest *lib.CreateLayoutRequest = &lib.CreateLayoutRequest{
Name: "layoutName",
Identifier: "layoutIdentifier",
Description: "layoutDescription",
Content: "layoutContent",
Variables: []interface{}(nil),
IsDefault: true,
}
res, _ := json.Marshal(createLayoutRequest)
fmt.Println(string(res))
var expectedResponse *lib.CreateLayoutResponse = &lib.CreateLayoutResponse{
Data: struct {
Id string `json:"_id"`
}{
Id: "2222",
},
}

httpServer := createTestServer(t, TestServerOptions[lib.CreateLayoutRequest, lib.CreateLayoutResponse]{
expectedURLPath: "/v1/layouts",
expectedSentBody: *createLayoutRequest,
expectedSentMethod: http.MethodPost,
responseStatusCode: http.StatusCreated,
responseBody: *expectedResponse,
})

ctx := context.Background()
c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
resp, err := c.LayoutApi.Create(ctx, *createLayoutRequest)

require.NoError(t, err)
require.Equal(t, expectedResponse, resp)
}

func TestLayoutService_List_Layouts_Success(t *testing.T) {
body := map[string]string{}
var expectedResponse *lib.LayoutsResponse = &lib.LayoutsResponse{
Page: 0,
PageSize: 20,
TotalCount: 1,
Data: []lib.LayoutResponse{{
Id: "id",
OrganizationId: "orgId",
EnvironmentId: "envId",
CreatorId: "creatorId",
Name: "layoutName",
Identifier: "layoutIdentifier",
Description: "layoutDescription",
Channel: "in_app",
Content: "layoutContent",
ContentType: "layoutContentType",
Variables: []interface{}{},
IsDefault: true,
IsDeleted: false,
CreatedAt: "createdAt",
UpdatedAt: "updatedAt",
ParentId: "parentId",
}},
}
httpServer := createTestServer(t, TestServerOptions[map[string]string, lib.LayoutsResponse]{
expectedURLPath: "/v1/layouts",
expectedSentMethod: http.MethodGet,
expectedSentBody: body,
responseStatusCode: http.StatusCreated,
responseBody: *expectedResponse,
})

ctx := context.Background()
c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
resp, err := c.LayoutApi.List(ctx, nil)

require.NoError(t, err)
require.Equal(t, expectedResponse, resp)
}

func TestLayoutService_Get_Layout_Success(t *testing.T) {

var expectedResponse *lib.LayoutResponse = &lib.LayoutResponse{
Id: "id",
OrganizationId: "orgId",
EnvironmentId: "envId",
CreatorId: "creatorId",
Name: "layoutName",
Identifier: "layoutIdentifier",
Description: "layoutDescription",
Channel: "in_app",
Content: "layoutContent",
ContentType: "layoutContentType",
Variables: []interface{}{},
IsDefault: true,
IsDeleted: false,
CreatedAt: "createdAt",
UpdatedAt: "updatedAt",
ParentId: "parentId",
}

httpServer := createTestServer(t, TestServerOptions[map[string]string, lib.LayoutResponse]{
expectedURLPath: fmt.Sprintf("/v1/layouts/%s", LayoutId),
expectedSentMethod: http.MethodGet,
responseStatusCode: http.StatusOK,
responseBody: *expectedResponse,
})

ctx := context.Background()
c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
resp, err := c.LayoutApi.Get(ctx, "2222")

require.NoError(t, err)
require.Equal(t, expectedResponse, resp)
}

func TestLayoutService_Delete_Layout_Success(t *testing.T) {

body := map[string]string{}

httpServer := createTestServer(t, TestServerOptions[map[string]string, map[string]string]{
expectedURLPath: fmt.Sprintf("/v1/layouts/%s", LayoutId),
expectedSentMethod: http.MethodDelete,
responseStatusCode: http.StatusOK,
responseBody: body,
})

ctx := context.Background()
c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
err := c.LayoutApi.Delete(ctx, "2222")

require.NoError(t, err)
}

func TestLayoutService_Update_Layout_Success(t *testing.T) {

var updateLayoutRequest *lib.CreateLayoutRequest = &lib.CreateLayoutRequest{
Name: "layoutName",
Identifier: "layoutIdentifier",
Description: "layoutDescription",
Content: "layoutContent",
Variables: []interface{}(nil),
IsDefault: false,
}
res, _ := json.Marshal(updateLayoutRequest)
fmt.Println(string(res))
var expectedResponse *lib.LayoutResponse = &lib.LayoutResponse{
Id: "id",
OrganizationId: "orgId",
EnvironmentId: "envId",
CreatorId: "creatorId",
Name: "layoutName",
Identifier: "layoutIdentifier",
Description: "layoutDescription",
Channel: "in_app",
Content: "layoutContent",
ContentType: "layoutContentType",
Variables: []interface{}{},
IsDefault: true,
IsDeleted: false,
CreatedAt: "createdAt",
UpdatedAt: "updatedAt",
ParentId: "parentId",
}
httpServer := createTestServer[lib.CreateLayoutRequest, lib.LayoutResponse](t, TestServerOptions[lib.CreateLayoutRequest, lib.LayoutResponse]{
expectedURLPath: fmt.Sprintf("/v1/layouts/%s", LayoutId),
expectedSentBody: *updateLayoutRequest,
expectedSentMethod: http.MethodPatch,
responseStatusCode: http.StatusOK,
responseBody: *expectedResponse,
})
ctx := context.Background()
c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
resp, err := c.LayoutApi.Update(ctx, "2222", *updateLayoutRequest)
require.NoError(t, err)
require.Equal(t, expectedResponse, resp)
}

func TestLayoutService_Layout_SetDefault(t *testing.T) {

body := map[string]string{}

httpServer := createTestServer(t, TestServerOptions[map[string]string, map[string]string]{
expectedURLPath: fmt.Sprintf("/v1/layouts/%s/default", LayoutId),
expectedSentBody: body,
expectedSentMethod: http.MethodPost,
responseStatusCode: http.StatusNoContent,
responseBody: body,
})

ctx := context.Background()
c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(httpServer.URL)})
err := c.LayoutApi.SetDefault(ctx, LayoutId)

require.NoError(t, err)
}
44 changes: 44 additions & 0 deletions lib/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,50 @@ type InboundParserResponse struct {
Data MxRecordConfiguredStatus `json:"data"`
}

type CreateLayoutRequest struct {
Name string `json:"name"`
Identifier string `json:"identifier"`
Description string `json:"description"`
Content string `json:"content"`
Variables []interface{} `json:"variables,omitempty"`
IsDefault bool `json:"isDefault,omitempty"`
}

type CreateLayoutResponse struct {
Data struct {
Id string `json:"_id"`
} `json:"data"`
}
type LayoutRequestOptions struct {
Page *int `json:"page,omitempty"`
PageSize *int `json:"pageSize,omitempty"`
Key *string `json:"key,omitempty"`
OrderBy *int `json:"orderBy,omitempty"`
}
type LayoutResponse struct {
Id string `json:"_id"`
OrganizationId string `json:"_organizationId"`
EnvironmentId string `json:"_environmentId"`
CreatorId string `json:"_creatorId"`
Name string `json:"name"`
Identifier string `json:"identifier"`
Description string `json:"description"`
Channel string `json:"channel"`
Content string `json:"content"`
ContentType string `json:"contentType"`
Variables []interface{} `json:"variables"`
IsDefault bool `json:"isDefault"`
IsDeleted bool `json:"isDeleted"`
CreatedAt string `json:"createdAt"`
UpdatedAt string `json:"updatedAt"`
ParentId string `json:"_parentId"`
}
type LayoutsResponse struct {
TotalCount int `json:"totalCount"`
Data []LayoutResponse `json:"data"`
PageSize int `json:"pageSize"`
Page int `json:"page"`
}
type BlueprintByTemplateIdResponse struct {
Id string `json:"_id,omitempty"`
Name string `json:"name,omitempty"`
Expand Down
Loading

0 comments on commit 8f79e77

Please sign in to comment.