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

Water - Marj & Sophia #26

Open
wants to merge 49 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
357833e
initial commit, added Workspace class file
Schmarj3 Oct 6, 2020
56499a7
added gemfile
Schmarj3 Oct 6, 2020
8aea6f9
moved .env file to lib directory
Schmarj3 Oct 6, 2020
ddc3a7f
added dotenv.load for testing
Schmarj3 Oct 6, 2020
fe91dea
troubleshooting .env
SoCodeDo Oct 6, 2020
14c2410
Merge branch 'master' of https://github.com/Schmarj3/slack-cli into m…
SoCodeDo Oct 6, 2020
5e23a2d
add dotenv.load again
SoCodeDo Oct 7, 2020
e217619
changed dotenv to Dotenv.load
Schmarj3 Oct 7, 2020
874389d
updated vcr,removed params from Workspace class
Schmarj3 Oct 7, 2020
dc5bc9a
add new file for Channel class
Schmarj3 Oct 7, 2020
70de03d
updated workspace.rb with template code, removed comments from slack.rb
Schmarj3 Oct 7, 2020
60784a0
added new files for class User and Recipient
Schmarj3 Oct 7, 2020
c831b5b
added template code to Channel and Recipient class
Schmarj3 Oct 7, 2020
079a887
Wave 1 Complete
SoCodeDo Oct 7, 2020
4f15584
added new prompt options for wave 2
Schmarj3 Oct 7, 2020
e332dd9
added some pseudo code to several class files
Schmarj3 Oct 8, 2020
82d978e
added require statments for httparty and env
Schmarj3 Oct 8, 2020
09d048f
added url, params, and get http method
Schmarj3 Oct 8, 2020
b66cd02
fixed the self.get method
Schmarj3 Oct 8, 2020
f4b031c
added instance variables and called new class for testing
Schmarj3 Oct 8, 2020
30556a7
removed extra comma in attr_reader
Schmarj3 Oct 8, 2020
875aa2c
added channel class code to user class
Schmarj3 Oct 8, 2020
8e5080d
made changes to self.list all method in channel and user classes
Schmarj3 Oct 8, 2020
2a08a46
fixed initialize method formatting
Schmarj3 Oct 8, 2020
3dd6feb
added pp for testing User self.list_all
Schmarj3 Oct 8, 2020
34e3e7d
fixed the User self.list_all, changed formatting
Schmarj3 Oct 8, 2020
baa3662
added code to the select_channel method
Schmarj3 Oct 8, 2020
7e4ca44
fixed the list_all method in Channel and User classes
Schmarj3 Oct 8, 2020
a2a130d
added workspace.rb added select_user method and debugged select_chann…
Schmarj3 Oct 8, 2020
ceb0bd1
updated workspace select user and channel methods
Schmarj3 Oct 9, 2020
cfc9255
assigned workspace instance variable in slack.rb
Schmarj3 Oct 9, 2020
1764779
removed logic from selected instance variable
Schmarj3 Oct 9, 2020
5e78123
changed how selected instance variable is stored
Schmarj3 Oct 9, 2020
62a6fd4
removed return statment in select user and channel
Schmarj3 Oct 9, 2020
9b3a944
changed code in show_details method and select user and channnel methods
Schmarj3 Oct 9, 2020
cb7eb51
modified slack.rb
SoCodeDo Oct 9, 2020
fb62659
added slack_api_wrapper.rb
SoCodeDo Oct 9, 2020
4d2988b
Wave 3 in progress
SoCodeDo Oct 10, 2020
39b0ea0
debugging false message return with HTTParty
SoCodeDo Oct 10, 2020
21daf11
removed commented lines that were no longer needed
Schmarj3 Oct 10, 2020
ed81649
changed key for httparty.post method
Schmarj3 Oct 10, 2020
70d9cd4
started creating tests
SoCodeDo Oct 10, 2020
b843781
modified channel_test and test_helper
SoCodeDo Oct 10, 2020
91f9d05
channel test passing 73% coverage
SoCodeDo Oct 10, 2020
c467a49
started writing user and workspace tests
SoCodeDo Oct 10, 2020
6c1f594
workspace test in progress, passing
SoCodeDo Oct 10, 2020
800eedf
refactored select channel method
SoCodeDo Oct 10, 2020
ec7e876
all tests passing with user input in terminal
SoCodeDo Oct 11, 2020
08db616
all tests passing without user input
SoCodeDo Oct 11, 2020
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
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/coverage/

