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, err := cache.NewRepoCacheNoEvents(repo)
 32	require.NoError(t, err)
 33
 34	defer backend.Close()
 35	interrupt.RegisterCleaner(backend.Close)
 36
 37	author, err := identity.NewIdentity(repo, "Michael Muré", "batolettre@gmail.com")
 38	require.NoError(t, err)
 39
 40	tests := []struct {
 41		name string
 42		url  string
 43		bug  *bug.Snapshot
 44	}{
 45		{
 46			name: "simple issue",
 47			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/1",
 48			bug: &bug.Snapshot{
 49				Operations: []dag.Operation{
 50					bug.NewCreateOp(author, 0, "simple issue", "initial comment", nil),
 51					bug.NewAddCommentOp(author, 0, "first comment", nil),
 52					bug.NewAddCommentOp(author, 0, "second comment", nil),
 53				},
 54			},
 55		},
 56		{
 57			name: "empty issue",
 58			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/2",
 59			bug: &bug.Snapshot{
 60				Operations: []dag.Operation{
 61					bug.NewCreateOp(author, 0, "empty issue", "", nil),
 62				},
 63			},
 64		},
 65		{
 66			name: "complex issue",
 67			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/3",
 68			bug: &bug.Snapshot{
 69				Operations: []dag.Operation{
 70					bug.NewCreateOp(author, 0, "complex issue", "initial comment", nil),
 71					bug.NewLabelChangeOperation(author, 0, []bug.Label{"bug"}, []bug.Label{}),
 72					bug.NewLabelChangeOperation(author, 0, []bug.Label{"duplicate"}, []bug.Label{}),
 73					bug.NewLabelChangeOperation(author, 0, []bug.Label{}, []bug.Label{"duplicate"}),
 74					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),
 75					bug.NewSetTitleOp(author, 0, "complex issue edited", "complex issue"),
 76					bug.NewSetTitleOp(author, 0, "complex issue", "complex issue edited"),
 77					bug.NewSetStatusOp(author, 0, common.ClosedStatus),
 78					bug.NewSetStatusOp(author, 0, common.OpenStatus),
 79				},
 80			},
 81		},
 82		{
 83			name: "editions",
 84			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/4",
 85			bug: &bug.Snapshot{
 86				Operations: []dag.Operation{
 87					bug.NewCreateOp(author, 0, "editions", "initial comment edited", nil),
 88					bug.NewEditCommentOp(author, 0, "", "erased then edited again", nil),
 89					bug.NewAddCommentOp(author, 0, "first comment", nil),
 90					bug.NewEditCommentOp(author, 0, "", "first comment edited", nil),
 91				},
 92			},
 93		},
 94		{
 95			name: "comment deletion",
 96			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/5",
 97			bug: &bug.Snapshot{
 98				Operations: []dag.Operation{
 99					bug.NewCreateOp(author, 0, "comment deletion", "", nil),
100				},
101			},
102		},
103		{
104			name: "edition deletion",
105			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/6",
106			bug: &bug.Snapshot{
107				Operations: []dag.Operation{
108					bug.NewCreateOp(author, 0, "edition deletion", "initial comment", nil),
109					bug.NewEditCommentOp(author, 0, "", "initial comment edited again", nil),
110					bug.NewAddCommentOp(author, 0, "first comment", nil),
111					bug.NewEditCommentOp(author, 0, "", "first comment edited again", nil),
112				},
113			},
114		},
115		{
116			name: "hidden comment",
117			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/7",
118			bug: &bug.Snapshot{
119				Operations: []dag.Operation{
120					bug.NewCreateOp(author, 0, "hidden comment", "initial comment", nil),
121					bug.NewAddCommentOp(author, 0, "first comment", nil),
122				},
123			},
124		},
125		{
126			name: "transferred issue",
127			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/8",
128			bug: &bug.Snapshot{
129				Operations: []dag.Operation{
130					bug.NewCreateOp(author, 0, "transferred issue", "", nil),
131				},
132			},
133		},
134		{
135			name: "unicode control characters",
136			url:  "https://github.com/MichaelMure/git-bug-test-github-bridge/issues/10",
137			bug: &bug.Snapshot{
138				Operations: []dag.Operation{
139					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),
140				},
141			},
142		},
143	}
144
145	login := "test-identity"
146	author.SetMetadata(metaKeyGithubLogin, login)
147
148	token := auth.NewToken(target, envToken)
149	token.SetMetadata(auth.MetaKeyLogin, login)
150	err = auth.Store(repo, token)
151	require.NoError(t, err)
152
153	ctx := context.Background()
154
155	importer := &githubImporter{}
156	err = importer.Init(ctx, backend, core.Configuration{
157		confKeyOwner:        "MichaelMure",
158		confKeyProject:      "git-bug-test-github-bridge",
159		confKeyDefaultLogin: login,
160	})
161	require.NoError(t, err)
162
163	start := time.Now()
164
165	events, err := importer.ImportAll(ctx, backend, time.Time{})
166	require.NoError(t, err)
167
168	for result := range events {
169		require.NoError(t, result.Err)
170	}
171
172	fmt.Printf("test repository imported in %f seconds\n", time.Since(start).Seconds())
173
174	require.Len(t, backend.Bugs().AllIds(), len(tests))
175
176	for _, tt := range tests {
177		t.Run(tt.name, func(t *testing.T) {
178			b, err := backend.Bugs().ResolveBugCreateMetadata(metaKeyGithubUrl, tt.url)
179			require.NoError(t, err)
180
181			ops := b.Snapshot().Operations
182			require.Len(t, tt.bug.Operations, len(b.Snapshot().Operations))
183
184			for i, op := range tt.bug.Operations {
185				require.IsType(t, ops[i], op)
186				require.Equal(t, op.Author().Name(), ops[i].Author().Name())
187
188				switch op := op.(type) {
189				case *bug.CreateOperation:
190					require.Equal(t, op.Title, ops[i].(*bug.CreateOperation).Title)
191					require.Equal(t, op.Message, ops[i].(*bug.CreateOperation).Message)
192				case *bug.SetStatusOperation:
193					require.Equal(t, op.Status, ops[i].(*bug.SetStatusOperation).Status)
194				case *bug.SetTitleOperation:
195					require.Equal(t, op.Was, ops[i].(*bug.SetTitleOperation).Was)
196					require.Equal(t, op.Title, ops[i].(*bug.SetTitleOperation).Title)
197				case *bug.LabelChangeOperation:
198					require.ElementsMatch(t, op.Added, ops[i].(*bug.LabelChangeOperation).Added)
199					require.ElementsMatch(t, op.Removed, ops[i].(*bug.LabelChangeOperation).Removed)
200				case *bug.AddCommentOperation:
201					require.Equal(t, op.Message, ops[i].(*bug.AddCommentOperation).Message)
202				case *bug.EditCommentOperation:
203					require.Equal(t, op.Message, ops[i].(*bug.EditCommentOperation).Message)
204
205				default:
206					panic("unknown operation type")
207				}
208			}
209		})
210	}
211}