1package github
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "math/rand"
8 "net/http"
9 "os"
10 "testing"
11 "time"
12
13 "github.com/stretchr/testify/require"
14
15 "github.com/MichaelMure/git-bug/bridge/core"
16 "github.com/MichaelMure/git-bug/cache"
17 "github.com/MichaelMure/git-bug/repository"
18 "github.com/MichaelMure/git-bug/util/interrupt"
19)
20
21const (
22 testRepoBaseName = "git-bug-test-github-exporter"
23)
24
25// testCases creates bugs in repo cache
26func testCases(repo *cache.RepoCache, identity *cache.IdentityCache) (map[string]*cache.BugCache, error) {
27 bugs := make(map[string]*cache.BugCache)
28
29 // simple bug
30 simpleBug, err := repo.NewBugRaw(identity, time.Now().Unix(), "simple bug", "new bug", nil, nil)
31 if err != nil {
32 return nil, err
33 }
34 bugs["simple bug"] = simpleBug
35
36 /*
37 // bug with comments
38 bugWithComments, err := repo.NewBugRaw(author, time.Now().Unix(), "bug with comments", "new bug", nil, nil)
39 if err != nil {
40 return nil, err
41 }
42
43 _, err = bugWithComments.AddCommentRaw(author, time.Now().Unix(), "new comment", nil, nil)
44 if err != nil {
45 return nil, err
46 }
47 bugs["bug with comments"] = bugWithComments
48
49 // bug with label changes
50 bugLabelChange, err := repo.NewBugRaw(author, time.Now().Unix(), "bug label change", "new bug", nil, nil)
51 if err != nil {
52 return nil, err
53 }
54
55 _, _, err = bugLabelChange.ChangeLabelsRaw(author, time.Now().Unix(), []string{"bug", "core"}, nil, nil)
56 if err != nil {
57 return nil, err
58 }
59
60 _, _, err = bugLabelChange.ChangeLabelsRaw(author, time.Now().Unix(), nil, []string{"bug"}, nil)
61 if err != nil {
62 return nil, err
63 }
64 bugs["bug change label"] = bugWithComments
65 */
66 return nil, err
67}
68
69func TestExporter(t *testing.T) {
70 user := os.Getenv("TEST_USER")
71 token := os.Getenv("BOT_TOKEN")
72 if token == "" {
73 t.Skip("Env var GITHUB_TOKEN_PRIVATE missing")
74 }
75
76 repo := repository.CreateTestRepo(false)
77 defer repository.CleanupTestRepos(t, repo)
78
79 backend, err := cache.NewRepoCache(repo)
80 require.NoError(t, err)
81
82 author, err := backend.NewIdentity("test identity", "hello@testidentity.org")
83 if err != nil {
84 t.Fatal(err)
85 }
86
87 err = backend.SetUserIdentity(author)
88 if err != nil {
89 t.Fatal(err)
90 }
91
92 defer backend.Close()
93 interrupt.RegisterCleaner(backend.Close)
94
95 tests, err := testCases(backend, author)
96 if err != nil {
97 t.Fatal(err)
98 }
99
100 // generate project name
101 projectName := generateRepoName()
102 fmt.Println("creating repo", projectName)
103 if err := createRepository(projectName, token); err != nil {
104 t.Fatal(err)
105 }
106
107 //
108 //
109 defer func(t *testing.T) {
110 fmt.Println("deleting repo", projectName)
111 if err := deleteRepository(projectName, user, token); err != nil {
112 t.Fatal(err)
113 }
114 }(t)
115
116 exporter := &githubExporter{}
117 err = exporter.Init(core.Configuration{
118 keyOwner: user,
119 keyProject: projectName,
120 keyToken: token,
121 })
122 require.NoError(t, err)
123
124 start := time.Now()
125
126 err = exporter.ExportAll(backend, time.Time{})
127 require.NoError(t, err)
128
129 fmt.Printf("test repository exported in %f seconds\n", time.Since(start).Seconds())
130 for name, tt := range tests {
131 t.Run(name, func(t *testing.T) {
132 fmt.Println(tt.Snapshot())
133 })
134 }
135}
136
137func generateRepoName() string {
138 rand.Seed(time.Now().UnixNano())
139 var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
140 b := make([]rune, 8)
141 for i := range b {
142 b[i] = letterRunes[rand.Intn(len(letterRunes))]
143 }
144 return fmt.Sprintf("%s-%s", testRepoBaseName, string(b))
145}
146
147func createRepository(project, token string) error {
148 url := fmt.Sprintf("%s/user/repos", githubV3Url)
149
150 params := struct {
151 Name string `json:"name"`
152 Description string `json:"description"`
153 Private bool `json:"private"`
154 HasIssues bool `json:"has_issues"`
155 }{
156 Name: project,
157 Description: "git-bug exporter temporary test repository",
158 Private: true,
159 HasIssues: true,
160 }
161
162 data, err := json.Marshal(params)
163 if err != nil {
164 return err
165 }
166
167 req, err := http.NewRequest("POST", url, bytes.NewBuffer(data))
168 if err != nil {
169 return err
170 }
171
172 // need the token for private repositories
173 req.Header.Set("Authorization", fmt.Sprintf("token %s", token))
174
175 client := &http.Client{
176 Timeout: defaultTimeout,
177 }
178
179 resp, err := client.Do(req)
180 if err != nil {
181 return err
182 }
183
184 return resp.Body.Close()
185}
186
187func deleteRepository(project, owner, token string) error {
188 url := fmt.Sprintf("%s/repos/%s/%s", githubV3Url, owner, project)
189
190 req, err := http.NewRequest("DELETE", url, nil)
191 if err != nil {
192 return err
193 }
194
195 // need the token for private repositories
196 req.Header.Set("Authorization", fmt.Sprintf("token %s", token))
197
198 client := &http.Client{
199 Timeout: defaultTimeout,
200 }
201
202 resp, err := client.Do(req)
203 if err != nil {
204 return err
205 }
206
207 defer resp.Body.Close()
208
209 if resp.StatusCode != http.StatusNoContent {
210 return fmt.Errorf("error deleting repository")
211 }
212
213 return nil
214}