marley 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,6 @@
1
1
  require "rack/test"
2
2
  require 'marley/reggae'
3
3
  module Marley
4
- #simple mocking framework; could be expanded to a general use client by adding display code.
5
4
  class TestClient
6
5
  CRUD2REST={'create' => 'post','read' => 'get','update' => 'put', 'del' => 'delete'}
7
6
  DEFAULT_OPTS={:url => nil,:root_url => nil, :resource_name => nil, :instance_id => nil, :method => nil, :extention =>nil, :auth => nil, :code => nil, :debug => nil}
@@ -10,7 +9,7 @@ module Marley
10
9
  def app
11
10
  Marley::Router.new
12
11
  end
13
- def initialize(opts)
12
+ def initialize(opts={})
14
13
  @opts=DEFAULT_OPTS.merge(opts)
15
14
  end
16
15
  def make_url(opts=nil)
@@ -0,0 +1,36 @@
1
+
2
+ module Marley
3
+ module Utils
4
+ def self.hash_keys_to_syms(hsh)
5
+ hsh.inject({}) {|h,(k,v)| h[k.to_sym]= v.class==Hash ? hash_keys_to_syms(v) : v;h }
6
+ end
7
+ # @todo: make options inheritable?
8
+ def self.rest_opts_mod(name,opts,key_proc)
9
+ Module.new do |m|
10
+ @create_opts=[name,opts,key_proc]
11
+ def self.create_opts
12
+ @create_opts
13
+ end
14
+ def self.new(name=nil,opts=nil,key_proc=nil)
15
+ Marley::Utils.rest_opts_mod(*@create_opts)
16
+ end
17
+ opts.each {|opt| attr_accessor "#{name}_#{opt}"}
18
+ define_method "rest_#{name}" do
19
+ if opts.find {|opt| send(:"#{name}_#{opt}").to_s > ""}
20
+ foo=opts.inject({}) do |h,k|
21
+ i=send("#{name}_#{k}".sub(/^_/,''))
22
+ h[k.to_sym]=i.class==Hash ? i[key_proc.call] : i
23
+ h
24
+ end
25
+ if Marley.constants.include?("Reggae#{name.camelcase}")
26
+ Marley.const_get(:"Reggae#{name.camelcase}").new(foo)
27
+ else
28
+ foo
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ RestActions=Utils.rest_opts_mod('actions',['get','post','put','delete'],lambda {$request[:user].class})
36
+ end
@@ -1,91 +1,87 @@
1
1
 
2
- RESTRICT_HIDE=1
3
- RESTRICT_RO=2
4
- RESTRICT_REQ=4
5
- TYPE_INDEX=0
6
- NAME_INDEX=1
7
- RESTRICTIONS_INDEX=2
8
- module Sequel::Plugins::RestConvenience
9
- module ClassMethods
10
- def controller
11
- Marley::ModelController.new(self)
12
- end
13
- def resource_name
14
- self.name.sub(/.*::/,'').underscore
15
- end
16
- def reggae_link(action=nil)
17
- [:link,{:url => "/#{self.resource_name}/#{action}",:title => "#{action.humanize} #{self.resource_name.humanize}".strip}]
18
- end
19
- def list(params=nil)
20
- user=$request[:user]
21
- if user.respond_to?(otm=self.resource_name.pluralize)
22
- if user.method(otm).arity==0
23
- if (relationship=user.send(otm)).respond_to?(:filter)
24
- relationship.filter($request[:get_params][resource_name.to_sym] || {}).all
2
+ module Sequel
3
+ module Plugins::RestConvenience
4
+ module ClassMethods
5
+ include Marley::RestActions
6
+ def controller
7
+ Marley::ModelController.new(self)
8
+ end
9
+ def resource_name
10
+ self.name.sub(/.*::/,'').underscore
11
+ end
12
+ def reggae_link(action=nil)
13
+ [:link,{:url => "/#{self.resource_name}/#{action}",:title => "#{action.humanize} #{self.resource_name.humanize}".strip}]
14
+ end
15
+ def list(params=nil)
16
+ user=$request[:user]
17
+ if user.respond_to?(otm=self.resource_name.pluralize)
18
+ if user.method(otm).arity==0
19
+ if (relationship=user.send(otm)).respond_to?(:filter)
20
+ relationship.filter($request[:get_params][resource_name.to_sym] || {}).all
21
+ else
22
+ user.send(otm)
23
+ end
25
24
  else
26
- user.send(otm)
25
+ user.send(otm,$request[:get_params][resource_name.to_sym])
27
26
  end
28
27
  else
29
- user.send(otm,$request[:get_params][resource_name.to_sym])
28
+ raise Marley::AuthorizationError
30
29
  end
31
- else
32
- raise Marley::AuthorizationError
30
+ end
31
+ def autocomplete(input_content)
32
+ filter(:name.like("#{input_content.strip}%")).map {|rec| [rec.id, rec.name]}
33
33
  end
