Skip to content

Commit

Permalink
tmp
Browse files Browse the repository at this point in the history
  • Loading branch information
dtaniwaki committed May 8, 2016
1 parent 85c92ea commit 2c5fc24
Show file tree
Hide file tree
Showing 30 changed files with 487 additions and 33 deletions.
1 change: 1 addition & 0 deletions app/controllers/base_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class BaseController < ApplicationController
include Pundit
include PunditExt
include OriginConcern
include UrlHelper
after_action :verify_authorized, except: :index
after_action :verify_policy_scoped, only: :index
Expand Down
8 changes: 0 additions & 8 deletions app/controllers/browserstack_credentials_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,4 @@ def destroy
def browserstack_permitted_params
params.require(:browserstack).permit(:username, :password)
end

def origin
url = params[:origin]
return if url.nil?
url = URI.parse(url)
# Only allow redirection to the same scheme/host to avoid open redirection
url.host == request.host && url.scheme == request.scheme ? url.to_s : nil
end
end
21 changes: 21 additions & 0 deletions app/controllers/concerns/origin_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
module OriginConcern
extend ActiveSupport::Concern

included do
before_action :set_origin
helper_method :origin
end

def set_origin
session[:origin] = params[:origin] if params[:origin].present?
end

def origin
return @origin if @origin.present?
url = params[:origin] || session[:origin]
return if url.nil?
url = URI.parse(url)
# Only allow redirection to the same scheme/host to avoid open redirection
@origin ||= url.host == request.host && url.scheme == request.scheme ? url.to_s : nil
end
end
62 changes: 62 additions & 0 deletions app/controllers/slack_integrations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
class SlackIntegrationsController < BaseController
def show
@integration = UserIntegration::Slack.find(params[:id])
authorize @integration
end

def new
@integration = current_user.user_integrations.build.becomes! UserIntegration::Slack
authorize @integration
end

def create
@integration = current_user.user_integrations.build.becomes! UserIntegration::Slack
authorize @integration

@integration.assign_attributes(permitted_params)

if @integration.save
flash[:notice] = 'Successfully created new integration'
redirect_to origin || slack_integration_path(@integration)
return
end

render :new
end

def edit
@integration = UserIntegration::Slack.find(params[:id])
authorize @integration
end

def update
@integration = UserIntegration::Slack.find(params[:id])
authorize @integration

@integration.assign_attributes(permitted_params)

if @integration.save
flash[:notice] = 'Successfully updated the integration'
redirect_to origin || slack_integration_path(@integration)
return
end

render :edit
end

def destroy
@integration = UserIntegration::Slack.find(params[:id])
authorize @integration

@integration.destroy!

flash[:notice] = 'Successfully deleted the integration'
redirect_to origin || user_integrations_path
end

private

def permitted_params
params.require(:integration).permit(:name, :webhook_url)
end
end
5 changes: 5 additions & 0 deletions app/controllers/user_integrations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class UserIntegrationsController < BaseController
def index
@integrations = policy_scope!(current_user.user_integrations).all
end
end
1 change: 1 addition & 0 deletions app/models/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class Test < ApplicationRecord
has_many :user_tests, inverse_of: :test
has_many :test_versions, inverse_of: :test
has_many :updating_test_versions, -> { where(id: nil) }, class_name: 'TestVersion', inverse_of: :test
has_many :accessible_users, through: :user_tests, source: :user

acts_as_paranoid

Expand Down
17 changes: 13 additions & 4 deletions app/models/test_execution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class TestExecution < ApplicationRecord

enum state: { initial: 0, running: 1, done: 2, failed: 3 }

after_commit :send_notification!
after_commit :send_notification_async!, if: -> { previous_changes[:state].present? && (done? || failed?) }

validate :validate_execution_limit
validate :validate_executable
Expand Down Expand Up @@ -45,10 +45,19 @@ def check_completion!
end

def send_notification!
return if previous_changes[:state].nil?
return unless done? || failed?
(test.user_tests.preload(:user).map(&:user) + [user]).uniq.each do |u|
sent_to_owner = false
test.accessible_users.preload(:user_integrations).find_each do |u|
sent_to_owner = true if u == user
UserMailer.test_execution_result(u, self).deliver_now
u.user_integrations.each do |ui|
ui.notify!(:test_execution_result, self)
end
end
unless sent_to_owner
UserMailer.test_execution_result(user, self).deliver_now
user.user_integrations.each do |ui|
ui.notify!(:test_execution_result, self)
end
end
end

Expand Down
1 change: 1 addition & 0 deletions app/models/test_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class TestVersion < TestStepSet
has_many :browsers, through: :test_browsers

scope :with_user, ->(user) { joins(:user_test_versions).merge(UserTestVersion.where(user_id: user.is_a?(ActiveRecord::Base) ? user.id : user)) }
scope :with_test, ->(test) { where(test_id: test.is_a?(ActiveRecord::Base) ? test.id : test) }

after_create :assign_current_test_version!

Expand Down
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class User < ApplicationRecord
has_many :accessible_shared_test_step_sets, through: :user_shared_test_step_sets, source: :shared_test_step_set
has_many :user_credentials, class_name: 'UserCredential::Base', inverse_of: :user
has_one :browserstack_credential, class_name: 'UserCredential::Browserstack', inverse_of: :user
has_many :user_integrations, class_name: 'UserIntegration::Base', inverse_of: :user

acts_as_paranoid

Expand Down
7 changes: 7 additions & 0 deletions app/models/user_integration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module UserIntegration
def self.integration_classes
[
UserIntegration::Slack
]
end
end
37 changes: 37 additions & 0 deletions app/models/user_integration/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module UserIntegration
class Base < ApplicationRecord
include SerializedAttribute

