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

Sockets - Tati Hana #20

Open
wants to merge 75 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
b7f136a
added .env and did verification
tatsqui Mar 19, 2019
3eb6a7c
removed comment
tatsqui Mar 19, 2019
af9d38f
creating necessary class files
tatsqui Mar 19, 2019
e0c01e4
configuring test_helper.rb
tatsqui Mar 19, 2019
b8ef5d2
debugging test_helper
tatsqui Mar 19, 2019
8d2236b
set up test spec files
hanalways Mar 19, 2019
268e8a7
initialize and create send message method
hanalways Mar 19, 2019
33024d0
require dotenv
hanalways Mar 19, 2019
daed6bd
debugging bad token and string escape characters may be needed
tatsqui Mar 19, 2019
d35b5ea
added kwards to #send_message
tatsqui Mar 19, 2019
8095052
#correction .send_message
tatsqui Mar 19, 2019
531e18f
wrote tests for .send_message and tests are green
tatsqui Mar 19, 2019
3688e72
self.get method and test
hanalways Mar 19, 2019
9c3d836
SlackError for bad parameters test
hanalways Mar 19, 2019
4dc98b3
SlackError for inauthorization
hanalways Mar 19, 2019
0ac44df
added details and self.list
hanalways Mar 20, 2019
fd2d0c9
create and move constants to respective classes
hanalways Mar 20, 2019
637be8c
"adding channel class"
tatsqui Mar 20, 2019
a3fc48c
working on self.list channel.rb
tatsqui Mar 20, 2019
6a2a7c8
refactor self.get and define constants
hanalways Mar 20, 2019
0f4cff0
added .list and #details
tatsqui Mar 20, 2019
c55c990
move constants and refactor self.get
hanalways Mar 20, 2019
a7c294e
moved constants updated self.get tests
hanalways Mar 20, 2019
b5ff318
update self.list and self.list_users methods
hanalways Mar 20, 2019
489063b
"adding tests to channel_spec"
tatsqui Mar 20, 2019
b31c6e7
"first test passed in channel_spec"
tatsqui Mar 20, 2019
85cc32e
updating self.list in Channel
tatsqui Mar 20, 2019
45f1f1b
added #details in channel class
tatsqui Mar 20, 2019
bca0e4d
added details and updated list to reference correct values
tatsqui Mar 20, 2019
963e0a9
wrote nominal tests for channel_spec
tatsqui Mar 20, 2019
3094413
generating test ideas for channel_spec
tatsqui Mar 20, 2019
84530e4
renamed httparty gem in recipient and moved private methods
tatsqui Mar 20, 2019
a48e230
user self.get self.details and tests
hanalways Mar 20, 2019
cf221f1
refactored self.list to instantiate User
hanalways Mar 20, 2019
3ed78f2
namespace with a SlackCli module
hanalways Mar 20, 2019
0484e3a
added module and refactored channel_spec
tatsqui Mar 20, 2019
f77a14f
"merge"
tatsqui Mar 20, 2019
0f9ce9d
"namespacing in recipient_spec and removed unnecessary test in channe…
tatsqui Mar 20, 2019
bc9cc58
replaced missing end
tatsqui Mar 20, 2019
6a9bdf0
added namespace to SlackError in recipient spec
tatsqui Mar 20, 2019
d42ca8f
refactor list_users so it returns nil
hanalways Mar 20, 2019
aeb1918
adding driver code to workspace in main
tatsqui Mar 20, 2019
e6fc010
merged hana's changes
tatsqui Mar 20, 2019
08fc989
added comment for me to revisit in channel#details
tatsqui Mar 20, 2019
6337047
writing more driver code in workspace
tatsqui Mar 20, 2019
34733dd
removed binding.pry
tatsqui Mar 20, 2019
e6aa86f
refactor self.list_users method
hanalways Mar 21, 2019
a88b86d
DRYed up channel/user and workspace
tatsqui Mar 21, 2019
e7ccce6
Merge branch 'master' of https://github.com/hanalways/slack-cli
tatsqui Mar 21, 2019
79412b7
list_channels and list_users methods
hanalways Mar 21, 2019
c981d71
working logic for select, bug for send_message
hanalways Mar 21, 2019
e31cace
refactor send_message method and write some tests
hanalways Mar 21, 2019
b230f92
moved driver code into slack.rb
tatsqui Mar 21, 2019
6b0725b
commented out tests for superclass Recipient
tatsqui Mar 21, 2019
1d12a37
miscellaneous changes in channel and user specs
tatsqui Mar 21, 2019
624b2b4
changed #details to return variable in method
tatsqui Mar 21, 2019
0f95b07
making tests in user and channel specs more congruent
tatsqui Mar 21, 2019
1a18c7d
added more selected_user/channel validation tests
tatsqui Mar 21, 2019
54b43c0
details method updated with error
hanalways Mar 21, 2019
64d648f
"working out #details exception"
tatsqui Mar 21, 2019
3e80151
merge
tatsqui Mar 21, 2019
1bba049
trying out tri-error block
tatsqui Mar 21, 2019
4de5188
rescue details when selected nil
tatsqui Mar 21, 2019
6b7fd8e
added real error message
tatsqui Mar 21, 2019
bf211e2
"writing edge case tests for workspace"
tatsqui Mar 21, 2019
0f93205
additional tests for coverage
hanalways Mar 22, 2019
53788e2
"made .error_helper a class method"
tatsqui Mar 22, 2019
a33963f
list_url template method, moved some tests into recipient
tatsqui Mar 22, 2019
2456ebc
"merging files"
tatsqui Mar 22, 2019
de4fa52
added missing end workspace.rb
tatsqui Mar 22, 2019
bfcc4d5
added missing ends in workspace_spec
tatsqui Mar 22, 2019
1d9024e
"editing style"
tatsqui Mar 22, 2019
df3c9f4
hid view from simplecov, and some methods in Recipient that are only …
tatsqui Mar 22, 2019
9097e75
added checking for when the select_channel or user does not exist
tatsqui Mar 22, 2019
640e673
"added one more test for selecting nil user"
tatsqui 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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
/tmp/

