Init version of twitter and facebook channel connector.

This commit is contained in:
Martin Edenhofer 2015-12-30 14:24:13 +01:00
parent 3878c40e70
commit 49172439a7
18 changed files with 831 additions and 46 deletions

View file

@ -187,6 +187,40 @@ job_integration_otrs_31:
- rake db:migrate
- ruby -I test/ test/integration/otrs_import_test.rb
job_integration_twitter_ff:
stage: browser
tags:
- browser-ff
- twitter
script:
- export BROWSER_PORT=3041
- export WS_PORT=3042
- export BROWSER_URL=http://$IP:$BROWSER_PORT
- RAILS_ENV=test rake db:create
- script/bootstrap.sh
- rake assets:precompile
- script/build/test_startup.sh $RAILS_ENV $BROWSER_PORT $WS_PORT
- ruby -I test/ test/integration/twitter_browser_test.rb || script/build/test_shutdown.sh $RAILS_ENV $BROWSER_PORT $WS_PORT 1
- script/build/test_shutdown.sh $RAILS_ENV $BROWSER_PORT $WS_PORT
http://192.168.122.75:3041/api/v1/external_credentials/twitter/callback
job_integration_facebook_ff:
stage: browser
tags:
- browser-ff
- facebook
script:
- export BROWSER_PORT=3051
- export WS_PORT=3052
- export BROWSER_URL=http://$IP:$BROWSER_PORT
- RAILS_ENV=test rake db:create
- script/bootstrap.sh
- rake assets:precompile
- script/build/test_startup.sh $RAILS_ENV $BROWSER_PORT $WS_PORT
- ruby -I test/ test/integration/facebook_browser_test.rb || script/build/test_shutdown.sh $RAILS_ENV $BROWSER_PORT $WS_PORT 1
- script/build/test_shutdown.sh $RAILS_ENV $BROWSER_PORT $WS_PORT
http://192.168.122.75:3051/api/v1/external_credentials/facebook/callback
job_integration_autowizard_ff:
stage: browser
tags:
@ -264,8 +298,8 @@ job_integration_autowizard_chrome:
tags:
- browser-chrome
script:
- export BROWSER_PORT=3071
- export WS_PORT=3072
- export BROWSER_PORT=4001
- export WS_PORT=4002
- export BROWSER_URL=http://$IP:$BROWSER_PORT
- RAILS_ENV=test rake db:create
- cp contrib/auto_wizard_example.json auto_wizard.json
@ -280,8 +314,8 @@ job_integration_browser_chrome_1:
tags:
- browser-chrome
script:
- export BROWSER_PORT=3041
- export WS_PORT=3042
- export BROWSER_PORT=4011
- export WS_PORT=4012
- export BROWSER_URL=http://$IP:$BROWSER_PORT
- unset MAILBOX_AUTO1
- unset MAILBOX_AUTO2
@ -300,8 +334,8 @@ job_integration_browser_chrome_2:
tags:
- browser-chrome
script:
- export BROWSER_PORT=3051
- export WS_PORT=3052
- export BROWSER_PORT=4021
- export WS_PORT=4022
- export BROWSER_URL=http://$IP:$BROWSER_PORT
- unset MAILBOX_AUTO1
- unset MAILBOX_AUTO2
@ -320,8 +354,8 @@ job_integration_browser_chrome_3:
tags:
- browser-chrome
script:
- export BROWSER_PORT=3061
- export WS_PORT=3062
- export BROWSER_PORT=4031
- export WS_PORT=4032
- export BROWSER_URL=http://$IP:$BROWSER_PORT
- unset MAILBOX_AUTO1
- unset MAILBOX_AUTO2

View file

