From 7444d73574d86f717e7f2ca5c54002b68d41c734 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Tue, 19 Mar 2019 14:11:31 -0700 Subject: [PATCH 01/15] set up vcr, created spec and program files --- lib/channel.rb | 0 lib/recipient.rb | 0 lib/user.rb | 0 lib/verification.rb | 25 +++++++++++++++++++++++++ lib/workspace.rb | 0 specs/channel.rb | 0 specs/recipient_spec.rb | 0 specs/test_helper.rb | 23 ++++++++++++++++------- specs/user_spec.rb | 0 specs/workspace_spec.rb | 0 10 files changed, 41 insertions(+), 7 deletions(-) create mode 100644 lib/channel.rb create mode 100644 lib/recipient.rb create mode 100644 lib/user.rb create mode 100644 lib/verification.rb create mode 100644 lib/workspace.rb create mode 100644 specs/channel.rb create mode 100644 specs/recipient_spec.rb create mode 100644 specs/user_spec.rb create mode 100644 specs/workspace_spec.rb diff --git a/lib/channel.rb b/lib/channel.rb new file mode 100644 index 00000000..e69de29b diff --git a/lib/recipient.rb b/lib/recipient.rb new file mode 100644 index 00000000..e69de29b diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 00000000..e69de29b diff --git a/lib/verification.rb b/lib/verification.rb new file mode 100644 index 00000000..8bd976a9 --- /dev/null +++ b/lib/verification.rb @@ -0,0 +1,25 @@ +# Use the dotenv gem to load environment variables +# Use HTTParty to send a GET request to the channels.list endpoint +# Check that the request completed successfully, and print relevant information to the console if it didn't +# Loop through the results and print out the name of each channel + +require "dotenv" +require "HTTParty" +require "pry" + +Dotenv.load + +KEY = ENV["SLACK_TOKEN"] +url = "https://slack.com/api/channels.list" +query = { token: KEY } + +response = HTTParty.get(url, query: query) +binding.pry +if response.code != 200 + puts response.reason + puts response.code +else + response["channels"].each do |channel| + puts channel["name"] + end +end diff --git a/lib/workspace.rb b/lib/workspace.rb new file mode 100644 index 00000000..e69de29b diff --git a/specs/channel.rb b/specs/channel.rb new file mode 100644 index 00000000..e69de29b diff --git a/specs/recipient_spec.rb b/specs/recipient_spec.rb new file mode 100644 index 00000000..e69de29b diff --git a/specs/test_helper.rb b/specs/test_helper.rb index 81ccd06b..6d5702d9 100644 --- a/specs/test_helper.rb +++ b/specs/test_helper.rb @@ -1,15 +1,24 @@ -require 'simplecov' +require "simplecov" SimpleCov.start -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 "vcr" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new VCR.configure do |config| config.cassette_library_dir = "specs/cassettes" config.hook_into :webmock -end \ No newline at end of file + + 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 + } + + config.filter_sensitive_data("") do + ENV["SLACK_TOKEN"] + end +end diff --git a/specs/user_spec.rb b/specs/user_spec.rb new file mode 100644 index 00000000..e69de29b diff --git a/specs/workspace_spec.rb b/specs/workspace_spec.rb new file mode 100644 index 00000000..e69de29b From c037b1570ec71c10705090e16128a8df31fc930c Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Tue, 19 Mar 2019 15:30:54 -0700 Subject: [PATCH 02/15] created and tested self.get method in recipient --- lib/channel.rb | 22 ++++++++++++++++++++++ lib/recipient.rb | 32 ++++++++++++++++++++++++++++++++ lib/slack.rb | 2 +- lib/slackapierror.rb | 1 + specs/recipient_spec.rb | 40 ++++++++++++++++++++++++++++++++++++++++ specs/test_helper.rb | 6 ++++++ 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 lib/slackapierror.rb diff --git a/lib/channel.rb b/lib/channel.rb index e69de29b..754b3e19 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -0,0 +1,22 @@ +# require "dotenv" +# require "HTTParty" +# require "pry" + +# Dotenv.load + +# KEY = ENV["SLACK_TOKEN"] +# url = "https://slack.com/api/channels.list" +# query = { token: KEY } + +# def self.get(url, query) +# response = HTTParty.get(url, query: query) +# if response.code != 200 +# raise SlackApiError +# puts "Invalid request, error #{response.code}" +# puts +# puts response.code +# else +# response["channels"].each do |channel| +# puts channel["name"] +# end +# end diff --git a/lib/recipient.rb b/lib/recipient.rb index e69de29b..db33a7a8 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -0,0 +1,32 @@ +require "dotenv" +require "HTTParty" +require "pry" + +Dotenv.load +KEY = ENV["SLACK_TOKEN"] + +module Slack + class SlackApiError < StandardError; end + + class Recipient + def self.get(url, query:) + response = HTTParty.get(url, query: query) + if response["ok"] == false + raise SlackApiError.new("Invalid request, error #{response.code}: #{response.message}") + end + return response + end + end +end + +# query_params = { +# token: "abcdef", +# } + +# query_params2 = { +# token: KEY, +# } + +# response1 = Slack::Recipient.get(url: "https://slack.com/api/channels.list", query: query_params2) +# response2 = Slack::Recipient.get(url: "https://slack.com/api/channels.list", query: query_params) +# binding.pry diff --git a/lib/slack.rb b/lib/slack.rb index 960cf2f7..1ee5a205 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -8,4 +8,4 @@ def main puts "Thank you for using the Ada Slack CLI" end -main if __FILE__ == $PROGRAM_NAME \ No newline at end of file +main if __FILE__ == $PROGRAM_NAME diff --git a/lib/slackapierror.rb b/lib/slackapierror.rb new file mode 100644 index 00000000..dde4abe8 --- /dev/null +++ b/lib/slackapierror.rb @@ -0,0 +1 @@ +SlackApiError < StandardError diff --git a/specs/recipient_spec.rb b/specs/recipient_spec.rb index e69de29b..f0bdaf6d 100644 --- a/specs/recipient_spec.rb +++ b/specs/recipient_spec.rb @@ -0,0 +1,40 @@ +require_relative "test_helper" +# slack id is correctly extracted + +describe "Recipient" do + describe "self.get method" do + before do + @url = "https://slack.com/api/channels.list" + end + it "successfully returns a response" do + VCR.use_cassette("get_data") do + query_params = { + token: KEY, + } + response = Slack::Recipient.get(@url, query: query_params) + expect(response["ok"]).must_equal true + end + end + + it "will raise an exception if the search fails" do + VCR.use_cassette("more_data") do + query_params = { + token: "U R A TOKEN", + } + expect { + Slack::Recipient.get(@url, query: query_params) + }.must_raise Slack::SlackApiError + end + end + end +end + +# name is correct + +# request is successful + +# raise error if there is bad url + +# raise error if api token is not authenticated + +# error invoked if not called in subclass diff --git a/specs/test_helper.rb b/specs/test_helper.rb index 6d5702d9..c6f43979 100644 --- a/specs/test_helper.rb +++ b/specs/test_helper.rb @@ -7,6 +7,12 @@ require "minitest/skip_dsl" require "vcr" +require_relative "../lib/channel.rb" +require_relative "../lib/recipient.rb" +require_relative "../lib/slack.rb" +require_relative "../lib/user.rb" +require_relative "../lib/workspace.rb" + Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new VCR.configure do |config| From d11b5e16fb982a93b4b9bb7392bc7fea9406c6b0 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Tue, 19 Mar 2019 16:33:50 -0700 Subject: [PATCH 03/15] created self.list method and tests for channel --- lib/channel.rb | 52 +++++++++++++++++++++++++++---------------- lib/recipient.rb | 24 ++++++++++---------- specs/channel.rb | 0 specs/channel_spec.rb | 27 ++++++++++++++++++++++ 4 files changed, 72 insertions(+), 31 deletions(-) delete mode 100644 specs/channel.rb create mode 100644 specs/channel_spec.rb diff --git a/lib/channel.rb b/lib/channel.rb index 754b3e19..6947b694 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -1,22 +1,36 @@ -# require "dotenv" -# require "HTTParty" -# require "pry" +require "dotenv" +require "HTTParty" +require "pry" -# Dotenv.load +require_relative "recipient" -# KEY = ENV["SLACK_TOKEN"] -# url = "https://slack.com/api/channels.list" -# query = { token: KEY } +Dotenv.load -# def self.get(url, query) -# response = HTTParty.get(url, query: query) -# if response.code != 200 -# raise SlackApiError -# puts "Invalid request, error #{response.code}" -# puts -# puts response.code -# else -# response["channels"].each do |channel| -# puts channel["name"] -# end -# end +module Slack + class Channel < Recipient + CHANNEL_URL = "https://slack.com/api/channels.list" + @query = { token: KEY } + + attr_reader :slack_id, :name, :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 + response = self.get(CHANNEL_URL, query: @query) + # binding.pry + channels = response["channels"].map do |channel| + id = channel["id"] + name = channel["name"] + topic = channel["topic"]["value"] + member_count = channel["num_members"] + self.new(id, name, topic, member_count) + end + return channels + end + end +end diff --git a/lib/recipient.rb b/lib/recipient.rb index db33a7a8..1e96345d 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -9,24 +9,24 @@ module Slack class SlackApiError < StandardError; end class Recipient + attr_reader :slack_id, :name + + def initialize(slack_id, name) + @slack_id = slack_id + @name = name + end + def self.get(url, query:) response = HTTParty.get(url, query: query) if response["ok"] == false raise SlackApiError.new("Invalid request, error #{response.code}: #{response.message}") end + return response end + + def self.list + raise notImplementedError, "implement in child class" + end end end - -# query_params = { -# token: "abcdef", -# } - -# query_params2 = { -# token: KEY, -# } - -# response1 = Slack::Recipient.get(url: "https://slack.com/api/channels.list", query: query_params2) -# response2 = Slack::Recipient.get(url: "https://slack.com/api/channels.list", query: query_params) -# binding.pry diff --git a/specs/channel.rb b/specs/channel.rb deleted file mode 100644 index e69de29b..00000000 diff --git a/specs/channel_spec.rb b/specs/channel_spec.rb new file mode 100644 index 00000000..dff63c8f --- /dev/null +++ b/specs/channel_spec.rb @@ -0,0 +1,27 @@ +require_relative "test_helper" + +describe "Channel" do + describe "self.list" do + before do + VCR.use_cassette("make channels") do + query_params = { + token: KEY, + } + @channels = Slack::Channel.list + end + end + + it "will return an array of Channels" do + expect(@channels).must_be_kind_of Array + expect(@channels[0]).must_be_kind_of Slack::Channel + end + + it "will assign the correct attributes to each Channel" do + channel = @channels[0] + expect(channel.slack_id).must_equal "CH2V3FHEY" + expect(channel.name).must_equal "general" + expect(channel.topic).must_equal "Company-wide announcements and work-based matters" + expect(channel.member_count).must_equal 2 + end + end +end From 6d4c6adc60f0fdafdda0e67d879db6fe2227d216 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 14:44:50 -0700 Subject: [PATCH 04/15] Wrote Channel.details and subsequent tests --- lib/channel.rb | 15 ++++++++++++--- specs/channel_spec.rb | 45 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/lib/channel.rb b/lib/channel.rb index 6947b694..45a6e510 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -13,7 +13,7 @@ class Channel < Recipient attr_reader :slack_id, :name, :topic, :member_count - def initialize(slack_id, name, topic, member_count) + def initialize(slack_id:, name:, topic:, member_count:) @slack_id = slack_id @name = name @topic = topic @@ -22,15 +22,24 @@ def initialize(slack_id, name, topic, member_count) def self.list response = self.get(CHANNEL_URL, query: @query) - # binding.pry + # binding.pry channels = response["channels"].map do |channel| id = channel["id"] name = channel["name"] topic = channel["topic"]["value"] member_count = channel["num_members"] - self.new(id, name, topic, member_count) + self.new(slack_id: id, name: name, topic: topic, member_count: member_count) end return channels end + + def details + return { + slack_id: slack_id, + name: name, + topic: topic, + member_count: member_count, + } + end end end diff --git a/specs/channel_spec.rb b/specs/channel_spec.rb index dff63c8f..56b07a07 100644 --- a/specs/channel_spec.rb +++ b/specs/channel_spec.rb @@ -3,25 +3,56 @@ describe "Channel" do describe "self.list" do before do - VCR.use_cassette("make channels") do + VCR.use_cassette("make channels list") do query_params = { token: KEY, } @channels = Slack::Channel.list + @channel = @channels.first end end it "will return an array of Channels" do expect(@channels).must_be_kind_of Array - expect(@channels[0]).must_be_kind_of Slack::Channel + expect(@channel).must_be_kind_of Slack::Channel end it "will assign the correct attributes to each Channel" do - channel = @channels[0] - expect(channel.slack_id).must_equal "CH2V3FHEY" - expect(channel.name).must_equal "general" - expect(channel.topic).must_equal "Company-wide announcements and work-based matters" - expect(channel.member_count).must_equal 2 + expect(@channel.slack_id).must_equal "CH2V3FHEY" + expect(@channel.name).must_equal "general" + expect(@channel.topic).must_equal "Company-wide announcements and work-based matters" + expect(@channel.member_count).must_equal 2 + end + + it "has the correct data tyes for each attribute" do + expect(@channel.slack_id).must_be_kind_of String + expect(@channel.name).must_be_kind_of String + expect(@channel.topic).must_be_kind_of String + expect(@channel.member_count).must_be_kind_of Integer + end + end + + describe "details" do + before do + VCR.use_cassette("show channel details") do + query_params = { + token: KEY, + } + @channels = Slack::Channel.list + @channel = @channels.first + end + end + + it "returns the correct data" do + details = @channel.details + expected_details = { + slack_id: @channel.slack_id, + name: @channel.name, + topic: @channel.topic, + member_count: @channel.member_count, + } + + expect(details).must_equal expected_details end end end From 2ff0a71901e34d5e23e3c9adfcf045ca9445591c Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 14:45:25 -0700 Subject: [PATCH 05/15] added NotImplementedError to Recipient.list and Recipient#details and subsequent tests --- lib/recipient.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/recipient.rb b/lib/recipient.rb index 1e96345d..57717672 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -11,7 +11,7 @@ class SlackApiError < StandardError; end class Recipient attr_reader :slack_id, :name - def initialize(slack_id, name) + def initialize(slack_id:, name:) @slack_id = slack_id @name = name end @@ -25,8 +25,14 @@ def self.get(url, query:) return response end + # private + def self.list - raise notImplementedError, "implement in child class" + raise NotImplementedError, "implement in child class" + end + + def details + raise NotImplementedError, "implement in child class" end end end From d34a78e96f83a983a1197c3b04c4bbd6788727dc Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 14:45:57 -0700 Subject: [PATCH 06/15] Added tests for self.list and details --- specs/recipient_spec.rb | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/specs/recipient_spec.rb b/specs/recipient_spec.rb index f0bdaf6d..a24593aa 100644 --- a/specs/recipient_spec.rb +++ b/specs/recipient_spec.rb @@ -1,5 +1,4 @@ require_relative "test_helper" -# slack id is correctly extracted describe "Recipient" do describe "self.get method" do @@ -16,8 +15,8 @@ end end - it "will raise an exception if the search fails" do - VCR.use_cassette("more_data") do + it "will raise an exception with incorrect token" do + VCR.use_cassette("get_data") do query_params = { token: "U R A TOKEN", } @@ -26,6 +25,34 @@ }.must_raise Slack::SlackApiError end end + + it "will raise an exception with invalid url" do + VCR.use_cassette("get_data") do + query_params = { + token: KEY, + } + expect { + Slack::Recipient.get("abcdefg", query: query_params) + }.must_raise Addressable::URI::InvalidURIError + end + end + end + + describe "self.list" do + it "returns a notImplementedError" do + expect { + Slack::Recipient.list + }.must_raise NotImplementedError + end + end + + describe "details" do + it "returns a notImplementedError" do + recipient = Slack::Recipient.new(slack_id: 123, name: "hi") + expect { + recipient.details + }.must_raise NotImplementedError + end end end From fde2c26ef40e0d2afae772fc57689c59a0237816 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 14:46:22 -0700 Subject: [PATCH 07/15] Wrote class and subsequent tests --- lib/user.rb | 48 ++++++++++++++++++++++++++++++++++++ specs/user_spec.rb | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 109 insertions(+) diff --git a/lib/user.rb b/lib/user.rb index e69de29b..436a186f 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -0,0 +1,48 @@ +require "dotenv" +require "HTTParty" +require "pry" + +require_relative "recipient" + +Dotenv.load + +module Slack + class User < Recipient + USER_URL = "https://slack.com/api/users.list" + @query = { token: KEY } + + attr_reader :slack_id, :name, :real_name, :status_text, :status_emoji + + def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:) + @slack_id = slack_id + @name = name + @real_name = real_name + @status_text = status_text + @status_emoji = status_emoji + end + + def self.list + response = self.get(USER_URL, query: @query) + # binding.pry + users = response["members"].map do |user| + id = user["id"] + name = user["name"] + real_name = user["real_name"] + status_text = user["profile"]["status_text"] + status_emoji = user["profile"]["status_emoji"] + self.new(slack_id: id, name: name, real_name: real_name, status_text: status_text, status_emoji: status_emoji) + end + return users + end + + def details + return { + slack_id: slack_id, + name: name, + real_name: real_name, + status_text: status_text, + status_emoji: status_emoji, + } + end + end +end diff --git a/specs/user_spec.rb b/specs/user_spec.rb index e69de29b..ad3cd64c 100644 --- a/specs/user_spec.rb +++ b/specs/user_spec.rb @@ -0,0 +1,61 @@ +require_relative "test_helper" + +describe "User" do + describe "self.list" do + before do + VCR.use_cassette("make users list") do + query_params = { + token: KEY, + } + @users = Slack::User.list + @user = @users.first + end + end + + it "will return an array of Users" do + expect(@users).must_be_kind_of Array + expect(@user).must_be_kind_of Slack::User + end + + it "will assign the correct attributes to each user" do + expect(@user.slack_id).must_equal "USLACKBOT" + expect(@user.name).must_equal "slackbot" + expect(@user.real_name).must_equal "Slackbot" + expect(@user.status_text).must_equal "" + expect(@user.status_emoji).must_equal "" + end + + it "has the correct data tyes for each attribute" do + expect(@user.slack_id).must_be_kind_of String + expect(@user.name).must_be_kind_of String + expect(@user.real_name).must_be_kind_of String + expect(@user.status_text).must_be_kind_of String + expect(@user.status_emoji).must_be_kind_of String + end + end + + describe "details" do + before do + VCR.use_cassette("show user details") do + query_params = { + token: KEY, + } + @users = Slack::User.list + @user = @users.first + end + end + + it "returns the correct data" do + details = @user.details + expected_details = { + slack_id: @user.slack_id, + name: @user.name, + real_name: @user.real_name, + status_text: @user.status_text, + status_emoji: @user.status_emoji, + } + + expect(details).must_equal expected_details + end + end +end From 36fa1a5d0300f9929a83f708875be461ee6e6741 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 14:46:47 -0700 Subject: [PATCH 08/15] def class and module in file --- lib/workspace.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/workspace.rb b/lib/workspace.rb index e69de29b..0274b0c2 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -0,0 +1,4 @@ +module Slack + class Workspace + end +end From d2d8222d4c9fff2e63a13a6d6fa71650cca9d6fe Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 15:28:26 -0700 Subject: [PATCH 09/15] Wrote Workspace.new and Workspace#select_user methods and initialization test --- lib/workspace.rb | 35 +++++++++++++++++++++++++++++++++++ specs/workspace_spec.rb | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/lib/workspace.rb b/lib/workspace.rb index 0274b0c2..17e53c02 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -1,4 +1,39 @@ +require_relative "user" +require_relative "channel" + module Slack class Workspace + attr_reader :users, :channels + attr_accessor :selected + + def initialize + @users = Slack::User.list + @channels = Slack::Channel.list + @selected = nil + end + + def select_user(value) + @users.each do |user| + if user.name == value + @selected = user + return user + elsif user.id == value + @selected = user + return user + end + end + return nil + end + + def select_channel() + # out of list of channels, find the one that matches vlaue + # set the one that matches value to @selected + end + + def show_details + end + + def send_message + end end end diff --git a/specs/workspace_spec.rb b/specs/workspace_spec.rb index e69de29b..42330ca2 100644 --- a/specs/workspace_spec.rb +++ b/specs/workspace_spec.rb @@ -0,0 +1,39 @@ +require_relative "test_helper" + +describe "Workspace class" do + describe "initialize method" do + it "will return expected user info" do + VCR.use_cassette("initialize workspace") do + query_params = { + token: KEY, + } + workspace = Slack::Workspace.new + workspace_first_user = workspace.users[0] + first_loaded_user = Slack::User.list.first + + expect(workspace).must_be_kind_of Slack::Workspace + expect(workspace.users).must_be_kind_of Array + expect(workspace_first_user).must_be_kind_of Slack::User + expect(workspace.users.last).must_be_kind_of Slack::User + expect(workspace_first_user.slack_id).must_equal first_loaded_user.slack_id + end + end + + it "will return expected channel info" do + VCR.use_cassette("initialize workspace") do + query_params = { + token: KEY, + } + workspace = Slack::Workspace.new + workspace_first_channel = workspace.channels[0] + first_loaded_channel = Slack::Channel.list.first + + expect(workspace).must_be_kind_of Slack::Workspace + expect(workspace.channels).must_be_kind_of Array + expect(workspace_first_channel).must_be_kind_of Slack::Channel + expect(workspace.channels.last).must_be_kind_of Slack::Channel + expect(workspace_first_channel.slack_id).must_equal first_loaded_channel.slack_id + end + end + end +end From 12aae9945c37933c321ffc20336e0f8558e4f985 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 15:29:32 -0700 Subject: [PATCH 10/15] Slack#main is where Workspace gets instantiated --- lib/slack.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 1ee5a205..9470b9a9 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,9 +1,9 @@ #!/usr/bin/env ruby +require_relative "workspace" def main puts "Welcome to the Ada Slack CLI!" - - # TODO project + workspace = Slack::Workspace.new puts "Thank you for using the Ada Slack CLI" end From 606145b555edf48da633c0b63c6e0ab57a57ad50 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 15:55:30 -0700 Subject: [PATCH 11/15] Wrote Workspace#select_channel method and subsequent tests --- lib/workspace.rb | 16 +++++++--- specs/workspace_spec.rb | 68 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 4 deletions(-) diff --git a/lib/workspace.rb b/lib/workspace.rb index 17e53c02..f8c500b0 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -17,7 +17,7 @@ def select_user(value) if user.name == value @selected = user return user - elsif user.id == value + elsif user.slack_id == value @selected = user return user end @@ -25,9 +25,17 @@ def select_user(value) return nil end - def select_channel() - # out of list of channels, find the one that matches vlaue - # set the one that matches value to @selected + def select_channel(value) + @channels.each do |channel| + if channel.name == value + @selected = channel + return channel + elsif channel.slack_id == value + @selected = channel + return channel + end + end + return nil end def show_details diff --git a/specs/workspace_spec.rb b/specs/workspace_spec.rb index 42330ca2..90cd421e 100644 --- a/specs/workspace_spec.rb +++ b/specs/workspace_spec.rb @@ -36,4 +36,72 @@ end end end + + describe "select user method" do + before do + VCR.use_cassette("initialize workspace") do + query_params = { + token: KEY, + } + @workspace = Slack::Workspace.new + end + end + + it "will select a user based on user's name" do + name = "evelynnkaplan" + selected_user = @workspace.select_user(name) + + expect(selected_user).must_be_kind_of Slack::User + expect(selected_user.name).must_equal name + end + + it "will select a user based on user's id" do + id = "UH0J2E2D6" + selected_user = @workspace.select_user(id) + + expect(selected_user).must_be_kind_of Slack::User + expect(selected_user.slack_id).must_equal id + end + + it "returns nil if no user is found" do + id = "cat" + selected_user = @workspace.select_user(id) + + expect(selected_user).must_be_nil + end + end + + describe "select channel method" do + before do + VCR.use_cassette("initialize workspace") do + query_params = { + token: KEY, + } + @workspace = Slack::Workspace.new + end + end + + it "will select a channel based on channel's name" do + name = "random" + selected_channel = @workspace.select_channel(name) + + expect(selected_channel).must_be_kind_of Slack::Channel + expect(selected_channel.name).must_equal name + end + + it "will select a channel based on channel's id" do + id = "CH4DKF32S" + selected_channel = @workspace.select_channel(id) + + expect(selected_channel).must_be_kind_of Slack::Channel + expect(selected_channel.slack_id).must_equal id + end + + it "returns nil if no channel is found" do + id = "dog" + selected_channel = @workspace.select_channel(id) + + expect(selected_channel).must_be_nil + end + end end From 1404acaa3e518ac117828e2288f56a1a85b191d4 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Wed, 20 Mar 2019 15:55:51 -0700 Subject: [PATCH 12/15] Wrote notes --- lib/slack.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/slack.rb b/lib/slack.rb index 9470b9a9..89cf93a9 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -8,4 +8,6 @@ def main puts "Thank you for using the Ada Slack CLI" end +# Make sure all user input gets checked/converted for casing issues (.upcase for usernames, etc.) + main if __FILE__ == $PROGRAM_NAME From 272b7c1cca720312979c2672e750726f44bc2798 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Thu, 21 Mar 2019 14:29:25 -0700 Subject: [PATCH 13/15] built user interface --- lib/channel.rb | 7 +---- lib/slack.rb | 66 ++++++++++++++++++++++++++++++++++++++++- lib/user.rb | 8 +---- lib/workspace.rb | 1 + specs/channel_spec.rb | 10 +------ specs/user_spec.rb | 11 +------ specs/workspace_spec.rb | 20 +++++++++++++ 7 files changed, 90 insertions(+), 33 deletions(-) diff --git a/lib/channel.rb b/lib/channel.rb index 45a6e510..1ecb4f9d 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -34,12 +34,7 @@ def self.list end def details - return { - slack_id: slack_id, - name: name, - topic: topic, - member_count: member_count, - } + return "slack_id: #{slack_id}, name: #{name}, topic: #{topic}, member_count: #{member_count}" end end end diff --git a/lib/slack.rb b/lib/slack.rb index 89cf93a9..9f2f905e 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,9 +1,73 @@ #!/usr/bin/env ruby + +# implement details code +# make a method +# messages + require_relative "workspace" +require "table_print" def main - puts "Welcome to the Ada Slack CLI!" workspace = Slack::Workspace.new + puts "Welcome to the Ada Slack CLI! \n + There are #{workspace.channels.length} channels and #{workspace.users.length} users\n + What would you like to do?" + + commands = ["list users", "list channels", "quit", "select user", "select channel", "details"] + + puts "Here are your options:\n" + puts commands + + input = gets.chomp.downcase + + until input == "quit" + case input + when "list users" + tp workspace.users, :name, :slack_id, :real_name + puts "Great, what would you like to do next?" + input = gets.chomp.downcase + when "list channels" + tp workspace.channels, :name, :topic, :slack_id, :member_count + puts "Great, what would you like to do next?" + input = gets.chomp.downcase + when "select user" + puts "Please type in username or Slack ID" + user = gets.chomp + selected_user = workspace.select_user(user) + if selected_user + puts "You selected user #{selected_user.name}" + puts "What would you like to do next?" + puts commands + input = gets.chomp + else + puts "This user does not exist" + puts "What would you like to do next?" + puts commands + input = gets.chomp + end + when "select channel" + puts "Please type in channel name or Slack ID" + channel = gets.chomp + selected_channel = workspace.select_channel(channel) + if selected_channel + puts "You selected the channel called \'#{selected_channel.name}\'" + puts "What would you like to do next?" + puts commands + input = gets.chomp + else + puts "This channel does not exist" + puts "What would you like to do next?" + puts commands + input = gets.chomp + end + when "details" + break + else + puts "Command not valid. Please type one of the following" + puts commands + input = gets.chomp + end + end puts "Thank you for using the Ada Slack CLI" end diff --git a/lib/user.rb b/lib/user.rb index 436a186f..c8bd802d 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -36,13 +36,7 @@ def self.list end def details - return { - slack_id: slack_id, - name: name, - real_name: real_name, - status_text: status_text, - status_emoji: status_emoji, - } + return "slack_id: #{slack_id}, name: #{name}, real_name: #{real_name}, status_text: #{status_text}, status_emoji: #{status_emoji}" end end end diff --git a/lib/workspace.rb b/lib/workspace.rb index f8c500b0..b8e73605 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -39,6 +39,7 @@ def select_channel(value) end def show_details + return selected.details if selected end def send_message diff --git a/specs/channel_spec.rb b/specs/channel_spec.rb index 56b07a07..92b565c2 100644 --- a/specs/channel_spec.rb +++ b/specs/channel_spec.rb @@ -44,15 +44,7 @@ end it "returns the correct data" do - details = @channel.details - expected_details = { - slack_id: @channel.slack_id, - name: @channel.name, - topic: @channel.topic, - member_count: @channel.member_count, - } - - expect(details).must_equal expected_details + expect(@channel.details).must_be_kind_of String end end end diff --git a/specs/user_spec.rb b/specs/user_spec.rb index ad3cd64c..33fff53e 100644 --- a/specs/user_spec.rb +++ b/specs/user_spec.rb @@ -46,16 +46,7 @@ end it "returns the correct data" do - details = @user.details - expected_details = { - slack_id: @user.slack_id, - name: @user.name, - real_name: @user.real_name, - status_text: @user.status_text, - status_emoji: @user.status_emoji, - } - - expect(details).must_equal expected_details + expect(@user.details).must_be_kind_of String end end end diff --git a/specs/workspace_spec.rb b/specs/workspace_spec.rb index 90cd421e..94798e3b 100644 --- a/specs/workspace_spec.rb +++ b/specs/workspace_spec.rb @@ -104,4 +104,24 @@ expect(selected_channel).must_be_nil end end + + describe "show details" do + before do + VCR.use_cassette("test details") do + query_params = { + token: KEY, + } + @workspace = Slack::Workspace.new + end + end + + it "details for selected recipient is string" do + @workspace.select_user("evelynnkaplan") + expect(@workspace.show_details).must_be_kind_of String + end + + it "returns nil if no recipient" do + expect(@workspace.show_details).must_be_nil + end + end end From 7c9a866f6c9c475d07fade5396931ac732c1defe Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Fri, 22 Mar 2019 11:25:00 -0700 Subject: [PATCH 14/15] Wrote Workspace#send_message and Recipient#send_message and subsequent tests --- .vscode/launch.json | 15 ++++++++++++ lib/recipient.rb | 16 +++++++++++++ lib/slack.rb | 14 +++++++++-- lib/workspace.rb | 7 +++++- specs/recipient_spec.rb | 30 ++++++++++++++++-------- specs/workspace_spec.rb | 51 +++++++++++++++++++++++++++++++++++++++++ 6 files changed, 121 insertions(+), 12 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..10f2f390 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Local File", + "type": "Ruby", + "request": "launch", + "cwd": "${workspaceRoot}", + "program": "${file}" + } + ] +} \ No newline at end of file diff --git a/lib/recipient.rb b/lib/recipient.rb index 57717672..74506519 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -4,6 +4,7 @@ Dotenv.load KEY = ENV["SLACK_TOKEN"] +MESSAGE_URL = "https://slack.com/api/chat.postMessage" module Slack class SlackApiError < StandardError; end @@ -25,6 +26,21 @@ def self.get(url, query:) return response end + def send_message(message) + body = { + token: KEY, + channel: slack_id, + text: message, + } + response = HTTParty.post(MESSAGE_URL, body: body) + + if response["ok"] == false + raise SlackApiError.new("Invalid request, error #{response.code}: #{response.message}") + end + + return response + end + # private def self.list diff --git a/lib/slack.rb b/lib/slack.rb index 9f2f905e..73a3939d 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -13,7 +13,7 @@ def main There are #{workspace.channels.length} channels and #{workspace.users.length} users\n What would you like to do?" - commands = ["list users", "list channels", "quit", "select user", "select channel", "details"] + commands = ["list users", "list channels", "select user", "select channel", "details", "quit"] puts "Here are your options:\n" puts commands @@ -61,7 +61,17 @@ def main input = gets.chomp end when "details" - break + if workspace.show_details == nil + puts "No user or channel is selected" + puts "What would you like to do next?" + puts commands + input = gets.chomp + else + puts workspace.show_details + puts "What would you like to do next?" + puts commands + input = gets.chomp + end else puts "Command not valid. Please type one of the following" puts commands diff --git a/lib/workspace.rb b/lib/workspace.rb index b8e73605..660bf0c1 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -42,7 +42,12 @@ def show_details return selected.details if selected end - def send_message + def send_message(message) + if selected + selected.send_message(message) + else + return nil + end end end end diff --git a/specs/recipient_spec.rb b/specs/recipient_spec.rb index a24593aa..cfb19cfe 100644 --- a/specs/recipient_spec.rb +++ b/specs/recipient_spec.rb @@ -54,14 +54,26 @@ }.must_raise NotImplementedError end end -end - -# name is correct - -# request is successful - -# raise error if there is bad url -# raise error if api token is not authenticated + describe "send_message" do + before do + VCR.use_cassette("send_message") do + query_params = { + token: KEY, + } + url = "https://slack.com/api/channels.list" + response = Slack::Recipient.get(url, query: query_params) + slack_id = response["channels"].first["id"] + name = response["channels"].first["name"] + @recipient = Slack::Recipient.new(slack_id: slack_id, name: name) + end + end -# error invoked if not called in subclass + it "successfully sends a message" do + VCR.use_cassette("send_message") do + message = @recipient.send_message("HELLO WORLD!") + expect(message["ok"]).must_equal true + end + end + end +end diff --git a/specs/workspace_spec.rb b/specs/workspace_spec.rb index 94798e3b..676cb8d9 100644 --- a/specs/workspace_spec.rb +++ b/specs/workspace_spec.rb @@ -124,4 +124,55 @@ expect(@workspace.show_details).must_be_nil end end + + describe "send_message" do + before do + VCR.use_cassette("workspace send message") do + query_params = { + token: KEY, + } + @workspace = Slack::Workspace.new + end + end + + it "successfully sends a message to a user" do + VCR.use_cassette("workspace send message") do + selected_user = @workspace.select_user("evelynnkaplan") + response = @workspace.send_message("sup dog") + + expect(response["ok"]).must_equal true + end + end + + it "doesn't send a message to a user that doesn't exist" do + VCR.use_cassette("workspace send message") do + selected_user = @workspace.select_user("ricksteves") + response = @workspace.send_message("sup dog") + + expect(response).must_be_nil + end + end + + it "successfully sends a message to a channel" do + VCR.use_cassette("workspace send message") do + selected_channel = @workspace.select_channel("random") + response = @workspace.send_message("sup dog") + + expect(response["ok"]).must_equal true + end + end + + it "doesn't send a message to a channel that doesn't exist" do + VCR.use_cassette("workspace send message") do + selected_channel = @workspace.select_channel("Rick Steves' channel") + response = @workspace.send_message("sup dog") + + expect(response).must_be_nil + end + end + + it "returns nil if there's no selected user or channel" do + expect(@workspace.send_message("sup dog")).must_be_nil + end + end end From d4d644346b616272502299d95d0104736473c5a7 Mon Sep 17 00:00:00 2001 From: Shirley Chu Date: Fri, 22 Mar 2019 14:29:31 -0700 Subject: [PATCH 15/15] cleaned up command line loop --- lib/slack.rb | 54 +++++++++++++++----------------------------- lib/user.rb | 1 - specs/test_helper.rb | 4 ++-- 3 files changed, 20 insertions(+), 39 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 73a3939d..85defc95 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,49 +1,35 @@ #!/usr/bin/env ruby -# implement details code -# make a method -# messages - require_relative "workspace" require "table_print" def main workspace = Slack::Workspace.new puts "Welcome to the Ada Slack CLI! \n - There are #{workspace.channels.length} channels and #{workspace.users.length} users\n - What would you like to do?" - - commands = ["list users", "list channels", "select user", "select channel", "details", "quit"] + There are #{workspace.channels.length} channels and #{workspace.users.length} users\n" - puts "Here are your options:\n" - puts commands + commands = ["list users", "list channels", "select user", "select channel", "details", "send message", "quit"] - input = gets.chomp.downcase + while true + puts "\nWhat would you like to do?" + puts + puts commands + puts + input = gets.chomp.downcase - until input == "quit" case input when "list users" tp workspace.users, :name, :slack_id, :real_name - puts "Great, what would you like to do next?" - input = gets.chomp.downcase when "list channels" tp workspace.channels, :name, :topic, :slack_id, :member_count - puts "Great, what would you like to do next?" - input = gets.chomp.downcase when "select user" puts "Please type in username or Slack ID" user = gets.chomp selected_user = workspace.select_user(user) if selected_user puts "You selected user #{selected_user.name}" - puts "What would you like to do next?" - puts commands - input = gets.chomp else puts "This user does not exist" - puts "What would you like to do next?" - puts commands - input = gets.chomp end when "select channel" puts "Please type in channel name or Slack ID" @@ -51,31 +37,27 @@ def main selected_channel = workspace.select_channel(channel) if selected_channel puts "You selected the channel called \'#{selected_channel.name}\'" - puts "What would you like to do next?" - puts commands - input = gets.chomp else puts "This channel does not exist" - puts "What would you like to do next?" - puts commands - input = gets.chomp end when "details" if workspace.show_details == nil puts "No user or channel is selected" - puts "What would you like to do next?" - puts commands - input = gets.chomp else puts workspace.show_details - puts "What would you like to do next?" - puts commands - input = gets.chomp end + when "send message" + if workspace.selected == nil + puts "No user or channel selected. Try again" + else + puts "Write your message here" + message = gets.chomp + workspace.send_message(message) + end + when "quit" + break else puts "Command not valid. Please type one of the following" - puts commands - input = gets.chomp end end diff --git a/lib/user.rb b/lib/user.rb index c8bd802d..1e402551 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -23,7 +23,6 @@ def initialize(slack_id:, name:, real_name:, status_text:, status_emoji:) def self.list response = self.get(USER_URL, query: @query) - # binding.pry users = response["members"].map do |user| id = user["id"] name = user["name"] diff --git a/specs/test_helper.rb b/specs/test_helper.rb index c6f43979..77e78fc8 100644 --- a/specs/test_helper.rb +++ b/specs/test_helper.rb @@ -20,8 +20,8 @@ config.hook_into :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 + :record => :new_episodes, + :match_requests_on => [:method, :uri, :body], } config.filter_sensitive_data("") do