ape 1.5.1 → 1.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -57,6 +57,10 @@ module Ape
57
57
  end
58
58
  return false
59
59
  end
60
+
61
+ def code
62
+ @response.code
63
+ end
60
64
 
61
65
  def getBody contentType
62
66
 
@@ -66,15 +70,27 @@ module Ape
66
70
  if @contentType =~ /^([^;]*);/
67
71
  @contentType = $1
68
72
  end
69
-
73
+
70
74
  if contentType != @contentType
71
- @last_error = "Content-type must be '#{contentType}', not '#{@contentType}'"
75
+ @response = Net::HTTPGone.new('1.1', '409',
76
+ "Content-type must be '#{contentType}', not '#{@contentType}'")
77
+ @body = ""
72
78
  end
73
79
  end
74
80
 
75
81
  @body = @response.body
76
82
  return true
77
83
  end
84
+
85
+ # Handy wrapper with optional media-type checking; return the Response object
86
+ def Getter.retrieve(uri, content_type=nil, authent=nil)
87
+
88
+ getter = Getter.new(uri, authent)
89
+ raise(Exception, "Bad URI value #{uri}") if getter.last_error
90
+
91
+ getter.get content_type
92
+ return getter.response
93
+ end
78
94
  end
79
95
  end
80
96
 
@@ -8,12 +8,11 @@ module Ape
8
8
 
9
9
  def initialize(uriString, authent)
10
10
  super uriString, authent
11
- @headers = {}
12
11
  @entry = nil
13
12
  end
14
13
 
15
- def set_header(name, val)
16
- @headers[name] = val
14
+ def authoritative?
15
+ @response['Location'] == @response['Content-Location']
17
16
  end
18
17
 
19
18
  def post(contentType, body, req = nil)
@@ -35,16 +34,16 @@ module Ape
35
34
  return false
36
35
  end
37
36
 
38
- if (!((@response['Content-type'] =~ %r{^application/atom\+xml}) ||
39
- (@response['Content-type'] =~ %r{^application/atom\+xml;type=entry})))
37
+ # XXX how can this happen?
38
+ if (!(@response['Content-type'] =~ %r{^application/atom\+xml(;type=entry)?}))
40
39
  return true
41
40
  end
42
41
 
43
42
  begin
44
- @entry = Entry.new(@response.body)
43
+ @entry = Entry.new(:text => @response.body, :uri => @response['Location'])
45
44
  return true
46
45
  rescue ArgumentError
47
- @last_error = @entry.broken
46
+ @last_error = $!.to_s
48
47
  return false
49
48
  end
50
49
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved
1
+ # Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved
2
2
  # Use is subject to license terms - see file "LICENSE"
3
3
 
4
4
  module Ape
@@ -16,6 +16,7 @@ module Ape
16
16
 
17
17
  AtomMediaType = 'application/atom+xml' unless defined?(AtomMediaType)
18
18
  AtomEntryMediaType = 'application/atom+xml;type=entry' unless defined?(AtomEntryMediaType)
19
+ AtomFeedMediaType = 'application/atom+xml;type=feed' unless defined?(AtomFeedMediaType)
19
20
  AppMediaType = 'application/atomsvc+xml' unless defined?(AppMediaType)
20
21
 
21
22
  end
@@ -23,7 +23,7 @@ module Ape
23
23
 
24
24
  def self.supported_outputs
25
25
  Dir[File.join(File.dirname(__FILE__), 'reporters/*.rb'),
26
- File.join(Ape.home, 'reporters/*.rb')].map { |file|
26
+ File.join(::Ape.home, 'reporters/*.rb')].map { |file|
27
27
  file.gsub(/(.+\/reporters\/)(.+)(_reporter.rb)/, '\2').gsub(/_/, '')
28
28
  }.sort.join(", ").downcase
29
29
  end
@@ -61,8 +61,8 @@ module Ape
61
61
  end
62
62
 
63
63
  def Samples.entry_path(type)
