Skip to content

Instantly share code, notes, and snippets.

@jszmajda
Created October 17, 2011 22:16
Show Gist options
  • Select an option

  • Save jszmajda/1294014 to your computer and use it in GitHub Desktop.

Select an option

Save jszmajda/1294014 to your computer and use it in GitHub Desktop.
A potential spec for a ruby X.commerce gem

Overview

This is a rough spec for a gem I would like to use to connect to X.commerce. As X.commerce is new and my experience with it is limited, I'd like to discuss with the community first how best to structure the interaction before actual code is written.

Structure

I've spec'd out the following basic object structure:

module XCommerce
  class Configuration
  end
  class Tenant
  end
  class Topic
  end
  class Message
  end
  class Serialization
    class Avro
    end
    class Json
    end
    class Plain
    end
  end
end

Usage

To publish messages, you would first configure the system with your credentials using XCommere.configure, then you would construct a XCommerce::Topic to push XCommerce::Messages to the fabric.

To subscribe to a topic, you would probably configure in the same manner, then maybe use XCommerce::Topic to establish a subscription, and (most likely) XCommerce::Serialization to parse messages.

Murky Details

The X.commerce docs mention validating the headers from the fabric. This should be handled by this gem in some way (like Shopify's ActiveMerchant gem does with PayPal, for example). I'm not sure how that's supposed to operate at the moment, so I left it off.

It might also be overkill to include serialization wrappers in here, but I thought the XCommerce::Serialization class would provide at least a thin wrapper around whatever serialization does take place, keeping the library flexible.

I also missed a little on how to deal specifically with multi-tenancy, so I didn't cover it specifically, but I figure it's doable in the XCommerce::Tenant class.

describe XCommerce do
it "is configurable" do
XCommerce.configure do |conf|
conf.should be_instance_of(XCommerce::Configuration)
end
end
it "returns its configuration" do
XCommerce.configuration.should be_instance_of(XCommerce::Configuration)
end
describe XCommerce::Configuration do
before :each do
@conf = XCommerce::Configuration.new
end
describe "#endpoint" do
it "defaults the x.commerce endpoint appropriately" do
expected_endpoint = "https://www.x.com/whatever" #FIXME
@conf.endpoint.should == expected_endpoint
end
it "allows configuring the endpoint" do
dev_endpoint = "http://127.0.0.1:8080"
#conf.endpoint = dev_endpoint
#conf.endpoint.should == dev_endpoint
end
end
describe "#self_token" do
it "defaults to nil" do
@conf.self_token.should be_nil
end
it "is configurable" do
token = "4141"
@conf.self_token = token
@conf.self_token.should == token
end
end
end
describe XCommerce::Tenant do
subject { XCommerce::Tenant.new }
it "has a bearer token" do
token = "1234"
subject.bearer_token = token
subject.bearer_token.should == token
end
describe "#me" do
before :all do
@self_token = '5125'
XCommerce.configure {|c| c.self_token = @self_token }
end
it "returns a tenant for the self token" do
myself = XCommerce::Tenant.me
myself.bearer_token.should == @self_token
end
end
end
describe XCommerce::Topic do
before :all do
@topic = '/foo/bar'
end
subject { XCommerce::Topic.new }
it "has a path" do
subject.path = @topic
subject.path.should == @topic
end
it "has a convenient constructor" do
topic = XCommerce::Topic.new(:path => @topic)
topic.path.should == @topic
end
it "publishes a message" do
message = XCommerce::Message.new(:body => 'foo')
topic = XCommerce::Topic.new(@topic)
topic.publish(message)
pending "mock http interaction"
end
end
describe XCommerce::Message do
describe "attributes" do
before :all do
@body = '{"message":"Hello World"}'
@tenant = XCommerce::Tenant.me
end
subject { XCommerce::Message.new }
it "has a body" do
subject.body = @body
subject.body.should == @body
end
it "has a tenant" do
subject.tenant = @tenant
subject.tenant.should == @tenant
end
end
describe "construction" do
it "raises an exception attempting to construct with no body" do
lambda {
XCommerce::Message.new
}.should raise_exception(XCommerce::Message::NoBodyPresentError)
end
it "is constructable with a body and tenant" do
m = XCommerce::Message.new(:body => 'serialized data', :tenant => @tenant)
end
it "is constructable with just a body" do
m = XCommerce::Message.new(:body => 'serialized data')
m.tenant.should == XCommerce::Tenant.me
end
end
end
shared_examples_for "all X.commerce serializers" do
it "encodes data" do
result = subject.serialize({'a' => 1})
result.should_not be_nil
end
it "decodes data" do
result = XCommerce::Serialization.deserialize '{"b": 2}'
result.should_not be_nil
end
end
describe XCommerce::Serialization do
subject { XCommerce::Serialization }
it "has a default implementation" do
XCommerce::Serialization.serializer.should_not be_nil
end
it_should_behave_like "all X.commerce serializers"
describe XCommerce::Serialization::Avro do
subject do
@avro_schema = '{"some":"schema"}'
XCommerce::Serialization::Avro.new(@avro_schema)
end
it_should_behave_like "all X.commerce serializers"
it "encodes to avro"
it "decodes from avro"
end
describe XCommerce::Serialization::Json do
subject { XCommerce::Serialization::Json.new }
it_should_behave_like "all X.commerce serializers"
it "encodes to json"
it "decodes from json"
end
describe XCommerce::Serialization::Plain do
subject { XCommerce::Serialization::Plain.new }
it_should_behave_like "all X.commerce serializers"
it "encodes to plain text"
it "decodes from plain text"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment