はじめに
hkob の雑記録の第388回目(通算785日目)は、NotionRubyMapping に position object を追加します。今月、Create a page の際に position object を指定できるようになりました。詳しくは1月21日の記事で解説しています。今日は、この実装をするためのテストデータを作成します。
Create a Page の position object : hkob の雑記録 (386) - hkob’s blog
テストページの作成
まず、テスト用のページを作成します。ページの中身は何もないところから始めます。

page_end への追加
まず、page_end への追加を行います。スクリプトは以下のようになります。ページ内へのページ追加となるので、title プロパティしかありません。この場合の識別子は title となります。このことを Notion API 活用術に書いてなかった気がします。追加しておきましょう。position object を省略した時は page_end になるので、わざわざ記述する必要はないのですが、フレームワークとしては対応する必要があるでしょう。 create_page_page_end.sh は以下のようになります。
curl 'https://api.notion.com/v1/pages' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H "Content-Type: application/json" \ -H "Notion-Version: 2025-09-03" \ --data '{ "parent": { "type": "page_id", "page_id": "2f0d8e4e98ab8065b3a2ec9fd4b3e57a" }, "properties": { "title": { "type": "title", "title": [ { "type": "text", "text": { "content": "New Page at page_end", "link": null }, "plain_text": "New Page at page_end", "href": null } ] } }, "position": { "type": "page_end" } }'
実行するとページ下部にページが作成されました。

page_start への追加
これまでできなかったページトップへの追加です。当然 page_start に変更するだけです。
curl 'https://api.notion.com/v1/pages' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H "Content-Type: application/json" \ -H "Notion-Version: 2025-09-03" \ --data '{ "parent": { "type": "page_id", "page_id": "2f0d8e4e98ab8065b3a2ec9fd4b3e57a" }, "properties": { "title": { "type": "title", "title": [ { "type": "text", "text": { "content": "New Page at page_start", "link": null }, "plain_text": "New Page at page_start", "href": null } ] } }, "position": { "type": "page_start" } }'
問題なくページのトップに作成されました。

after_block への追加
page_start で作成したページの id を使って、after_block のテストを作成します。
curl 'https://api.notion.com/v1/pages' \ -H 'Authorization: Bearer '"$NOTION_API_KEY"'' \ -H "Content-Type: application/json" \ -H "Notion-Version: 2025-09-03" \ --data '{ "parent": { "type": "page_id", "page_id": "2f0d8e4e98ab8065b3a2ec9fd4b3e57a" }, "properties": { "title": { "type": "title", "title": [ { "type": "text", "text": { "content": "New Page at after_block", "link": null }, "plain_text": "New Page at after_block", "href": null } ] } }, "position": { "type": "after_block", "after_block": { "id": "2f0d8e4e-98ab-812c-a8f5-cce62b2d3f6e" } } }'
実行すると page_start と page_end の中間にページが作成されました。

テストの作成
テストデータを作成しただけで終わってしまうと短すぎるので、テストまで記載してしまいましょう。まず、親ページの PAGE_ID を定義しておきます。
describe "position object for create a page" do let(:ppid) { TestConnection::POSITION_TEST_PARENT_PAGE_ID } let(:parent_page) { Page.new id: ppid } [ ["page_end", "page_end", {"type" => "page_end"}, TestConnection::POSITION_TEST_PAGE_END_ID], ["page_start", "page_start", {"type" => "page_start"}, TestConnection::POSITION_TEST_PAGE_START_ID], ["after_block", TestConnection::POSITION_TEST_PAGE_START_ID, {"type" => "after_block", "after_block" => {"id" => TestConnection::POSITION_TEST_PAGE_START_ID}}, TestConnection::POSITION_TEST_AFTER_BLOCK_ID], ].each do |(key, value, position, id)| context "when it creates at #{key}" do let(:title) { "New Page at #{key}" } context "when not dry_run" do let(:target) do parent_page.create_child_page position: value do |_, pp| pp["title"] << title end end it { expect(target.id).to eq id } it { expect(nc.hex_id(target.parent_id)).to eq ppid } end context "when dry_run" do let(:dry_run) do parent_page.create_child_page position: value, dry_run: true do |_, pp| pp["title"] << title end end it_behaves_like "dry run", :post, :pages_path, json: { "properties" => { "title" => { "type" => "title", "title" => [ { "type" => "text", "text" => { "content" => "New Page at #{key}", "link" => nil, }, "plain_text" => "New Page at #{key}", "href" => nil, }, ], }, }, "parent" => { "type" => "page_id", "page_id" => TestConnection::POSITION_TEST_PARENT_PAGE_ID, }, "position" => position, } end end end end
3つのケースに対してはテスト部分は共通なので、変化分のみをパラメータとして括り出し、3回テストを実行するようにしています。それぞれ実際に WebMock を使った場合と dry_run のスクリプト出力結果をテストしています。
テスト結果
テストを実行したところ、create_child_page が実装されていないということに、今気づきました。データソース内にページを作成する実装はしていたものの、ページ内にページを追加するメソッドを忘れていたようです。これを忘れていたから、Notion API 活用術でも title の表記を忘れていたのですね。Page の下に Page を作成する場合は、Title property しか存在せず title 以外の文字列は設定できないので、自動的に用意されることにします。上のテストではそれを踏まえて TitleProperty の作成部分を消してしまいました。
NoMethodError: undefined method 'create_child_page' for an instance of NotionRubyMapping::Page Shared Example Group: "dry run" called from ./spec/notion_ruby_mapping/blocks/page_spec.rb:1206 # ./spec/notion_ruby_mapping/blocks/page_spec.rb:1201:in 'block (6 levels) in <module:NotionRubyMapping>' # ./spec/spec_helper.rb:3020:in 'block (2 levels) in <module:RSpec>' Finished in 1.09 seconds (files took 1.02 seconds to load) 3012 examples, 9 failures
おわりに
これまで Page 内に Page を作成することをしていなかったので、実装漏れに全く気づいていませんでした。明日は Notion 座談会なので、土曜日に実装することにします。だいぶアップデートもたまったので、今回の実装が完了したらバージョンアップをリリースすることにしましょう。