.DS_Store
.idea/

# Ignore environemnt variables
.env
.byebug_history
coverage
9 changes: 9 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

# gem "rails"
gem 'dotenv'
gem 'httparty'
21 changes: 21 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
GEM
remote: https://rubygems.org/
specs:
dotenv (2.7.6)
httparty (0.18.1)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2020.0512)
multi_xml (0.6.0)

PLATFORMS
ruby

DEPENDENCIES
dotenv
httparty

BUNDLED WITH
1.17.2
28 changes: 28 additions & 0 deletions lib/channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'httparty'
require_relative 'recipient'

CHANNEL_URL = "https://slack.com/api/conversations.list"


class Channel < Recipient
attr_reader :topic, :member_count

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

def self.list_all
all_channels = self.get(CHANNEL_URL, PARAMS)["channels"]

all_channels.map do |channel_hash|
new(
channel_hash["id"],
channel_hash["name"],
channel_hash["topic"],
channel_hash["num_members"]
)
end
end
end
45 changes: 45 additions & 0 deletions lib/recipient.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
require 'dotenv'
require 'httparty'
Dotenv.load

# BASE_URL = 'https://slack.com/api/'

BOT_API_KEY = ENV['BOT_TOKEN']
PARAMS = {token: ENV['SLACK_TOKEN']}
Copy link

Choose a reason for hiding this comment

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

The PARAMS constant gets defined in recipient.rb, but never used here. Instead, it gets used in the child classes Channel and User only.

Putting the PARAMS constant here isn't bad, actually, it's quite common! And it takes advantage of inheritance! This is awesome, well done :D But I also want to highlight that it makes the code a little less readable-- as I read the other classes, I will think, "where does this constant get defined?!" and eventually (quickly) realize it's in Recipient. Again, I don't think you made the wrong decision, I think PARAMS has a good reason to live in recipient.rb, but in case you hadn't thought about it, it might be even better to repeat yourself and redefine PARAMS in both Channel and User if that makes sense to you.


class Recipient
attr_reader :slack_id, :name

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

def send_message(message)
response = HTTParty.post(
"https://slack.com/api/chat.postMessage",
body: {
token: BOT_API_KEY,
text: message,
channel: @slack_id
},
headers: { 'Content-Type' => 'application/x-www-form-urlencoded' }
)
return response.code == 200 && response.parsed_response["ok"]
end

def self.get(url, params)
response = HTTParty.get(url, query: params)
return response
end

private

def details
raise NotImplementedError, 'Implement me in a child class!'
end

def self.list_all
raise NotImplementedError, 'Implement me in a child class!'
end
Comment on lines +38 to +44
Copy link

Choose a reason for hiding this comment

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

Well done on making these template methods!!

end
47 changes: 46 additions & 1 deletion lib/slack.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,55 @@
#!/usr/bin/env ruby
require 'dotenv'
require 'httparty'

require_relative 'workspace'


def main
puts "Welcome to the Ada Slack CLI!"
workspace = Workspace.new

# TODO project
exit_program = false

until exit_program
puts
puts "Please select an option:"
puts "A. List Users"
puts "B. List Channels"
puts "C. Select User"
puts "D. Select Channel"
puts "E. Details"
puts "F. Send Message"
puts "G. Quit Program"
puts
user_input = gets.chomp.upcase
puts

case user_input
when "A", "LIST USERS"
workspace.users.each { |user| puts user.name }
when "B", "LIST CHANNELS"
workspace.channels.each { |channel| puts channel.name }
when "C", "SELECT USER"
puts "Please enter a Username or Slack ID:"
input = gets.chomp
workspace.select_user(input)
when "D", "SELECT CHANNEL"
puts "Please enter a Channel or Slack ID:"
input = gets.chomp
workspace.select_channel(input)
when "E", "DETAILS"
workspace.show_details
when "F", "SEND MESSAGE"
p "send a message to the current recipient"
workspace.send_message

