mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-07-22 12:49:32 +00:00
Telegram rewrote the forwardMessages and copyMessages return sentence from "an array of MessageId" to "an Array of MessageId". The pattern that handles the "... of the sent messages is returned" shape matched lowercase only, so both methods fell back to bool and the weekly regen job failed at the audit step. Add approved_any_locations to overrides.json so a union that renders as `any` by design can be approved as data instead of a code change. Approve InputRichMessageMedia.Media, a five-variant InputMedia union added in Bot API 10.2 that has no declared parent type. Make the drift test compare HEAD against itself. It compared the working tree against HEAD, so it failed whenever a regen run added a method.
243 lines
7.1 KiB
Go
243 lines
7.1 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/lukaszraczylo/go-telegram/internal/spec"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// ---- auditBool -----------------------------------------------------------
|
|
|
|
func TestAuditBool_FlagsUnapprovedBoolMethod(t *testing.T) {
|
|
api := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "getMe", Doc: "A simple method.", Returns: spec.TypeRef{Kind: spec.KindPrimitive, Name: "bool"}},
|
|
},
|
|
}
|
|
ov := &spec.Overrides{}
|
|
problems := auditBool(api, ov)
|
|
require.Len(t, problems, 1)
|
|
require.Contains(t, problems[0], "bool fallback: getMe")
|
|
}
|
|
|
|
func TestAuditBool_SkipsApprovedBoolMethod(t *testing.T) {
|
|
api := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "setWebhook", Doc: "Use this to set webhook.", Returns: spec.TypeRef{Kind: spec.KindPrimitive, Name: "bool"}},
|
|
},
|
|
}
|
|
ov := &spec.Overrides{ApprovedBoolMethods: []string{"setWebhook"}}
|
|
problems := auditBool(api, ov)
|
|
require.Empty(t, problems)
|
|
}
|
|
|
|
func TestAuditBool_SkipsMethodWithReturnsTrueDoc(t *testing.T) {
|
|
api := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "doThing", Doc: "Returns True on success.", Returns: spec.TypeRef{Kind: spec.KindPrimitive, Name: "bool"}},
|
|
},
|
|
}
|
|
ov := &spec.Overrides{}
|
|
problems := auditBool(api, ov)
|
|
require.Empty(t, problems)
|
|
}
|
|
|
|
func TestAuditBool_SkipsNonBoolMethods(t *testing.T) {
|
|
api := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "getMe", Doc: "Gets user.", Returns: spec.TypeRef{Kind: spec.KindNamed, Name: "User"}},
|
|
},
|
|
}
|
|
ov := &spec.Overrides{}
|
|
require.Empty(t, auditBool(api, ov))
|
|
}
|
|
|
|
// ---- auditAny ------------------------------------------------------------
|
|
|
|
func TestAuditAny_FlagsUnrecognisedOneOf(t *testing.T) {
|
|
api := &spec.API{
|
|
Types: []spec.TypeDecl{
|
|
{
|
|
Name: "Foo",
|
|
Fields: []spec.Field{
|
|
{Name: "Bar", JSONName: "bar", Type: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"A", "B", "C"}}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
out := auditAny(api, &spec.Overrides{})
|
|
require.Len(t, out, 1)
|
|
require.Contains(t, out[0], "any field: Foo.Bar")
|
|
}
|
|
|
|
func TestAuditAny_SkipsApprovedLocations(t *testing.T) {
|
|
api := &spec.API{
|
|
Types: []spec.TypeDecl{
|
|
{
|
|
Name: "Foo",
|
|
Fields: []spec.Field{
|
|
{Name: "Bar", JSONName: "bar", Type: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"A", "B"}}},
|
|
},
|
|
},
|
|
},
|
|
Methods: []spec.MethodDecl{
|
|
{
|
|
Name: "doThing",
|
|
Returns: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"A", "B"}},
|
|
Params: []spec.Field{
|
|
{Name: "Baz", JSONName: "baz", Type: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"A", "B"}}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
require.Len(t, auditAny(api, &spec.Overrides{}), 3)
|
|
|
|
ov := &spec.Overrides{ApprovedAnyLocations: []string{"Foo.Bar", "doThing", "doThing.Baz"}}
|
|
require.Empty(t, auditAny(api, ov))
|
|
}
|
|
|
|
func TestAuditAny_SkipsChatIDShape(t *testing.T) {
|
|
api := &spec.API{
|
|
Types: []spec.TypeDecl{
|
|
{
|
|
Name: "SendMessage",
|
|
Fields: []spec.Field{
|
|
{Name: "ChatID", JSONName: "chat_id", Type: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"int64", "string"}}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
require.Empty(t, auditAny(api, &spec.Overrides{}))
|
|
}
|
|
|
|
func TestAuditAny_SkipsKnownUnion(t *testing.T) {
|
|
api := &spec.API{
|
|
Types: []spec.TypeDecl{
|
|
{Name: "InputMedia", OneOf: []string{"InputMediaPhoto", "InputMediaVideo"}},
|
|
{
|
|
Name: "SomeMethod",
|
|
Fields: []spec.Field{
|
|
{Name: "Media", JSONName: "media", Type: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"InputMediaPhoto", "InputMediaVideo"}}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
require.Empty(t, auditAny(api, &spec.Overrides{}))
|
|
}
|
|
|
|
func TestAuditAny_SkipsReplyMarkupShape(t *testing.T) {
|
|
api := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{
|
|
Name: "sendMessage",
|
|
Params: []spec.Field{
|
|
{Name: "ReplyMarkup", JSONName: "reply_markup", Type: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"InlineKeyboardMarkup", "ReplyKeyboardMarkup", "ReplyKeyboardRemove", "ForceReply"}}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
require.Empty(t, auditAny(api, &spec.Overrides{}))
|
|
}
|
|
|
|
func TestAuditAny_SkipsInputFileShape(t *testing.T) {
|
|
api := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{
|
|
Name: "sendPhoto",
|
|
Params: []spec.Field{
|
|
{Name: "Photo", JSONName: "photo", Type: spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"InputFile", "string"}}},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
require.Empty(t, auditAny(api, &spec.Overrides{}))
|
|
}
|
|
|
|
// ---- diffSignatures ------------------------------------------------------
|
|
|
|
func TestDiffSignatures_AddedMethod(t *testing.T) {
|
|
prev := &spec.API{}
|
|
cur := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "newMethod", Returns: spec.TypeRef{Kind: spec.KindPrimitive, Name: "bool"}},
|
|
},
|
|
}
|
|
changes := diffSignatures(prev, cur)
|
|
require.Len(t, changes, 1)
|
|
require.Contains(t, changes[0], "added method: newMethod")
|
|
}
|
|
|
|
func TestDiffSignatures_RemovedMethod(t *testing.T) {
|
|
prev := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "oldMethod", Returns: spec.TypeRef{Kind: spec.KindPrimitive, Name: "bool"}},
|
|
},
|
|
}
|
|
cur := &spec.API{}
|
|
changes := diffSignatures(prev, cur)
|
|
require.Len(t, changes, 1)
|
|
require.Contains(t, changes[0], "removed method: oldMethod")
|
|
}
|
|
|
|
func TestDiffSignatures_ChangedReturn(t *testing.T) {
|
|
prev := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "getMe", Returns: spec.TypeRef{Kind: spec.KindPrimitive, Name: "bool"}},
|
|
},
|
|
}
|
|
cur := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "getMe", Returns: spec.TypeRef{Kind: spec.KindNamed, Name: "User"}},
|
|
},
|
|
}
|
|
changes := diffSignatures(prev, cur)
|
|
require.Len(t, changes, 1)
|
|
require.Contains(t, changes[0], "getMe")
|
|
require.Contains(t, changes[0], "bool")
|
|
require.Contains(t, changes[0], "User")
|
|
}
|
|
|
|
func TestDiffSignatures_Clean(t *testing.T) {
|
|
api := &spec.API{
|
|
Methods: []spec.MethodDecl{
|
|
{Name: "getMe", Returns: spec.TypeRef{Kind: spec.KindNamed, Name: "User"}},
|
|
},
|
|
}
|
|
require.Empty(t, diffSignatures(api, api))
|
|
}
|
|
|
|
// ---- typeRefEqual --------------------------------------------------------
|
|
|
|
func TestTypeRefEqual_Primitive(t *testing.T) {
|
|
a := spec.TypeRef{Kind: spec.KindPrimitive, Name: "bool"}
|
|
require.True(t, typeRefEqual(a, a))
|
|
b := spec.TypeRef{Kind: spec.KindPrimitive, Name: "string"}
|
|
require.False(t, typeRefEqual(a, b))
|
|
}
|
|
|
|
func TestTypeRefEqual_Array(t *testing.T) {
|
|
elem := &spec.TypeRef{Kind: spec.KindNamed, Name: "Update"}
|
|
a := spec.TypeRef{Kind: spec.KindArray, ElemType: elem}
|
|
b := spec.TypeRef{Kind: spec.KindArray, ElemType: &spec.TypeRef{Kind: spec.KindNamed, Name: "Update"}}
|
|
require.True(t, typeRefEqual(a, b))
|
|
|
|
c := spec.TypeRef{Kind: spec.KindArray, ElemType: &spec.TypeRef{Kind: spec.KindNamed, Name: "Message"}}
|
|
require.False(t, typeRefEqual(a, c))
|
|
}
|
|
|
|
func TestTypeRefEqual_OneOf(t *testing.T) {
|
|
a := spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"int64", "string"}}
|
|
b := spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"string", "int64"}}
|
|
require.True(t, typeRefEqual(a, b))
|
|
|
|
c := spec.TypeRef{Kind: spec.KindOneOf, Variants: []string{"int64"}}
|
|
require.False(t, typeRefEqual(a, c))
|
|
}
|
|
|
|
func TestTypeRefEqual_NilVsNonNilElem(t *testing.T) {
|
|
a := spec.TypeRef{Kind: spec.KindArray}
|
|
b := spec.TypeRef{Kind: spec.KindArray, ElemType: &spec.TypeRef{Kind: spec.KindNamed, Name: "Update"}}
|
|
require.False(t, typeRefEqual(a, b))
|
|
}
|