badges_engine_test 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +40 -0
  3. data/Rakefile +38 -0
  4. data/app/assets/images/badges_engine/test-badge.png +0 -0
  5. data/app/assets/javascripts/badges_engine/application.js +9 -0
  6. data/app/assets/javascripts/badges_engine/assertions.js +2 -0
  7. data/app/assets/javascripts/badges_engine/badges.js +2 -0
  8. data/app/assets/stylesheets/badges_engine/application.css +77 -0
  9. data/app/assets/stylesheets/badges_engine/assertions.css +4 -0
  10. data/app/assets/stylesheets/badges_engine/badges.css +4 -0
  11. data/app/controllers/badges_engine/application_controller.rb +5 -0
  12. data/app/controllers/badges_engine/assertions_controller.rb +102 -0
  13. data/app/controllers/badges_engine/badges_controller.rb +85 -0
  14. data/app/helpers/badges_engine/application_helper.rb +4 -0
  15. data/app/helpers/badges_engine/assertions_helper.rb +4 -0
  16. data/app/helpers/badges_engine/badges_helper.rb +4 -0
  17. data/app/models/badges_engine/assertion.rb +80 -0
  18. data/app/models/badges_engine/badge.rb +23 -0
  19. data/app/models/badges_engine/issuer.rb +18 -0
  20. data/app/views/badges_engine/assertions/_form.html.haml +25 -0
  21. data/app/views/badges_engine/assertions/edit.html.haml +7 -0
  22. data/app/views/badges_engine/assertions/index.html.haml +29 -0
  23. data/app/views/badges_engine/assertions/new.html.haml +5 -0
  24. data/app/views/badges_engine/assertions/show.html.haml +26 -0
  25. data/app/views/badges_engine/badges/_form.html.haml +22 -0
  26. data/app/views/badges_engine/badges/edit.html.haml +7 -0
  27. data/app/views/badges_engine/badges/index.html.haml +29 -0
  28. data/app/views/badges_engine/badges/new.html.haml +5 -0
  29. data/app/views/badges_engine/badges/show.html.haml +25 -0
  30. data/app/views/layouts/badges_engine/application.html.haml +11 -0
  31. data/config/routes.rb +10 -0
  32. data/db/migrate/20110925034415_create_badges_engine_badges.rb +14 -0
  33. data/db/migrate/20110925034612_create_badges_engine_assertions.rb +16 -0
  34. data/lib/badges_engine.rb +8 -0
  35. data/lib/badges_engine/badges_user.rb +26 -0
  36. data/lib/badges_engine/configuration.rb +29 -0
  37. data/lib/badges_engine/engine.rb +27 -0
  38. data/lib/badges_engine/rails/engine.rb +74 -0
  39. data/lib/badges_engine/version.rb +3 -0
  40. data/lib/generators/badges_engine/USAGE +8 -0
  41. data/lib/generators/badges_engine/install/USAGE +8 -0
  42. data/lib/generators/badges_engine/install/install_generator.rb +14 -0
  43. data/lib/generators/badges_engine/install/templates/initializer.rb +11 -0
  44. data/lib/tasks/badges_engine_tasks.rake +4 -0
  45. metadata +185 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,40 @@