# Used by dotenv library to load environment variables.
# .env
.env

## Specific to RubyMotion:
.dat*
Expand Down
34 changes: 34 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
require_relative "recipient"

module SlackCli
class Channel < SlackCli::Recipient
attr_reader :topic, :member_count
def initialize(slack_id, name, topic, member_count)
@slack_id = slack_id
@name = name
@topic = topic
@member_count = member_count
end

def self.list_url
return "https://slack.com/api/channels.list"
end

def self.list
response = get
channels = response["channels"].map do |channel|
slack_id = channel["id"]
name = channel["name"]
topic = channel["topic"]["value"]
member_count = channel["num_members"]
self.new(slack_id, name, topic, member_count)
end
return channels
end

def details
deets = "Channel name: #{name} \nID: #{slack_id} \ntopic: #{topic}, \nMember count:#{member_count}\n"
return deets
end
end
end
67 changes: 67 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require "httparty"
require "pry"

require "dotenv"
Dotenv.load

module SlackCli
class SlackError < StandardError; end

class Recipient
MSG_URL = "https://slack.com/api/chat.postMessage"
TOKEN = ENV["SLACK_TOKEN"]

attr_reader :send_message, :name, :slack_id, :error_helper, :details, :list
# :nocov:
def initialize
@slack_id = slack_id
@name = name
end
# :nocov:

def self.list_url
raise NotImplementedError, "TODO: implement me in a child class"
end

Choose a reason for hiding this comment

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

This is a great use of a template method.


def post_message(name, message)
body_params = {
token: TOKEN,
as_user: true,
channel: name,
text: message,
}
response = HTTParty.post(MSG_URL, body: body_params)

if response != 200 && !response["ok"]
raise SlackCli::SlackError "Error: #{response["error"]}"
else
return response
end
end

def self.get
query_params = {
token: TOKEN,
}
response = HTTParty.get(list_url, query: query_params)
return error_helper(response)
end

# :nocov:
def details
raise NotImplementedError "TODO: implement me in a child class"
end

Choose a reason for hiding this comment

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

Instead of excluding this from coverage, why not have a test that Recipient by itself without a subclass will raise this exception when this method is called?


def self.list
raise NotImplementedError "TODO: implement me in a child class"
end
# :nocov:

def self.error_helper(response)
unless response.code == 200 && response["ok"]
raise SlackError, "Error #{response.code}: #{response["error"]}"
end
return response
end
end
end
64 changes: 59 additions & 5 deletions lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,65 @@
#!/usr/bin/env ruby
require_relative "workspace"

# :nocov:
def main
puts "Welcome to the Ada Slack CLI!"
workspace = Workspace.new
puts "TatiHana Slack Channels loaded #{SlackCli::Channel.list.length} channels"
puts "TatiHana Users loaded #{SlackCli::User.list.length} users"

# TODO project
def options
puts "Please choose one of the following options:
- list users
- list channels
- select user
- select channel
- details
- send message
- quit
Enter your choice now:"
# selected = false
end

