Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sw integrate queue with bot #50

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
source 'https://rubygems.org'
source 'http://rubygems.org'

gem 'rails', '4.1.8'
gem 'mysql2'
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
GEM
remote: https://rubygems.org/
remote: http://rubygems.org/
specs:
actionmailer (4.1.8)
actionpack (= 4.1.8)
Expand Down
4 changes: 4 additions & 0 deletions app/models/channel_queue.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ def members_string
"```#{formatted_response}```"
end

def first_user_in_line
channel_queue_memberships.order(created_at: :asc).joins(:user).first&.user
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a NextInQueue service that's also used by the /queue open command, but it shouldn't be any different or more robust than this, afaik

end

private

def clear_inactive_members
Expand Down
24 changes: 22 additions & 2 deletions app/services/evacancy/ev_connect_service.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
module Evacancy
class EvConnectService
EV_CHARGERS_OF_50_CHANNEL_ID = 'CBJNVA87R'.freeze
# Currently we only have one building so the channel ID can be hard coded
# eventually when we have more buildings we may need a Locations model containing
# attributes like channel_id, webhook_url, and has_many StationPorts

AVAILABLE = 'AVAILABLE'.freeze

class << self
Expand All @@ -17,9 +22,24 @@ def check_ports
end

if previously_open === 0 and currently_open > 0
SlackWebhookService.send_message('A spot is available!')
channel_queue = ChannelQueue.find_by(slack_channel_id: EV_CHARGERS_OF_50_CHANNEL_ID)
first_user = channel_queue.first_user_in_line
next_in_line = first_user ? "<@#{first_user.slack_user_id}>" : "No one"

message = <<~MESSAGE
A spot is available!
#{next_in_line} is next in line!
Please dequeue with `/queue charging` after you plug in!
MESSAGE

SlackWebhookService.send_message(message)
elsif previously_open > 0 and currently_open === 0
SlackWebhookService.send_message('All spots have been taken!')
message = <<~MESSAGE
All spots have been taken!
Please dequeue with `/queue charging` if you just plugged in!
MESSAGE

SlackWebhookService.send_message(message)
end
end

Expand Down
4 changes: 2 additions & 2 deletions config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@
# ENV variables
ENV['ATTR_ENCRYPTION_KEY'] = 'DUMMY_ENCRYPTION_KEY_ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ENV['SLACK_WEBHOOKS'] = 'hook1, hook2'
ENV['EV_CONNECT_EMAIL'] = '[email protected]'
ENV['EV_CONNECT_PASSWORD'] = 'password'
ENV['EVCONNECT_EMAIL'] = '[email protected]'
ENV['EVCONNECT_PASSWORD'] = 'password'
end
4 changes: 2 additions & 2 deletions config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,6 @@
# ENV variables
ENV['ATTR_ENCRYPTION_KEY'] = 'DUMMY_ENCRYPTION_KEY_ABCDEFGHIJKLMNOPQRSTUVWXYZ'
ENV['SLACK_WEBHOOKS'] = 'hook1, hook2'
ENV['EV_CONNECT_EMAIL'] = '[email protected]'
ENV['EV_CONNECT_PASSWORD'] = 'password'
ENV['EVCONNECT_EMAIL'] = '[email protected]'
ENV['EVCONNECT_PASSWORD'] = 'password'
end
11 changes: 11 additions & 0 deletions db/migrate/20200320175734_update_ev_connect_token_type.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class UpdateEvConnectTokenType < ActiveRecord::Migration
def up
change_column :ev_connect_tokens, :access_token, :text
change_column :ev_connect_tokens, :refresh_token, :text
end

def down
change_column :ev_connect_tokens, :access_token, :string
change_column :ev_connect_tokens, :refresh_token, :string
end
end
15 changes: 15 additions & 0 deletions db/migrate/20200320185718_update_station_names.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
class UpdateStationNames < ActiveRecord::Migration
def up
EvConnectStationPort.find_by(qr_code: 'TBWS05').update!(qr_code: 'TWBS05')
EvConnectStationPort.find_by(qr_code: 'TBWS06').update!(qr_code: 'TWBS06')
EvConnectStationPort.find_by(qr_code: 'TBWS07').update!(qr_code: 'TWBS07')
EvConnectStationPort.find_by(qr_code: 'TBWS08').update!(qr_code: 'TWBS08')
end

def down
EvConnectStationPort.find_by(qr_code: 'TWBS05').update!(qr_code: 'TBWS05')
EvConnectStationPort.find_by(qr_code: 'TWBS06').update!(qr_code: 'TBWS06')
EvConnectStationPort.find_by(qr_code: 'TWBS07').update!(qr_code: 'TBWS07')
EvConnectStationPort.find_by(qr_code: 'TWBS08').update!(qr_code: 'TBWS08')
end
end
6 changes: 3 additions & 3 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20200221185935) do
ActiveRecord::Schema.define(version: 20200320185718) do

create_table "channel_queue_memberships", force: true do |t|
t.integer "user_id", null: false
Expand All @@ -35,8 +35,8 @@
end

create_table "ev_connect_tokens", force: true do |t|
t.string "access_token", null: false
t.string "refresh_token", null: false
t.text "access_token", null: false
t.text "refresh_token", null: false
t.datetime "expires_at", null: false
t.datetime "created_at"
t.datetime "updated_at"
Expand Down
14 changes: 14 additions & 0 deletions test/models/channel_queue_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,18 @@ def test_members_string__expire_after_7am__clears_inactive

