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.
- data/README.rdoc +2 -27
- data/Rakefile +3 -0
- data/TODO +11 -9
- data/lib/joints/basic_menu_system.rb +6 -23
- data/lib/joints/basic_messaging.rb +3 -3
- data/lib/joints/basic_user.rb +2 -2
- data/lib/joints/tagged_messaging.rb +4 -4
- data/lib/joints/tagging.rb +5 -9
- data/lib/marley.rb +21 -36
- data/lib/marley/joint.rb +4 -0
- data/lib/marley/reggae.rb +15 -10
- data/lib/marley/test_helpers.rb +1 -2
- data/lib/marley/utils.rb +36 -0
- data/lib/sequel/plugins/rest_convenience.rb +72 -76
- data/marley-0.3.0.gem +0 -0
- data/marley.gemspec +4 -2
- data/reggae.ebnf +11 -5
- data/test/tagged_messaging_tests.rb +4 -4
- data/test/test.sqlite3 +0 -0
- data/test/user_tests.rb +1 -1
- metadata +6 -5
- data/forum_tests.rb +0 -356
- data/lib/joints/user_based_navigation.rb +0 -39
data/lib/marley/test_helpers.rb
CHANGED
@@ -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)
|
data/lib/marley/utils.rb
ADDED
@@ -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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
-
|
28
|
+
raise Marley::AuthorizationError
|
30
29
|
end
|
31
|
-
|
32
|
-
|
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
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
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
|
-
|
51
|
-
|
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
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
-
|
80
|
-
|
81
|
-
|
82
|
-
to_a
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
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.
|
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' | '
|
18
|
+
instance_property ::= 'name' | 'url' | 'new_rec' | 'search' | 'schema' | 'actions'
|
19
19
|
|
20
|
-
instance_list_property ::='title' | 'description' | 'schema' | '
|
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
|
-
|
42
|
+
actions_value ::= '{' '"' ('get' | 'post' | 'put' | 'delete') '"' ':' methods (',' '"' ('get' | 'post' | 'put' | 'delete') '"' ':' methods )* '}'
|
43
43
|
|
44
|
-
|
44
|
+
methods::= '[' ( get_method (',' get_method)* | post_method (',' post_method)* | put_method (',' put_method)* | delete_method (',' delete_method)* ) ']'
|
45
45
|
|
46
|
-
|
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].
|
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].
|
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].
|
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].
|
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.
|
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-
|
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
|
-
-
|
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
|