NotionRubyMapping のアップデート(22) : hkob の雑記録 (181)

はじめに

hkob の雑記録の第181回目は、昨日作成した外部URLからファイルをアップロードするためのテストデータを使って、テストと実装を追記します。

status の追加

外部ファイルからの取り込みを行った場合、アップロード完了を status で確認する必要があります。このため、FileUploadObject@status を保持するようにしました。まずテストでこれまでの二つの場合でも status をチェックするようにしました。

      context "with a small file" do
        (中略)
        it { expect(subject.id).to eq id }
        it { expect(subject.status).to eq "pending" }
      end

      context "with a large file" do
        (中略)
        it { expect(subject.id).to eq id }
        it { expect(subject.status).to eq "pending" }
      end

attr_reader:status を追加すると同時に、create 時に response から status を取得します。

  attr_reader :id, :fname, :status

  # @return [FileUploadObject]
  def create(payload)
    nc = NotionRubyMapping::NotionCache.instance
    response = nc.create_file_upload_request(payload)
    @id = nc.hex_id response["id"]
    @status = response["status"]
  end

with an external file のテスト追加

外部ファイルに対する FileUploadObjectnew のテストを追加します。アップロード後は pending ですが、reload したら uploaded に変わるシーケンスをテストします。

      context "with an external file" do
        let(:fname) { "dummy.pdf" }
        let(:id) { TestConnection::FILE_UPLOAD_PDF_ID }
        let(:external_url) { "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" }

        subject { described_class.new fname: fname, external_url: external_url }
        it { expect(subject.id).to eq id }
        it { expect(subject.status).to eq "pending" }
        it { expect(subject.reload.status).to eq "uploaded" }
      end

external_url に対する処理を書こうと思っていたら、すでに記載済でした。

  def initialize(fname:, external_url: nil)
    @fname = fname
    if external_url
      payload = {mode: "external_url", external_url: external_url, filename: fname}
      create payload
    else
      (中略)
    end
  end
  

WebMock の準備

コードは動作しますが、Web アクセスの stub がなくてエラーになっています。external_url の stub を以下のように準備しました。

    def create_file_upload
      generate_stubs_sub :post, __method__, :file_uploads_path, {
        image: [nil, 200, {}],
        video: [nil, 200, {"number_of_parts" => 2, "mode" => "multi_part", "filename" => "sample-15s.mp4"}],
        external_url: [nil, 200,
                       {
                         "mode" => "external_url",
                         "external_url" => "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
                         "filename" => "dummy.pdf",
                       }],
      }
    end

reload の実装

reload では FileUploadObject の読み込みが必要です。Rails 的な流れだと show に相当するので file_upload_request ですが、すでに使ってしまっていました。そこで、single_file_upload の方を send_file_upload_request に名称変更しました。

  def single_file_upload(fname = @fname, part_number = 0)
    (中略)
    response = nc.send_file_upload_request fname, @id, options
    (中略)
  end

Notioncache の該当部分の修正

これに合わせて、これまでのメソッド名の修正をします。send_file_upload_path というのも Rails way になっていますね。

    # @param [String] fname
    # @param [String] id
    # @param [Hash] options
    # @return [Hash]
    def send_file_upload_request(fname, id, options = {})
      multipart_request(send_file_upload_path(id), fname, options)
    end

    # @param [String] id
    # @return [String]
    def send_file_upload_path(id)
      "v1/file_uploads/#{id}/send"
    end

代わりに今回の retrieve のためのメソッドである file_upload_requestfile_upload_path を追加します。

    def file_upload_request(file_id)
      request :get, file_upload_path(file_id)
    end

    def file_upload_path(file_id)
      "v1/file_uploads/#{file_id}"
    end

ここまで準備すれば reload は簡単です。

  def reload
    nc = NotionRubyMapping::NotionCache.instance
    response = nc.file_upload_request @id
    @status = response["status"]
    self
  end

おわりに

これで reload 後の statusunloaded になるまで reload によるポーリングなどで待てばいいと思います。

hkob.notion.site