diff --git a/lib/model.go b/lib/model.go index 16964d6..ab12cdc 100644 --- a/lib/model.go +++ b/lib/model.go @@ -477,3 +477,10 @@ type ChangesBulkApplyPayload struct { type ChangesApplyResponse struct { Data []ChangesGetResponseData `json:"data,omitempty"` } + + +type UpdateTenantRequest struct { + Name string `json:"name"` + Data map[string]interface{} `json:"data"` + Identifier string `json:"identifier"` +} diff --git a/lib/novu.go b/lib/novu.go index 287616f..d3e0b1f 100644 --- a/lib/novu.go +++ b/lib/novu.go @@ -50,6 +50,7 @@ type APIClient struct { TopicsApi *TopicService IntegrationsApi *IntegrationService InboundParserApi *InboundParserService + TenantApi *TenantService } type service struct { @@ -108,6 +109,7 @@ func NewAPIClient(apiKey string, cfg *Config) *APIClient { c.IntegrationsApi = (*IntegrationService)(&c.common) c.InboundParserApi = (*InboundParserService)(&c.common) c.BlueprintApi = (*BlueprintService)(&c.common) + c.TenantApi = (*TenantService)(&c.common) return c } diff --git a/lib/tenants.go b/lib/tenants.go new file mode 100644 index 0000000..dc8f803 --- /dev/null +++ b/lib/tenants.go @@ -0,0 +1,90 @@ +package lib + +import ( + "bytes" + "context" + "encoding/json" + "net/http" +) + +type TenantService service + +func (e *TenantService) CreateTenant(ctx context.Context, name string,identifier string) (JsonResponse, error) { + var resp JsonResponse + URL := e.client.config.BackendURL.JoinPath("tenants") + n := map[string]string{"name": name,"identifier":identifier} + jsonBody, _ := json.Marshal(n) + b := bytes.NewBuffer(jsonBody) + req, err := http.NewRequestWithContext(ctx, http.MethodPost, URL.String(), b) + if err != nil { + return resp, err + } + _, err = e.client.sendRequest(req, &resp) + if err != nil { + return resp, err + } + return resp, nil +} + +func (e *TenantService) GetTenants(ctx context.Context,page string,limit string) (JsonResponse, error) { + var resp JsonResponse + URL := e.client.config.BackendURL.JoinPath("tenants") + v := URL.Query(); + v.Set("page",page) + v.Set("limit",limit) + URL.RawQuery = v.Encode() + req, err := http.NewRequestWithContext(ctx, http.MethodGet, URL.String(), http.NoBody) + if err != nil { + return resp, err + } + _, err = e.client.sendRequest(req, &resp) + if err != nil { + return resp, err + } + return resp, nil +} + +func (e *TenantService) GetTenant(ctx context.Context,identifier string) (JsonResponse, error) { + var resp JsonResponse + URL := e.client.config.BackendURL.JoinPath("tenants",identifier) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, URL.String(), http.NoBody) + if err != nil { + return resp, err + } + _, err = e.client.sendRequest(req, &resp) + if err != nil { + return resp, err + } + return resp, nil +} + +func (e *TenantService) DeleteTenant(ctx context.Context, identifier string) (JsonResponse, error) { + var resp JsonResponse + URL := e.client.config.BackendURL.JoinPath("tenants", identifier) + req, err := http.NewRequestWithContext(ctx, http.MethodDelete, URL.String(), http.NoBody) + if err != nil { + return resp, err + } + _, err = e.client.sendRequest(req, &resp) + if err != nil { + return resp, err + } + return resp, nil +} + + +func (e *TenantService) UpdateTenant(ctx context.Context, identifier string,updateTenantObject *UpdateTenantRequest) (JsonResponse, error) { + var resp JsonResponse + URL := e.client.config.BackendURL.JoinPath("tenants", identifier) + jsonBody, _ := json.Marshal(updateTenantObject) + b := bytes.NewBuffer(jsonBody) + req, err := http.NewRequestWithContext(ctx, http.MethodPatch, URL.String(), b) + if err != nil { + return resp, err + } + _, err = e.client.sendRequest(req, &resp) + if err != nil { + return resp, err + } + return resp, nil +} diff --git a/lib/tenants_test.go b/lib/tenants_test.go new file mode 100644 index 0000000..d664313 --- /dev/null +++ b/lib/tenants_test.go @@ -0,0 +1,136 @@ +package lib_test + +import ( + "context" + "net/http" + "net/http/httptest" + "testing" + + "github.com/novuhq/go-novu/lib" +) + +var tenantsApiResponse = `{ + "data": { + "_environmentId": "string", + "_id": "string", + "createdAt": "string", + "data": "object", + "identifier": "string", + "name": "string", + "updatedAt": "string" + } + } + +` + +func TestCreateTenant(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + t.Errorf("Want POST, got %s", r.Method) + } + if r.URL.Path != "/v1/tenants" { + t.Errorf("Want /v1/tenants, got %s", r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(tenantsApiResponse)) + })) + defer server.Close() + c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(server.URL)}) + resp, err := c.TenantApi.CreateTenant(context.Background(), "Tenant", "TenantId") + if err != nil { + t.Errorf("Error should be nil, got %v", err) + } + if resp.Data == nil || resp.Data == "" { + t.Error("Expected response, got none") + } +} + +func TestGetTenants(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Errorf("Want GET, got %s", r.Method) + } + if r.URL.Path != "/v1/tenants" { + t.Errorf("Want /v1/tenants, got %s", r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(tenantsApiResponse)) + })) + defer server.Close() + c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(server.URL)}) + resp, err := c.TenantApi.GetTenants(context.Background(), "1", "10") + if err != nil { + t.Errorf("Error should be nil, got %v", err) + } + if resp.Data == nil || resp.Data == "" { + t.Error("Expected response, got none") + } +} + +func TestGetTenant(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + t.Errorf("Want GET, got %s", r.Method) + } + if r.URL.Path != "/v1/tenants/TenantId" { + t.Errorf("Want /v1/feeds, got %s", r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(tenantsApiResponse)) + })) + defer server.Close() + c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(server.URL)}) + resp, err := c.TenantApi.GetTenant(context.Background(), "TenantId") + if err != nil { + t.Errorf("Error should be nil, got %v", err) + } + if resp.Data == nil || resp.Data == "" { + t.Error("Expected response, got none") + } +} + +func TestDeleteTenant(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodDelete { + t.Errorf("Want DELETE, got %s", r.Method) + } + if r.URL.Path != "/v1/tenants/TenantId" { + t.Errorf("Want /v1/tenants/TenantId, got %s", r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(tenantsApiResponse)) + })) + defer server.Close() + c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(server.URL)}) + resp, err := c.TenantApi.DeleteTenant(context.Background(), "TenantId") + if err != nil { + t.Errorf("Error should be nil, got %v", err) + } + if resp.Data == nil || resp.Data == "" { + t.Error("Expected response, got none") + } +} + +func TestUpdateTenant(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPatch { + t.Errorf("Want PATCH, got %s", r.Method) + } + if r.URL.Path != "/v1/tenants/TenantId" { + t.Errorf("Want /v1/tenants/TenantId, got %s", r.URL.Path) + } + w.Header().Set("Content-Type", "application/json") + w.Write([]byte(tenantsApiResponse)) + })) + defer server.Close() + c := lib.NewAPIClient(novuApiKey, &lib.Config{BackendURL: lib.MustParseURL(server.URL)}) + resp, err := c.TenantApi.UpdateTenant(context.Background(), "TenantId", &lib.UpdateTenantRequest{ + Name: "Tenant2", + }) + if err != nil { + t.Errorf("Error should be nil, got %v", err) + } + if resp.Data == nil || resp.Data == "" { + t.Error("Expected response, got none") + } +}