northpass 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/.pairs +16 -0
- data/.rspec +2 -0
- data/Gemfile +6 -0
- data/Gemfile.ocra +7 -0
- data/LICENSE.txt +22 -0
- data/README.md +100 -0
- data/Rakefile +36 -0
- data/bin/sk +10 -0
- data/bin/sk_gui +8 -0
- data/circle.yml +8 -0
- data/config/ca-bundle.crt +3894 -0
- data/config/color_scheme.css.erb +91 -0
- data/config/fixtures.yml +255 -0
- data/config/learning.html.erb +43 -0
- data/config/learning_color_scheme.css.erb +70 -0
- data/config/locale.yml +110 -0
- data/config/school_website.html.erb +37 -0
- data/lib/schoolkeep.rb +16 -0
- data/lib/schoolkeep/cli.rb +135 -0
- data/lib/schoolkeep/client.rb +54 -0
- data/lib/schoolkeep/fixture.rb +130 -0
- data/lib/schoolkeep/fixture/stubs.rb +106 -0
- data/lib/schoolkeep/gui_client.rb +99 -0
- data/lib/schoolkeep/scribble.rb +480 -0
- data/lib/schoolkeep/scribble/methods/app.rb +17 -0
- data/lib/schoolkeep/scribble/methods/collection_each.rb +3 -0
- data/lib/schoolkeep/scribble/methods/display_search_form.rb +28 -0
- data/lib/schoolkeep/scribble/methods/filter_parameter_value.rb +11 -0
- data/lib/schoolkeep/scribble/methods/hide_search_box.rb +17 -0
- data/lib/schoolkeep/scribble/methods/l.rb +13 -0
- data/lib/schoolkeep/scribble/methods/limit.rb +11 -0
- data/lib/schoolkeep/scribble/methods/no_filter_selected_class.rb +19 -0
- data/lib/schoolkeep/scribble/methods/pluralize.rb +32 -0
- data/lib/schoolkeep/scribble/methods/query_parameter_value.rb +11 -0
- data/lib/schoolkeep/scribble/methods/script.rb +45 -0
- data/lib/schoolkeep/scribble/methods/t.rb +25 -0
- data/lib/schoolkeep/server.rb +132 -0
- data/lib/schoolkeep/template.rb +67 -0
- data/lib/schoolkeep/template_names.rb +24 -0
- data/lib/schoolkeep/version.rb +3 -0
- data/lib/schoolkeep/views/asset_cache.rb +34 -0
- data/lib/schoolkeep/views/color_scheme.rb +19 -0
- data/lib/schoolkeep/views/layout.rb +72 -0
- data/media/schoolkeep.ico +0 -0
- data/media/sk-144.gif +0 -0
- data/media/sk-16.gif +0 -0
- data/media/sk-57.gif +0 -0
- data/media/sk-72.gif +0 -0
- data/schoolkeep.gemspec +28 -0
- data/spec/cli_spec.rb +70 -0
- data/spec/features/cli_spec.rb +51 -0
- data/spec/features/client_spec.rb +48 -0
- data/spec/fixture_spec.rb +68 -0
- data/spec/methods/filter_parameter_value_spec.rb +28 -0
- data/spec/methods/pluralize_spec.rb +41 -0
- data/spec/methods/query_parameter_value_spec.rb +26 -0
- data/spec/methods/script_spec.rb +52 -0
- data/spec/methods/t_spec.rb +33 -0
- data/spec/server_spec.rb +81 -0
- data/spec/spec_helper.rb +48 -0
- data/spec/views/asset_cache_spec.rb +24 -0
- data/spec/views/color_scheme_spec.rb +15 -0
- metadata +223 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
module Schoolkeep
|
2
|
+
TEMPLATE_NAMES = %w(
|
3
|
+
_course.html
|
4
|
+
_filters.html
|
5
|
+
_footer.html
|
6
|
+
_head.html
|
7
|
+
_header.html
|
8
|
+
_my_content_header.html
|
9
|
+
_search_form.html
|
10
|
+
_virtual_event_session.html
|
11
|
+
course_cover.html
|
12
|
+
course_details.html
|
13
|
+
course_index.html
|
14
|
+
custom_page.html
|
15
|
+
custom_javascript.html
|
16
|
+
custom_javascript_v1.html
|
17
|
+
custom_javascript_v2.html
|
18
|
+
homepage.html
|
19
|
+
my_content.html
|
20
|
+
not_found.html
|
21
|
+
server_error.html
|
22
|
+
styles.css
|
23
|
+
)
|
24
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "net/http"
|
2
|
+
require "uri"
|
3
|
+
|
4
|
+
module Schoolkeep
|
5
|
+
module Views
|
6
|
+
class AssetCache
|
7
|
+
attr_reader :host
|
8
|
+
|
9
|
+
def initialize(host)
|
10
|
+
@host = host
|
11
|
+
end
|
12
|
+
|
13
|
+
def [](path)
|
14
|
+
cached_get(path) || path
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def get(path)
|
20
|
+
url = File.join(host, path)
|
21
|
+
res = Net::HTTP.get_response(URI(url))
|
22
|
+
res["location"]
|
23
|
+
end
|
24
|
+
|
25
|
+
def cached_get(path)
|
26
|
+
cache[path] ||= get(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def cache
|
30
|
+
@cache ||= {}
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "schoolkeep"
|
2
|
+
require "erb"
|
3
|
+
require "schoolkeep/fixture"
|
4
|
+
|
5
|
+
module Schoolkeep
|
6
|
+
module Views
|
7
|
+
class ColorScheme
|
8
|
+
def initialize(name)
|
9
|
+
@_name = name
|
10
|
+
@color_scheme = Fixture.for("styles.css.sktl")[:color_palette]
|
11
|
+
end
|
12
|
+
|
13
|
+
def render
|
14
|
+
css_path = File.join(GEM_ROOT, "config/#{@_name}.css.erb")
|
15
|
+
ERB.new(File.read(css_path), nil, "-").result(binding)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "schoolkeep"
|
3
|
+
require "schoolkeep/template"
|
4
|
+
require "schoolkeep/fixture"
|
5
|
+
require "schoolkeep/views/asset_cache"
|
6
|
+
|
7
|
+
module Schoolkeep
|
8
|
+
module Views
|
9
|
+
class Layout
|
10
|
+
class << self
|
11
|
+
attr_accessor :asset_host
|
12
|
+
|
13
|
+
def asset_cache
|
14
|
+
@asset_cache ||= AssetCache.new(asset_host)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
BODY_CLASSES = {
|
19
|
+
"course_details.html.sktl" => "school_website-courses school_website-courses-show",
|
20
|
+
"course_index.html.sktl" => "school_website-courses school_website-courses-index",
|
21
|
+
"custom_page.html.sktl" => "school_website-custom_pages school_website-custom_pages-show",
|
22
|
+
"homepage.html.sktl" => "school_website-homepages school_website-homepages-show",
|
23
|
+
"my_content.html.sktl" => "school_website-my_content school_website-my_content-index"
|
24
|
+
}
|
25
|
+
|
26
|
+
LAYOUTS = Hash.new("school_website")
|
27
|
+
LAYOUTS["course_cover.html.sktl"] = "learning"
|
28
|
+
|
29
|
+
attr_reader :body
|
30
|
+
def initialize(template)
|
31
|
+
@template = template
|
32
|
+
@school = Fixture.globals[:current_school]
|
33
|
+
@preview_banner = Fixture.globals[:preview_banner]
|
34
|
+
end
|
35
|
+
|
36
|
+
def body_classes
|
37
|
+
BODY_CLASSES[@template.name]
|
38
|
+
end
|
39
|
+
|
40
|
+
def asset_url(path)
|
41
|
+
self.class.asset_cache[path]
|
42
|
+
end
|
43
|
+
|
44
|
+
def current_school
|
45
|
+
@school
|
46
|
+
end
|
47
|
+
|
48
|
+
def preview_banner
|
49
|
+
@preview_banner
|
50
|
+
end
|
51
|
+
|
52
|
+
def render_skt(partial_name, variables: {})
|
53
|
+
name = "#{partial_name}.html.sktl"
|
54
|
+
Template.new(name).render(variables: variables)
|
55
|
+
end
|
56
|
+
|
57
|
+
def render(variables: {})
|
58
|
+
@body = @template.render(variables: variables)
|
59
|
+
layout_path = File.join(GEM_ROOT, "config/#{LAYOUTS[@template.name]}.html.erb")
|
60
|
+
layout= File.read(layout_path)
|
61
|
+
set_context_variables_for_layout
|
62
|
+
ERB.new(layout).result(binding)
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def set_context_variables_for_layout
|
68
|
+
@display_search_form = @template.name == "my_content.html.sktl"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
Binary file
|
data/media/sk-144.gif
ADDED
Binary file
|
data/media/sk-16.gif
ADDED
Binary file
|
data/media/sk-57.gif
ADDED
Binary file
|
data/media/sk-72.gif
ADDED
Binary file
|
data/schoolkeep.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'schoolkeep/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "northpass"
|
8
|
+
spec.version = Schoolkeep::VERSION
|
9
|
+
spec.authors = ["Ryan Ong", "SchoolKeep Developers"]
|
10
|
+
spec.email = ["ryan@northpass.com", "dev@northpass.com"]
|
11
|
+
spec.summary = %q{A cli to develop custom templates for and upload to SchoolKeep.}
|
12
|
+
spec.homepage = "https://github.com/SchoolKeep/schoolkeep-ruby"
|
13
|
+
spec.license = "MIT"
|
14
|
+
|
15
|
+
spec.files = `git ls-files -z`.split("\x0")
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
+
spec.require_paths = ["lib"]
|
18
|
+
|
19
|
+
spec.add_dependency "thor", "~> 0.19.0"
|
20
|
+
spec.add_dependency "faraday", "~> 0.9"
|
21
|
+
spec.add_dependency "scribble"
|
22
|
+
spec.add_dependency "i18n"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.7"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
spec.add_development_dependency "rspec", "~> 3.1.0"
|
27
|
+
spec.add_development_dependency "activesupport"
|
28
|
+
end
|
data/spec/cli_spec.rb
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
require "schoolkeep/cli"
|
2
|
+
require "tmpdir"
|
3
|
+
require "yaml"
|
4
|
+
require "open3"
|
5
|
+
|
6
|
+
module Schoolkeep
|
7
|
+
RSpec.describe CLI do
|
8
|
+
describe "#reset" do
|
9
|
+
it "returns an error when there is an invalid template name" do
|
10
|
+
_, error, process = Open3.capture3 "SK_API_KEY=test #{bin_path} reset non_existetnt_file.sktl"
|
11
|
+
|
12
|
+
expect(process).not_to be_success
|
13
|
+
expect(error).to include "invalid template name"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "#generate-fixtures" do
|
18
|
+
it "copies the fixture file" do
|
19
|
+
Dir.mktmpdir do |dir|
|
20
|
+
output, _, process = Open3.capture3 "#{bin_path} generate-fixtures --dir #{dir}"
|
21
|
+
expect(process).to be_success
|
22
|
+
expect(output).to include "fixtures.yml has been generated"
|
23
|
+
expect(File.exist?(File.join(dir, "config/fixtures.yml"))).to be true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#server" do
|
29
|
+
it "serves directory" do
|
30
|
+
Dir.mktmpdir do |dir|
|
31
|
+
Dir.mkdir "#{dir}/templates"
|
32
|
+
File.write "#{dir}/templates/custom_page.html.sktl", ""
|
33
|
+
|
34
|
+
port = find_available_port
|
35
|
+
@pid = spawn("#{bin_path} server --dir #{dir} --port #{port} --quiet")
|
36
|
+
|
37
|
+
Timeout.timeout(60) { sleep 0.1 until responsive?(port) }
|
38
|
+
|
39
|
+
response = Faraday.get("http://localhost:#{port}/")
|
40
|
+
expect(response.body).to include "custom_page.html.sktl"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
after do
|
45
|
+
Process.kill("INT", @pid) if @pid
|
46
|
+
end
|
47
|
+
|
48
|
+
def responsive?(port)
|
49
|
+
res = Faraday.get("http://localhost:#{port}/")
|
50
|
+
|
51
|
+
if res.success?
|
52
|
+
return res.body.include?("custom_page.html.sktl")
|
53
|
+
end
|
54
|
+
rescue Faraday::ConnectionFailed
|
55
|
+
return false
|
56
|
+
end
|
57
|
+
|
58
|
+
def find_available_port
|
59
|
+
server = TCPServer.new('127.0.0.1', 0)
|
60
|
+
server.addr[1]
|
61
|
+
ensure
|
62
|
+
server.close if server
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def bin_path
|
67
|
+
@bin_path ||= File.expand_path("../../bin/sk", __FILE__)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "schoolkeep/cli"
|
2
|
+
require "schoolkeep/client"
|
3
|
+
require "tmpdir"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
module Schoolkeep
|
7
|
+
RSpec.describe CLI, :schoolkeep_client, type: :feature do
|
8
|
+
describe "#upload and #reset" do
|
9
|
+
it "uploads the all templates and then deletes it" do
|
10
|
+
Dir.mktmpdir do |template_dir|
|
11
|
+
test_string = rand(36**100).to_s(36)
|
12
|
+
TEMPLATE_NAMES.each do |name|
|
13
|
+
File.write "#{template_dir}/#{name}.sktl", test_string
|
14
|
+
end
|
15
|
+
|
16
|
+
expect(system("#{bin_path} upload --dir #{template_dir} --quiet --all")).to be true
|
17
|
+
|
18
|
+
response = Faraday.get(ENV["SK_CUSTOM_PAGE_URL"])
|
19
|
+
expect(response.body).to include test_string
|
20
|
+
|
21
|
+
expect(system("#{bin_path} reset --all --quiet")).to be true
|
22
|
+
|
23
|
+
response = Faraday.get(ENV["SK_CUSTOM_PAGE_URL"])
|
24
|
+
expect(response.body).not_to include test_string
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it "uploads the all templates and then deletes it" do
|
29
|
+
Dir.mktmpdir do |template_dir|
|
30
|
+
test_string = rand(36**100).to_s(36)
|
31
|
+
custom_page_path = File.join(template_dir, "custom_page.html.sktl")
|
32
|
+
File.write custom_page_path, test_string
|
33
|
+
|
34
|
+
expect(system("#{bin_path} upload #{custom_page_path} --quiet")).to be true
|
35
|
+
|
36
|
+
response = Faraday.get(ENV["SK_CUSTOM_PAGE_URL"])
|
37
|
+
expect(response.body).to include test_string
|
38
|
+
|
39
|
+
expect(system("#{bin_path} reset custom_page.html.sktl --quiet")).to be true
|
40
|
+
|
41
|
+
response = Faraday.get(ENV["SK_CUSTOM_PAGE_URL"])
|
42
|
+
expect(response.body).not_to include test_string
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def bin_path
|
48
|
+
@bin_path ||= File.expand_path("../../../bin/sk", __FILE__)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require "schoolkeep/client"
|
2
|
+
require "tempfile"
|
3
|
+
|
4
|
+
module Schoolkeep
|
5
|
+
RSpec.describe Client, :schoolkeep_client, type: :feature do
|
6
|
+
describe "#upload and #delete" do
|
7
|
+
it "deletes the custom_page template" do
|
8
|
+
expect(client.upload("custom_page.html", temp_file, "sktl")).to be_success
|
9
|
+
response = Faraday.get(ENV["SK_CUSTOM_PAGE_URL"])
|
10
|
+
|
11
|
+
expect(response.body).to include test_string
|
12
|
+
|
13
|
+
expect(client.delete("custom_page.html")).to be_success
|
14
|
+
response = Faraday.get(ENV["SK_CUSTOM_PAGE_URL"])
|
15
|
+
|
16
|
+
expect(response.body).not_to include test_string
|
17
|
+
end
|
18
|
+
|
19
|
+
after do
|
20
|
+
temp_file.unlink
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_string
|
24
|
+
@test_string ||= rand(36**100).to_s(36)
|
25
|
+
end
|
26
|
+
|
27
|
+
def temp_file
|
28
|
+
@temp_file ||= Tempfile.new("any_file.sktl").tap do |file|
|
29
|
+
file.write(test_string)
|
30
|
+
file.rewind
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#get_fixtures" do
|
36
|
+
it "downloads fixtures" do
|
37
|
+
response = client.get_fixtures
|
38
|
+
|
39
|
+
expect(response).to be_success
|
40
|
+
expect(YAML.load(response.body)).to have_key "globals"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def client
|
45
|
+
@client ||= Client.new(ENV["SK_API_KEY"])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require "schoolkeep/fixture"
|
2
|
+
|
3
|
+
module Schoolkeep
|
4
|
+
RSpec.describe Fixture do
|
5
|
+
describe "#globals" do
|
6
|
+
it "reads global file and needs no dev file" do
|
7
|
+
globals = Fixture.new(nil).globals
|
8
|
+
|
9
|
+
expect(globals[:current_learner].name).to eq "Test Learner"
|
10
|
+
end
|
11
|
+
|
12
|
+
it "reads global file and uses dev overwrites" do
|
13
|
+
file = Tempfile.new(%w(fixture yml))
|
14
|
+
|
15
|
+
begin
|
16
|
+
file.write(dev_fixtures.to_yaml)
|
17
|
+
file.rewind
|
18
|
+
globals = Fixture.new(file.path).globals
|
19
|
+
expect(globals[:current_learner].name).to eq "Fixture Test"
|
20
|
+
ensure
|
21
|
+
file.close
|
22
|
+
file.unlink # deletes the temp file
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def dev_fixtures
|
27
|
+
{"globals" => { "current_learner" => {"name" => "Fixture Test"}}}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "#for" do
|
32
|
+
it "reads global file and needs no dev file" do
|
33
|
+
fixtures = Fixture.new(nil).for("custom_page.html.sktl")
|
34
|
+
expect(fixtures[:custom_page].headline).to eq "Sample Custom Page"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "renders all templates without errors" do
|
38
|
+
Schoolkeep::TEMPLATE_NAMES.each do |name|
|
39
|
+
Fixture.new(nil).for("#{name}.sktl")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it "reads global file and uses dev overwrites" do
|
44
|
+
file = Tempfile.new(%w(fixture yml))
|
45
|
+
|
46
|
+
begin
|
47
|
+
file.write(dev_fixtures.to_yaml)
|
48
|
+
file.rewind
|
49
|
+
fixtures = Fixture.new(file.path).for("custom_page.html.sktl")
|
50
|
+
expect(fixtures[:custom_page].headline).to eq "Fixture Test"
|
51
|
+
ensure
|
52
|
+
file.close
|
53
|
+
file.unlink # deletes the temp file
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
it "properly references courses" do
|
58
|
+
fixtures = Fixture.new(nil).for("course_details.html.sktl")
|
59
|
+
|
60
|
+
expect(fixtures[:course].name).to eq "photography course"
|
61
|
+
end
|
62
|
+
|
63
|
+
def dev_fixtures
|
64
|
+
{ "templates" => { "custom_page.html.sktl" => { "custom_page" => {"headline" => "Fixture Test"}}}}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require "scribble"
|
2
|
+
require "schoolkeep/scribble/methods/query_parameter_value"
|
3
|
+
|
4
|
+
module Scribble::Methods
|
5
|
+
RSpec.describe FilterParameterValue do
|
6
|
+
describe "#query_parameter_value" do
|
7
|
+
it "escapes HTML" do
|
8
|
+
rendered = render("<input value='{{ filter_parameter_value }}>'", "test_template")
|
9
|
+
|
10
|
+
expect(rendered).to eq \
|
11
|
+
"<input value=''><script>alert('HAXXX')</script>>'"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(source, template_name, locale = :en)
|
16
|
+
Scribble::Template.new(source).render(
|
17
|
+
variables: {
|
18
|
+
template_name: template_name,
|
19
|
+
params: {
|
20
|
+
filter: {
|
21
|
+
category_name: "'><script>alert('HAXXX')</script>"
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|