self.table_name = 'user_integrations'

belongs_to :user, inverse_of: :user_integrations

validates :name, length: { maximum: 100 }, presence: true

before_validation :reset_last_error, if: :data_changed?

def self.policy_class
UserIntegrationPolicy
end

def notify!(name, *args)
public_send(name, *args)
self.last_error = nil
save!
rescue => e
logger.warn "#{e.message}\n #{e.backtrace.join("\n ")}"
self.last_error = e.message
save!
end

def test_execution_result(_test_execution)
raise NotImplementedError
end

private

def reset_last_error
self.last_error = nil
end
end
end
40 changes: 40 additions & 0 deletions app/models/user_integration/slack.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module UserIntegration
class Slack < Base
include UrlHelper

serialized_attribute :webhook_url

validates :webhook_url, url: true, presence: true

def test_execution_result(test_execution)
# TODO: i18n
text = "Hi #{user.name}! The test execution result of <#{test_version_position_url(test_execution.test_version)}|#{test_execution.test_version.title}> is ready."
color = case test_execution.state
when 'done'
'good'
when 'failed'
'danger'
end
faraday.post(webhook_url, username: 'E2E Tester',
text: text,
attachments: [
author_name: test_execution.user.name,
title: "Test Execution \##{test_execution.to_param}",
title_link: test_execution_url(test_execution),
color: color
])
end

private

def faraday
@faraday ||= Faraday.new(nil, ssl: { verify: false }) do |conn|
conn.request :json
conn.response :raise_error
conn.adapter Faraday.default_adapter
conn.options.timeout = 5
conn.options.open_timeout = 3
end
end
end
end
17 changes: 17 additions & 0 deletions app/policies/user_integration_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class UserIntegrationPolicy < ApplicationPolicy
def index?
true
end

def create?
true
end

def update?
@record.user == @user
end

def destroy?
@record.user == @user
end
end
4 changes: 4 additions & 0 deletions app/policies/user_test_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ def index?
true
end

def show?
@record.user == @user
end

def create?
@record.test.user_tests.with_user(@user).exists?
end
Expand Down
4 changes: 4 additions & 0 deletions app/views/slack_integrations/_form.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
= f.error_notification
= f.input :name
= f.input :webhook_url
= f.button :submit, class: 'btn-success'
10 changes: 10 additions & 0 deletions app/views/slack_integrations/edit.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- content_for :title, 'Edit Slack Test Integration'

= link_to 'Back to integrations', user_integrations_path

h1
small.glyphicon.glyphicon-link
| Edit Slack Test Integration

= simple_form_for @integration, url: slack_integration_path(@integration), as: :integration, method: :put do |f|
= render 'form', f: f
10 changes: 10 additions & 0 deletions app/views/slack_integrations/new.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
- content_for :title, 'New Slack Test Integration'

= link_to 'Back to integrations', user_integrations_path

h1
small.glyphicon.glyphicon-link
| New Slack Test Integration

= simple_form_for @integration, url: slack_integrations_path, as: :integration, method: :post do |f|
= render 'form', f: f
32 changes: 32 additions & 0 deletions app/views/slack_integrations/show.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
- content_for :title, 'Slack Test Integration'

= link_to 'Back to integrations', user_integrations_path

h1
small.glyphicon.glyphicon-link
| Slack Test Integration

.block
.pull-right
.e2e-margined-btn-group
- if policy(@integration).edit?
= link_to 'Edit', edit_slack_integration_path(@integration), class: 'btn btn-default'
- if policy(@integration).destroy?
= link_to 'Delete', slack_integration_path(@integration), method: :delete, data: { confirm: 'Are you sure?' }, class: 'btn btn-default'
h2.e2e-truncate
= @integration.name

.block
.row
.col-lg-3.text-right
| Webhook URL
.col-lg-9
= @integration.webhook_url
- if @integration.last_error.present?
.row.text-danger
.col-lg-3.text-right
.glyphicon.glyphicon-exclamation-sign
| Last Error
.col-lg-9
code = @integration.last_error

6 changes: 6 additions & 0 deletions app/views/tests/show.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@
.col-lg-6
= render '/shared/variables_form', target: @user_test, variable_name: 'user_test_variables'

.panel.panel-default
.panel-heading
= link_to user_integrations_path(origin: request.url) do
small.glyphicon.glyphicon-link
| Integrations

.col-lg-6
- user_test = @test.user_tests.build
- if policy(user_test).new?
Expand Down
35 changes: 35 additions & 0 deletions app/views/user_integrations/index.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
- content_for :title, 'User Integrations'

- if origin
= link_to 'Back', origin

h1
small.glyphicon.glyphicon-link
| User Integrations

- UserIntegration.integration_classes.each do |klass|
- records = @integrations.select { |i| i.class == klass }
.block
.pull-right
= link_to 'New Integration', new_slack_integration_path, class: 'btn btn-success'
h2
= image_tag image_path("integrations/#{klass.name.humanize.demodulize}.png"), width: 32, height: 32
= " #{klass.name.humanize.demodulize} "
small = link_to '', doc_url(:integration_slack), target: '_blank', class: 'glyphicon glyphicon-new-window'

- if records.present?
.panel.panel-default
table.table.table-striped
tr
th Name
th
- records.each do |r|
tr
td = link_to r.name, slack_integration_path(r)
td
= link_to 'Edit', edit_slack_integration_path(r)
|
= link_to 'Delete', slack_integration_path(r), method: :delete, data: { confirm: 'Are you sure?' }
- else
.alert.alert-warning
| You don't have any integration.

0 comments on commit 2c5fc24

Please sign in to comment.