64
- File.exist?(File.join(Ape.home, "/#{type}.eruby"))?
65
- File.join(Ape.home, "/#{type}.eruby") :
64
+ File.exist?(File.join(::Ape.home, "/#{type}.eruby"))?
65
+ File.join(::Ape.home, "/#{type}.eruby") :
66
66
  File.join(File.dirname(__FILE__), "/../../samples/#{type}.eruby")
67
67
  end
68
68
 
@@ -16,7 +16,7 @@ module Ape
16
16
  # * :port - the port number to listen on
17
17
  # * :directory - the ape home directory
18
18
  def self.run(options)
19
- Ape.home = options[:home]
19
+ ::Ape.home = options[:home]
20
20
 
21
21
  mongrel = Mongrel::Configurator.new(:host => options[:host], :port => options[:port]) do
22
22
  log "=> Booting mongrel"
@@ -4,9 +4,26 @@ require 'rexml/xpath'
4
4
 
5
5
  module Ape
6
6
  class Service
7
- def Service.collections(service, uri)
8
- nodes = REXML::XPath.match(service, '//app:collection', Names::XmlNamespaces)
9
- nodes.collect { |n| Collection.new(n, uri) }
7
+ require File.dirname(__FILE__) + '/util.rb'
8
+ include Ape::Util::InstanceMethods
9
+
10
+ attr_accessor :service, :reporter
11
+
12
+ def initialize(opts = {}) #uri = nil, authent = nil)
13
+ @authent = opts[:authent]
14
+ @reporter = opts[:reporter]
15
+ if opts[:uri]
16
+ @uri = opts[:uri]
17
+ resource = check_resource(@uri, 'Service document', Names::AppMediaType, @reporter)
18
+ raise StandardError, "Service document not found at: #{@uri}" unless resource
19
+
20
+ @service = REXML::Document.new(resource.body, { :raw => nil })
21
+ end
22
+ end
23
+
24
+ def collections(uri = @uri)
25
+ nodes = REXML::XPath.match(@service, '//app:collection', Names::XmlNamespaces)
26
+ nodes.collect { |n| CollElement.new(n, uri) }
10
27
  end
11
28
  end
12
29
  end
@@ -1,9 +1,14 @@
1
1
  module Ape
2
2
  module Util
3
- def self.included(base)
4
- base.extend ClassMethods
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
5
  include InstanceMethods
6
6
  end
7
+
8
+ def self.extended(base)
9
+ base.extend InstanceMethods
10
+ base.extend ClassMethods
11
+ end
7
12
 
8
13
  module InstanceMethods
9
14
  =begin
@@ -20,9 +25,9 @@ module Ape
20
25
 
21
26
  # * Get it, make sure it has the right content-type
22
27
  worked = resource.get(content_type)
23
- reporter.save_dialog(name, resource)
28
+ reporter.save_dialog(name, resource) if report
24
29
 
25
- reporter.security_warning(self) if (resource.security_warning)
30
+ reporter.security_warning(self) if (resource.security_warning && report)
26
31
 
27
32
  if !worked
28
33
  # oops, couldn't even get get it
@@ -32,7 +37,6 @@ module Ape
32
37
  elsif resource.last_error
33
38
  # oops, media-type problem
34
39
  reporter.error(self, "#{name}: #{resource.last_error}", name) if report
35
-
36
40
  else
37
41
  # resource fetched and is of right type
38
42
  reporter.success(self, "#{name}: it exists and is served properly.", name) if report
@@ -48,7 +52,7 @@ module Ape
48
52
  resolvers or samples.
49
53
  =end
50
54
  def resolve_plugin(key, dir, suffix, drop_underlines = false)
51
- [File.dirname(__FILE__), Ape.home].each do |path|
55
+ [File.dirname(__FILE__), ::Ape.home].each do |path|
52
56
  Dir[File.join(path, "#{dir}/*.rb")].each do |file|
53
57
  require file
