sup

A curses threads-with-tags style email client

sup.git

git clone https://supmua.dev/git/sup/

test/integration/test_draft.rb (4094B) - raw

      1 require "sup"
      2 require "test_helper"
      3 
      4 class TestDraft < Minitest::Test
      5   include Redwood
      6 
      7   def setup
      8     @path = Dir.mktmpdir
      9     start
     10     @draft_dir = File.join @path, "drafts"
     11     @test_message_1 = <<EOS
     12 From: Some Person <someone@example.invalid>
     13 To:
     14 Cc:
     15 Bcc:
     16 Subject: draft
     17 Date: Fri, 11 Apr 2025 22:34:05 +1000
     18 Message-ID: <123@example.invalid>
     19 
     20 My incomplete message
     21 EOS
     22     DraftManager.instance.instance_eval "@dir = '#{@draft_dir}'"
     23     Index.init @path
     24     Index.load
     25     SourceManager.instance.instance_eval "@sources = {}"
     26     @draft_source = DraftManager.new_source
     27     SourceManager.add_source @draft_source
     28   end
     29 
     30   def teardown
     31     ObjectSpace.each_object(Class).select {|a| a < Redwood::Singleton}.each do |klass|
     32       klass.deinstantiate! unless klass == Redwood::Logger
     33     end
     34     FileUtils.rm_r @path
     35   end
     36 
     37   def test_write_draft
     38     DraftManager.write_draft { |f| f.write @test_message_1 }
     39 
     40     draft_filename = File.join @draft_dir, "0"
     41     assert File.exist? draft_filename
     42     assert_equal @test_message_1, (File.read draft_filename)
     43 
     44     ## Check that it is loaded back into the index successfully too.
     45     messages_in_index = Index.instance.enum_for(:each_message).to_a
     46     assert_equal @test_message_1, messages_in_index.first.raw_message
     47     assert_equal [:draft, :inbox].to_set, messages_in_index.first.labels
     48   end
     49 
     50   def test_discard_draft
     51     DraftManager.write_draft { |f| f.write @test_message_1 }
     52     draft_filename = File.join @draft_dir, "0"
     53     assert File.exist? draft_filename
     54     message_in_index = Index.instance.enum_for(:each_message).to_a.first
     55 
     56     DraftManager.discard message_in_index
     57     refute File.exist? draft_filename
     58   end
     59 
     60   def test_discard_already_deleted_from_disk
     61     DraftManager.write_draft { |f| f.write @test_message_1 }
     62     draft_filename = File.join @draft_dir, "0"
     63     assert File.exist? draft_filename
     64     message_in_index = Index.instance.enum_for(:each_message).to_a.first
     65 
     66     File.delete draft_filename
     67 
     68     DraftManager.discard message_in_index
     69     refute File.exist? draft_filename
     70   end
     71 
     72   def test_load_malformed_draft
     73     ## Sup always writes drafts by serialising a Message, meaning the draft is
     74     ## guaranteed to have certain headers like Date. But it's always possible
     75     ## for the user to edit the draft directly on the filesystem and leave it
     76     ## in some kind of malformed state. Sup should handle it without crashing.
     77     draft_filename = File.join @draft_dir, "0"
     78     fallback_date = Time.new 2025, 5, 3, 15, 47, 41
     79     File.write draft_filename, <<EOS
     80 Some-Header: Value
     81 
     82 body
     83 EOS
     84     File.utime fallback_date, fallback_date, draft_filename
     85     PollManager.poll_from @draft_source
     86     messages_in_index = Index.instance.enum_for(:each_message).to_a
     87     assert_equal "", messages_in_index[0].subj
     88     assert_equal fallback_date, messages_in_index[0].date
     89 
     90     File.write (File.join @draft_dir, "1"), <<EOS
     91 missing a header!
     92 EOS
     93     PollManager.poll_from @draft_source
     94     messages_in_index = Index.instance.enum_for(:each_message).to_a
     95     assert_equal "", messages_in_index[0].subj
     96 
     97     File.write (File.join @draft_dir, "2"), ""
     98     PollManager.poll_from @draft_source
     99     messages_in_index = Index.instance.enum_for(:each_message).to_a
    100     assert_equal "", messages_in_index[0].subj
    101   end
    102 
    103   def test_draft_with_non_ascii_chars
    104     message = <<EOS
    105 From: Some Person <someone@example.invalid>
    106 To:
    107 Cc:
    108 Bcc:
    109 Subject: UTF-8 draft 🤐
    110 Date: Fri, 11 Apr 2025 22:34:05 +1000
    111 Message-ID: <123@example.invalid>
    112 
    113 ¡Buen día! Доброго ранку! おはよう!
    114 EOS
    115     DraftManager.write_draft { |f| f.write message }
    116     draft_filename = File.join @draft_dir, "0"
    117     assert_equal message, (File.read draft_filename)
    118 
    119     PollManager.poll_from @draft_source
    120     messages_in_index = Index.instance.enum_for(:each_message).to_a
    121     assert_equal "UTF-8 draft 🤐", messages_in_index[0].subj
    122     assert_equal message, messages_in_index.first.raw_message
    123     assert_equal "¡Buen día! Доброго ранку! おはよう!", \
    124                  messages_in_index[0].chunks[0].lines[0]
    125   end
    126 end