sk_api_schema 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.0.2
@@ -68,7 +68,6 @@
68
68
  "description": "Geolocation longitude",
69
69
  "optional":true,
70
70
  "type":"string"
71
- },
72
-
71
+ }
73
72
  }
74
73
  }
@@ -0,0 +1,59 @@
1
+ { "type":"object",
2
+ "title": "attachment",
3
+ "description":"An file attachment",
4
+ "properties": {
5
+ "id": {
6
+ "description": "uuid of the object.",
7
+ "identity":true,
8
+ "readonly":true,
9
+ "type":"string"
10
+ },
11
+ "filename": {
12
+ "description": "The filename as set when uploaded",
13
+ "optional":true,
14
+ "readonly":true,
15
+ "type":"string"
16
+ },
17
+ "disk_filename": {
18
+ "description": "The filename as set by SK",
19
+ "optional":true,
20
+ "readonly":true,
21
+ "type":"string"
22
+ },
23
+ "url": {
24
+ "description": "File download url. Unique and valid for 15 minutes, public accessible.",
25
+ "optional":true,
26
+ "readonly":true,
27
+ "type":"string"
28
+ },
29
+ "content_type": {
30
+ "description": "Auto detected on upload. Might not always reflect the real content type",
31
+ "optional":true,
32
+ "readonly":true,
33
+ "type":"string"
34
+ },
35
+ "size": {
36
+ "description": "Filesize in kb. Auto detected on upload.",
37
+ "optional":true,
38
+ "readonly":true,
39
+ "type":"integer"
40
+ },
41
+ "is_signed": {
42
+ "description": "True if the file(pdf) has been digitally signed.",
43
+ "optional":true,
44
+ "type":"boolean"
45
+ },
46
+ "created_at": {
47
+ "description": "Date the object was created in SK. Never changes aftwerwards",
48
+ "format":"date-time",
49
+ "readonly":true, "type":"string"
50
+ },
51
+ "updated_at": {
52
+ "description": "Date the object was edited in SK.",
53
+ "format":"date-time",
54
+ "readonly":true,
55
+ "type":"string"
56
+ }
57
+
58
+ }
59
+ }
@@ -76,6 +76,13 @@
76
76
  "type":"object",
77
77
  "properties":{"$ref":"./client.json#properties"}
78
78
  },
79
+ "archived_pdf":{
80
+ "description": "Archived PDF version of the document. Is created when an document is printed and archived. A document can have multiple archived versions. This only returns the most recent one. ",
81
+ "optional":true,
82
+ "readonly":true,
83
+ "type":"object",
84
+ "properties":{"$ref":"./attachment.json#properties"}
85
+ },
79
86
  "client_id":{
80
87
  "description": "The clients uuid, must be set for a new document. New invoices take the clients address field, due days and cash discount if those fields are not set.",
81
88
  "type":"string"
data/lib/sk_api_schema.rb CHANGED
@@ -1 +1,65 @@
1
- require 'activesupport'
1
+ require 'activesupport'
2
+
3
+ module SK
4
+ module Api
5
+ class Schema
6
+
7
+ # Read a schema with a given version and return it as hash
8
+ # See ../json folder for available schema's and versions
9
+ # === Parameter
10
+ # schema<String|Symbol>::name of the schema, available ones are in json directory
11
+ # version<String>:: version to read, this is the folder name where the schema is in.
12
+ def self.read(schema, version)
13
+ file_path = File.join(File.dirname(__FILE__), '../json', version, "#{schema}.json")
14
+ plain_data = File.open(file_path, 'r'){|f| f.read}
15
+ ActiveSupport::JSON.decode(plain_data)
16
+ end
17
+
18
+ # Create a Hash with the available (api)object attributes defined in
19
+ # schema properties.
20
+ #
21
+ # === Example
22
+ # obj = Invoice.new(:title =>'hello world', :number=>'4711')
23
+ # obj_hash = Sk::Api::Schema.to_hash_from_schema(obj, 'v1.0')
24
+ #
25
+ # obj_hash => { invoice =>{'title'=>'hello world', 'number'=>'4711' } }
26
+ #
27
+ # === Parameter
28
+ # obj<Object>:. An ruby object which is returned as hash
29
+ # version<String>:. An ruby object which is returned as hash
30
+ # === Return
31
+ # <Hash{String=>{String=>Mixed}}>:: The object as hash:
32
+ # { invoice =>{'title'=>'hello world', 'number'=>''4711 } }
33
+ def self.to_hash_from_schema(obj, version)
34
+ # get objects class name without inheritance
35
+ obj_class_name = obj.class.name.split('::').last.underscore
36
+ # init data hash
37
+ data = {}
38
+ # get schema
39
+ schema = self.read(obj_class_name, version)
40
+ # iterate over the defined schema fields
41
+ schema['properties'].each do |field, prop|
42
+ if prop['type'] == 'array'
43
+ # always set an empty array
44
+ data[field] = []
45
+ if rel_objects = obj.send( field )
46
+ rel_objects.each do |rel_obj|
47
+ # call related objects to_hash_from_schema method ex: data[:client][:addresses] << SKApi::Models::Address.to_hash_from_schema(object)
48
+ data[field] << self.to_hash_from_schema(rel_obj, version)
49
+ end
50
+ end
51
+ elsif prop['type'] == 'object' # a singular related object
52
+ data[field] = nil
53
+ if rel_obj = obj.send( field )
54
+ data[field] = self.to_hash_from_schema(rel_obj, version)
55
+ end
56
+ else # a simple field is only added if objects know its
57
+ data[field] = obj.send(field) if obj.respond_to?(field.to_sym)
58
+ end
59
+ end
60
+ { obj_class_name => data }
61
+ end
62
+
63
+ end
64
+ end
65
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sk_api_schema}
8
- s.version = "0.0.1"
8
+ s.version = "0.0.2"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Georg Leciejewski"]
12
- s.date = %q{2010-11-08}
12
+ s.date = %q{2010-11-11}
13
13
  s.description = %q{SalesKing API JSON schema and utility methods}
