fix: sync latest Android and langpack updates
This commit is contained in:
parent
20b388eeaa
commit
4570df5939
20 changed files with 12384 additions and 27 deletions
|
|
@ -228,6 +228,105 @@ func TestChannelsGetParticipantsHidesAnonymousAdminFromRegularMember(t *testing.
|
|||
}
|
||||
}
|
||||
|
||||
func TestChannelsEditAdminCreatorSelfCanToggleAnonymous(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
userStore := memory.NewUserStore()
|
||||
owner, _ := userStore.Create(ctx, domain.User{AccessHash: 41, Phone: "15550002171", FirstName: "Owner"})
|
||||
admin, _ := userStore.Create(ctx, domain.User{AccessHash: 42, Phone: "15550002172", FirstName: "Admin"})
|
||||
channelStore := memory.NewChannelStore()
|
||||
r := New(Config{}, Deps{
|
||||
Users: appusers.NewService(userStore),
|
||||
Channels: appchannels.NewService(channelStore),
|
||||
}, zaptest.NewLogger(t), clock.System)
|
||||
created, err := r.onMessagesCreateChat(WithUserID(ctx, owner.ID), &tg.MessagesCreateChatRequest{
|
||||
Users: []tg.InputUserClass{&tg.InputUser{UserID: admin.ID, AccessHash: admin.AccessHash}},
|
||||
Title: "Creator Anonymous Group",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create chat: %v", err)
|
||||
}
|
||||
channel := created.Updates.(*tg.Updates).Chats[0].(*tg.Channel)
|
||||
inputChannel := &tg.InputChannel{ChannelID: channel.ID, AccessHash: channel.AccessHash}
|
||||
|
||||
updates, err := r.onChannelsEditAdmin(WithUserID(ctx, owner.ID), &tg.ChannelsEditAdminRequest{
|
||||
Channel: inputChannel,
|
||||
UserID: &tg.InputUser{UserID: owner.ID, AccessHash: owner.AccessHash},
|
||||
AdminRights: tg.ChatAdminRights{
|
||||
Anonymous: true,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("creator toggles own anonymous admin rights: %v", err)
|
||||
}
|
||||
var participantUpdate *tg.ChannelParticipantCreator
|
||||
for _, update := range updates.(*tg.Updates).Updates {
|
||||
upd, ok := update.(*tg.UpdateChannelParticipant)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if creator, ok := upd.NewParticipant.(*tg.ChannelParticipantCreator); ok && creator.UserID == owner.ID {
|
||||
participantUpdate = creator
|
||||
break
|
||||
}
|
||||
}
|
||||
if participantUpdate == nil {
|
||||
t.Fatalf("editAdmin updates = %+v, want creator participant update", updates.(*tg.Updates).Updates)
|
||||
}
|
||||
if !participantUpdate.AdminRights.Anonymous || !participantUpdate.AdminRights.ChangeInfo || !participantUpdate.AdminRights.AddAdmins {
|
||||
t.Fatalf("creator update rights = %+v, want anonymous plus full creator projection", participantUpdate.AdminRights)
|
||||
}
|
||||
|
||||
participant, err := r.onChannelsGetParticipant(WithUserID(ctx, owner.ID), &tg.ChannelsGetParticipantRequest{
|
||||
Channel: inputChannel,
|
||||
Participant: &tg.InputPeerUser{UserID: owner.ID, AccessHash: owner.AccessHash},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("get creator participant: %v", err)
|
||||
}
|
||||
projectedCreator, ok := participant.Participant.(*tg.ChannelParticipantCreator)
|
||||
if !ok {
|
||||
t.Fatalf("participant = %T, want ChannelParticipantCreator", participant.Participant)
|
||||
}
|
||||
if !projectedCreator.AdminRights.Anonymous || !projectedCreator.AdminRights.ChangeInfo || !projectedCreator.AdminRights.AddAdmins {
|
||||
t.Fatalf("projected creator rights = %+v, want anonymous plus full creator projection", projectedCreator.AdminRights)
|
||||
}
|
||||
|
||||
chats, err := r.onChannelsGetChannels(WithUserID(ctx, owner.ID), []tg.InputChannelClass{inputChannel})
|
||||
if err != nil {
|
||||
t.Fatalf("get channels: %v", err)
|
||||
}
|
||||
projectedChannel := chats.(*tg.MessagesChats).Chats[0].(*tg.Channel)
|
||||
rights, ok := projectedChannel.GetAdminRights()
|
||||
if !ok {
|
||||
t.Fatalf("projected channel has no admin rights: %+v", projectedChannel)
|
||||
}
|
||||
if !rights.Anonymous || !rights.ChangeInfo || !rights.AddAdmins {
|
||||
t.Fatalf("projected channel admin rights = %+v, want anonymous plus full creator projection", rights)
|
||||
}
|
||||
|
||||
if _, err := r.onChannelsEditAdmin(WithUserID(ctx, owner.ID), &tg.ChannelsEditAdminRequest{
|
||||
Channel: inputChannel,
|
||||
UserID: &tg.InputUser{UserID: admin.ID, AccessHash: admin.AccessHash},
|
||||
AdminRights: tg.ChatAdminRights{
|
||||
Anonymous: true,
|
||||
ChangeInfo: true,
|
||||
AddAdmins: true,
|
||||
},
|
||||
}); err != nil {
|
||||
t.Fatalf("promote admin: %v", err)
|
||||
}
|
||||
_, err = r.onChannelsEditAdmin(WithUserID(ctx, admin.ID), &tg.ChannelsEditAdminRequest{
|
||||
Channel: inputChannel,
|
||||
UserID: &tg.InputUser{UserID: owner.ID, AccessHash: owner.AccessHash},
|
||||
AdminRights: tg.ChatAdminRights{
|
||||
ChangeInfo: true,
|
||||
},
|
||||
})
|
||||
if err == nil || !strings.Contains(err.Error(), "USER_CREATOR") {
|
||||
t.Fatalf("admin edits creator err = %v, want USER_CREATOR", err)
|
||||
}
|
||||
}
|
||||
|
||||
func tgParticipantListHasUser(participants []tg.ChannelParticipantClass, userID int64) bool {
|
||||
for _, participant := range participants {
|
||||
for _, id := range channelParticipantUserRefs(participant) {
|
||||
|
|
|
|||
|
|
@ -402,6 +402,7 @@ func (r *Router) onChannelsEditAdmin(ctx context.Context, req *tg.ChannelsEditAd
|
|||
ChannelID: channelID,
|
||||
MemberID: target.ID,
|
||||
AdminRights: domainChannelAdminRights(req.AdminRights),
|
||||
RankSet: req.Flags.Has(0),
|
||||
Rank: req.Rank,
|
||||
Date: int(r.clock.Now().Unix()),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -780,10 +780,7 @@ func tgChatAdminRights(rights domain.ChannelAdminRights) tg.ChatAdminRights {
|
|||
}
|
||||
|
||||
func creatorProjectionAdminRights(rights domain.ChannelAdminRights) domain.ChannelAdminRights {
|
||||
creatorRights := domain.CreatorChannelAdminRights()
|
||||
creatorRights.Anonymous = rights.Anonymous
|
||||
creatorRights.ManageDirectMessages = rights.ManageDirectMessages
|
||||
return creatorRights
|
||||
return domain.CreatorProjectionAdminRights(rights)
|
||||
}
|
||||
|
||||
func domainChannelAdminRights(rights tg.ChatAdminRights) domain.ChannelAdminRights {
|
||||
|
|
|
|||
|
|
@ -91,8 +91,8 @@ func (r *Router) langpackLanguages(ctx context.Context, langPack string) []tg.La
|
|||
if langPack == "" {
|
||||
langPack = langPackFromClient(ctx)
|
||||
}
|
||||
_ = langPack
|
||||
return []tg.LangPackLanguage{
|
||||
langPack = strings.ToLower(langPack)
|
||||
languages := []tg.LangPackLanguage{
|
||||
{
|
||||
Official: true,
|
||||
Name: "English",
|
||||
|
|
@ -114,6 +114,20 @@ func (r *Router) langpackLanguages(ctx context.Context, langPack string) []tg.La
|
|||
TranslationsURL: "",
|
||||
},
|
||||
}
|
||||
if langPack == "android" {
|
||||
languages = append(languages, tg.LangPackLanguage{
|
||||
Official: true,
|
||||
Rtl: true,
|
||||
Name: "Persian",
|
||||
NativeName: "فارسی",
|
||||
LangCode: "fa",
|
||||
PluralCode: "fa",
|
||||
StringsCount: 11002,
|
||||
TranslatedCount: 11002,
|
||||
TranslationsURL: "",
|
||||
})
|
||||
}
|
||||
return languages
|
||||
}
|
||||
|
||||
func langPackFromClient(ctx context.Context) string {
|
||||
|
|
@ -124,6 +138,12 @@ func langPackFromClient(ctx context.Context) string {
|
|||
if info.LangPack != "" {
|
||||
return info.LangPack
|
||||
}
|
||||
switch info.ClientType() {
|
||||
case ClientTypeAndroid:
|
||||
return string(ClientTypeAndroid)
|
||||
case ClientTypeTDesktop:
|
||||
return string(ClientTypeTDesktop)
|
||||
}
|
||||
client := strings.ToLower(info.DeviceModel + " " + info.SystemVersion + " " + info.AppVersion)
|
||||
if strings.Contains(client, "android") {
|
||||
return "android"
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ func TestLangpackGetLanguagesCurrentAndLegacy(t *testing.T) {
|
|||
if err := (&tg.LangpackGetLanguagesRequest{LangPack: "tdesktop"}).Encode(&in); err != nil {
|
||||
t.Fatalf("encode request: %v", err)
|
||||
}
|
||||
assertLangpackLanguages(t, r, context.Background(), &in)
|
||||
langs := dispatchLangpackLanguages(t, r, context.Background(), &in)
|
||||
assertHasLangpackLanguage(t, langs, "en")
|
||||
assertNoLangpackLanguage(t, langs, "fa")
|
||||
})
|
||||
|
||||
t.Run("legacy android no args", func(t *testing.T) {
|
||||
|
|
@ -30,7 +32,17 @@ func TestLangpackGetLanguagesCurrentAndLegacy(t *testing.T) {
|
|||
AppVersion: "12.7.3",
|
||||
LangCode: "en",
|
||||
})
|
||||
assertLangpackLanguages(t, r, ctx, &in)
|
||||
langs := dispatchLangpackLanguages(t, r, ctx, &in)
|
||||
assertHasLangpackLanguage(t, langs, "en")
|
||||
assertHasLangpackLanguage(t, langs, "fa")
|
||||
})
|
||||
|
||||
t.Run("legacy android from cached client type", func(t *testing.T) {
|
||||
var in bin.Buffer
|
||||
in.PutID(0x800fd57d)
|
||||
ctx := WithClientInfo(context.Background(), ClientInfo{Type: ClientTypeAndroid})
|
||||
langs := dispatchLangpackLanguages(t, r, ctx, &in)
|
||||
assertHasLangpackLanguage(t, langs, "fa")
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -58,6 +70,23 @@ func TestLangpackGetLanguage(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLangpackAndroidPersianLanguage(t *testing.T) {
|
||||
r := New(Config{DC: 2, IP: "127.0.0.1", Port: 2398}, Deps{}, zaptest.NewLogger(t), clock.System)
|
||||
|
||||
lang := r.langpackLanguage(context.Background(), "android", "fa")
|
||||
if lang.LangCode != "fa" || lang.PluralCode != "fa" || lang.Name != "Persian" || lang.NativeName != "فارسی" || !lang.Rtl {
|
||||
t.Fatalf("android fa language = %+v", lang)
|
||||
}
|
||||
|
||||
languages := r.langpackLanguages(androidClientContext(), "")
|
||||
for _, item := range languages {
|
||||
if item.LangCode == "fa" {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("android languages = %+v, want fa entry", languages)
|
||||
}
|
||||
|
||||
func TestLegacyLangpackGetLangPack(t *testing.T) {
|
||||
r := New(Config{DC: 2, IP: "127.0.0.1", Port: 2398}, Deps{}, zaptest.NewLogger(t), clock.System)
|
||||
|
||||
|
|
@ -157,7 +186,7 @@ func TestLegacyAccountRegisterDevice(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func assertLangpackLanguages(t *testing.T, r *Router, ctx context.Context, in *bin.Buffer) {
|
||||
func dispatchLangpackLanguages(t *testing.T, r *Router, ctx context.Context, in *bin.Buffer) []tg.LangPackLanguage {
|
||||
t.Helper()
|
||||
enc, err := r.Dispatch(ctx, [8]byte{}, 0, in)
|
||||
if err != nil {
|
||||
|
|
@ -171,8 +200,25 @@ func assertLangpackLanguages(t *testing.T, r *Router, ctx context.Context, in *b
|
|||
if err := langs.Decode(&out); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
if len(langs.Elems) == 0 || langs.Elems[0].LangCode != "en" {
|
||||
t.Fatalf("languages = %+v, want English entry", langs.Elems)
|
||||
return langs.Elems
|
||||
}
|
||||
|
||||
func assertHasLangpackLanguage(t *testing.T, langs []tg.LangPackLanguage, code string) {
|
||||
t.Helper()
|
||||
for _, lang := range langs {
|
||||
if lang.LangCode == code {
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("languages = %+v, want %s entry", langs, code)
|
||||
}
|
||||
|
||||
func assertNoLangpackLanguage(t *testing.T, langs []tg.LangPackLanguage, code string) {
|
||||
t.Helper()
|
||||
for _, lang := range langs {
|
||||
if lang.LangCode == code {
|
||||
t.Fatalf("languages = %+v, want no %s entry", langs, code)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue