1// Copyright 2013 The go-github AUTHORS. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6package github
7
8import (
9	"context"
10	"encoding/json"
11	"fmt"
12	"net/http"
13	"reflect"
14	"testing"
15)
16
17func TestActivityService_ListEvents(t *testing.T) {
18	client, mux, _, teardown := setup()
19	defer teardown()
20
21	mux.HandleFunc("/events", func(w http.ResponseWriter, r *http.Request) {
22		testMethod(t, r, "GET")
23		testFormValues(t, r, values{
24			"page": "2",
25		})
26		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
27	})
28
29	opt := &ListOptions{Page: 2}
30	ctx := context.Background()
31	events, _, err := client.Activity.ListEvents(ctx, opt)
32	if err != nil {
33		t.Errorf("Activities.ListEvents returned error: %v", err)
34	}
35
36	want := []*Event{{ID: String("1")}, {ID: String("2")}}
37	if !reflect.DeepEqual(events, want) {
38		t.Errorf("Activities.ListEvents returned %+v, want %+v", events, want)
39	}
40
41	const methodName = "ListEvents"
42	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
43		got, resp, err := client.Activity.ListEvents(ctx, opt)
44		if got != nil {
45			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
46		}
47		return resp, err
48	})
49}
50
51func TestActivityService_ListRepositoryEvents(t *testing.T) {
52	client, mux, _, teardown := setup()
53	defer teardown()
54
55	mux.HandleFunc("/repos/o/r/events", func(w http.ResponseWriter, r *http.Request) {
56		testMethod(t, r, "GET")
57		testFormValues(t, r, values{
58			"page": "2",
59		})
60		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
61	})
62
63	opt := &ListOptions{Page: 2}
64	ctx := context.Background()
65	events, _, err := client.Activity.ListRepositoryEvents(ctx, "o", "r", opt)
66	if err != nil {
67		t.Errorf("Activities.ListRepositoryEvents returned error: %v", err)
68	}
69
70	want := []*Event{{ID: String("1")}, {ID: String("2")}}
71	if !reflect.DeepEqual(events, want) {
72		t.Errorf("Activities.ListRepositoryEvents returned %+v, want %+v", events, want)
73	}
74
75	const methodName = "ListRepositoryEvents"
76	testBadOptions(t, methodName, func() (err error) {
77		_, _, err = client.Activity.ListRepositoryEvents(ctx, "\n", "\n", opt)
78		return err
79	})
80
81	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
82		got, resp, err := client.Activity.ListRepositoryEvents(ctx, "o", "r", opt)
83		if got != nil {
84			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
85		}
86		return resp, err
87	})
88}
89
90func TestActivityService_ListRepositoryEvents_invalidOwner(t *testing.T) {
91	client, _, _, teardown := setup()
92	defer teardown()
93
94	ctx := context.Background()
95	_, _, err := client.Activity.ListRepositoryEvents(ctx, "%", "%", nil)
96	testURLParseError(t, err)
97}
98
99func TestActivityService_ListIssueEventsForRepository(t *testing.T) {
100	client, mux, _, teardown := setup()
101	defer teardown()
102
103	mux.HandleFunc("/repos/o/r/issues/events", func(w http.ResponseWriter, r *http.Request) {
104		testMethod(t, r, "GET")
105		testFormValues(t, r, values{
106			"page": "2",
107		})
108		fmt.Fprint(w, `[{"id":1},{"id":2}]`)
109	})
110
111	opt := &ListOptions{Page: 2}
112	ctx := context.Background()
113	events, _, err := client.Activity.ListIssueEventsForRepository(ctx, "o", "r", opt)
114	if err != nil {
115		t.Errorf("Activities.ListIssueEventsForRepository returned error: %v", err)
116	}
117
118	want := []*IssueEvent{{ID: Int64(1)}, {ID: Int64(2)}}
119	if !reflect.DeepEqual(events, want) {
120		t.Errorf("Activities.ListIssueEventsForRepository returned %+v, want %+v", events, want)
121	}
122
123	const methodName = "ListIssueEventsForRepository"
124	testBadOptions(t, methodName, func() (err error) {
125		_, _, err = client.Activity.ListIssueEventsForRepository(ctx, "\n", "\n", opt)
126		return err
127	})
128
129	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
130		got, resp, err := client.Activity.ListIssueEventsForRepository(ctx, "o", "r", opt)
131		if got != nil {
132			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
133		}
134		return resp, err
135	})
136}
137
138func TestActivityService_ListIssueEventsForRepository_invalidOwner(t *testing.T) {
139	client, _, _, teardown := setup()
140	defer teardown()
141
142	ctx := context.Background()
143	_, _, err := client.Activity.ListIssueEventsForRepository(ctx, "%", "%", nil)
144	testURLParseError(t, err)
145}
146
147func TestActivityService_ListEventsForRepoNetwork(t *testing.T) {
148	client, mux, _, teardown := setup()
149	defer teardown()
150
151	mux.HandleFunc("/networks/o/r/events", func(w http.ResponseWriter, r *http.Request) {
152		testMethod(t, r, "GET")
153		testFormValues(t, r, values{
154			"page": "2",
155		})
156		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
157	})
158
159	opt := &ListOptions{Page: 2}
160	ctx := context.Background()
161	events, _, err := client.Activity.ListEventsForRepoNetwork(ctx, "o", "r", opt)
162	if err != nil {
163		t.Errorf("Activities.ListEventsForRepoNetwork returned error: %v", err)
164	}
165
166	want := []*Event{{ID: String("1")}, {ID: String("2")}}
167	if !reflect.DeepEqual(events, want) {
168		t.Errorf("Activities.ListEventsForRepoNetwork returned %+v, want %+v", events, want)
169	}
170
171	const methodName = "ListEventsForRepoNetwork"
172	testBadOptions(t, methodName, func() (err error) {
173		_, _, err = client.Activity.ListEventsForRepoNetwork(ctx, "\n", "\n", opt)
174		return err
175	})
176
177	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
178		got, resp, err := client.Activity.ListEventsForRepoNetwork(ctx, "o", "r", opt)
179		if got != nil {
180			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
181		}
182		return resp, err
183	})
184}
185
186func TestActivityService_ListEventsForRepoNetwork_invalidOwner(t *testing.T) {
187	client, _, _, teardown := setup()
188	defer teardown()
189
190	ctx := context.Background()
191	_, _, err := client.Activity.ListEventsForRepoNetwork(ctx, "%", "%", nil)
192	testURLParseError(t, err)
193}
194
195func TestActivityService_ListEventsForOrganization(t *testing.T) {
196	client, mux, _, teardown := setup()
197	defer teardown()
198
199	mux.HandleFunc("/orgs/o/events", func(w http.ResponseWriter, r *http.Request) {
200		testMethod(t, r, "GET")
201		testFormValues(t, r, values{
202			"page": "2",
203		})
204		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
205	})
206
207	opt := &ListOptions{Page: 2}
208	ctx := context.Background()
209	events, _, err := client.Activity.ListEventsForOrganization(ctx, "o", opt)
210	if err != nil {
211		t.Errorf("Activities.ListEventsForOrganization returned error: %v", err)
212	}
213
214	want := []*Event{{ID: String("1")}, {ID: String("2")}}
215	if !reflect.DeepEqual(events, want) {
216		t.Errorf("Activities.ListEventsForOrganization returned %+v, want %+v", events, want)
217	}
218
219	const methodName = "ListEventsForOrganization"
220	testBadOptions(t, methodName, func() (err error) {
221		_, _, err = client.Activity.ListEventsForOrganization(ctx, "\n", opt)
222		return err
223	})
224
225	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
226		got, resp, err := client.Activity.ListEventsForOrganization(ctx, "o", opt)
227		if got != nil {
228			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
229		}
230		return resp, err
231	})
232}
233
234func TestActivityService_ListEventsForOrganization_invalidOrg(t *testing.T) {
235	client, _, _, teardown := setup()
236	defer teardown()
237
238	ctx := context.Background()
239	_, _, err := client.Activity.ListEventsForOrganization(ctx, "%", nil)
240	testURLParseError(t, err)
241}
242
243func TestActivityService_ListEventsPerformedByUser_all(t *testing.T) {
244	client, mux, _, teardown := setup()
245	defer teardown()
246
247	mux.HandleFunc("/users/u/events", func(w http.ResponseWriter, r *http.Request) {
248		testMethod(t, r, "GET")
249		testFormValues(t, r, values{
250			"page": "2",
251		})
252		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
253	})
254
255	opt := &ListOptions{Page: 2}
256	ctx := context.Background()
257	events, _, err := client.Activity.ListEventsPerformedByUser(ctx, "u", false, opt)
258	if err != nil {
259		t.Errorf("Events.ListPerformedByUser returned error: %v", err)
260	}
261
262	want := []*Event{{ID: String("1")}, {ID: String("2")}}
263	if !reflect.DeepEqual(events, want) {
264		t.Errorf("Events.ListPerformedByUser returned %+v, want %+v", events, want)
265	}
266
267	const methodName = "ListEventsPerformedByUser"
268	testBadOptions(t, methodName, func() (err error) {
269		_, _, err = client.Activity.ListEventsPerformedByUser(ctx, "\n", false, opt)
270		return err
271	})
272
273	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
274		got, resp, err := client.Activity.ListEventsPerformedByUser(ctx, "u", false, opt)
275		if got != nil {
276			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
277		}
278		return resp, err
279	})
280}
281
282func TestActivityService_ListEventsPerformedByUser_publicOnly(t *testing.T) {
283	client, mux, _, teardown := setup()
284	defer teardown()
285
286	mux.HandleFunc("/users/u/events/public", func(w http.ResponseWriter, r *http.Request) {
287		testMethod(t, r, "GET")
288		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
289	})
290
291	ctx := context.Background()
292	events, _, err := client.Activity.ListEventsPerformedByUser(ctx, "u", true, nil)
293	if err != nil {
294		t.Errorf("Events.ListPerformedByUser returned error: %v", err)
295	}
296
297	want := []*Event{{ID: String("1")}, {ID: String("2")}}
298	if !reflect.DeepEqual(events, want) {
299		t.Errorf("Events.ListPerformedByUser returned %+v, want %+v", events, want)
300	}
301}
302
303func TestActivityService_ListEventsPerformedByUser_invalidUser(t *testing.T) {
304	client, _, _, teardown := setup()
305	defer teardown()
306
307	ctx := context.Background()
308	_, _, err := client.Activity.ListEventsPerformedByUser(ctx, "%", false, nil)
309	testURLParseError(t, err)
310}
311
312func TestActivityService_ListEventsReceivedByUser_all(t *testing.T) {
313	client, mux, _, teardown := setup()
314	defer teardown()
315
316	mux.HandleFunc("/users/u/received_events", func(w http.ResponseWriter, r *http.Request) {
317		testMethod(t, r, "GET")
318		testFormValues(t, r, values{
319			"page": "2",
320		})
321		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
322	})
323
324	opt := &ListOptions{Page: 2}
325	ctx := context.Background()
326	events, _, err := client.Activity.ListEventsReceivedByUser(ctx, "u", false, opt)
327	if err != nil {
328		t.Errorf("Events.ListReceivedByUser returned error: %v", err)
329	}
330
331	want := []*Event{{ID: String("1")}, {ID: String("2")}}
332	if !reflect.DeepEqual(events, want) {
333		t.Errorf("Events.ListReceivedUser returned %+v, want %+v", events, want)
334	}
335
336	const methodName = "ListEventsReceivedByUser"
337	testBadOptions(t, methodName, func() (err error) {
338		_, _, err = client.Activity.ListEventsReceivedByUser(ctx, "\n", false, opt)
339		return err
340	})
341
342	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
343		got, resp, err := client.Activity.ListEventsReceivedByUser(ctx, "u", false, opt)
344		if got != nil {
345			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
346		}
347		return resp, err
348	})
349}
350
351func TestActivityService_ListEventsReceivedByUser_publicOnly(t *testing.T) {
352	client, mux, _, teardown := setup()
353	defer teardown()
354
355	mux.HandleFunc("/users/u/received_events/public", func(w http.ResponseWriter, r *http.Request) {
356		testMethod(t, r, "GET")
357		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
358	})
359
360	ctx := context.Background()
361	events, _, err := client.Activity.ListEventsReceivedByUser(ctx, "u", true, nil)
362	if err != nil {
363		t.Errorf("Events.ListReceivedByUser returned error: %v", err)
364	}
365
366	want := []*Event{{ID: String("1")}, {ID: String("2")}}
367	if !reflect.DeepEqual(events, want) {
368		t.Errorf("Events.ListReceivedByUser returned %+v, want %+v", events, want)
369	}
370}
371
372func TestActivityService_ListEventsReceivedByUser_invalidUser(t *testing.T) {
373	client, _, _, teardown := setup()
374	defer teardown()
375
376	ctx := context.Background()
377	_, _, err := client.Activity.ListEventsReceivedByUser(ctx, "%", false, nil)
378	testURLParseError(t, err)
379}
380
381func TestActivityService_ListUserEventsForOrganization(t *testing.T) {
382	client, mux, _, teardown := setup()
383	defer teardown()
384
385	mux.HandleFunc("/users/u/events/orgs/o", func(w http.ResponseWriter, r *http.Request) {
386		testMethod(t, r, "GET")
387		testFormValues(t, r, values{
388			"page": "2",
389		})
390		fmt.Fprint(w, `[{"id":"1"},{"id":"2"}]`)
391	})
392
393	opt := &ListOptions{Page: 2}
394	ctx := context.Background()
395	events, _, err := client.Activity.ListUserEventsForOrganization(ctx, "o", "u", opt)
396	if err != nil {
397		t.Errorf("Activities.ListUserEventsForOrganization returned error: %v", err)
398	}
399
400	want := []*Event{{ID: String("1")}, {ID: String("2")}}
401	if !reflect.DeepEqual(events, want) {
402		t.Errorf("Activities.ListUserEventsForOrganization returned %+v, want %+v", events, want)
403	}
404
405	const methodName = "ListUserEventsForOrganization"
406	testBadOptions(t, methodName, func() (err error) {
407		_, _, err = client.Activity.ListUserEventsForOrganization(ctx, "\n", "\n", opt)
408		return err
409	})
410
411	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
412		got, resp, err := client.Activity.ListUserEventsForOrganization(ctx, "o", "u", opt)
413		if got != nil {
414			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
415		}
416		return resp, err
417	})
418}
419
420func TestActivityService_EventParsePayload_typed(t *testing.T) {
421	raw := []byte(`{"type": "PushEvent","payload":{"push_id": 1}}`)
422	var event *Event
423	if err := json.Unmarshal(raw, &event); err != nil {
424		t.Fatalf("Unmarshal Event returned error: %v", err)
425	}
426
427	want := &PushEvent{PushID: Int64(1)}
428	got, err := event.ParsePayload()
429	if err != nil {
430		t.Fatalf("ParsePayload returned unexpected error: %v", err)
431	}
432	if !reflect.DeepEqual(got, want) {
433		t.Errorf("Event.ParsePayload returned %+v, want %+v", got, want)
434	}
435}
436
437// TestEvent_Payload_untyped checks that unrecognized events are parsed to an
438// interface{} value (instead of being discarded or throwing an error), for
439// forward compatibility with new event types.
440func TestActivityService_EventParsePayload_untyped(t *testing.T) {
441	raw := []byte(`{"type": "UnrecognizedEvent","payload":{"field": "val"}}`)
442	var event *Event
443	if err := json.Unmarshal(raw, &event); err != nil {
444		t.Fatalf("Unmarshal Event returned error: %v", err)
445	}
446
447	want := map[string]interface{}{"field": "val"}
448	got, err := event.ParsePayload()
449	if err != nil {
450		t.Fatalf("ParsePayload returned unexpected error: %v", err)
451	}
452	if !reflect.DeepEqual(got, want) {
453		t.Errorf("Event.ParsePayload returned %+v, want %+v", got, want)
454	}
455}
456
457func TestActivityService_EventParsePayload_installation(t *testing.T) {
458	raw := []byte(`{"type": "PullRequestEvent","payload":{"installation":{"id":1}}}`)
459	var event *Event
460	if err := json.Unmarshal(raw, &event); err != nil {
461		t.Fatalf("Unmarshal Event returned error: %v", err)
462	}
463
464	want := &PullRequestEvent{Installation: &Installation{ID: Int64(1)}}
465	got, err := event.ParsePayload()
466	if err != nil {
467		t.Fatalf("ParsePayload returned unexpected error: %v", err)
468	}
469	if !reflect.DeepEqual(got, want) {
470		t.Errorf("Event.ParsePayload returned %+v, want %+v", got, want)
471	}
472}
473