import_test.go

  1package github
  2
  3import (
  4	"context"
  5	"fmt"
  6	"os"
  7	"testing"
  8	"time"
  9
 10	"github.com/stretchr/testify/require"
 11
 12	"github.com/MichaelMure/git-bug/bridge/core"
 13	"github.com/MichaelMure/git-bug/bridge/core/auth"
 14	"github.com/MichaelMure/git-bug/cache"
 15	"github.com/MichaelMure/git-bug/entities/bug"
 16	"github.com/MichaelMure/git-bug/entities/common"
 17	"github.com/MichaelMure/git-bug/entities/identity"
 18	"github.com/MichaelMure/git-bug/entity/dag"
 19	"github.com/MichaelMure/git-bug/repository"
 20	"github.com/MichaelMure/git-bug/util/interrupt"
 21)
 22
 23func TestGithubImporter(t *testing.T) {
 24	envToken := os.Getenv("GITHUB_TOKEN_PRIVATE")
 25	if envToken == "" {
 26		t.Skip("Env var GITHUB_TOKEN_PRIVATE missing")
 27	}
 28
 29	repo := repository.CreateGoGitTestRepo(t, false)
 30
 31	backend, buildEvents, err := cache.NewRepoCache(repo)
 32	require.NoError(t, err)
 33	for event := range buildEvents {
 34		require.NoError(t, event.Err)
 35	}
 36
 37	defer backend.Close()
 38	interrupt.RegisterCleaner(backend.Close)
 39
 40	author, err := identity.NewIdentity(repo, "Michael Muré", "batolettre@gmail.com")
 41	require.NoError(t, err)
 42
 43	tests := []struct {
 44		name string
 45		url  string
 46		bug  *bug.Snapshot
 47	}{
 48		{
 49			name: "simple issue",
 50			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/1",
 51			bug: &bug.Snapshot{
 52				Operations: []dag.Operation{
 53					bug.NewCreateOp(author, 0, "simple issue", "initial comment", nil),
 54					bug.NewAddCommentOp(author, 0, "first comment", nil),
 55					bug.NewAddCommentOp(author, 0, "second comment", nil),
 56				},
 57			},
 58		},
 59		{
 60			name: "empty issue",
 61			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/2",
 62			bug: &bug.Snapshot{
 63				Operations: []dag.Operation{
 64					bug.NewCreateOp(author, 0, "empty issue", "", nil),
 65				},
 66			},
 67		},
 68		{
 69			name: "complex issue",
 70			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/3",
 71			bug: &bug.Snapshot{
 72				Operations: []dag.Operation{
 73					bug.NewCreateOp(author, 0, "complex issue", "initial comment", nil),
 74					bug.NewLabelChangeOperation(author, 0, []bug.Label{"bug"}, []bug.Label{}),
 75					bug.NewLabelChangeOperation(author, 0, []bug.Label{"duplicate"}, []bug.Label{}),
 76					bug.NewLabelChangeOperation(author, 0, []bug.Label{}, []bug.Label{"duplicate"}),
 77					bug.NewAddCommentOp(author, 0, "### header\n\n**bold**\n\n_italic_\n\n> with quote\n\n`inline code`\n\n```\nmultiline code\n```\n\n- bulleted\n- list\n\n1. numbered\n1. list\n\n- [ ] task\n- [x] list\n\n@MichaelMure mention\n\n#2 reference issue\n#3 auto-reference issue\n\n![image](https://user-images.githubusercontent.com/294669/56870222-811faf80-6a0c-11e9-8f2c-f0beb686303f.png)", nil),
 78					bug.NewSetTitleOp(author, 0, "complex issue edited", "complex issue"),
 79					bug.NewSetTitleOp(author, 0, "complex issue", "complex issue edited"),
 80					bug.NewSetStatusOp(author, 0, common.ClosedStatus),
 81					bug.NewSetStatusOp(author, 0, common.OpenStatus),
 82				},
 83			},
 84		},
 85		{
 86			name: "editions",
 87			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/4",
 88			bug: &bug.Snapshot{
 89				Operations: []dag.Operation{
 90					bug.NewCreateOp(author, 0, "editions", "initial comment edited", nil),
 91					bug.NewEditCommentOp(author, 0, "", "erased then edited again", nil),
 92					bug.NewAddCommentOp(author, 0, "first comment", nil),
 93					bug.NewEditCommentOp(author, 0, "", "first comment edited", nil),
 94				},
 95			},
 96		},
 97		{
 98			name: "comment deletion",
 99			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/5",
100			bug: &bug.Snapshot{
101				Operations: []dag.Operation{
102					bug.NewCreateOp(author, 0, "comment deletion", "", nil),
103				},
104			},
105		},
106		{
107			name: "edition deletion",
108			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/6",
109			bug: &bug.Snapshot{
110				Operations: []dag.Operation{
111					bug.NewCreateOp(author, 0, "edition deletion", "initial comment", nil),
112					bug.NewEditCommentOp(author, 0, "", "initial comment edited again", nil),
113					bug.NewAddCommentOp(author, 0, "first comment", nil),
114					bug.NewEditCommentOp(author, 0, "", "first comment edited again", nil),
115				},
116			},
117		},
118		{
119			name: "hidden comment",
120			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/7",
121			bug: &bug.Snapshot{
122				Operations: []dag.Operation{
123					bug.NewCreateOp(author, 0, "hidden comment", "initial comment", nil),
124					bug.NewAddCommentOp(author, 0, "first comment", nil),
125				},
126			},
127		},
128		{
129			name: "transfered issue",
130			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/8",
131			bug: &bug.Snapshot{
132				Operations: []dag.Operation{
133					bug.NewCreateOp(author, 0, "transfered issue", "", nil),
134				},
135			},
136		},
137		{
138			name: "unicode control characters",
139			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/10",
140			bug: &bug.Snapshot{
141				Operations: []dag.Operation{
142					bug.NewCreateOp(author, 0, "unicode control characters", "u0000: \nu0001: \nu0002: \nu0003: \nu0004: \nu0005: \nu0006: \nu0007: \nu0008: \nu0009: \t\nu0010: \nu0011: \nu0012: \nu0013: \nu0014: \nu0015: \nu0016: \nu0017: \nu0018: \nu0019:", nil),
143				},
144			},
145		},
146	}
147
148	login := "test-identity"
149	author.SetMetadata(metaKeyGithubLogin, login)
150
151	token := auth.NewToken(target, envToken)
152	token.SetMetadata(auth.MetaKeyLogin, login)
153	err = auth.Store(repo, token)
154	require.NoError(t, err)
155
156	ctx := context.Background()
157
158	importer := &githubImporter{}
159	err = importer.Init(ctx, backend, core.Configuration{
160		confKeyOwner:        "MichaelMure",
161		confKeyProject:      "git-bug-test-github-bridge",
162		confKeyDefaultLogin: login,
163	})
164	require.NoError(t, err)
165
166	start := time.Now()
167
168	events, err := importer.ImportAll(ctx, backend, time.Time{})
169	require.NoError(t, err)
170
171	for result := range events {
172		require.NoError(t, result.Err)
173	}
174
175	fmt.Printf("test repository imported in %f seconds\n", time.Since(start).Seconds())
176
177	require.Len(t, backend.Bugs().AllIds(), len(tests))
178
179	for _, tt := range tests {
180		t.Run(tt.name, func(t *testing.T) {
181			b, err := backend.Bugs().ResolveBugCreateMetadata(metaKeyGithubUrl, tt.url)
182			require.NoError(t, err)
183
184			ops := b.Snapshot().Operations
185			require.Len(t, tt.bug.Operations, len(b.Snapshot().Operations))
186
187			for i, op := range tt.bug.Operations {
188				require.IsType(t, ops[i], op)
189				require.Equal(t, op.Author().Name(), ops[i].Author().Name())
190
191				switch op := op.(type) {
192				case *bug.CreateOperation:
193					require.Equal(t, op.Title, ops[i].(*bug.CreateOperation).Title)
194					require.Equal(t, op.Message, ops[i].(*bug.CreateOperation).Message)
195				case *bug.SetStatusOperation:
196					require.Equal(t, op.Status, ops[i].(*bug.SetStatusOperation).Status)
197				case *bug.SetTitleOperation:
198					require.Equal(t, op.Was, ops[i].(*bug.SetTitleOperation).Was)
199					require.Equal(t, op.Title, ops[i].(*bug.SetTitleOperation).Title)
200				case *bug.LabelChangeOperation:
201					require.ElementsMatch(t, op.Added, ops[i].(*bug.LabelChangeOperation).Added)
202					require.ElementsMatch(t, op.Removed, ops[i].(*bug.LabelChangeOperation).Removed)
203				case *bug.AddCommentOperation:
204					require.Equal(t, op.Message, ops[i].(*bug.AddCommentOperation).Message)
205				case *bug.EditCommentOperation:
206					require.Equal(t, op.Message, ops[i].(*bug.EditCommentOperation).Message)
207
208				default:
209					panic("unknown operation type")
210				}
211			}
212		})
213	}
214}