1
+ BadgesEngine
2
+ ============
3
+
4
+
5
+ Description
6
+ -----------
7
+ This project is a mountable Rails 3.1 engine gem. The purpose is to make a Rails app that installs and mounts this an issuer of badges following the design of the Mozilla Open Badges Infrastructure: [http://openbadges.org/)](http://openbadges.org/).
8
+
9
+ Maybe it will be useful to folks interested in the ['Badges for Lifelong Learning'](http://www.dmlcompetition.net/)
10
+
11
+
12
+ Install
13
+ -------
14
+ Start by adding the gem to your Gemfile, then do the usual routine, and install the bundle:
15
+
16
+ gem 'badges_engine'
17
+
18
+ Next there are migrations to copy over:
19
+
20
+ rake badges_engine:install:migrations
21
+
22
+ That will copy the migrations over to support saving the badges and assertions.
23
+
24
+ Next you can run the install rails generator.
25
+ This will mount the engine in your routes.rb, and add 'config/initializers/badges_engine.rb'
26
+
27
+ rails generate badges_engine:install
28
+
29
+ Next you should edit 'config/initializers/badges_engine.rb'.
30
+
31
+ This sets up the initial values you need for the issuer, and specifies the User class for mixins.
32
+
33
+
34
+ Author(s)
35
+ -----------
36
+ Andrew Kuklewicz - https://github.com/kookster
37
+
38
+ License
39
+ -------
40
+ This project uses MIT-LICENSE.
@@ -0,0 +1,38 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+ RDoc::Task.new(:rdoc) do |rdoc|
15
+ rdoc.rdoc_dir = 'rdoc'
16
+ rdoc.title = 'BadgesEngine'
17
+ rdoc.options << '--line-numbers'
18
+ rdoc.rdoc_files.include('README.rdoc')
19
+ rdoc.rdoc_files.include('lib/**/*.rb')
20
+ end
21
+
22
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
23
+ load 'rails/tasks/engine.rake'
24
+
25
+
26
+ Bundler::GemHelper.install_tasks
27
+
28
+ require 'rake'
29
+ require 'rspec/core'
30
+ require 'rspec/core/rake_task'
31
+
32
+
33
+ RSpec::Core::RakeTask.new(:spec) do |spec|
34
+ spec.pattern = FileList['spec/**/*_spec.rb']
35
+ end
36
+
37
+ desc 'Default: Run all specs.'
38
+ task :default => :spec
@@ -0,0 +1,9 @@
1
+ // This is a manifest file that'll be compiled into including all the files listed below.
2
+ // Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
3
+ // be included in the compiled file accessible from http://example.com/assets/application.js
4
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
5
+ // the compiled file.
6
+ //
7
+ // = require jquery
8
+ // = require jquery_ujs
9
+ // = require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,77 @@
1
+ /*
2
+ * This is a manifest file that'll automatically include all the stylesheets available in this directory
3
+ * and any sub-directories. You're free to add application-wide styles to this file and they'll appear at
4
+ * the top of the compiled file, but it's generally better to create a new file per style scope.
5
+ *= require_self
6
+ *= require_tree .
7
+ */
8
+
9
+ div.field label {
10
+ display:block;
11
+ font-weight: bold;
12
+ }
13
+
14
+
15
+ div.field div.help {
16
+ font-style: italic;
17
+ }
18
+
19
+
20
+ /* scaffold - for now */
21
+
22
+ body { background-color: #fff; color: #333; }
23
+
24
+ body, p, ol, ul, td {
25
+ font-family: verdana, arial, helvetica, sans-serif;
26
+ font-size: 13px;
27
+ line-height: 18px;
28
+ }
29
+
30
+ pre {
31
+ background-color: #eee;
32
+ padding: 10px;
33
+ font-size: 11px;
34
+ }
35
+
36
+ a { color: #000; }
37
+ a:visited { color: #666; }
38
+ a:hover { color: #fff; background-color:#000; }
39
+
40
+ div.field, div.actions {
41
+ margin-bottom: 10px;
42
+ }
43
+
44
+ #notice {
45
+ color: green;
46
+ }
47
+
48
+ .field_with_errors {
49
+ padding: 2px;
50
+ background-color: red;
51
+ display: table;
52
+ }
53
+
54
+ #error_explanation {
55
+ width: 450px;
56
+ border: 2px solid red;
57
+ padding: 7px;
58
+ padding-bottom: 0;
59
+ margin-bottom: 20px;
60
+ background-color: #f0f0f0;
61
+ }
62
+
63
+ #error_explanation h2 {
64
+ text-align: left;
65
+ font-weight: bold;
66
+ padding: 5px 5px 5px 15px;
67
+ font-size: 12px;
68
+ margin: -7px;
69
+ margin-bottom: 0px;
70
+ background-color: #c00;
71
+ color: #fff;
72
+ }
73
+
74
+ #error_explanation ul li {
75
+ font-size: 12px;
76
+ list-style: square;
77
+ }
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,5 @@
1
+ require 'haml-rails'
2
+ module BadgesEngine
3
+ class ApplicationController < ActionController::Base
4
+ end
5
+ end
@@ -0,0 +1,102 @@
1
+ module BadgesEngine
2
+ class AssertionsController < ApplicationController
3
+
4
+ def bake_callback
5
+ @assertion = Assertion.find(params[:id])
6
+ respond_to do |format|
7
+ if @assertion && @assertion.token == params[:token]
8
+ format.html { render action: 'show' }
9
+ format.json { render json: @assertion.open_badges_as_json }
10
+ else
11
+ format.html {render text: 'Cannot access badge assertion.', status: :unauthorized}
12
+ format.json {
13
+ error = {status: 'failure', error: 'unauthorized', reason: 'Cannot access badge assertion.'}
14
+ render json: error, status: :unauthorized
15
+ }
16
+ end
17
+ end
18
+ end
19
+
20
+ # GET /assertions
21
+ # GET /assertions.json
22
+ def index
23
+ @assertions = Assertion.all
24
+
25
+ respond_to do |format|
26
+ format.html # index.html.haml
27
+ format.json { render json: @assertions }
28
+ end
29
+ end
30
+
31
+ # GET /assertions/1
32
+ # GET /assertions/1.json
33
+ def show
34
+ @assertion = Assertion.find(params[:id])
35
+
36
+ respond_to do |format|
37
+ format.html # show.html.haml
38
+ format.json { render json: @assertion }
39
+ end
40
+ end
41
+
42
+ # GET /assertions/new
43
+ # GET /assertions/new.json
44
+ def new
45
+ @assertion = Assertion.new
46
+
47
+ respond_to do |format|
48
+ format.html # new.html.haml
49
+ format.json { render json: @assertion }
50
+ end
51
+ end
52
+
53
+ # GET /assertions/1/edit
54
+ def edit
55
+ @assertion = Assertion.find(params[:id])
56
+ end
57
+
58
+ # POST /assertions
59
+ # POST /assertions.json
60
+ def create
61
+ @assertion = Assertion.new(params[:assertion])
62
+
63
+ respond_to do |format|
64
+ if @assertion.save
65
+ format.html { redirect_to @assertion, notice: 'Assertion was successfully created.' }
66
+ format.json { render json: @assertion, status: :created, location: @assertion }
67
+ else
68
+ format.html { render action: "new" }
69
+ format.json { render json: @assertion.errors, status: :unprocessable_entity }
70
+ end
71
+ end
72
+ end
73
+
74
+ # PUT /assertions/1
75
+ # PUT /assertions/1.json
76
+ def update
77
+ @assertion = Assertion.find(params[:id])
78
+
79
+ respond_to do |format|
80
+ if @assertion.update_attributes(params[:assertion])
81
+ format.html { redirect_to @assertion, notice: 'Assertion was successfully updated.' }
82
+ format.json { head :ok }
83
+ else
84
+ format.html { render action: "edit" }
85
+ format.json { render json: @assertion.errors, status: :unprocessable_entity }
86
+ end
87
+ end
88
+ end
89
+
90
+ # DELETE /assertions/1
91
+ # DELETE /assertions/1.json
92
+ def destroy
93
+ @assertion = Assertion.find(params[:id])
94
+ @assertion.destroy
95
+
96
+ respond_to do |format|
97
+ format.html { redirect_to assertions_url }
98
+ format.json { head :ok }
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,85 @@
1
+ module BadgesEngine
2
+ class BadgesController < ApplicationController
3
+ # GET /badges
4
+ # GET /badges.json
5
+ def index
6
+ @badges = Badge.all
7
+
8
+ respond_to do |format|
9
+ format.html # index.html.haml
10
+ format.json { render json: @badges }
11
+ end
12
+ end
13
+
14
+ # GET /badges/1
15
+ # GET /badges/1.json
16
+ def show
17
+ @badge = Badge.find(params[:id])
18
+
19
+ respond_to do |format|
20
+ format.html # show.html.haml
21
+ format.json { render json: @badge }
22
+ end
23
+ end
24
+
25
+ # GET /badges/new
26
+ # GET /badges/new.json
27
+ def new
28
+ @badge = Badge.new
29
+
30
+ respond_to do |format|
31
+ format.html # new.html.haml
32
+ format.json { render json: @badge }
33
+ end
34
+ end
35
+
36
+ # GET /badges/1/edit
37
+ def edit
38
+ @badge = Badge.find(params[:id])
39
+ end
40
+
41
+ # POST /badges
42
+ # POST /badges.json
43
+ def create
44
+ @badge = Badge.new(params[:badge])
45
+
46
+ respond_to do |format|
47
+ if @badge.save
48
+ format.html { redirect_to @badge, notice: 'Badge was successfully created.' }
49
+ format.json { render json: @badge, status: :created, location: @badge }
50
+ else
51
+ format.html { render action: "new" }
52
+ format.json { render json: @badge.errors, status: :unprocessable_entity }
53
+ end
54
+ end
55
+ end
56
+
57
+ # PUT /badges/1
58
+ # PUT /badges/1.json
59
+ def update
60
+ @badge = Badge.find(params[:id])
61
+
62
+ respond_to do |format|
63
+ if @badge.update_attributes(params[:badge])
64
+ format.html { redirect_to @badge, notice: 'Badge was successfully updated.' }
65
+ format.json { head :ok }
66
+ else
67
+ format.html { render action: "edit" }
68
+ format.json { render json: @badge.errors, status: :unprocessable_entity }
69
+ end
70
+ end
71
+ end
72
+
73
+ # DELETE /badges/1
74
+ # DELETE /badges/1.json
75
+ def destroy
76
+ @badge = Badge.find(params[:id])
77
+ @badge.destroy
78
+
79
+ respond_to do |format|
80
+ format.html { redirect_to badges_url }
81
+ format.json { head :ok }
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,4 @@
1
+ module BadgesEngine
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module BadgesEngine
2
+ module AssertionsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module BadgesEngine
2
+ module BadgesHelper
3
+ end
4
+ end
@@ -0,0 +1,80 @@
1
+ require 'uri'
2
+ require 'json'
3
+ require 'net/http'
4
+
5
+ module BadgesEngine
6
+ class Assertion < ActiveRecord::Base
7
+
8
+ include BadgesEngine::Engine.routes.url_helpers
9
+
10
+ belongs_to :badge
11
+
12
+ validates_presence_of :badge_id
13
+ validates_presence_of :user_id
14
+
15
+ # validates_associated :user, :badge
16
+ validates_associated :badge
17
+
18
+ before_validation(:on=>:create) do
19
+ self.token = SecureRandom.urlsafe_base64(16)
20
+ end
21
+
22
+ after_commit :bake, :if => :update_assertion?
23
+
24
+ class <<self
25
+ def associate_user_class(user_class)
26
+ belongs_to :user, :class_name=>user_class.to_s, :foreign_key=>'user_id'
27
+ end
28
+ end
29
+
30
+ def recipient
31
+ self.user.try(:email)
32
+ end
33
+
34
+
35
+ def update_assertion?
36
+ persisted? && !is_baked?
37
+ end
38
+
39
+ def baking_callback_url
40
+ origin_uri = URI.parse(BadgesEngine::Configuration.issuer.origin)
41
+ secret_assertion_url(:id=>self.id, :token=>self.token, :host=>origin_uri.host)
42
+ end
43
+
44
+ def bake
45
+ uri = URI.parse(BadgesEngine::Configuration.baker_url)
46
+ http = Net::HTTP.new(uri.host, uri.port)
47
+ path = "#{uri.path}?assertion=#{self.baking_callback_url}"
48
+ headers = {'Content-Type'=>'application/json','Accept'=>'application/json'}
49
+ logger.debug("request: #{uri.host}#{path}")
50
+ response = http.get(path, headers)
51
+
52
+ unless response.kind_of?(Net::HTTPSuccess)
53
+ raise "Baking badge failed: Response was not a success:\n\t'#{response.inspect}'"
54
+ end
55
+
56
+ if !response || response.body.blank?
57
+ raise "Baking badge failed: Response was blank:\n\t'#{response.inspect}'"
58
+ end
59
+
60
+ badges_response = ActiveSupport::JSON.decode(response.body)
61
+ logger.debug("response: #{badges_response.inspect}")
62
+
63
+ if badges_response['status'] == 'success'
64
+ self.update_attribute(:is_baked, true)
65
+ else
66
+ raise "Baking badge failed:\n\tStatus:'#{badges_response['status']}'\n\tError:'#{badges_response['error']}'\n\tReason:'#{badges_response['reason']}'"
67
+ end
68
+ end
69
+
70
+ def open_badges_as_json
71
+ as_json( :only=>[:evidence, :expires, :issued_on],
72
+ :methods=>[:recipient],
73
+ :include=>{ :badge=>{
74
+ :only=>[:version, :name, :image, :description, :criteria],
75
+ :methods=>:issuer} }
76
+ )
77
+ end
78
+
79
+ end
80
+ end
@@ -0,0 +1,23 @@
1
+ module BadgesEngine
2
+ class Badge < ActiveRecord::Base
3
+
4
+ include BadgesEngine::Engine.routes.url_helpers
5
+
6
+ has_many :assertions
7
+
8
+ validates_uniqueness_of :name
9
+
10
+ before_validation(:on=>:create) do
11
+ self.version ||= BadgesEngine::Configuration.badge_version
12
+ end
13
+
14
+ def issuer
15
+ BadgesEngine::Configuration.issuer
16
+ end
17
+
18
+ def criteria
19
+ read_attribute(:criteria).blank? ? badge_path(self) : read_attribute(:criteria)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ module BadgesEngine
2
+ class Issuer
3
+ include ActiveModel::Validations
4
+ include ActiveModel::Serialization
5
+
6
+ validates_presence_of :origin, :name
7
+
8
+ attr_accessor :origin, :name, :org, :contact
9
+
10
+ def initialize(attrs={})
11
+ @origin = attrs[:origin]
12
+ @name = attrs[:name]
13
+ @org = attrs[:org]
14
+ @contact = attrs[:contact]
15
+ end
16
+
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ = form_for @assertion do |f|
2
+ -if @assertion.errors.any?
3
+ #error_explanation
4
+ %h2= "#{pluralize(@assertion.errors.count, "error")} prohibited this assertion from being saved:"
5
+ %ul
6
+ - @assertion.errors.full_messages.each do |msg|
7
+ %li= msg
8
+
9
+ .field
10
+ = f.label :user_id
11
+ = f.number_field :user_id
12
+ .field
13
+ = f.label :badge_id
14
+ = f.number_field :badge_id
15
+ .field
16
+ = f.label :evidence
17
+ = f.text_field :evidence
18
+ .field
19
+ = f.label :expires
20
+ = f.date_select :expires
21
+ .field
22
+ = f.label :issued_on
23
+ = f.date_select :issued_on
24
+ .actions
25
+ = f.submit 'Save'
@@ -0,0 +1,7 @@
1
+ %h1 Editing assertion
2
+
3
+ = render 'form'
4
+
5
+ = link_to 'Show', @assertion
6
+ \|
7
+ = link_to 'Back', assertions_path
@@ -0,0 +1,29 @@
1
+ %h1 Listing assertions
2
+
3
+ %table
4
+ %tr
5
+ %th User
6
+ %th Badge
7
+ %th Recipient
8
+ %th Evidence
9
+ %th Expires
10
+ %th Issued on
11
+ %th
12
+ %th
13
+ %th
14
+
15
+ - @assertions.each do |assertion|
16
+ %tr
17
+ %td= assertion.user_id
18
+ %td= assertion.badge_id
19
+ %td= assertion.recipient
20
+ %td= assertion.evidence
21
+ %td= assertion.expires
22
+ %td= assertion.issued_on
23
+ %td= link_to 'Show', assertion
24
+ %td= link_to 'Edit', edit_assertion_path(assertion)
25
+ %td= link_to 'Destroy', assertion, :confirm => 'Are you sure?', :method => :delete
26
+
27
+ %br
28
+
29
+ = link_to 'New Assertion', new_assertion_path
@@ -0,0 +1,5 @@
1
+ %h1 New assertion
2
+
3
+ = render 'form'
4
+
5
+ = link_to 'Back', assertions_path
@@ -0,0 +1,26 @@
1
+ %p
2
+ %b User:
3
+ = @assertion.user_id
4
+ %p
5
+ %b Badge:
6
+ = @assertion.badge_id
7
+ %p
8
+ %b Recipient:
9
+ = @assertion.recipient
10
+ %p
11
+ %b Evidence:
12
+ = @assertion.evidence
13
+ %p
14
+ %b Expires:
15
+ = @assertion.expires
16
+ %p
17
+ %b Issued on:
18
+ = @assertion.issued_on
19
+
20
+ %p
21
+ %b Baking Callback URL
22
+ = @assertion.baking_callback_url
23
+
24
+ = link_to 'Edit', edit_assertion_path(@assertion)
25
+ \|
26
+ = link_to 'Back', assertions_path
@@ -0,0 +1,22 @@
1
+ = form_for @badge do |f|
2
+ -if @badge.errors.any?
3
+ #error_explanation
4
+ %h2= "#{pluralize(@badge.errors.count, "error")} prohibited this badge from being saved:"
5
+ %ul
6
+ - @badge.errors.full_messages.each do |msg|
7
+ %li= msg
8
+
9
+ .field
10
+ = f.label :name
11
+ = f.text_field :name
12
+ .field
13
+ = f.label :image
14
+ = f.text_field :image
15
+ .field
16
+ = f.label :description
17
+ = f.text_field :description
18
+ .field
19
+ = f.label :criteria
20
+ = f.text_field :criteria
21
+ .actions
22
+ = f.submit 'Save'
@@ -0,0 +1,7 @@
1
+ %h1 Editing badge
2
+
3
+ = render 'form'
4
+
5
+ = link_to 'Show', @badge
6
+ \|
7
+ = link_to 'Back', badges_path
@@ -0,0 +1,29 @@
1
+ %h1 Listing badges
2
+
3
+ %table
4
+ %tr
5
+ %th Issuer
6
+ %th Version
7
+ %th Name
8
+ %th Image
9
+ %th Description
10
+ %th Criteria
11
+ %th
12
+ %th
13
+ %th
14
+
15
+ - @badges.each do |badge|
16
+ %tr
17
+ %td= badge.issuer_id
18
+ %td= badge.version
19
+ %td= badge.name
20
+ %td= badge.image
21
+ %td= badge.description
22
+ %td= badge.criteria
23
+ %td= link_to 'Show', badge
24
+ %td= link_to 'Edit', edit_badge_path(badge)
25
+ %td= link_to 'Destroy', badge, :confirm => 'Are you sure?', :method => :delete
26
+
27
+ %br
28
+
29
+ = link_to 'New Badge', new_badge_path
@@ -0,0 +1,5 @@
1
+ %h1 New badge
2
+
3
+ = render 'form'
4
+
5
+ = link_to 'Back', badges_path
@@ -0,0 +1,25 @@
1
+ %p#notice= notice
2
+
3
+ %p
4
+ %b Issuer:
5
+ = @badge.issuer_id
6
+ %p
7
+ %b Version:
8
+ = @badge.version
9
+ %p
10
+ %b Name:
11
+ = @badge.name
12
+ %p
13
+ %b Image:
14
+ = @badge.image
15
+ .image= image_tag(@badge.image)
16
+ %p
17
+ %b Description:
18
+ = @badge.description
19
+ %p
20
+ %b Criteria:
21
+ = @badge.criteria
22
+
23
+ = link_to 'Edit', edit_badge_path(@badge)
24
+ \|
25
+ = link_to 'Back', badges_path
@@ -0,0 +1,11 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title My App
5
+ = stylesheet_link_tag 'badges_engine/application'
6
+ = javascript_include_tag 'badges_engine/application'
7
+ = csrf_meta_tags
8
+ %body
9
+ - flash.each do |name, msg|
10
+ = content_tag(:div, msg, id: "flash_#{name}", class: 'notice') if msg.is_a?(String)
11
+ = yield
@@ -0,0 +1,10 @@
1
+ BadgesEngine::Engine.routes.draw do
2
+
3
+ resources :badges
4
+
5
+ resources :assertions
6
+
7
+ match 'a/:id/:token.json' => 'assertions#bake_callback', :via => :get, :defaults => { :format => 'json' }, :as => :secret_assertion
8
+
9
+ root :to=>'badges#index'
10
+ end
@@ -0,0 +1,14 @@
1
+ class CreateBadgesEngineBadges < ActiveRecord::Migration
2
+ def change
3
+ create_table :badges_engine_badges do |t|
4
+ t.integer :issuer_id
5
+ t.string :version
6
+ t.string :name
7
+ t.string :image
8
+ t.string :description
9
+ t.string :criteria
10
+
11
+ t.timestamps
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,16 @@
1
+ class CreateBadgesEngineAssertions < ActiveRecord::Migration
2
+ def change
3
+ create_table :badges_engine_assertions do |t|
4
+ t.integer :user_id
5
+ t.integer :badge_id
6
+ t.string :evidence
7
+ t.date :expires
8
+ t.date :issued_on
9
+
10
+ t.string :token
11
+ t.boolean :is_baked
12
+
13
+ t.timestamps
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,8 @@
1
+ require "badges_engine/engine"
2
+ require "badges_engine/version"
3
+ require "badges_engine/configuration"
4
+ require "badges_engine/badges_user"
5
+ require "badges_engine/rails/engine"
6
+
7
+ module BadgesEngine
8
+ end
@@ -0,0 +1,26 @@
1
+ module BadgesEngine
2
+
3
+ module BadgesUser
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ has_many :assertions, :class_name=>'BadgesEngine::Assertion', :foreign_key=>:user_id
9
+ has_many :badges, :through=>:assertions, :class_name=>'BadgesEngine::Badge'
10
+ end
11
+
12
+ module ClassMethods
13
+
14
+ end
15
+
16
+ module InstanceMethods
17
+
18
+ def add_badge(badge_or_name)
19
+ badge = badge_or_name.is_a?(BadgesEngine::Badge) ? badge_or_name : BadgesEngine::Badge.find_by_name(badge_or_name)
20
+ end
21
+
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,29 @@
1
+ module BadgesEngine
2
+
3
+ module Configuration
4
+
5
+ # Configure Cornerstone. Run rails generate cornerstone_install to create
6
+ # a fresh initializer with all configuration values.
7
+
8
+ class << self
9
+ def setup
10
+ yield self
11
+ end
12
+
13
+ attr_reader :issuer, :user_class
14
+ attr_accessor :baker_url, :badges_origin, :badge_version
15
+
16
+ def issuer=(attrs)
17
+ @issuer = BadgesEngine::Issuer.new(attrs)
18
+ end
19
+
20
+ def user_class=(klass)
21
+ @user_class = klass
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+
@@ -0,0 +1,27 @@
1
+ require 'jquery-rails'
2
+
3
+ module BadgesEngine
4
+ class Engine < Rails::Engine
5
+ isolate_namespace BadgesEngine
6
+ engine_name 'badges_engine'
7
+
8
+ ActiveRecord::Base.include_root_in_json = false
9
+
10
+ config.generators do |g|
11
+ g.orm :active_record
12
+ g.test_framework :rspec, :views => false, :fixture => true
13
+ g.template_engine :haml
14
+ end
15
+
16
+ config.to_prepare do
17
+ user_class = BadgesEngine::Configuration.user_class
18
+ if user_class
19
+ BadgesEngine::Assertion.associate_user_class(user_class)
20
+ user_class.send(:include, BadgesEngine::BadgesUser)
21
+ else
22
+
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,74 @@
1
+ # http://www.builtfromsource.com/2011/09/21/testing-routes-with-rails-3-1-engines/
2
+ module BadgesEngine
3
+ module Rails
4
+ module Engine
5
+ ##
6
+ # Automatically append all of the current engine's routes to the main
7
+ # application's route set. This needs to be done for ALL functional tests that
8
+ # use engine routes, since the mounted routes don't work during tests.
9
+ #
10
+ # @param [Symbol] engine_symbol Optional; if provided, uses this symbol to
11
+ # locate the engine class by name, otherwise uses the module of the calling
12
+ # test case as the presumed name of the engine.
13
+ #
14
+ # @author Jason Hamilton (jhamilton@greatherorift.com)
15
+ # @author Matthew Ratzloff (matt@urbaninfluence.com)
16
+ def load_engine_routes(path=nil)
17
+ name = self.class.name.split("::").first.split("(").last
18
+
19
+ engine = ("#{name}::Engine").constantize
20
+ engine_name = engine.engine_name
21
+ engine_path = path || engine_name.underscore
22
+ engine_module = name.underscore
23
+
24
+ # Append the routes for this module to the existing routes
25
+ ::Rails.application.routes.disable_clear_and_finalize = true
26
+ ::Rails.application.routes.clear!
27
+ ::Rails.application.routes_reloader.paths.each { |path| load(path) }
28
+ ::Rails.application.routes.draw do
29
+ resourced_routes = []
30
+
31
+ named_routes = engine.routes.named_routes.routes
32
+ unnamed_routes = engine.routes.routes - named_routes.values
33
+
34
+ engine.routes.routes.each do |route|
35
+ # Call the method by hand based on the symbol
36
+ path = "/#{engine_path}#{route.path}"
37
+ verb = route.verb.to_s.downcase.to_sym
38
+ requirements = route.requirements
39
+ if path_helper = named_routes.key(route)
40
+ requirements[:as] = path_helper
41
+ elsif route.requirements[:controller].present?
42
+ # Presume that all controllers referenced in routes should also be
43
+ # resources and append that routing on the end so that *_path helpers
44
+ # will still work
45
+ resourced_routes << route.requirements[:controller].gsub("#{engine_module}/", "").to_sym
46
+ else
47
+ end
48
+ if respond_to?(verb)
49
+ # puts "send: verb:#{verb}, path:#{path}, requirements:#{requirements.inspect}"
50
+ send(verb, path, requirements)
51
+ end
52
+ end
53
+
54
+ # Add each route, once, to the end under a scope to trick path helpers.
55
+ # This will probably break as soon as there is route name overlap, but
56
+ # we'll cross that bridge when we get to it.
57
+ resourced_routes.uniq!
58
+ scope engine_name.downcase do
59
+ resourced_routes.each do |resource|
60
+ resources resource
61
+ end
62
+ end
63
+ end
64
+
65
+ # Finalize the routes
66
+ ::Rails.application.routes.finalize!
67
+ ::Rails.application.routes.disable_clear_and_finalize = false
68
+ end
69
+
70
+ end
71
+ end
72
+ end
73
+
74
+ Rails::Engine.send(:include, BadgesEngine::Rails::Engine)
@@ -0,0 +1,3 @@
1
+ module BadgesEngine
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate badges_engine:initializer
6
+
7
+ This will create:
8
+ config/initializers/badges_engine.rb
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Explain the generator
3
+
4
+ Example:
5
+ rails generate initializer Thing
6
+
7
+ This will create:
8
+ what/will/it/create
@@ -0,0 +1,14 @@
1
+ class BadgesEngine::InstallGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ desc "Copy the default configuration file to config/initializers/badges_engine.rb"
5
+ def copy_initializer_file
6
+ copy_file "initializer.rb", "config/initializers/badges_engine.rb"
7
+ end
8
+
9
+ desc "Add the mount for the engine routes"
10
+ def mount_routes
11
+ route("mount BadgesEngine::Engine => '/badges', :as => 'badges'")
12
+ end
13
+
14
+ end
@@ -0,0 +1,11 @@
1
+ BadgesEngine::Configuration.setup do |config|
2
+ config.issuer = {
3
+ :origin=>'http://example.com',
4
+ :name=>'Example Company',
5
+ :org=>'My Organization',
6
+ :contact=>'me@example.com'
7
+ }
8
+ config.baker_url = 'http://beta.openbadges.org/baker'
9
+ config.badge_version = '0.5.0'
10
+ config.user_class = User
11
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :badges_engine do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: badges_engine_test
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Andrew Kuklewicz
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-31 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 3.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: jquery-rails
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: haml
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: haml-rails
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: sqlite3
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec-rails
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Not suitable for production
111
+ email:
112
+ - andrew@prx.org
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - app/controllers/badges_engine/application_controller.rb
118
+ - app/controllers/badges_engine/assertions_controller.rb
119
+ - app/controllers/badges_engine/badges_controller.rb
120
+ - app/models/badges_engine/assertion.rb
121
+ - app/models/badges_engine/badge.rb
122
+ - app/models/badges_engine/issuer.rb
123
+ - app/assets/javascripts/badges_engine/badges.js
124
+ - app/assets/javascripts/badges_engine/assertions.js
125
+ - app/assets/javascripts/badges_engine/application.js
126
+ - app/assets/stylesheets/badges_engine/application.css
127
+ - app/assets/stylesheets/badges_engine/assertions.css
128
+ - app/assets/stylesheets/badges_engine/badges.css
129
+ - app/assets/images/badges_engine/test-badge.png
130
+ - app/views/layouts/badges_engine/application.html.haml
131
+ - app/views/badges_engine/badges/_form.html.haml
132
+ - app/views/badges_engine/badges/show.html.haml
133
+ - app/views/badges_engine/badges/index.html.haml
134
+ - app/views/badges_engine/badges/new.html.haml
135
+ - app/views/badges_engine/badges/edit.html.haml
136
+ - app/views/badges_engine/assertions/_form.html.haml
137
+ - app/views/badges_engine/assertions/show.html.haml
138
+ - app/views/badges_engine/assertions/index.html.haml
139
+ - app/views/badges_engine/assertions/new.html.haml
140
+ - app/views/badges_engine/assertions/edit.html.haml
141
+ - app/helpers/badges_engine/assertions_helper.rb
142
+ - app/helpers/badges_engine/badges_helper.rb
143
+ - app/helpers/badges_engine/application_helper.rb
144
+ - config/routes.rb
145
+ - db/migrate/20110925034612_create_badges_engine_assertions.rb
146
+ - db/migrate/20110925034415_create_badges_engine_badges.rb
147
+ - lib/badges_engine.rb
148
+ - lib/generators/badges_engine/install/install_generator.rb
149
+ - lib/generators/badges_engine/install/templates/initializer.rb
150
+ - lib/generators/badges_engine/install/USAGE
151
+ - lib/generators/badges_engine/USAGE
152
+ - lib/badges_engine/rails/engine.rb
153
+ - lib/badges_engine/configuration.rb
154
+ - lib/badges_engine/version.rb
155
+ - lib/badges_engine/engine.rb
156
+ - lib/badges_engine/badges_user.rb
157
+ - lib/tasks/badges_engine_tasks.rake
158
+ - MIT-LICENSE
159
+ - Rakefile
160
+ - README.md
161
+ homepage: ''
162
+ licenses: []
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ required_rubygems_version: !ruby/object:Gem::Requirement
174
+ none: false
175
+ requirements:
176
+ - - ! '>='
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ requirements: []
180
+ rubyforge_project:
181
+ rubygems_version: 1.8.24
182
+ signing_key:
183
+ specification_version: 3
184
+ summary: Rails 3.2 Engine for Mozilla Open Badges Issuers
185
+ test_files: []