34
34
  end
35
- def autocomplete(input_content)
36
- filter(:name.like("#{input_content.strip}%")).map {|rec| [rec.id, rec.name]}
37
- end
38
- end
39
- module InstanceMethods
40
- def get_actions; [];end
41
- def edit; self; end
42
- def rest_cols
43
- columns.reject do |c|
44
- if new?
45
- c.to_s.match(/(^id$)|(_type$)|(date_(created|updated))/)
46
- else
47
- c.to_s.match(/_type$/)
35
+ module InstanceMethods
36
+ include Marley::RestActions
37
+ def edit; self; end
38
+ def rest_cols
39
+ columns.reject do |c|
40
+ if new?
41
+ c.to_s.match(/(^id$)|(_type$)|(date_(created|updated))/)
42
+ else
43
+ c.to_s.match(/_type$/)
44
+ end
48
45
  end
49
46
  end
50
- end
51
- def hidden_cols
52
- columns.select {|c| c.to_s.match(/(_id$)/)}
53
- end
54
- def write_cols
55
- rest_cols.reject {|c| c.to_s.match(/(^id$)|(date_(created|updated))/)}
56
- end
57
- def required_cols;[];end
58
- def rest_schema
59
- rest_cols.map do |col_name|
60
- db_spec=db_schema.to_hash[col_name]
61
- col_type=db_spec ? db_spec[:db_type].downcase : col_name
62
- restrictions=0
63
- restrictions|=RESTRICT_HIDE if hidden_cols.include?(col_name)
64
- restrictions|=RESTRICT_RO unless write_cols.include?(col_name)
65
- restrictions|=RESTRICT_REQ if required_cols.include?(col_name) || (db_spec && !db_spec[:allow_null])
66
- [col_type, col_name, restrictions,send(col_name)]
47
+ def hidden_cols
48
+ columns.select {|c| c.to_s.match(/(_id$)/)}
67
49
  end
68
- end
69
- def to_s
70
- respond_to?('name') ? name : id.to_s
71
- end
72
- def to_a
73
- a=Marley::ReggaeInstance.new( {:name => self.class.resource_name,:url => url ,:new_rec => self.new?,:schema => rest_schema,:get_actions => get_actions.class==Hash ? get_actions[$request[:user].class] : get_actions})
74
- if respond_to?(:rest_associations) && ! new?
75
- a.contents=rest_associations.map do |assoc|
76
- (assoc.class==Symbol ? send(assoc) : assoc).map{|instance| instance.to_a}
50
+ def write_cols
51
+ rest_cols.reject {|c| c.to_s.match(/(^id$)|(date_(created|updated))/)}
52
+ end
53
+ def required_cols;[];end
54
+ def rest_schema
55
+ rest_cols.map do |col_name|
56
+ db_spec=db_schema.to_hash[col_name]
57
+ col_type=db_spec ? db_spec[:db_type].downcase : col_name
58
+ restrictions=0
59
+ restrictions|=RESTRICT_HIDE if hidden_cols.include?(col_name)
60
+ restrictions|=RESTRICT_RO unless write_cols.include?(col_name)
61
+ restrictions|=RESTRICT_REQ if required_cols.include?(col_name) || (db_spec && !db_spec[:allow_null])
62
+ [col_type, col_name, restrictions,send(col_name)]
77
63
  end
78
64
  end
79
- a
80
- end
81
- def to_json
82
- to_a.to_json
83
- end
84
- def url(action=nil)
85
- "/#{self.class.resource_name}/#{self[:id]}/#{action}".sub('//','/')
86
- end
87
- def reggae_link(action=nil)
88
- [:link,{:url => url,:title => "#{action.humanize}"}]
65
+ def to_s
66
+ respond_to?('name') ? name : id.to_s
67
+ end
68
+ def to_a
69
+ a=Marley::ReggaeInstance.new( {:name => self.class.resource_name,:url => url ,:new_rec => self.new?,:schema => rest_schema,:actions => self.class.rest_actions})
70
+ a.contents=self.class.associations.map do |assoc|
71
+ assoc=send("#{assoc}_dataset")
72
+ (assoc.respond_to?(:current_user_dataset) ? assoc.current_user_dataset : assoc).map{|instance| instance.to_a} if assoc.respond_to?(:rest_actions)
73
+ end.compact unless new?
74
+ a
75
+ end
76
+ def to_json(*args)
77
+ to_a.to_json
78
+ end
79
+ def url(action=nil)
80
+ "/#{self.class.resource_name}/#{self[:id]}/#{action}".sub('//','/')
81
+ end
82
+ def reggae_link(action=nil)
83
+ [:link,{:url => url,:title => "#{action.humanize}"}]
84
+ end
89
85
  end
90
86
  end
91
87
  end
data/marley-0.3.0.gem ADDED
Binary file
data/marley.gemspec CHANGED
@@ -2,15 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{marley}
5
- s.version = "0.3.0"
5
+ s.version = "0.4.0"
6
6
  s.summary = %q{Irie default restful routes for your models and other objects}
