Repository: ctreminiom/go-atlassian
Pull request #194 (2023-05-07 05:21:32)

:sparkles: Implemented the Admin Cloud Organization Directory Service.
1. Added the ability to extract the last-activity information from an Atlassian Account using the id as reference.
2. Added the ability to suspend, enable and remove accounts.


Patch:
diff --git a/admin/apl_client_impl.go b/admin/apl_client_impl.go
index 5a455df..f8997ae 100644
--- a/admin/apl_client_impl.go
+++ b/admin/apl_client_impl.go
@@ -49,7 +49,11 @@ func New(httpClient common.HttpClient) (*Client, error) {
 		Schema: internal.NewSCIMSchemaService(client),
 	}
 
-	client.Organization = internal.NewOrganizationService(client, internal.NewOrganizationPolicyService(client))
+	client.Organization = internal.NewOrganizationService(
+		client,
+		internal.NewOrganizationPolicyService(client),
+		internal.NewOrganizationDirectoryService(client))
+
 	client.User = internal.NewUserService(client, internal.NewUserTokenService(client))
 
 	return client, nil
diff --git a/admin/internal/organization_directory_impl.go b/admin/internal/organization_directory_impl.go
new file mode 100644
index 0000000..6158a81
--- /dev/null
+++ b/admin/internal/organization_directory_impl.go
@@ -0,0 +1,176 @@
+package internal
+
+import (
+	"context"
+	"fmt"
+	model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
+	"github.com/ctreminiom/go-atlassian/service"
+	"github.com/ctreminiom/go-atlassian/service/admin"
+	"net/http"
+)
+
+func NewOrganizationDirectoryService(client service.Client) *OrganizationDirectoryService {
+	return &OrganizationDirectoryService{internalClient: &internalOrganizationDirectoryServiceImpl{c: client}}
+}
+
+type OrganizationDirectoryService struct {
+	internalClient admin.OrganizationDirectoryConnector
+}
+
+// Activity returns a user’s last active date for each product listed in Atlassian Administration.
+//
+// Active is defined as viewing a product's page for a minimum of 2 seconds.
+//
+// Last activity data can be delayed by up to 4 hours.
+//
+// If the user has not accessed a product, the product_access response field will be empty.
+//
+// The added_to_org date field is available only to customers using the new user management experience.
+//
+// GET /admin/v1/orgs/{orgId}/directory/users/{accountId}/last-active-dates
+//
+// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#users-last-active-dates
+func (o *OrganizationDirectoryService) Activity(ctx context.Context, organizationID, accountID string) (*model.UserProductAccessScheme, *model.ResponseScheme, error) {
+	return o.internalClient.Activity(ctx, organizationID, accountID)
+}
+
+// Remove removes user access to products listed in Atlassian Administration.
+//
+// -- The API is available for customers using the new user management experience only. --
+//
+// Note: Users with emails whose domain is claimed can still be found in Managed accounts in Directory.
+//
+// DELETE /admin/v1/orgs/{orgId}/directory/users/{accountId}
+//
+// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#remove-user-access
+func (o *OrganizationDirectoryService) Remove(ctx context.Context, organizationID, accountID string) (*model.ResponseScheme, error) {
+	return o.internalClient.Remove(ctx, organizationID, accountID)
+}
+
+// Suspend suspends user access to products listed in Atlassian Administration.
+//
+// -- The API is available for customers using the new user management experience only. --
+//
+// Note: Users with emails whose domain is claimed can still be found in Managed accounts in Directory.
+//
+// POST /admin/v1/orgs/{orgId}/directory/users/{accountId}/suspend-access
+//
+// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#suspend-user-access
+func (o *OrganizationDirectoryService) Suspend(ctx context.Context, organizationID, accountID string) (*model.GenericActionSuccessScheme, *model.ResponseScheme, error) {
+	return o.internalClient.Suspend(ctx, organizationID, accountID)
+}
+
+// Restore restores user access to products listed in Atlassian Administration.
+//
+// -- The API is available for customers using the new user management experience only. --
+//
+// Note: Users with emails whose domain is claimed can still be found in Managed accounts in Directory.
+//
+// POST /admin/v1/orgs/{orgId}/directory/users/{accountId}/restore-access
+//
+// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#restore-user-access
+func (o *OrganizationDirectoryService) Restore(ctx context.Context, organizationID, accountID string) (*model.GenericActionSuccessScheme, *model.ResponseScheme, error) {
+	return o.internalClient.Restore(ctx, organizationID, accountID)
+}
+
+type internalOrganizationDirectoryServiceImpl struct {
+	c service.Client
+}
+
+func (i *internalOrganizationDirectoryServiceImpl) Activity(ctx context.Context, organizationID, accountID string) (*model.UserProductAccessScheme, *model.ResponseScheme, error) {
+
+	if organizationID == "" {
+		return nil, nil, model.ErrNoAdminOrganizationError
+	}
+
+	if accountID == "" {
+		return nil, nil, model.ErrNoAdminAccountIDError
+	}
+
+	endpoint := fmt.Sprintf("admin/v1/orgs/%v/directory/users/%v/last-active-dates", organizationID, accountID)
+
+	request, err := i.c.NewRequest(ctx, http.MethodGet, endpoint, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	accessInfo := new(model.UserProductAccessScheme)
+	response, err := i.c.Call(request, accessInfo)
+	if err != nil {
+		return nil, response, err
+	}
+
+	return accessInfo, response, nil
+}
+
+func (i *internalOrganizationDirectoryServiceImpl) Remove(ctx context.Context, organizationID, accountID string) (*model.ResponseScheme, error) {
+
+	if organizationID == "" {
+		return nil, model.ErrNoAdminOrganizationError
+	}
+
+	if accountID == "" {
+		return nil, model.ErrNoAdminAccountIDError
+	}
+
+	endpoint := fmt.Sprintf("admin/v1/orgs/%v/directory/users/%v", organizationID, accountID)
+
+	request, err := i.c.NewRequest(ctx, http.MethodDelete, endpoint, nil)
+	if err != nil {
+		return nil, err
+	}
+
+	return i.c.Call(request, nil)
+}
+
+func (i *internalOrganizationDirectoryServiceImpl) Suspend(ctx context.Context, organizationID, accountID string) (*model.GenericActionSuccessScheme, *model.ResponseScheme, error) {
+
+	if organizationID == "" {
+		return nil, nil, model.ErrNoAdminOrganizationError
+	}
+
+	if accountID == "" {
+		return nil, nil, model.ErrNoAdminAccountIDError
+	}
+
+	endpoint := fmt.Sprintf("admin/v1/orgs/%v/directory/users/%v/suspend-access", organizationID, accountID)
+
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	message := new(model.GenericActionSuccessScheme)
+	response, err := i.c.Call(request, message)
+	if err != nil {
+		return nil, response, err
+	}
+
+	return message, response, nil
+}
+
+func (i *internalOrganizationDirectoryServiceImpl) Restore(ctx context.Context, organizationID, accountID string) (*model.GenericActionSuccessScheme, *model.ResponseScheme, error) {
+
+	if organizationID == "" {
+		return nil, nil, model.ErrNoAdminOrganizationError
+	}
+
+	if accountID == "" {
+		return nil, nil, model.ErrNoAdminAccountIDError
+	}
+
+	endpoint := fmt.Sprintf("admin/v1/orgs/%v/directory/users/%v/restore-access", organizationID, accountID)
+
+	request, err := i.c.NewRequest(ctx, http.MethodPost, endpoint, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	message := new(model.GenericActionSuccessScheme)
+	response, err := i.c.Call(request, message)
+	if err != nil {
+		return nil, response, err
+	}
+
+	return message, response, nil
+}
diff --git a/admin/internal/organization_impl.go b/admin/internal/organization_impl.go
index 1650d87..ccf041c 100644
--- a/admin/internal/organization_impl.go
+++ b/admin/internal/organization_impl.go
@@ -12,13 +12,14 @@ import (
 	"strings"
 )
 
-func NewOrganizationService(client service.Client, policy *OrganizationPolicyService) *OrganizationService {
-	return &OrganizationService{internalClient: &internalOrganizationImpl{c: client}, Policy: policy}
+func NewOrganizationService(client service.Client, policy *OrganizationPolicyService, directory *OrganizationDirectoryService) *OrganizationService {
+	return &OrganizationService{internalClient: &internalOrganizationImpl{c: client}, Policy: policy, Directory: directory}
 }
 
 type OrganizationService struct {
 	internalClient admin.OrganizationConnector
 	Policy         *OrganizationPolicyService
+	Directory      *OrganizationDirectoryService
 }
 
 // Gets returns a list of your organizations (based on your API key).
diff --git a/pkg/infra/models/admin_organization.go b/pkg/infra/models/admin_organization.go
index 96b86c9..6e241fc 100644
--- a/pkg/infra/models/admin_organization.go
+++ b/pkg/infra/models/admin_organization.go
@@ -183,3 +183,24 @@ type OrganizationEventActionModelAttributesScheme struct {
 	DisplayName      string `json:"displayName,omitempty"`
 	GroupDisplayName string `json:"groupDisplayName,omitempty"`
 }
+
+type UserProductAccessScheme struct {
+	Data *UserProductAccessDataScheme `json:"data,omitempty"`
+}
+
+type UserProductAccessDataScheme struct {
+	ProductAccess []*UserProductLastActiveScheme `json:"product_access,omitempty"`
+	AddedToOrg    string                         `json:"added_to_org,omitempty"`
+}
+
+type UserProductLastActiveScheme struct {
+	Id         string `json:"id,omitempty"`
+	Key        string `json:"key,omitempty"`
+	Name       string `json:"name,omitempty"`
+	Url        string `json:"url,omitempty"`
+	LastActive string `json:"last_active,omitempty"`
+}
+
+type GenericActionSuccessScheme struct {
+	Message string `json:"message,omitempty"`
+}
diff --git a/service/admin/organization_directory.go b/service/admin/organization_directory.go
new file mode 100644
index 0000000..79ba97d
--- /dev/null
+++ b/service/admin/organization_directory.go
@@ -0,0 +1,59 @@
+package admin
+
+import (
+	"context"
+	"github.com/ctreminiom/go-atlassian/pkg/infra/models"
+)
+
+// OrganizationDirectoryConnector represents the cloud admin organization directory endpoints.
+// Use it to remove, restore, and suspend users from the organization.
+type OrganizationDirectoryConnector interface {
+
+	// Activity returns a user’s last active date for each product listed in Atlassian Administration.
+	//
+	// Active is defined as viewing a product's page for a minimum of 2 seconds.
+	//
+	// Last activity data can be delayed by up to 4 hours.
+	//
+	// If the user has not accessed a product, the product_access response field will be empty.
+	//
+	// The added_to_org date field is available only to customers using the new user management experience.
+	//
+	// GET /admin/v1/orgs/{orgId}/directory/users/{accountId}/last-active-dates
+	//
+	// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#users-last-active-dates
+	Activity(ctx context.Context, organizationID, accountID string) (*models.UserProductAccessScheme, *models.ResponseScheme, error)
+
+	// Remove removes user access to products listed in Atlassian Administration.
+	//
+	// -- The API is available for customers using the new user management experience only. --
+	//
+	// Note: Users with emails whose domain is claimed can still be found in Managed accounts in Directory.
+	//
+	// DELETE /admin/v1/orgs/{orgId}/directory/users/{accountId}
+	//
+	// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#remove-user-access
+	Remove(ctx context.Context, organizationID, accountID string) (*models.ResponseScheme, error)
+
+	// Suspend suspends user access to products listed in Atlassian Administration.
+	//
+	// -- The API is available for customers using the new user management experience only. --
+	//
+	// Note: Users with emails whose domain is claimed can still be found in Managed accounts in Directory.
+	//
+	// POST /admin/v1/orgs/{orgId}/directory/users/{accountId}/suspend-access
+	//
+	// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#suspend-user-access
+	Suspend(ctx context.Context, organizationID, accountID string) (*models.GenericActionSuccessScheme, *models.ResponseScheme, error)
+
+	// Restore restores user access to products listed in Atlassian Administration.
+	//
+	// -- The API is available for customers using the new user management experience only. --
+	//
+	// Note: Users with emails whose domain is claimed can still be found in Managed accounts in Directory.
+	//
+	// POST /admin/v1/orgs/{orgId}/directory/users/{accountId}/restore-access
+	//
+	// https://docs.go-atlassian.io/atlassian-admin-cloud/organization/directory#restore-user-access
+	Restore(ctx context.Context, organizationID, accountID string) (*models.GenericActionSuccessScheme, *models.ResponseScheme, error)
+}


Test patch:
diff --git a/admin/internal/organization_directory_impl_test.go b/admin/internal/organization_directory_impl_test.go
new file mode 100644
index 0000000..b509ba8
--- /dev/null
+++ b/admin/internal/organization_directory_impl_test.go
@@ -0,0 +1,507 @@
+package internal
+
+import (
+	"context"
+	"errors"
+	model "github.com/ctreminiom/go-atlassian/pkg/infra/models"
+	"github.com/ctreminiom/go-atlassian/service"
+	"github.com/ctreminiom/go-atlassian/service/mocks"
+	"github.com/stretchr/testify/assert"
+	"net/http"
+	"testing"
+)
+
+func Test_internalOrganizationDirectoryServiceImpl_Activity(t *testing.T) {
+
+	type fields struct {
+		c service.Client
+	}
+
+	type args struct {
+		ctx                       context.Context
+		organizationID, accountID string
+	}
+
+	testCases := []struct {
+		name    string
+		fields  fields
+		args    args
+		on      func(*fields)
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the parameters are correct",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodGet,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample/last-active-dates",
+					nil).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
+					&model.UserProductAccessScheme{}).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+
+			},
+		},
+
+		{
+			name: "when the organization id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminOrganizationError,
+		},
+
+		{
+			name: "when the account id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminAccountIDError,
+		},
+
+		{
+			name: "when the http request cannot be created",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodGet,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample/last-active-dates",
+					nil).
+					Return(&http.Request{}, errors.New("error, unable to create the http request"))
+
+				fields.c = client
+
+			},
+			wantErr: true,
+			Err:     errors.New("error, unable to create the http request"),
+		},
+	}
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+
+			if testCase.on != nil {
+				testCase.on(&testCase.fields)
+			}
+
+			service := NewOrganizationDirectoryService(testCase.fields.c)
+
+			gotResult, gotResponse, err := service.Activity(testCase.args.ctx, testCase.args.organizationID,
+				testCase.args.accountID)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.EqualError(t, err, testCase.Err.Error())
+
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+			}
+
+		})
+	}
+}
+
+func Test_internalOrganizationDirectoryServiceImpl_Remove(t *testing.T) {
+
+	type fields struct {
+		c service.Client
+	}
+
+	type args struct {
+		ctx                       context.Context
+		organizationID, accountID string
+	}
+
+	testCases := []struct {
+		name    string
+		fields  fields
+		args    args
+		on      func(*fields)
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the parameters are correct",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodDelete,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample",
+					nil).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
+					nil).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+
+			},
+		},
+
+		{
+			name: "when the organization id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminOrganizationError,
+		},
+
+		{
+			name: "when the account id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminAccountIDError,
+		},
+
+		{
+			name: "when the http request cannot be created",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodDelete,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample",
+					nil).
+					Return(&http.Request{}, errors.New("error, unable to create the http request"))
+
+				fields.c = client
+
+			},
+			wantErr: true,
+			Err:     errors.New("error, unable to create the http request"),
+		},
+	}
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+
+			if testCase.on != nil {
+				testCase.on(&testCase.fields)
+			}
+
+			service := NewOrganizationDirectoryService(testCase.fields.c)
+
+			gotResponse, err := service.Remove(testCase.args.ctx, testCase.args.organizationID,
+				testCase.args.accountID)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.EqualError(t, err, testCase.Err.Error())
+
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+			}
+
+		})
+	}
+}
+
+func Test_internalOrganizationDirectoryServiceImpl_Suspend(t *testing.T) {
+
+	type fields struct {
+		c service.Client
+	}
+
+	type args struct {
+		ctx                       context.Context
+		organizationID, accountID string
+	}
+
+	testCases := []struct {
+		name    string
+		fields  fields
+		args    args
+		on      func(*fields)
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the parameters are correct",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodPost,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample/suspend-access",
+					nil).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
+					&model.GenericActionSuccessScheme{}).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+
+			},
+		},
+
+		{
+			name: "when the organization id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminOrganizationError,
+		},
+
+		{
+			name: "when the account id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminAccountIDError,
+		},
+
+		{
+			name: "when the http request cannot be created",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodPost,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample/suspend-access",
+					nil).
+					Return(&http.Request{}, errors.New("error, unable to create the http request"))
+
+				fields.c = client
+
+			},
+			wantErr: true,
+			Err:     errors.New("error, unable to create the http request"),
+		},
+	}
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+
+			if testCase.on != nil {
+				testCase.on(&testCase.fields)
+			}
+
+			service := NewOrganizationDirectoryService(testCase.fields.c)
+
+			gotResult, gotResponse, err := service.Suspend(testCase.args.ctx, testCase.args.organizationID,
+				testCase.args.accountID)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.EqualError(t, err, testCase.Err.Error())
+
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+			}
+
+		})
+	}
+}
+
+func Test_internalOrganizationDirectoryServiceImpl_Restore(t *testing.T) {
+
+	type fields struct {
+		c service.Client
+	}
+
+	type args struct {
+		ctx                       context.Context
+		organizationID, accountID string
+	}
+
+	testCases := []struct {
+		name    string
+		fields  fields
+		args    args
+		on      func(*fields)
+		wantErr bool
+		Err     error
+	}{
+		{
+			name: "when the parameters are correct",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodPost,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample/restore-access",
+					nil).
+					Return(&http.Request{}, nil)
+
+				client.On("Call",
+					&http.Request{},
+					&model.GenericActionSuccessScheme{}).
+					Return(&model.ResponseScheme{}, nil)
+
+				fields.c = client
+
+			},
+		},
+
+		{
+			name: "when the organization id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminOrganizationError,
+		},
+
+		{
+			name: "when the account id is not provided",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+			},
+			wantErr: true,
+			Err:     model.ErrNoAdminAccountIDError,
+		},
+
+		{
+			name: "when the http request cannot be created",
+			args: args{
+				ctx:            context.TODO(),
+				organizationID: "organization-id-sample",
+				accountID:      "account-id-sample",
+			},
+			on: func(fields *fields) {
+
+				client := mocks.NewClient(t)
+
+				client.On("NewRequest",
+					context.Background(),
+					http.MethodPost,
+					"admin/v1/orgs/organization-id-sample/directory/users/account-id-sample/restore-access",
+					nil).
+					Return(&http.Request{}, errors.New("error, unable to create the http request"))
+
+				fields.c = client
+
+			},
+			wantErr: true,
+			Err:     errors.New("error, unable to create the http request"),
+		},
+	}
+
+	for _, testCase := range testCases {
+		t.Run(testCase.name, func(t *testing.T) {
+
+			if testCase.on != nil {
+				testCase.on(&testCase.fields)
+			}
+
+			service := NewOrganizationDirectoryService(testCase.fields.c)
+
+			gotResult, gotResponse, err := service.Restore(testCase.args.ctx, testCase.args.organizationID,
+				testCase.args.accountID)
+
+			if testCase.wantErr {
+
+				if err != nil {
+					t.Logf("error returned: %v", err.Error())
+				}
+
+				assert.EqualError(t, err, testCase.Err.Error())
+
+			} else {
+
+				assert.NoError(t, err)
+				assert.NotEqual(t, gotResponse, nil)
+				assert.NotEqual(t, gotResult, nil)
+			}
+
+		})
+	}
+}
diff --git a/admin/internal/organization_impl_test.go b/admin/internal/organization_impl_test.go
index ffbd374..bed43b8 100644
--- a/admin/internal/organization_impl_test.go
+++ b/admin/internal/organization_impl_test.go
@@ -90,7 +90,7 @@ func Test_internalOrganizationImpl_Gets(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Gets(testCase.args.ctx, testCase.args.cursor)
 
@@ -201,7 +201,7 @@ func Test_internalOrganizationImpl_Get(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Get(testCase.args.ctx, testCase.args.organizationID)
 
@@ -314,7 +314,7 @@ func Test_internalOrganizationImpl_Users(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Users(testCase.args.ctx, testCase.args.organizationID, testCase.args.cursor)
 
@@ -427,7 +427,7 @@ func Test_internalOrganizationImpl_Domains(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Domains(testCase.args.ctx, testCase.args.organizationID, testCase.args.cursor)
 
@@ -550,7 +550,7 @@ func Test_internalOrganizationImpl_Domain(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Domain(testCase.args.ctx, testCase.args.organizationID, testCase.args.domainID)
 
@@ -687,7 +687,7 @@ func Test_internalOrganizationImpl_Events(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Events(testCase.args.ctx, testCase.args.organizationID,
 				testCase.args.options, testCase.args.cursor)
@@ -811,7 +811,7 @@ func Test_internalOrganizationImpl_Event(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Event(testCase.args.ctx, testCase.args.organizationID, testCase.args.eventID)
 
@@ -912,7 +912,7 @@ func Test_internalOrganizationImpl_Actions(t *testing.T) {
 				testCase.on(&testCase.fields)
 			}
 
-			service := NewOrganizationService(testCase.fields.c, nil)
+			service := NewOrganizationService(testCase.fields.c, nil, nil)
 
 			gotResult, gotResponse, err := service.Actions(testCase.args.ctx, testCase.args.organizationID)