nebius/SWE-rebench-V2-PRs huggingface dataset:
Repository: slack-go/slack
Pull request #755 (2020-07-05 22:50:06)

Add SetUserRealName for change user's realName
Added SetUserRealName to permit user's change the realName.


Patch:
diff --git a/users.go b/users.go
index 364958e..cdef424 100644
--- a/users.go
+++ b/users.go
@@ -509,6 +509,41 @@ func (api *Client) DeleteUserPhotoContext(ctx context.Context) (err error) {
 	return response.Err()
 }
 
+// SetUserRealName changes the currently authenticated user's realName
+//
+// For more information see SetUserRealNameContextWithUser
+func (api *Client) SetUserRealName(realName string) error {
+	return api.SetUserRealNameContextWithUser(context.Background(), realName, realName)
+}
+
+// SetUserRealNameContextWithUser will set a real name for the provided user with a custom context
+func (api *Client) SetUserRealNameContextWithUser(ctx context.Context, user, realName string) error {
+	profile, err := json.Marshal(
+		&struct {
+			RealName string `json:"real_name"`
+		}{
+			RealName: realName,
+		},
+	)
+
+	if err != nil {
+		return err
+	}
+
+	values := url.Values{
+		"user":    {user},
+		"token":   {api.token},
+		"profile": {string(profile)},
+	}
+
+	response := &userResponseFull{}
+	if err = api.postMethod(ctx, "users.profile.set", values, response); err != nil {
+		return err
+	}
+
+	return response.Err()
+}
+
 // SetUserCustomStatus will set a custom status and emoji for the currently
 // authenticated user. If statusEmoji is "" and statusText is not, the Slack API
 // will automatically set it to ":speech_balloon:". Otherwise, if both are ""


Test patch:
diff --git a/users_test.go b/users_test.go
index ab1697e..34502a3 100644
--- a/users_test.go
+++ b/users_test.go
@@ -302,7 +302,7 @@ func TestGetUserByEmail(t *testing.T) {
 	}
 }
 
