github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/systests/git_test.go (about)

     1  // Copyright 2017 Keybase, Inc. All rights reserved. Use of
     2  // this source code is governed by the included BSD license.
     3  
     4  package systests
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/keybase/client/go/git"
    14  	"github.com/keybase/client/go/libkb"
    15  	"github.com/keybase/client/go/protocol/keybase1"
    16  	"github.com/keybase/client/go/teams"
    17  	"github.com/stretchr/testify/require"
    18  )
    19  
    20  func TestGitTeamer(t *testing.T) {
    21  	tt := newTeamTester(t)
    22  	defer tt.cleanup()
    23  
    24  	alice := tt.addUser("abc")
    25  
    26  	aliceTeamer := git.NewTeamer(alice.tc.G)
    27  
    28  	t.Logf("team that doesn't exist")
    29  	_, err := aliceTeamer.LookupOrCreate(context.Background(), keybase1.FolderHandle{
    30  		Name:       "notateamxxx",
    31  		FolderType: keybase1.FolderType_TEAM,
    32  	})
    33  	require.Error(t, err)
    34  	require.IsType(t, teams.TeamDoesNotExistError{}, err, "%v", err)
    35  
    36  	t.Logf("team that exists")
    37  	teamID, teamName := tt.users[0].createTeam2()
    38  	res, err := aliceTeamer.LookupOrCreate(context.Background(), keybase1.FolderHandle{
    39  		Name:       teamName.String(),
    40  		FolderType: keybase1.FolderType_TEAM,
    41  	})
    42  	require.NoError(t, err)
    43  	require.Equal(t, res.TeamID, teamID)
    44  	require.Equal(t, res.Visibility, keybase1.TLFVisibility_PRIVATE)
    45  
    46  	for _, public := range []bool{false, true} {
    47  		t.Logf("public:%v", public)
    48  
    49  		visibility := keybase1.TLFVisibility_PRIVATE
    50  		if public {
    51  			visibility = keybase1.TLFVisibility_PUBLIC
    52  		}
    53  
    54  		folderType := keybase1.FolderType_PRIVATE
    55  		if public {
    56  			folderType = keybase1.FolderType_PUBLIC
    57  		}
    58  
    59  		t.Logf("iteam that doesn't exist (gets created)")
    60  		bob := tt.addUser("bob")
    61  		gil := tt.addUser("gil")
    62  		frag := fmt.Sprintf("%v,%v#%v", alice.username, bob.username, gil.username)
    63  		res, err = aliceTeamer.LookupOrCreate(context.Background(), keybase1.FolderHandle{
    64  			Name:       frag,
    65  			FolderType: folderType,
    66  		})
    67  		require.NoError(t, err)
    68  		expectedTeam, _, _, err := teams.LookupImplicitTeam(context.Background(), alice.tc.G, frag, public, teams.ImplicitTeamOptions{})
    69  		require.NoError(t, err)
    70  		require.Equal(t, public, expectedTeam.ID.IsPublic())
    71  		require.Equal(t, expectedTeam.ID, res.TeamID,
    72  			"teamer should have created a team that was then looked up")
    73  		require.Equal(t, visibility, res.Visibility)
    74  
    75  		t.Logf("iteam that already exists")
    76  		bob = tt.addUser("bob")
    77  		gil = tt.addUser("gil")
    78  		frag = fmt.Sprintf("%v,%v#%v", alice.username, bob.username, gil.username)
    79  		team, _, _, err := teams.LookupOrCreateImplicitTeam(context.Background(), alice.tc.G, frag, public)
    80  		require.NoError(t, err)
    81  		require.Equal(t, public, team.ID.IsPublic())
    82  		res, err = aliceTeamer.LookupOrCreate(context.Background(), keybase1.FolderHandle{
    83  			Name:       frag,
    84  			FolderType: folderType,
    85  		})
    86  		require.NoError(t, err)
    87  		require.Equal(t, res.TeamID, team.ID, "teamer should return the same team that was created earlier")
    88  		require.Equal(t, visibility, res.Visibility)
    89  
    90  		t.Logf("iteam conflict")
    91  		alice.drainGregor()
    92  		bob = tt.addUser("bob")
    93  		iTeamNameCreate1 := strings.Join([]string{alice.username, bob.username}, ",")
    94  		iTeamNameCreate2 := strings.Join([]string{alice.username, bob.username + "@rooter"}, ",")
    95  		_, _, _, err = teams.LookupOrCreateImplicitTeam(context.Background(), alice.tc.G, iTeamNameCreate1, public)
    96  		require.NoError(t, err)
    97  		iTeam2, _, _, err := teams.LookupOrCreateImplicitTeam(context.Background(), alice.tc.G, iTeamNameCreate2, public)
    98  		require.NoError(t, err)
    99  		require.Equal(t, public, iTeam2.ID.IsPublic())
   100  
   101  		t.Logf("prove to create the conflict")
   102  		bob.proveRooter()
   103  
   104  		t.Logf("wait for someone to add bob")
   105  		pollForConditionWithTimeout(t, 20*time.Second, "bob to be added to the team after rooter proof", func(ctx context.Context) bool {
   106  			team, err := teams.Load(ctx, alice.tc.G, keybase1.LoadTeamArg{
   107  				ID:          iTeam2.ID,
   108  				Public:      public,
   109  				ForceRepoll: true,
   110  			})
   111  			require.NoError(t, err)
   112  			role, err := team.MemberRole(ctx, bob.userVersion())
   113  			require.NoError(t, err)
   114  			return role != keybase1.TeamRole_NONE
   115  		})
   116  
   117  		t.Logf("find out the conflict suffix")
   118  		_, _, _, conflicts, err := teams.LookupImplicitTeamAndConflicts(context.Background(), alice.tc.G, iTeamNameCreate1, public, teams.ImplicitTeamOptions{})
   119  		require.NoError(t, err)
   120  		require.Len(t, conflicts, 1)
   121  		t.Logf("check")
   122  		res, err = aliceTeamer.LookupOrCreate(context.Background(), keybase1.FolderHandle{
   123  			Name:       iTeamNameCreate1 + " " + libkb.FormatImplicitTeamDisplayNameSuffix(conflicts[0]),
   124  			FolderType: folderType,
   125  		})
   126  		require.NoError(t, err)
   127  		require.Equal(t, res.TeamID, iTeam2.ID, "teamer should return the old conflicted team")
   128  		require.Equal(t, visibility, res.Visibility)
   129  	}
   130  }