mirror of
https://github.com/dstotijn/go-notion.git
synced 2025-06-08 23:46:12 +02:00
Convert Block
from a struct to an interface (#27)
This commit is contained in:
parent
1bd13b04cf
commit
8c9f519e73
859
block.go
859
block.go
@ -2,13 +2,22 @@ package notion
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Block represents content on the Notion platform.
|
// Block represents content on the Notion platform.
|
||||||
// See: https://developers.notion.com/reference/block
|
// See: https://developers.notion.com/reference/block
|
||||||
type Block struct {
|
type Block interface {
|
||||||
Object string `json:"object"`
|
ID() string
|
||||||
|
CreatedTime() time.Time
|
||||||
|
LastEditedTime() time.Time
|
||||||
|
HasChildren() bool
|
||||||
|
Archived() bool
|
||||||
|
json.Marshaler
|
||||||
|
}
|
||||||
|
|
||||||
|
type blockDTO struct {
|
||||||
ID string `json:"id,omitempty"`
|
ID string `json:"id,omitempty"`
|
||||||
Type BlockType `json:"type,omitempty"`
|
Type BlockType `json:"type,omitempty"`
|
||||||
CreatedTime *time.Time `json:"created_time,omitempty"`
|
CreatedTime *time.Time `json:"created_time,omitempty"`
|
||||||
@ -16,115 +25,642 @@ type Block struct {
|
|||||||
HasChildren bool `json:"has_children,omitempty"`
|
HasChildren bool `json:"has_children,omitempty"`
|
||||||
Archived *bool `json:"archived,omitempty"`
|
Archived *bool `json:"archived,omitempty"`
|
||||||
|
|
||||||
Paragraph *RichTextBlock `json:"paragraph,omitempty"`
|
Paragraph *ParagraphBlock `json:"paragraph,omitempty"`
|
||||||
Heading1 *Heading `json:"heading_1,omitempty"`
|
Heading1 *Heading1Block `json:"heading_1,omitempty"`
|
||||||
Heading2 *Heading `json:"heading_2,omitempty"`
|
Heading2 *Heading2Block `json:"heading_2,omitempty"`
|
||||||
Heading3 *Heading `json:"heading_3,omitempty"`
|
Heading3 *Heading3Block `json:"heading_3,omitempty"`
|
||||||
BulletedListItem *RichTextBlock `json:"bulleted_list_item,omitempty"`
|
BulletedListItem *BulletedListItemBlock `json:"bulleted_list_item,omitempty"`
|
||||||
NumberedListItem *RichTextBlock `json:"numbered_list_item,omitempty"`
|
NumberedListItem *NumberedListItemBlock `json:"numbered_list_item,omitempty"`
|
||||||
ToDo *ToDo `json:"to_do,omitempty"`
|
ToDo *ToDoBlock `json:"to_do,omitempty"`
|
||||||
Toggle *RichTextBlock `json:"toggle,omitempty"`
|
Toggle *ToggleBlock `json:"toggle,omitempty"`
|
||||||
ChildPage *ChildPage `json:"child_page,omitempty"`
|
ChildPage *ChildPageBlock `json:"child_page,omitempty"`
|
||||||
ChildDatabase *ChildDatabase `json:"child_database,omitempty"`
|
ChildDatabase *ChildDatabaseBlock `json:"child_database,omitempty"`
|
||||||
Callout *Callout `json:"callout,omitempty"`
|
Callout *CalloutBlock `json:"callout,omitempty"`
|
||||||
Quote *RichTextBlock `json:"quote,omitempty"`
|
Quote *QuoteBlock `json:"quote,omitempty"`
|
||||||
Code *Code `json:"code,omitempty"`
|
Code *CodeBlock `json:"code,omitempty"`
|
||||||
Embed *Embed `json:"embed,omitempty"`
|
Embed *EmbedBlock `json:"embed,omitempty"`
|
||||||
Image *FileBlock `json:"image,omitempty"`
|
Image *ImageBlock `json:"image,omitempty"`
|
||||||
Video *FileBlock `json:"video,omitempty"`
|
Video *VideoBlock `json:"video,omitempty"`
|
||||||
File *FileBlock `json:"file,omitempty"`
|
File *FileBlock `json:"file,omitempty"`
|
||||||
PDF *FileBlock `json:"pdf,omitempty"`
|
PDF *PDFBlock `json:"pdf,omitempty"`
|
||||||
Bookmark *Bookmark `json:"bookmark,omitempty"`
|
Bookmark *BookmarkBlock `json:"bookmark,omitempty"`
|
||||||
Equation *Equation `json:"equation,omitempty"`
|
Equation *EquationBlock `json:"equation,omitempty"`
|
||||||
Divider *Divider `json:"divider,omitempty"`
|
Divider *DividerBlock `json:"divider,omitempty"`
|
||||||
TableOfContents *TableOfContents `json:"table_of_contents,omitempty"`
|
TableOfContents *TableOfContentsBlock `json:"table_of_contents,omitempty"`
|
||||||
Breadcrumb *Breadcrumb `json:"breadcrumb,omitempty"`
|
Breadcrumb *BreadcrumbBlock `json:"breadcrumb,omitempty"`
|
||||||
ColumnList *ColumnList `json:"column_list,omitempty"`
|
ColumnList *ColumnListBlock `json:"column_list,omitempty"`
|
||||||
Column *Column `json:"column,omitempty"`
|
Column *ColumnBlock `json:"column,omitempty"`
|
||||||
Table *Table `json:"table,omitempty"`
|
Table *TableBlock `json:"table,omitempty"`
|
||||||
TableRow *TableRow `json:"table_row,omitempty"`
|
TableRow *TableRowBlock `json:"table_row,omitempty"`
|
||||||
LinkPreview *LinkPreview `json:"link_preview,omitempty"`
|
LinkPreview *LinkPreviewBlock `json:"link_preview,omitempty"`
|
||||||
LinkToPage *LinkToPage `json:"link_to_page,omitempty"`
|
LinkToPage *LinkToPageBlock `json:"link_to_page,omitempty"`
|
||||||
SyncedBlock *SyncedBlock `json:"synced_block,omitempty"`
|
SyncedBlock *SyncedBlock `json:"synced_block,omitempty"`
|
||||||
Template *RichTextBlock `json:"template,omitempty"`
|
Template *TemplateBlock `json:"template,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type RichTextBlock struct {
|
type baseBlock struct {
|
||||||
|
id string
|
||||||
|
createdTime time.Time
|
||||||
|
lastEditedTime time.Time
|
||||||
|
hasChildren bool
|
||||||
|
archived bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// ID returns the identifier (UUIDv4) for the block.
|
||||||
|
func (b baseBlock) ID() string {
|
||||||
|
return b.id
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b baseBlock) CreatedTime() time.Time {
|
||||||
|
return b.createdTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b baseBlock) LastEditedTime() time.Time {
|
||||||
|
return b.lastEditedTime
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b baseBlock) HasChildren() bool {
|
||||||
|
return b.hasChildren
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b baseBlock) Archived() bool {
|
||||||
|
return b.archived
|
||||||
|
}
|
||||||
|
|
||||||
|
type ParagraphBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
Text []RichText `json:"text"`
|
Text []RichText `json:"text"`
|
||||||
Children []Block `json:"children,omitempty"`
|
Children []Block `json:"children,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Heading struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
Text []RichText `json:"text"`
|
func (b ParagraphBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ParagraphBlock
|
||||||
|
dto struct {
|
||||||
|
Paragraph blockAlias `json:"paragraph"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Paragraph: blockAlias(b),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type ToDo struct {
|
type BulletedListItemBlock struct {
|
||||||
RichTextBlock
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b BulletedListItemBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias BulletedListItemBlock
|
||||||
|
dto struct {
|
||||||
|
BulletedListItem blockAlias `json:"bulleted_list_item"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
BulletedListItem: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type NumberedListItemBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b NumberedListItemBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias NumberedListItemBlock
|
||||||
|
dto struct {
|
||||||
|
NumberedListItem blockAlias `json:"numbered_list_item"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
NumberedListItem: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type QuoteBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b QuoteBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias QuoteBlock
|
||||||
|
dto struct {
|
||||||
|
Quote blockAlias `json:"quote"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Quote: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToggleBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b ToggleBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ToggleBlock
|
||||||
|
dto struct {
|
||||||
|
Toggle blockAlias `json:"toggle"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Toggle: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type TemplateBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b TemplateBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias TemplateBlock
|
||||||
|
dto struct {
|
||||||
|
Template blockAlias `json:"template"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Template: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Heading1Block struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b Heading1Block) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias Heading1Block
|
||||||
|
dto struct {
|
||||||
|
Heading1 blockAlias `json:"heading_1"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Heading1: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Heading2Block struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b Heading2Block) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias Heading2Block
|
||||||
|
dto struct {
|
||||||
|
Heading2 blockAlias `json:"heading_2"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Heading2: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type Heading3Block struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b Heading3Block) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias Heading3Block
|
||||||
|
dto struct {
|
||||||
|
Heading3 blockAlias `json:"heading_3"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Heading3: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ToDoBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
Checked *bool `json:"checked,omitempty"`
|
Checked *bool `json:"checked,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChildPage struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b ToDoBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ToDoBlock
|
||||||
|
dto struct {
|
||||||
|
ToDo blockAlias `json:"to_do"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
ToDo: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChildPageBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ChildDatabase struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b ChildPageBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ChildPageBlock
|
||||||
|
dto struct {
|
||||||
|
ChildPage blockAlias `json:"child_page"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
ChildPage: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChildDatabaseBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
Title string `json:"title"`
|
Title string `json:"title"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Callout struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
RichTextBlock
|
func (b ChildDatabaseBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ChildDatabaseBlock
|
||||||
|
dto struct {
|
||||||
|
ChildDatabase blockAlias `json:"child_database"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
ChildDatabase: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type CalloutBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
Icon *Icon `json:"icon,omitempty"`
|
Icon *Icon `json:"icon,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Code struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
RichTextBlock
|
func (b CalloutBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias CalloutBlock
|
||||||
|
dto struct {
|
||||||
|
Callout blockAlias `json:"callout"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Callout: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type CodeBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Text []RichText `json:"text"`
|
||||||
|
Children []Block `json:"children,omitempty"`
|
||||||
Caption []RichText `json:"caption,omitempty"`
|
Caption []RichText `json:"caption,omitempty"`
|
||||||
Language *string `json:"language,omitempty"`
|
Language *string `json:"language,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Embed struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b CodeBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias CodeBlock
|
||||||
|
dto struct {
|
||||||
|
Code blockAlias `json:"code"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Code: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmbedBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type FileBlock struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
Type FileType `json:"type"`
|
func (b EmbedBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias EmbedBlock
|
||||||
|
dto struct {
|
||||||
|
Embed blockAlias `json:"embed"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Embed: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ImageBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Type FileType `json:"type"`
|
||||||
File *FileFile `json:"file,omitempty"`
|
File *FileFile `json:"file,omitempty"`
|
||||||
External *FileExternal `json:"external,omitempty"`
|
External *FileExternal `json:"external,omitempty"`
|
||||||
Caption []RichText `json:"caption,omitempty"`
|
Caption []RichText `json:"caption,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Bookmark struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b ImageBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ImageBlock
|
||||||
|
dto struct {
|
||||||
|
Image blockAlias `json:"image"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Image: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type VideoBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Type FileType `json:"type"`
|
||||||
|
File *FileFile `json:"file,omitempty"`
|
||||||
|
External *FileExternal `json:"external,omitempty"`
|
||||||
|
Caption []RichText `json:"caption,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b VideoBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias VideoBlock
|
||||||
|
dto struct {
|
||||||
|
Video blockAlias `json:"video"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Video: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type FileBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Type FileType `json:"type"`
|
||||||
|
File *FileFile `json:"file,omitempty"`
|
||||||
|
External *FileExternal `json:"external,omitempty"`
|
||||||
|
Caption []RichText `json:"caption,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b FileBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias FileBlock
|
||||||
|
dto struct {
|
||||||
|
File blockAlias `json:"file"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
File: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type PDFBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Type FileType `json:"type"`
|
||||||
|
File *FileFile `json:"file,omitempty"`
|
||||||
|
External *FileExternal `json:"external,omitempty"`
|
||||||
|
Caption []RichText `json:"caption,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b PDFBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias PDFBlock
|
||||||
|
dto struct {
|
||||||
|
PDF blockAlias `json:"pdf"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
PDF: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type BookmarkBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
Caption []RichText `json:"caption,omitempty"`
|
Caption []RichText `json:"caption,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ColumnList struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b BookmarkBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias BookmarkBlock
|
||||||
|
dto struct {
|
||||||
|
Bookmark blockAlias `json:"bookmark"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Bookmark: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type EquationBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Expression string `json:"expression"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b EquationBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias EquationBlock
|
||||||
|
dto struct {
|
||||||
|
Equation blockAlias `json:"equation"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Equation: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnListBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
Children []Block `json:"children,omitempty"`
|
Children []Block `json:"children,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Column struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b ColumnListBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ColumnListBlock
|
||||||
|
dto struct {
|
||||||
|
ColumnList blockAlias `json:"column_list"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
ColumnList: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type ColumnBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
Children []Block `json:"children,omitempty"`
|
Children []Block `json:"children,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Table struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b ColumnBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias ColumnBlock
|
||||||
|
dto struct {
|
||||||
|
Column blockAlias `json:"column"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Column: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
TableWidth int `json:"table_width"`
|
TableWidth int `json:"table_width"`
|
||||||
HasColumnHeader bool `json:"has_column_header"`
|
HasColumnHeader bool `json:"has_column_header"`
|
||||||
HasRowHeader bool `json:"has_row_header"`
|
HasRowHeader bool `json:"has_row_header"`
|
||||||
Children []Block `json:"children,omitempty"`
|
Children []Block `json:"children,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type TableRow struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b TableBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias TableBlock
|
||||||
|
dto struct {
|
||||||
|
Table blockAlias `json:"table"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Table: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableRowBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
Cells [][]RichText `json:"cells"`
|
Cells [][]RichText `json:"cells"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type LinkToPage struct {
|
// MarshalJSON implements json.Marshaler.
|
||||||
Type LinkToPageType `json:"type"`
|
func (b TableRowBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias TableRowBlock
|
||||||
|
dto struct {
|
||||||
|
TableRow blockAlias `json:"table_row"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
TableRow: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type LinkPreviewBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
URL string `json:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b LinkPreviewBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias LinkPreviewBlock
|
||||||
|
dto struct {
|
||||||
|
LinkPreview blockAlias `json:"link_preview"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
LinkPreview: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type LinkToPageBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
|
Type LinkToPageType `json:"type"`
|
||||||
PageID string `json:"page_id,omitempty"`
|
PageID string `json:"page_id,omitempty"`
|
||||||
DatabaseID string `json:"database_id,omitempty"`
|
DatabaseID string `json:"database_id,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b LinkToPageBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias LinkToPageBlock
|
||||||
|
dto struct {
|
||||||
|
LinkToPage blockAlias `json:"link_to_page"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
LinkToPage: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type LinkToPageType string
|
type LinkToPageType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -133,10 +669,26 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SyncedBlock struct {
|
type SyncedBlock struct {
|
||||||
|
baseBlock
|
||||||
|
|
||||||
SyncedFrom *SyncedFrom `json:"synced_from"`
|
SyncedFrom *SyncedFrom `json:"synced_from"`
|
||||||
Children []Block `json:"children,omitempty"`
|
Children []Block `json:"children,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b SyncedBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias SyncedBlock
|
||||||
|
dto struct {
|
||||||
|
SyncedBlock blockAlias `json:"synced_block"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
SyncedBlock: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type SyncedFrom struct {
|
type SyncedFrom struct {
|
||||||
Type SyncedFromType `json:"type"`
|
Type SyncedFromType `json:"type"`
|
||||||
BlockID string `json:"block_id"`
|
BlockID string `json:"block_id"`
|
||||||
@ -146,11 +698,59 @@ type SyncedFromType string
|
|||||||
|
|
||||||
const SyncedFromTypeBlockID SyncedFromType = "block_id"
|
const SyncedFromTypeBlockID SyncedFromType = "block_id"
|
||||||
|
|
||||||
type (
|
type DividerBlock struct {
|
||||||
Divider struct{}
|
baseBlock
|
||||||
TableOfContents struct{}
|
}
|
||||||
Breadcrumb struct{}
|
|
||||||
)
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b DividerBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias DividerBlock
|
||||||
|
dto struct {
|
||||||
|
Divider blockAlias `json:"divider"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Divider: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type TableOfContentsBlock struct {
|
||||||
|
baseBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b TableOfContentsBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias TableOfContentsBlock
|
||||||
|
dto struct {
|
||||||
|
TableOfContents blockAlias `json:"table_of_contents"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
TableOfContents: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
type BreadcrumbBlock struct {
|
||||||
|
baseBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON implements json.Marshaler.
|
||||||
|
func (b BreadcrumbBlock) MarshalJSON() ([]byte, error) {
|
||||||
|
type (
|
||||||
|
blockAlias BreadcrumbBlock
|
||||||
|
dto struct {
|
||||||
|
Breadcrumb blockAlias `json:"breadcrumb"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
return json.Marshal(dto{
|
||||||
|
Breadcrumb: blockAlias(b),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
type BlockType string
|
type BlockType string
|
||||||
|
|
||||||
@ -196,17 +796,148 @@ type PaginationQuery struct {
|
|||||||
|
|
||||||
// BlockChildrenResponse contains results (block children) and pagination data returned from a find request.
|
// BlockChildrenResponse contains results (block children) and pagination data returned from a find request.
|
||||||
type BlockChildrenResponse struct {
|
type BlockChildrenResponse struct {
|
||||||
Results []Block `json:"results"`
|
Results []Block
|
||||||
|
HasMore bool
|
||||||
|
NextCursor *string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (resp *BlockChildrenResponse) UnmarshalJSON(b []byte) error {
|
||||||
|
type responseDTO struct {
|
||||||
|
Results []blockDTO `json:"results"`
|
||||||
HasMore bool `json:"has_more"`
|
HasMore bool `json:"has_more"`
|
||||||
NextCursor *string `json:"next_cursor"`
|
NextCursor *string `json:"next_cursor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
var dto responseDTO
|
||||||
|
|
||||||
|
if err := json.Unmarshal(b, &dto); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.HasMore = dto.HasMore
|
||||||
|
resp.NextCursor = dto.NextCursor
|
||||||
|
resp.Results = make([]Block, len(dto.Results))
|
||||||
|
|
||||||
|
for i, blockDTO := range dto.Results {
|
||||||
|
resp.Results[i] = blockDTO.Block()
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// MarshalJSON implements json.Marshaler.
|
func (dto blockDTO) Block() Block {
|
||||||
func (b Block) MarshalJSON() ([]byte, error) {
|
baseBlock := baseBlock{
|
||||||
type blockAlias Block
|
id: dto.ID,
|
||||||
|
hasChildren: dto.HasChildren,
|
||||||
|
}
|
||||||
|
|
||||||
alias := blockAlias(b)
|
if dto.CreatedTime != nil {
|
||||||
alias.Object = "block"
|
baseBlock.createdTime = *dto.CreatedTime
|
||||||
|
}
|
||||||
|
|
||||||
return json.Marshal(alias)
|
if dto.LastEditedTime != nil {
|
||||||
|
baseBlock.lastEditedTime = *dto.LastEditedTime
|
||||||
|
}
|
||||||
|
|
||||||
|
if dto.Archived != nil {
|
||||||
|
baseBlock.archived = *dto.Archived
|
||||||
|
}
|
||||||
|
|
||||||
|
switch dto.Type {
|
||||||
|
case BlockTypeParagraph:
|
||||||
|
dto.Paragraph.baseBlock = baseBlock
|
||||||
|
return dto.Paragraph
|
||||||
|
case BlockTypeHeading1:
|
||||||
|
dto.Heading1.baseBlock = baseBlock
|
||||||
|
return dto.Heading1
|
||||||
|
case BlockTypeHeading2:
|
||||||
|
dto.Heading2.baseBlock = baseBlock
|
||||||
|
return dto.Heading2
|
||||||
|
case BlockTypeHeading3:
|
||||||
|
dto.Heading3.baseBlock = baseBlock
|
||||||
|
return dto.Heading3
|
||||||
|
case BlockTypeBulletedListItem:
|
||||||
|
dto.BulletedListItem.baseBlock = baseBlock
|
||||||
|
return dto.BulletedListItem
|
||||||
|
case BlockTypeNumberedListItem:
|
||||||
|
dto.NumberedListItem.baseBlock = baseBlock
|
||||||
|
return dto.NumberedListItem
|
||||||
|
case BlockTypeToDo:
|
||||||
|
dto.ToDo.baseBlock = baseBlock
|
||||||
|
return dto.ToDo
|
||||||
|
case BlockTypeToggle:
|
||||||
|
dto.Toggle.baseBlock = baseBlock
|
||||||
|
return dto.Toggle
|
||||||
|
case BlockTypeChildPage:
|
||||||
|
dto.ChildPage.baseBlock = baseBlock
|
||||||
|
return dto.ChildPage
|
||||||
|
case BlockTypeChildDatabase:
|
||||||
|
dto.ChildDatabase.baseBlock = baseBlock
|
||||||
|
return dto.ChildDatabase
|
||||||
|
case BlockTypeCallout:
|
||||||
|
dto.Callout.baseBlock = baseBlock
|
||||||
|
return dto.Callout
|
||||||
|
case BlockTypeQuote:
|
||||||
|
dto.Quote.baseBlock = baseBlock
|
||||||
|
return dto.Quote
|
||||||
|
case BlockTypeCode:
|
||||||
|
dto.Code.baseBlock = baseBlock
|
||||||
|
return dto.Code
|
||||||
|
case BlockTypeEmbed:
|
||||||
|
dto.Embed.baseBlock = baseBlock
|
||||||
|
return dto.Embed
|
||||||
|
case BlockTypeImage:
|
||||||
|
dto.Image.baseBlock = baseBlock
|
||||||
|
return dto.Image
|
||||||
|
case BlockTypeVideo:
|
||||||
|
dto.Video.baseBlock = baseBlock
|
||||||
|
return dto.Video
|
||||||
|
case BlockTypeFile:
|
||||||
|
dto.File.baseBlock = baseBlock
|
||||||
|
return dto.File
|
||||||
|
case BlockTypePDF:
|
||||||
|
dto.PDF.baseBlock = baseBlock
|
||||||
|
return dto.PDF
|
||||||
|
case BlockTypeBookmark:
|
||||||
|
dto.Bookmark.baseBlock = baseBlock
|
||||||
|
return dto.Bookmark
|
||||||
|
case BlockTypeEquation:
|
||||||
|
dto.Equation.baseBlock = baseBlock
|
||||||
|
return dto.Equation
|
||||||
|
case BlockTypeDivider:
|
||||||
|
dto.Divider.baseBlock = baseBlock
|
||||||
|
return dto.Divider
|
||||||
|
case BlockTypeTableOfContents:
|
||||||
|
dto.TableOfContents.baseBlock = baseBlock
|
||||||
|
return dto.TableOfContents
|
||||||
|
case BlockTypeBreadCrumb:
|
||||||
|
dto.Breadcrumb.baseBlock = baseBlock
|
||||||
|
return dto.Breadcrumb
|
||||||
|
case BlockTypeColumnList:
|
||||||
|
dto.ColumnList.baseBlock = baseBlock
|
||||||
|
return dto.ColumnList
|
||||||
|
case BlockTypeColumn:
|
||||||
|
dto.Column.baseBlock = baseBlock
|
||||||
|
return dto.Column
|
||||||
|
case BlockTypeTable:
|
||||||
|
dto.Table.baseBlock = baseBlock
|
||||||
|
return dto.Table
|
||||||
|
case BlockTypeTableRow:
|
||||||
|
dto.TableRow.baseBlock = baseBlock
|
||||||
|
return dto.TableRow
|
||||||
|
case BlockTypeLinkPreview:
|
||||||
|
dto.LinkPreview.baseBlock = baseBlock
|
||||||
|
return dto.LinkPreview
|
||||||
|
case BlockTypeLinkToPage:
|
||||||
|
dto.LinkToPage.baseBlock = baseBlock
|
||||||
|
return dto.LinkToPage
|
||||||
|
case BlockTypeSyncedBlock:
|
||||||
|
dto.SyncedBlock.baseBlock = baseBlock
|
||||||
|
return dto.SyncedBlock
|
||||||
|
case BlockTypeTemplate:
|
||||||
|
dto.Template.baseBlock = baseBlock
|
||||||
|
return dto.Template
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("type %q is unsupported", dto.Type))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
52
client.go
52
client.go
@ -413,87 +413,93 @@ func (c *Client) AppendBlockChildren(ctx context.Context, blockID string, childr
|
|||||||
|
|
||||||
// FindBlockByID returns a single of block for a given block ID.
|
// FindBlockByID returns a single of block for a given block ID.
|
||||||
// See: https://developers.notion.com/reference/retrieve-a-block
|
// See: https://developers.notion.com/reference/retrieve-a-block
|
||||||
func (c *Client) FindBlockByID(ctx context.Context, blockID string) (block Block, err error) {
|
func (c *Client) FindBlockByID(ctx context.Context, blockID string) (Block, error) {
|
||||||
req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/blocks/%v", blockID), nil)
|
req, err := c.newRequest(ctx, http.MethodGet, fmt.Sprintf("/blocks/%v", blockID), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: invalid request: %w", err)
|
return nil, fmt.Errorf("notion: invalid request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.httpClient.Do(req)
|
res, err := c.httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: failed to make HTTP request: %w", err)
|
return nil, fmt.Errorf("notion: failed to make HTTP request: %w", err)
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
if res.StatusCode != http.StatusOK {
|
if res.StatusCode != http.StatusOK {
|
||||||
return Block{}, fmt.Errorf("notion: failed to find block: %w", parseErrorResponse(res))
|
return nil, fmt.Errorf("notion: failed to find block: %w", parseErrorResponse(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.NewDecoder(res.Body).Decode(&block)
|
var dto blockDTO
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&dto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: failed to parse HTTP response: %w", err)
|
return nil, fmt.Errorf("notion: failed to parse HTTP response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return block, nil
|
return dto.Block(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateBlock updates a block.
|
// UpdateBlock updates a block.
|
||||||
// See: https://developers.notion.com/reference/update-a-block
|
// See: https://developers.notion.com/reference/update-a-block
|
||||||
func (c *Client) UpdateBlock(ctx context.Context, blockID string, block Block) (updatedBlock Block, err error) {
|
func (c *Client) UpdateBlock(ctx context.Context, blockID string, block Block) (Block, error) {
|
||||||
body := &bytes.Buffer{}
|
body := &bytes.Buffer{}
|
||||||
|
|
||||||
err = json.NewEncoder(body).Encode(block)
|
err := json.NewEncoder(body).Encode(block)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: failed to encode body params to JSON: %w", err)
|
return nil, fmt.Errorf("notion: failed to encode body params to JSON: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := c.newRequest(ctx, http.MethodPatch, "/blocks/"+blockID, body)
|
req, err := c.newRequest(ctx, http.MethodPatch, "/blocks/"+blockID, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: invalid request: %w", err)
|
return nil, fmt.Errorf("notion: invalid request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.httpClient.Do(req)
|
res, err := c.httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: failed to make HTTP request: %w", err)
|
return nil, fmt.Errorf("notion: failed to make HTTP request: %w", err)
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
if res.StatusCode != http.StatusOK {
|
if res.StatusCode != http.StatusOK {
|
||||||
return Block{}, fmt.Errorf("notion: failed to update block: %w", parseErrorResponse(res))
|
return nil, fmt.Errorf("notion: failed to update block: %w", parseErrorResponse(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.NewDecoder(res.Body).Decode(&updatedBlock)
|
var dto blockDTO
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&dto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: failed to parse HTTP response: %w", err)
|
return nil, fmt.Errorf("notion: failed to parse HTTP response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return updatedBlock, nil
|
return dto.Block(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteBlock sets `archived: true` on a (page) block object.
|
// DeleteBlock sets `archived: true` on a (page) block object.
|
||||||
// See: https://developers.notion.com/reference/delete-a-block
|
// See: https://developers.notion.com/reference/delete-a-block
|
||||||
func (c *Client) DeleteBlock(ctx context.Context, blockID string) (deletedBlock Block, err error) {
|
func (c *Client) DeleteBlock(ctx context.Context, blockID string) (Block, error) {
|
||||||
req, err := c.newRequest(ctx, http.MethodDelete, "/blocks/"+blockID, nil)
|
req, err := c.newRequest(ctx, http.MethodDelete, "/blocks/"+blockID, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: invalid request: %w", err)
|
return nil, fmt.Errorf("notion: invalid request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.httpClient.Do(req)
|
res, err := c.httpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: failed to make HTTP request: %w", err)
|
return nil, fmt.Errorf("notion: failed to make HTTP request: %w", err)
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
defer res.Body.Close()
|
||||||
|
|
||||||
if res.StatusCode != http.StatusOK {
|
if res.StatusCode != http.StatusOK {
|
||||||
return Block{}, fmt.Errorf("notion: failed to delete block: %w", parseErrorResponse(res))
|
return nil, fmt.Errorf("notion: failed to delete block: %w", parseErrorResponse(res))
|
||||||
}
|
}
|
||||||
|
|
||||||
err = json.NewDecoder(res.Body).Decode(&deletedBlock)
|
var dto blockDTO
|
||||||
|
|
||||||
|
err = json.NewDecoder(res.Body).Decode(&dto)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Block{}, fmt.Errorf("notion: failed to parse HTTP response: %w", err)
|
return nil, fmt.Errorf("notion: failed to parse HTTP response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return deletedBlock, nil
|
return dto.Block(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindUserByID fetches a user by ID.
|
// FindUserByID fetches a user by ID.
|
||||||
|
292
client_test.go
292
client_test.go
@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/dstotijn/go-notion"
|
"github.com/dstotijn/go-notion"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
"github.com/google/go-cmp/cmp/cmpopts"
|
||||||
)
|
)
|
||||||
|
|
||||||
type mockRoundtripper struct {
|
type mockRoundtripper struct {
|
||||||
@ -1667,10 +1668,7 @@ func TestCreatePage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Children: []notion.Block{
|
Children: []notion.Block{
|
||||||
{
|
¬ion.ParagraphBlock{
|
||||||
Object: "block",
|
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Text: ¬ion.Text{
|
Text: ¬ion.Text{
|
||||||
@ -1680,7 +1678,6 @@ func TestCreatePage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
Icon: ¬ion.Icon{
|
Icon: ¬ion.Icon{
|
||||||
Type: notion.IconTypeExternal,
|
Type: notion.IconTypeExternal,
|
||||||
External: ¬ion.FileExternal{
|
External: ¬ion.FileExternal{
|
||||||
@ -1763,8 +1760,6 @@ func TestCreatePage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"children": []interface{}{
|
"children": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"object": "block",
|
|
||||||
"type": "paragraph",
|
|
||||||
"paragraph": map[string]interface{}{
|
"paragraph": map[string]interface{}{
|
||||||
"text": []interface{}{
|
"text": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -1846,10 +1841,7 @@ func TestCreatePage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Children: []notion.Block{
|
Children: []notion.Block{
|
||||||
{
|
¬ion.ParagraphBlock{
|
||||||
Object: "block",
|
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Text: ¬ion.Text{
|
Text: ¬ion.Text{
|
||||||
@ -1860,7 +1852,6 @@ func TestCreatePage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
respBody: func(_ *http.Request) io.Reader {
|
respBody: func(_ *http.Request) io.Reader {
|
||||||
return strings.NewReader(
|
return strings.NewReader(
|
||||||
`{
|
`{
|
||||||
@ -1916,8 +1907,6 @@ func TestCreatePage(t *testing.T) {
|
|||||||
},
|
},
|
||||||
"children": []interface{}{
|
"children": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"object": "block",
|
|
||||||
"type": "paragraph",
|
|
||||||
"paragraph": map[string]interface{}{
|
"paragraph": map[string]interface{}{
|
||||||
"text": []interface{}{
|
"text": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -2877,6 +2866,14 @@ func TestFindPagePropertyByID(t *testing.T) {
|
|||||||
func TestFindBlockChildrenById(t *testing.T) {
|
func TestFindBlockChildrenById(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
type blockFields struct {
|
||||||
|
id string
|
||||||
|
createdTime time.Time
|
||||||
|
lastEditedTime time.Time
|
||||||
|
hasChildren bool
|
||||||
|
archived bool
|
||||||
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
query *notion.PaginationQuery
|
query *notion.PaginationQuery
|
||||||
@ -2884,6 +2881,7 @@ func TestFindBlockChildrenById(t *testing.T) {
|
|||||||
respStatusCode int
|
respStatusCode int
|
||||||
expQueryParams url.Values
|
expQueryParams url.Values
|
||||||
expResponse notion.BlockChildrenResponse
|
expResponse notion.BlockChildrenResponse
|
||||||
|
expBlockFields []blockFields
|
||||||
expError error
|
expError error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -2939,13 +2937,7 @@ func TestFindBlockChildrenById(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expResponse: notion.BlockChildrenResponse{
|
expResponse: notion.BlockChildrenResponse{
|
||||||
Results: []notion.Block{
|
Results: []notion.Block{
|
||||||
{
|
¬ion.ParagraphBlock{
|
||||||
Object: "block",
|
|
||||||
ID: "ae9c9a31-1c1e-4ae2-a5ee-c539a2d43113",
|
|
||||||
CreatedTime: notion.TimePtr(mustParseTime(time.RFC3339Nano, "2021-05-14T09:15:00.000Z")),
|
|
||||||
LastEditedTime: notion.TimePtr(mustParseTime(time.RFC3339Nano, "2021-05-14T09:15:00.000Z")),
|
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Type: notion.RichTextTypeText,
|
Type: notion.RichTextTypeText,
|
||||||
@ -2960,10 +2952,18 @@ func TestFindBlockChildrenById(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
HasMore: true,
|
HasMore: true,
|
||||||
NextCursor: notion.StringPtr("A^hd"),
|
NextCursor: notion.StringPtr("A^hd"),
|
||||||
},
|
},
|
||||||
|
expBlockFields: []blockFields{
|
||||||
|
{
|
||||||
|
id: "ae9c9a31-1c1e-4ae2-a5ee-c539a2d43113",
|
||||||
|
createdTime: mustParseTime(time.RFC3339, "2021-05-14T09:15:00.000Z"),
|
||||||
|
lastEditedTime: mustParseTime(time.RFC3339, "2021-05-14T09:15:00.000Z"),
|
||||||
|
hasChildren: false,
|
||||||
|
archived: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
expError: nil,
|
expError: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3049,9 +3049,35 @@ func TestFindBlockChildrenById(t *testing.T) {
|
|||||||
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff := cmp.Diff(tt.expResponse, resp); diff != "" {
|
if diff := cmp.Diff(tt.expResponse, resp, cmpopts.IgnoreUnexported(notion.ParagraphBlock{})); diff != "" {
|
||||||
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(tt.expBlockFields) != len(resp.Results) {
|
||||||
|
t.Fatalf("expected %v result(s), got %v", len(tt.expBlockFields), len(resp.Results))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, exp := range tt.expBlockFields {
|
||||||
|
if exp.id != resp.Results[i].ID() {
|
||||||
|
t.Fatalf("id not equal (expected: %v, got: %v)", exp.id, resp.Results[i].ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.createdTime != resp.Results[i].CreatedTime() {
|
||||||
|
t.Fatalf("createdTime not equal (expected: %v, got: %v)", exp.createdTime, resp.Results[i].CreatedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.lastEditedTime != resp.Results[i].LastEditedTime() {
|
||||||
|
t.Fatalf("lastEditedTime not equal (expected: %v, got: %v)", exp.lastEditedTime, resp.Results[i].LastEditedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.hasChildren != resp.Results[i].HasChildren() {
|
||||||
|
t.Fatalf("hasChildren not equal (expected: %v, got: %v)", exp.hasChildren, resp.Results[i].HasChildren())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.archived != resp.Results[i].Archived() {
|
||||||
|
t.Fatalf("archived not equal (expected: %v, got: %v)", exp.archived, resp.Results[i].Archived())
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3059,6 +3085,14 @@ func TestFindBlockChildrenById(t *testing.T) {
|
|||||||
func TestAppendBlockChildren(t *testing.T) {
|
func TestAppendBlockChildren(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
type blockFields struct {
|
||||||
|
id string
|
||||||
|
createdTime time.Time
|
||||||
|
lastEditedTime time.Time
|
||||||
|
hasChildren bool
|
||||||
|
archived bool
|
||||||
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
children []notion.Block
|
children []notion.Block
|
||||||
@ -3066,14 +3100,13 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
respStatusCode int
|
respStatusCode int
|
||||||
expPostBody map[string]interface{}
|
expPostBody map[string]interface{}
|
||||||
expResponse notion.BlockChildrenResponse
|
expResponse notion.BlockChildrenResponse
|
||||||
|
expBlockFields []blockFields
|
||||||
expError error
|
expError error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "successful response",
|
name: "successful response",
|
||||||
children: []notion.Block{
|
children: []notion.Block{
|
||||||
{
|
¬ion.ParagraphBlock{
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Text: ¬ion.Text{
|
Text: ¬ion.Text{
|
||||||
@ -3083,7 +3116,6 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
respBody: func(_ *http.Request) io.Reader {
|
respBody: func(_ *http.Request) io.Reader {
|
||||||
return strings.NewReader(
|
return strings.NewReader(
|
||||||
`{
|
`{
|
||||||
@ -3128,8 +3160,6 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
expPostBody: map[string]interface{}{
|
expPostBody: map[string]interface{}{
|
||||||
"children": []interface{}{
|
"children": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"object": "block",
|
|
||||||
"type": "paragraph",
|
|
||||||
"paragraph": map[string]interface{}{
|
"paragraph": map[string]interface{}{
|
||||||
"text": []interface{}{
|
"text": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -3144,13 +3174,7 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
},
|
},
|
||||||
expResponse: notion.BlockChildrenResponse{
|
expResponse: notion.BlockChildrenResponse{
|
||||||
Results: []notion.Block{
|
Results: []notion.Block{
|
||||||
{
|
¬ion.ParagraphBlock{
|
||||||
Object: "block",
|
|
||||||
ID: "ae9c9a31-1c1e-4ae2-a5ee-c539a2d43113",
|
|
||||||
CreatedTime: notion.TimePtr(mustParseTime(time.RFC3339Nano, "2021-05-14T09:15:00.000Z")),
|
|
||||||
LastEditedTime: notion.TimePtr(mustParseTime(time.RFC3339Nano, "2021-05-14T09:15:00.000Z")),
|
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Type: notion.RichTextTypeText,
|
Type: notion.RichTextTypeText,
|
||||||
@ -3165,18 +3189,24 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
HasMore: true,
|
HasMore: true,
|
||||||
NextCursor: notion.StringPtr("A^hd"),
|
NextCursor: notion.StringPtr("A^hd"),
|
||||||
},
|
},
|
||||||
|
expBlockFields: []blockFields{
|
||||||
|
{
|
||||||
|
id: "ae9c9a31-1c1e-4ae2-a5ee-c539a2d43113",
|
||||||
|
createdTime: mustParseTime(time.RFC3339, "2021-05-14T09:15:00.000Z"),
|
||||||
|
lastEditedTime: mustParseTime(time.RFC3339, "2021-05-14T09:15:00.000Z"),
|
||||||
|
hasChildren: false,
|
||||||
|
archived: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
expError: nil,
|
expError: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "error response",
|
name: "error response",
|
||||||
children: []notion.Block{
|
children: []notion.Block{
|
||||||
{
|
¬ion.ParagraphBlock{
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Text: ¬ion.Text{
|
Text: ¬ion.Text{
|
||||||
@ -3186,7 +3216,6 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
respBody: func(_ *http.Request) io.Reader {
|
respBody: func(_ *http.Request) io.Reader {
|
||||||
return strings.NewReader(
|
return strings.NewReader(
|
||||||
`{
|
`{
|
||||||
@ -3201,8 +3230,6 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
expPostBody: map[string]interface{}{
|
expPostBody: map[string]interface{}{
|
||||||
"children": []interface{}{
|
"children": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
"object": "block",
|
|
||||||
"type": "paragraph",
|
|
||||||
"paragraph": map[string]interface{}{
|
"paragraph": map[string]interface{}{
|
||||||
"text": []interface{}{
|
"text": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -3268,9 +3295,35 @@ func TestAppendBlockChildren(t *testing.T) {
|
|||||||
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff := cmp.Diff(tt.expResponse, resp); diff != "" {
|
if diff := cmp.Diff(tt.expResponse, resp, cmpopts.IgnoreUnexported(notion.ParagraphBlock{})); diff != "" {
|
||||||
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(tt.expBlockFields) != len(resp.Results) {
|
||||||
|
t.Fatalf("expected %v result(s), got %v", len(tt.expBlockFields), len(resp.Results))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, exp := range tt.expBlockFields {
|
||||||
|
if exp.id != resp.Results[i].ID() {
|
||||||
|
t.Fatalf("id not equal (expected: %v, got: %v)", exp.id, resp.Results[i].ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.createdTime != resp.Results[i].CreatedTime() {
|
||||||
|
t.Fatalf("createdTime not equal (expected: %v, got: %v)", exp.createdTime, resp.Results[i].CreatedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.lastEditedTime != resp.Results[i].LastEditedTime() {
|
||||||
|
t.Fatalf("lastEditedTime not equal (expected: %v, got: %v)", exp.lastEditedTime, resp.Results[i].LastEditedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.hasChildren != resp.Results[i].HasChildren() {
|
||||||
|
t.Fatalf("hasChildren not equal (expected: %v, got: %v)", exp.hasChildren, resp.Results[i].HasChildren())
|
||||||
|
}
|
||||||
|
|
||||||
|
if exp.archived != resp.Results[i].Archived() {
|
||||||
|
t.Fatalf("archived not equal (expected: %v, got: %v)", exp.archived, resp.Results[i].Archived())
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3944,6 +3997,11 @@ func TestFindBlockByID(t *testing.T) {
|
|||||||
respBody func(r *http.Request) io.Reader
|
respBody func(r *http.Request) io.Reader
|
||||||
respStatusCode int
|
respStatusCode int
|
||||||
expBlock notion.Block
|
expBlock notion.Block
|
||||||
|
expID string
|
||||||
|
expCreatedTime time.Time
|
||||||
|
expLastEditedTime time.Time
|
||||||
|
expHasChildren bool
|
||||||
|
expArchived bool
|
||||||
expError error
|
expError error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -3966,16 +4024,14 @@ func TestFindBlockByID(t *testing.T) {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
respStatusCode: http.StatusOK,
|
respStatusCode: http.StatusOK,
|
||||||
expBlock: notion.Block{
|
expBlock: ¬ion.ChildPageBlock{
|
||||||
Object: "block",
|
Title: "test title",
|
||||||
ID: "048e165e-352d-4119-8128-e46c3527d95c",
|
|
||||||
Type: "child_page",
|
|
||||||
CreatedTime: mustParseTimePointer(time.RFC3339, "2021-10-02T06:09:00Z"),
|
|
||||||
LastEditedTime: mustParseTimePointer(time.RFC3339, "2021-10-02T06:31:00Z"),
|
|
||||||
HasChildren: true,
|
|
||||||
ChildPage: ¬ion.ChildPage{Title: "test title"},
|
|
||||||
Archived: notion.BoolPtr(false),
|
|
||||||
},
|
},
|
||||||
|
expID: "048e165e-352d-4119-8128-e46c3527d95c",
|
||||||
|
expCreatedTime: mustParseTime(time.RFC3339, "2021-10-02T06:09:00Z"),
|
||||||
|
expLastEditedTime: mustParseTime(time.RFC3339, "2021-10-02T06:31:00Z"),
|
||||||
|
expHasChildren: true,
|
||||||
|
expArchived: false,
|
||||||
expError: nil,
|
expError: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -3991,7 +4047,7 @@ func TestFindBlockByID(t *testing.T) {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
respStatusCode: http.StatusNotFound,
|
respStatusCode: http.StatusNotFound,
|
||||||
expBlock: notion.Block{},
|
expBlock: nil,
|
||||||
expError: errors.New("notion: failed to find block: Could not find block with ID: test id. (code: object_not_found, status: 404)"),
|
expError: errors.New("notion: failed to find block: Could not find block with ID: test id. (code: object_not_found, status: 404)"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -4023,9 +4079,31 @@ func TestFindBlockByID(t *testing.T) {
|
|||||||
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff := cmp.Diff(tt.expBlock, block); diff != "" {
|
if diff := cmp.Diff(tt.expBlock, block, cmpopts.IgnoreUnexported(notion.ChildPageBlock{})); diff != "" {
|
||||||
t.Fatalf("user not equal (-exp, +got):\n%v", diff)
|
t.Fatalf("user not equal (-exp, +got):\n%v", diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if block != nil {
|
||||||
|
if tt.expID != block.ID() {
|
||||||
|
t.Fatalf("id not equal (expected: %v, got: %v)", tt.expID, block.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expCreatedTime != block.CreatedTime() {
|
||||||
|
t.Fatalf("createdTime not equal (expected: %v, got: %v)", tt.expCreatedTime, block.CreatedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expLastEditedTime != block.LastEditedTime() {
|
||||||
|
t.Fatalf("lastEditedTime not equal (expected: %v, got: %v)", tt.expLastEditedTime, block.LastEditedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expHasChildren != block.HasChildren() {
|
||||||
|
t.Fatalf("hasChildren not equal (expected: %v, got: %v)", tt.expHasChildren, block.HasChildren())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expArchived != block.Archived() {
|
||||||
|
t.Fatalf("archived not equal (expected: %v, got: %v)", tt.expArchived, block.Archived())
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4040,12 +4118,16 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
respStatusCode int
|
respStatusCode int
|
||||||
expPostBody map[string]interface{}
|
expPostBody map[string]interface{}
|
||||||
expResponse notion.Block
|
expResponse notion.Block
|
||||||
|
expID string
|
||||||
|
expCreatedTime time.Time
|
||||||
|
expLastEditedTime time.Time
|
||||||
|
expHasChildren bool
|
||||||
|
expArchived bool
|
||||||
expError error
|
expError error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "successful response",
|
name: "successful response",
|
||||||
block: notion.Block{
|
block: ¬ion.ParagraphBlock{
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Text: ¬ion.Text{
|
Text: ¬ion.Text{
|
||||||
@ -4054,7 +4136,6 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
respBody: func(_ *http.Request) io.Reader {
|
respBody: func(_ *http.Request) io.Reader {
|
||||||
return strings.NewReader(
|
return strings.NewReader(
|
||||||
`{
|
`{
|
||||||
@ -4091,7 +4172,6 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
respStatusCode: http.StatusOK,
|
respStatusCode: http.StatusOK,
|
||||||
expPostBody: map[string]interface{}{
|
expPostBody: map[string]interface{}{
|
||||||
"object": "block",
|
|
||||||
"paragraph": map[string]interface{}{
|
"paragraph": map[string]interface{}{
|
||||||
"text": []interface{}{
|
"text": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -4102,14 +4182,7 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expResponse: notion.Block{
|
expResponse: ¬ion.ParagraphBlock{
|
||||||
Object: "block",
|
|
||||||
ID: "048e165e-352d-4119-8128-e46c3527d95c",
|
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
CreatedTime: mustParseTimePointer(time.RFC3339, "2021-10-02T06:09:00Z"),
|
|
||||||
LastEditedTime: mustParseTimePointer(time.RFC3339, "2021-10-02T06:31:00Z"),
|
|
||||||
HasChildren: true,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Type: notion.RichTextTypeText,
|
Type: notion.RichTextTypeText,
|
||||||
@ -4123,14 +4196,16 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Archived: notion.BoolPtr(false),
|
expID: "048e165e-352d-4119-8128-e46c3527d95c",
|
||||||
},
|
expCreatedTime: mustParseTime(time.RFC3339, "2021-10-02T06:09:00Z"),
|
||||||
|
expLastEditedTime: mustParseTime(time.RFC3339, "2021-10-02T06:31:00Z"),
|
||||||
|
expHasChildren: true,
|
||||||
|
expArchived: false,
|
||||||
expError: nil,
|
expError: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "error response",
|
name: "error response",
|
||||||
block: notion.Block{
|
block: ¬ion.ParagraphBlock{
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Text: ¬ion.Text{
|
Text: ¬ion.Text{
|
||||||
@ -4139,7 +4214,6 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
|
||||||
respBody: func(_ *http.Request) io.Reader {
|
respBody: func(_ *http.Request) io.Reader {
|
||||||
return strings.NewReader(
|
return strings.NewReader(
|
||||||
`{
|
`{
|
||||||
@ -4152,7 +4226,6 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
respStatusCode: http.StatusBadRequest,
|
respStatusCode: http.StatusBadRequest,
|
||||||
expPostBody: map[string]interface{}{
|
expPostBody: map[string]interface{}{
|
||||||
"object": "block",
|
|
||||||
"paragraph": map[string]interface{}{
|
"paragraph": map[string]interface{}{
|
||||||
"text": []interface{}{
|
"text": []interface{}{
|
||||||
map[string]interface{}{
|
map[string]interface{}{
|
||||||
@ -4163,7 +4236,7 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
expResponse: notion.Block{},
|
expResponse: nil,
|
||||||
expError: errors.New("notion: failed to update block: foobar (code: validation_error, status: 400)"),
|
expError: errors.New("notion: failed to update block: foobar (code: validation_error, status: 400)"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -4216,9 +4289,31 @@ func TestUpdateBlock(t *testing.T) {
|
|||||||
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff := cmp.Diff(tt.expResponse, updatedBlock); diff != "" {
|
if diff := cmp.Diff(tt.expResponse, updatedBlock, cmpopts.IgnoreUnexported(notion.ParagraphBlock{})); diff != "" {
|
||||||
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if updatedBlock != nil {
|
||||||
|
if tt.expID != updatedBlock.ID() {
|
||||||
|
t.Fatalf("id not equal (expected: %v, got: %v)", tt.expID, updatedBlock.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expCreatedTime != updatedBlock.CreatedTime() {
|
||||||
|
t.Fatalf("createdTime not equal (expected: %v, got: %v)", tt.expCreatedTime, updatedBlock.CreatedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expLastEditedTime != updatedBlock.LastEditedTime() {
|
||||||
|
t.Fatalf("lastEditedTime not equal (expected: %v, got: %v)", tt.expLastEditedTime, updatedBlock.LastEditedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expHasChildren != updatedBlock.HasChildren() {
|
||||||
|
t.Fatalf("hasChildren not equal (expected: %v, got: %v)", tt.expHasChildren, updatedBlock.HasChildren())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expArchived != updatedBlock.Archived() {
|
||||||
|
t.Fatalf("archived not equal (expected: %v, got: %v)", tt.expArchived, updatedBlock.Archived())
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4231,6 +4326,11 @@ func TestDeleteBlock(t *testing.T) {
|
|||||||
respBody func(r *http.Request) io.Reader
|
respBody func(r *http.Request) io.Reader
|
||||||
respStatusCode int
|
respStatusCode int
|
||||||
expResponse notion.Block
|
expResponse notion.Block
|
||||||
|
expID string
|
||||||
|
expCreatedTime time.Time
|
||||||
|
expLastEditedTime time.Time
|
||||||
|
expHasChildren bool
|
||||||
|
expArchived bool
|
||||||
expError error
|
expError error
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
@ -4270,14 +4370,7 @@ func TestDeleteBlock(t *testing.T) {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
respStatusCode: http.StatusOK,
|
respStatusCode: http.StatusOK,
|
||||||
expResponse: notion.Block{
|
expResponse: ¬ion.ParagraphBlock{
|
||||||
Object: "block",
|
|
||||||
ID: "048e165e-352d-4119-8128-e46c3527d95c",
|
|
||||||
Type: notion.BlockTypeParagraph,
|
|
||||||
CreatedTime: mustParseTimePointer(time.RFC3339, "2021-10-02T06:09:00Z"),
|
|
||||||
LastEditedTime: mustParseTimePointer(time.RFC3339, "2021-10-02T06:31:00Z"),
|
|
||||||
HasChildren: true,
|
|
||||||
Paragraph: ¬ion.RichTextBlock{
|
|
||||||
Text: []notion.RichText{
|
Text: []notion.RichText{
|
||||||
{
|
{
|
||||||
Type: notion.RichTextTypeText,
|
Type: notion.RichTextTypeText,
|
||||||
@ -4291,8 +4384,11 @@ func TestDeleteBlock(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Archived: notion.BoolPtr(true),
|
expID: "048e165e-352d-4119-8128-e46c3527d95c",
|
||||||
},
|
expCreatedTime: mustParseTime(time.RFC3339, "2021-10-02T06:09:00Z"),
|
||||||
|
expLastEditedTime: mustParseTime(time.RFC3339, "2021-10-02T06:31:00Z"),
|
||||||
|
expHasChildren: true,
|
||||||
|
expArchived: true,
|
||||||
expError: nil,
|
expError: nil,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -4308,7 +4404,7 @@ func TestDeleteBlock(t *testing.T) {
|
|||||||
)
|
)
|
||||||
},
|
},
|
||||||
respStatusCode: http.StatusBadRequest,
|
respStatusCode: http.StatusBadRequest,
|
||||||
expResponse: notion.Block{},
|
expResponse: nil,
|
||||||
expError: errors.New("notion: failed to delete block: foobar (code: validation_error, status: 400)"),
|
expError: errors.New("notion: failed to delete block: foobar (code: validation_error, status: 400)"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -4340,9 +4436,31 @@ func TestDeleteBlock(t *testing.T) {
|
|||||||
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
t.Fatalf("error not equal (expected: %v, got: %v)", tt.expError, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if diff := cmp.Diff(tt.expResponse, deletedBlock); diff != "" {
|
if diff := cmp.Diff(tt.expResponse, deletedBlock, cmpopts.IgnoreUnexported(notion.ParagraphBlock{})); diff != "" {
|
||||||
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
t.Fatalf("response not equal (-exp, +got):\n%v", diff)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if deletedBlock != nil {
|
||||||
|
if tt.expID != deletedBlock.ID() {
|
||||||
|
t.Fatalf("id not equal (expected: %v, got: %v)", tt.expID, deletedBlock.ID())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expCreatedTime != deletedBlock.CreatedTime() {
|
||||||
|
t.Fatalf("createdTime not equal (expected: %v, got: %v)", tt.expCreatedTime, deletedBlock.CreatedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expLastEditedTime != deletedBlock.LastEditedTime() {
|
||||||
|
t.Fatalf("lastEditedTime not equal (expected: %v, got: %v)", tt.expLastEditedTime, deletedBlock.LastEditedTime())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expHasChildren != deletedBlock.HasChildren() {
|
||||||
|
t.Fatalf("hasChildren not equal (expected: %v, got: %v)", tt.expHasChildren, deletedBlock.HasChildren())
|
||||||
|
}
|
||||||
|
|
||||||
|
if tt.expArchived != deletedBlock.Archived() {
|
||||||
|
t.Fatalf("archived not equal (expected: %v, got: %v)", tt.expArchived, deletedBlock.Archived())
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user