assert_equal 2, ChannelQueueMembership.count
end

def test_first_user_in_line
first_user_in_line = User.create!(slack_user_id: '2', slack_user_name: 'jane', rank: 1500)
channel_queue = ChannelQueue.create!(slack_channel_name: 'ev-chargers-of-appfolio', slack_channel_id: 'U1234')
ChannelQueueMembership.create!(channel_queue: channel_queue, user: User.create!(slack_user_id: '1', slack_user_name: 'joe', rank: 1500), created_at: Time.now)
ChannelQueueMembership.create!(channel_queue: channel_queue, user: first_user_in_line, created_at: 5.minutes.ago)

assert_equal first_user_in_line, channel_queue.first_user_in_line
end

def test_first_in_line__no_users_in_line
channel_queue = ChannelQueue.create!(slack_channel_name: 'ev-chargers-of-appfolio', slack_channel_id: 'U1234')
assert_equal nil, channel_queue.first_user_in_line
end
end
55 changes: 52 additions & 3 deletions test/services/evacancy/ev_connect_service_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ class EvConnectServiceTest < ActiveSupport::TestCase
@token = EvConnectToken.create!(access_token: 'access_token', refresh_token: 'refresh_token', expires_at: Time.now + 30)
@station1 = EvConnectStationPort.create!(qr_code: 'a1', port_status: 'AVAILABLE')
@station2 = EvConnectStationPort.create!(qr_code: 'a2', port_status: 'AVAILABLE')

@channel_queue = ChannelQueue.create(slack_channel_id: 'CBJNVA87R', slack_channel_name: 'test')
end

def test_check_ports
Expand All @@ -25,7 +27,43 @@ def test_check_ports
assert_equal @station2.reload.port_status, 'AVAILABLE'
end

def test_check_ports__one_spot_opens
def test_check_ports__one_spot_opens__someone_in_line
@station1.update!(port_status: 'CHARGING')
@station2.update!(port_status: 'CHARGING')

available_response = mock
available_body = {
portStatus: 'AVAILABLE'
}.to_json
available_response.expects(:body).returns(available_body)

charging_response = mock
charging_body = {
portStatus: 'CHARGING'
}.to_json
charging_response.expects(:body).returns(charging_body)

RestClient.expects(:get).with("https://api.evconnect.com/rest/v6/networks/ev-connect/stationPorts?qrCode=#{@station1.qr_code}", { 'EVC-API-TOKEN' => @token.access_token }).returns(available_response)
RestClient.expects(:get).with("https://api.evconnect.com/rest/v6/networks/ev-connect/stationPorts?qrCode=#{@station2.qr_code}", { 'EVC-API-TOKEN' => @token.access_token }).returns(charging_response)

first_user = User.create!(slack_user_id: '2', slack_user_name: 'jane', rank: 1500)
ChannelQueueMembership.create!(channel_queue: @channel_queue, user: first_user)

message = <<~MESSAGE
A spot is available!
<@#{first_user.slack_user_id}> is next in line!
Please dequeue with `/queue charging` after you plug in!
MESSAGE

SlackWebhookService.expects(:send_message).with(message)

Evacancy::EvConnectService.check_ports

assert_equal @station1.reload.port_status, 'AVAILABLE'
assert_equal @station2.reload.port_status, 'CHARGING'
end

def test_check_ports__one_spot_opens__no_one_in_line
@station1.update!(port_status: 'CHARGING')
@station2.update!(port_status: 'CHARGING')

Expand All @@ -44,7 +82,13 @@ def test_check_ports__one_spot_opens
RestClient.expects(:get).with("https://api.evconnect.com/rest/v6/networks/ev-connect/stationPorts?qrCode=#{@station1.qr_code}", { 'EVC-API-TOKEN' => @token.access_token }).returns(available_response)
RestClient.expects(:get).with("https://api.evconnect.com/rest/v6/networks/ev-connect/stationPorts?qrCode=#{@station2.qr_code}", { 'EVC-API-TOKEN' => @token.access_token }).returns(charging_response)

SlackWebhookService.expects(:send_message).with('A spot is available!')
message = <<~MESSAGE
A spot is available!
No one is next in line!
Please dequeue with `/queue charging` after you plug in!
MESSAGE

SlackWebhookService.expects(:send_message).with(message)

Evacancy::EvConnectService.check_ports

Expand All @@ -62,7 +106,12 @@ def test_check_ports__all_spots_close
RestClient.expects(:get).with("https://api.evconnect.com/rest/v6/networks/ev-connect/stationPorts?qrCode=#{@station1.qr_code}", { 'EVC-API-TOKEN' => @token.access_token }).returns(response)
RestClient.expects(:get).with("https://api.evconnect.com/rest/v6/networks/ev-connect/stationPorts?qrCode=#{@station2.qr_code}", { 'EVC-API-TOKEN' => @token.access_token }).returns(response)

SlackWebhookService.expects(:send_message).with('All spots have been taken!')
message = <<~MESSAGE
All spots have been taken!
Please dequeue with `/queue charging` if you just plugged in!
MESSAGE

SlackWebhookService.expects(:send_message).with(message)

@station1.update!(port_status: 'AVAILABLE')

Expand Down