Permalink
Browse files

Merge pull request #11 from alphagov/new_product_features_form

New product features form
  • Loading branch information...
2 parents eadaf2f + 4c99e6a commit c196ced2b5d2d569f1009853281cf2d2aef08b4a @jamiecobbett jamiecobbett committed Nov 22, 2012
Showing with 511 additions and 144 deletions.
  1. +2 −0 Gemfile
  2. +8 −0 Gemfile.lock
  3. +5 −0 app/assets/javascripts/application.js
  4. +2 −0 app/assets/stylesheets/application.css
  5. +4 −0 app/assets/stylesheets/forms.css
  6. +0 −46 app/controllers/application_controller.rb
  7. +1 −1 app/controllers/content_change_requests_controller.rb
  8. +1 −1 app/controllers/create_new_user_requests_controller.rb
  9. +11 −19 app/controllers/general_requests_controller.rb
  10. +15 −0 app/controllers/new_feature_requests_controller.rb
  11. +1 −1 app/controllers/remove_user_requests_controller.rb
  12. +77 −0 app/controllers/requests_controller.rb
  13. +1 −1 app/controllers/support_controller.rb
  14. +3 −12 app/models/general_request.rb
  15. +11 −0 app/models/new_feature_request.rb
  16. +9 −0 app/models/time_constraint.rb
  17. +17 −0 app/models/with_requester.rb
  18. +16 −0 app/models/with_time_constraint.rb
  19. +1 −0 app/views/layouts/application.html.erb
  20. +23 −0 app/views/new_feature_requests/new.html.erb
  21. +9 −7 app/views/support/_requester.html.erb
  22. +7 −0 app/views/support/_time_constraint.html.erb
  23. +40 −0 config/initializers/validates_timeliness.rb
  24. +16 −0 config/locales/validates_timeliness.en.yml
  25. +1 −0 config/routes.rb
  26. +4 −4 features/general_requests.feature
  27. +33 −0 features/new_feature_requests.feature
  28. +0 −19 features/step_definitions/general_request_steps.rb
  29. +53 −0 features/step_definitions/request_steps.rb
  30. +9 −0 features/step_definitions/zendesk_steps.rb
  31. +2 −15 lib/general_request_zendesk_ticket.rb
  32. +32 −0 lib/new_feature_request_zendesk_ticket.rb
  33. +2 −2 lib/zendesk_request.rb
  34. +32 −10 lib/zendesk_ticket.rb
  35. +7 −0 test/unit/models/new_feature_request_test.rb
  36. +35 −0 test/unit/models/time_constraint_test.rb
  37. +21 −6 test/unit/zendesk_ticket_test.rb
  38. 0 vendor/assets/javascripts/.gitkeep
  39. 0 vendor/assets/stylesheets/.gitkeep
  40. 0 vendor/plugins/.gitkeep