-func TestUserCustomStatus(t *testing.T) {
+func TestUserProfileSet(t *testing.T) {
 	up := &UserProfile{}
 
 	setUserProfile := newProfileHandler(up)
@@ -317,6 +317,22 @@ func TestUserCustomStatus(t *testing.T) {
 
 	up.RealName = "Test User"
 	testSetUserCustomStatusWithUser(api, "Test User", up, t)
+
+	up.RealName = "Real Name Test"
+	testSetUserRealName(api, up, t)
+}
+
+func testSetUserRealName(api *Client, up *UserProfile, t *testing.T) {
+	const (
+		realName = "Real Name Test"
+	)
+	if err := api.SetUserRealName(realName); err != nil {
+		t.Fatalf(`SetUserRealName(%q) = %#v, want <nil>`, realName, err)
+	}
+
+	if up.RealName != realName {
+		t.Fatalf(`UserProfile.RealName = %q, want %q`, up.RealName, realName)
+	}
 }
 
 func testSetUserCustomStatus(api *Client, up *UserProfile, t *testing.T) {
Repository: slack-go/slack
Pull request #761 (2020-07-14 13:24:11)

[Feat] conversations.mark
Slack has added a conversations.mark endpoint which will replace the existing im, mpim, channel and group mark endpoints.

This PR implements the new endpoint.

ramikalai: This solves issue #749 
ramikalai: @ollieparsley can you please check and merge?

Patch:
diff --git a/conversation.go b/conversation.go
index 60c50fc..6fc4a08 100644
--- a/conversation.go
+++ b/conversation.go
@@ -621,3 +621,25 @@ func (api *Client) GetConversationHistoryContext(ctx context.Context, params *Ge
 
 	return &response, response.Err()
 }
+
+// MarkConversation sets the read mark of a conversation to a specific point
+func (api *Client) MarkConversation(channel, ts string) (err error) {
+	return api.MarkConversationContext(context.Background(), channel, ts)
+}
+
+// MarkConversationContext sets the read mark of a conversation to a specific point with a custom context
+func (api *Client) MarkConversationContext(ctx context.Context, channel, ts string) error {
+	values := url.Values{
+		"token":   {api.token},
+		"channel": {channel},
+		"ts":      {ts},
+	}
+
+	response := &SlackResponse{}
+
+	err := api.postMethod(ctx, "conversations.mark", values, response)
+	if err != nil {
+		return err
+	}
+	return response.Err()
+}


Test patch:
diff --git a/conversation_test.go b/conversation_test.go
index 3f00374..032e3b2 100644
--- a/conversation_test.go
+++ b/conversation_test.go
@@ -555,3 +555,13 @@ func TestGetConversationHistory(t *testing.T) {
 		return
 	}
 }
+
+func TestMarkConversation(t *testing.T) {
+	once.Do(startServer)
+	api := New("testing-token", OptionAPIURL("http://"+serverAddr+"/"))
+	err := api.MarkConversation("CXXXXXXXX", "1401383885.000061")
+	if err != nil {
+		t.Errorf("Unexpected error: %s", err)
+		return
+	}
+}
Repository: slack-go/slack
Pull request #767 (2020-07-30 13:32:07)

Add Header block
This PR adds Slack's shiny new Header block! (https://api.slack.com/reference/messaging/blocks#header)


Patch:
diff --git a/block.go b/block.go
index 4b4b155..dd4b871 100644
--- a/block.go
+++ b/block.go
@@ -16,6 +16,7 @@ const (
 	MBTContext MessageBlockType = "context"
 	MBTFile    MessageBlockType = "file"
 	MBTInput   MessageBlockType = "input"
+	MBTHeader  MessageBlockType = "header"
 )
 
 // Block defines an interface all block types should implement
diff --git a/block_header.go b/block_header.go
new file mode 100644
index 0000000..6dff4b8
--- /dev/null
+++ b/block_header.go
@@ -0,0 +1,38 @@
+package slack
+
+// HeaderBlock defines a new block of type header
+//
+// More Information: https://api.slack.com/reference/messaging/blocks#header
+type HeaderBlock struct {
+	Type    MessageBlockType `json:"type"`
+	Text    *TextBlockObject `json:"text,omitempty"`
+	BlockID string           `json:"block_id,omitempty"`
+}
+
+// BlockType returns the type of the block
+func (s HeaderBlock) BlockType() MessageBlockType {
+	return s.Type
+}
+
+// HeaderBlockOption allows configuration of options for a new header block
+type HeaderBlockOption func(*HeaderBlock)
+
+func HeaderBlockOptionBlockID(blockID string) HeaderBlockOption {
+	return func(block *HeaderBlock) {
+		block.BlockID = blockID
+	}
+}
+
+// NewHeaderBlock returns a new instance of a header block to be rendered
+func NewHeaderBlock(textObj *TextBlockObject, options ...HeaderBlockOption) *HeaderBlock {
+	block := HeaderBlock{
+		Type: MBTHeader,
+		Text: textObj,
+	}
+
+	for _, option := range options {
+		option(&block)
+	}
+
+	return &block
+}


Test patch:
diff --git a/block_header_test.go b/block_header_test.go
new file mode 100644
index 0000000..f1cfb5d
--- /dev/null
+++ b/block_header_test.go
@@ -0,0 +1,18 @@
+package slack
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestNewHeaderBlock(t *testing.T) {
+
+	textInfo := NewTextBlockObject("plain_text", "This is quite the header", false, false)
+
+	headerBlock := NewHeaderBlock(textInfo, HeaderBlockOptionBlockID("test_block"))
+	assert.Equal(t, string(headerBlock.Type), "header")
+	assert.Equal(t, string(headerBlock.BlockID), "test_block")
+	assert.Equal(t, headerBlock.Text.Type, "plain_text")
+	assert.Contains(t, headerBlock.Text.Text, "quite the header")
+}
Repository: slack-go/slack
Pull request #770 (2020-08-05 20:44:24)

Allow EMPTY Text fields on attachments (required field)
This patch makes `text` a required field on attachments. We have code that creates a button as an attachment with empty text field. The regression caused the `text` json attribute to be removed when empty, which breaks the slack API.

This change moves it back to required, so even if empty, a field is still sent: `"text":""`


##### Pull Request Guidelines

These are recommendations for pull requests.
They are strictly guidelines to help manage expectations.

##### PR preparation
Run `make pr-prep` from the root of the repository to run formatting, linting and tests.

##### Should this be an issue instead
Maybe? It was definitely a regression from 0.6.0. Without this change, you cannot post a button attachment w/o having some text included.

##### API changes

- fixed existing tests



Patch:
diff --git a/attachments.go b/attachments.go
index b5b79f9..5f388e9 100644
--- a/attachments.go
+++ b/attachments.go
@@ -75,7 +75,7 @@ type Attachment struct {
 	Title     string `json:"title,omitempty"`
 	TitleLink string `json:"title_link,omitempty"`
 	Pretext   string `json:"pretext,omitempty"`
-	Text      string `json:"text,omitempty"`
+	Text      string `json:"text"` // Required
 
 	ImageURL string `json:"image_url,omitempty"`
 	ThumbURL string `json:"thumb_url,omitempty"`


Test patch:
diff --git a/attachements_test.go b/attachements_test.go
index 4b951f1..24e2254 100644
--- a/attachements_test.go
+++ b/attachements_test.go
@@ -12,6 +12,7 @@ func TestAttachment_UnmarshalMarshalJSON_WithBlocks(t *testing.T) {
 
 	originalAttachmentJson := `{
     "id": 1,
+    "text":"",
     "blocks": [
       {
         "type": "section",
diff --git a/chat_test.go b/chat_test.go
index 450cae7..a038728 100644
--- a/chat_test.go
+++ b/chat_test.go
@@ -101,7 +101,7 @@ func TestPostMessage(t *testing.T) {
 					}),
 			},
 			expected: url.Values{
-				"attachments": []string{`[{"blocks":` + blockStr + `}]`},
+				"attachments": []string{`[{"text":"","blocks":` + blockStr + `}]`},
 				"channel":     []string{"CXXX"},
 				"token":       []string{"testing-token"},
 			},
Repository: slack-go/slack
Pull request #788 (2020-08-20 09:22:34)

Resolve: Revert changes to json tags in Attachment's Text field
Resolve: Revert changes to json tags in Attachment's Text field. #784 

Documentation of API says that `text` field is required in `Attachment`, but when you want to send it with `blocks` field as well, it returns `invalid_attachment` error. This is because `blocks` cannot be sent along with `text` (even with empty `"text":""`)

kanata2: @prgres Thank you. Please fix failed test cases.

Patch:
diff --git a/attachments.go b/attachments.go
index 5f388e9..b5b79f9 100644
--- a/attachments.go
+++ b/attachments.go
@@ -75,7 +75,7 @@ type Attachment struct {
 	Title     string `json:"title,omitempty"`
 	TitleLink string `json:"title_link,omitempty"`
 	Pretext   string `json:"pretext,omitempty"`
-	Text      string `json:"text"` // Required
+	Text      string `json:"text,omitempty"`
 
 	ImageURL string `json:"image_url,omitempty"`
 	ThumbURL string `json:"thumb_url,omitempty"`


Test patch:
diff --git a/attachments_test.go b/attachments_test.go
index 24e2254..4b951f1 100644
--- a/attachments_test.go
+++ b/attachments_test.go
@@ -12,7 +12,6 @@ func TestAttachment_UnmarshalMarshalJSON_WithBlocks(t *testing.T) {
 
 	originalAttachmentJson := `{
     "id": 1,
-    "text":"",
     "blocks": [
       {
         "type": "section",
diff --git a/chat_test.go b/chat_test.go
index a038728..450cae7 100644
--- a/chat_test.go
+++ b/chat_test.go
@@ -101,7 +101,7 @@ func TestPostMessage(t *testing.T) {
 					}),
 			},
 			expected: url.Values{
-				"attachments": []string{`[{"text":"","blocks":` + blockStr + `}]`},
+				"attachments": []string{`[{"blocks":` + blockStr + `}]`},
 				"channel":     []string{"CXXX"},
 				"token":       []string{"testing-token"},
 			},
Repository: slack-go/slack
Pull request #821 (2020-10-13 07:11:09)

add slash commands api_app_id parameter
Add api_app_id to slash command struct


Patch:
diff --git a/slash.go b/slash.go
index f62065a..b2c5094 100644
--- a/slash.go
+++ b/slash.go
@@ -19,6 +19,7 @@ type SlashCommand struct {
 	Text           string `json:"text"`
 	ResponseURL    string `json:"response_url"`
 	TriggerID      string `json:"trigger_id"`
+	APIAppID       string `json:"api_app_id"`
 }
 
 // SlashCommandParse will parse the request of the slash command
@@ -39,6 +40,7 @@ func SlashCommandParse(r *http.Request) (s SlashCommand, err error) {
 	s.Text = r.PostForm.Get("text")
 	s.ResponseURL = r.PostForm.Get("response_url")
 	s.TriggerID = r.PostForm.Get("trigger_id")
+	s.APIAppID = r.PostForm.Get("api_app_id")
 	return s, nil
 }
 


Test patch:
diff --git a/slash_test.go b/slash_test.go
index eabf38a..e5c79e9 100644
--- a/slash_test.go
+++ b/slash_test.go
@@ -33,6 +33,7 @@ func TestSlash_ServeHTTP(t *testing.T) {
 				"token":           []string{"valid"},
 				"channel_name":    []string{"channel"},
 				"trigger_id":      []string{"0000000000.1111111111.222222222222aaaaaaaaaaaaaa"},
+				"api_app_id":      []string{"A123456"},
 			},
 			wantParams: SlashCommand{
 				Command:        "/command",
@@ -48,6 +49,7 @@ func TestSlash_ServeHTTP(t *testing.T) {
 				Token:          "valid",
 				ChannelName:    "channel",
 				TriggerID:      "0000000000.1111111111.222222222222aaaaaaaaaaaaaa",
+				APIAppID:       "A123456",
 			},
 			wantStatusCode: http.StatusOK,
 		},
Repository: slack-go/slack
Pull request #875 (2020-12-21 06:37:15)

Add missing `Image512` field in `UserProfile`
##### PR preparation
> Run `make pr-prep` from the root of the repository to run formatting, linting and tests.

🙆 



##### API changes

> Since API changes have to be maintained they undergo a more detailed review and are more likely to require changes.

Added `Image512` field in `UserProfile`.


ref: https://api.slack.com/types/user





Patch:
diff --git a/users.go b/users.go
index c2ee871..5d8cb35 100644
--- a/users.go
+++ b/users.go
@@ -31,6 +31,7 @@ type UserProfile struct {
 	Image48               string                  `json:"image_48"`
 	Image72               string                  `json:"image_72"`
 	Image192              string                  `json:"image_192"`
+	Image512              string                  `json:"image_512"`
 	ImageOriginal         string                  `json:"image_original"`
 	Title                 string                  `json:"title"`
 	BotID                 string                  `json:"bot_id,omitempty"`


Test patch:
diff --git a/users_test.go b/users_test.go
index f4c96d6..a492089 100644
--- a/users_test.go
+++ b/users_test.go
@@ -46,6 +46,7 @@ func getTestUserProfile() UserProfile {
 		Image48:               "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2016-10-18/92962080834_ef14c1469fc0741caea1_48.jpg",
 		Image72:               "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2016-10-18/92962080834_ef14c1469fc0741caea1_72.jpg",
 		Image192:              "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2016-10-18/92962080834_ef14c1469fc0741caea1_192.jpg",
+		Image512:              "https://s3-us-west-2.amazonaws.com/slack-files2/avatars/2016-10-18/92962080834_ef14c1469fc0741caea1_512.jpg",
 		Fields:                getTestUserProfileCustomFields(),
 	}
 }
Repository: slack-go/slack
Pull request #879 (2021-01-05 01:10:20)

Adding apps.uninstall method
##### Changes
Adding the `apps.uninstall` method, which completely removes a Slack app installation from its workspace (revoking any and all tokens in the process).

##### Docs
https://api.slack.com/methods/apps.uninstall




Patch:
diff --git a/apps.go b/apps.go
index cb26ad8..d974943 100644
--- a/apps.go
+++ b/apps.go
@@ -3,6 +3,7 @@ package slack
 import (
 	"context"
 	"encoding/json"
+	"net/url"
 )
 
 type listEventAuthorizationsResponse struct {
@@ -41,3 +42,20 @@ func (api *Client) ListEventAuthorizationsContext(ctx context.Context, eventCont
 
 	return resp.Authorizations, nil
 }
+
+func (api *Client) UninstallApp(clientID, clientSecret string) error {
+	values := url.Values{
+		"token":         {api.token},
+		"client_id":     {clientID},
+		"client_secret": {clientSecret},
+	}
+
+	response := SlackResponse{}
+
+	err := api.getMethod(context.Background(), "apps.uninstall", values, &response)
+	if err != nil {
+		return err
+	}
+
+	return response.Err()
+}


Test patch:
diff --git a/apps_test.go b/apps_test.go
index a6cd2bc..6d5f621 100644
--- a/apps_test.go
+++ b/apps_test.go
@@ -36,3 +36,22 @@ func testListEventAuthorizationsHandler(w http.ResponseWriter, r *http.Request)
 	})
 	w.Write(response)
 }
+
+func TestUninstallApp(t *testing.T) {
+	http.HandleFunc("/apps.uninstall", testUninstallAppHandler)
+	once.Do(startServer)
+
+	api := New("test-token", OptionAPIURL("http://"+serverAddr+"/"))
+
+	err := api.UninstallApp("", "")
+
+	if err != nil {
+		t.Errorf("Failed, but should have succeeded")
+	}
+}
+
+func testUninstallAppHandler(w http.ResponseWriter, r *http.Request) {
+	w.Header().Set("Content-Type", "application/json")
+	response, _ := json.Marshal(SlackResponse{Ok: true})
+	w.Write(response)
+}
Repository: slack-go/slack
Pull request #895 (2021-02-12 12:17:53)

Create a validation function to check TextBlockObject values
##### Description
**What**
Created a new validation function that can be optionally used to validate the fields in TextBlockObject

**Why**
1. Updates #881 
If we want to catch this problem absolutely like adding the validation like when initializing TextBlockObject, we need to change the IO of the existing API. So, it's a suggestion of the workaround to catch this.

2. It's also useful to catch other problems in TextBlockObject values
For example, we can add a new validation that picks up an unexpected value is in `Type` field by typo.
Even without using this in the production code, the client can make it useful in their unit test codes.

##### Should this be an issue instead
- [x] is it a convenience method? (no new functionality, streamlines some use case)
- [ ] exposes a previously private type, const, method, etc.
- [ ] is it application specific (caching, retry logic, rate limiting, etc)
- [ ] is it performance related.

##### API changes
It just created a new public function that doesn't mutate any data or states. Also, no change for the any existing API.


Patch:
diff --git a/block_object.go b/block_object.go
index d17806c..eae177f 100644
--- a/block_object.go
+++ b/block_object.go
@@ -2,6 +2,7 @@ package slack
 
 import (
 	"encoding/json"
+	"errors"
 )
 
 // Block Objects are also known as Composition Objects
@@ -135,6 +136,16 @@ func (s TextBlockObject) MixedElementType() MixedElementType {
 	return MixedElementText
 }
 
+// Validate checks if TextBlockObject has valid values
+func (s TextBlockObject) Validate() error {
+	// https://github.com/slack-go/slack/issues/881
+	if s.Type == "mrkdwn" && s.Emoji {
+		return errors.New("emoji cannot be true in mrkdown")
+	}
+
+	return nil
+}
+
 // NewTextBlockObject returns an instance of a new Text Block Object
 func NewTextBlockObject(elementType, text string, emoji, verbatim bool) *TextBlockObject {
 	return &TextBlockObject{


Test patch:
diff --git a/block_object_test.go b/block_object_test.go
index ea4e045..869fc30 100644
--- a/block_object_test.go
+++ b/block_object_test.go
@@ -1,6 +1,7 @@
 package slack
 
 import (
+	"errors"
 	"testing"
 
 	"github.com/stretchr/testify/assert"
@@ -83,3 +84,34 @@ func TestNewOptionGroupBlockElement(t *testing.T) {
 	assert.Len(t, optGroup.Options, 1, "Options should contain one element")
 
 }
+
+func TestValidateTextBlockObject(t *testing.T) {
+	tests := []struct {
+		input    TextBlockObject
+		expected error
+	}{
+		{
+			input: TextBlockObject{
+				Type:     "plain_text",
+				Text:     "testText",
+				Emoji:    false,
+				Verbatim: false,
+			},
+			expected: nil,
+		},
+		{
+			input: TextBlockObject{
+				Type:     "mrkdwn",
+				Text:     "testText",
+				Emoji:    true,
+				Verbatim: false,
+			},
+			expected: errors.New("emoji cannot be true in mrkdown"),
+		},
+	}
+
+	for _, test := range tests {
+		err := test.input.Validate()
+		assert.Equal(t, err, test.expected)
+	}
+}
Repository: slack-go/slack
Pull request #902 (2021-02-26 15:03:56)

Add the new condition to the validation func for TextBlockObject
# What
- Add the new validation condition that checks whether the value in the `Type` field is valid to the validation func for the `TextBlockObject`

# Why
- There may be a case that a user puts invalid value to this field such as mistaking it for other Struct or having a simple typo. 

# Ref
 [official API doc](https://api.slack.com/reference/block-kit/composition-objects#text)


Patch:
diff --git a/block_object.go b/block_object.go
index eae177f..5ced7f9 100644
--- a/block_object.go
+++ b/block_object.go
@@ -138,6 +138,10 @@ func (s TextBlockObject) MixedElementType() MixedElementType {
 
 // Validate checks if TextBlockObject has valid values
 func (s TextBlockObject) Validate() error {
+	if s.Type != "plain_text" && s.Type != "mrkdwn" {
+		return errors.New("type must be either of plain_text or mrkdwn")
+	}
+
 	// https://github.com/slack-go/slack/issues/881
 	if s.Type == "mrkdwn" && s.Emoji {
 		return errors.New("emoji cannot be true in mrkdown")


Test patch:
diff --git a/block_object_test.go b/block_object_test.go
index 869fc30..9889fae 100644
--- a/block_object_test.go
+++ b/block_object_test.go
@@ -99,6 +99,24 @@ func TestValidateTextBlockObject(t *testing.T) {
 			},
 			expected: nil,
 		},
+		{
+			input: TextBlockObject{
+				Type:     "mrkdwn",
+				Text:     "testText",
+				Emoji:    false,
+				Verbatim: false,
+			},
+			expected: nil,
+		},
+		{
+			input: TextBlockObject{
+				Type:     "invalid",
+				Text:     "testText",
+				Emoji:    false,
+				Verbatim: false,
+			},
+			expected: errors.New("type must be either of plain_text or mrkdwn"),
+		},
 		{
 			input: TextBlockObject{
 				Type:     "mrkdwn",
Repository: slack-go/slack
Pull request #1106 (2022-08-31 07:48:15)

Handle null value in JSONTime
Handle the NULL value, when API returns "timestamp": null

It returns JSONTime(0) in this case.

##### Pull Request Guidelines

These are recommendations for pull requests.
They are strictly guidelines to help manage expectations.

##### PR preparation
Run `make pr-prep` from the root of the repository to run formatting, linting and tests.

##### API changes

Since API changes have to be maintained they undergo a more detailed review and are more likely to require changes.

- no tests, if you're adding to the API include at least a single test of the happy case.
- If you can accomplish your goal without changing the API, then do so.
- dependency changes. updates are okay. adding/removing need justification.

###### Examples of API changes that do not meet guidelines:
- in library cache for users. caches are use case specific.
- Convenience methods for Sending Messages, update, post, ephemeral, etc. consider opening an issue instead.



Patch:
diff --git a/info.go b/info.go
index fde2bc9..b06dffd 100644
--- a/info.go
+++ b/info.go
@@ -409,6 +409,11 @@ func (t JSONTime) Time() time.Time {
 func (t *JSONTime) UnmarshalJSON(buf []byte) error {
 	s := bytes.Trim(buf, `"`)
 
+	if bytes.EqualFold(s, []byte("null")) {
+		*t = JSONTime(0)
+		return nil
+	}
+
 	v, err := strconv.Atoi(string(s))
 	if err != nil {
 		return err


Test patch:
diff --git a/info_test.go b/info_test.go
new file mode 100644
index 0000000..baf91d0
--- /dev/null
+++ b/info_test.go
@@ -0,0 +1,44 @@
+package slack
+
+import (
+	"testing"
+)
+
+func TestJSONTime_UnmarshalJSON(t *testing.T) {
+	type args struct {
+		buf []byte
+	}
+	tests := []struct {
+		name    string
+		args    args
+		wantTr  JSONTime
+		wantErr bool
+	}{
+		{
+			"acceptable int64 timestamp",
+			args{[]byte(`1643435556`)},
+			JSONTime(1643435556),
+			false,
+		},
+		{
+			"acceptable string timestamp",
+			args{[]byte(`"1643435556"`)},
+			JSONTime(1643435556),
+			false,
+		},
+		{
+			"null",
+			args{[]byte(`null`)},
+			JSONTime(0),
+			false,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			var tr JSONTime
+			if err := tr.UnmarshalJSON(tt.args.buf); (err != nil) != tt.wantErr {
+				t.Errorf("JSONTime.UnmarshalJSON() error = %v, wantErr %v", err, tt.wantErr)
+			}
+		})
+	}
+}