From cae97730dc26c47e417fb7f75111645f260678ca Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 14:42:56 -0700 Subject: [PATCH 01/16] add Workspace class, add user_list & channel_list method in slack.rb --- lib/slack.rb | 32 ++++++++++++++++++++++++++++++++ lib/workspace.rb | 9 +++++++++ 2 files changed, 41 insertions(+) create mode 100644 lib/workspace.rb diff --git a/lib/slack.rb b/lib/slack.rb index 8a0b659b..255da281 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,10 +1,42 @@ #!/usr/bin/env ruby +require 'httparty' +require_relative 'workspace' +require 'dotenv' + +Dotenv.load +SLACK_TOKEN = ENV['SLACK_TOKEN'] + +def user_list + url = "https://slack.com/api/users.list" + puts HTTParty.get(url, token: SLACK_TOKEN) +end + +def channel_list + url = "https://slack.com/api/conversations.list" + puts HTTParty.get(url, token: SLACK_TOKEN) +end def main puts "Welcome to the Ada Slack CLI!" workspace = Workspace.new # TODO project + puts "What would you like to do with CLI? 1. list users, 2. list channels, 3. quit" + input = gets.chomp + + loop do + if input == "list users" || input == "1" + return user_list + elsif input == "list channels" || input == "2" + return channel_list + elsif input == "quit" || input == "3" + break + else + puts "Please choose one of the options." + end + input = gets.chomp + end + puts "Thank you for using the Ada Slack CLI" end diff --git a/lib/workspace.rb b/lib/workspace.rb new file mode 100644 index 00000000..7215771d --- /dev/null +++ b/lib/workspace.rb @@ -0,0 +1,9 @@ +class Workspace + attr_reader :users, :channels + + def initialize(users: [], channels: []) + @users = users + @channels = channels + end + +end \ No newline at end of file From 0c8ba33eb0f99943b0d3f4180b19cee95e200372 Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 15:03:09 -0700 Subject: [PATCH 02/16] complete print user list and channel list --- lib/slack.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 255da281..7005ec65 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -8,12 +8,12 @@ def user_list url = "https://slack.com/api/users.list" - puts HTTParty.get(url, token: SLACK_TOKEN) + return HTTParty.get(url, query: {token: SLACK_TOKEN}) end def channel_list url = "https://slack.com/api/conversations.list" - puts HTTParty.get(url, token: SLACK_TOKEN) + return HTTParty.get(url, query: {token: SLACK_TOKEN}) end def main @@ -26,9 +26,9 @@ def main loop do if input == "list users" || input == "1" - return user_list + puts user_list elsif input == "list channels" || input == "2" - return channel_list + puts channel_list elsif input == "quit" || input == "3" break else From efd0d88500dcce44561ad6efce1c0941af2a75bd Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 15:40:23 -0700 Subject: [PATCH 03/16] complete wave1: list users & channels --- lib/slack.rb | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 7005ec65..9cd26c65 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -2,39 +2,53 @@ require 'httparty' require_relative 'workspace' require 'dotenv' +require 'table_print' Dotenv.load SLACK_TOKEN = ENV['SLACK_TOKEN'] def user_list url = "https://slack.com/api/users.list" - return HTTParty.get(url, query: {token: SLACK_TOKEN}) + response = HTTParty.get(url, query: {token: SLACK_TOKEN}) + users = [] + response["members"].each do |member| + users << {name: member["name"], real_name: member["real_name"], id: member["id"]} + end + + return users end def channel_list url = "https://slack.com/api/conversations.list" - return HTTParty.get(url, query: {token: SLACK_TOKEN}) + response = HTTParty.get(url, query: {token: SLACK_TOKEN}) + channels = [] + response["channels"].each do |channel| + channels << {channel_name: channel["name"], topic: channel["topic"]["value"], member_count: channel["num_members"], slack_ID: channel["id"]} + end + return channels end def main puts "Welcome to the Ada Slack CLI!" workspace = Workspace.new - # TODO project - puts "What would you like to do with CLI? 1. list users, 2. list channels, 3. quit" - input = gets.chomp + loop do + puts "What would you like to do with CLI? \n1. list users \n2. list channels \n3. quit" + input = gets.chomp + if input == "list users" || input == "1" - puts user_list + tp user_list + puts "\n\n" elsif input == "list channels" || input == "2" - puts channel_list + tp channel_list + puts "\n\n" elsif input == "quit" || input == "3" break else puts "Please choose one of the options." end - input = gets.chomp end From a530980dffc6820437e2b2f9ff3f0bed12a545e9 Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 15:59:30 -0700 Subject: [PATCH 04/16] add tests for Workspace --- .gitignore | 1 + lib/slack.rb | 2 -- test/test_helper.rb | 5 ++++- test/workspace_test.rb | 20 ++++++++++++++++++++ 4 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 test/workspace_test.rb diff --git a/.gitignore b/.gitignore index 3ff4fada..5504b740 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ # Ignore environemnt variables .env +lib/.env diff --git a/lib/slack.rb b/lib/slack.rb index 9cd26c65..d01a0a38 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -32,8 +32,6 @@ def main puts "Welcome to the Ada Slack CLI!" workspace = Workspace.new - - loop do puts "What would you like to do with CLI? \n1. list users \n2. list channels \n3. quit" input = gets.chomp diff --git a/test/test_helper.rb b/test/test_helper.rb index 1fcf2bab..db481c12 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -8,6 +8,7 @@ require 'minitest/reporters' require 'minitest/skip_dsl' require 'vcr' +require_relative '../lib/workspace' Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new @@ -23,7 +24,9 @@ :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 # Don't leave our token lying around in a cassette file. end diff --git a/test/workspace_test.rb b/test/workspace_test.rb new file mode 100644 index 00000000..1821e580 --- /dev/null +++ b/test/workspace_test.rb @@ -0,0 +1,20 @@ +require_relative 'test_helper' + +describe "Initializer" do + it "is an instance of Workspace" do + expect(Workspace.new).must_be_kind_of Workspace + end + + it "uses must be an empty array" do + workspace1 = Workspace.new + expect(workspace1.users).must_be_kind_of Array + expect(workspace1.users).must_be_empty + end + + it "channels must be an empty array" do + workspace1 = Workspace.new + expect(workspace1.channels).must_be_kind_of Array + expect(workspace1.channels).must_be_empty + end + +end From 12d17ce395c18a6b8d8ddeb22e669afc97aa0890 Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 16:49:35 -0700 Subject: [PATCH 05/16] add test for User class. pass all the tests --- test/channel_test.rb | 0 test/test_helper.rb | 2 ++ test/user_test.rb | 24 ++++++++++++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 test/channel_test.rb create mode 100644 test/user_test.rb diff --git a/test/channel_test.rb b/test/channel_test.rb new file mode 100644 index 00000000..e69de29b diff --git a/test/test_helper.rb b/test/test_helper.rb index db481c12..78c33acc 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -9,6 +9,8 @@ require 'minitest/skip_dsl' require 'vcr' require_relative '../lib/workspace' +require_relative '../lib/user' +require_relative '../lib/channel' Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new diff --git a/test/user_test.rb b/test/user_test.rb new file mode 100644 index 00000000..bed824ab --- /dev/null +++ b/test/user_test.rb @@ -0,0 +1,24 @@ +require_relative 'test_helper' + +describe "Initializer" do + before do + @user1 = User.new(123, "Totoro", "Ghibli") + end + + it "is an instance of User" do + expect(@user1).must_be_kind_of User + end + + it "username must be a string" do + expect(@user1.user_name).must_be_kind_of String + end + + it "real name must be a string" do + expect(@user1.real_name).must_be_kind_of String + end + + it "Slack ID must be a integer" do + expect(@user1.slack_id).must_be_kind_of Integer + end + +end \ No newline at end of file From cfbfe8aa15f56ecc3bf20428ca9122934f92de99 Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 16:57:33 -0700 Subject: [PATCH 06/16] add test for Channel class. pass all the tests --- test/channel_test.rb | 28 ++++++++++++++++++++++++++++ test/user_test.rb | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/test/channel_test.rb b/test/channel_test.rb index e69de29b..11b04cfb 100644 --- a/test/channel_test.rb +++ b/test/channel_test.rb @@ -0,0 +1,28 @@ +require_relative 'test_helper' + +describe "Initializer" do + before do + @channel1 = Channel.new(123, "snacks", "ice cream", 5) + end + + it "is an instance of User" do + expect(@channel1).must_be_kind_of Channel + end + + it "username must be a string" do + expect(@channel1.name).must_be_kind_of String + end + + it "real name must be a string" do + expect(@channel1.topic).must_be_kind_of String + end + + it "Slack ID must be a integer" do + expect(@channel1.slack_id).must_be_kind_of Integer + end + + it "member count must be a integer" do + expect(@channel1.member_count).must_be_kind_of Integer + end + +end \ No newline at end of file diff --git a/test/user_test.rb b/test/user_test.rb index bed824ab..2a2b29aa 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -10,7 +10,7 @@ end it "username must be a string" do - expect(@user1.user_name).must_be_kind_of String + expect(@user1.name).must_be_kind_of String end it "real name must be a string" do From 3680318854981715bdaa60a17b7d4ba2451cd2f2 Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 17:42:07 -0700 Subject: [PATCH 07/16] add test for list_all for User and Channel --- lib/channel.rb | 23 +++++++++++++++++++++++ lib/recipient.rb | 25 +++++++++++++++++++++++++ lib/user.rb | 22 ++++++++++++++++++++++ test/channel_test.rb | 16 ++++++++++++++++ test/user_test.rb | 16 ++++++++++++++++ 5 files changed, 102 insertions(+) create mode 100644 lib/channel.rb create mode 100644 lib/recipient.rb create mode 100644 lib/user.rb diff --git a/lib/channel.rb b/lib/channel.rb new file mode 100644 index 00000000..e94f6501 --- /dev/null +++ b/lib/channel.rb @@ -0,0 +1,23 @@ +require_relative 'recipient' + +class Channel < Recipient + attr_reader :name, :topic, :member_count, :slack_id + + def initialize(slack_id, name, topic, member_count) + super(slack_id, name) + @topic = topic + @member_count = member_count + end + + def self.list_all + response = self.get("https://slack.com/api/conversations.list") + channels = [] + response["channels"].each do |channel| + channels << Channel.new(channel["id"], channel["name"], channel["topic"]["value"], channel["num_members"]) + end + return channels + end + +end + +Channel.list_all.each {|channel| puts channel.name} \ No newline at end of file diff --git a/lib/recipient.rb b/lib/recipient.rb new file mode 100644 index 00000000..852ec5b0 --- /dev/null +++ b/lib/recipient.rb @@ -0,0 +1,25 @@ +require 'httparty' +require_relative 'workspace' +require 'dotenv' +require 'table_print' + +class Recipient + Dotenv.load ##inside or outside? + BASE_URL = "https://slack.com/api/" + SLACK_TOKEN = ENV['SLACK_TOKEN'] + + attr_reader :slack_id, :name + + def initialize(slack_id, name)#should we get rid of name???? + @slack_id = slack_id + @name = name + end + + def self.get(url) + return HTTParty.get(url, query: {token: SLACK_TOKEN}) + end + + def self.list_all + raise NotImplementedError, 'Implement me in a child class!' + end +end \ No newline at end of file diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 00000000..697a7e78 --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,22 @@ +require_relative 'recipient' + +class User < Recipient + attr_reader :name, :real_name, :slack_id + + def initialize(slack_id, name, real_name) + super(slack_id, name) #super(name)????? + @real_name = real_name + end + + def self.list_all + response = self.get("https://slack.com/api/users.list") + users = [] + response["members"].each do |member| + users << User.new(member["id"], member["name"], member["real_name"]) + end + return users + end +end + +#??????????? + User.list_all.each { |user| puts user.name } \ No newline at end of file diff --git a/test/channel_test.rb b/test/channel_test.rb index 11b04cfb..247716f2 100644 --- a/test/channel_test.rb +++ b/test/channel_test.rb @@ -25,4 +25,20 @@ expect(@channel1.member_count).must_be_kind_of Integer end +end + +describe "list_all" do + + it "should return all the channels" do + expect(Channel.list_all.length).must_be 3 + end + + it "return the correct info for the first" do + expect(Channel.list_all.first.name).must_be "random" + end + + it "return the correct info for the last" do + expect(Channel.list_all.last.name).must_be "slack-cli" + end + end \ No newline at end of file diff --git a/test/user_test.rb b/test/user_test.rb index 2a2b29aa..9a6448d1 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -21,4 +21,20 @@ expect(@user1.slack_id).must_be_kind_of Integer end +end + +describe "list_all" do + + it "should return all the users" do + expect(User.list_all.length).must_be 5 + end + + it "return the correct info for the first" do + expect(User.list_all.first.name).must_be "slackbot" + end + + it "return the correct info for the last" do + expect(User.list_all.last.name).must_be "api_project" + end + end \ No newline at end of file From 31009c81d24373d469f96c0e781426846e72d58e Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Tue, 6 Oct 2020 22:02:31 -0700 Subject: [PATCH 08/16] add VCR to tests --- test/cassettes/list_all_channels.yml | 74 ++++++++++++++++++++++++++++ test/cassettes/list_all_users.yml | 74 ++++++++++++++++++++++++++++ test/channel_test.rb | 17 +++++-- test/user_test.rb | 15 ++++-- 4 files changed, 174 insertions(+), 6 deletions(-) create mode 100644 test/cassettes/list_all_channels.yml create mode 100644 test/cassettes/list_all_users.yml diff --git a/test/cassettes/list_all_channels.yml b/test/cassettes/list_all_channels.yml new file mode 100644 index 00000000..86f4eb0a --- /dev/null +++ b/test/cassettes/list_all_channels.yml @@ -0,0 +1,74 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/conversations.list?token= + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 07 Oct 2020 04:57:19 GMT + Server: + - Apache + X-Slack-Req-Id: + - 1b9deaa802fb250110cc11e18f4a5f89 + X-Oauth-Scopes: + - incoming-webhook,channels:read,groups:read,im:read,mpim:read,users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '693' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-ce55,haproxy-edge-pdx-rf66 + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01C16GNVMZ","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601965941,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C10DATH8","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01C16GNGG3"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":false,"is_private":false,"is_mpim":false,"topic":{"value":"cs + memes are great!","creator":"U01C10G57NE","last_set":1602023254},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C10DATH8","last_set":1601965941},"previous_names":[],"num_members":2},{"id":"C01C761G84U","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601965941,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C10DATH8","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01C16GNGG3"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":false,"is_private":false,"is_mpim":false,"topic":{"value":"We + finish wave 1!!","creator":"U01C10DATH8","last_set":1602023247},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C10DATH8","last_set":1601965941},"previous_names":[],"num_members":2},{"id":"C01CQR91448","name":"slack-cli","is_channel":true,"is_group":false,"is_im":false,"created":1601966059,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"slack-cli","is_shared":false,"parent_conversation":null,"creator":"U01C10DATH8","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01C16GNGG3"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":false,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C10DATH8","last_set":1601966059},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + recorded_at: Wed, 07 Oct 2020 04:57:19 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/list_all_users.yml b/test/cassettes/list_all_users.yml new file mode 100644 index 00000000..ab11066d --- /dev/null +++ b/test/cassettes/list_all_users.yml @@ -0,0 +1,74 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?token= + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 07 Oct 2020 05:02:00 GMT + Server: + - Apache + X-Slack-Req-Id: + - 7cc614de3e4cc73c50fd7015891bd79b + X-Oauth-Scopes: + - incoming-webhook,channels:read,groups:read,im:read,mpim:read,users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '1289' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-ngke,haproxy-edge-pdx-rshi + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"T01C16GNGG3","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Slackbot","real_name_normalized":"Slackbot","display_name":"Slackbot","display_name_normalized":"Slackbot","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"sv41d8cd98f0","always_active":true,"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_32.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/80588\/marketing\/img\/avatars\/slackbot\/avatar-slackbot.png","image_512":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":0},{"id":"U01BVT790NA","team_id":"T01C16GNGG3","name":"api_project2","deleted":false,"color":"3c989f","real_name":"API + project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"API + project","real_name_normalized":"API project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g3cef7409b5d","api_app_id":"A01C2R7G4SF","always_active":false,"bot_id":"B01C2RDCQUB","image_24":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1602006272},{"id":"U01C10DATH8","team_id":"T01C16GNGG3","name":"yjlin789","deleted":false,"color":"9f69e7","real_name":"Jing","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Jing","real_name_normalized":"Jing","display_name":"Jing","display_name_normalized":"Jing","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"1581dfb66e14","image_original":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_original.jpg","is_custom_image":true,"first_name":"Jing","last_name":"","image_24":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_72.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_192.jpg","image_512":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_512.jpg","image_1024":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_1024.jpg","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601966120},{"id":"U01C10G57NE","team_id":"T01C16GNGG3","name":"rencarothers","deleted":false,"color":"4bbe2e","real_name":"Ren + Carothers","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Ren + Carothers","real_name_normalized":"Ren Carothers","display_name":"Ren Carothers","display_name_normalized":"Ren + Carothers","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g53fff90c824","image_24":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1602018318},{"id":"U01C8PNLVS8","team_id":"T01C16GNGG3","name":"api_project","deleted":true,"profile":{"title":"","phone":"","skype":"","real_name":"API + project","real_name_normalized":"API project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g12a061ce8c3","api_app_id":"A01BMQV0Z7H","always_active":false,"bot_id":"B01BMSK9J79","image_24":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_bot":true,"is_app_user":false,"updated":1602021025}],"cache_ts":1602046920,"response_metadata":{"next_cursor":""}}' + recorded_at: Wed, 07 Oct 2020 05:02:00 GMT +recorded_with: VCR 6.0.0 diff --git a/test/channel_test.rb b/test/channel_test.rb index 247716f2..9170cacb 100644 --- a/test/channel_test.rb +++ b/test/channel_test.rb @@ -30,15 +30,26 @@ describe "list_all" do it "should return all the channels" do - expect(Channel.list_all.length).must_be 3 + VCR.use_cassette("list_all_channels") do + response = Channel.list_all + + expect(response.length).must_equal 3 + end + end it "return the correct info for the first" do - expect(Channel.list_all.first.name).must_be "random" + VCR.use_cassette("list_all_channels") do + response = Channel.list_all + expect(response.first.name).must_equal "random" + end end it "return the correct info for the last" do - expect(Channel.list_all.last.name).must_be "slack-cli" + VCR.use_cassette("list_all_channels") do + response = Channel.list_all + expect(response.last.name).must_equal "slack-cli" + end end end \ No newline at end of file diff --git a/test/user_test.rb b/test/user_test.rb index 9a6448d1..f3834bdd 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -26,15 +26,24 @@ describe "list_all" do it "should return all the users" do - expect(User.list_all.length).must_be 5 + VCR.use_cassette("list_all_users") do + response = User.list_all + expect(response.length).must_equal 5 + end end it "return the correct info for the first" do - expect(User.list_all.first.name).must_be "slackbot" + VCR.use_cassette("list_all_users") do + response = User.list_all + expect(response.first.name).must_equal "slackbot" + end end it "return the correct info for the last" do - expect(User.list_all.last.name).must_be "api_project" + VCR.use_cassette("list_all_users") do + response = User.list_all + expect(response.last.name).must_equal "api_project" + end end end \ No newline at end of file From 84a2b1b8e67dfbd05884e2f7d933d762c49135dd Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Wed, 7 Oct 2020 11:26:47 -0700 Subject: [PATCH 09/16] start Workspace, did not pass tests --- lib/channel.rb | 6 +++--- lib/recipient.rb | 4 ++++ lib/slack.rb | 23 ----------------------- lib/user.rb | 5 +++-- lib/workspace.rb | 19 +++++++++++++++---- 5 files changed, 25 insertions(+), 32 deletions(-) diff --git a/lib/channel.rb b/lib/channel.rb index e94f6501..4ab72db9 100644 --- a/lib/channel.rb +++ b/lib/channel.rb @@ -7,6 +7,8 @@ def initialize(slack_id, name, topic, member_count) super(slack_id, name) @topic = topic @member_count = member_count + + raise ArgumentError, "slack ID, name, topic, and member count are all required." unless topic || member_count end def self.list_all @@ -18,6 +20,4 @@ def self.list_all return channels end -end - -Channel.list_all.each {|channel| puts channel.name} \ No newline at end of file +end \ No newline at end of file diff --git a/lib/recipient.rb b/lib/recipient.rb index 852ec5b0..23338f0e 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -13,6 +13,8 @@ class Recipient def initialize(slack_id, name)#should we get rid of name???? @slack_id = slack_id @name = name + + raise ArgumentError, "slack ID and name are required." unless slack_id || name end def self.get(url) @@ -22,4 +24,6 @@ def self.get(url) def self.list_all raise NotImplementedError, 'Implement me in a child class!' end + + end \ No newline at end of file diff --git a/lib/slack.rb b/lib/slack.rb index d01a0a38..b6fedc67 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -4,29 +4,6 @@ require 'dotenv' require 'table_print' -Dotenv.load -SLACK_TOKEN = ENV['SLACK_TOKEN'] - -def user_list - url = "https://slack.com/api/users.list" - response = HTTParty.get(url, query: {token: SLACK_TOKEN}) - users = [] - response["members"].each do |member| - users << {name: member["name"], real_name: member["real_name"], id: member["id"]} - end - - return users -end - -def channel_list - url = "https://slack.com/api/conversations.list" - response = HTTParty.get(url, query: {token: SLACK_TOKEN}) - channels = [] - response["channels"].each do |channel| - channels << {channel_name: channel["name"], topic: channel["topic"]["value"], member_count: channel["num_members"], slack_ID: channel["id"]} - end - return channels -end def main puts "Welcome to the Ada Slack CLI!" diff --git a/lib/user.rb b/lib/user.rb index 697a7e78..e5b0e71c 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -6,6 +6,8 @@ class User < Recipient def initialize(slack_id, name, real_name) super(slack_id, name) #super(name)????? @real_name = real_name + + #raise ArgumentError, "real name is required." unless real_name end def self.list_all @@ -18,5 +20,4 @@ def self.list_all end end -#??????????? - User.list_all.each { |user| puts user.name } \ No newline at end of file +tp User.new(1, "a", "ada").list_all \ No newline at end of file diff --git a/lib/workspace.rb b/lib/workspace.rb index 7215771d..07fe007b 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -1,9 +1,20 @@ +require_relative 'recipient' +require_relative 'user' +require_relative 'channel' +require 'table_print' + class Workspace attr_reader :users, :channels + attr_accessor :selected + + def initialize(users: [], channels: [], selected: nil) + @users = User.new(1,"a","ada").list_all + @channels = Channel.list_all + @selected = selected - def initialize(users: [], channels: []) - @users = users - @channels = channels end -end \ No newline at end of file + +end + +tp Workspace.new \ No newline at end of file From 08dc9d1955a7354686d09cf2f6a0b377fb80ff68 Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Wed, 7 Oct 2020 12:01:11 -0700 Subject: [PATCH 10/16] initialize workspace. pass tests --- .gitignore | 1 + lib/recipient.rb | 4 +- lib/slack.rb | 4 +- lib/user.rb | 6 +- lib/workspace.rb | 4 +- ...t_all_users_and_channels_for_workspace.yml | 145 ++++++++++++++++++ test/channel_test.rb | 9 ++ test/recipient_test.rb | 24 +++ test/user_test.rb | 9 ++ test/workspace_test.rb | 20 +-- 10 files changed, 207 insertions(+), 19 deletions(-) create mode 100644 test/cassettes/list_all_users_and_channels_for_workspace.yml create mode 100644 test/recipient_test.rb diff --git a/.gitignore b/.gitignore index 5504b740..0b7a5469 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ # Ignore environemnt variables .env lib/.env +coverage diff --git a/lib/recipient.rb b/lib/recipient.rb index 23338f0e..429b4be7 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -1,5 +1,5 @@ require 'httparty' -require_relative 'workspace' +#require_relative 'workspace' require 'dotenv' require 'table_print' @@ -14,7 +14,7 @@ def initialize(slack_id, name)#should we get rid of name???? @slack_id = slack_id @name = name - raise ArgumentError, "slack ID and name are required." unless slack_id || name + raise ArgumentError, "slack ID and name are required." unless slack_id || name end def self.get(url) diff --git a/lib/slack.rb b/lib/slack.rb index b6fedc67..ef9b70a5 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -14,10 +14,10 @@ def main input = gets.chomp if input == "list users" || input == "1" - tp user_list + tp workspace.users puts "\n\n" elsif input == "list channels" || input == "2" - tp channel_list + tp workspace.channels puts "\n\n" elsif input == "quit" || input == "3" break diff --git a/lib/user.rb b/lib/user.rb index e5b0e71c..53053633 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -7,17 +7,17 @@ def initialize(slack_id, name, real_name) super(slack_id, name) #super(name)????? @real_name = real_name - #raise ArgumentError, "real name is required." unless real_name + raise ArgumentError, "real name is required." unless real_name end def self.list_all response = self.get("https://slack.com/api/users.list") users = [] response["members"].each do |member| - users << User.new(member["id"], member["name"], member["real_name"]) + users << User.new(member["id"], member["name"], member["real_name"] || member["profile"]["real_name"]) end return users end end -tp User.new(1, "a", "ada").list_all \ No newline at end of file +tp User.list_all \ No newline at end of file diff --git a/lib/workspace.rb b/lib/workspace.rb index 07fe007b..55105d77 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -8,7 +8,7 @@ class Workspace attr_accessor :selected def initialize(users: [], channels: [], selected: nil) - @users = User.new(1,"a","ada").list_all + @users = User.list_all @channels = Channel.list_all @selected = selected @@ -16,5 +16,3 @@ def initialize(users: [], channels: [], selected: nil) end - -tp Workspace.new \ No newline at end of file diff --git a/test/cassettes/list_all_users_and_channels_for_workspace.yml b/test/cassettes/list_all_users_and_channels_for_workspace.yml new file mode 100644 index 00000000..32500dd5 --- /dev/null +++ b/test/cassettes/list_all_users_and_channels_for_workspace.yml @@ -0,0 +1,145 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?token= + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 07 Oct 2020 17:49:22 GMT + Server: + - Apache + X-Slack-Req-Id: + - 28a5a5fa0515e5e4166176ad10bde18d + X-Oauth-Scopes: + - incoming-webhook,channels:read,groups:read,im:read,mpim:read,users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '1289' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-rog1,haproxy-edge-pdx-ts3v + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"T01C16GNGG3","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Slackbot","real_name_normalized":"Slackbot","display_name":"Slackbot","display_name_normalized":"Slackbot","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"sv41d8cd98f0","always_active":true,"first_name":"slackbot","last_name":"","image_24":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_24.png","image_32":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_32.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_72.png","image_192":"https:\/\/a.slack-edge.com\/80588\/marketing\/img\/avatars\/slackbot\/avatar-slackbot.png","image_512":"https:\/\/a.slack-edge.com\/80588\/img\/slackbot_512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":0},{"id":"U01BVT790NA","team_id":"T01C16GNGG3","name":"api_project2","deleted":false,"color":"3c989f","real_name":"API + project","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"API + project","real_name_normalized":"API project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g3cef7409b5d","api_app_id":"A01C2R7G4SF","always_active":false,"bot_id":"B01C2RDCQUB","image_24":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/3cef7409b5d39d250a40826935a0e09e.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0011-512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":true,"is_app_user":false,"updated":1602006272},{"id":"U01C10DATH8","team_id":"T01C16GNGG3","name":"yjlin789","deleted":false,"color":"9f69e7","real_name":"Jing","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Jing","real_name_normalized":"Jing","display_name":"Jing","display_name_normalized":"Jing","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"1581dfb66e14","image_original":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_original.jpg","is_custom_image":true,"first_name":"Jing","last_name":"","image_24":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_72.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_192.jpg","image_512":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_512.jpg","image_1024":"https:\/\/avatars.slack-edge.com\/2020-10-05\/1409017415330_1581dfb66e143840e9c7_1024.jpg","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":true,"is_owner":true,"is_primary_owner":true,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1601966120},{"id":"U01C10G57NE","team_id":"T01C16GNGG3","name":"rencarothers","deleted":false,"color":"4bbe2e","real_name":"Ren + Carothers","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Ren + Carothers","real_name_normalized":"Ren Carothers","display_name":"Ren Carothers","display_name_normalized":"Ren + Carothers","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g53fff90c824","image_24":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/53fff90c824dbabb405a72411db7f297.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0021-512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_admin":false,"is_owner":false,"is_primary_owner":false,"is_restricted":false,"is_ultra_restricted":false,"is_bot":false,"is_app_user":false,"updated":1602018318},{"id":"U01C8PNLVS8","team_id":"T01C16GNGG3","name":"api_project","deleted":true,"profile":{"title":"","phone":"","skype":"","real_name":"API + project","real_name_normalized":"API project","display_name":"","display_name_normalized":"","fields":null,"status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g12a061ce8c3","api_app_id":"A01BMQV0Z7H","always_active":false,"bot_id":"B01BMSK9J79","image_24":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/12a061ce8c34f2344cc3c05d80896652.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0008-512.png","status_text_canonical":"","team":"T01C16GNGG3"},"is_bot":true,"is_app_user":false,"updated":1602021025}],"cache_ts":1602092962,"response_metadata":{"next_cursor":""}}' + recorded_at: Wed, 07 Oct 2020 17:49:22 GMT +- request: + method: get + uri: https://slack.com/api/conversations.list?token= + body: + encoding: US-ASCII + string: '' + headers: + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Wed, 07 Oct 2020 18:58:37 GMT + Server: + - Apache + X-Slack-Req-Id: + - 1801e59aedf673ae525b0d093fb52abc + X-Oauth-Scopes: + - incoming-webhook,channels:read,groups:read,im:read,mpim:read,users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '693' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-9bli,haproxy-edge-pdx-ts3v + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"C01C16GNVMZ","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1601965941,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"U01C10DATH8","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01C16GNGG3"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":false,"is_private":false,"is_mpim":false,"topic":{"value":"cs + memes are great!","creator":"U01C10G57NE","last_set":1602023254},"purpose":{"value":"This + channel is for... well, everything else. It\u2019s a place for team jokes, + spur-of-the-moment ideas, and funny GIFs. Go wild!","creator":"U01C10DATH8","last_set":1601965941},"previous_names":[],"num_members":2},{"id":"C01C761G84U","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1601965941,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"U01C10DATH8","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01C16GNGG3"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":false,"is_private":false,"is_mpim":false,"topic":{"value":"We + finish wave 1!!","creator":"U01C10DATH8","last_set":1602023247},"purpose":{"value":"This + is the one channel that will always include everyone. It\u2019s a great spot + for announcements and team-wide conversations.","creator":"U01C10DATH8","last_set":1601965941},"previous_names":[],"num_members":2},{"id":"C01CQR91448","name":"slack-cli","is_channel":true,"is_group":false,"is_im":false,"created":1601966059,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"slack-cli","is_shared":false,"parent_conversation":null,"creator":"U01C10DATH8","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["T01C16GNGG3"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":false,"is_private":false,"is_mpim":false,"topic":{"value":"","creator":"","last_set":0},"purpose":{"value":"This + *channel* is for working on a project. Hold meetings, share docs, and make + decisions together with your team.","creator":"U01C10DATH8","last_set":1601966059},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + recorded_at: Wed, 07 Oct 2020 18:58:37 GMT +recorded_with: VCR 6.0.0 diff --git a/test/channel_test.rb b/test/channel_test.rb index 9170cacb..768c2525 100644 --- a/test/channel_test.rb +++ b/test/channel_test.rb @@ -25,6 +25,15 @@ expect(@channel1.member_count).must_be_kind_of Integer end + it "raise error when slack is or name is missing" do + expect{Channel.new(123)}.must_raise ArgumentError + expect{Channel.new(name: "Totoro")}.must_raise ArgumentError + end + + it "raise error when topic or member count is missing" do + expect{Channel.new(123, "Totoro", member_count: 5)}.must_raise ArgumentError + expect{Channel.new(123, "snacks", "ice cream")}.must_raise ArgumentError + end end describe "list_all" do diff --git a/test/recipient_test.rb b/test/recipient_test.rb new file mode 100644 index 00000000..8577ae50 --- /dev/null +++ b/test/recipient_test.rb @@ -0,0 +1,24 @@ +require_relative 'test_helper' + +describe "Initializer" do + before do + @recipient1 = Recipient.new(123, "Totoro") + end + + it "is an instance of User" do + expect(@recipient1).must_be_kind_of Recipient + end + + it "username must be a string" do + expect(@recipient1.name).must_be_kind_of String + end + + it "Slack ID must be a integer" do + expect(@recipient1.slack_id).must_be_kind_of Integer + end + + it "raise error when slack is or name is missing" do + expect{Recipient.new(123)}.must_raise ArgumentError + expect{Recipient.new(name: "Totoro")}.must_raise ArgumentError + end +end \ No newline at end of file diff --git a/test/user_test.rb b/test/user_test.rb index f3834bdd..33870b06 100644 --- a/test/user_test.rb +++ b/test/user_test.rb @@ -21,6 +21,15 @@ expect(@user1.slack_id).must_be_kind_of Integer end + it "raise error when slack is or name is missing" do + expect{User.new(123)}.must_raise ArgumentError + expect{User.new(name: "Totoro")}.must_raise ArgumentError + end + + it "raise error when real name is missing" do + expect{User.new(123, "Totoro")}.must_raise ArgumentError + end + end describe "list_all" do diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 1821e580..5cb45e26 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -1,20 +1,22 @@ require_relative 'test_helper' describe "Initializer" do + before do + VCR.use_cassette("list_all_users_and_channels_for_workspace") do + @workspace1 = Workspace.new + end + end + it "is an instance of Workspace" do - expect(Workspace.new).must_be_kind_of Workspace + expect(@workspace1).must_be_kind_of Workspace end - it "uses must be an empty array" do - workspace1 = Workspace.new - expect(workspace1.users).must_be_kind_of Array - expect(workspace1.users).must_be_empty + it "uses must be an array" do + expect(@workspace1.users).must_be_kind_of Array end - it "channels must be an empty array" do - workspace1 = Workspace.new - expect(workspace1.channels).must_be_kind_of Array - expect(workspace1.channels).must_be_empty + it "channels must be an array" do + expect(@workspace1.channels).must_be_kind_of Array end end From 87d3f06e529b0d4f7223f30cb30c8d96c24add1f Mon Sep 17 00:00:00 2001 From: Yingjing Lin Date: Wed, 7 Oct 2020 16:21:01 -0700 Subject: [PATCH 11/16] complete select and detail method. pass all the tests --- lib/slack.rb | 61 +++++++++++++++++++++++++++++++++++++++++------- lib/user.rb | 2 +- lib/workspace.rb | 15 ++++++++++++ 3 files changed, 68 insertions(+), 10 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index ef9b70a5..f6672168 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -7,22 +7,28 @@ def main puts "Welcome to the Ada Slack CLI!" - workspace = Workspace.new + @workspace = Workspace.new loop do - puts "What would you like to do with CLI? \n1. list users \n2. list channels \n3. quit" + puts "What would you like to do with CLI? \n1. list users \n2. list channels \n3. select user \n4. select channel \n5. detail\n (about the selected user or channel) \n6. quit" input = gets.chomp - if input == "list users" || input == "1" - tp workspace.users + case input + when "list users", "1" + tp @workspace.users puts "\n\n" - elsif input == "list channels" || input == "2" - tp workspace.channels + when "list channels", "2" + tp @workspace.channels puts "\n\n" - elsif input == "quit" || input == "3" + when "select user", "3" + select_a_user + when "select channel", "4" + select_a_channel + when "detail", "5" + tp @workspace.selected + puts "\n\n" + when "quit", "6" break - else - puts "Please choose one of the options." end end @@ -30,4 +36,41 @@ def main puts "Thank you for using the Ada Slack CLI" end +def select_a_user + loop do + puts "What's the user's slack id or username? enter 6 or quit to exit." + id_or_name = gets.chomp + if id_or_name == "6" || id_or_name == "quit" + break + end + begin + @workspace.select_user(id_or_name) + rescue Exception + puts "Please enter a valid username or id.\n\n" + else + puts "Ok, #{id_or_name} is selected.\n\n" + break + end + end +end + +def select_a_channel + loop do + puts "What's the channel's slack id or username? enter 6 or quit to exit." + id_or_name = gets.chomp + if id_or_name == "6" || id_or_name == "quit" + break + end + begin + @workspace.select_channel(id_or_name) + rescue Exception + puts "Please enter a valid channel name or id.\n\n" + else + puts "Ok, #{id_or_name} is selected.\n\n" + break + end + end +end + + main if __FILE__ == $PROGRAM_NAME \ No newline at end of file diff --git a/lib/user.rb b/lib/user.rb index 53053633..d8d20e7d 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -20,4 +20,4 @@ def self.list_all end end -tp User.list_all \ No newline at end of file + diff --git a/lib/workspace.rb b/lib/workspace.rb index 55105d77..d08184f6 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -14,5 +14,20 @@ def initialize(users: [], channels: [], selected: nil) end + def select_user(name_or_id) + @selected = @users.find {|user| user.slack_id == name_or_id} + @selected = @users.find {|user| user.name == name_or_id} unless @selected + raise Exception.new("no user found.") unless @selected + return @selected + end + + def select_channel(name_or_id) + @selected = @channels.find {|channel| channel.slack_id == name_or_id} + @selected = @channels.find {|channel| channel.name == name_or_id} unless @selected + raise Exception.new("no channel found.") unless @selected + return @selected + end end + +p Workspace.new.select_user("slackbot") \ No newline at end of file From 2928c71df61c1c1523f1174d91ebf7592f2f1d6c Mon Sep 17 00:00:00 2001 From: Ren Carothers Date: Thu, 8 Oct 2020 11:40:36 -0700 Subject: [PATCH 12/16] wrote methods in slack.rb, workspace and recipient that allow user to write a message then use http post to send message, wrote tests --- lib/recipient.rb | 17 ++++++++++++++++ lib/slack.rb | 16 +++++++++++++-- lib/workspace.rb | 7 ++++++- test/workspace_test.rb | 45 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 3 deletions(-) diff --git a/lib/recipient.rb b/lib/recipient.rb index 429b4be7..401d398c 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -25,5 +25,22 @@ def self.list_all raise NotImplementedError, 'Implement me in a child class!' end + def self.send_message(slack_id, message) + url = "https://slack.com/api/chat.postMessage" + response = HTTParty.post( + url, + body: { + token: SLACK_TOKEN, + text: message, + channel: slack_id + }, + headers: { 'Content-Type' => 'application/x-www-form-urlencoded' } + ) + if response.code != 200 || response.parsed_response["ok"] == false + raise Exception.new("Http request code #{response.code} error #{response.parsed_response["error"]}") + end + return response + end + end \ No newline at end of file diff --git a/lib/slack.rb b/lib/slack.rb index f6672168..b17861fa 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -10,7 +10,7 @@ def main @workspace = Workspace.new loop do - puts "What would you like to do with CLI? \n1. list users \n2. list channels \n3. select user \n4. select channel \n5. detail\n (about the selected user or channel) \n6. quit" + puts "What would you like to do with CLI? \n1. list users \n2. list channels \n3. select user \n4. select channel \n5. detail\n (about the selected user or channel) \n6. send message \n7. quit" input = gets.chomp case input @@ -27,7 +27,10 @@ def main when "detail", "5" tp @workspace.selected puts "\n\n" - when "quit", "6" + when "send message", "6" + write_message + puts "\n\n" + when "quit", "7" break end end @@ -36,6 +39,15 @@ def main puts "Thank you for using the Ada Slack CLI" end +def write_message + puts "What is your message?" + message = gets.chomp + if message == nil + return false + end + puts "Ok, we sent off your message!" if @workspace.send_message(message) +end + def select_a_user loop do puts "What's the user's slack id or username? enter 6 or quit to exit." diff --git a/lib/workspace.rb b/lib/workspace.rb index d08184f6..65442f8d 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -28,6 +28,11 @@ def select_channel(name_or_id) return @selected end + def send_message(message) + raise Exception.new("nothing selected, please select a user/channel to send to first!") if @selected == nil + channel = @selected.slack_id + Recipient.send_message(channel, message) + return true + end end -p Workspace.new.select_user("slackbot") \ No newline at end of file diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 5cb45e26..93d150db 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -20,3 +20,48 @@ end end + +describe "select user or channel" do + before do + VCR.use_cassette("list_all_users_and_channels_for_workspace") do + @workspace1 = Workspace.new + end + end + it "return correct user" do + expect(@workspace1.select_user("yjlin789")).must_be_kind_of User + expect(@workspace1.select_user("yjlin789").name).must_equal "yjlin789" + expect(@workspace1.select_user("USLACKBOT").name).must_equal "slackbot" + end + it "return correct channel" do + expect(@workspace1.select_channel("random")).must_be_kind_of Channel + expect(@workspace1.select_channel("random").name).must_equal "random" + expect(@workspace1.select_channel("C01C761G84U").name).must_equal "general" + end +end + +describe "send_message" do + before do + VCR.use_cassette("list_all_users_and_channels_for_workspace") do + @workspace1 = Workspace.new + @message = "Test Message" + @workspace1.selected = Recipient.new("C01C16GNVMZ","random") + end + end + + it "successfully sends a message" do + VCR.use_cassette("send_message") do + expect(@workspace1.send_message(@message).parsed_response["ok"]).must_equal true + end + end + + it "raise an error if message is nil" do + @message = nil + expect{@workspace1.send_message(@message)}.must_raise Exception + end + + it "if user or channel is not selected, raises an error" do + @workspace1.selected = nil + expect{@workspace1.send_message(@message)}.must_raise Exception + end + +end From f0035787d88b405b5a1fc8d9aba1ebce262a1caa Mon Sep 17 00:00:00 2001 From: Ren Carothers Date: Thu, 8 Oct 2020 12:14:30 -0700 Subject: [PATCH 13/16] added tests for recipient, pass all the tests --- .idea/.gitignore | 0 .idea/.rakeTasks | 7 + .idea/inspectionProfiles/Project_Default.xml | 6 + .idea/misc.xml | 4 + .idea/modules.xml | 8 + .idea/slack-cli.iml | 32 +++ .idea/vcs.xml | 6 + .idea/workspace.xml | 232 +++++++++++++++++++ lib/recipient.rb | 1 + lib/slack.rb | 2 +- lib/workspace.rb | 2 +- test/cassettes/recipient_send_message.yml | 70 ++++++ test/cassettes/send_message_to_channel.yml | 70 ++++++ test/cassettes/send_message_to_user.yml | 70 ++++++ test/recipient_test.rb | 20 ++ test/workspace_test.rb | 13 +- 16 files changed, 538 insertions(+), 5 deletions(-) create mode 100644 .idea/.gitignore create mode 100644 .idea/.rakeTasks create mode 100644 .idea/inspectionProfiles/Project_Default.xml create mode 100644 .idea/misc.xml create mode 100644 .idea/modules.xml create mode 100644 .idea/slack-cli.iml create mode 100644 .idea/vcs.xml create mode 100644 .idea/workspace.xml create mode 100644 test/cassettes/recipient_send_message.yml create mode 100644 test/cassettes/send_message_to_channel.yml create mode 100644 test/cassettes/send_message_to_user.yml diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 00000000..e69de29b diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks new file mode 100644 index 00000000..e409da2a --- /dev/null +++ b/.idea/.rakeTasks @@ -0,0 +1,7 @@ + + diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 00000000..b0db9b0f --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 00000000..510e7fcc --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 00000000..7a98b196 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/slack-cli.iml b/.idea/slack-cli.iml new file mode 100644 index 00000000..329312d1 --- /dev/null +++ b/.idea/slack-cli.iml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 00000000..94a25f7f --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 00000000..2cadebb6 --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,232 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1602024079201 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/lib/recipient.rb b/lib/recipient.rb index 401d398c..cc15adc6 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -26,6 +26,7 @@ def self.list_all end def self.send_message(slack_id, message) + raise Exception.new("message is required") if message == nil url = "https://slack.com/api/chat.postMessage" response = HTTParty.post( url, diff --git a/lib/slack.rb b/lib/slack.rb index b17861fa..32fca9ab 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -45,7 +45,7 @@ def write_message if message == nil return false end - puts "Ok, we sent off your message!" if @workspace.send_message(message) + puts "Ok, we sent off your message!" if @workspace.send_message(message).parsed_response["ok"] == true end def select_a_user diff --git a/lib/workspace.rb b/lib/workspace.rb index 65442f8d..be33a1f6 100644 --- a/lib/workspace.rb +++ b/lib/workspace.rb @@ -32,7 +32,7 @@ def send_message(message) raise Exception.new("nothing selected, please select a user/channel to send to first!") if @selected == nil channel = @selected.slack_id Recipient.send_message(channel, message) - return true + # return true end end diff --git a/test/cassettes/recipient_send_message.yml b/test/cassettes/recipient_send_message.yml new file mode 100644 index 00000000..503d4981 --- /dev/null +++ b/test/cassettes/recipient_send_message.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=&text=Test%20Message&channel=C01C16GNVMZ + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 19:10:46 GMT + Server: + - Apache + X-Slack-Req-Id: + - 0d3d260dd851a23b3621f14996905152 + X-Oauth-Scopes: + - incoming-webhook,channels:read,groups:read,im:read,mpim:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '320' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-a01j,haproxy-edge-pdx-1nke + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channel":"C01C16GNVMZ","ts":"1602184246.000600","message":{"bot_id":"B01C2RDCQUB","type":"message","text":"Test + Message","user":"U01BVT790NA","ts":"1602184246.000600","team":"T01C16GNGG3","bot_profile":{"id":"B01C2RDCQUB","deleted":false,"name":"API + project","updated":1602006272,"app_id":"A01C2R7G4SF","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01C16GNGG3"}}}' + recorded_at: Thu, 08 Oct 2020 19:10:46 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/send_message_to_channel.yml b/test/cassettes/send_message_to_channel.yml new file mode 100644 index 00000000..a411d13f --- /dev/null +++ b/test/cassettes/send_message_to_channel.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=&text=Test%20Message&channel=C01C16GNVMZ + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 19:02:19 GMT + Server: + - Apache + X-Slack-Req-Id: + - d4d1cea63b4e25ea64a20afd1801c545 + X-Oauth-Scopes: + - incoming-webhook,channels:read,groups:read,im:read,mpim:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '321' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-3qgr,haproxy-edge-pdx-jcbi + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channel":"C01C16GNVMZ","ts":"1602183739.000500","message":{"bot_id":"B01C2RDCQUB","type":"message","text":"Test + Message","user":"U01BVT790NA","ts":"1602183739.000500","team":"T01C16GNGG3","bot_profile":{"id":"B01C2RDCQUB","deleted":false,"name":"API + project","updated":1602006272,"app_id":"A01C2R7G4SF","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01C16GNGG3"}}}' + recorded_at: Thu, 08 Oct 2020 19:02:19 GMT +recorded_with: VCR 6.0.0 diff --git a/test/cassettes/send_message_to_user.yml b/test/cassettes/send_message_to_user.yml new file mode 100644 index 00000000..17050899 --- /dev/null +++ b/test/cassettes/send_message_to_user.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=&text=Test%20Message&channel=U01C10G57NE + headers: + Content-Type: + - application/x-www-form-urlencoded + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Date: + - Thu, 08 Oct 2020 19:02:19 GMT + Server: + - Apache + X-Slack-Req-Id: + - 1e850e2f756012c2ee536306a94751d2 + X-Oauth-Scopes: + - incoming-webhook,channels:read,groups:read,im:read,mpim:read,users:read,chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Origin: + - "*" + X-Slack-Backend: + - r + X-Content-Type-Options: + - nosniff + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts, x-b3-traceid, x-b3-spanid, x-b3-parentspanid, + x-b3-sampled, x-b3-flags + Vary: + - Accept-Encoding + Pragma: + - no-cache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Content-Length: + - '323' + Content-Type: + - application/json; charset=utf-8 + X-Via: + - haproxy-www-ur5l,haproxy-edge-pdx-dhzt + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channel":"D01CSEP0M5E","ts":"1602183739.000100","message":{"bot_id":"B01C2RDCQUB","type":"message","text":"Test + Message","user":"U01BVT790NA","ts":"1602183739.000100","team":"T01C16GNGG3","bot_profile":{"id":"B01C2RDCQUB","deleted":false,"name":"API + project","updated":1602006272,"app_id":"A01C2R7G4SF","icons":{"image_36":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_36.png","image_48":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/bot_48.png","image_72":"https:\/\/a.slack-edge.com\/80588\/img\/plugins\/app\/service_72.png"},"team_id":"T01C16GNGG3"}}}' + recorded_at: Thu, 08 Oct 2020 19:02:19 GMT +recorded_with: VCR 6.0.0 diff --git a/test/recipient_test.rb b/test/recipient_test.rb index 8577ae50..061d78e5 100644 --- a/test/recipient_test.rb +++ b/test/recipient_test.rb @@ -21,4 +21,24 @@ expect{Recipient.new(123)}.must_raise ArgumentError expect{Recipient.new(name: "Totoro")}.must_raise ArgumentError end +end + +describe "send_message" do + before do + @recipient1 = Recipient.new("C01C16GNVMZ","random") + @message = "Test Message" + # end + end + + it "successfully sends a message" do + VCR.use_cassette("recipient_send_message") do + expect(Recipient.send_message(@recipient1.slack_id, @message).parsed_response["ok"]).must_equal true + end + end + + it "raise an error if message is nil" do + @message = nil + expect{@recipient1.send_message(@message)}.must_raise Exception + end + end \ No newline at end of file diff --git a/test/workspace_test.rb b/test/workspace_test.rb index 93d150db..7d6956b1 100644 --- a/test/workspace_test.rb +++ b/test/workspace_test.rb @@ -48,9 +48,16 @@ end end - it "successfully sends a message" do - VCR.use_cassette("send_message") do - expect(@workspace1.send_message(@message).parsed_response["ok"]).must_equal true + it "successfully sends a message to a channel" do + VCR.use_cassette("send_message_to_channel") do + expect(@workspace1.send_message(@message).parsed_response["ok"]).must_equal true + end + end + + it "successfully sends a message to a user" do + VCR.use_cassette("send_message_to_user") do + @workspace1.selected = Recipient.new("U01C10G57NE","rencarothers") + expect(@workspace1.send_message(@message).parsed_response["ok"]).must_equal true end end From 36959ae7af57805777b727389fe419f614461cb5 Mon Sep 17 00:00:00 2001 From: Ren Carothers Date: Thu, 8 Oct 2020 15:03:48 -0700 Subject: [PATCH 14/16] tweaked slack.rb to output a message in the case of exceptions --- lib/recipient.rb | 2 +- lib/slack.rb | 28 ++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/recipient.rb b/lib/recipient.rb index cc15adc6..2c7df9fa 100644 --- a/lib/recipient.rb +++ b/lib/recipient.rb @@ -26,7 +26,7 @@ def self.list_all end def self.send_message(slack_id, message) - raise Exception.new("message is required") if message == nil + raise Exception.new("message is required") if message == "" url = "https://slack.com/api/chat.postMessage" response = HTTParty.post( url, diff --git a/lib/slack.rb b/lib/slack.rb index 32fca9ab..37a08e92 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -25,34 +25,46 @@ def main when "select channel", "4" select_a_channel when "detail", "5" - tp @workspace.selected - puts "\n\n" + if @workspace.selected == nil + puts "Please select a user or channel first!" + puts "\n\n" + else + tp @workspace.selected + puts "\n\n" + end when "send message", "6" write_message puts "\n\n" when "quit", "7" break + else + puts "Please enter one of the menu items or their corresponding number values." + puts "\n\n" end end - puts "Thank you for using the Ada Slack CLI" end def write_message + if @workspace.selected == nil + puts "Please select a user or channel first!" + else puts "What is your message?" message = gets.chomp - if message == nil + if message == "" + puts "No message was inputted." return false end puts "Ok, we sent off your message!" if @workspace.send_message(message).parsed_response["ok"] == true + end end def select_a_user loop do - puts "What's the user's slack id or username? enter 6 or quit to exit." + puts "What's the user's slack id or username? enter 7 or quit to exit." id_or_name = gets.chomp - if id_or_name == "6" || id_or_name == "quit" + if id_or_name == "7" || id_or_name == "quit" break end begin @@ -68,9 +80,9 @@ def select_a_user def select_a_channel loop do - puts "What's the channel's slack id or username? enter 6 or quit to exit." + puts "What's the channel's slack id or username? enter 7 or quit to exit." id_or_name = gets.chomp - if id_or_name == "6" || id_or_name == "quit" + if id_or_name == "7" || id_or_name == "quit" break end begin From c6a8fd1a9d83f28f5a886bc0dfa84314b2a2b473 Mon Sep 17 00:00:00 2001 From: Ren Carothers Date: Thu, 8 Oct 2020 15:06:20 -0700 Subject: [PATCH 15/16] added more distinctive menu --- lib/slack.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/slack.rb b/lib/slack.rb index 37a08e92..0d9c56ee 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -10,7 +10,7 @@ def main @workspace = Workspace.new loop do - puts "What would you like to do with CLI? \n1. list users \n2. list channels \n3. select user \n4. select channel \n5. detail\n (about the selected user or channel) \n6. send message \n7. quit" + puts "************** What would you like to do with CLI? ************ \n1. list users \n2. list channels \n3. select user \n4. select channel \n5. detail\n (about the selected user or channel) \n6. send message \n7. quit" input = gets.chomp case input From 286d659c97ec01d10dda3f335b2cff31f2f1d148 Mon Sep 17 00:00:00 2001 From: Ren Carothers Date: Thu, 8 Oct 2020 15:14:56 -0700 Subject: [PATCH 16/16] just adding silly emjois now apparently haha --- lib/slack.rb | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/lib/slack.rb b/lib/slack.rb index 0d9c56ee..b4fa0c8d 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -10,7 +10,7 @@ def main @workspace = Workspace.new loop do - puts "************** What would you like to do with CLI? ************ \n1. list users \n2. list channels \n3. select user \n4. select channel \n5. detail\n (about the selected user or channel) \n6. send message \n7. quit" + puts "(~ ̄▽ ̄)~ What would you like to do with CLI? ~( ̄▽ ̄~) \n1. list users \n2. list channels \n3. select user \n4. select channel \n5. detail\n (about the selected user or channel) \n6. send message \n7. quit" input = gets.chomp case input @@ -26,6 +26,7 @@ def main select_a_channel when "detail", "5" if @workspace.selected == nil + puts "ヽ(ˋДˊ)ノ" puts "Please select a user or channel first!" puts "\n\n" else @@ -36,8 +37,10 @@ def main write_message puts "\n\n" when "quit", "7" + puts "乀(ˉεˉ乀) bye~" break else + puts "ヽ(ˋДˊ)ノ" puts "Please enter one of the menu items or their corresponding number values." puts "\n\n" end @@ -48,15 +51,15 @@ def main def write_message if @workspace.selected == nil - puts "Please select a user or channel first!" + puts "ヽ(ˋДˊ)ノ \nPlease select a user or channel first!" else puts "What is your message?" message = gets.chomp if message == "" - puts "No message was inputted." + puts "ヽ(ˋДˊ)ノ \nNo message was inputted." return false end - puts "Ok, we sent off your message!" if @workspace.send_message(message).parsed_response["ok"] == true + puts "ヽ(ˋ▽ˊ)ノ \nOk, we sent off your message!" if @workspace.send_message(message).parsed_response["ok"] == true end end @@ -70,9 +73,9 @@ def select_a_user begin @workspace.select_user(id_or_name) rescue Exception - puts "Please enter a valid username or id.\n\n" + puts "ヽ(ˋДˊ)ノ \nPlease enter a valid username or id.\n\n" else - puts "Ok, #{id_or_name} is selected.\n\n" + puts "ヽ(ˋ▽ˊ)ノ \nOk, #{id_or_name} is selected.\n\n" break end end @@ -88,9 +91,9 @@ def select_a_channel begin @workspace.select_channel(id_or_name) rescue Exception - puts "Please enter a valid channel name or id.\n\n" + puts "ヽ(ˋДˊ)ノ \nPlease enter a valid channel name or id.\n\n" else - puts "Ok, #{id_or_name} is selected.\n\n" + puts "ヽ(ˋ▽ˊ)ノ \nOk, #{id_or_name} is selected.\n\n" break end end