Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

Align project notification events #1809

Merged
merged 3 commits into from
Oct 13, 2023
Merged
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
64 changes: 38 additions & 26 deletions notifications.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,24 @@ type NotificationSettings struct {
// GitLab API docs:
// https://docs.gitlab.com/ee/api/notification_settings.html#valid-notification-levels
type NotificationEvents struct {
CloseIssue bool `json:"close_issue"`
CloseMergeRequest bool `json:"close_merge_request"`
FailedPipeline bool `json:"failed_pipeline"`
MergeMergeRequest bool `json:"merge_merge_request"`
NewIssue bool `json:"new_issue"`
NewMergeRequest bool `json:"new_merge_request"`
NewNote bool `json:"new_note"`
ReassignIssue bool `json:"reassign_issue"`
ReassignMergeRequest bool `json:"reassign_merge_request"`
ReopenIssue bool `json:"reopen_issue"`
ReopenMergeRequest bool `json:"reopen_merge_request"`
SuccessPipeline bool `json:"success_pipeline"`
CloseIssue bool `json:"close_issue"`
CloseMergeRequest bool `json:"close_merge_request"`
FailedPipeline bool `json:"failed_pipeline"`
FixedPipeline bool `json:"fixed_pipeline"`
IssueDue bool `json:"issue_due"`
MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"`
MergeMergeRequest bool `json:"merge_merge_request"`
MovedProject bool `json:"moved_project"`
NewIssue bool `json:"new_issue"`
NewMergeRequest bool `json:"new_merge_request"`
NewEpic bool `json:"new_epic"`
NewNote bool `json:"new_note"`
PushToMergeRequest bool `json:"push_to_merge_request"`
ReassignIssue bool `json:"reassign_issue"`
ReassignMergeRequest bool `json:"reassign_merge_request"`
ReopenIssue bool `json:"reopen_issue"`
ReopenMergeRequest bool `json:"reopen_merge_request"`
SuccessPipeline bool `json:"success_pipeline"`
}

func (ns NotificationSettings) String() string {
Expand Down Expand Up @@ -87,20 +93,26 @@ func (s *NotificationSettingsService) GetGlobalSettings(options ...RequestOption
// NotificationSettingsOptions represents the available options that can be passed
// to the API when updating the notification settings.
type NotificationSettingsOptions struct {
Level *NotificationLevelValue `url:"level,omitempty" json:"level,omitempty"`
NotificationEmail *string `url:"notification_email,omitempty" json:"notification_email,omitempty"`
CloseIssue *bool `url:"close_issue,omitempty" json:"close_issue,omitempty"`
CloseMergeRequest *bool `url:"close_merge_request,omitempty" json:"close_merge_request,omitempty"`
FailedPipeline *bool `url:"failed_pipeline,omitempty" json:"failed_pipeline,omitempty"`
MergeMergeRequest *bool `url:"merge_merge_request,omitempty" json:"merge_merge_request,omitempty"`
NewIssue *bool `url:"new_issue,omitempty" json:"new_issue,omitempty"`
NewMergeRequest *bool `url:"new_merge_request,omitempty" json:"new_merge_request,omitempty"`
NewNote *bool `url:"new_note,omitempty" json:"new_note,omitempty"`
ReassignIssue *bool `url:"reassign_issue,omitempty" json:"reassign_issue,omitempty"`
ReassignMergeRequest *bool `url:"reassign_merge_request,omitempty" json:"reassign_merge_request,omitempty"`
ReopenIssue *bool `url:"reopen_issue,omitempty" json:"reopen_issue,omitempty"`
ReopenMergeRequest *bool `url:"reopen_merge_request,omitempty" json:"reopen_merge_request,omitempty"`
SuccessPipeline *bool `url:"success_pipeline,omitempty" json:"success_pipeline,omitempty"`
Level *NotificationLevelValue `url:"level,omitempty" json:"level,omitempty"`
NotificationEmail *string `url:"notification_email,omitempty" json:"notification_email,omitempty"`
CloseIssue *bool `url:"close_issue,omitempty" json:"close_issue,omitempty"`
CloseMergeRequest *bool `url:"close_merge_request,omitempty" json:"close_merge_request,omitempty"`
FailedPipeline *bool `url:"failed_pipeline,omitempty" json:"failed_pipeline,omitempty"`
FixedPipeline *bool `url:"fixed_pipeline,omitempty" json:"fixed_pipeline,omitempty"`
IssueDue *bool `url:"issue_due,omitempty" json:"issue_due,omitempty"`
MergeMergeRequest *bool `url:"merge_merge_request,omitempty" json:"merge_merge_request,omitempty"`
MergeWhenPipelineSucceeds *bool `url:"merge_when_pipeline_succeeds,omitempty" json:"merge_when_pipeline_succeeds,omitempty"`
MovedProject *bool `url:"moved_project,omitempty" json:"moved_project,omitempty"`
NewEpic *bool `url:"new_epic,omitempty" json:"new_epic,omitempty"`
NewIssue *bool `url:"new_issue,omitempty" json:"new_issue,omitempty"`
NewMergeRequest *bool `url:"new_merge_request,omitempty" json:"new_merge_request,omitempty"`
NewNote *bool `url:"new_note,omitempty" json:"new_note,omitempty"`
PushToMergeRequest *bool `url:"push_to_merge_request,omitempty" json:"push_to_merge_request,omitempty"`
ReassignIssue *bool `url:"reassign_issue,omitempty" json:"reassign_issue,omitempty"`
ReassignMergeRequest *bool `url:"reassign_merge_request,omitempty" json:"reassign_merge_request,omitempty"`
ReopenIssue *bool `url:"reopen_issue,omitempty" json:"reopen_issue,omitempty"`
ReopenMergeRequest *bool `url:"reopen_merge_request,omitempty" json:"reopen_merge_request,omitempty"`
SuccessPipeline *bool `url:"success_pipeline,omitempty" json:"success_pipeline,omitempty"`
}

// UpdateGlobalSettings updates current notification settings and email address.
Expand Down
150 changes: 150 additions & 0 deletions notifications_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package gitlab

import (
"encoding/json"
"fmt"
"io"
"net/http"
"reflect"
"testing"
Expand Down Expand Up @@ -47,3 +49,151 @@ func TestGetGlobalSettings(t *testing.T) {
t.Errorf("NotificationSettings.GetGlobalSettings returned %+v, want %+v", settings, want)
}
}

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

mux.HandleFunc("/api/v4/projects/1/notification_settings", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodGet)
fmt.Fprintf(w, `{
"level":"custom",
"events":{
"new_note":true,
"new_issue":true,
"reopen_issue":true,
"close_issue":true,
"reassign_issue":true,
"issue_due":true,
"new_merge_request":true,
"push_to_merge_request":true,
"reopen_merge_request":true,
"close_merge_request":true,
"reassign_merge_request":true,
"merge_merge_request":true,
"failed_pipeline":true,
"fixed_pipeline":true,
"success_pipeline":true,
"moved_project":true,
"merge_when_pipeline_succeeds":true,
"new_epic":true
}
}`)
})

settings, _, err := client.NotificationSettings.GetSettingsForProject(1)
if err != nil {
t.Errorf("NotifcationSettings.GetSettingsForProject returned error: %v", err)
}

want := &NotificationSettings{
Level: 5, //custom
Events: &NotificationEvents{
NewEpic: true,
NewNote: true,
NewIssue: true,
ReopenIssue: true,
CloseIssue: true,
ReassignIssue: true,
IssueDue: true,
NewMergeRequest: true,
PushToMergeRequest: true,
ReopenMergeRequest: true,
CloseMergeRequest: true,
ReassignMergeRequest: true,
MergeMergeRequest: true,
FailedPipeline: true,
FixedPipeline: true,
SuccessPipeline: true,
MovedProject: true,
MergeWhenPipelineSucceeds: true,
},
}
if !reflect.DeepEqual(settings, want) {
t.Errorf("NotificationSettings.GetSettingsForProject returned %+v, want %+v", settings, want)
}
}

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