54
58
  plugin_name = file.gsub(/(.+\/#{dir}\/)(.+)(_#{suffix}.rb)/, '\2')
@@ -64,4 +68,4 @@ resolvers or samples.
64
68
  end
65
69
  end
66
70
  end
67
- end
71
+ end
@@ -11,7 +11,7 @@ module Ape
11
11
 
12
12
  def self.custom_validators(reporter, authent)
13
13
  validators = []
14
- Dir[Ape.home + '/validators/*.rb'].each do |v|
14
+ Dir[::Ape.home + '/validators/*.rb'].each do |v|
15
15
  require v
16
16
  class_name = v.gsub(/(.+\/validators\/)(.+)(.rb)/, '\2').gsub(/(^|_)(.)/) { $2.upcase }
17
17
  validator = eval("#{class_name}.new", binding, __FILE__, __LINE__)
@@ -29,7 +29,7 @@ module Ape
29
29
  return
30
30
  end
31
31
 
32
- my_entry = Entry.new(Samples.basic_entry)
32
+ my_entry = Entry.new(:text => Samples.basic_entry)
33
33
 
34
34
  # ask it to use this in the URI
35
35
  slug_num = rand(100000)
@@ -71,7 +71,7 @@ module Ape
71
71
  reporter.info(self, "Examining the new entry as retrieved using Location header in POST response:")
72
72
 
73
73
  begin
74
- new_entry = Entry.new(new_entry.body, location)
74
+ new_entry = Entry.new(:text => new_entry.body, :uri => location)
75
75
  rescue REXML::ParseException
76
76
  prob = $!.to_s.gsub(/\n/, '<br/>')
77
77
  reporter.error(self, "New entry is not well-formed: #{prob}")
@@ -99,7 +99,6 @@ module Ape
99
99
  # * fetch the feed again and check that version
100
100
  from_feed = find_entry(collection_uri, "entry collection", entry_id)
101
101
  if from_feed.class == String
102
- reporter.success(self, "About to check #{collection_uri}")
103
102
  Feed.read(collection_uri, "Can't find entry in collection", reporter)
104
103
  reporter.error(self, "New entry didn't show up in the collections feed.")
105
104
  return
@@ -30,7 +30,7 @@ module Ape
30
30
  return
31
31
  end
32
32
 
33
- ids = entries.map { |e| e.child_content('id)') }
33
+ ids = entries.map { |e| e.child_content('id') }
34
34
 
35
35
  # let's update one of them; have to fetch it first to get the ETag
36
36
  two_media = entries[1].link('edit-media')
@@ -75,4 +75,4 @@ module Ape
75
75
  reporter.success(self, "Entries correctly ordered after update of multi-post.")
76
76
  end
77
77
  end
78
- end
78
+ end
@@ -25,7 +25,6 @@ module Ape
25
25
  slug_re = %r{apix.?#{slug_num}}
26
26
  poster.set_header('Slug', slug)
27
27
 
28
- #poster.set_header('Slug', slug)
29
28
  worked = poster.post('image/jpeg', Samples.picture)
30
29
  reporter.save_dialog(name, poster)
31
30
  if !worked
@@ -50,7 +49,7 @@ module Ape
50
49
 
51
50
  # * See if the <content src= is there and usable
52
51
  begin
53
- media_link_entry = Entry.new(media_link_entry.body, mle_uri)
52
+ media_link_entry = Entry.new(:text => media_link_entry.body, :uri => mle_uri)
54
53
  rescue REXML::ParseException
55
54
  prob = $!.to_s.gsub(/\n/, '<br/>')
56
55
  reporter.error(self, "Media link entry is not well-formed: #{prob}")
@@ -22,7 +22,7 @@ module Ape
22
22
  return unless entry
23
23
 
24
24
  begin
25
- entry = Entry.new(entry.body, location)
25
+ entry = Entry.new(:text => entry.body, :uri => location)
26
26
  rescue REXML::ParseException
27
27
  prob = $!.to_s.gsub(/\n/, '<br/>')
28
28
  reporter.error(self, "New entry is not well-formed: #{prob}")
@@ -6,30 +6,23 @@ module Ape
6
6
 
7
7
  def validate(opts = {})
8
8
  init_service_document(opts[:uri])
9
- raise ValidationError, "service document not found in: #{opts[uri]}" unless @service
10
9
  init_service_collections(opts[:uri])
11
- raise ValidationError unless @entry_collections && @media_collections
12
10
  end
13
11
 
14
12
  def init_service_document(uri)
15
13
  reporter.info(self, "TESTING: Service document and collections.")
16
- name = 'Retrieval of Service Document'
17
- service = check_resource(uri, name, Names::AppMediaType)
18
- return unless service
19
-
20
- # * XML-parse the service doc
21
- text = service.body
14
+
22
15
  begin
23
- @service = REXML::Document.new(text, { :raw => nil })
24
- rescue REXML::ParseException
16
+ @service_document = Service.new(:uri => uri, :reporter => reporter )
17
+ rescue Exception
25
18
  prob = $!.to_s.gsub(/\n/, '<br/>')
26
- reporter.error(self, "Service document not well-formed: #{prob}")
19
+ reporter.error(self, "Service document not usable: #{prob}")
27
20
  return
28
21
  end
29
22
 
30
23
  # RNC-validate the service doc
31
24
  Validator.instance(:schema, @reporter).validate(:schema => Samples.service_RNC,
32
- :title => 'Service doc', :doc => @service)
25
+ :title => 'Service doc', :doc => @service_document.service)
33
26
  end
34
27
 
35
28
  def init_service_collections(uri)
@@ -37,23 +30,20 @@ module Ape
37
30
  # the requested_* arguments are the requested collection titles; if
38
31
  # provided, try to match them, otherwise just pick the first listed
39
32
  #
40
- begin
41
- @service_collections = Service.collections(@service, uri)
42
- rescue Exception
43
- reporter.error(self, "Couldn't read collections from service doc: #{$!}")
44
- return
45
- end
46
-
47
- if @service_collections.length > 0
33
+ collections = @service_document.collections
34
+ if collections.length > 0
35
+
48
36
  reporter.start_list(self, "Found these collections")
49
- @service_collections.each do |collection|
37
+ collections.each do |collection|
50
38
  reporter.list_item("'#{collection.title}' " +
51
- "accepts #{collection.accept.join(', ')}")
39
+ "accepts #{collection.accept.join(', ')}")
52
40
 
53
- if (collection.accept.index(Names::AtomEntryMediaType))
41
+ if collection.accept?(Names::AtomEntryMediaType)
54
42
  @entry_collections ||= []
55
43
  @entry_collections << collection
56
- else
44
+ end
45
+
46
+ if collection.accept?('image/jpeg')
57
47
  @media_collections ||= []
58
48
  @media_collections << collection
59
49
  end
@@ -1,8 +1,8 @@
1
- module Ape
2
- module VERSION
1
+ module Ape #:nodoc:
2
+ module VERSION #:nodoc:
3
3
  MAJOR = 1
4
- MINOR = 5
5
- TINY = 1
4
+ MINOR = 6
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -15,7 +15,7 @@ module Writer
15
15
  end
16
16
  end
17
17
  Ape::Invoker.send(:include, Writer)
18
-
18
+
19
19
  module ApeAccessors
20
20
  def service=(service)
21
21
  @service = service
@@ -47,3 +47,26 @@ class ValidatorMock < Ape::Validator
47
47
  deterministic
48
48
  requires_presence_of :entry_collection
49
49
  end
50
+
51
+ def collection(title, accept = ['application/atom+xml;type=entry'])
52
+ collection = "<collection href=\"http://localhost\">" +
53
+ "<atom:title>#{title}</atom:title>"
54
+ accept.each do |a|
55
+ collection += "<accept>#{a}</accept>"
56
+ end
57
+ collection += "</collection>"
58
+ end
59
+
60
+ def service(&block)
61
+ service = "<service xmlns=\"http://www.w3.org/2007/app\"" +
62
+ " xmlns:atom=\"http://www.w3.org/2005/Atom\"><workspace>"
63
+ service += yield
64
+ service += "</workspace></service>"
65
+ REXML::Document.new(service)
66
+ end
67
+
68
+ def collections(&block)
69
+ s = service(&block)
70
+ nodes = REXML::XPath.match(s, '//app:collection', Ape::Names::XmlNamespaces)
71
+ nodes.collect { |n| Ape::CollElement.new(n) }
72
+ end
@@ -10,26 +10,26 @@ class ApeTest < Test::Unit::TestCase
10
10
  end
11
11
 
12
12
  def test_check_manifest_raises_validation_error
13
- @ape.entry_collections = service { collection('Attachments', ['image/jpg']) }
13
+ @ape.media_collections = collections { collection('Attachments', ['image/jpg']) }
14
14
  assert_raise(Ape::ValidationError) {
15
- variables = @ape.check_manifest(ValidatorMock.new)
15
+ @ape.check_manifest(ValidatorMock.new)
16
16
  }
17
17
  end
18
18
 
19
19
  def test_check_manifest_assert_first_entry_collection
20
- @ape.entry_collections = service { collection('Posts') }
20
+ @ape.entry_collections = collections { collection('Posts') }
21
21
  variables = @ape.check_manifest(ValidatorMock.new)
22
22
  assert_equal('Posts', variables[:entry_collection].title)
23
23
  end
24
24
 
25
25
  def test_check_manifest_assert_first_media_collection
26
- @ape.media_collections = service { collection('Attachments', ['image/jpg']) }
26
+ @ape.media_collections = collections { collection('Attachments', ['image/jpg']) }
27
27
  variables = stub_manifest([:media_collection])
28
28
  assert_equal('Attachments', variables[:media_collection].title)
29
29
  end
30
30
 
31
31
  def test_check_manifest_assert_select_last_collection
32
- @ape.entry_collections = service {
32
+ @ape.entry_collections = collections {
33
33
  collection('Posts') +
34
34
  collection('Comments')
35
35
  }
@@ -39,7 +39,7 @@ class ApeTest < Test::Unit::TestCase
39
39
  end
40
40
 
41
41
  def test_select_first_collection_by_type
42
- @ape.entry_collections = service {
42
+ @ape.entry_collections = collections {
43
43
  collection('Posts') +
44
44
  collection('Attachments', ['image/jpg']) +
45
45
  collection('Attachments2', ['image/png'])
@@ -49,7 +49,7 @@ class ApeTest < Test::Unit::TestCase
49
49
  end
50
50
 
51
51
  def test_select_first_collection_by_title
52
- @ape.entry_collections = service {
52
+ @ape.entry_collections = collections {
53
53
  collection('Posts') +
54
54
  collection('Attachments', ['image/jpg'])
55
55
  }
@@ -58,7 +58,7 @@ class ApeTest < Test::Unit::TestCase
58
58
  end
59
59
 
60
60
  def test_select_by_name_raises_validation_error
61
- @ape.entry_collections = service {
61
+ @ape.entry_collections = collections {
62
62
  collection('Posts') +
63
63
  collection('Attachments', ['image/jpg'])
64
64
  }
@@ -73,20 +73,4 @@ class ApeTest < Test::Unit::TestCase
73
73
  @ape.check_manifest(validator)
74
74
  end
75
75
 
76
- def collection(title, accept = ['application/atom+xml;type=entry'])
77
- collection = "<collection href=\"http://localhost\">" +
78
- "<atom:title>#{title}</atom:title>"
79
- accept.each do |a|
80
- collection += "<accept>#{a}</accept>"
81
- end
82
- collection += "</collection>"
83
- end
84
-
85
- def service(&block)
86
- service = "<service xmlns=\"http://www.w3.org/2007/app\"" +
87
- " xmlns:atom=\"http://www.w3.org/2005/Atom\"><workspace>"
88
- service += yield
89
- service += "</workspace></service>"
90
- Ape::Service.collections(REXML::Document.new(service), nil)
91
- end
92
76
  end