7
- s.description = %q{Marley implements a web services microframework on top of Rack and Sequel on the server side and Jquery on the client side.}
7
+ s.description = %q{Marley implements a web services microframework on top of Rack and Sequel on the server side and Jquery on the client side. After 0.4.0 the joints framework will be redone. However, I'm releasing this because I still think it's worth playing with and the joint restructuring will take a while.
8
+ }
8
9
  s.authors = ["Herb Daily"]
9
10
  s.email = 'herb.daily@safe-mail.net'
10
11
  s.homepage = 'http://github.com/herbdaily/marley'
11
12
  s.required_rubygems_version = Gem::Requirement.new(">= 1.0.0") if s.respond_to? :required_rubygems_version=
12
13
  s.add_runtime_dependency 'sequel', '~>3.27'
13
14
  s.add_runtime_dependency 'rack', '~>1.2.2'
15
+ # add rubydoctest dependency
14
16
  s.add_runtime_dependency 'json', '~>1.1.7'
15
17
  s.files = Dir.glob(["*","lib/**/*","examples/**/*","test/**/*"])
16
18
  end
data/reggae.ebnf CHANGED
@@ -15,9 +15,9 @@ section_property ::= 'title' | 'description' | 'navigation'
15
15
 
16
16
  link_property ::= 'title' | 'description' | 'url'
17
17
 
18
- instance_property ::= 'name' | 'url' | 'new_rec' | 'search' | 'schema' | 'get_actions' | 'delete_action'
18
+ instance_property ::= 'name' | 'url' | 'new_rec' | 'search' | 'schema' | 'actions'
19
19
 
20
- instance_list_property ::='title' | 'description' | 'schema' | 'get_actions' | 'delete_action' | 'items'
20
+ instance_list_property ::='title' | 'description' | 'schema' | 'actions' | 'items'
21
21
 
22
22
  msg_property ::= 'title' | 'description'
23
23
 
@@ -39,11 +39,17 @@ schema_value ::= '[' col_spec (',' colspec)? ']'
39
39
 
40
40
  items_value ::= '[' '[' col_value (',' col_value)* ']' (',' '[' col_value (',' col_value)* ']')* ']'
41
41
 
42
- get_actions_value ::= '[' action (',' action)*']'
42
+ actions_value ::= '{' '"' ('get' | 'post' | 'put' | 'delete') '"' ':' methods (',' '"' ('get' | 'post' | 'put' | 'delete') '"' ':' methods )* '}'
43
43
 
44
- action ::= string_value
44
+ methods::= '[' ( get_method (',' get_method)* | post_method (',' post_method)* | put_method (',' put_method)* | delete_method (',' delete_method)* ) ']'
45
45
 
46
- delete_action_value ::= 'remove_parent' | 'deactivate' | 'delete'
46
+ get_action ::= string_literal
47
+
48
+ post_action ::= resource
49
+
50
+ put_action ::= resource
51
+
52
+ delete_method ::= 'remove_parent' | 'deactivate' | 'delete'
47
53
 
48
54
  col_spec ::= '[' col_type ',' col_name ',' col_restrictions (',' col_value)? ']'
49
55
 
@@ -93,7 +93,7 @@ class MessageTests < Test::Unit::TestCase
93
93
  end
94
94
  should "have reply, reply_all and new_tags instance get actions" do
95
95
  resp=@client.read({})
96
- assert_same_elements ['reply','reply_all','new_tags'], resp[0].get_actions
96
+ assert_same_elements ['reply','reply_all','new_tags'], resp[0].actions[:get]
97
97
  end
98
98
  context "user1 instance actions" do
99
99
  setup do
@@ -140,7 +140,7 @@ class MessageTests < Test::Unit::TestCase
140
140
  assert_same_elements ["sent", "test", "test2"], @tags.map{|t| t.schema[:tag].col_value}
141
141
  end
142
142
  should "allow sender to remove his own tags'" do
143
- assert_equal 'remove_parent', @tags[0].delete_action
143
+ assert_equal 'remove_parent', @tags[0].actions[:delete]
144
144
  assert @client.del({},{:url => @tags[0].url+@msg.url})
145
145
  assert_equal 2, @client.read[0].find_instances('user_tag').length
146
146
  end
@@ -159,7 +159,7 @@ class MessageTests < Test::Unit::TestCase
159
159
  assert_equal 'test,test2', reply.schema[:tags].col_value
160
160
  end
161
161
  should "allow receiver to remove his own tags'" do
162
- assert_equal 'remove_parent', @tags[0].delete_action
162
+ assert_equal 'remove_parent', @tags[0].actions[:delete]
163
163
  assert @client.del({},{:url => @tags[0].url+@msg.url})
164
164
  assert_equal 2, @client.read[0].find_instances('user_tag').length
165
165
  end
