Repository: line/line-bot-sdk-go
Pull request #392 (2023-11-17 01:57:01)

ChannelAPIClient shouldn't require channelToken

codecov-commenter: ## [Codecov](https://app.codecov.io/gh/line/line-bot-sdk-go/pull/392?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Comparison is base [(`d920a8d`)](https://app.codecov.io/gh/line/line-bot-sdk-go/commit/d920a8d34a2f35b866d876ce612b8bf276f9998f?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line) 55.68% compared to head [(`adf5212`)](https://app.codecov.io/gh/line/line-bot-sdk-go/pull/392?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line) 55.68%.

> :exclamation: Current head adf5212 differs from pull request most recent head cdff9ce. Consider uploading reports for the commit cdff9ce to get more accurate results


<details><summary>Additional details and impacted files</summary>


```diff
@@           Coverage Diff           @@
##           master     #392   +/-   ##
=======================================
  Coverage   55.68%   55.68%           
=======================================
  Files          86       86           
  Lines        5414     5414           
=======================================
  Hits         3015     3015           
  Misses       2179     2179           
  Partials      220      220           
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/line/line-bot-sdk-go/pull/392?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=line).


Patch:
diff --git a/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble b/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble
index dcafe93..ae0c47f 100644
--- a/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble
+++ b/generator/src/main/resources/line-bot-sdk-go-generator/api.pebble
@@ -3,6 +3,7 @@
 {# @pebvariable name="generatorClass" type="java.lang.String" -#}
 {# @pebvariable name="classname" type="java.lang.String" -#}
 {# @pebvariable name="authenticated" type="java.lang.Boolean" -#}
+{# @pebvariable name="authMethods" type="java.util.ArrayList<org.openapitools.codegen.CodegenSecurity>" -#}
 {% include "./licenseInfo.pebble" %}
 //go:generate python3 ../../generate-code.py
 {# @pebvariable name="packageName" type="java.lang.String" #}
@@ -27,7 +28,9 @@ import (
 type {{classname}} struct {
 	httpClient       *http.Client
 	endpoint     *url.URL
+{% if authMethods != null -%}
 	channelToken string
+{% endif -%}
 	ctx context.Context
 }
 
@@ -35,13 +38,18 @@ type {{classname}} struct {
 type {{ classname }}Option func (* {{ classname }}) error
 
 // New returns a new bot client instance.
-func New{{ classname }}(channelToken string, options ...{{classname}}Option) (*{{ classname }}, error) {
+func New{{ classname }}({% if authMethods != null %}channelToken string, {% endif %}options ...{{classname}}Option) (*{{ classname }}, error) {
+    {% if authMethods != null -%}
 	if channelToken == "" {
 		return nil, errors.New("missing channel access token")
 	}
 
+    {% endif -%}
+
 	c := &{{ classname }}{
+{% if authMethods != null -%}
 		channelToken: channelToken,
+{% endif -%}
 		httpClient:   http.DefaultClient,
 	}
 
@@ -67,9 +75,11 @@ func (call *{{ classname }}) WithContext(ctx context.Context) *{{ classname }} {
 }
 
 func (client *{{ classname }}) Do(req *http.Request) (*http.Response, error) {
+{% if authMethods != null -%}
 	if client.channelToken != "" {
 		req.Header.Set("Authorization", "Bearer "+client.channelToken)
 	}
+{% endif -%}
 	req.Header.Set("User-Agent", "LINE-BotSDK-Go/"+linebot.GetVersion())
 	if client.ctx != nil {
 		req = req.WithContext(client.ctx)
diff --git a/linebot/channel_access_token/.openapi-generator/FILES b/linebot/channel_access_token/.openapi-generator/FILES
index 59cecb0..bdda60f 100644
--- a/linebot/channel_access_token/.openapi-generator/FILES
+++ b/linebot/channel_access_token/.openapi-generator/FILES
@@ -5,3 +5,4 @@ model_issue_channel_access_token_response.go
 model_issue_short_lived_channel_access_token_response.go
 model_issue_stateless_channel_access_token_response.go
 model_verify_channel_access_token_response.go
+tests/api/api_channel_access_token_test_test.go
diff --git a/linebot/channel_access_token/api_channel_access_token.go b/linebot/channel_access_token/api_channel_access_token.go
index 55f3ae6..cd69bb9 100644
--- a/linebot/channel_access_token/api_channel_access_token.go
+++ b/linebot/channel_access_token/api_channel_access_token.go
@@ -24,7 +24,6 @@ import (
 	"bytes"
 	"context"
 	"encoding/json"
-	"errors"
 	"fmt"
 	"io"
 	"log"
@@ -36,24 +35,18 @@ import (
 )
 
 type ChannelAccessTokenAPI struct {
-	httpClient   *http.Client
-	endpoint     *url.URL
-	channelToken string
-	ctx          context.Context
+	httpClient *http.Client
+	endpoint   *url.URL
+	ctx        context.Context
 }
 
 // ChannelAccessTokenAPIOption type
 type ChannelAccessTokenAPIOption func(*ChannelAccessTokenAPI) error
 
 // New returns a new bot client instance.
-func NewChannelAccessTokenAPI(channelToken string, options ...ChannelAccessTokenAPIOption) (*ChannelAccessTokenAPI, error) {
-	if channelToken == "" {
-		return nil, errors.New("missing channel access token")
-	}
-
+func NewChannelAccessTokenAPI(options ...ChannelAccessTokenAPIOption) (*ChannelAccessTokenAPI, error) {
 	c := &ChannelAccessTokenAPI{
-		channelToken: channelToken,
-		httpClient:   http.DefaultClient,
+		httpClient: http.DefaultClient,
 	}
 
 	u, err := url.ParseRequestURI("https://api.line.me")
@@ -78,9 +71,6 @@ func (call *ChannelAccessTokenAPI) WithContext(ctx context.Context) *ChannelAcce
 }
 
 func (client *ChannelAccessTokenAPI) Do(req *http.Request) (*http.Response, error) {
-	if client.channelToken != "" {
-		req.Header.Set("Authorization", "Bearer "+client.channelToken)
-	}
 	req.Header.Set("User-Agent", "LINE-BotSDK-Go/"+linebot.GetVersion())
 	if client.ctx != nil {
 		req = req.WithContext(client.ctx)


Test patch:
diff --git a/generator/src/main/resources/line-bot-sdk-go-generator/api_test.pebble b/generator/src/main/resources/line-bot-sdk-go-generator/api_test.pebble
index 07aa170..afcb98c 100644
--- a/generator/src/main/resources/line-bot-sdk-go-generator/api_test.pebble
+++ b/generator/src/main/resources/line-bot-sdk-go-generator/api_test.pebble
@@ -2,6 +2,7 @@
 {# @pebvariable name="operations" type="org.openapitools.codegen.model.OperationMap" -#}
 {# @pebvariable name="packageName" type="String" -#}
 {# @pebvariable name="classname" type="String" -#}
+{# @pebvariable name="authMethods" type="java.util.ArrayList<org.openapitools.codegen.CodegenSecurity>" -#}
 package tests
 
 import (
@@ -47,7 +48,7 @@ func Test{{ op.operationId }}(t *testing.T) {
     )
 
 	client, err := {{ packageName }}.New{{ classname }}(
-		"MY_CHANNEL_TOKEN",
+		{% if authMethods != null %}"MY_CHANNEL_TOKEN",{% endif %}
         {{ packageName }}.WithEndpoint(server.URL),
 	)
 	if err != nil {
diff --git a/linebot/channel_access_token/tests/api/api_channel_access_token_test_test.go b/linebot/channel_access_token/tests/api/api_channel_access_token_test_test.go
index ca8701d..819032f 100644
--- a/linebot/channel_access_token/tests/api/api_channel_access_token_test_test.go
+++ b/linebot/channel_access_token/tests/api/api_channel_access_token_test_test.go
@@ -1,1 +1,262 @@
 package tests
+
+import (
+	"log"
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/line/line-bot-sdk-go/v7/linebot/channel_access_token"
+)
+
+func TestGetsAllValidChannelAccessTokenKeyIds(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.GetsAllValidChannelAccessTokenKeyIds(
+		"hello",
+
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}
+
+func TestIssueChannelToken(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
+				t.Fatalf("Invalid content-type: %s", r.Header.Get("Content-Type"))
+				return
+			}
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.IssueChannelToken(
+		"hello",
+
+		"hello",
+
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}
+
+func TestIssueChannelTokenByJWT(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
+				t.Fatalf("Invalid content-type: %s", r.Header.Get("Content-Type"))
+				return
+			}
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.IssueChannelTokenByJWT(
+		"hello",
+
+		"hello",
+
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}
+
+func TestIssueStatelessChannelToken(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
+				t.Fatalf("Invalid content-type: %s", r.Header.Get("Content-Type"))
+				return
+			}
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.IssueStatelessChannelToken(
+		"hello",
+
+		"hello",
+
+		"hello",
+
+		"hello",
+
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}
+
+func TestRevokeChannelToken(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
+				t.Fatalf("Invalid content-type: %s", r.Header.Get("Content-Type"))
+				return
+			}
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.RevokeChannelToken(
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}
+
+func TestRevokeChannelTokenByJWT(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
+				t.Fatalf("Invalid content-type: %s", r.Header.Get("Content-Type"))
+				return
+			}
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.RevokeChannelTokenByJWT(
+		"hello",
+
+		"hello",
+
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}
+
+func TestVerifyChannelToken(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			if r.Header.Get("Content-Type") != "application/x-www-form-urlencoded" {
+				t.Fatalf("Invalid content-type: %s", r.Header.Get("Content-Type"))
+				return
+			}
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.VerifyChannelToken(
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}
+
+func TestVerifyChannelTokenByJWT(t *testing.T) {
+	server := httptest.NewServer(
+		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+
+			w.WriteHeader(http.StatusOK)
+			w.Write([]byte("{}"))
+		}),
+	)
+
+	client, err := channel_access_token.NewChannelAccessTokenAPI(
+
+		channel_access_token.WithEndpoint(server.URL),
+	)
+	if err != nil {
+		t.Fatalf("Failed to create client: %v", err)
+	}
+	resp, err := client.VerifyChannelTokenByJWT(
+		"hello",
+	)
+	if err != nil {
+		t.Fatalf("Failed to call API: %v", err)
+	}
+	log.Printf("Got response: %v", resp)
+}