Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
dbbcbcd
testing Slack API Authorization
Kimberly-Fasbender Mar 19, 2019
7e44032
created workspace class and tested to ensure the api request came thru
CloudyLopez Mar 19, 2019
a4c79d6
added Slack module, User.list, and one test for it
Kimberly-Fasbender Mar 19, 2019
29f63e0
added testing for self.get & raising an Error for bad request
Kimberly-Fasbender Mar 20, 2019
1813aa0
created custom error for self.get and updated testing
Kimberly-Fasbender Mar 20, 2019
01cb461
added testing for User.list and made it pass
Kimberly-Fasbender Mar 20, 2019
0971306
updated custom error
Kimberly-Fasbender Mar 20, 2019
629990d
made a table for users
Kimberly-Fasbender Mar 20, 2019
e970ccc
wrote tests for channels spec and passed
CloudyLopez Mar 20, 2019
963687f
made additional tests for channels.rb
CloudyLopez Mar 20, 2019
1229ceb
fixed the key issue and created tests in channels and added code to o…
CloudyLopez Mar 20, 2019
019ce36
erased key oops my bad
CloudyLopez Mar 20, 2019
9bcd182
completed wave one implemented loop and all wave one requirement have…
CloudyLopez Mar 20, 2019
05f6ac3
starting wave 2, set up additional options
CloudyLopez Mar 20, 2019
3a65cc4
created workspace and some tests
CloudyLopez Mar 21, 2019
3d19813
added Workspace#select_user and updated CLI
Kimberly-Fasbender Mar 21, 2019
4214627
added testing for Workspace#select_user
Kimberly-Fasbender Mar 21, 2019
5c587fa
added testing for Recipient.list and fixed a few bugs
Kimberly-Fasbender Mar 21, 2019
bd9e395
made select_channel updates to CLI
Kimberly-Fasbender Mar 21, 2019
dfbb58b
added details & show_details pseudocode
Kimberly-Fasbender Mar 21, 2019
d1305b4
added Recipient#details, User#detail, Channel#details
Kimberly-Fasbender Mar 21, 2019
472cc1d
added testing for User#details and Channel#details
Kimberly-Fasbender Mar 21, 2019
5ce756a
updated Workspace#show_details to return false if no user or channel …
Kimberly-Fasbender Mar 21, 2019
1e11e83
added testing for Workspace#show_details for invalid parameters
Kimberly-Fasbender Mar 21, 2019
0ef65c2
added send message functionality to the CLI
Kimberly-Fasbender Mar 21, 2019
9222bf3
updated testing for Workspace#send_message
Kimberly-Fasbender Mar 21, 2019
edc7cc4
fixed a typo in CLI
Kimberly-Fasbender Mar 22, 2019
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
32 changes: 32 additions & 0 deletions lib/channels.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
require_relative "recipient"

module Slack
class Channel < Recipient
URL = "https://slack.com/api/channels.list"
PARAM = {token: ENV["KEY"]}

attr_reader :topic, :member_count

def initialize(slack_id, name, topic, member_count)
super(slack_id, name)
@name = name
@topic = topic
@member_count = member_count
end

def self.list
json_data = self.get(URL, PARAM)

json_data["channels"].map do |channel|
self.new(channel["id"], channel["name"], channel["topic"]["value"], channel["members"].length)
end
end

def details
super.push("topic", "member_count")

Choose a reason for hiding this comment

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

Very clever 👍

end
end
end

# ap Slack::User.get("https://slack.com/api/users.list", {token: ENV["KEY"]})
# # puts Slack::User.list(potato)
59 changes: 59 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
require "httparty"
require "dotenv"

Dotenv.load

module Slack
class ResponseError < StandardError; end

class Recipient
URL = "https://slack.com/api/chat.postMessage"

attr_reader :slack_id, :name

def initialize(slack_id, name)
@slack_id = slack_id
@name = name
end

def self.get(url, params)
user_data = HTTParty.get(url, query: params)

Choose a reason for hiding this comment

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

It's not always user data, so this variable name could use some improvement.


if user_data["ok"] == false
raise ResponseError, "There was an error!\nMessage: #{user_data["error"]}"
end

return user_data
end

def send_message(message, selected)
message_request = HTTParty.post(URL,
body: {
token: ENV["KEY"],
text: message,
channel: selected,
as_user: true,
},
headers: {"Content-Type" => "application/x-www-form-urlencoded"})