// Create the request to send
var reqBody NotificationSettingsOptions
customLevel := notificationLevelTypes["custom"]
options := NotificationSettingsOptions{
Level: &customLevel,
NewEpic: Bool(true),
MovedProject: Bool(true),
CloseIssue: Bool(true),
}

// Handle the request on the server, and return a fully hydrated response
mux.HandleFunc("/api/v4/projects/1/notification_settings", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, http.MethodPut)

// Store the body for later, so we can check only some values are marshaled properly for update
body, _ := io.ReadAll(r.Body)
json.Unmarshal(body, &reqBody)

fmt.Fprintf(w, `{
"level":"custom",
"events":{
"new_note":true,
"new_issue":true,
"reopen_issue":true,
"close_issue":true,
"reassign_issue":true,
"issue_due":true,
"new_merge_request":true,
"push_to_merge_request":true,
"reopen_merge_request":true,
"close_merge_request":true,
"reassign_merge_request":true,
"merge_merge_request":true,
"failed_pipeline":true,
"fixed_pipeline":true,
"success_pipeline":true,
"moved_project":true,
"merge_when_pipeline_succeeds":true,
"new_epic":true
}
}`)
})

// Make the actual request
settings, _, err := client.NotificationSettings.UpdateSettingsForProject(1, &options)
if err != nil {
t.Errorf("NotifcationSettings.UpdateSettingsForProject returned error: %v", err)
}

// Test the response and the request
wantResponse := &NotificationSettings{
Level: customLevel,
Events: &NotificationEvents{
NewEpic: true,
NewNote: true,
NewIssue: true,
ReopenIssue: true,
CloseIssue: true,
ReassignIssue: true,
IssueDue: true,
NewMergeRequest: true,
PushToMergeRequest: true,
ReopenMergeRequest: true,
CloseMergeRequest: true,
ReassignMergeRequest: true,
MergeMergeRequest: true,
FailedPipeline: true,
FixedPipeline: true,
SuccessPipeline: true,
MovedProject: true,
MergeWhenPipelineSucceeds: true,
},
}

if !reflect.DeepEqual(settings, wantResponse) {
t.Errorf("NotificationSettings.UpdateSettingsForProject returned for the response %+v, want %+v", settings, wantResponse)
}
if !reflect.DeepEqual(settings, wantResponse) {
t.Errorf("NotificationSettings.UpdateSettingsForProject send for the request %+v, want %+v", reqBody, options)
}
}
Loading