when "G", "Q", "QUIT PROGRAM"
exit_program = true
else
puts "Incorrect value, please try again"
end
end

puts "Thank you for using the Ada Slack CLI"
end
Expand Down
26 changes: 26 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'httparty'
require_relative 'recipient'

USER_URL = "https://slack.com/api/users.list"


class User < Recipient
attr_reader :real_name

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

def self.list_all
all_members = self.get(USER_URL, PARAMS)["members"]

all_members.map do |user_hash|
Comment on lines +16 to +18
Copy link

Choose a reason for hiding this comment

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

Highlighting something that I wrote in the feedback table--

If self.get comes back with an unsuccessful response, then the ["members"] part at the end here will break the code.

It might be worth anticipating this failure and testing for it!

new(
user_hash["id"],
user_hash["name"],
user_hash["real_name"]
)
end
end
end
72 changes: 72 additions & 0 deletions lib/workspace.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
require_relative 'user'
require_relative 'channel'
require 'httparty'

class Workspace
attr_reader :channels, :users, :selected

def initialize(selected: nil)
@channels = Channel.list_all
@users = User.list_all
@selected
end

def select_channel(user_input)
user_input
Copy link

Choose a reason for hiding this comment

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

This line technically doesn't do anything! Feel free to delete it


if user_input
selected = @channels.find { |hash| hash.name == user_input }

if selected.nil?
selected = @channels.find {|hash| hash.slack_id == user_input }
end

results = selected.nil? ? "This is not a valid Channel" : selected.name
puts "Result: #{results} "
Comment on lines +24 to +25
Copy link

Choose a reason for hiding this comment

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

Following some other comments-- it might be interesting to move these lines back into slack.rb. You're returning selected anyway back to slack.rb, so you can do this print logic there too!

end

@selected = selected
return selected
end

def select_user(user_input)
user_input
Copy link

Choose a reason for hiding this comment

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

Similar to above-- this line of code doesn't do anything! Feel free to delete it


if user_input
selected = @users.find { |hash| hash.name == user_input }

if selected.nil?
selected = @users.find {|hash| hash.slack_id == user_input }
end

results = selected.nil? ? "This is not a valid User" : selected.name
puts "Result: #{results} "
end
Comment on lines +35 to +44
Copy link

Choose a reason for hiding this comment

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

Looking at this nested if selected.nil?... I feel like there's a chance for refactoring here to make these ifs slimmer and cooler. Honestly, I don't think this is necessary, and I haven't actually thought of a suggestion to refactor 😅 , but I thought it was fun that I'm inspired by your code to look at it more deeply. That's a sign of well-written code!


@selected = selected
return selected
end

def show_details
if @selected.is_a?(User)
pp [@selected.slack_id, @selected.name, @selected.real_name]
elsif @selected.is_a?(Channel)
pp [@selected.name, @selected.topic, @selected.member_count, @selected.slack_id]
end
end

def send_message
# store the user's message
# send message to the @selected recipient
if @selected.nil?
puts "Please select a user or channel."
else
puts "Enter your message here:"
message = gets.chomp
http_post_response = @selected.send_message(message)
p http_post_response
Copy link

Choose a reason for hiding this comment

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

You probably don't need this line for the project submission!

Comment on lines +66 to +67
Copy link

Choose a reason for hiding this comment

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

Here, you name the variable http_post_response. I agree that during @selected.send_message method, a POST request is sent at one point. However, what does @selected.send_message return? It doesn't return an http POST response! It returns true or false based on the current implementation

It might be good to reconsider the variable name here. I might put is_successful_message or is_successful

end

return !!http_post_response
Copy link

Choose a reason for hiding this comment

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

!! on a boolean is just the original boolean!

AKA

!true is false, and !!true is true
!false is true, and !!false is false

Comment on lines +58 to +70
Copy link

Choose a reason for hiding this comment

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

It might be worth considering moving this a lot of logic into slack.rb as a helper method.

I bring this up because this method has a lot of logic around getting input and printing feedback. In the Workspace class, imagine if the send_message method already assumed that the user selected something and wrote down a message.

Consider something like this:

def send_message(message)
  is_successful = @selected.send_message(message)
  return is_successful
end

end
end
Loading