if message_request["ok"] == false
raise ResponseError, "There was an error!\nMessage: #{message_request["error"]}"
end

return message_request
end

def details
["name", "slack_id"]
end

def self.list
raise NotImplementedError, "Implement me in a child class!"

Choose a reason for hiding this comment

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

🥇

end
end
end

# slack = Recipient.new
# slack.get("https://slack.com/api/channels.list", {token: ENV["KEY"]})

# puts slack
66 changes: 62 additions & 4 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,69 @@
#!/usr/bin/env ruby
require_relative "workspace"
require "table_print"
require "colorize"

Dotenv.load

# module Slack
def main
puts "Welcome to the Ada Slack CLI!"
# users = Slack::User
# channel = Slack::Channel
workspace = Slack::Workspace.new

puts "Welcome to the Ada Slack CLI!".colorize(:magenta)
print "#{workspace.users.length} users and #{workspace.channels.length} ".colorize(:magenta)
puts "channels were uploaded.".colorize(:magenta)

# TODO project
selection = 1
while selection != 6
puts "\nPlease make a selection:\n".colorize(:magenta)
puts "1. list users".colorize(:blue)
puts "2. list channels".colorize(:green)
puts "3. select user".colorize(:blue)
puts "4. select channel".colorize(:green)
puts "5. details".colorize(:yellow)
puts "6. send message".colorize(:yellow)
puts "7. quit\n".colorize(:light_red)

puts "Thank you for using the Ada Slack CLI"
selection = gets.chomp

case selection
when "1", "list users"
tp workspace.users, "slack_id", :Name => {:display_method => "real_name"},
:include => {:User_Name => {:display_method => "name"}}
when "2", "list channels"
tp workspace.channels, "name", "slack_id", "topic", "member_count"
when "3", "select user"
print "Please enter in the user's USER_NAME or SLACK_ID: ".colorize(:blue)
user_descriptor = gets.chomp
puts "\n#{workspace.select_user(user_descriptor)}".colorize(:light_red)
when "4", "select channel"
print "Please enter in the channel's NAME or SLACK_ID: ".colorize(:green)
channel_descriptor = gets.chomp
puts "\n#{workspace.select_channel(channel_descriptor)}".colorize(:light_red)
when "5", "details"
if workspace.show_details == false
puts "No channel or user has been selected.".colorize(:light_red)
else
workspace.show_details
end
when "6", "send message"
print "Please enter in a message to send: ".colorize(:yellow)
message = gets.chomp
sending_message = workspace.send_message(message)
if sending_message == false
puts "--- No channel or user selected. ----".colorize(:light_red)
elsif sending_message == nil
puts "--- Invalid message, unable to send. ---".colorize(:light_red)
else puts "--- Message sent succesfully! ---".colorize(:blue) end
when "7", "quit"
puts "Thank you for using the Ada Slack CLI".colorize(:magenta)
exit
end # end
end
end

main if __FILE__ == $PROGRAM_NAME
# end

main if __FILE__ == $PROGRAM_NAME
30 changes: 30 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
require_relative "recipient"

module Slack
class User < Recipient
URL = "https://slack.com/api/users.list"
PARAM = {token: ENV["KEY"]}

attr_reader :real_name

def initialize(slack_id, name, real_name)
super(slack_id, name)
@real_name = real_name
end

def self.list
json_data = self.get(URL, PARAM)

json_data["members"].map do |user|
self.new(user["id"], user["name"], user["profile"]["real_name"])
end
end

def details
super << "real_name"
end
end
end

# ap Slack::User.get("https://slack.com/api/users.list", {token: ENV["KEY"]})
# # puts Slack::User.list(potato)
58 changes: 58 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# workspace file for keeping all things slack
require "dotenv"
require "httparty"

require_relative "user"
require_relative "channels"

Dotenv.load

module Slack
class Workspace
URL = "https://slack.com/api/users.list"
attr_reader :users, :channels
attr_accessor :selected

def initialize
@users = User.list
@channels = Channel.list
@selected = nil
end

def select_user(user_descriptor)
users.find do |user|

Choose a reason for hiding this comment

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

When using find it's intended to be used like this:

@selected = users.find do |user|
  user_descriptor == user.name || user_descriptor == user.slack_id
