code.vegaprotocol.io/vega@v0.79.0/core/integration/steps/team_has_the_following_members.go (about) 1 // Copyright (C) 2023 Gobalsky Labs Limited 2 // 3 // This program is free software: you can redistribute it and/or modify 4 // it under the terms of the GNU Affero General Public License as 5 // published by the Free Software Foundation, either version 3 of the 6 // License, or (at your option) any later version. 7 // 8 // This program is distributed in the hope that it will be useful, 9 // but WITHOUT ANY WARRANTY; without even the implied warranty of 10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 // GNU Affero General Public License for more details. 12 // 13 // You should have received a copy of the GNU Affero General Public License 14 // along with this program. If not, see <http://www.gnu.org/licenses/>. 15 16 package steps 17 18 import ( 19 "context" 20 "fmt" 21 "sort" 22 23 "code.vegaprotocol.io/vega/core/collateral" 24 "code.vegaprotocol.io/vega/core/events" 25 "code.vegaprotocol.io/vega/core/integration/stubs" 26 "code.vegaprotocol.io/vega/core/referral" 27 "code.vegaprotocol.io/vega/core/teams" 28 "code.vegaprotocol.io/vega/core/types" 29 "code.vegaprotocol.io/vega/libs/num" 30 commandspb "code.vegaprotocol.io/vega/protos/vega/commands/v1" 31 32 "github.com/cucumber/godog" 33 ) 34 35 func TheTeamHasTheFollowingMembers(teamsEngine *teams.Engine, team string, table *godog.Table) error { 36 // Get a list of all the parties in a team 37 members := teamsEngine.GetTeamMembers(team, 0) 38 rows := []string{} 39 for _, r := range parseMembersTable(table) { 40 row := newMembersRow(r) 41 rows = append(rows, row.Party()) 42 } 43 sort.Strings(members) 44 sort.Strings(rows) 45 46 // Do we have the same amount of parties in each list? 47 if len(members) != len(rows) { 48 return fmt.Errorf("different number of team members between the table (%d) and the engine (%d)", len(rows), len(members)) 49 } 50 51 // Do we have the same members in each list? 52 for i, r := range members { 53 if r != rows[i] { 54 return fmt.Errorf("party details are different (%s != %s)", r, rows[i]) 55 } 56 } 57 return nil 58 } 59 60 func TheFollowingTeamsWithRefereesAreCreated( 61 col *collateral.Engine, 62 broker *stubs.BrokerStub, 63 netDeposits *num.Uint, 64 referralEngine *referral.Engine, 65 teamsEngine *teams.Engine, 66 table *godog.Table, 67 ) error { 68 ctx := context.Background() 69 for _, r := range parseCreateTeamTable(table) { 70 row := teamRow{ 71 r: r, 72 } 73 asset := row.Asset() 74 balance := row.Balance() 75 parties := row.Members() 76 evts := make([]events.Event, 0, len(parties)) 77 // 1. ensure deposits are made 78 for _, pid := range parties { 79 res, err := col.Deposit( 80 ctx, 81 pid, 82 asset, 83 balance.Clone(), 84 ) 85 if err != nil { 86 return err 87 } 88 evts = append(evts, events.NewLedgerMovements(ctx, []*types.LedgerMovement{res})) 89 // increase overal deposits by the balance added 90 netDeposits.AddSum(balance) 91 } 92 broker.SendBatch(evts) 93 // 2. Now create the referral code 94 code, team, referrer := types.ReferralSetID(row.Code()), row.Team(), types.PartyID(row.Referrer()) 95 if err := referralEngine.CreateReferralSet(ctx, referrer, code); err != nil { 96 return err 97 } 98 // 3. Create a team 99 teamPB := &commandspb.CreateReferralSet_Team{ 100 Name: team, 101 Closed: row.Closed(), 102 AllowList: row.AllowList(), 103 } 104 if err := teamsEngine.CreateTeam(ctx, referrer, types.TeamID(team), teamPB); err != nil { 105 return err 106 } 107 // 4. All parties apply the referral code, skip the first in parties slice, they are the referrer 108 joinTeam := &commandspb.JoinTeam{ 109 Id: team, 110 } 111 // 5. Join team 112 for _, pid := range parties[1:] { 113 if err := referralEngine.ApplyReferralCode(ctx, types.PartyID(pid), code); err != nil { 114 return err 115 } 116 if err := teamsEngine.JoinTeam(ctx, types.PartyID(pid), joinTeam); err != nil { 117 return err 118 } 119 } 120 } 121 return nil 122 } 123 124 func parseMembersTable(table *godog.Table) []RowWrapper { 125 return StrictParseTable(table, []string{ 126 "party", 127 }, []string{}) 128 } 129 130 func parseCreateTeamTable(table *godog.Table) []RowWrapper { 131 return StrictParseTable(table, []string{ 132 "referrer", 133 "prefix", 134 "code", 135 "team name", 136 "referees", 137 "balance", 138 "asset", 139 }, []string{ 140 "closed", 141 "allow list", 142 }) 143 } 144 145 type membersRow struct { 146 row RowWrapper 147 } 148 149 func newMembersRow(r RowWrapper) membersRow { 150 row := membersRow{ 151 row: r, 152 } 153 return row 154 } 155 156 func (r membersRow) Party() string { 157 return r.row.MustStr("party") 158 } 159 160 type teamRow struct { 161 r RowWrapper 162 } 163 164 func (t teamRow) Referrer() string { 165 return t.r.MustStr("referrer") 166 } 167 168 func (t teamRow) Code() string { 169 return t.r.MustStr("code") 170 } 171 172 func (t teamRow) Team() string { 173 return t.r.MustStr("team name") 174 } 175 176 func (t teamRow) Asset() string { 177 return t.r.MustStr("asset") 178 } 179 180 func (t teamRow) Prefix() string { 181 return t.r.MustStr("prefix") 182 } 183 184 func (t teamRow) MemberCount() int { 185 return int(t.r.MustU32("referees")) 186 } 187 188 func (t teamRow) Balance() *num.Uint { 189 return t.r.MustUint("balance") 190 } 191 192 func (t teamRow) Closed() bool { 193 if !t.r.HasColumn("closed") { 194 return false 195 } 196 return t.r.MustBool("closed") 197 } 198 199 func (t teamRow) Members() []string { 200 cnt := t.MemberCount() 201 ids := make([]string, 0, cnt) 202 ids = append(ids, t.Referrer()) 203 pidFmt := fmt.Sprintf("%s-%%04d", t.Prefix()) 204 for i := 0; i < cnt; i++ { 205 ids = append(ids, fmt.Sprintf(pidFmt, i+1)) 206 } 207 return ids 208 } 209 210 func (t teamRow) AllowList() []string { 211 if !t.Closed() { 212 return nil 213 } 214 generated := t.Members() 215 if !t.r.HasColumn("allow list") { 216 return generated 217 } 218 explicit := t.r.MustStrSlice("allow list", ",") 219 return append(explicit, generated...) 220 }