puts "Thank you for using the Ada Slack CLI"
options
choice = gets.chomp
loop do
case choice
when "list users"
puts workspace.list_users
when "list channels"
puts workspace.list_channels
when "select user"
puts "what user would you like to select?"
selected_user = gets.chomp
workspace.select_user(selected_user)
when "select channel"
puts "What channel would you like to select?"
selected_channel = gets.chomp
workspace.select_channel(selected_channel)
when "details"
begin
puts workspace.show_details
rescue
puts "No user or channel selected, try again."
end
when "send message"
if workspace.selected == nil
puts "No user or channel selected"
else
# begin
message = gets.chomp
workspace.send_message(message)
# rescue SlackCli::SlackError
puts "No user or channel selected, try again"
# end

Choose a reason for hiding this comment

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

This error message always prints out, even if the send is successful. Instead, you should check the result and give the user positive or negative feedback.

end
when "quit"
puts "Thanks for checking out TatiHana! Bye bye..."
exit
end
options
choice = gets.chomp
end
end

main if __FILE__ == $PROGRAM_NAME
main if __FILE__ == $0
# :nocov:
45 changes: 45 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require "pry"

require_relative "recipient"

module SlackCli
class User < Recipient
attr_reader :real_name, :status_text, :status_emoji

def initialize(name, slack_id, real_name, status_text, status_emoji)
@name = name
@slack_id = slack_id
@real_name = real_name
@status_text = status_text
@status_emoji = status_emoji
end

def self.list_url
return "https://slack.com/api/users.list"
end

def self.list
response = get

users = response["members"].map do |user|
name = user["name"]
slack_id = user["id"]
real_name = user["profile"]["real_name"]
status_text = user["profile"]["status_text"]
status_emoji = user["profile"]["status_emoji"]
self.new(name, slack_id, real_name, status_text, status_emoji)
end

return users
end

def details
user_details = "Username: #{name}
Slack ID: #{slack_id}
Real Name: #{real_name}
Status Text: #{status_text}
Status Emoji: #{status_emoji}"
return user_details
end
end
end
76 changes: 76 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# workspace
require_relative "user"
require_relative "channel"
require "terminal-table"
require "pry"

class Workspace
attr_reader :users, :channels, :selected, :list_users, :list_channels

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

def select_channel(name)
@selected = @channels.find do |channel|
channel.name == name || channel.slack_id == name
end
if @selected == nil
puts "That channel does not exist"
else
return @selected
end
end

def select_user(name)
@selected = @users.find do |user|
user.name == name || user.slack_id == name
end

Choose a reason for hiding this comment

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

Good use of the .find enumerable here.


if @selected == nil
puts "That user does not exist"
else
return @selected

Choose a reason for hiding this comment

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

Since this code is here to interact with the user, I would probably consider it view code and move it to the main method.

end
end

def show_details
if @selected == nil
raise SlackCli::SlackError, "No user or channel selected!"
else
@selected.details
end
end

def send_message(message)
if @selected == nil
raise SlackCli::SlackError, "No user or channel selected!"
else
message.strip!
if message.length == 0
raise SlackCli::SlackError, "Message must cannot be nil or blank..."
else
@selected.post_message(@selected.slack_id, message)
end
end
end

def list_channels
@channels.each do |channel|
puts "Channel name: #{channel.name}
ID: #{channel.slack_id}
Topic: #{channel.topic}
Member count:#{channel.member_count}"
end
return nil
end

def list_users
@users.each do |user|
puts "#{user.real_name} Slack ID: #{user.slack_id}"
end
return nil
end
end
38 changes: 38 additions & 0 deletions specs/channel_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require_relative "test_helper"

describe "Channel" do
let(:get_response) do
VCR.use_cassette("slack/channel_get") { SlackCli::Channel.get }
end
let(:channel_list) do
VCR.use_cassette("slack/channel_list") { SlackCli::Channel.list }
end

describe "self get method" do
it "successfully returns an HTTP response object" do
channels = get_response

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

describe "list" do
it "creates a list of all channels" do
channels = channel_list

expect(channels).must_be_kind_of Array

channels.each do |channel|
expect(channel).must_be_instance_of SlackCli::Channel
end
end
end

describe "details" do
it "lists details for an instance of Channel" do
channel = channel_list[1]

Choose a reason for hiding this comment

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

What happens if you create a Channel manually with bogus data and then call .details on it?

channel = SlackCli::Channel.new('bad_id', 'channel_dne', '', 0)
channel.details

Presumably this would work just fine, but it makes an interesting test case.

expect(channel.details).must_be_kind_of String
end
end
end
Loading