14
14
  s.email = %q{gl@salesking.eu}
15
15
  s.extra_rdoc_files = [
@@ -21,15 +21,15 @@ Gem::Specification.new do |s|
21
21
  "Rakefile",
22
22
  "VERSION",
23
23
  "json/v1.0/address.json",
24
+ "json/v1.0/attachment.json",
24
25
  "json/v1.0/client.json",
25
26
  "json/v1.0/credit_note.json",
26
27
  "json/v1.0/invoice.json",
27
28
  "json/v1.0/line_item.json",
28
29
  "lib/sk_api_schema.rb",
29
- "lib/utils/serializer.rb",
30
30
  "sk_api_schema.gemspec",
31
- "spec/spec_helper.rb",
32
- "spec/utils/field_map_spec.rb"
31
+ "spec/sk_api_schema_spec.rb",
32
+ "spec/spec_helper.rb"
33
33
  ]
34
34
  s.homepage = %q{http://github.com/salesking/sk_api_schema}
35
35
  s.rdoc_options = ["--charset=UTF-8"]
@@ -38,7 +38,7 @@ Gem::Specification.new do |s|
38
38
  s.summary = %q{SalesKing API JSON Schema}
39
39
  s.test_files = [
40
40
  "spec/spec_helper.rb",
41
- "spec/utils/field_map_spec.rb"
41
+ "spec/sk_api_schema_spec.rb"
42
42
  ]
43
43
 
44
44
  if s.respond_to? :specification_version then
@@ -0,0 +1,76 @@
1
+ require 'spec/spec_helper'
2
+
3
+ describe SK::Api::Schema do
4
+
5
+ it "should read json schema file" do
6
+ schema = SK::Api::Schema.read(:invoice, 'v1.0')
7
+ schema['title'].should == 'invoice'
8
+ schema['type'].should == 'object'
9
+ schema['properties'].should be_a Hash
10
+ schema['properties']['id']['identity'].should be_true
11
+ end
12
+
13
+ it "should raise error if version folder does not exist" do
14
+ lambda{
15
+ SK::Api::Schema.read(:invoice, 'v3.0')
16
+ }.should raise_error
17
+ end
18
+
19
+ it "should raise error if schema file does not exist" do
20
+ lambda{
21
+ SK::Api::Schema.read(:nope, 'v1.0')
22
+ }.should raise_error
23
+ end
24
+
25
+ end
26
+
27
+ describe SK::Api::Schema, 'object parsing' do
28
+
29
+ before :each do
30
+ @invoice = Invoice.new
31
+ @invoice.id = 'some-uuid'
32
+ @invoice.title = 'Your Invoice'
33
+ @invoice.number = '911'
34
+
35
+ @client = Client.new
36
+ @client.id = 'some-uuid'
37
+ @client.organisation = 'Dirty Food Inc.'
38
+ @client.number = '911'
39
+
40
+ @item = LineItem.new
41
+ @item.id = 'some-uuid'
42
+ @item.name = 'Pork Chops'
43
+ @item.description = 'Yummi Pork chopped by mexian emigrants'
44
+ @item.position = 1
45
+ @item.price_single = 0.99
46
+ end
47
+
48
+
49
+ it "should parse object without relations from schema" do
50
+ obj_hash = SK::Api::Schema.to_hash_from_schema(@invoice, 'v1.0')
51
+ obj_hash.should == {"invoice"=>{"number"=>"911", "line_items"=>[], "title"=>"Your Invoice", "id"=>"some-uuid", "date"=>nil, "client"=>nil, "due_date"=>nil}}
52
+ client_obj_hash = SK::Api::Schema.to_hash_from_schema(@client, 'v1.0')
53
+ client_obj_hash.should == {"client"=>{"number"=>"911", "addresses"=>[], "id"=>"some-uuid", "organisation"=>"Dirty Food Inc.", "last_name"=>nil}}
54
+ end
55
+
56
+ it "should parse object with relations from schema" do
57
+ @invoice.line_items = [@item]
58
+ @invoice.client = @client
59
+ obj_hash = SK::Api::Schema.to_hash_from_schema(@invoice, 'v1.0')
60
+ obj_hash.should == {"invoice"=>{"number"=>"911", "line_items"=>[{"line_item"=>{"position"=>1, "name"=>"Pork Chops", "id"=>"some-uuid", "description"=>"Yummi Pork chopped by mexian emigrants", "price_single"=>0.99}}], "title"=>"Your Invoice", "id"=>"some-uuid", "date"=>nil, "client"=>{"client"=>{"number"=>"911", "addresses"=>[], "id"=>"some-uuid", "organisation"=>"Dirty Food Inc.", "last_name"=>nil}}, "due_date"=>nil}}
61
+ end
62
+
63
+ end
64
+
65
+ ################################################################################
66
+ # virtual classes used in test
67
+ class Invoice
68
+ attr_accessor :id, :title, :description, :number, :date, :due_date, :line_items, :client
69
+ end
70
+
71
+ class LineItem
72
+ attr_accessor :id, :name, :description, :position, :price_single
73
+ end
74
+ class Client
75
+ attr_accessor :id, :organisation, :last_name, :number, :addresses
76
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  require 'rubygems'
2
2
  require 'spec'
3
- #require "#{File.dirname(__FILE__)}/../lib/sk_api"
3
+ require "#{File.dirname(__FILE__)}/../lib/sk_api_schema"
4
4
  #require File.dirname(__FILE__) + '/../vendor/jsonschema-1.0.0/lib/jsonschema'
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sk_api_schema
3
3
  version: !ruby/object:Gem::Version
4
- hash: 29
4
+ hash: 27
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 0
9
- - 1
10
- version: 0.0.1
9
+ - 2
10
+ version: 0.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Georg Leciejewski
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-11-08 00:00:00 +01:00
18
+ date: 2010-11-11 00:00:00 +01:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -60,15 +60,15 @@ files:
60
60
  - Rakefile
61
61
  - VERSION
62
62
  - json/v1.0/address.json
63
+ - json/v1.0/attachment.json
63
64
  - json/v1.0/client.json
64
65
  - json/v1.0/credit_note.json
65
66
  - json/v1.0/invoice.json
66
67
  - json/v1.0/line_item.json
67
68
  - lib/sk_api_schema.rb
68
- - lib/utils/serializer.rb
69
69
  - sk_api_schema.gemspec
70
+ - spec/sk_api_schema_spec.rb
70
71
  - spec/spec_helper.rb
71
- - spec/utils/field_map_spec.rb
72
72
  has_rdoc: true
73
73
  homepage: http://github.com/salesking/sk_api_schema
74
74
  licenses: []
@@ -105,4 +105,4 @@ specification_version: 3
105
105
  summary: SalesKing API JSON Schema
106
106
  test_files:
107
107
  - spec/spec_helper.rb
108
- - spec/utils/field_map_spec.rb
108
+ - spec/sk_api_schema_spec.rb
@@ -1,66 +0,0 @@
1
- module SKApi
2
- module Utils
3
- # Mixed into Resources::Base providing to_hash and to_json serialisation for
4
- # SKApi Resources.
5
- # Inside SalesKing this serialising is used to render the output.
6
- # f.ex. in the clients api controller
7
- # => SKApi::Resources::Client.to_json(a_client)
8
- # This way you can keep your API client up to date by using the resources and
9
- # relying on SKApi::Resources::Client.schema
10
- module Serializer
11
- def self.included(base)
12
- base.extend ClassMethods
13
- end
14
-
15
- module ClassMethods
16
-
17
- def schema_to_hash
18
-
19
- end
20
-
21
- # Create a Hash with the available (api)object attributes defined in api_fields.
22
- #
23
- # ==== Parameter
24
- # obj<object>:. An ruby object which is returned as hash
25
- def to_hash_from_schema(obj)
26
- # first set the root node to the objects class name as symbol
27
- obj_class_name = obj.class.name.split('::').last.underscore
28
- # obj_class_name = obj.class.to_s.underscore.to_sym
29
- data = { obj_class_name => {} }
30
- # iterate over the defined api fields hash
31
- self.schema_props.each do |field, props|
32
- if props['type'] == 'array'
33
- # always set the field, so the user can expect an empty array
34
- data[obj_class_name][field] = []
35
- if rel_objects = obj.send( field )
36
- rel_objects.each do |rel_obj|
37
- # setup scope for related class
38
- klass = "SKApi::Resources::#{rel_obj.class}".constantize
39
- # call related objects to_hash_from_schema method ex: data[:client][:addresses] << SKApi::Models::Address.to_hash_from_schema(object)
40
- data[obj_class_name][field] << klass.to_hash_from_schema(rel_obj)
41
- end
42
- end
43
- elsif props['type'] == 'object' # a singular resource TODO should we add an empty object?
44
- if rel_obj = obj.send( field )
45
- klass = "SKApi::Resources::#{rel_obj.class}".constantize
46
- # ex: data['invoice']['client'] = SKApi::Models::Client.to_hash_from_schema(client)
47
- data[obj_class_name][field] = klass.to_hash_from_schema(rel_obj)
48
- end
49
- else # a simple field which can be directly called, only added of objects know its
50
- data[obj_class_name][field] = obj.send(field) if obj.respond_to?(field.to_sym)
51
- end
52
- end
53
- data
54
- end
55
-
56
- def to_json(obj)
57
- data = self.to_hash_from_schema(obj)
58
- # data[:links] = self.api_links
59
- ActiveSupport::JSON.encode(data)
60
- end
61
-
62
- end #ClassMethods
63
-
64
- end #mixin
65
- end #utils
66
- end #SKApi
@@ -1,73 +0,0 @@
1
- require 'spec/spec_helper'
2
-
3
- describe SKApi::Utils::FieldMap do
4
-
5
- before :each do
6
- @loc_obj = LocalContact.new
7
- @rem_obj = RemoteContact.new()
8
- @map = SKApi::Utils::FieldMap.new(@loc_obj, @rem_obj, map_hash)
9
- end
10
-
11
- it "should create a mapping" do
12
- @map.outdated?.should be_false # both objects are empty
13
- end
14
-
15
- it "should find outdated fields" do
16
- @loc_obj.firstname = 'theo'
17
- @map.outdated?.should be_true
18
- @map.outdated.first[:loc_key].should == :firstname
19
- end
20
-
21
- it "should update outdated remote fields" do
22
- @loc_obj.firstname = 'theo'
23
- @map.update_remote_outdated
24
- @rem_obj.first_name.should == @loc_obj.firstname
25
- # test logging
26
- @map.log.should_not be_empty
27
- end
28
-
29
- it "should update outdated local fields" do
30
- @rem_obj.first_name = 'Heinz'
31
- @map.update_local_outdated
32
- @rem_obj.first_name.should == @loc_obj.firstname
33
- @map.log.length.should == 1
34
- end
35
- # it "should update outdated local fields" do
36
- # @rem_obj.first_name = 'Heinz'
37
- # @map.outdated?
38
- # @map.update_local_outdated
39
- # @rem_obj.first_name.should == @loc_obj.firstname
40
- # end
41
-
42
- def map_hash
43
- [
44
- {:loc_key => :firstname, :rem_key => :first_name},
45
- {:loc_key => :street, :rem_key => :address1},
46
- {:loc_key => :postcode, :rem_key => :zip},
47
- {:loc_key => :city, :rem_key => :city},
48
- {:loc_key => :gender, :rem_key => :gender, :trans => { :obj=>'TransferFunctions',
49
- :loc_trans => 'set_local_gender',
50
- :rem_trans => 'set_remote_gender'}
51
- }
52
- ]
53
- end
54
-
55
- end
56
-
57
- class RemoteContact
58
- attr_accessor :first_name, :address1, :zip, :city, :gender
59
- end
60
- class LocalContact
61
- attr_accessor :firstname, :street, :postcode, :city, :gender
62
- end
63
-
64
- class TransferFunctions
65
- def self.set_local_gender(remote_val)
66
- return 'male' if remote_val == 'm'
67
- return 'female' if remote_val == 'f'
68
- end
69
- def self.set_remote_gender(local_val)
70
- return 'm' if local_val == 'male'
71
- return 'f' if local_val == 'female'
72
- end
73
- end