diff --git a/gitlab/gitlab.go b/gitlab/gitlab.go index e181817..3fe6ac8 100644 --- a/gitlab/gitlab.go +++ b/gitlab/gitlab.go @@ -38,6 +38,7 @@ const ( objectPush string = "push" objectTag string = "tag_push" objectMergeRequest string = "merge_request" + objectBuild string = "build" ) // Option is a configuration option for the webhook @@ -173,9 +174,15 @@ func eventParsing(gitLabEvent Event, events []Event, payload []byte) (interface{ err := json.Unmarshal([]byte(payload), &pl) return pl, err case JobEvents: - var p1 JobEventPayload - err := json.Unmarshal([]byte(payload), &p1) - return p1, err + var pl JobEventPayload + err := json.Unmarshal([]byte(payload), &pl) + if err != nil { + return nil, err + } + if pl.ObjectKind == objectBuild { + return eventParsing(BuildEvents, events, payload) + } + return pl, nil case SystemHookEvents: var pl SystemHookPayload diff --git a/gitlab/gitlab_test.go b/gitlab/gitlab_test.go index f13e608..df82c0c 100644 --- a/gitlab/gitlab_test.go +++ b/gitlab/gitlab_test.go @@ -231,15 +231,67 @@ func TestWebhooks(t *testing.T) { "X-Gitlab-Event": []string{"Build Hook"}, }, }, + } + + for _, tt := range tests { + tc := tt + client := &http.Client{} + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + payload, err := os.Open(tc.filename) + assert.NoError(err) + defer func() { + _ = payload.Close() + }() + + var parseError error + var results interface{} + server := newServer(func(w http.ResponseWriter, r *http.Request) { + results, parseError = hook.Parse(r, tc.event) + }) + defer server.Close() + req, err := http.NewRequest(http.MethodPost, server.URL+path, payload) + assert.NoError(err) + req.Header = tc.headers + req.Header.Set("Content-Type", "application/json") + req.Header.Set("X-Gitlab-Token", "sampleToken!") + + resp, err := client.Do(req) + assert.NoError(err) + assert.Equal(http.StatusOK, resp.StatusCode) + assert.NoError(parseError) + assert.Equal(reflect.TypeOf(tc.typ), reflect.TypeOf(results)) + }) + } +} + +func TestJobHooks(t *testing.T) { + assert := require.New(t) + tests := []struct { + name string + events []Event + typ interface{} + filename string + headers http.Header + }{ { name: "JobEvent", - event: JobEvents, + events: []Event{JobEvents}, typ: JobEventPayload{}, filename: "../testdata/gitlab/job-event.json", headers: http.Header{ "X-Gitlab-Event": []string{"Job Hook"}, }, }, + { + name: "JobEvent", + events: []Event{JobEvents, BuildEvents}, + typ: BuildEventPayload{}, + filename: "../testdata/gitlab/build-event.json", + headers: http.Header{ + "X-Gitlab-Event": []string{"Job Hook"}, + }, + }, } for _, tt := range tests { @@ -256,7 +308,7 @@ func TestWebhooks(t *testing.T) { var parseError error var results interface{} server := newServer(func(w http.ResponseWriter, r *http.Request) { - results, parseError = hook.Parse(r, tc.event) + results, parseError = hook.Parse(r, tc.events...) }) defer server.Close() req, err := http.NewRequest(http.MethodPost, server.URL+path, payload)