rack-a_day_without 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YjIxNDM3NmRjZDI3Yjc0ZDc1ZDJjZDAyMWFhMzE5OWYxN2ZiZTFhOA==
5
+ data.tar.gz: !binary |-
6
+ ZjNjMWM0ZjI1ZDhhNmEyMTc5NDg1YzA1Njc4MjE2OTY1NWE3ZDNjZA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ N2Q4ZDkyZDA4OWJhZmI2OGMxM2RhYzc3MTMyMDVmN2FiNDU5Zjg3NmU2NWQz
10
+ ZTM0ZGY2NDQzZGRmY2M4YzZmZTc4MzE3ODBjOTI5YjBhMjMwOTM3ZTM5Yjk2
11
+ NTdlYTJiNjJkNDQyOWQ3Y2M1OTgxYzljN2JmMDc4ZmY3ZDcwOWU=
12
+ data.tar.gz: !binary |-
13
+ NTBlYzQzMjJlNmZkYTAzYjZlZjk2MjZlNTkwM2JkOGVlNjJjMDRkNTAwMTBj
14
+ ODhkNTUzNmE4MTUwOGZjNTczNzJiZmQ4ZjRiMGY2OGNmNjUxOGFlMGE5Njhk
15
+ YWNjMmNhOGViOTE3ODM1MmM0ZmQxNzBkZmM2YTdmMThmMzhhZGI=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in a_day_without.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Jack Jennings
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,72 @@
1
+ # Rack::ADayWithout
2
+
3
+ `Rack::ADayWithout` is a middleware for Rack-based web applications, originally built to display alternate content for the [Day Without Art](https://en.wikipedia.org/wiki/Day_Without_Art).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'rack-a_day_without', require: 'rack/a_day_without'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install rack-a_day_without
18
+
19
+ ## Usage
20
+
21
+ Use `Rack::ADayWithout` as a middleware in your Rack (or Rails) application. The `on` option must be set to the date the site should serve the alternate content.
22
+
23
+ ```ruby
24
+ use Rack::ADayWithout, 'Art', on: '1/12/2014'
25
+ ```
26
+
27
+ You can also use the alternate syntax which uses child-classes to set the `subject` of ADayWithout. This is equivalent to the above example:
28
+
29
+ ```ruby
30
+ use Rack::ADayWithout::Art, on: '1/12/2014'
31
+ ```
32
+
33
+ ### Writing Content
34
+
35
+ By default, the middleware will write an empty content string for all requests on the specified day. If the `content` or `file` options are set, the content string or file contents will be written instead.
36
+
37
+ ```ruby
38
+ use Rack::ADayWithout, 'Art', on: '1/12/2014', content: 'A Day Without Art'
39
+ # or...
40
+ use Rack::ADayWithout, 'Art', on: '1/12/2014', file: './public/index.html'
41
+ ```
42
+
43
+ ### Bypass Routes
44
+
45
+ The `bypass` option allows some routes to pass through the middleware without being blocked. This can be useful if you have an admin area that should still be available during the day without. `bypass` can be set to be a `String`, a `Regexp` or an `Array` of either.
46
+
47
+ ```ruby
48
+ use Rack::ADayWithout, 'Art', on: '1/12/2014',
49
+ bypass: [/^\/admin/, '/about']
50
+ ```
51
+
52
+ ## With Rails
53
+
54
+ Load the rack middleware inside of `config/application.rb`:
55
+
56
+ ```ruby
57
+ module YourApp
58
+ class Application < Rails::Application
59
+ # ...
60
+
61
+ config.middleware.use Rack::ADayWithout, 'Art', on: '22/11/2014'
62
+ end
63
+ end
64
+ ```
65
+
66
+ ## Contributing
67
+
68
+ 1. Fork it
69
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
70
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
71
+ 4. Push to the branch (`git push origin my-new-feature`)
72
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new(:test) do |t|
5
+ t.libs << "test"
6
+ end
7
+
8
+ task :default => :test
@@ -0,0 +1,5 @@
1
+ module Rack
2
+ class ADayWithout
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,73 @@
1
+ require "date"
2
+ require "rack"
3
+ require "rack/a_day_without/version"
4
+
5
+ module Rack
6
+ class ADayWithout
7
+
8
+ def self.const_missing const_name
9
+ const_set const_name, self.new_subject_subclass
10
+ end
11
+
12
+ def self.new_subject_subclass
13
+ Class.new(self) do
14
+ def initialize app, options = {}
15
+ subject = self.class.name.split('::').last
16
+ super app, subject, options
17
+ end
18
+ end
19
+ end
20
+
21
+ def initialize app, subject, options = {}
22
+ @app = app
23
+ @subject = subject
24
+ @content = options[:content]
25
+ @file = options[:file]
26
+ @date = parse_date options[:on]
27
+ @allowed = parse_allowed_routes options[:bypass]
28
+ end
29
+
30
+ def call env
31
+ allowed = allowed_path? env['PATH_INFO']
32
+ if @date == Date.today && !allowed
33
+ res = Response.new
34
+ res["X-Day-Without"] = @subject
35
+ res.write content
36
+ res.finish
37
+ else
38
+ @app.call env
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def content
45
+ if @file
46
+ ::File.read @file
47
+ else
48
+ @content.to_s
49
+ end
50
+ end
51
+
52
+ def parse_allowed_routes allowed
53
+ if allowed.nil?
54
+ []
55
+ elsif allowed.respond_to? :to_ary
56
+ allowed.to_ary || [allowed]
57
+ else
58
+ [allowed]
59
+ end
60
+ end
61
+
62
+ def parse_date dateish
63
+ Date.parse dateish.to_s
64
+ end
65
+
66
+ def allowed_path? path
67
+ @allowed.any? do |a|
68
+ a.is_a?(Regexp) ? a.match(path.to_s) : a == path.to_s
69
+ end
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'rack/a_day_without/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "rack-a_day_without"
8
+ spec.version = Rack::ADayWithout::VERSION
9
+ spec.authors = ["Jack Jennings"]
10
+ spec.email = ["j@ckjennin.gs"]
11
+ spec.summary = %q{Rack middleware for serving alternate content on a given day}
12
+ spec.homepage = "http://github.com/jackjennings/rack-a_day_without"
13
+ spec.license = "MIT"
14
+
15
+ spec.files = `git ls-files`.split($/)
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_dependency "rack", "~> 1.4"
21
+
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake", "~> 0"
24
+ spec.add_development_dependency "minitest", "~> 5.4"
25
+ end
@@ -0,0 +1,2 @@
1
+ <!DOCTYPE html>
2
+ <html><head></head><body>Hi!</body></html>
@@ -0,0 +1,5 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'rack/a_day_without'
3
+
4
+ require 'minitest'
5
+ require 'minitest/autorun'
@@ -0,0 +1,140 @@
1
+ require 'minitest_helper'
2
+
3
+ describe Rack::ADayWithout do
4
+
5
+ it 'must have a version number' do
6
+ Rack::ADayWithout::VERSION.wont_be_nil
7
+ end
8
+
9
+ describe 'when used as middleware' do
10
+ before do
11
+ @app = Proc.new do
12
+ Rack::Response.new {|r| r.write 'Downstream app'}.finish
13
+ end
14
+ end
15
+
16
+ it 'blocks a request' do
17
+ endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.today
18
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
19
+ status.must_equal 200
20
+ body.body.must_equal ['']
21
+ end
22
+
23
+ it 'passes a request' do
24
+ endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.new
25
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
26
+ status.must_equal 200
27
+ body.body.must_equal ['Downstream app']
28
+ end
29
+
30
+ it 'blocks with supplied content' do
31
+ endpoint = Rack::ADayWithout.new @app, 'Art',
32
+ on: Date.today,
33
+ content: 'foobar'
34
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
35
+ status.must_equal 200
36
+ body.body.must_equal ['foobar']
37
+ end
38
+
39
+ it 'blocks with supplied file' do
40
+ path = 'test/fixtures/index.html'
41
+ content = File.read(path)
42
+ endpoint = Rack::ADayWithout.new @app, 'Art',
43
+ on: Date.today,
44
+ file: path
45
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
46
+ status.must_equal 200
47
+ body.body.must_equal [content]
48
+ end
49
+
50
+ it 'passes allowed routes' do
51
+ endpoint = Rack::ADayWithout.new @app, 'Art',
52
+ on: Date.today,
53
+ bypass: '/bar'
54
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
55
+ status.must_equal 200
56
+ body.body.must_equal ['Downstream app']
57
+ end
58
+
59
+ it 'blocks sub-path of allowed routes' do
60
+ endpoint = Rack::ADayWithout.new @app, 'Art',
61
+ on: Date.today,
62
+ bypass: '/bar'
63
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar/bar'))
64
+ status.must_equal 200
65
+ body.body.must_equal ['']
66
+ end
67
+
68
+ it 'passes allowed routes as regexp' do
69
+ endpoint = Rack::ADayWithout.new @app, 'Art',
70
+ on: Date.today,
71
+ bypass: %r{^/bar}
72
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar/baz'))
73
+ status.must_equal 200
74
+ body.body.must_equal ['Downstream app']
75
+ end
76
+
77
+ it 'passes allowed routes as array' do
78
+ endpoint = Rack::ADayWithout.new @app, 'Art',
79
+ on: Date.today,
80
+ bypass: ['/bar', '/baz']
81
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
82
+ status.must_equal 200
83
+ body.body.must_equal ['Downstream app']
84
+ end
85
+
86
+ it 'passes allowed routes as array with regexps' do
87
+ endpoint = Rack::ADayWithout.new @app, 'Art',
88
+ on: Date.today,
89
+ bypass: [%r{^/bar}, '/baz']
90
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar/baz'))
91
+ status.must_equal 200
92
+ body.body.must_equal ['Downstream app']
93
+ end
94
+
95
+ it 'sets HTTP header when blocked' do
96
+ endpoint = Rack::ADayWithout.new @app, 'Art',
97
+ on: Date.today
98
+ status, headers, body = endpoint.call(Rack::MockRequest.env_for('/bar'))
99
+ headers['X-Day-Without'].must_equal 'Art'
100
+ end
101
+ end
102
+
103
+ describe 'when initialized' do
104
+ it 'parses a date' do
105
+ date = '20/10/2014'
106
+ endpoint = Rack::ADayWithout.new @app, 'Art', on: date
107
+ endpoint.instance_variable_get('@date').must_equal Date.parse(date)
108
+ end
109
+
110
+ it 'parses a date' do
111
+ date = '20/10/2014'
112
+ endpoint = Rack::ADayWithout.new @app, 'Art', on: date
113
+ endpoint.instance_variable_get('@date').must_equal Date.parse(date)
114
+ end
115
+
116
+ it 'stores a subject' do
117
+ endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.new
118
+ endpoint.instance_variable_get('@subject').must_equal 'Art'
119
+ end
120
+
121
+ it 'stores allowed routes in array' do
122
+ endpoint = Rack::ADayWithout.new @app, 'Art', on: Date.new, bypass: 'foo'
123
+ endpoint.instance_variable_get('@allowed').must_equal ['foo']
124
+ end
125
+ end
126
+
127
+ describe 'when dynamically subclassed' do
128
+ it 'creates a subclass' do
129
+ endpoint = Rack::ADayWithout::Art
130
+ endpoint.name.must_equal "Rack::ADayWithout::Art"
131
+ endpoint.ancestors.must_include Rack::ADayWithout
132
+ end
133
+
134
+ it 'store subject by name' do
135
+ endpoint = Rack::ADayWithout::Art.new @app, on: Date.today
136
+ endpoint.instance_variable_get('@subject').must_equal 'Art'
137
+ end
138
+ end
139
+
140
+ end
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-a_day_without
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jack Jennings
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.4'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.4'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '5.4'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '5.4'
69
+ description:
70
+ email:
71
+ - j@ckjennin.gs
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .travis.yml
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - lib/rack/a_day_without.rb
83
+ - lib/rack/a_day_without/version.rb
84
+ - rack-a_day_without.gemspec
85
+ - test/fixtures/index.html
86
+ - test/minitest_helper.rb
87
+ - test/test_rack_a_day_without.rb
88
+ homepage: http://github.com/jackjennings/rack-a_day_without
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ! '>='
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ! '>='
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.4.4
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Rack middleware for serving alternate content on a given day
112
+ test_files:
113
+ - test/fixtures/index.html
114
+ - test/minitest_helper.rb
115
+ - test/test_rack_a_day_without.rb