diff --git a/lib/channel.rb b/lib/channel.rb new file mode 100644 index 00000000..b2993c34 --- /dev/null +++ b/lib/channel.rb @@ -0,0 +1,30 @@ +class Channel < Recipient + attr_reader :topic, :member_count + + def initialize(topic: , member_count: , slack_id: , name: ) + super(slack_id: slack_id, name: name) + @topic = topic + @member_count = member_count + end + + def details + details = """ + Channel Details: + Slack ID: #{@slack_id} + Name: #{@name} + Topic: #{@topic} + Member Count: #{@member_count} + """ + + return details + end + + def self.list + response = self.get("https://slack.com/api/channels.list", ENV["SLACK_TOKEN"]) + + members = response["channels"].map do |channel| + self.new(slack_id: channel["id"], name: channel["name"], topic: channel["topic"]["value"], member_count: channel["members"].length ) + end + return members + end +end diff --git a/lib/recipient.rb b/lib/recipient.rb new file mode 100644 index 00000000..7419ae44 --- /dev/null +++ b/lib/recipient.rb @@ -0,0 +1,30 @@ +class Recipient + attr_reader :slack_id, :name + + def initialize(slack_id: , name: ) + @slack_id = slack_id + @name = name + end + + def self.get(url, params) + query = { + token: params + } + + response = HTTParty.get(url, query: query) + + if response["error"] + raise SlackApiError.new "#{response.code}: #{response.message} -- #{response["error"]}" + end + + return response + end + + def details + raise NotImplementedError.new "Implement me in a child class!" + end + + def self.list + raise NotImplementedError.new "Implement me in a child class!" + end +end diff --git a/lib/slack.rb b/lib/slack.rb index 960cf2f7..090c7670 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,11 +1,138 @@ #!/usr/bin/env ruby +require_relative 'workspace' def main + workspace = Workspace.new + # variable to format command line entry + prompt = "> " + puts "Welcome to the Ada Slack CLI!" - - # TODO project - + puts "The number of channels is #{workspace.channels.length}." + puts "The number of users is #{workspace.users.length}" + + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + until search == "quit" + + case search + when "quit" + exit + + when "list users", "users" + puts + puts "Listing Users..." + workspace.users.each do |user| + puts + puts "Username: #{user.name}" + puts "Real Name: #{user.real_name}" + puts "Slack ID: #{user.slack_id}" + end + puts + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + + when "list channels", "channels" + puts + puts "Listing Channels..." + workspace.channels.each do |channel| + puts + puts "Channel name: #{channel.name}" + puts "Topic: #{channel.topic}" + puts "Member count: #{channel.member_count}" + puts "Slack ID: #{channel.slack_id}" + end + puts + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + + when "select channel", "channel" + puts "Please enter a channel name or slack_id for the channel you would like to select:" + print prompt + input = gets.chomp + + if workspace.select_channel(input: input) + workspace.select_channel(input: input) + puts """ + #{input} is now selected + """ + else + puts """ + No channel has that name or ID + """ + end + + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + + when "select user", "user" + puts "Please enter a username or slack_id for the user you would like to select:" + print prompt + input = gets.chomp + + if workspace.select_user(input: input) + workspace.select_user(input: input) + puts """ + #{input} is now selected + """ + else + puts """ + No user has that name or ID + """ + end + + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + + when "details" + if workspace.show_details + puts "Here are the details for #{workspace.selected.name}:" + puts workspace.show_details + else + puts """ + No recipient is currently selected + """ + end + + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + + when "send message", "message" + unless workspace.selected.nil? + puts "What message would you like to send to #{workspace.selected.name}?" + message = gets.chomp + + workspace.send_message(message, workspace.selected.slack_id) + + puts """ + Message posted! + """ + else + puts """ + No recipient selected! + """ + end + + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + else + puts """ + Invalid Command + """ + puts "Do you want to list users, list channels, select user, select channel, show details for selected, send message to selected or quit?" + print prompt + search = gets.chomp.downcase + end + end + 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/slack_api_error.rb b/lib/slack_api_error.rb new file mode 100644 index 00000000..e65f8de8 --- /dev/null +++ b/lib/slack_api_error.rb @@ -0,0 +1 @@ +class SlackApiError < StandardError; end diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 00000000..5206d055 --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,31 @@ +class User < Recipient + attr_reader :real_name, :status_text, :status_emoji + + def initialize(real_name:, slack_id:, name:) + super(slack_id: slack_id, name: name) + @real_name = real_name + @status_text = status_text + @status_emoji = status_emoji + end + + def details + details = """ + User Details: + Slack ID: #{@slack_id} + Username: #{@name} + Real Name: #{@real_name} + """ + + return details + end + + def self.list + response = self.get("https://slack.com/api/users.list", ENV["SLACK_TOKEN"]) + + members = response["members"].map do |member| + self.new(slack_id: member["id"], name: member["name"], real_name: member["real_name"] ) + end + return members + end +end + diff --git a/lib/workspace.rb b/lib/workspace.rb new file mode 100644 index 00000000..b465da66 --- /dev/null +++ b/lib/workspace.rb @@ -0,0 +1,70 @@ +require 'httparty' +require 'awesome_print' +require 'pry' +require 'dotenv' +Dotenv.load + +require_relative 'slack_api_error' +require_relative 'recipient' +require_relative 'channel' +require_relative 'user' + +class Workspace + attr_reader :users, :channels, :selected + + def initialize + @users = User.list + @channels = Channel.list + @selected = nil + end + + def select_channel(input: nil) + channel_names = @channels.map { |channel| channel.name } + channel_ids = @channels.map { |channel| channel.slack_id } + + if channel_names.include?(input) + @selected = @channels.find { |c| input == c.name } + elsif channel_ids.include?(input) + @selected = @channels.find { |c| input == c.slack_id } + else + return nil + end + return @selected + end + + def select_user(input: nil) + usernames = @users.map { |user| user.name } + user_ids = @users.map { |user| user.slack_id } + + if usernames.include?(input) + @selected = @users.find { |u| input == u.name } + elsif user_ids.include?(input) + @selected = @users.find { |u| input == u.slack_id } + else + return nil + end + return @selected + end + + def show_details + return @selected.details if @selected + end + + def send_message(message, channel) + response = HTTParty.post( + "https://slack.com/api/chat.postMessage", + body: { + token: ENV["SLACK_TOKEN"], + channel: channel, + text: message + }, + headers: { 'Content-Type' => 'application/x-www-form-urlencoded' } + ) + + if response["error"] + raise SlackApiError.new "#{response.code}: #{response.message} -- #{response["error"]}" + end + + return response + end +end diff --git a/test/cassettes/construct_workspace.yml b/test/cassettes/construct_workspace.yml new file mode 100644 index 00000000..1fb54e6b --- /dev/null +++ b/test/cassettes/construct_workspace.yml @@ -0,0 +1,156 @@ +--- +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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '932' + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:21:44 GMT + Server: + - Apache + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - b1c516f3-eb2e-492e-b35b-55a991e0a73c + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write:bot + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Vary: + - Accept-Encoding + Pragma: + - no-cache + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-2wz3 + X-Cache: + - Miss from cloudfront + Via: + - 1.1 61e75bd33e6585cb966e70a5677b630b.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - gVBYCyM8oNWBXtCd-4-I4SCLXl0I5FlSycaBsCdu0o_hgWFLmgYv0A== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"TMURTAYBV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":null,"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":"TMURTAYBV"},"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":"UMURTAYP5","team_id":"TMURTAYBV","name":"juliabouv","deleted":false,"color":"9f69e7","real_name":"Julia + Bouvier","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Julia + Bouvier","real_name_normalized":"Julia Bouvier","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"gd5cb54a2a82","first_name":"Julia","last_name":"Bouvier","image_24":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-512.png","status_text_canonical":"","team":"TMURTAYBV"},"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":1568073742,"has_2fa":false},{"id":"UN863PN23","team_id":"TMURTAYBV","name":"amalh.a97","deleted":false,"color":"4bbe2e","real_name":"Amal","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Amal","real_name_normalized":"Amal","display_name":"Amal","display_name_normalized":"Amal","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g1bf8487fb4a","image_24":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-512.png","status_text_canonical":"","team":"TMURTAYBV"},"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":1568073520,"has_2fa":false}],"cache_ts":1568409704,"response_metadata":{"next_cursor":""}}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:21:44 GMT +- request: + method: get + uri: https://slack.com/api/channels.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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '592' + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:21:44 GMT + Server: + - Apache + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - 4574c2b0-9e17-41b9-8471-43ef67541dcd + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write:bot + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read + Vary: + - Accept-Encoding + Pragma: + - no-cache + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-ntno + X-Cache: + - Miss from cloudfront + Via: + - 1.1 bae03a76f4f3eb92893beec8dc1a7f7d.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - wZNMOOqmR2WjbeddhBlprimOoqMLjQ7cUN3R6TrzX-iSh-NqPG9QWA== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"CN5RT17J8","name":"random","is_channel":true,"created":1568073362,"is_archived":false,"is_general":false,"unlinked":0,"creator":"UMURTAYP5","name_normalized":"random","is_shared":false,"is_org_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"members":["UMURTAYP5","UN863PN23"],"topic":{"value":"Non-work + banter and water cooler conversation","creator":"UMURTAYP5","last_set":1568073362},"purpose":{"value":"A + place for non-work-related flimflam, faffing, hodge-podge or jibber-jabber + you''d prefer to keep out of more focused work-related channels.","creator":"UMURTAYP5","last_set":1568073362},"previous_names":[],"num_members":2},{"id":"CN862L6AK","name":"general","is_channel":true,"created":1568073362,"is_archived":false,"is_general":true,"unlinked":0,"creator":"UMURTAYP5","name_normalized":"general","is_shared":false,"is_org_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"members":["UMURTAYP5","UN863PN23"],"topic":{"value":"Company-wide + announcements and work-based matters","creator":"UMURTAYP5","last_set":1568073362},"purpose":{"value":"This + channel is for workspace-wide communication and announcements. All members + are in this channel.","creator":"UMURTAYP5","last_set":1568073362},"previous_names":[],"num_members":2},{"id":"CN862LB8F","name":"awesome-slack-cli-design-activity","is_channel":true,"created":1568073362,"is_archived":false,"is_general":false,"unlinked":0,"creator":"UMURTAYP5","name_normalized":"awesome-slack-cli-design-activity","is_shared":false,"is_org_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"members":["UMURTAYP5","UN863PN23"],"topic":{"value":"Discussing + the amazing things that are happening here.","creator":"UMURTAYP5","last_set":1568094901},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:21:45 GMT +recorded_with: VCR 5.0.0 diff --git a/test/cassettes/get_recipient_api.yml b/test/cassettes/get_recipient_api.yml new file mode 100644 index 00000000..6981e6b3 --- /dev/null +++ b/test/cassettes/get_recipient_api.yml @@ -0,0 +1,78 @@ +--- +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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '932' + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:21:46 GMT + Server: + - Apache + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - 4a1be412-3f1e-4f5b-9f70-cc66d0a1c4a9 + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write:bot + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Vary: + - Accept-Encoding + Pragma: + - no-cache + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-lcub + X-Cache: + - Miss from cloudfront + Via: + - 1.1 61e75bd33e6585cb966e70a5677b630b.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - kJ3A1T2YNhGSsxVUvApMUYPBlCSAYqDLDR7XwBVWHYEf8SXOf1Xarw== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"TMURTAYBV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":null,"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":"TMURTAYBV"},"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":"UMURTAYP5","team_id":"TMURTAYBV","name":"juliabouv","deleted":false,"color":"9f69e7","real_name":"Julia + Bouvier","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Julia + Bouvier","real_name_normalized":"Julia Bouvier","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"gd5cb54a2a82","first_name":"Julia","last_name":"Bouvier","image_24":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-512.png","status_text_canonical":"","team":"TMURTAYBV"},"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":1568073742,"has_2fa":false},{"id":"UN863PN23","team_id":"TMURTAYBV","name":"amalh.a97","deleted":false,"color":"4bbe2e","real_name":"Amal","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Amal","real_name_normalized":"Amal","display_name":"Amal","display_name_normalized":"Amal","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g1bf8487fb4a","image_24":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-512.png","status_text_canonical":"","team":"TMURTAYBV"},"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":1568073520,"has_2fa":false}],"cache_ts":1568409706,"response_metadata":{"next_cursor":""}}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:21:46 GMT +recorded_with: VCR 5.0.0 diff --git a/test/cassettes/get_recipient_api_error.yml b/test/cassettes/get_recipient_api_error.yml new file mode 100644 index 00000000..be7080a1 --- /dev/null +++ b/test/cassettes/get_recipient_api_error.yml @@ -0,0 +1,64 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/users.list?token=bad_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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '55' + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:21:46 GMT + Server: + - Apache + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Vary: + - Accept-Encoding + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - ae030d6e-e3a5-4555-9c2a-a6693b50364c + X-Xss-Protection: + - '0' + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-x0xq + X-Cache: + - Miss from cloudfront + Via: + - 1.1 bae03a76f4f3eb92893beec8dc1a7f7d.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - 2bfTSy4EErfby2rMZlCWwO-LaeK8GYHbJy7z9hV-F-fEsmbfyI1IYg== + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"invalid_auth"}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:21:46 GMT +recorded_with: VCR 5.0.0 diff --git a/test/cassettes/list_channels.yml b/test/cassettes/list_channels.yml new file mode 100644 index 00000000..50921cea --- /dev/null +++ b/test/cassettes/list_channels.yml @@ -0,0 +1,81 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/channels.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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '592' + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:21:47 GMT + Server: + - Apache + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - 8a2a8a28-889c-4c6f-a2f5-a1a9daf3d5e8 + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write:bot + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - channels:read + Vary: + - Accept-Encoding + Pragma: + - no-cache + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-neww + X-Cache: + - Miss from cloudfront + Via: + - 1.1 91ba452fa0dd14b0102b6441c9a2d2d4.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - zDLtGX8YJXfKMEWkMAWcYzJ0xi_azXHr3UWgx5hhjFOV7kc0W53zHg== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"CN5RT17J8","name":"random","is_channel":true,"created":1568073362,"is_archived":false,"is_general":false,"unlinked":0,"creator":"UMURTAYP5","name_normalized":"random","is_shared":false,"is_org_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"members":["UMURTAYP5","UN863PN23"],"topic":{"value":"Non-work + banter and water cooler conversation","creator":"UMURTAYP5","last_set":1568073362},"purpose":{"value":"A + place for non-work-related flimflam, faffing, hodge-podge or jibber-jabber + you''d prefer to keep out of more focused work-related channels.","creator":"UMURTAYP5","last_set":1568073362},"previous_names":[],"num_members":2},{"id":"CN862L6AK","name":"general","is_channel":true,"created":1568073362,"is_archived":false,"is_general":true,"unlinked":0,"creator":"UMURTAYP5","name_normalized":"general","is_shared":false,"is_org_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"members":["UMURTAYP5","UN863PN23"],"topic":{"value":"Company-wide + announcements and work-based matters","creator":"UMURTAYP5","last_set":1568073362},"purpose":{"value":"This + channel is for workspace-wide communication and announcements. All members + are in this channel.","creator":"UMURTAYP5","last_set":1568073362},"previous_names":[],"num_members":2},{"id":"CN862LB8F","name":"awesome-slack-cli-design-activity","is_channel":true,"created":1568073362,"is_archived":false,"is_general":false,"unlinked":0,"creator":"UMURTAYP5","name_normalized":"awesome-slack-cli-design-activity","is_shared":false,"is_org_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"members":["UMURTAYP5","UN863PN23"],"topic":{"value":"Discussing + the amazing things that are happening here.","creator":"UMURTAYP5","last_set":1568094901},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:21:47 GMT +recorded_with: VCR 5.0.0 diff --git a/test/cassettes/list_users.yml b/test/cassettes/list_users.yml new file mode 100644 index 00000000..9a9ca03f --- /dev/null +++ b/test/cassettes/list_users.yml @@ -0,0 +1,78 @@ +--- +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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '932' + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:21:45 GMT + Server: + - Apache + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - '0785ff3e-c56f-4f9c-ac9a-8306bf035b4c' + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write:bot + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - users:read + Vary: + - Accept-Encoding + Pragma: + - no-cache + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-tucf + X-Cache: + - Miss from cloudfront + Via: + - 1.1 2efa65d04af0269ba633652ff413a9f3.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - Cpse8ZoelujVTMVUXoiDAGiLJQuMrEnTeJwBSRjNhdiDqGb1ALg65g== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"TMURTAYBV","name":"slackbot","deleted":false,"color":"757575","real_name":"Slackbot","tz":null,"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":"TMURTAYBV"},"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":"UMURTAYP5","team_id":"TMURTAYBV","name":"juliabouv","deleted":false,"color":"9f69e7","real_name":"Julia + Bouvier","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Julia + Bouvier","real_name_normalized":"Julia Bouvier","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"gd5cb54a2a82","first_name":"Julia","last_name":"Bouvier","image_24":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/d5cb54a2a827985e630c7b1a77aec5bd.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0025-512.png","status_text_canonical":"","team":"TMURTAYBV"},"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":1568073742,"has_2fa":false},{"id":"UN863PN23","team_id":"TMURTAYBV","name":"amalh.a97","deleted":false,"color":"4bbe2e","real_name":"Amal","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Amal","real_name_normalized":"Amal","display_name":"Amal","display_name_normalized":"Amal","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g1bf8487fb4a","image_24":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/1bf8487fb4a2755ba217af6ed776cbce.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2F80588%2Fimg%2Favatars%2Fuser_shapes%2Fava_0011-512.png","status_text_canonical":"","team":"TMURTAYBV"},"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":1568073520,"has_2fa":false}],"cache_ts":1568409705,"response_metadata":{"next_cursor":""}}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:21:45 GMT +recorded_with: VCR 5.0.0 diff --git a/test/cassettes/send_slack_message.yml b/test/cassettes/send_slack_message.yml new file mode 100644 index 00000000..64a67936 --- /dev/null +++ b/test/cassettes/send_slack_message.yml @@ -0,0 +1,72 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=&channel=general&text=This%20is%20a%20message + headers: + Content-Type: + - application/x-www-form-urlencoded + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:23:18 GMT + Server: + - Apache + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - 31b4a7ec-cf38-4ae7-ad98-c2ffa27947b4 + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write:bot + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write:bot + Vary: + - Accept-Encoding + Pragma: + - no-cache + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-z6bk + X-Cache: + - Miss from cloudfront + Via: + - 1.1 08905871043ac5aeb0ec57f59d339cc4.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - YAANzacO1Sg5OE3ZAyH_R4gfwJ3SxJNkqaiVpEWMomdMf4-iSFewNw== + body: + encoding: UTF-8 + string: '{"ok":true,"channel":"CN862L6AK","ts":"1568409798.000200","message":{"type":"message","subtype":"bot_message","text":"This + is a message","ts":"1568409798.000200","username":"Branches - Julia B. - API + Project","bot_id":"BN7EKDCGY"}}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:23:18 GMT +recorded_with: VCR 5.0.0 diff --git a/test/cassettes/send_slack_message_error.yml b/test/cassettes/send_slack_message_error.yml new file mode 100644 index 00000000..61d25a4a --- /dev/null +++ b/test/cassettes/send_slack_message_error.yml @@ -0,0 +1,70 @@ +--- +http_interactions: +- request: + method: post + uri: https://slack.com/api/chat.postMessage + body: + encoding: UTF-8 + string: token=&channel=general&text= + headers: + Content-Type: + - application/x-www-form-urlencoded + response: + status: + code: 200 + message: OK + headers: + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Date: + - Fri, 13 Sep 2019 21:23:19 GMT + Server: + - Apache + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - 2d2f86a8-2fe8-493b-a451-230e296251cd + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write:bot + Expires: + - Mon, 26 Jul 1997 05:00:00 GMT + Cache-Control: + - private, no-cache, no-store, must-revalidate + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Xss-Protection: + - '0' + X-Accepted-Oauth-Scopes: + - chat:write:bot + Vary: + - Accept-Encoding + Pragma: + - no-cache + Access-Control-Allow-Headers: + - slack-route, x-slack-version-ts + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-fdpw + X-Cache: + - Miss from cloudfront + Via: + - 1.1 5e247ae48d5501e7c1be84d6fd290885.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - BOS50-C1 + X-Amz-Cf-Id: + - a5aNOoeszOcT9rDDxT3YXZBZLq9rM4zIp8jGNm5pOa5fBJkbBW3L-g== + body: + encoding: UTF-8 + string: '{"ok":false,"error":"no_text"}' + http_version: + recorded_at: Fri, 13 Sep 2019 21:23:19 GMT +recorded_with: VCR 5.0.0 diff --git a/test/channel_test.rb b/test/channel_test.rb new file mode 100644 index 00000000..2cf862a2 --- /dev/null +++ b/test/channel_test.rb @@ -0,0 +1,89 @@ +require_relative "test_helper" + +describe "Channel" do + before do + @channel = Channel.new(topic: "cool_things", member_count: 5, slack_id: "4321", name: "ThisIsAPlace") + end + describe "#initialize" do + it "creates instance of Channel" do + VCR.use_cassette("initialize_channel") do + expect(@channel).must_be_kind_of Channel + end + end + + it "responds to variable names" do + VCR.use_cassette("initialize_channel") do + [:topic, :member_count, :slack_id, :name].each do |variable| + expect(@channel).must_respond_to variable + end + end + end + + it "creates accurate attributes" do + VCR.use_cassette("initialize_channel") do + expect(@channel.topic).must_be_kind_of String + expect(@channel.topic).must_equal "cool_things" + + expect(@channel.member_count).must_be_kind_of Integer + expect(@channel.member_count).must_equal 5 + + expect(@channel.slack_id).must_be_kind_of String + expect(@channel.slack_id).must_equal "4321" + + expect(@channel.name).must_be_kind_of String + expect(@channel.name).must_equal "ThisIsAPlace" + end + end + end + + describe "#details" do + it "must return something" do + expect (@channel.details).wont_be_nil + end + + it "must return accurate info" do + expect (@channel.details).must_include "cool_things" + expect (@channel.details).must_include "5" + expect (@channel.details).must_include "4321" + expect (@channel.details).must_include "ThisIsAPlace" + end + end + + describe "list method" do + it "self.list returns an array of Channels" do + VCR.use_cassette("list_channels") do + results = Channel.list + expect(results).must_be_instance_of Array + results.each do |result| + expect(result).must_be_instance_of Channel + end + end + end + + it "returns accurate information" do + VCR.use_cassette("list_channels") do + results = Channel.list + + info = [ + {slack_id: "CN5RT17J8", name: "random", topic: "Non-work banter and water cooler conversation", member_count: 2}, + {slack_id: "CN862L6AK", name: "general", topic: "Company-wide announcements and work-based matters", member_count: 2}, + {slack_id: "CN862LB8F", name: "awesome-slack-cli-design-activity", topic: "Discussing the amazing things that are happening here.", member_count: 2}, + ] + + results.each_with_index do |result, index| + expect(result.slack_id).must_be_kind_of String + expect(result.slack_id).must_equal info[index][:slack_id] + + expect(result.name).must_be_kind_of String + expect(result.name).must_equal info[index][:name] + + expect(result.topic).must_be_kind_of String + expect(result.topic).must_equal info[index][:topic] + + expect(result.member_count).must_be_kind_of Integer + expect(result.member_count).must_equal info[index][:member_count] + end + end + end + end +end diff --git a/test/recipient_test.rb b/test/recipient_test.rb new file mode 100644 index 00000000..db3ed97a --- /dev/null +++ b/test/recipient_test.rb @@ -0,0 +1,65 @@ +require_relative "test_helper" + + +describe "Recipient" do + before do + @recipient = Recipient.new(slack_id: "thisisanid", name: "thisisaname") + end + describe "#initialize" do + it "creates instance of Recipient" do + VCR.use_cassette("initialize_recipient") do + expect(@recipient).must_be_kind_of Recipient + end + end + + it "responds to variable names" do + VCR.use_cassette("initialize_recipient") do + [:slack_id, :name].each do |variable| + expect(@recipient).must_respond_to variable + end + end + end + + it "creates accurate attributes" do + VCR.use_cassette("initialize_recipient") do + expect(@recipient.slack_id).must_be_kind_of String + expect(@recipient.slack_id).must_equal "thisisanid" + + expect(@recipient.name).must_be_kind_of String + expect(@recipient.name).must_equal "thisisaname" + + end + end + end + + describe "get" do + it "response is not nil" do + VCR.use_cassette("get_recipient_api") do + response = Recipient.get("https://slack.com/api/users.list", ENV["SLACK_TOKEN"]) + expect(response).wont_be_nil + end + end + + it "raises exception if there is an error in API response" do + VCR.use_cassette("get_recipient_api_error") do + expect { Recipient.get("https://slack.com/api/users.list", "bad_token") }.must_raise SlackApiError + end + end + end + + describe "#details" do + it "raises NotImplementedError" do + VCR.use_cassette("recipient_details_error") do + expect{ @recipient.details }.must_raise NotImplementedError + end + end + end + + describe "list" do + it "raises NotImplementedError" do + VCR.use_cassette("recipient_list_error") do + expect{ Recipient.list }.must_raise NotImplementedError + end + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 90aeb408..7a9d058c 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -2,16 +2,33 @@ SimpleCov.start do add_filter 'test/' end +require "dotenv" +Dotenv.load require 'minitest' require 'minitest/autorun' require 'minitest/reporters' require 'minitest/skip_dsl' require 'vcr' +require 'webmock/minitest' +require 'httparty' + +require_relative '../lib/slack_api_error' +require_relative '../lib/recipient' +require_relative '../lib/channel' +require_relative '../lib/user' +require_relative '../lib/workspace' Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new VCR.configure do |config| config.cassette_library_dir = "test/cassettes" config.hook_into :webmock + + # Don't leave our token lying around in a cassette file. + config.filter_sensitive_data("") do + ENV["SLACK_TOKEN"] + end end + + diff --git a/test/user_test.rb b/test/user_test.rb new file mode 100644 index 00000000..e8be1b13 --- /dev/null +++ b/test/user_test.rb @@ -0,0 +1,83 @@ +require_relative "test_helper" + +describe "User" do + before do + @user = User.new(real_name: "Bob", slack_id: "1234", name: "Bobiscool") + end + describe "initialize" do + it "creates instance of User" do + VCR.use_cassette("initialize_user") do + expect(@user).must_be_kind_of User + end + end + + it "responds to variable names" do + VCR.use_cassette("initialize_user") do + [:real_name, :slack_id, :name].each do |variable| + expect(@user).must_respond_to variable + end + end + end + + it "creates accurate attributes" do + VCR.use_cassette("initialize_user") do + expect(@user.real_name).must_be_kind_of String + expect(@user.real_name).must_equal "Bob" + + expect(@user.name).must_be_kind_of String + expect(@user.name).must_equal "Bobiscool" + + expect(@user.slack_id).must_be_kind_of String + expect(@user.slack_id).must_equal "1234" + end + end + end + + describe "#details" do + it "must return something" do + expect (@user.details).wont_be_nil + end + + it "must return accurate info" do + expect (@user.details).must_include "Bob" + expect (@user.details).must_include "1234" + expect (@user.details).must_include "Bobiscool" + end + end + + describe "list method" do + it "self.list returns an array of users" do + VCR.use_cassette("list_users") do + results = User.list + expect(results).must_be_instance_of Array + results.each do |result| + expect(result).must_be_instance_of User + + end + end + end + + it "returns accurate information" do + VCR.use_cassette("list_users") do + results = User.list + + info = [ + {slack_id: "USLACKBOT", name: "slackbot", real_name: "Slackbot"}, + {slack_id: "UMURTAYP5", name:"juliabouv", real_name:"Julia Bouvier"}, + {slack_id:"UN863PN23", name:"amalh.a97", real_name:"Amal"} + ] + + results.each_with_index do |result, index| + expect(result.slack_id).must_be_kind_of String + expect(result.slack_id).must_equal info[index][:slack_id] + + expect(result.name).must_be_kind_of String + expect(result.name).must_equal info[index][:name] + + expect(result.real_name).must_be_kind_of String + expect(result.real_name).must_equal info[index][:real_name] + end + end + end + end +end diff --git a/test/workspace_test.rb b/test/workspace_test.rb new file mode 100644 index 00000000..dd54b820 --- /dev/null +++ b/test/workspace_test.rb @@ -0,0 +1,140 @@ +require_relative "test_helper" +describe "Workspace" do + before do + VCR.use_cassette("construct_workspace") do + @workspace = Workspace.new + end + end + + describe "#initialize" do + it "creates instance of Workspace" do + expect(@workspace).must_be_kind_of Workspace + end + + it "responds to variable names" do + [:users, :channels, :selected].each do |variable| + expect(@workspace).must_respond_to variable + end + end + + it "creates accurate attributes" do + expect(@workspace.users).must_be_kind_of Array + @workspace.users.each do |user| + expect(user).must_be_instance_of User + end + + expect(@workspace.channels).must_be_kind_of Array + @workspace.channels.each do |channel| + expect(channel).must_be_instance_of Channel + end + + expect(@workspace.selected).must_be_nil + end + end + + describe "#select_channel" do + it "returns instance of Channel when name is provided" do + expect(@workspace.select_channel(input: "random")).must_be_instance_of Channel + end + + it "returns instance of Channel when id is provided" do + expect(@workspace.select_channel(input: "CN5RT17J8")).must_be_instance_of Channel + end + + it "assigns instance of User to @selected" do + expect(@workspace.selected).must_be_nil + @workspace.select_channel(input: "random") + + expect(@workspace.selected).must_be_instance_of Channel + expect(@workspace.selected.name).must_equal "random" + expect(@workspace.selected.topic).must_equal "Non-work banter and water cooler conversation" + expect(@workspace.selected.member_count).must_equal 2 + expect(@workspace.selected.slack_id).must_equal "CN5RT17J8" + end + + it "returns nil if no valid name or id provided" do + expect(@workspace.select_channel).must_be_nil + end + end + + describe "#select_user" do + it "returns instance of User when name is provided" do + expect(@workspace.select_user(input: "slackbot")).must_be_instance_of User + end + + it "returns instance of User when id is provided" do + expect(@workspace.select_user(input: "USLACKBOT")).must_be_instance_of User + end + + it "returns instance of User when name is provided" do + expect(@workspace.selected).must_be_nil + @workspace.select_user(input: "slackbot") + + expect(@workspace.selected).must_be_instance_of User + expect(@workspace.selected.name).must_equal "slackbot" + expect(@workspace.selected.real_name).must_equal "Slackbot" + expect(@workspace.selected.slack_id).must_equal "USLACKBOT" + end + + it "returns nil if no name or id provided" do + expect(@workspace.select_user).must_be_nil + end + end + + describe "#show_details" do + it "returns details if @selected is user" do + @workspace.select_user(input: "slackbot") + + expect(@workspace.show_details).wont_be_nil + expect(@workspace.show_details).must_include "slackbot" + expect(@workspace.show_details).must_include "Slackbot" + expect(@workspace.show_details).must_include "USLACKBOT" + + @workspace.select_user(input: "USLACKBOT") + + expect(@workspace.show_details).wont_be_nil + expect(@workspace.show_details).must_include "slackbot" + expect(@workspace.show_details).must_include "Slackbot" + expect(@workspace.show_details).must_include "USLACKBOT" + end + + it "returns details if @selected is channel" do + @workspace.select_channel(input: "random") + + expect(@workspace.show_details).wont_be_nil + expect(@workspace.show_details).must_include "random" + expect(@workspace.show_details).must_include "CN5RT17J8" + expect(@workspace.show_details).must_include "2" + expect(@workspace.show_details).must_include "Non-work banter and water cooler conversation" + + @workspace.select_channel(input: "CN5RT17J8") + + expect(@workspace.show_details).wont_be_nil + expect(@workspace.show_details).must_include "random" + expect(@workspace.show_details).must_include "CN5RT17J8" + expect(@workspace.show_details).must_include "2" + expect(@workspace.show_details).must_include "Non-work banter and water cooler conversation" + end + + it "returns nil if nothing is @selected" do + expect(@workspace.show_details).must_be_nil + end + end + + describe "#send_message" do + it "can send a valid message" do + VCR.use_cassette("send_slack_message") do + response = @workspace.send_message("This is a message", "general") + + expect(response).wont_be_nil + expect(response["ok"]).must_equal true + end + end + + it "raises exception if there is an error in API response" do + VCR.use_cassette("send_slack_message_error") do + expect { @workspace.send_message("", "general") }.must_raise SlackApiError + end + end + end +end