Commit da0b1dd5 authored by Heidi Berry's avatar Heidi Berry Committed by Timo Furrer
Browse files

feat(integrations): add group integration for microsoft teams

Changelog: Improvements
parent e736e37b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ type Client struct {
	GroupCluster                     GroupClustersServiceInterface
	GroupEpicBoards                  GroupEpicBoardsServiceInterface
	GroupImportExport                GroupImportExportServiceInterface
	Integrations                     IntegrationsServiceInterface
	GroupIssueBoards                 GroupIssueBoardsServiceInterface
	GroupIterations                  GroupIterationsServiceInterface
	GroupLabels                      GroupLabelsServiceInterface
@@ -426,6 +427,7 @@ func NewAuthSourceClient(as AuthSource, options ...ClientOptionFunc) (*Client, e
	c.GroupCluster = &GroupClustersService{client: c}
	c.GroupEpicBoards = &GroupEpicBoardsService{client: c}
	c.GroupImportExport = &GroupImportExportService{client: c}
	c.Integrations = &IntegrationsService{client: c}
	c.GroupIssueBoards = &GroupIssueBoardsService{client: c}
	c.GroupIterations = &GroupIterationsService{client: c}
	c.GroupLabels = &GroupLabelsService{client: c}
+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ var serviceMap = map[any]any{
	&ImportService{}:                           (*ImportServiceInterface)(nil),
	&InstanceClustersService{}:                 (*InstanceClustersServiceInterface)(nil),
	&InstanceVariablesService{}:                (*InstanceVariablesServiceInterface)(nil),
	&IntegrationsService{}:                     (*IntegrationsServiceInterface)(nil),
	&InvitesService{}:                          (*InvitesServiceInterface)(nil),
	&IssueBoardsService{}:                      (*IssueBoardsServiceInterface)(nil),
	&IssueLinksService{}:                       (*IssueLinksServiceInterface)(nil),

integrations.go

0 → 100644
+202 −0
Original line number Diff line number Diff line
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package gitlab

import (
	"fmt"
	"net/http"
	"time"
)

type (
	IntegrationsServiceInterface interface {
		ListActiveGroupIntegrations(gid any, opt *ListActiveIntegrationsOptions, options ...RequestOptionFunc) ([]*Integration, *Response, error)
		SetGroupMicrosoftTeamsNotifications(gid any, opt *SetMicrosoftTeamsNotificationsOptions, options ...RequestOptionFunc) (*Integration, *Response, error)
		DisableGroupMicrosoftTeamsNotifications(gid any, options ...RequestOptionFunc) (*Response, error)
		GetGroupMicrosoftTeamsNotifications(gid any, options ...RequestOptionFunc) (*Integration, *Response, error)
	}

	// IntegrationsService handles communication with the group
	// integrations related methods of the GitLab API.
	//
	// GitLab API docs: https://docs.gitlab.com/ee/api/group_integrations.html
	IntegrationsService struct {
		client *Client
	}
)

var _ IntegrationsServiceInterface = (*IntegrationsService)(nil)

// Integration represents a GitLab group or project integration.
//
// GitLab API docs:
// https://docs.gitlab.com/api/group_integrations/
// https://docs.gitlab.com/api/project_integrations/
type Integration struct {
	ID                             int        `json:"id"`
	Title                          string     `json:"title"`
	Slug                           string     `json:"slug"`
	CreatedAt                      *time.Time `json:"created_at"`
	UpdatedAt                      *time.Time `json:"updated_at"`
	Active                         bool       `json:"active"`
	AlertEvents                    bool       `json:"alert_events"`
	CommitEvents                   bool       `json:"commit_events"`
	ConfidentialIssuesEvents       bool       `json:"confidential_issues_events"`
	ConfidentialNoteEvents         bool       `json:"confidential_note_events"`
	DeploymentEvents               bool       `json:"deployment_events"`
	GroupConfidentialMentionEvents bool       `json:"group_confidential_mention_events"`
	GroupMentionEvents             bool       `json:"group_mention_events"`
	IncidentEvents                 bool       `json:"incident_events"`
	IssuesEvents                   bool       `json:"issues_events"`
	JobEvents                      bool       `json:"job_events"`
	MergeRequestsEvents            bool       `json:"merge_requests_events"`
	NoteEvents                     bool       `json:"note_events"`
	PipelineEvents                 bool       `json:"pipeline_events"`
	PushEvents                     bool       `json:"push_events"`
	TagPushEvents                  bool       `json:"tag_push_events"`
	VulnerabilityEvents            bool       `json:"vulnerability_events"`
	WikiPageEvents                 bool       `json:"wiki_page_events"`
	CommentOnEventEnabled          bool       `json:"comment_on_event_enabled"`
	Inherited                      bool       `json:"inherited"`
}

// ListActiveIntegrationsOptions represents the available
// ListActiveIntegrations() options.
//
// GitLab API docs:
// https://docs.gitlab.com/api/group_integrations/#list-all-active-integrations
type ListActiveIntegrationsOptions struct {
	ListOptions
}

// ListActiveIntegrations Get a list of all active group integrations.
// The vulnerability_events field is only available for GitLab Enterprise Edition.
//
// GitLab API docs:
// https://docs.gitlab.com/api/group_integrations/#list-all-active-integrations
func (s *IntegrationsService) ListActiveGroupIntegrations(gid any, opt *ListActiveIntegrationsOptions, options ...RequestOptionFunc) ([]*Integration, *Response, error) {
	group, err := parseID(gid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("groups/%s/integrations", PathEscape(group))

	req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
	if err != nil {
		return nil, nil, err
	}

	var integrations []*Integration
	resp, err := s.client.Do(req, &integrations)
	if err != nil {
		return nil, resp, err
	}

	return integrations, resp, nil
}

// SetMicrosoftTeamsNotificationsOptions represents the available
// SetMicrosoftTeamsNotifications() options.
//
// GitLab API docs:
// https://docs.gitlab.com/api/group_integrations/#set-up-microsoft-teams-notifications
type SetMicrosoftTeamsNotificationsOptions struct {
	Targets                   *string `url:"targets,omitempty"`
	Webhook                   *string `url:"webhook,omitempty"`
	NotifyOnlyBrokenPipelines *bool   `url:"notify_only_broken_pipelines,omitempty"`
	NotifyOnlyDefaultBranch   *bool   `url:"notify_only_default_branch,omitempty"`
	BranchesToBeNotified      *string `url:"branches_to_be_notified,omitempty"`
	PushEvents                *bool   `url:"push_events,omitempty"`
	IssuesEvents              *bool   `url:"issues_events,omitempty"`
	ConfidentialIssuesEvents  *bool   `url:"confidential_issues_events,omitempty"`
	MergeRequestsEvents       *bool   `url:"merge_requests_events,omitempty"`
	TagPushEvents             *bool   `url:"tag_push_events,omitempty"`
	NoteEvents                *bool   `url:"note_events,omitempty"`
	ConfidentialNoteEvents    *bool   `url:"confidential_note_events,omitempty"`
	PipelineEvents            *bool   `url:"pipeline_events,omitempty"`
	WikiPageEvents            *bool   `url:"wiki_page_events,omitempty"`
	UseInheritedSettings      *bool   `url:"use_inherited_settings,omitempty"`
}

// SetGroupMicrosoftTeamsNotifications sets up Microsoft Teams notifications for a group.
//
// GitLab API docs:
// https://docs.gitlab.com/api/group_integrations/#set-up-microsoft-teams-notifications
func (s *IntegrationsService) SetGroupMicrosoftTeamsNotifications(gid any, opt *SetMicrosoftTeamsNotificationsOptions, options ...RequestOptionFunc) (*Integration, *Response, error) {
	group, err := parseID(gid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("groups/%s/integrations/microsoft_teams", PathEscape(group))

	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
	if err != nil {
		return nil, nil, err
	}

	integration := new(Integration)
	resp, err := s.client.Do(req, integration)
	if err != nil {
		return nil, resp, err
	}
	return integration, resp, nil
}

// DisableGroupMicrosoftTeamsNotifications disables Microsoft Teams notifications
// for a group. Integration settings are reset.
//
// GitLab API docs:
// https://docs.gitlab.com/api/group_integrations/#disable-microsoft-teams-notifications
func (s *IntegrationsService) DisableGroupMicrosoftTeamsNotifications(gid any, options ...RequestOptionFunc) (*Response, error) {
	group, err := parseID(gid)
	if err != nil {
		return nil, err
	}
	u := fmt.Sprintf("groups/%s/integrations/microsoft_teams", PathEscape(group))

	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.Do(req, nil)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// GetGroupMicrosoftTeamsNotifications gets the Microsoft Teams notifications for a group.
//
// GitLab API docs:
// https://docs.gitlab.com/api/group_integrations/#get-microsoft-teams-notifications-settings
func (s *IntegrationsService) GetGroupMicrosoftTeamsNotifications(gid any, options ...RequestOptionFunc) (*Integration, *Response, error) {
	group, err := parseID(gid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("groups/%s/integrations/microsoft_teams", PathEscape(group))

	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
	if err != nil {
		return nil, nil, err
	}

	integration := new(Integration)
	resp, err := s.client.Do(req, integration)
	if err != nil {
		return nil, nil, err
	}
	return integration, resp, nil
}

integrations_test.go

0 → 100644
+270 −0
Original line number Diff line number Diff line
package gitlab

import (
	"fmt"
	"net/http"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func TestListActiveGroupIntegrations(t *testing.T) {
	t.Parallel()
	mux, client := setup(t)

	mux.HandleFunc("/api/v4/groups/1/integrations", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprint(w, `[
			{
				"id": 1,
				"title": "Microsoft Teams",
				"slug": "microsoft_teams",
				"created_at": "2023-01-01T00:00:00.000Z",
				"updated_at": "2023-01-02T00:00:00.000Z",
				"active": true,
				"commit_events": true,
				"push_events": true,
				"issues_events": true,
				"alert_events": false,
				"confidential_issues_events": false,
				"merge_requests_events": true,
				"tag_push_events": true,
				"deployment_events": false,
				"note_events": true,
				"confidential_note_events": false,
				"pipeline_events": true,
				"wiki_page_events": false,
				"job_events": false,
				"comment_on_event_enabled": true,
				"inherited": false,
				"vulnerability_events": false
			},
			{
				"id": 2,
				"title": "Slack",
				"slug": "slack",
				"created_at": "2023-01-03T00:00:00.000Z",
				"updated_at": "2023-01-04T00:00:00.000Z",
				"active": true,
				"commit_events": false,
				"push_events": true,
				"issues_events": true,
				"alert_events": true,
				"confidential_issues_events": true,
				"merge_requests_events": true,
				"tag_push_events": false,
				"deployment_events": true,
				"note_events": false,
				"confidential_note_events": false,
				"pipeline_events": false,
				"wiki_page_events": true,
				"job_events": true,
				"comment_on_event_enabled": false,
				"inherited": true,
				"vulnerability_events": true
			}
		]`)
	})

	integrations, resp, err := client.Integrations.ListActiveGroupIntegrations(1, nil)
	assert.NoError(t, err)
	assert.NotNil(t, resp)

	createdAt1, _ := time.Parse(time.RFC3339, "2023-01-01T00:00:00.000Z")
	updatedAt1, _ := time.Parse(time.RFC3339, "2023-01-02T00:00:00.000Z")
	createdAt2, _ := time.Parse(time.RFC3339, "2023-01-03T00:00:00.000Z")
	updatedAt2, _ := time.Parse(time.RFC3339, "2023-01-04T00:00:00.000Z")

	want := []*Integration{
		{
			ID:                       1,
			Title:                    "Microsoft Teams",
			Slug:                     "microsoft_teams",
			CreatedAt:                &createdAt1,
			UpdatedAt:                &updatedAt1,
			Active:                   true,
			CommitEvents:             true,
			PushEvents:               true,
			IssuesEvents:             true,
			AlertEvents:              false,
			ConfidentialIssuesEvents: false,
			MergeRequestsEvents:      true,
			TagPushEvents:            true,
			DeploymentEvents:         false,
			NoteEvents:               true,
			ConfidentialNoteEvents:   false,
			PipelineEvents:           true,
			WikiPageEvents:           false,
			JobEvents:                false,
			CommentOnEventEnabled:    true,
			Inherited:                false,
			VulnerabilityEvents:      false,
		},
		{
			ID:                       2,
			Title:                    "Slack",
			Slug:                     "slack",
			CreatedAt:                &createdAt2,
			UpdatedAt:                &updatedAt2,
			Active:                   true,
			CommitEvents:             false,
			PushEvents:               true,
			IssuesEvents:             true,
			AlertEvents:              true,
			ConfidentialIssuesEvents: true,
			MergeRequestsEvents:      true,
			TagPushEvents:            false,
			DeploymentEvents:         true,
			NoteEvents:               false,
			ConfidentialNoteEvents:   false,
			PipelineEvents:           false,
			WikiPageEvents:           true,
			JobEvents:                true,
			CommentOnEventEnabled:    false,
			Inherited:                true,
			VulnerabilityEvents:      true,
		},
	}
	assert.Equal(t, want, integrations)
	assert.NotNil(t, resp)
}

func TestSetGroupMicrosoftTeamsNotifications(t *testing.T) {
	t.Parallel()
	mux, client := setup(t)

	mux.HandleFunc("/api/v4/groups/1/integrations/microsoft_teams", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodPut)
		fmt.Fprint(w, `{
			"id": 1,
			"title": "Microsoft Teams",
			"slug": "microsoft_teams",
			"created_at": "2023-01-01T00:00:00.000Z",
			"updated_at": "2023-01-02T00:00:00.000Z",
			"active": true,
			"commit_events": true,
			"push_events": true,
			"issues_events": true,
			"alert_events": false,
			"confidential_issues_events": false,
			"merge_requests_events": true,
			"tag_push_events": true,
			"deployment_events": false,
			"note_events": true,
			"confidential_note_events": false,
			"pipeline_events": true,
			"wiki_page_events": false,
			"job_events": false,
			"comment_on_event_enabled": true,
			"inherited": false,
			"vulnerability_events": false
		}`)
	})
	integration, resp, err := client.Integrations.SetGroupMicrosoftTeamsNotifications(1, nil)
	assert.NoError(t, err)
	assert.NotNil(t, resp)
	createdAt, _ := time.Parse(time.RFC3339, "2023-01-01T00:00:00.000Z")
	updatedAt, _ := time.Parse(time.RFC3339, "2023-01-02T00:00:00.000Z")
	want := &Integration{
		ID:                       1,
		Title:                    "Microsoft Teams",
		Slug:                     "microsoft_teams",
		CreatedAt:                &createdAt,
		UpdatedAt:                &updatedAt,
		Active:                   true,
		CommitEvents:             true,
		PushEvents:               true,
		IssuesEvents:             true,
		AlertEvents:              false,
		ConfidentialIssuesEvents: false,
		MergeRequestsEvents:      true,
		TagPushEvents:            true,
		DeploymentEvents:         false,
		NoteEvents:               true,
		ConfidentialNoteEvents:   false,
		PipelineEvents:           true,
		WikiPageEvents:           false,
		JobEvents:                false,
		CommentOnEventEnabled:    true,
		Inherited:                false,
		VulnerabilityEvents:      false,
	}
	assert.Equal(t, want, integration)
}

func TestDisableGroupMicrosoftTeamsNotifications(t *testing.T) {
	t.Parallel()
	mux, client := setup(t)

	mux.HandleFunc("/api/v4/groups/1/integrations/microsoft_teams", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodDelete)
	})
	resp, err := client.Integrations.DisableGroupMicrosoftTeamsNotifications(1)
	assert.NoError(t, err)
	assert.NotNil(t, resp)
}

func TestGetGroupMicrosoftTeamsNotifications(t *testing.T) {
	t.Parallel()
	mux, client := setup(t)

	mux.HandleFunc("/api/v4/groups/1/integrations/microsoft_teams", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, http.MethodGet)
		fmt.Fprint(w, `{
			"id": 1,
			"title": "Microsoft Teams",
			"slug": "microsoft_teams",
			"created_at": "2023-01-01T00:00:00.000Z",
			"updated_at": "2023-01-02T00:00:00.000Z",
			"active": true,
			"commit_events": true,
			"push_events": true,
			"issues_events": true,
			"alert_events": false,
			"confidential_issues_events": false,
			"merge_requests_events": true,
			"tag_push_events": true,
			"deployment_events": false,
			"note_events": true,
			"confidential_note_events": false,
			"pipeline_events": true,
			"wiki_page_events": false,
			"job_events": false,
			"comment_on_event_enabled": true,
			"inherited": false,
			"vulnerability_events": false
		}`)
	})
	integration, resp, err := client.Integrations.GetGroupMicrosoftTeamsNotifications(1)
	assert.NoError(t, err)
	assert.NotNil(t, resp)

	createdAt, _ := time.Parse(time.RFC3339, "2023-01-01T00:00:00.000Z")
	updatedAt, _ := time.Parse(time.RFC3339, "2023-01-02T00:00:00.000Z")
	want := &Integration{
		ID:                       1,
		Title:                    "Microsoft Teams",
		Slug:                     "microsoft_teams",
		CreatedAt:                &createdAt,
		UpdatedAt:                &updatedAt,
		Active:                   true,
		CommitEvents:             true,
		PushEvents:               true,
		IssuesEvents:             true,
		AlertEvents:              false,
		ConfidentialIssuesEvents: false,
		MergeRequestsEvents:      true,
		TagPushEvents:            true,
		DeploymentEvents:         false,
		NoteEvents:               true,
		ConfidentialNoteEvents:   false,
		PipelineEvents:           true,
		WikiPageEvents:           false,
		JobEvents:                false,
		CommentOnEventEnabled:    true,
		Inherited:                false,
		VulnerabilityEvents:      false,
	}
	assert.Equal(t, want, integration)
}
+1 −28
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ import (
	"fmt"
	"net/http"
	"strconv"
	"time"
)

type (
@@ -103,33 +102,7 @@ var _ ServicesServiceInterface = (*ServicesService)(nil)
// Service represents a GitLab service.
//
// GitLab API docs: https://docs.gitlab.com/api/project_integrations/
type Service struct {
	ID                             int        `json:"id"`
	Title                          string     `json:"title"`
	Slug                           string     `json:"slug"`
	CreatedAt                      *time.Time `json:"created_at"`
	UpdatedAt                      *time.Time `json:"updated_at"`
	Active                         bool       `json:"active"`
	AlertEvents                    bool       `json:"alert_events"`
	CommitEvents                   bool       `json:"commit_events"`
	ConfidentialIssuesEvents       bool       `json:"confidential_issues_events"`
	ConfidentialNoteEvents         bool       `json:"confidential_note_events"`
	DeploymentEvents               bool       `json:"deployment_events"`
	GroupConfidentialMentionEvents bool       `json:"group_confidential_mention_events"`
	GroupMentionEvents             bool       `json:"group_mention_events"`
	IncidentEvents                 bool       `json:"incident_events"`
	IssuesEvents                   bool       `json:"issues_events"`
	JobEvents                      bool       `json:"job_events"`
	MergeRequestsEvents            bool       `json:"merge_requests_events"`
	NoteEvents                     bool       `json:"note_events"`
	PipelineEvents                 bool       `json:"pipeline_events"`
	PushEvents                     bool       `json:"push_events"`
	TagPushEvents                  bool       `json:"tag_push_events"`
	VulnerabilityEvents            bool       `json:"vulnerability_events"`
	WikiPageEvents                 bool       `json:"wiki_page_events"`
	CommentOnEventEnabled          bool       `json:"comment_on_event_enabled"`
	Inherited                      bool       `json:"inherited"`
}
type Service = Integration

// ListServices gets a list of all active services.
//
Loading