(99.44% coverage) TODO: Need to reset current draft when a draft is signed/committed to the log
This commit is contained in:
parent
7568d0412e
commit
f4b6ddbf51
|
@ -36,5 +36,5 @@ Eg: `pigeon identity show` becomes `./pigeon-cli show`.
|
|||
- [ ] add parsers and validators for all CLI inputs
|
||||
- [ ] Performance benchmarks
|
||||
- [ ] Performance tuning (DO THIS LAST!)
|
||||
|
||||
- [ ] Add Lipmaa links like the Bamboo folks do.
|
||||
- [ ] Update spec to look [like this](https://gist.github.com/RickCarlino/3ff4178db4a75fd135832c403cd313d4)
|
||||
|
|
|
@ -32,6 +32,7 @@ module Pigeon
|
|||
USER_NS = "user"
|
||||
BLCK_NS = "blocked"
|
||||
MESG_NS = "messages"
|
||||
DEPTH_INDEX_NS = "messages.by_depth"
|
||||
|
||||
# ^ Internal namespaces for PStore keys
|
||||
|
||||
|
|
|
@ -2,62 +2,42 @@ require "digest"
|
|||
|
||||
module Pigeon
|
||||
class Message
|
||||
attr_reader :author, :kind, :body, :signature
|
||||
attr_reader :author, :kind, :body, :signature, :depth, :prev
|
||||
|
||||
def self.from_draft(draft, author: KeyPair.current)
|
||||
self.new(author: KeyPair.current,
|
||||
kind: draft.kind,
|
||||
body: draft.body).save
|
||||
end
|
||||
|
||||
def initialize(author:, kind:, body: )
|
||||
@author = author
|
||||
@kind = kind
|
||||
@body = body
|
||||
end
|
||||
|
||||
def save
|
||||
Pigeon::Storage.current.set_config(CURRENT_DRAFT, self)
|
||||
self
|
||||
body: draft.body)
|
||||
end
|
||||
|
||||
def sign
|
||||
store = Pigeon::Storage.current
|
||||
@signature = calculate_signature
|
||||
@depth = Pigeon::Storage.current.message_count
|
||||
@saved = true
|
||||
@depth = store.message_count
|
||||
@prev = store.get_message_by_depth(@depth - 1)
|
||||
self.freeze
|
||||
Pigeon::Storage.current.save_message(self)
|
||||
Pigeon::Message.reset_current
|
||||
@signature
|
||||
store.save_message(self)
|
||||
self
|
||||
end
|
||||
|
||||
def render
|
||||
Template.new(self).render
|
||||
end
|
||||
|
||||
def depth
|
||||
calculate_depth
|
||||
end
|
||||
|
||||
def prev
|
||||
if @saved
|
||||
previous_message
|
||||
else
|
||||
raise Pigeon::PREV_REQUIRES_SAVE
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def initialize(author:, kind:, body:)
|
||||
@author = author
|
||||
@kind = kind
|
||||
@body = body
|
||||
# Side effects in a constructor? Hmm...
|
||||
sign
|
||||
end
|
||||
|
||||
def calculate_signature
|
||||
template = Template.new(self)
|
||||
string = template.render_without_signature
|
||||
KeyPair.current.sign(string)
|
||||
end
|
||||
|
||||
def previous_message
|
||||
raise "TODO - I need to create a `Pigeon::Index` class or something. " \
|
||||
"need a way to index messages by: signature, depth"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,12 +21,12 @@ module Pigeon
|
|||
private
|
||||
|
||||
def do_render(template)
|
||||
author = message.author
|
||||
author = message.author.public_key
|
||||
body = message.body
|
||||
depth = message.depth
|
||||
kind = message.kind
|
||||
depth = message.depth || "NONE"
|
||||
prev = message.saved? ? message.prev : "NONE"
|
||||
signature = message.signature || "NONE"
|
||||
prev = message.prev || "NONE"
|
||||
signature = message.signature
|
||||
|
||||
ERB.new(template).result(binding)
|
||||
end
|
||||
|
|
|
@ -11,19 +11,27 @@ module Pigeon
|
|||
@current ||= self.new
|
||||
end
|
||||
|
||||
# def message_count
|
||||
# store.transaction do
|
||||
# store[MESG_NS] ||= {}
|
||||
# store[MESG_NS].count
|
||||
# end
|
||||
# end
|
||||
def get_message_by_depth(depth)
|
||||
store.transaction do
|
||||
# Map<Integer, Signature>
|
||||
index = store[DEPTH_INDEX_NS] ||= {}
|
||||
index[depth]
|
||||
end
|
||||
end
|
||||
|
||||
# def save_message(msg)
|
||||
# store.transaction do
|
||||
# store[MESG_NS] ||= {}
|
||||
# store[MESG_NS][msg.depth || -100] = msg
|
||||
# end
|
||||
# end
|
||||
def message_count
|
||||
store.transaction do
|
||||
index = store[MESG_NS] ||= {}
|
||||
index.count
|
||||
end
|
||||
end
|
||||
|
||||
def save_message(msg)
|
||||
store.transaction do
|
||||
store[MESG_NS] ||= {}
|
||||
store[MESG_NS][msg.signature] = msg
|
||||
end
|
||||
end
|
||||
|
||||
def set_config(key, value)
|
||||
store.transaction do
|
||||
|
|
|
@ -97,7 +97,7 @@ module Pigeon
|
|||
desc "sign", "Commit current DRAFT to local feed."
|
||||
|
||||
def sign
|
||||
puts Pigeon::Draft.current.sign.render
|
||||
raise "Work in progress! under_construction.gif"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
BEFORE DELETING CONSTANTS:
|
||||
==========================
|
||||
rspec ./spec/pigeon/kitchen_sink_spec.rb:4 # Kitch sink spec does everything
|
||||
rspec ./spec/pigeon/storage_spec.rb:15 # Pigeon::Storage deletes a config
|
||||
rspec ./spec/pigeon/storage_spec.rb:34 # Pigeon::Storage manages blobs
|
||||
rspec ./spec/pigeon/storage_spec.rb:41 # Pigeon::Storage manages peers
|
||||
rspec ./spec/pigeon/storage_spec.rb:26 # Pigeon::Storage manages configs
|
||||
rspec ./spec/pigeon/key_pair_spec.rb:36 # Pigeon::KeyPair saves to disk
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
require "spec_helper"
|
||||
|
||||
RSpec.describe Pigeon::Message do
|
||||
before(:each) do
|
||||
Pigeon::Storage.reset
|
||||
Pigeon::KeyPair.reset
|
||||
end
|
||||
|
||||
let(:draft) do
|
||||
draft = Pigeon::Draft.create(kind: "unit_test")
|
||||
hash = Pigeon::Storage.current.set_blob(File.read("./logo.png"))
|
||||
draft["a"] = "bar"
|
||||
draft["b"] = hash
|
||||
draft
|
||||
end
|
||||
|
||||
it "creates a single message" do
|
||||
message = Pigeon::Message.from_draft(draft)
|
||||
expect(message.author).to eq(Pigeon::KeyPair.current)
|
||||
expect(message.body).to eq(draft.body)
|
||||
expect(message.depth).to eq(0)
|
||||
expect(message.kind).to eq("unit_test")
|
||||
expect(message.prev).to eq(nil)
|
||||
expect(message.signature.include?(".sig.ed25519")).to eq(true)
|
||||
expect(message.signature.length).to be > 99
|
||||
actual = message.render
|
||||
expected = [
|
||||
"author __AUTHOR__",
|
||||
"kind unit_test",
|
||||
"prev NONE",
|
||||
"depth 0",
|
||||
"",
|
||||
"a:\"bar\"",
|
||||
"b:&6462a5f5174b53702fc25afe67a8f9a29f572610a65bafefff627531552f096f.sha256",
|
||||
"",
|
||||
"signature __SIGNATURE__ \n",
|
||||
].join("\n")
|
||||
.gsub("__AUTHOR__", message.author.public_key)
|
||||
.gsub("__SIGNATURE__", message.signature)
|
||||
expect(actual).to eq(expected)
|
||||
end
|
||||
|
||||
it "creates a chain of messages"
|
||||
end
|
|
@ -11,8 +11,14 @@ RSpec.describe Pigeon::Template do
|
|||
BOTTOM_HALF = "signature XYZ.sig.sha256 \n"
|
||||
EXPECTED_DRAFT = TOP_HALF + BOTTOM_HALF
|
||||
|
||||
class FakeKeypair
|
||||
def self.public_key
|
||||
"FAKE_AUTHOR"
|
||||
end
|
||||
end
|
||||
|
||||
it "renders a draft" do
|
||||
args = ["FAKE_AUTHOR",
|
||||
args = [FakeKeypair,
|
||||
{ foo: "bar".inspect },
|
||||
"FAKE_KIND",
|
||||
23,
|
||||
|
|
Loading…
Reference in New Issue