View
@@ -14,9 +14,11 @@ gem 'aws-ses', require: 'aws/ses'
gem 'exception_notification', '~> 2.4.1', require: 'exception_notifier'
gem 'gds-sso', '2.1.0'
gem 'jquery-rails'
+gem 'jquery-ui-rails', '2.0.2'
gem 'plek', '0.5.0'
gem 'zendesk_api', '0.1.2'
gem 'formtastic-bootstrap', '2.0.0'
+gem 'validates_timeliness', '3.0.14'
group :test do
gem "mocha", "0.12.6", require: false
View
@@ -98,6 +98,9 @@ GEM
jquery-rails (2.1.3)
railties (>= 3.1.0, < 5.0)
thor (~> 0.14)
+ jquery-ui-rails (2.0.2)
+ jquery-rails
+ railties (>= 3.1.0)
json (1.7.5)
jwt (0.1.5)
multi_json (>= 1.0)
@@ -192,6 +195,7 @@ GEM
libv8 (~> 3.3.10)
thor (0.16.0)
tilt (1.3.3)
+ timeliness (0.3.7)
treetop (1.4.11)
polyglot
polyglot (>= 0.3.1)
@@ -203,6 +207,8 @@ GEM
kgio (~> 2.6)
rack
raindrops (~> 0.7)
+ validates_timeliness (3.0.14)
+ timeliness (~> 0.3.6)
warden (1.2.1)
rack (>= 1.0)
webmock (1.8.11)
@@ -232,6 +238,7 @@ DEPENDENCIES
formtastic-bootstrap (= 2.0.0)
gds-sso (= 2.1.0)
jquery-rails
+ jquery-ui-rails (= 2.0.2)
mocha (= 0.12.6)
plek (= 0.5.0)
poltergeist (= 0.7.0)
@@ -241,5 +248,6 @@ DEPENDENCIES
therubyracer (~> 0.9.4)
uglifier (>= 1.0.3)
unicorn (= 4.3.1)
+ validates_timeliness (= 3.0.14)
webmock (= 1.8.11)
zendesk_api (= 0.1.2)
@@ -12,4 +12,9 @@
//
//= require jquery
//= require jquery_ujs
+//= require jquery.ui.datepicker
//= require_tree .
+
+$(document).ready(function() {
+ $('input[calendar-enabled=true]').datepicker({minDate: 0, dateFormat: 'dd-mm-yy'});
+});
@@ -11,4 +11,6 @@
*= require_self
*= require_tree .
*= require formtastic-bootstrap
+ *= require jquery.ui.datepicker
+ *= require forms
*/
@@ -0,0 +1,4 @@
+legend {
+ font-size: 1.2em;
+ font-weight: bold;
+}
@@ -1,53 +1,7 @@
-require "zendesk_request"
-require "zendesk_client"
-
class ApplicationController < ActionController::Base
include GDS::SSO::ControllerMethods
before_filter :authenticate_user!
protect_from_forgery
-
- private
-
- def on_get(template)
- load_client_and_organisations("zendesk_error_upon_new_form")
-
- @formdata = {}
- render :"#{template}", :layout => "application"
- end
-
- def on_post(params, route)
- load_client_and_organisations("zendesk_error_upon_submit")
- @formdata = params
-
- if @errors.empty?
- ticket = ZendeskRequest.raise_zendesk_request(@client, params, route)
- if ticket
- redirect_to '/acknowledge'
- else
- return render :"support/zendesk_error", :locals => {:error_string => "zendesk_error_upon_submit"}
- end
- else
- render :"#{@template}", :layout => "application", :status => 400
- end
- end
-
- def load_client_and_organisations(error_string)
- begin
- @client = ZendeskClient.get_client(logger)
- @organisations = ZendeskRequest.get_organisations(@client)
- rescue ZendeskError
- return render :"support/zendesk_error", :locals => {:error_string => error_string}
- end
- end
-
- def prepopulate_organisation_list
- begin
- @client = ZendeskClient.get_client(logger)
- @organisations = ZendeskRequest.get_organisations(@client)
- rescue ZendeskError
- return render :"support/zendesk_error", :locals => {:error_string => "zendesk_error_upon_new_form"}
- end
- end
end
@@ -1,6 +1,6 @@
require 'guard'
-class ContentChangeRequestsController < ApplicationController
+class ContentChangeRequestsController < RequestsController
def new
@formdata = {}
prepopulate_organisation_list
@@ -1,4 +1,4 @@
-class CreateNewUserRequestsController < ApplicationController
+class CreateNewUserRequestsController < RequestsController
def new
@formdata = {}
prepopulate_organisation_list
@@ -1,26 +1,18 @@
require 'general_request_zendesk_ticket'
-class GeneralRequestsController < ApplicationController
- def new
- @request = GeneralRequest.new(:requester => Requester.new)
- prepopulate_organisation_list
- end
+class GeneralRequestsController < RequestsController
- def create
- @request = GeneralRequest.new(params[:general_request])
- @request.user_agent = request.user_agent
+ def new_request
+ GeneralRequest.new(:requester => Requester.new)
+ end
- load_client_and_organisations("zendesk_error_upon_submit")
+ def zendesk_ticket_class
+ GeneralRequestZendeskTicket
+ end
- if @request.valid?
- ticket = ZendeskRequest.raise_ticket(@client, GeneralRequestZendeskTicket.new(@request))
- if ticket
- redirect_to acknowledge_path
- else
- return render "support/zendesk_error", :locals => {:error_string => "zendesk_error_upon_submit"}
- end
- else
- render :new, :status => 400
- end
+ def parse_request_from_params
+ user_request = GeneralRequest.new(params[:general_request])
+ user_request.user_agent = request.user_agent
+ user_request
end
end
@@ -0,0 +1,15 @@
+require 'new_feature_request_zendesk_ticket'
+
+class NewFeatureRequestsController < RequestsController
+ def new_request
+ NewFeatureRequest.new(:requester => Requester.new, :time_constraint => TimeConstraint.new)
+ end
+
+ def zendesk_ticket_class
+ NewFeatureRequestZendeskTicket
+ end
+
+ def parse_request_from_params
+ NewFeatureRequest.new(params[:new_feature_request])
+ end
+end
@@ -1,6 +1,6 @@
require 'guard'
-class RemoveUserRequestsController < ApplicationController
+class RemoveUserRequestsController < RequestsController
def new
@formdata = {}
prepopulate_organisation_list
@@ -0,0 +1,77 @@
+require "zendesk_request"
+require "zendesk_client"
+
+class RequestsController < ApplicationController
+ def new
+ @request = new_request
+ prepopulate_organisation_list
+ end
+
+ def create
+ @request = parse_request_from_params
+ if @request.valid?
+ raise_ticket(zendesk_ticket_class.new(@request))
+ else
+ prepopulate_organisation_list
+ render :new, :status => 400
+ end
+ end
+
+ private
+
+ def on_get(template)
+ load_client_and_organisations("zendesk_error_upon_new_form")
+
+ @formdata = {}
+ render :"#{template}", :layout => "application"
+ end
+
+ def on_post(params, route)
+ load_client_and_organisations("zendesk_error_upon_submit")
+ @formdata = params
+
+ if @errors.empty?
+ ticket = ZendeskRequest.raise_zendesk_request(@client, params, route)
+ if ticket
+ redirect_to '/acknowledge'
+ else
+ return render :"support/zendesk_error", :locals => {:error_string => "zendesk_error_upon_submit"}
+ end
+ else
+ render :"#{@template}", :layout => "application", :status => 400
+ end
+ end
+
+ def raise_ticket(ticket)
+ load_client
+
+ ticket = ZendeskRequest.raise_ticket(@client, ticket)
+
+ if ticket
+ redirect_to acknowledge_path
+ else
+ return render "support/zendesk_error", :locals => {:error_string => "zendesk_error_upon_submit"}
+ end
+ end
+
+ def load_client_and_organisations(error_string)
+ load_client
+ load_organisations(error_string)
+ end
+
+ def load_client
+ @client = ZendeskClient.get_client(logger)
+ end
+
+ def load_organisations(error_string)
+ begin
+ @organisations = ZendeskRequest.get_organisations(@client)
+ rescue ZendeskError
+ return render :"support/zendesk_error", :locals => {:error_string => error_string}
+ end
+ end
+
+ def prepopulate_organisation_list
+ load_client_and_organisations("zendesk_error_upon_new_form")
+ end
+end
@@ -1,6 +1,6 @@
require "guard"
-class SupportController < ApplicationController
+class SupportController < RequestsController
def remove_user
if request.method == "GET"
on_get("useraccess/userremove")
@@ -1,17 +1,8 @@
require 'tableless_model'
-require 'requester'
+require 'with_requester'
class GeneralRequest < TablelessModel
- attr_accessor :requester, :url, :additional, :user_agent
+ include WithRequester
- validates_presence_of :requester
- validate do |request|
- if request.requester and not request.requester.valid?
- errors[:base] << "Requester details are either not complete or invalid."
- end
- end
-
- def requester_attributes=(attr)
- self.requester = Requester.new(attr)
- end
+ attr_accessor :url, :additional, :user_agent
end
@@ -0,0 +1,11 @@
+require 'tableless_model'
+require 'with_requester'
+require 'with_time_constraint'
+
+class NewFeatureRequest < TablelessModel
+ include WithRequester
+ include WithTimeConstraint
+
+ attr_accessor :user_need, :url_of_example, :inside_government
+ validates_presence_of :user_need
+end
@@ -0,0 +1,9 @@
+require 'tableless_model'
+
+class TimeConstraint < TablelessModel
+ attr_accessor :not_before_date, :needed_by_date, :time_constraint_reason
+
+ validates_date :needed_by_date, :allow_nil => true, :allow_blank => true, :on_or_after => :today
+ validates_date :not_before_date, :allow_nil => true, :allow_blank => true, :on_or_after => :today
+ validates_date :not_before_date, :before => :needed_by_date, :unless => Proc.new { |c| c.needed_by_date.nil? || c.needed_by_date.blank? }
+end
@@ -0,0 +1,17 @@
+require 'requester'
+
+module WithRequester
+ def self.included(base)
+ base.validates_presence_of :requester
+ base.validate do |request|
+ if request.requester and not request.requester.valid?
+ errors[:base] << "Requester details are either not complete or invalid."
+ end
+ end
+ end
+ attr_accessor :requester
+
+ def requester_attributes=(attr)
+ self.requester = Requester.new(attr)
+ end
+end
@@ -0,0 +1,16 @@
+require 'time_constraint'
+
+module WithTimeConstraint
+ def self.included(base)
+ base.validate do |request|
+ if request.time_constraint and not request.time_constraint.valid?
+ errors[:base] << "Time constraint details are invalid."
+ end
+ end
+ end
+ attr_accessor :time_constraint
+
+ def time_constraint_attributes=(attr)
+ self.time_constraint = TimeConstraint.new(attr)
+ end
+end
@@ -34,6 +34,7 @@
<ul class="nav nav-list">
<li class="nav-header">Content request</li>
<%= nav_link 'Content change', new_content_change_request_path %>
+ <%= nav_link 'New feature/need', new_new_feature_request_path %>
</ul>
<ul class="nav nav-list">
<li class="nav-header">User Access</li>
Oops, something went wrong.

0 comments on commit c196ced

Please sign in to comment.