@@ -273,7 +273,7 @@ class MessageTests < Test::Unit::TestCase
273
273
  @client.create(@post.set_values('title' => 'test', 'message' => 'asdf','tags' => 'admintag1,admintag2'),{:auth => @admin_auth})
274
274
  @client.auth=@user2_auth
275
275
  posts=@client.read({})
276
- assert_same_elements ['reply','new_tags','new_user_tags'], posts[0].get_actions
276
+ assert_same_elements ['reply','new_tags','new_user_tags'], posts[0].actions[:get]
277
277
  reply=@client.read({},{:instance_id => posts[0].schema[:id].col_value,:method => 'reply'})
278
278
  tags=@client.read({},{:instance_id => posts[0].schema[:id].col_value,:method => 'new_tags'})
279
279
  user_tags=@client.read({},{:instance_id => posts[0].schema[:id].col_value,:method => 'new_user_tags'})
data/test/test.sqlite3 CHANGED
Binary file
data/test/user_tests.rb CHANGED
@@ -42,7 +42,7 @@ class UserTests < Test::Unit::TestCase
42
42
  context "existing user logged in" do
43
43
  setup do
44
44
  @client.code=201
45
- assert @client.create(:'user[name]' => 'user1',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
45
+ assert @client.create({:'user[name]' => 'user1',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf'})
46
46
  assert @client.create(:'user[name]' => 'user2',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
47
47
  @client.code=200
48
48
  @client.auth=['user1','asdfasdf']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: marley
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Herb Daily
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2011-11-20 00:00:00 -03:00
12
+ date: 2011-12-01 00:00:00 -03:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -42,7 +42,7 @@ dependencies:
42
42
  - !ruby/object:Gem::Version
43
43
  version: 1.1.7
44
44
  version:
45
- description: Marley implements a web services microframework on top of Rack and Sequel on the server side and Jquery on the client side.
45
+ description: "Marley implements a web services microframework on top of Rack and Sequel on the server side and Jquery on the client side. After 0.4.0 the joints framework will be redone. However, I'm releasing this because I still think it's worth playing with and the joint restructuring will take a while.\n "
46
46
  email: herb.daily@safe-mail.net
47
47
  executables: []
48
48
 
@@ -51,15 +51,17 @@ extensions: []
51
51
  extra_rdoc_files: []
52
52
 
53
53
  files:
54
+ - marley-0.3.0.gem
54
55
  - marley.gemspec
55
56
  - Rakefile
56
57
  - Favicon.ico
57
58
  - README.rdoc
58
59
  - TODO
59
60
  - reggae.ebnf
60
- - forum_tests.rb
61
+ - marley-0.4.0.gem
61
62
  - lib/marley.rb
62
63
  - lib/marley/test_helpers.rb
64
+ - lib/marley/utils.rb
63
65
  - lib/marley/joint.rb
64
66
  - lib/marley/controllers.rb
65
67
  - lib/marley/reggae.rb
@@ -73,7 +75,6 @@ files:
73
75
  - lib/joints/basic_messaging.rb
74
76
  - lib/joints/basic_user.rb
75
77
  - lib/joints/tagging.rb
76
- - lib/joints/user_based_navigation.rb
77
78
  - lib/joints/basic_menu_system.rb
78
79
  - lib/joints/tagged_messaging.rb
79
80
  - examples/forum.js
data/forum_tests.rb DELETED
@@ -1,356 +0,0 @@
1
- require 'rubygems'
2
- require 'test/unit'
3
- require 'shoulda'
4
- EXAMPLES_DIR=File.dirname(__FILE__) + '/../examples'
5
-
6
- ENV['MARLEY_TESTING']='true'
7
- `cp #{EXAMPLES_DIR}/empty.sqlite3 #{EXAMPLES_DIR}/forum_test.sqlite3`
8
- require "#{EXAMPLES_DIR}/forum.rb"
9
- require "#{EXAMPLES_DIR}/../lib/marley/test_helpers"
10
-
11
- class UserTests < Test::Unit::TestCase
12
- def setup
13
- Marley::Resources::User.delete
14
- @client=Marley::TestClient.new(:resource_name => 'user',:code => 400)
15
- end
16
- should "return login form with no params" do
17
- assert @client.read({},{:resource_name => '',:code => 200})
18
- end
19
- should "not allow access to menus, private messages, or posts" do
20
- assert @client.read({:resource_name =>'pm_menu'},{:code => 401})
21
- assert @client.read({:resource_name =>'post_menu'},{:code => 401})
22
- assert @client.read({:resource_name =>'private_message'},{:code => 401})
23
- assert @client.read({:resource_name =>'post'},{:code => 401})
24
- end
25
- should "validate new user properly" do
26
- assert resp=@client.create
27
- assert_equal :error, resp.resource_type
28
- assert_equal "validation", resp.error_type
29
- assert_equal ["is required"], resp.error_details[:name]
30
- resp=@client.create({:'user[name]' => 'asdf'})
31
- assert_equal :error, resp.resource_type
32
- assert_equal "validation", resp.error_type
33
- resp=@client.create({:'user[name]' => 'asdf',:'user[password]' => 'asdfaf'})
34
- assert_equal :error, resp.resource_type
35
- assert_equal "validation", resp.error_type
36
- assert_equal ["Password must contain at least 8 characters"], resp.error_details[:password]
37
- resp=@client.create(:'user[name]' => 'asdf',:'user[password]' => 'asdfasdf')
38
- assert_equal :error, resp.resource_type
39
- assert_equal "validation", resp.error_type
40
- assert_equal ["Passwords do not match"], resp.error_details[:confirm_password]
41
- end
42
- should "allow creation of a new user and disallow user with the same name" do
43
- @client.code=200
44
- @client.create(:'user[name]' => 'asdf',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
45
- assert @client.create({:'user[name]' => 'asdf',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf'},{:code => 400})
46
- end
47
- context "existing user logged in" do
48
- setup do
49
- @client.code=201
50
- assert @client.create(:'user[name]' => 'user1',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
51
- assert @client.create(:'user[name]' => 'user2',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
52
- @client.code=200
53
- @client.auth=['user1','asdfasdf']
54
- end
55
- should "show menus" do
56
- menu= @client.read({},:resource_name => '')
57
- assert_same_elements ["User Info", "Private Messages", "Public Posts"], menu.navigation.map{|n| n.title}
58
- assert @client.read({},:resource_name => 'private_message/section')
59
- assert @client.read({},:resource_name => 'post/section')
60
- end
61
- should "allow viewing and changing of user columns with proper validation" do
62
- @client.instance_id=1
63
- assert user=@client.read({})
64
- params=user.to_params
65
- assert @client.update(params,{:code => 204})
66
- assert err=@client.update(params.update('user[password]' => 'zxcvzxcv'),{:code => 400})
67
- assert_equal :error, err.resource_type
68
- assert_equal "validation", err.error_type
69
- assert @client.update(params.update('user[password]' => 'zxcvzxcv','user[confirm_password]' => 'zxcvzxcv', 'user[old_password]' => 'asdfasdf'),:code => 204)
70
- assert @client.read({},:code => 401)
71
- @client.auth=['user1','zxcvzxcv']
72
- assert @client.read({})
73
- @client.instance_id=2
74
- assert @client.update(params.update('user[password]' => 'zxcvzxcv','user[confirm_password]' => 'zxcvzxcv', 'user[old_password]' => 'asdfasdf'),:code => 403)
75
- end
76
- end
77
- end
78
- class MessageTests < Test::Unit::TestCase
79
- def setup
80
- Marley::Resources::User.delete
81
- Marley::Resources::Message.delete
82
- Marley::Resources::Tag.delete
83
- DB[:messages_tags].delete
84
- @client=Marley::TestClient.new(:resource_name => 'user')
85
- @client.create(:'user[name]' => 'user1',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
86
- @client.create(:'user[name]' => 'user2',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
87
- @client.create(:'user[name]' => 'admin',:'user[password]' => 'asdfasdf',:'user[confirm_password]' => 'asdfasdf')
88
- @admin_auth=['admin','asdfasdf']
89
- @user1_auth=['user1','asdfasdf']
90
- @user2_auth=['user2','asdfasdf']
91
- Marley::Resources::User[:name => 'admin'].update(:user_type => 'Admin')
92
- end
93
- context "Private Messages" do
94
- setup do
95
- @client.resource_name='private_message'
96
- end
97
- context "regular user (user1) logged in" do
98
- setup do
99
- @client.auth=@user1_auth
100
- end
101
- should "show PM list" do
102
- assert @client.read({})
103
- end
104
- should "validate new user generated PMs properly" do
105
- #reject a PM with only recipients
106
- resp=@client.create({:'private_message[recipients]' => 'user2'},{:code => 400})
107
- assert_equal :error, resp.resource_type
108
- assert_equal "validation", resp.error_type
109
- assert_equal ["is required"], resp.error_details[:title]
110
- assert_equal ["is required"], resp.error_details[:message]
111
- #reject a PM to a non-existent user
112
- resp=@client.create({:'private_message[recipients]' => 'asdfasdfasdfasdf',:'private_message[title]' => 'asdf',:'private_message[message]' => 'asdf'},{:code => 400})
113
- assert_equal :error, resp.resource_type
114
- assert_equal "validation", resp.error_type
115
- assert resp.error_details[:recipients][0]
116
- #reject a PM from user to user
117
- resp=@client.create({:'private_message[recipients]' => 'user2',:'private_message[title]' => 'asdf',:'private_message[message]' => 'asdf'},{:code => 400})
118
- assert_equal :error, resp.resource_type
119
- assert_equal "validation", resp.error_type
120
- assert resp.error_details[:recipients][0]
121
- end
122
- should "accept a PM to admin" do
123
- assert @client.create({:'private_message[recipients]' => 'admin',:'private_message[title]' => 'asdf',:'private_message[message]' => 'asdf'})
124
- end
125
- end
126
- context "admin logged in" do
127
- setup do
128
- @client.auth=@admin_auth
129
- end
130
- should "validate new admin generated PMs properly" do
131
- resp=@client.create({:'private_message[recipients]' => 'user2'},{:code => 400})
132
- assert_equal :error, resp.resource_type
133
- assert_equal "validation", resp.error_type
134
- assert_equal ["is required"], resp.error_details[:title]
135
- assert_equal ["is required"], resp.error_details[:message]
136
- end
137
- should "accept a PM to user1" do
138
- assert @client.create({:'private_message[recipients]' => 'user1',:'private_message[title]' => 'asdf',:'private_message[message]' => 'asdf'})
139
- end
140
- end
141
- context "message with no tags" do
142
- setup do
143
- @client.auth=@admin_auth
144
- @client.create({:'private_message[recipients]' => 'user1',:'private_message[title]' => 'asdf',:'private_message[message]' => 'asdf'})
145
- end
146
- should "show up in PM list of sender and receiver" do
147
- resp=@client.read({})
148
- assert_equal 1, resp.length
149
- resp=@client.read({},{:auth => @user1_auth})
150
- assert_equal 1, resp.length
151
- end
152
- should "have sent tag for sender" do
153
- resp=@client.read({})
154
- assert_equal 3, resp[0].length
155
- assert_equal "sent", resp.find_instances('user_tag')[0].schema[:tag].col_value
156
- end
157
- should "have inbox tag for receiver" do
158
- resp=@client.read({},{:auth => @user1_auth})
159
- assert_equal 3, resp[0].length
160
- assert_equal "inbox", resp.find_instances('user_tag')[0].schema[:tag].col_value
161
- end
162
- should "have reply, reply_all and new_tags instance get actions" do
163
- resp=@client.read({})
164
- assert_same_elements ['reply','reply_all','new_tags'], resp[0].get_actions
165
- end
166
- context "user1 instance actions" do
167
- setup do
168
- @client.auth=@user1_auth
169
- @msg=@client.read({})[0]
170
- @client.instance_id=@msg.schema[:id].col_value
171
- @reply=@client.read({},{:method => 'reply'})
172
- @new_tags=@client.read({},:method => 'new_tags')
173
- end
174
- context "reply" do
175
- should "have author in to field and default title beginning with 're:'" do
176
- assert_equal 'admin', @reply.schema[:recipients].col_value
177
- assert_equal 're: ', @reply.schema[:title].col_value[0 .. 3]
178
- end
179
- should "accept reply" do
180
- assert @client.create(@reply.to_params.merge('private_message[message]' => 'asdf'),{:method => nil,:instance_id => nil})
181
- end
182
- end
183
- context "new tags" do
184
- should "return tag instance with name tag and same url as original message" do
185
- assert_equal 'tags', @new_tags.name
186
- assert_equal "#{@msg.url}tags", @new_tags.url
187
- end
188
- should "accept new tags, which should then show up with the original message" do
189
- assert @client.create({'private_message[tags]' => 'added_tag1, added_tag2'},{:method => 'tags'})
190
- msg=@client.read({})
191
- user_tags=msg.find_instances('user_tag')
192
- assert_same_elements ["inbox", "added_tag1", "added_tag2"], user_tags.map{|t| t.schema[:tag].col_value}
193
- end
194
- end
195
- end
196
- end
197
- context "message with 2 tags" do
198
- setup do
199
- @client.auth=@admin_auth
200
- @client.create({:'private_message[recipients]' => 'user1',:'private_message[title]' => 'asdf',:'private_message[message]' => 'asdf', :'private_message[tags]' => 'test,test2'})
201
- end
202
- context "sender (admin) logged in" do
203
- setup do
204
- @msg=@client.read[0]
205
- @tags=@msg.find_instances('user_tag')
206
- end
207
- should "have sent tag and both specified tags for sender" do
208
- assert_same_elements ["sent", "test", "test2"], @tags.map{|t| t.schema[:tag].col_value}
209
- end
210
- should "allow sender to remove his own tags'" do
211
- assert_equal 'remove_parent', @tags[0].delete_action
212
- assert @client.del({},{:url => @tags[0].url+@msg.url})
213
- assert_equal 2, @client.read[0].find_instances('user_tag').length
214
- end
215
- end
216
- context "receiver (user1)" do
217
- setup do
218
- @client.auth=@user1_auth
219
- @msg=@client.read[0]
220
- @tags=@msg.find_instances('user_tag')
221
- end
222
- should "have inbox tag and both specified tags" do
223
- assert_same_elements ["inbox", "test", "test2"], @tags.map{|t| t.schema[:tag].col_value}
224
- end
225
- should "have specified tags in reply" do
226
- reply=@client.read({},{:instance_id => @msg.schema[:id].col_value,:method => 'reply'})
227
- assert_equal 'test,test2', reply.schema[:tags].col_value
228
- end
229
- should "allow receiver to remove his own tags'" do
230
- assert_equal 'remove_parent', @tags[0].delete_action
231
- assert @client.del({},{:url => @tags[0].url+@msg.url})
232
- assert_equal 2, @client.read[0].find_instances('user_tag').length
233
- end
234
- end
235
- context 'user2' do
236
- should "have no messages" do
237
- assert resp=@client.read({},{:auth => @user2_auth})
238
- assert_equal 0, resp.length
239
- end
240
- end
241
- end
242
- context "message with 2 tags and 2 receivers" do
243
- setup do
244
- @client.create({:'private_message[recipients]' => 'user1,user2',:'private_message[title]' => 'asdf',:'private_message[message]' => 'asdf', :'private_message[tags]' => 'test,test2'},{:auth => @admin_auth})
245
- end
246
- should "have sent tag and both specified for sender" do
247
- resp=@client.read({},{:auth => @admin_auth})
248
- user_tags=resp[0].find_instances('user_tag')
249
- assert_same_elements ["sent", "test", "test2"], user_tags.map{|t| t.schema[:tag].col_value}
250
- end
251
- should "have inbox tag and both specified for 1st receiver (user1)" do
252
- resp=@client.read({},{:auth => @user1_auth})
253
- user_tags=resp[0].find_instances('user_tag')
254
- assert_same_elements ["inbox", "test", "test2"], user_tags.map{|t| t.schema[:tag].col_value}
255
- end
256
- should "have inbox tag and both specified for 2st receiver (user2)" do
257
- resp=@client.read({},{:auth => @user2_auth})
258
- user_tags=resp[0].find_instances('user_tag')
259
- assert_same_elements ["inbox", "test", "test2"], user_tags.map{|t| t.schema[:tag].col_value}
260
- end
261
- end
262
- context "message listing" do
263
- setup do
264
- #3 messages with tag "test" for user 1
265
- @client.create({:'private_message[recipients]' => 'user1',:'private_message[title]' => 'title1',:'private_message[message]' => 'body1', :'private_message[tags]' => 'test'},{:auth => @admin_auth})
266
- @client.create({:'private_message[recipients]' => 'user1',:'private_message[title]' => 'title2',:'private_message[message]' => 'body2', :'private_message[tags]' => 'test'},{:auth => @admin_auth})
267
- @client.create({:'private_message[recipients]' => 'user1',:'private_message[title]' => 'title3',:'private_message[message]' => 'body3', :'private_message[tags]' => 'test'},{:auth => @admin_auth})
268
- #2 messages with tag "test1" for user1 and user2
269
- @client.create({:'private_message[recipients]' => 'user2,user1',:'private_message[title]' => 'title1',:'private_message[message]' => 'body1', :'private_message[tags]' => 'test1'},{:auth => @admin_auth})
270
- @client.create({:'private_message[recipients]' => 'user2,user1',:'private_message[title]' => 'title2',:'private_message[message]' => 'body2', :'private_message[tags]' => 'test1'},{:auth => @admin_auth})
271
- end
272
- should "for sender (admin) show 3 messages with 'test' tag,2 messages with 'test1' tag, and 5 messages with 'sent' tag" do
273
- @client.auth=@admin_auth
274
- assert_equal 3, @client.read({:'private_message[tags]' => 'test'}).length
275
- assert_equal 2, @client.read({:'private_message[tags]' => 'test1'}).length
276
- assert_equal 5, @client.read({:'private_message[tags]' => 'sent'}).length
277
- end
278
- should "for user1 show 3 messages with 'test' tag, 2 messages with 'test1' tag, 5 messages with 'inbox' tag, and 5 messages with 'test' or 'test1' tags" do
279
- @client.auth=@user1_auth
280
- assert_equal 3, @client.read({:'private_message[tags]' => 'test'}).length
281
- assert_equal 2, @client.read({:'private_message[tags]' => 'test1'}).length
282
- assert_equal 5, @client.read({:'private_message[tags]' => 'inbox'}).length
283
- assert_equal 5, @client.read({:'private_message[tags]' => 'test,test1'}).length
284
- end
285
- should "for user2 show 0 messages with 'test' tag, 2 messages with 'test1' tag, 2 messages with 'inbox' tag and 2 messages with 'test' or 'test1' tags" do
286
- @client.auth=@user2_auth
287
- assert_equal 0, @client.read({:'private_message[tags]' => 'test'}).length
288
- assert_equal 2, @client.read({:'private_message[tags]' => 'test1'}).length
289
- assert_equal 2, @client.read({:'private_message[tags]' => 'inbox'}).length
290
- assert_equal 2, @client.read({:'private_message[tags]' => 'test,test1'}).length
291
- end
292
- end
293
- end
294
- context "Posts" do
295
- setup do
296
- @client.resource_name='post'
297
- end
298
- context 'validation' do
299
- should "get a validation error trying to post without a title or message as admin, user1, or user2" do
300
- resp=@client.create({},{:code => 400,:auth => @admin_auth})
301
- assert_equal :error, resp.resource_type
302
- assert_equal "validation", resp.error_type
303
- assert_equal ["is required"], resp.error_details[:title]
304
- assert_equal ["is required"], resp.error_details[:message]
305
- user1_resp=@client.create({},{:code => 400,:auth => @user1_auth})
306
- assert_equal user1_resp, resp
307
- user2_resp=@client.create({},{:code => 400,:auth => @user2_auth})
308
- assert_equal user2_resp, resp
309
- end
310
- should "be able to post with title and message as admin, user1, or user2" do
311
- assert @client.create({'post[title]' => 'test', 'post[message]' => 'asdf'},{:auth => @admin_auth})
312
- assert_equal 1, @client.read({},{:auth => @user1_auth}).length
313
- assert @client.create({'post[title]' => 'test', 'post[message]' => 'asdf'},{:auth => @user1_auth})
314
- assert_equal 2, @client.read({},{:auth => @user2_auth}).length
315
- assert @client.create({'post[title]' => 'test', 'post[message]' => 'asdf'},{:auth => @user2_auth})
316
- assert_equal 3, @client.read({},{:auth => @admin_auth}).length
317
- end
318
- end
319
- should 'list posts by public tags' do
320
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'admintag1,admintag2'},{:auth => @admin_auth})
321
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'admintag1,admintag2,admintag3'},{:auth => @admin_auth})
322
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'user1tag1'},{:auth => @user1_auth})
323
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'user1tag1,user1tag2'},{:auth => @user1_auth})
324
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'user1tag1,user1tag2,user1tag3'},{:auth => @user1_auth})
325
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'user2tag1,user2tag2,user2tag3'},{:auth => @user2_auth})
326
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'user2tag1,user2tag2,user2tag3,user2tag4'},{:auth => @user2_auth})
327
- assert_equal 7, @client.read({},{:auth => @admin_auth}).length
328
- assert_equal 7, @client.read({'post[title]' => 'test'},{:auth => @admin_auth}).length
329
- assert_equal 7, @client.read({'post[title]' => 'test'},{:auth => @user1_auth}).length
330
- assert_equal 7, @client.read({'post[title]' => 'test'},{:auth => @user2_auth}).length
331
- assert_equal 2, @client.read({'post[tags]' => 'admintag1'},{:auth => @admin_auth}).length
332
- assert_equal 2, @client.read({'post[tags]' => 'admintag1'},{:auth => @user1_auth}).length
333
- assert_equal 1, @client.read({'post[tags]' => 'admintag3'},{:auth => @user2_auth}).length
334
- assert_equal 1, @client.read({'post[tags]' => 'admintag3'},{:auth => @admin_auth}).length
335
- assert_equal 2, @client.read({'post[tags]' => 'user1tag2'},{:auth => @admin_auth}).length
336
- assert_equal 3, @client.read({'post[tags]' => 'user1tag1'},{:auth => @admin_auth}).length
337
- assert_equal 3, @client.read({'post[tags]' => 'user1tag1'},{:auth => @user2_auth}).length
338
- end
339
- should 'have usable reply, new_tags, and new_user_tags instance actions' do
340
- @client.create({'post[title]' => 'test', 'post[message]' => 'asdf','post[tags]' => 'admintag1,admintag2'},{:auth => @admin_auth})
341
- @client.auth=@user2_auth
342
- posts=@client.read({})
343
- assert_same_elements ['reply','new_tags','new_user_tags'], posts[0].get_actions
344
- reply=@client.read({},{:instance_id => posts[0].schema[:id].col_value,:method => 'reply'})
345
- tags=@client.read({},{:instance_id => posts[0].schema[:id].col_value,:method => 'new_tags'})
346
- user_tags=@client.read({},{:instance_id => posts[0].schema[:id].col_value,:method => 'new_user_tags'})
347
- assert_equal 're: test', reply.schema[:title].col_value
348
- assert @client.create(reply.to_params.merge('post[message]' => 'asdf'),{:method => nil,:instance_id => nil})
349
- assert @client.create(tags.to_params.merge('post[tags]' => '1,2,3'),{:url => tags.url})
350
- assert_same_elements ['1','2','3','admintag1','admintag2'], @client.read[0].find_instances('public_tag').map{|t| t.schema[:tag].col_value}
351
- assert @client.create(user_tags.to_params.merge('post[user_tags]' => '4,5,6'),{:url => user_tags.url})
352
- assert_same_elements ['4','5','6'], @client.read[0].find_instances('user_tag').map{|t| t.schema[:tag].col_value}
353
- assert_equal [], @client.read({},{:auth => @user1_auth})[0].find_instances('user_tag').map{|t| t.schema[:tag].col_value}
354
- end
355
- end
356
- end