mirror of
https://github.com/IBM/fp-go.git
synced 2025-11-23 22:14:53 +02:00
445 lines
11 KiB
Go
445 lines
11 KiB
Go
// Copyright (c) 2023 - 2025 IBM Corp.
|
|
// All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
package builder
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"testing"
|
|
|
|
E "github.com/IBM/fp-go/v2/either"
|
|
F "github.com/IBM/fp-go/v2/function"
|
|
C "github.com/IBM/fp-go/v2/http/content"
|
|
FD "github.com/IBM/fp-go/v2/http/form"
|
|
H "github.com/IBM/fp-go/v2/http/headers"
|
|
O "github.com/IBM/fp-go/v2/option"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestBuilder(t *testing.T) {
|
|
|
|
name := H.ContentType
|
|
withContentType := WithHeader(name)
|
|
withoutContentType := WithoutHeader(name)
|
|
|
|
b1 := F.Pipe1(
|
|
Default,
|
|
withContentType(C.JSON),
|
|
)
|
|
|
|
b2 := F.Pipe1(
|
|
b1,
|
|
withContentType(C.TextPlain),
|
|
)
|
|
|
|
b3 := F.Pipe1(
|
|
b2,
|
|
withoutContentType,
|
|
)
|
|
|
|
assert.Equal(t, O.None[string](), Default.GetHeader(name))
|
|
assert.Equal(t, O.Of(C.JSON), b1.GetHeader(name))
|
|
assert.Equal(t, O.Of(C.TextPlain), b2.GetHeader(name))
|
|
assert.Equal(t, O.None[string](), b3.GetHeader(name))
|
|
}
|
|
|
|
func TestWithFormData(t *testing.T) {
|
|
data := F.Pipe1(
|
|
FD.Default,
|
|
FD.WithValue("a")("b"),
|
|
)
|
|
|
|
res := F.Pipe1(
|
|
Default,
|
|
WithFormData(data),
|
|
)
|
|
|
|
assert.Equal(t, C.FormEncoded, Headers.Get(res).Get(H.ContentType))
|
|
}
|
|
|
|
func TestHash(t *testing.T) {
|
|
|
|
b1 := F.Pipe4(
|
|
Default,
|
|
WithContentType(C.JSON),
|
|
WithHeader(H.Accept)(C.JSON),
|
|
WithURL("http://www.example.com"),
|
|
WithJSON(map[string]string{"a": "b"}),
|
|
)
|
|
|
|
b2 := F.Pipe4(
|
|
Default,
|
|
WithURL("http://www.example.com"),
|
|
WithHeader(H.Accept)(C.JSON),
|
|
WithContentType(C.JSON),
|
|
WithJSON(map[string]string{"a": "b"}),
|
|
)
|
|
|
|
assert.Equal(t, MakeHash(b1), MakeHash(b2))
|
|
assert.NotEqual(t, MakeHash(Default), MakeHash(b2))
|
|
|
|
fmt.Println(MakeHash(b1))
|
|
}
|
|
|
|
// TestGetTargetURL tests URL construction with query parameters
|
|
func TestGetTargetURL(t *testing.T) {
|
|
builder := F.Pipe3(
|
|
Default,
|
|
WithURL("http://www.example.com?existing=param"),
|
|
WithQueryArg("limit")("10"),
|
|
WithQueryArg("offset")("20"),
|
|
)
|
|
|
|
result := builder.GetTargetURL()
|
|
assert.True(t, E.IsRight(result), "Expected Right result")
|
|
|
|
url := E.GetOrElse(func(error) string { return "" })(result)
|
|
assert.Contains(t, url, "limit=10")
|
|
assert.Contains(t, url, "offset=20")
|
|
assert.Contains(t, url, "existing=param")
|
|
}
|
|
|
|
// TestGetTargetURLWithInvalidURL tests error handling for invalid URLs
|
|
func TestGetTargetURLWithInvalidURL(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithURL("://invalid-url"),
|
|
)
|
|
|
|
result := builder.GetTargetURL()
|
|
assert.True(t, E.IsLeft(result), "Expected Left result for invalid URL")
|
|
}
|
|
|
|
// TestGetTargetUrl tests the deprecated GetTargetUrl function
|
|
func TestGetTargetUrl(t *testing.T) {
|
|
builder := F.Pipe2(
|
|
Default,
|
|
WithURL("http://www.example.com"),
|
|
WithQueryArg("test")("value"),
|
|
)
|
|
|
|
result := builder.GetTargetUrl()
|
|
assert.True(t, E.IsRight(result), "Expected Right result")
|
|
|
|
url := E.GetOrElse(func(error) string { return "" })(result)
|
|
assert.Contains(t, url, "test=value")
|
|
}
|
|
|
|
// TestSetMethod tests the SetMethod function
|
|
func TestSetMethod(t *testing.T) {
|
|
builder := Default.SetMethod("POST")
|
|
|
|
assert.Equal(t, "POST", builder.GetMethod())
|
|
}
|
|
|
|
// TestSetQuery tests the SetQuery function
|
|
func TestSetQuery(t *testing.T) {
|
|
query := make(url.Values)
|
|
query.Set("key1", "value1")
|
|
query.Set("key2", "value2")
|
|
|
|
builder := Default.SetQuery(query)
|
|
|
|
assert.Equal(t, "value1", builder.GetQuery().Get("key1"))
|
|
assert.Equal(t, "value2", builder.GetQuery().Get("key2"))
|
|
}
|
|
|
|
// TestSetHeaders tests the SetHeaders function
|
|
func TestSetHeaders(t *testing.T) {
|
|
headers := make(http.Header)
|
|
headers.Set("X-Custom-Header", "custom-value")
|
|
headers.Set("Authorization", "Bearer token")
|
|
|
|
builder := Default.SetHeaders(headers)
|
|
|
|
assert.Equal(t, "custom-value", builder.GetHeaders().Get("X-Custom-Header"))
|
|
assert.Equal(t, "Bearer token", builder.GetHeaders().Get("Authorization"))
|
|
}
|
|
|
|
// TestGetHeaderValues tests the GetHeaderValues function
|
|
func TestGetHeaderValues(t *testing.T) {
|
|
builder := F.Pipe2(
|
|
Default,
|
|
WithHeader("Accept")("application/json"),
|
|
WithHeader("Accept")("text/html"),
|
|
)
|
|
|
|
values := builder.GetHeaderValues("Accept")
|
|
assert.Contains(t, values, "text/html")
|
|
}
|
|
|
|
// TestGetUrl tests the deprecated GetUrl function
|
|
func TestGetUrl(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithURL("http://www.example.com"),
|
|
)
|
|
|
|
assert.Equal(t, "http://www.example.com", builder.GetUrl())
|
|
}
|
|
|
|
// TestSetUrl tests the deprecated SetUrl function
|
|
func TestSetUrl(t *testing.T) {
|
|
builder := Default.SetUrl("http://www.example.com")
|
|
|
|
assert.Equal(t, "http://www.example.com", builder.GetURL())
|
|
}
|
|
|
|
// TestWithJson tests the deprecated WithJson function
|
|
func TestWithJson(t *testing.T) {
|
|
data := map[string]string{"key": "value"}
|
|
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithJson(data),
|
|
)
|
|
|
|
contentType := O.GetOrElse(F.Constant(""))(builder.GetHeader(H.ContentType))
|
|
assert.Equal(t, C.JSON, contentType)
|
|
assert.True(t, O.IsSome(builder.GetBody()))
|
|
}
|
|
|
|
// TestQueryArg tests the QueryArg lens
|
|
func TestQueryArg(t *testing.T) {
|
|
lens := QueryArg("test")
|
|
|
|
builder := F.Pipe1(
|
|
Default,
|
|
lens.Set(O.Some("value")),
|
|
)
|
|
|
|
assert.Equal(t, O.Some("value"), lens.Get(builder))
|
|
assert.Equal(t, "value", builder.GetQuery().Get("test"))
|
|
}
|
|
|
|
// TestWithQueryArg tests the WithQueryArg function
|
|
func TestWithQueryArg(t *testing.T) {
|
|
builder := F.Pipe2(
|
|
Default,
|
|
WithQueryArg("param1")("value1"),
|
|
WithQueryArg("param2")("value2"),
|
|
)
|
|
|
|
assert.Equal(t, "value1", builder.GetQuery().Get("param1"))
|
|
assert.Equal(t, "value2", builder.GetQuery().Get("param2"))
|
|
}
|
|
|
|
// TestWithoutQueryArg tests the WithoutQueryArg function
|
|
func TestWithoutQueryArg(t *testing.T) {
|
|
builder := F.Pipe3(
|
|
Default,
|
|
WithQueryArg("param1")("value1"),
|
|
WithQueryArg("param2")("value2"),
|
|
WithoutQueryArg("param1"),
|
|
)
|
|
|
|
assert.Equal(t, "", builder.GetQuery().Get("param1"))
|
|
assert.Equal(t, "value2", builder.GetQuery().Get("param2"))
|
|
}
|
|
|
|
// TestGetHash tests the GetHash method
|
|
func TestGetHash(t *testing.T) {
|
|
builder := F.Pipe2(
|
|
Default,
|
|
WithURL("http://www.example.com"),
|
|
WithMethod("POST"),
|
|
)
|
|
|
|
hash := builder.GetHash()
|
|
assert.NotEmpty(t, hash)
|
|
assert.Equal(t, MakeHash(builder), hash)
|
|
}
|
|
|
|
// TestWithBytes tests the WithBytes function
|
|
func TestWithBytes(t *testing.T) {
|
|
data := []byte("test data")
|
|
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithBytes(data),
|
|
)
|
|
|
|
body := builder.GetBody()
|
|
assert.True(t, O.IsSome(body))
|
|
}
|
|
|
|
// TestWithoutBody tests the WithoutBody function
|
|
func TestWithoutBody(t *testing.T) {
|
|
builder := F.Pipe2(
|
|
Default,
|
|
WithBytes([]byte("data")),
|
|
WithoutBody,
|
|
)
|
|
|
|
assert.True(t, O.IsNone(builder.GetBody()))
|
|
}
|
|
|
|
// TestWithGet tests the WithGet convenience function
|
|
func TestWithGet(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithGet,
|
|
)
|
|
|
|
assert.Equal(t, "GET", builder.GetMethod())
|
|
}
|
|
|
|
// TestWithPost tests the WithPost convenience function
|
|
func TestWithPost(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithPost,
|
|
)
|
|
|
|
assert.Equal(t, "POST", builder.GetMethod())
|
|
}
|
|
|
|
// TestWithPut tests the WithPut convenience function
|
|
func TestWithPut(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithPut,
|
|
)
|
|
|
|
assert.Equal(t, "PUT", builder.GetMethod())
|
|
}
|
|
|
|
// TestWithDelete tests the WithDelete convenience function
|
|
func TestWithDelete(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithDelete,
|
|
)
|
|
|
|
assert.Equal(t, "DELETE", builder.GetMethod())
|
|
}
|
|
|
|
// TestWithBearer tests the WithBearer function
|
|
func TestWithBearer(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithBearer("my-token"),
|
|
)
|
|
|
|
auth := O.GetOrElse(F.Constant(""))(builder.GetHeader(H.Authorization))
|
|
assert.Equal(t, "Bearer my-token", auth)
|
|
}
|
|
|
|
// TestWithContentType tests the WithContentType function
|
|
func TestWithContentType(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithContentType(C.TextPlain),
|
|
)
|
|
|
|
contentType := O.GetOrElse(F.Constant(""))(builder.GetHeader(H.ContentType))
|
|
assert.Equal(t, C.TextPlain, contentType)
|
|
}
|
|
|
|
// TestWithAuthorization tests the WithAuthorization function
|
|
func TestWithAuthorization(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithAuthorization("Basic abc123"),
|
|
)
|
|
|
|
auth := O.GetOrElse(F.Constant(""))(builder.GetHeader(H.Authorization))
|
|
assert.Equal(t, "Basic abc123", auth)
|
|
}
|
|
|
|
// TestBuilderChaining tests that builder operations can be chained
|
|
func TestBuilderChaining(t *testing.T) {
|
|
builder := F.Pipe3(
|
|
Default,
|
|
WithURL("http://www.example.com"),
|
|
WithMethod("POST"),
|
|
WithHeader("X-Test")("test-value"),
|
|
)
|
|
|
|
// Verify all operations were applied
|
|
assert.Equal(t, "http://www.example.com", builder.GetURL())
|
|
assert.Equal(t, "POST", builder.GetMethod())
|
|
|
|
testHeader := O.GetOrElse(F.Constant(""))(builder.GetHeader("X-Test"))
|
|
assert.Equal(t, "test-value", testHeader)
|
|
}
|
|
|
|
// TestWithQuery tests the WithQuery function
|
|
func TestWithQuery(t *testing.T) {
|
|
query := make(url.Values)
|
|
query.Set("key1", "value1")
|
|
query.Set("key2", "value2")
|
|
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithQuery(query),
|
|
)
|
|
|
|
assert.Equal(t, "value1", builder.GetQuery().Get("key1"))
|
|
assert.Equal(t, "value2", builder.GetQuery().Get("key2"))
|
|
}
|
|
|
|
// TestWithHeaders tests the WithHeaders function
|
|
func TestWithHeaders(t *testing.T) {
|
|
headers := make(http.Header)
|
|
headers.Set("X-Test", "test-value")
|
|
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithHeaders(headers),
|
|
)
|
|
|
|
assert.Equal(t, "test-value", builder.GetHeaders().Get("X-Test"))
|
|
}
|
|
|
|
// TestWithUrl tests the deprecated WithUrl function
|
|
func TestWithUrl(t *testing.T) {
|
|
builder := F.Pipe1(
|
|
Default,
|
|
WithUrl("http://www.example.com"),
|
|
)
|
|
|
|
assert.Equal(t, "http://www.example.com", builder.GetURL())
|
|
}
|
|
|
|
// TestComplexBuilderComposition tests a complex builder composition
|
|
func TestComplexBuilderComposition(t *testing.T) {
|
|
builder := F.Pipe5(
|
|
Default,
|
|
WithURL("http://api.example.com/users"),
|
|
WithPost,
|
|
WithJSON(map[string]interface{}{
|
|
"name": "John Doe",
|
|
"email": "john@example.com",
|
|
}),
|
|
WithBearer("secret-token"),
|
|
WithQueryArg("notify")("true"),
|
|
)
|
|
|
|
assert.Equal(t, "http://api.example.com/users", builder.GetURL())
|
|
assert.Equal(t, "POST", builder.GetMethod())
|
|
|
|
contentType := O.GetOrElse(F.Constant(""))(builder.GetHeader(H.ContentType))
|
|
assert.Equal(t, C.JSON, contentType)
|
|
|
|
auth := O.GetOrElse(F.Constant(""))(builder.GetHeader(H.Authorization))
|
|
assert.Equal(t, "Bearer secret-token", auth)
|
|
|
|
assert.Equal(t, "true", builder.GetQuery().Get("notify"))
|
|
assert.True(t, O.IsSome(builder.GetBody()))
|
|
}
|