Skip to content

Commit 4635a66

Browse files
authored
Fix broken channel access token APIs in new client (#685)
Query parameters with snake_case names in the OpenAPI spec (e.g. `access_token`) were sent as camelCase (`accessToken`), causing requests to fail. The generator template used `param.paramName` (camelCase) instead of `param.baseName`(original from spec) as the query key. Fixed the template and regenerated. This change adds regression tests for this case. original: line/line-bot-sdk-nodejs#1569
1 parent 67c6ad6 commit 4635a66

File tree

4 files changed

+140
-6
lines changed

4 files changed

+140
-6
lines changed

generator/src/main/resources/line-bot-sdk-go-generator/api.pebble

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -279,14 +279,14 @@ func (client *{{ classname }}) {{ op.operationId }}WithHttpInfo(
279279
{% for qp in op.queryParams -%}
280280
{% if qp.isArray -%}
281281
for _, v := range *{{ qp.paramName }} {
282-
query.Add("{{ qp.paramName }}", v)
282+
query.Add("{{ qp.baseName }}", v)
283283
}
284284
{% elseif qp.isString and not qp.required -%}
285285
if {{ stringify(qp) }} != "" {
286-
query.Add("{{ qp.paramName }}", {{ stringify(qp) }})
286+
query.Add("{{ qp.baseName }}", {{ stringify(qp) }})
287287
}
288288
{% else -%}
289-
query.Add("{{ qp.paramName }}", {{ stringify(qp) }})
289+
query.Add("{{ qp.baseName }}", {{ stringify(qp) }})
290290
{% endif -%}
291291
{% endfor %}
292292
req.URL.RawQuery = query.Encode()

linebot/channel_access_token/api_channel_access_token.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ func (client *ChannelAccessTokenAPI) GetsAllValidChannelAccessTokenKeyIdsWithHtt
152152
}
153153

154154
query := url.Values{}
155-
query.Add("clientAssertionType", clientAssertionType)
156-
query.Add("clientAssertion", clientAssertion)
155+
query.Add("client_assertion_type", clientAssertionType)
156+
query.Add("client_assertion", clientAssertion)
157157

158158
req.URL.RawQuery = query.Encode()
159159

@@ -751,7 +751,7 @@ func (client *ChannelAccessTokenAPI) VerifyChannelTokenByJWTWithHttpInfo(
751751
}
752752

753753
query := url.Values{}
754-
query.Add("accessToken", accessToken)
754+
query.Add("access_token", accessToken)
755755

756756
req.URL.RawQuery = query.Encode()
757757

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package tests
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
9+
"github.com/line/line-bot-sdk-go/v8/linebot/channel_access_token"
10+
)
11+
12+
func TestGetsAllValidChannelAccessTokenKeyIdsWithHttpInfo(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
clientAssertionType string
16+
clientAssertion string
17+
}{
18+
{
19+
name: "Uses snake_case query parameter keys",
20+
clientAssertionType: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
21+
clientAssertion: "test_jwt_assertion",
22+
},
23+
}
24+
25+
for _, tt := range tests {
26+
t.Run(tt.name, func(t *testing.T) {
27+
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
28+
query := r.URL.Query()
29+
30+
if got := query.Get("client_assertion_type"); got != tt.clientAssertionType {
31+
t.Errorf("Expected query param client_assertion_type=%q, got %q", tt.clientAssertionType, got)
32+
}
33+
if got := query.Get("client_assertion"); got != tt.clientAssertion {
34+
t.Errorf("Expected query param client_assertion=%q, got %q", tt.clientAssertion, got)
35+
}
36+
37+
if got := query.Get("clientAssertionType"); got != "" {
38+
t.Errorf("camelCase key clientAssertionType should not be present, got %q", got)
39+
}
40+
if got := query.Get("clientAssertion"); got != "" {
41+
t.Errorf("camelCase key clientAssertion should not be present, got %q", got)
42+
}
43+
44+
w.WriteHeader(http.StatusOK)
45+
json.NewEncoder(w).Encode(channel_access_token.ChannelAccessTokenKeyIdsResponse{
46+
Kids: []string{"kid1", "kid2"},
47+
})
48+
}))
49+
defer mockServer.Close()
50+
51+
client, err := channel_access_token.NewChannelAccessTokenAPI(
52+
channel_access_token.WithEndpoint(mockServer.URL),
53+
)
54+
if err != nil {
55+
t.Fatalf("Failed to create client: %v", err)
56+
}
57+
58+
_, result, err := client.GetsAllValidChannelAccessTokenKeyIdsWithHttpInfo(
59+
tt.clientAssertionType,
60+
tt.clientAssertion,
61+
)
62+
if err != nil {
63+
t.Fatalf("Unexpected error: %v", err)
64+
}
65+
66+
if len(result.Kids) != 2 {
67+
t.Errorf("Expected 2 kids, got %d", len(result.Kids))
68+
}
69+
})
70+
}
71+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package tests
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
"net/http/httptest"
7+
"testing"
8+
9+
"github.com/line/line-bot-sdk-go/v8/linebot/channel_access_token"
10+
)
11+
12+
func TestVerifyChannelTokenByJWTWithHttpInfo(t *testing.T) {
13+
tests := []struct {
14+
name string
15+
accessToken string
16+
}{
17+
{
18+
name: "Uses snake_case query parameter key",
19+
accessToken: "test_channel_access_token",
20+
},
21+
}
22+
23+
for _, tt := range tests {
24+
t.Run(tt.name, func(t *testing.T) {
25+
mockServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
26+
query := r.URL.Query()
27+
28+
if got := query.Get("access_token"); got != tt.accessToken {
29+
t.Errorf("Expected query param access_token=%q, got %q", tt.accessToken, got)
30+
}
31+
32+
if got := query.Get("accessToken"); got != "" {
33+
t.Errorf("camelCase key accessToken should not be present, got %q", got)
34+
}
35+
36+
w.WriteHeader(http.StatusOK)
37+
json.NewEncoder(w).Encode(channel_access_token.VerifyChannelAccessTokenResponse{
38+
ClientId: "test_client_id",
39+
ExpiresIn: 3600,
40+
})
41+
}))
42+
defer mockServer.Close()
43+
44+
client, err := channel_access_token.NewChannelAccessTokenAPI(
45+
channel_access_token.WithEndpoint(mockServer.URL),
46+
)
47+
if err != nil {
48+
t.Fatalf("Failed to create client: %v", err)
49+
}
50+
51+
_, result, err := client.VerifyChannelTokenByJWTWithHttpInfo(
52+
tt.accessToken,
53+
)
54+
if err != nil {
55+
t.Fatalf("Unexpected error: %v", err)
56+
}
57+
58+
if result.ClientId != "test_client_id" {
59+
t.Errorf("Expected ClientId: test_client_id, got: %s", result.ClientId)
60+
}
61+
})
62+
}
63+
}

0 commit comments

Comments
 (0)