1// Copyright 2016 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	"fmt"
11	"net/http"
12	"reflect"
13	"strings"
14	"testing"
15)
16
17func TestMigrationService_StartMigration(t *testing.T) {
18	client, mux, _, teardown := setup()
19	defer teardown()
20
21	mux.HandleFunc("/orgs/o/migrations", func(w http.ResponseWriter, r *http.Request) {
22		testMethod(t, r, "POST")
23		testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
24
25		w.WriteHeader(http.StatusCreated)
26		w.Write(migrationJSON)
27	})
28
29	opt := &MigrationOptions{
30		LockRepositories:   true,
31		ExcludeAttachments: false,
32	}
33	ctx := context.Background()
34	got, _, err := client.Migrations.StartMigration(ctx, "o", []string{"r"}, opt)
35	if err != nil {
36		t.Errorf("StartMigration returned error: %v", err)
37	}
38	if want := wantMigration; !reflect.DeepEqual(got, want) {
39		t.Errorf("StartMigration = %+v, want %+v", got, want)
40	}
41
42	const methodName = "StartMigration"
43	testBadOptions(t, methodName, func() (err error) {
44		_, _, err = client.Migrations.StartMigration(ctx, "\n", []string{"\n"}, opt)
45		return err
46	})
47
48	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
49		got, resp, err := client.Migrations.StartMigration(ctx, "o", []string{"r"}, opt)
50		if got != nil {
51			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
52		}
53		return resp, err
54	})
55}
56
57func TestMigrationService_ListMigrations(t *testing.T) {
58	client, mux, _, teardown := setup()
59	defer teardown()
60
61	mux.HandleFunc("/orgs/o/migrations", func(w http.ResponseWriter, r *http.Request) {
62		testMethod(t, r, "GET")
63		testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
64
65		w.WriteHeader(http.StatusOK)
66		w.Write([]byte(fmt.Sprintf("[%s]", migrationJSON)))
67	})
68
69	ctx := context.Background()
70	got, _, err := client.Migrations.ListMigrations(ctx, "o", &ListOptions{Page: 1, PerPage: 2})
71	if err != nil {
72		t.Errorf("ListMigrations returned error: %v", err)
73	}
74	if want := []*Migration{wantMigration}; !reflect.DeepEqual(got, want) {
75		t.Errorf("ListMigrations = %+v, want %+v", got, want)
76	}
77
78	const methodName = "ListMigrations"
79	testBadOptions(t, methodName, func() (err error) {
80		_, _, err = client.Migrations.ListMigrations(ctx, "\n", &ListOptions{Page: 1, PerPage: 2})
81		return err
82	})
83
84	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
85		got, resp, err := client.Migrations.ListMigrations(ctx, "o", &ListOptions{Page: 1, PerPage: 2})
86		if got != nil {
87			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
88		}
89		return resp, err
90	})
91}
92
93func TestMigrationService_MigrationStatus(t *testing.T) {
94	client, mux, _, teardown := setup()
95	defer teardown()
96
97	mux.HandleFunc("/orgs/o/migrations/1", func(w http.ResponseWriter, r *http.Request) {
98		testMethod(t, r, "GET")
99		testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
100
101		w.WriteHeader(http.StatusOK)
102		w.Write(migrationJSON)
103	})
104
105	ctx := context.Background()
106	got, _, err := client.Migrations.MigrationStatus(ctx, "o", 1)
107	if err != nil {
108		t.Errorf("MigrationStatus returned error: %v", err)
109	}
110	if want := wantMigration; !reflect.DeepEqual(got, want) {
111		t.Errorf("MigrationStatus = %+v, want %+v", got, want)
112	}
113
114	const methodName = "MigrationStatus"
115	testBadOptions(t, methodName, func() (err error) {
116		_, _, err = client.Migrations.MigrationStatus(ctx, "\n", -1)
117		return err
118	})
119
120	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
121		got, resp, err := client.Migrations.MigrationStatus(ctx, "o", 1)
122		if got != nil {
123			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
124		}
125		return resp, err
126	})
127}
128
129func TestMigrationService_MigrationArchiveURL(t *testing.T) {
130	client, mux, _, teardown := setup()
131	defer teardown()
132
133	mux.HandleFunc("/orgs/o/migrations/1/archive", func(w http.ResponseWriter, r *http.Request) {
134		testMethod(t, r, "GET")
135		testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
136
137		http.Redirect(w, r, "/yo", http.StatusFound)
138	})
139	mux.HandleFunc("/yo", func(w http.ResponseWriter, r *http.Request) {
140		testMethod(t, r, "GET")
141
142		w.WriteHeader(http.StatusOK)
143		w.Write([]byte("0123456789abcdef"))
144	})
145
146	ctx := context.Background()
147	got, err := client.Migrations.MigrationArchiveURL(ctx, "o", 1)
148	if err != nil {
149		t.Errorf("MigrationStatus returned error: %v", err)
150	}
151	if want := "/yo"; !strings.HasSuffix(got, want) {
152		t.Errorf("MigrationArchiveURL = %+v, want %+v", got, want)
153	}
154
155	const methodName = "MigrationArchiveURL"
156	testBadOptions(t, methodName, func() (err error) {
157		_, err = client.Migrations.MigrationArchiveURL(ctx, "\n", -1)
158		return err
159	})
160}
161
162func TestMigrationService_DeleteMigration(t *testing.T) {
163	client, mux, _, teardown := setup()
164	defer teardown()
165
166	mux.HandleFunc("/orgs/o/migrations/1/archive", func(w http.ResponseWriter, r *http.Request) {
167		testMethod(t, r, "DELETE")
168		testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
169
170		w.WriteHeader(http.StatusNoContent)
171	})
172
173	ctx := context.Background()
174	if _, err := client.Migrations.DeleteMigration(ctx, "o", 1); err != nil {
175		t.Errorf("DeleteMigration returned error: %v", err)
176	}
177
178	const methodName = "DeleteMigration"
179	testBadOptions(t, methodName, func() (err error) {
180		_, err = client.Migrations.DeleteMigration(ctx, "\n", -1)
181		return err
182	})
183
184	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
185		return client.Migrations.DeleteMigration(ctx, "o", 1)
186	})
187}
188
189func TestMigrationService_UnlockRepo(t *testing.T) {
190	client, mux, _, teardown := setup()
191	defer teardown()
192
193	mux.HandleFunc("/orgs/o/migrations/1/repos/r/lock", func(w http.ResponseWriter, r *http.Request) {
194		testMethod(t, r, "DELETE")
195		testHeader(t, r, "Accept", mediaTypeMigrationsPreview)
196
197		w.WriteHeader(http.StatusNoContent)
198	})
199
200	ctx := context.Background()
201	if _, err := client.Migrations.UnlockRepo(ctx, "o", 1, "r"); err != nil {
202		t.Errorf("UnlockRepo returned error: %v", err)
203	}
204
205	const methodName = "UnlockRepo"
206	testBadOptions(t, methodName, func() (err error) {
207		_, err = client.Migrations.UnlockRepo(ctx, "\n", -1, "\n")
208		return err
209	})
210
211	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
212		return client.Migrations.UnlockRepo(ctx, "o", 1, "r")
213	})
214}
215
216var migrationJSON = []byte(`{
217  "id": 79,
218  "guid": "0b989ba4-242f-11e5-81e1-c7b6966d2516",
219  "state": "pending",
220  "lock_repositories": true,
221  "exclude_attachments": false,
222  "url": "https://api.github.com/orgs/octo-org/migrations/79",
223  "created_at": "2015-07-06T15:33:38-07:00",
224  "updated_at": "2015-07-06T15:33:38-07:00",
225  "repositories": [
226    {
227      "id": 1296269,
228      "name": "Hello-World",
229      "full_name": "octocat/Hello-World",
230      "description": "This your first repo!"
231    }
232  ]
233}`)
234
235var wantMigration = &Migration{
236	ID:                 Int64(79),
237	GUID:               String("0b989ba4-242f-11e5-81e1-c7b6966d2516"),
238	State:              String("pending"),
239	LockRepositories:   Bool(true),
240	ExcludeAttachments: Bool(false),
241	URL:                String("https://api.github.com/orgs/octo-org/migrations/79"),
242	CreatedAt:          String("2015-07-06T15:33:38-07:00"),
243	UpdatedAt:          String("2015-07-06T15:33:38-07:00"),
244	Repositories: []*Repository{
245		{
246			ID:          Int64(1296269),
247			Name:        String("Hello-World"),
248			FullName:    String("octocat/Hello-World"),
249			Description: String("This your first repo!"),
250		},
251	},
252}
253