end

if user_descriptor == user.name || user_descriptor == user.slack_id
@selected = user
end
end

if @selected == nil

Choose a reason for hiding this comment

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

There's a subtle error in the way you have it written. Consider:

  1. I select a valid user
  2. Then I try to select an invalid user name
  3. Since @selected is not nil we won't get the returned error message.

return "Could not find a user with USER_NAME or SLACK_ID #{user_descriptor}."
end
end

def select_channel(channel_descriptor)

Choose a reason for hiding this comment

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

See notes for select_user

Also if you notice the methods are identical... you could have one method that does both!

channels.find do |channel|
if channel_descriptor == channel.name || channel_descriptor == channel.slack_id
@selected = channel
end
end

if @selected == nil
return "Could not find a channel with NAME or SLACK_ID #{channel_descriptor}."
end
end

def show_details #currently_selected_recipient
return false if @selected == nil
tp @selected, @selected.details
end

def send_message(message)
return false if @selected == nil
return nil if message == ""

return @selected.send_message(message, @selected.slack_id)
end
end
end
52 changes: 52 additions & 0 deletions specs/channels_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require_relative "test_helper"

describe "Channels" do
describe "self.get" do
it "will successfully get a response from Slack API for user list" do
VCR.use_cassette("channel_information_find") do
url = "http://slack.com/api/channels.list"
query = {token: ENV["KEY"]}
request = Slack::Channel.get(url, query)

expect(request["ok"]).must_equal true
end
end

it "will raise an exception if the GET request fails" do
VCR.use_cassette("channel_information_find") do
url = "https://slack.com/api/channel.list"
query = {token: "dkdkdkdkdkdkd"}

expect {
Slack::Channel.get(url, query)
}.must_raise Slack::ResponseError
end
end
end
end

describe "Self.list" do
it "return an array of channels" do
VCR.use_cassette("channel_information_find") do
channels = Slack::Channel.list

expect(channels).must_be_kind_of Array

(0..channels.length - 1).each do |i|
expect(channels[i]).must_be_kind_of Slack::Channel
end
end

describe "#details" do
it "must return an array that contains the correct strings" do
channel = Slack::Channel.new("potato", "head", "toy", "story")
expect(channel.details).must_be_kind_of Array
expect(channel.details[0]).must_equal "name"
expect(channel.details[1]).must_equal "slack_id"
expect(channel.details[2]).must_equal "topic"
expect(channel.details[3]).must_equal "member_count"
end
end
# # end end
end
end
16 changes: 16 additions & 0 deletions specs/recipient_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
require_relative "test_helper"

describe "Recipient Class" do
describe "self.list" do
it "raises an Error if invoked directly (without subclassing)" do
expect {
Slack::Recipient.list
}.must_raise NotImplementedError
end
end

describe "#send_message" do
it "raises an Error if incorrect parameters are given" do

Choose a reason for hiding this comment

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

So maybe verify that it must_raise

end
end
end
Empty file added specs/slack_spec.rb
Empty file.
40 changes: 30 additions & 10 deletions specs/test_helper.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
require 'simplecov'
SimpleCov.start
require "simplecov"
SimpleCov.start do
add_filter %r{^/spec/}
end

require 'minitest'
require 'minitest/autorun'
require 'minitest/reporters'
require 'minitest/skip_dsl'
require 'vcr'
require "minitest"
require "minitest/autorun"
require "minitest/reporters"
require "minitest/skip_dsl"
require "webmock/minitest"
require "vcr"
require "dotenv"
require "table_print"
Dotenv.load

Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new

require_relative "../lib/recipient"
require_relative "../lib/user"
require_relative "../lib/slack"
require_relative "../lib/channels"
require_relative "../lib/workspace"

VCR.configure do |config|
config.cassette_library_dir = "specs/cassettes"
config.hook_into :webmock
end
config.cassette_library_dir = "specs/cassettes" # folder where casettes will be located
config.hook_into :webmock # tie into this other tool called webmock
config.default_cassette_options = {
:record => :new_episodes, # record new data when we don't have it yet
:match_requests_on => [:method, :uri, :body], # The http method, URI and body of a request all need to match
}
# Don't leave our token lying around in a cassette file.
config.filter_sensitive_data("<SLACK_TOKEN>") do
ENV["KEY"]
end
end
Loading