@ -486,9 +486,6 @@ class App.Controller extends Spine.Controller
item.created_by = App.User.find( item.created_by_id )
items
ws_send: (data) ->
App.Event.trigger( 'ws:send', JSON.stringify(data) )
# central method, is getting called on every ticket form change
ticketFormChanges: (params, attribute, attributes, classname, form, ui) =>
if @formMeta.dependencies && @formMeta.dependencies[attribute.name]
@ -573,6 +570,10 @@ class App.Controller extends Spine.Controller
logoUrl: ->
"#{@Config.get('image_path')}/#{@Config.get('product_logo')}"
selectAll: (e) ->
e.currentTarget.focus()
e.currentTarget.select()
class App.ControllerPermanent extends App.Controller
constructor: ->
super

View file

@ -1,16 +1,186 @@
class App.ChannelFacebook extends App.Controller
class Index extends App.ControllerContent
events:
'click .js-new': 'new'
'click .js-edit': 'edit'
'click .js-delete': 'delete'
'click .js-configApp': 'configApp'
constructor: ->
super
return if !@authenticate()
@title 'Facebook'
#@interval(@load, 60000)
@load()
# render page
@render()
render: ->
@html App.view('channel/facebook')(
head: 'some header'
load: =>
@startLoading()
@ajax(
id: 'facebook_index'
type: 'GET'
url: "#{@apiPath}/channels/facebook_index"
processData: true
success: (data, status, xhr) =>
@stopLoading()
App.Collection.loadAssets(data.assets)
@callbackUrl = data.callback_url
@render(data)
)
App.Config.set( 'Facebook', { prio: 6000, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: App.ChannelFacebook, role: ['Admin'] }, 'NavBarAdmin' )
render: (data) =>
# if no facebook app is registered, show intro
if !App.ExternalCredential.findByAttribute(name: 'facebook')
@html App.view('facebook/index')()
return
channels = []
for channel_id in data.channel_ids
channel = App.Channel.find(channel_id)
if channel && channel.options && channel.options.sync
displayName = '-'
if channel.options.sync.wall.group_id
group = App.Group.find(channel.options.sync.wall.group_id)
displayName = group.displayName()
channel.options.sync.wall.groupName = displayName
for page in channel.options.pages
displayName = '-'
for page_id, pageParams of channel.options.sync.pages
if page.id is page_id
if pageParams.group_id
group = App.Group.find(pageParams.group_id)
displayName = group.displayName()
page.groupName = displayName
channels.push channel
@html App.view('facebook/list')(
channels: channels
)
# accounts: accounts
# showDescription: showDescription
# description: description
if @channel_id
@edit(undefined, @channel_id)
configApp: =>
external_credential = App.ExternalCredential.findByAttribute('name', 'facebook')
contentInline = $(App.view('facebook/app_config')(
external_credential: external_credential
callbackUrl: @callbackUrl
))
contentInline.find('.js-select').on('click', (e) =>
@selectAll(e)
)
modal = new App.ControllerModal(
head: 'Connect Facebook App'
container: @el.parents('.content')
contentInline: contentInline
shown: true
button: 'Connect'
cancel: true
small: true
onSubmit: (e) =>
@formDisable(e)
# verify app credentals
@ajax(
id: 'facebook_app_verify'
type: 'POST'
url: "#{@apiPath}/external_credentials/facebook/app_verify"
data: JSON.stringify(modal.formParams())
processData: true
success: (data, status, xhr) =>
if data.attributes
if !external_credential
external_credential = new App.ExternalCredential
external_credential.load(name: 'facebook', credentials: modal.formParams())
external_credential.save(
done: =>
@load()
modal.close()
fail: ->
modal.element().find('.alert').removeClass('hidden').text('Unable to create entry.')
)
return
@formEnable(e)
modal.element().find('.alert').removeClass('hidden').text(data.error || 'Unable to verify App.')
)
)
new: (e) ->
window.location.href = "#{@apiPath}/external_credentials/facebook/link_account"
edit: (e, id) =>
if e
e.preventDefault()
id = $(e.target).closest('.action').data('id')
channel = App.Channel.find(id)
if !channel.options.sync
channel.options.sync = {}
if !channel.options.sync.wall
channel.options.sync.wall = {}
if !channel.options.sync.pages
channel.options.sync.pages = {}
content = $( App.view('facebook/account_edit')(channel: channel) )
groupSelection = (selected_id, el, prefix) ->
selection = App.UiElement.select.render(
name: "#{prefix}::group_id"
multiple: false
limit: 100
null: false
relation: 'Group'
nulloption: true
default: selected_id
)
el.html(selection)
groupSelection(channel.options.sync.wall.group_id, content.find('.js-wall .js-groups'), 'wall')
for page in channel.options.pages
pageConfigured = false
for page_id, pageParams of channel.options.sync.pages
if page.id is page_id
pageConfigured = true
groupSelection(pageParams.group_id, content.find(".js-groups[data-page-id=#{page.id}]"), "pages::#{page.id}")
if !pageConfigured
groupSelection('', content.find(".js-groups[data-page-id=#{page.id}]"), "pages::#{page.id}")
modal = new App.ControllerModal(
head: 'Facebook Account'
container: @el.parents('.content')
contentInline: content
shown: true
cancel: true
onSubmit: (e) =>
@formDisable(e)
channel.options.sync = modal.formParams()
@ajax(
id: 'channel_facebook_update'
type: 'POST'
url: "#{@apiPath}/channels/facebook_verify/#{channel.id}"
data: JSON.stringify(channel.attributes())
processData: true
success: (data, status, xhr) =>
@load()
modal.close()
fail: =>
@formEnable(e)
)
)
delete: (e) =>
e.preventDefault()
id = $(e.target).closest('.action').data('id')
item = App.Channel.find(id)
new App.ControllerGenericDestroyConfirm(
item: item
container: @el.closest('.content')
callback: @load
)
description: (e) =>
new App.ControllerGenericDescription(
description: App.Twitter.description
container: @el.closest('.content')
)
App.Config.set('Facebook', { prio: 5100, name: 'Facebook', parent: '#channels', target: '#channels/facebook', controller: Index, role: ['Admin'] }, 'NavBarAdmin')

View file

@ -4,7 +4,6 @@ class Index extends App.ControllerContent
'click .js-edit': 'edit'
'click .js-delete': 'delete'
'click .js-configApp': 'configApp'
'click .js-configApp': 'configApp'
constructor: ->
super
@ -23,12 +22,13 @@ class Index extends App.ControllerContent
success: (data, status, xhr) =>
@stopLoading()
App.Collection.loadAssets(data.assets)
@callbackUrl = data.callback_url
@render(data)
)
render: (data) =>
# if no twitter app is registered, show into
# if no twitter app is registered, show intro
if !App.ExternalCredential.findByAttribute(name: 'twitter')
@html App.view('twitter/index')()
return
@ -66,12 +66,19 @@ class Index extends App.ControllerContent
if @channel_id
@edit(undefined, @channel_id)
configApp: ->
external_credential = App.ExternalCredential.findByAttribute(name: 'twitter')
configApp: =>
external_credential = App.ExternalCredential.findByAttribute('name', 'twitter')
contentInline = $(App.view('twitter/app_config')(
external_credential: external_credential
callbackUrl: @callbackUrl
))
contentInline.find('.js-select').on('click', (e) =>
@selectAll(e)
)
modal = new App.ControllerModal(
head: 'Connect Twitter App'
container: @el.parents('.content')
contentInline: App.view('twitter/app_config')(external_credential: external_credential)
contentInline: contentInline
shown: true
button: 'Connect'
cancel: true

View file

@ -37,10 +37,6 @@ class CalendarSubscriptions extends App.Controller
$(e.currentTarget).next().removeClass('is-hidden')
$(e.currentTarget).remove()
selectAll: (e) ->
e.currentTarget.focus()
e.currentTarget.select()
onOptionsChange: =>
@setAllPreferencesToFalse()

View file

@ -0,0 +1,20 @@
<div class="alert alert--danger hidden" role="alert"></div>
<fieldset>
<%- @T('Wall') %>
<div class="js-wall">
<%= @channel.options.user.name %> -> <div data-page-id="<%= @channel.options.user.id %>" class="js-groups"></div>
</div>
<hr>
<%- @T('Pages') %>
<div class="js-pages">
<% if @channel.options.pages: %>
<% for page in @channel.options.pages: %>
<%= page.name %> -> <div data-page-id="<%= page.id %>" class="js-groups"></div><br>
<% end %>
<% end %>
</div>
</fieldset>

View file

@ -0,0 +1,29 @@
<div class="alert alert--danger hidden" role="alert"></div>
<p>
The tutorial on how to create a Facebook App is hosted on <a href="http://zammad.org/twitter-app-tutorial" target="_blank">zammad.org/facebook-app-tutorial</a>
</p>
<fieldset>
<h2><%- @T('Enter your %s App Keys', 'Facebook') %></h2>
<div class="input form-group">
<div class="formGroup-label">
<label for="application_id">Facebook APP ID <span>*</span></label>
</div>
<div class="controls">
<input id="application_id" type="text" name="application_id" value="<% if @external_credential && @external_credential.credentials: %><%= @external_credential.credentials.application_id %><% end %>" class="form-control" required autocomplete="off" >
</div>
</div>
<div class="input form-group">
<div class="formGroup-label">
<label for="application_secret">Facebook App Secret <span>*</span></label>
</div>
<div class="controls">
<input id="application_secret" type="text" name="application_secret" value="<% if @external_credential && @external_credential.credentials: %><%= @external_credential.credentials.application_secret %><% end %>" class="form-control" required autocomplete="off" >
</div>
</div>
<h2><%- @T('Your callback URL') %></h2>
<div class="input form-group">
<div class="controls">
<input class="form-control js-select" readonly value="<%= @callbackUrl %>">
</div>
</div>
</fieldset>

View file

@ -0,0 +1,14 @@
<div class="page-header">
<div class="page-header-title">
<h1><%- @T('Facebook') %> <small><%- @T('Accounts') %></small></h1>
</div>
</div>
<div class="page-content">
<div class="page-description">
<p>
Lorem ipsum Consequat ex dolore ullamco dolor ut eu eiusmod voluptate. Lorem ipsum Non aliquip Ut veniam cupidatat velit deserunt. Lorem ipsum Id reprehenderit deserunt esse eiusmod exercitation. Lorem ipsum Voluptate mollit sed Ut nulla consequat enim. Lorem ipsum Adipisicing ullamco dolor elit officia pariatur ex ea laboris Ut exercitation proident sed. Lorem ipsum In officia reprehenderit sed nulla incididunt aute incididunt ad quis tempor. Lorem ipsum Dolore est id minim dolore et labore incididunt commodo. Lorem ipsum Excepteur non consectetur anim ut nostrud amet et. Lorem ipsum Sunt nostrud nulla officia aute laborum enim in pariatur sit enim et.
</p>
<div class="btn btn--success js-configApp"><%- @T('Connect Facebook App') %></div>
</div>
</div>

View file

@ -0,0 +1,41 @@
<div class="page-header">
<div class="page-header-title">
<h1><%- @T('Facebook') %> <small><%- @T('Accounts') %></small></h1>
</div>
<div class="page-header-meta">
<a class="btn js-configApp"><%- @T('Configure App') %></a>
<a class="btn btn--success js-new"><%- @T('Add Account') %></a>
</div>
</div>
<div class="page-content">
<% for channel in @channels: %>
<div class="action" data-id="<%= channel.id %>">
<div class="action-block action-row">
<h2><%- @Icon('status', 'supergood-color inline') %> <%= channel.options.user.name %> <span class="text-muted"><%= channel.options.user.id %></span></h2>
</div>
<div class="action-flow action-flow--row">
<div class="action-block">
<h3><%- @T('Wall') %></h3>
<%= channel.options.user.name %> -> <%= channel.options.sync.wall.groupName %>
</div>
</div>
<div class="action-flow action-flow--row">
<div class="action-block">
<h3><%- @T('Pages') %></h3>
<% if channel.options.pages: %>
<% for page in channel.options.pages: %>
<%= page.name %> -> <%= page.groupName %><br>
(<%= page.perms %>)<br>
<% end %>
<% end %>
</div>
</div>
<div class="action-controls">
<div class="sla-toggle btn btn--danger btn--secondary js-delete"><%- @T('Delete') %></div>
<div class="sla-edit btn js-edit"><%- @T('Edit') %></div>
</div>
</div>
<% end %>
</div>

View file

@ -3,7 +3,7 @@
The tutorial on how to create a Twitter App is hosted on <a href="http://zammad.org/twitter-app-tutorial" target="_blank">zammad.org/twitter-app-tutorial</a>
</p>
<fieldset>
<h2>Enter your Twitter App Keys</h2>
<h2><%- @T('Enter your %s App Keys', 'Twitter') %></h2>
<div class="input form-group">
<div class="formGroup-label">
<label for="consumer_key">Twitter API Key <span>*</span></label>
@ -20,4 +20,10 @@
<input id="consumer_secret" type="text" name="consumer_secret" value="<% if @external_credential && @external_credential.credentials: %><%= @external_credential.credentials.consumer_secret %><% end %>" class="form-control" required autocomplete="off" >
</div>
</div>
<h2><%- @T('Your callback URL') %></h2>
<div class="input form-group">
<div class="controls">
<input class="form-control js-select" readonly value="<%= @callbackUrl %>">
</div>
</div>
</fieldset>

View file

@ -59,6 +59,7 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
render json: {
assets: assets,
channel_ids: channel_ids,
callback_url: ExternalCredential.callback_url('twitter'),
}
end
@ -67,6 +68,29 @@ curl http://localhost/api/v1/channels.json -v -u #{login}:#{password} -H "Conten
model_update_render(Channel, params)
end
def facebook_index
assets = {}
ExternalCredential.where(name: 'facebook').each {|external_credential|
assets = external_credential.assets(assets)
}
channel_ids = []
Channel.order(:id).each {|channel|
next if channel.area != 'Facebook::Account'
assets = channel.assets(assets)
channel_ids.push channel.id
}
render json: {
assets: assets,
channel_ids: channel_ids,
callback_url: ExternalCredential.callback_url('facebook'),
}
end
def facebook_verify
return if deny_if_not_role(Z_ROLENAME_ADMIN)
model_update_render(Channel, params)
end
def email_index
return if deny_if_not_role(Z_ROLENAME_ADMIN)
system_online_service = Setting.get('system_online_service')

View file

@ -34,13 +34,12 @@ class ExternalCredentialsController < ApplicationController
return
rescue => e
render json: { error: e.message }, status: :ok
end
def link_account
return if deny_if_not_role(Z_ROLENAME_ADMIN)
provider = params[:provider].downcase
attributes = ExternalCredential.request_account_to_link(provider, callback_url(provider))
attributes = ExternalCredential.request_account_to_link(provider)
session[:request_token] = attributes[:request_token]
redirect_to attributes[:authorize_url]
end
@ -56,11 +55,11 @@ class ExternalCredentialsController < ApplicationController
private
def callback_url(provider)
"#{Setting.get('http_type')}://#{Setting.get('fqdn')}#{Rails.configuration.api_path}/external_credentials/#{provider}/callback"
ExternalCredential.callback_url(provider)
end
def app_url(provider, channel_id)
"#{Setting.get('http_type')}://#{Setting.get('fqdn')}/#channels/#{provider}/#{channel_id}"
ExternalCredential.app_url(provider, channel_id)
end
end

View file

@ -9,9 +9,9 @@ class ExternalCredential < ApplicationModel
backend.app_verify(params)
end
def self.request_account_to_link(provider, callback)
def self.request_account_to_link(provider)
backend = load_backend(provider)
backend.request_account_to_link(callback)
backend.request_account_to_link
end
def self.link_account(provider, request_token, params)
@ -19,6 +19,14 @@ class ExternalCredential < ApplicationModel
backend.link_account(request_token, params)
end
def self.callback_url(provider)
"#{Setting.get('http_type')}://#{Setting.get('fqdn')}#{Rails.configuration.api_path}/external_credentials/#{provider}/callback"
end
def self.app_url(provider, channel_id)
"#{Setting.get('http_type')}://#{Setting.get('fqdn')}/#channels/#{provider}/#{channel_id}"
end
def self.load_backend(provider)
adapter = "ExternalCredential::#{provider.camelcase}"
require "#{adapter.to_filename}"

View file

@ -13,6 +13,10 @@ Zammad::Application.routes.draw do
match api_path + '/channels/twitter_index', to: 'channels#twitter_index', via: :get
match api_path + '/channels/twitter_verify/:id', to: 'channels#twitter_verify', via: :post
# facebook helper
match api_path + '/channels/facebook_index', to: 'channels#facebook_index', via: :get
match api_path + '/channels/facebook_verify/:id', to: 'channels#facebook_verify', via: :post
# channels
match api_path + '/channels/group/:id', to: 'channels#group_update', via: :post
match api_path + '/channels/:id', to: 'channels#destroy', via: :delete

View file

@ -0,0 +1,87 @@
class ExternalCredential::Facebook
def self.app_verify(params)
request_account_to_link(params)
params
end
def self.request_account_to_link(credentials = {})
external_credential = ExternalCredential.find_by(name: 'facebook')
if !credentials[:application_id]
credentials[:application_id] = external_credential.credentials['application_id']
end
if !credentials[:application_secret]
credentials[:application_secret] = external_credential.credentials['application_secret']
end
oauth = Koala::Facebook::OAuth.new(
credentials[:application_id],
credentials[:application_secret],
ExternalCredential.callback_url('facebook'),
)
oauth.get_app_access_token.inspect
state = rand(999_999_999_999).to_s
{
request_token: state,
authorize_url: oauth.url_for_oauth_code(permissions: 'publish_pages, manage_pages', state: state),
}
end
def self.link_account(_request_token, params)
# fail if request_token.params[:oauth_token] != params[:state]
external_credential = ExternalCredential.find_by(name: 'facebook')
fail 'No such account' if !external_credential
oauth = Koala::Facebook::OAuth.new(
external_credential.credentials['application_id'],
external_credential.credentials['application_secret'],
ExternalCredential.callback_url('facebook'),
)
access_token = oauth.get_access_token(params[:code])
client = Koala::Facebook::API.new(access_token)
user = client.get_object('me')
#p client.get_connections('me', 'accounts').inspect
pages = []
client.get_connections('me', 'accounts').each { |page|
pages.push(
id: page['id'],
name: page['name'],
access_token: page['access_token'],
perms: page['perms'],
)
}
# check if account already exists
Channel.where(area: 'Facebook::Account').each {|channel|
next if !channel.options
next if !channel.options['user']
next if !channel.options['user']['id']
next if channel.options['user']['id'] != user['id']
channel.options['auth']['access_token'] = access_token
channel.options['pages'] = pages
channel.save
return channel
}
# create channel
Channel.create(
area: 'Facebook::Account',
options: {
adapter: 'facebook',
auth: {
access_token: access_token
},
user: user,
pages: pages,
sync: {
wall: {},
pages: [],
}
},
active: true,
created_by_id: 1,
updated_by_id: 1,
)
end
end

View file

@ -1,15 +1,11 @@
class ExternalCredential::Twitter
def self.app_verify(params)
attributes = {
consumer_key: params[:consumer_key],
consumer_secret: params[:consumer_secret],
}
request_account_to_link('', attributes)
attributes
request_account_to_link(params)
params
end
def self.request_account_to_link(callback_url, credentials = {})
def self.request_account_to_link(credentials = {})
external_credential = ExternalCredential.find_by(name: 'twitter')
if !credentials[:consumer_key]
credentials[:consumer_key] = external_credential.credentials['consumer_key']
@ -21,8 +17,9 @@ class ExternalCredential::Twitter
credentials[:consumer_key],
credentials[:consumer_secret], {
site: 'https://api.twitter.com'
})
request_token = consumer.get_request_token(oauth_callback: callback_url)
}
)
request_token = consumer.get_request_token(oauth_callback: ExternalCredential.callback_url('twitter'))
{
request_token: request_token,
authorize_url: request_token.authorize_url,
@ -41,6 +38,21 @@ class ExternalCredential::Twitter
)
user = client.user
# check if account already exists
Channel.where(area: 'Twitter::Account').each {|channel|
next if !channel.options
next if !channel.options['user']
next if !channel.options['user']['id']
next if channel.options['user']['id'] != user['id']
# update access_token
channel.options['auth']['external_credential_id'] = external_credential.id
channel.options['auth']['oauth_token'] = access_token.token
channel.options['auth']['oauth_token_secret'] = access_token.secret
channel.save
return channel
}
# create channel
Channel.create(
area: 'Twitter::Account',

View file

@ -0,0 +1,170 @@
# encoding: utf-8
require 'browser_test_helper'
class FacebookBrowserTest < TestCase
def test_add_config
# app config
if !ENV['FACEBOOK_APP_ID']
fail "ERROR: Need FACEBOOK_APP_ID - hint FACEBOOK_APP_ID='1234'"
end
app_id = ENV['FACEBOOK_APP_ID']
if !ENV['FACEBOOK_APP_SECRET']
fail "ERROR: Need FACEBOOK_APP_SECRET - hint FACEBOOK_APP_SECRET='1234'"
end
app_secret = ENV['FACEBOOK_APP_SECRET']
if !ENV['FACEBOOK_USER_LOGIN']
fail "ERROR: Need FACEBOOK_USER_LOGIN - hint FACEBOOK_USER_LOGIN='1234'"
end
user_login = ENV['FACEBOOK_USER_LOGIN']
if !ENV['FACEBOOK_USER_PW']
fail "ERROR: Need FACEBOOK_USER_PW - hint FACEBOOK_USER_PW='1234'"
end
user_pw = ENV['FACEBOOK_USER_PW']
@browser = browser_instance
login(
username: 'master@example.com',
password: 'test',
url: browser_url,
)
tasks_close_all()
click(css: 'a[href="#manage"]')
click(css: 'a[href="#channels/facebook"]')
click(css: '#content .js-configApp')
sleep 2
set(
css: '#content .modal [name=application_id]',
value: app_id,
)
set(
css: '#content .modal [name=application_secret]',
value: 'wrong',
)
click(css: '#content .modal .js-submit')
watch_for(
css: '#content .modal .alert',
value: 'Error',
)
set(
css: '#content .modal [name=application_secret]',
value: app_secret,
)
click(css: '#content .modal .js-submit')
watch_for_disappear(
css: '#content .modal .alert',
value: 'Error',
)
watch_for(
css: '#content .js-new',
value: 'add account',
)
click(css: '#content .js-configApp')
set(
css: '#content .modal [name=application_secret]',
value: 'wrong',
)
click(css: '#content .modal .js-submit')
watch_for(
css: '#content .modal .alert',
value: 'Error',
)
set(
css: '#content .modal [name=application_secret]',
value: app_secret,
)
click(css: '#content .modal .js-submit')
watch_for_disappear(
css: '#content .modal .alert',
value: 'Error',
)
watch_for(
css: '#content .js-new',
value: 'add account',
)
click(css: '#content .js-new')
watch_for(
css: 'body',
value: 'Facebook Login',
)
set(
css: '#email',
value: user_login,
)
set(
css: '#pass',
value: user_pw,
)
click(css: '#login_button_inline')
#sleep 10
#click(css: 'div[role="dialog"] button[type="submit"][name="__CONFIRM__"]')
#sleep 10
#click(css: 'div[role="dialog"] button[type="submit"][name="__CONFIRM__"]')
#sleep 10
#watch_for(
# css: '#content .modal',
# value: '',
#)
watch_for(
css: '#navigation',
value: 'Dashboard',
)
#click(css: '#content .modal .js-close')
watch_for(
css: '#content',
value: 'Hansi Merkur',
)
exists(
css: '#content .main .action:nth-child(1)'
)
exists_not(
css: '#content .main .action:nth-child(2)'
)
click(css: '#content .js-new')
sleep 10
#click(css: '#login_button_inline')
#watch_for(
# css: '#content .modal',
# value: 'Search Terms',
#)
#click(css: '#content .modal .js-close')
watch_for(
css: '#content',
value: 'Hansi Merkur',
)
exists(
css: '#content .main .action:nth-child(1)'
)
exists_not(
css: '#content .main .action:nth-child(2)'
)
end
end

View file

@ -0,0 +1,163 @@
# encoding: utf-8
require 'browser_test_helper'
class TwitterBrowserTest < TestCase
def test_add_config
# app config
if !ENV['TWITTER_CONSUMER_KEY']
fail "ERROR: Need TWITTER_CONSUMER_KEY - hint TWITTER_CONSUMER_KEY='1234'"
end
consumer_key = ENV['TWITTER_CONSUMER_KEY']
if !ENV['TWITTER_CONSUMER_SECRET']
fail "ERROR: Need TWITTER_CONSUMER_SECRET - hint TWITTER_CONSUMER_SECRET='1234'"
end
consumer_secret = ENV['TWITTER_CONSUMER_SECRET']
if !ENV['TWITTER_USER_LOGIN']
fail "ERROR: Need TWITTER_USER_LOGIN - hint TWITTER_USER_LOGIN='1234'"
end
twitter_user_loign = ENV['TWITTER_USER_LOGIN']
if !ENV['TWITTER_USER_PW']
fail "ERROR: Need TWITTER_USER_PW - hint TWITTER_USER_PW='1234'"
end
twitter_pw = ENV['TWITTER_USER_PW']
@browser = browser_instance
login(
username: 'master@example.com',
password: 'test',
url: browser_url,
)
tasks_close_all()
click(css: 'a[href="#manage"]')
click(css: 'a[href="#channels/twitter"]')
click(css: '#content .js-configApp')
sleep 2
set(
css: '#content .modal [name=consumer_key]',
value: consumer_key,
)
set(
css: '#content .modal [name=consumer_secret]',
value: 'wrong',
)
click(css: '#content .modal .js-submit')
watch_for(
css: '#content .modal .alert',
value: 'Authorization Required',
)
set(
css: '#content .modal [name=consumer_secret]',
value: consumer_secret,
)
click(css: '#content .modal .js-submit')
watch_for_disappear(
css: '#content .modal .alert',
value: 'Authorization Required',
)
watch_for(
css: '#content .js-new',
value: 'add account',
)
click(css: '#content .js-configApp')
set(
css: '#content .modal [name=consumer_secret]',
value: 'wrong',
)
click(css: '#content .modal .js-submit')
watch_for(
css: '#content .modal .alert',
value: 'Authorization Required',
)
set(
css: '#content .modal [name=consumer_secret]',
value: consumer_secret,
)
click(css: '#content .modal .js-submit')
watch_for_disappear(
css: '#content .modal .alert',
value: 'Authorization Required',
)
watch_for(
css: '#content .js-new',
value: 'add account',
)
click(css: '#content .js-new')
sleep 10
set(
css: '#username_or_email',
value: twitter_user_loign,
)
set(
css: '#password',
value: twitter_pw,
)
click(css: '#allow')
#watch_for(
# css: '.notice.callback',
# value: 'Redirecting you back to the application',
#)
watch_for(
css: '#content .modal',
value: 'Search Terms',
)
click(css: '#content .modal .js-close')
watch_for(
css: '#content',
value: 'Armin Theo',
)
exists(
css: '#content .main .action:nth-child(1)'
)
exists_not(
css: '#content .main .action:nth-child(2)'
)
# add account again
click(css: '#content .js-new')
sleep 10
click(css: '#allow')
watch_for(
css: '#content .modal',
value: 'Search Terms',
)
click(css: '#content .modal .js-close')
watch_for(
css: '#content',
value: 'Armin Theo',
)
exists(
css: '#content .main .action:nth-child(1)'
)
exists_not(
css: '#content .main .action:nth-child(2)'
)
end
end