diff --git a/.gitignore b/.gitignore index 3ff4fada..8f571b1e 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ # Ignore environemnt variables .env +.bot-settings.json diff --git a/lib/channel.rb b/lib/channel.rb new file mode 100644 index 00000000..61c4933d --- /dev/null +++ b/lib/channel.rb @@ -0,0 +1,33 @@ +require "httparty" +require "dotenv" +require 'json' +require_relative "recipient" + +Dotenv.load + + +class Channel < Recipient + + attr_reader :topic, :memeber_count + + def initialize(topic:, memeber_count:, name:, slack_id:) + super(slack_id: slack_id, name: name) + @topic = topic + @memeber_count = memeber_count + end + + def self.list_all + data = Channel.get("https://slack.com/api/conversations.list") + + channels = [] + + data["channels"].each do |channel| + channels << Channel.new( + name: channel["name"], + slack_id: channel["id"], + topic: channel["topic"]["value"], + memeber_count: channel["num_members"]) + end + return channels + end +end \ No newline at end of file diff --git a/lib/recipient.rb b/lib/recipient.rb new file mode 100644 index 00000000..2fa48099 --- /dev/null +++ b/lib/recipient.rb @@ -0,0 +1,75 @@ +require "httparty" +require "dotenv" + + +Dotenv.load + +BASE_URL = "https://slack.com/api/" +API_KEY = ENV["SLACK_API_TOKEN"] +USER_URL = "#{BASE_URL}/users.list" +CHANNEL_URL = "#{BASE_URL}/conversations.list" + + +class Recipient + +attr_reader :slack_id, :name + + def initialize(slack_id:, name:) + @slack_id = slack_id + @name = name + end + + + def details + raise NotImplementedError, "Define this method in a child class" + end + + def self.get(url) + data = HTTParty.get(url, query: { token: ENV["SLACK_API_TOKEN"]}) + + #check for errors + if data.code != 200 || data["ok"] == false + raise SlackAPIError, "We encounter a problem: #{data["error"]}" + end + + return data + end + + def self.list_all + raise NotImplementedError, "Define this method in a child class" + end + + def send_message(message) + HTTParty.post("https://slack.com/api/chat.postMessage", query: { + token: ENV["SLACK_API_TOKEN"], + channel: self.slack_id, + text: message + } + ) + end + + def set_user_profile_name(name, emoji) + query = { + token: ENV["SLACK_API_TOKEN"], + profile: {display_name: name, status_emoji: emoji}.to_json, + user: self.slack_id, + } + + response = HTTParty.post("https://slack.com/api/users.profile.set?", query: query) + + #Optional - + #When I change these settings, the program should save them in the JSON format in a file named bot-settings.json. + #When I restart the program, it should reload those settings. + File.open("./.bot-settings.json", "w") do |name| + name.write(query.to_json) + end + + return response + end +end + + + + +class SlackAPIError < Exception +end \ No newline at end of file diff --git a/lib/slack.rb b/lib/slack.rb index 8a0b659b..aed278c6 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,12 +1,112 @@ #!/usr/bin/env ruby +require 'table_print' +require "dotenv" +require "httparty" +require "colorize" + +require_relative './workspace' + +Dotenv.load def main - puts "Welcome to the Ada Slack CLI!" - workspace = Workspace.new + workspace = Workspace.new + puts "\n" + puts "Welcome to the Ada Slack CLI! \n This Slack workspace currently has #{workspace.users.count} users and #{workspace.channels.count} channels." + + user_input = prompt_for_input + + until user_input == "quit" || user_input == "exit" + + case user_input + when "list users" + tp workspace.users, "slack_id", "name", "real_name", "status_emoji" + puts "\n" + + when "list channels" + tp workspace.channels, "name", "topic", "memeber_count", "slack_id" + puts "\n" + + when "select user" + print "Please enter the user name or ID: ".bold + user_name = gets.chomp.to_s + workspace.select_user(user_name) + puts "\n" + + when "select channel" + print "\n Please enter the channel name or ID: ".bold + channel_name = gets.chomp.to_s + workspace.select_channel(channel_name) + puts "\n" + + when "details" + if workspace.selected == "" + puts "\nYou haven't selected a user or channel!!! Try again!".bold + puts "\n" + else + workspace.show_details + user_input = nil + puts "\n" + end + + when "send message" + if workspace.selected == "" + puts "\nYou haven't selected a user or channel!!! Try again!".bold + puts "\n" + else + print "Please enter your message: " + message = gets.chomp.to_s + workspace.send_message(message) + if workspace.send_message(message) + puts "Your message is sent".blue.bold + else + puts "Something is not right.... message is not sent!".blue.bold + end + puts "\n" + end + + #Optional - can change global settings for the program include the username for the bot and an emoji to use as an icon + + when "update user profile setting" + if workspace.selected.class != User + puts "\nYou would need to select your own user id first, maybe try again?".bold + puts "\n" + else + print "\n enter the name that you would like to change your profile name to:".bold + new_name = gets.chomp.to_s + + print "\n enter the emoji you would like to use" + new_emoji = gets.chomp.to_s + workspace.set_profile_setting(new_name, new_emoji) + if workspace.set_profile_setting(new_name, new_emoji) + puts "\n Your profile has been successfully updated!".blue + else + puts "\n It didn't go thru, you might not be authorized to change their profile. Sorry :(".cyan.on_blue.bold + end + end - # TODO project + else + puts "Sorry, I didn't understand your request. Please try again.".yellow.bold + puts "\n" + end - puts "Thank you for using the Ada Slack CLI" + user_input = prompt_for_input + end + + + puts "Thank you for using the ADA Slack CLI!" + puts "\n" +end + +def prompt_for_input + print "Please choose an option: \n - list users \n - list channels \n - select user \n - select channel \n - details \n - send message \n - update user profile setting \nor quit \n" + puts "--------------------------------------------" + return gets.chomp.downcase end -main if __FILE__ == $PROGRAM_NAME \ No newline at end of file + +main if __FILE__ == $PROGRAM_NAME + + + +#As a user, I can see a history of messages sent to the currently selected recipient. +# If I change recipients, the message list should also change \ No newline at end of file diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 00000000..7e7ee3f6 --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,44 @@ +require "httparty" +require "dotenv" +require 'json' +require_relative "recipient" + +Dotenv.load + +class User < Recipient + + attr_reader :real_name, :status_text, :status_emoji + + def initialize(real_name: , status_text: , status_emoji: , name: , slack_id: ) + super(slack_id: slack_id, name: name) + + @real_name = real_name + @status_text = status_text + @status_emoji = status_emoji + + end + + def detail + tp self, "slack_id", "name", "real_name","status_emoji" + end + + def self.list_all + data = User.get("https://slack.com/api/users.list") + index = 0 + + users = [] + + data["members"].each do |user| + users << User.new( + name: user["name"], + slack_id: user["id"], + real_name: user["real_name"], + status_text: user["profile"]["status_text"], + status_emoji: user["profile"]["status_emoji"]) + end + return users + + end + +end + diff --git a/lib/workspace.rb b/lib/workspace.rb new file mode 100644 index 00000000..6b34d1fb --- /dev/null +++ b/lib/workspace.rb @@ -0,0 +1,71 @@ +require "httparty" +require "dotenv" +require_relative "user" +require_relative "channel" +require 'table_print' + +Dotenv.load + +class Workspace + + attr_reader :channels, :users, :selected + + def initialize + @channels = Channel.list_all + @users = User.list_all + @selected = "" + end + + def select_channel(channel_name) + @channels.each do |channel| + if channel.name == channel_name || channel.slack_id == channel_name + @selected = channel + puts "\n You have selected #{channel.name}" + break + else + @selected = nil + end + end + if @selected == nil + puts "The channel you just entered is not valid!!" + end + end + + def select_user(user_name) + @users.each do |user| + if user.real_name == user_name || user.slack_id == user_name || user.name == user_name + @selected = user + puts "\n You have selected #{user.real_name}" + break + else + @selected = nil + end + end + + if @selected == nil + puts "The user you just entered is not valid!!!" + end + end + + def show_details + if @selected.class == Channel + return tp @selected, "name", "topic", "memeber_count", "slack_id" + puts "\n" + elsif + @selected.class == User + return tp @selected, "slack_id", "name", "real_name","status_emoji" + puts "\n" + end + end + + def send_message(message) + response = @selected.send_message(message) + return response.code == 200 && response.parsed_response["ok"] + end + + def set_profile_setting(name, emoji) + response = @selected.set_user_profile_name(name, emoji) + return response.code == 200 && response.parsed_response["ok"] + end + +end \ No newline at end of file diff --git a/test/cassettes/channel-list-endpoint.yml b/test/cassettes/channel-list-endpoint.yml new file mode 100644 index 00000000..51d47d6b --- /dev/null +++ b/test/cassettes/channel-list-endpoint.yml @@ -0,0 +1,148 @@ +--- +http_interactions: +- request: + method: get + uri: https://slack.com/api/bogus.endpoint?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: + - '80' + Connection: + - keep-alive + Date: + - Mon, 16 Mar 2020 04:43:36 GMT + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + 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 + Referrer-Policy: + - no-referrer + X-Slack-Backend: + - h + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Vary: + - Accept-Encoding + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - aefd942b540d1ebfd300982c6ed00b55 + X-Xss-Protection: + - '0' + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-ffos + X-Cache: + - Miss from cloudfront + Via: + - 1.1 caf6806821bc479b28a6f1ce3043b8a6.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - SEA19-C2 + X-Amz-Cf-Id: + - "-JAjFakDF0XSTwrxnf7j5F60l5-zE8ZINHCfsL7RtAo-zArXemHtJg==" + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"unknown_method","req_method":"bogus.endpoint"}' + http_version: null + recorded_at: Mon, 16 Mar 2020 04:43:36 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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '646' + Connection: + - keep-alive + Date: + - Mon, 16 Mar 2020 04:43:36 GMT + Server: + - Apache + X-Slack-Req-Id: + - d78a8cfef68b064cb8b1b57ccf04bcc5 + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + 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' + Vary: + - Accept-Encoding + Pragma: + - no-cache + 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 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-69ma + X-Cache: + - Miss from cloudfront + Via: + - 1.1 2bedbeaa49b4a77447d30097858cb81a.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - SEA19-C2 + X-Amz-Cf-Id: + - oV1N-J8QQAIYXuE99oZ-rDBPOk1CsBhaUs3aorGovXy725UsOJV7lg== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"CRNUDTRQS","name":"everything","is_channel":true,"is_group":false,"is_im":false,"created":1577251090,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"everything","is_shared":false,"parent_conversation":null,"creator":"US1N1DHGQ","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["TS3HWCGMD"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"Everything + but work!","creator":"US3U562F8","last_set":1584078931},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":2},{"id":"CRQ896WKD","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1577251089,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"US1N1DHGQ","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["TS3HWCGMD"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"Company-wide + announcements and work-based matters","creator":"US1N1DHGQ","last_set":1577251089},"purpose":{"value":"This + channel is for workspace-wide communication and announcements. All members + are in this channel.","creator":"US1N1DHGQ","last_set":1577251089},"previous_names":[],"num_members":2},{"id":"CS3U4UHC6","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1577251089,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"US1N1DHGQ","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["TS3HWCGMD"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"Non-work + banter and water cooler conversation","creator":"US1N1DHGQ","last_set":1577251089},"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":"US1N1DHGQ","last_set":1577251089},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + http_version: null + recorded_at: Mon, 16 Mar 2020 04:43:36 GMT +recorded_with: VCR 5.1.0 diff --git a/test/cassettes/create_workspace.yml b/test/cassettes/create_workspace.yml new file mode 100644 index 00000000..75637a2d --- /dev/null +++ b/test/cassettes/create_workspace.yml @@ -0,0 +1,240 @@ +--- +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: + Content-Type: + - application/json; charset=utf-8 + Content-Length: + - '646' + Connection: + - keep-alive + Date: + - Thu, 26 Mar 2020 07:13:23 GMT + Server: + - Apache + X-Slack-Req-Id: + - b4e55dca2b20176220686bd981d1cc7b + X-Oauth-Scopes: + - identify,channels:history,groups:history,im:history,mpim:history,channels:read,users:read,users.profile:read,chat:write,users.profile:write + X-Accepted-Oauth-Scopes: + - channels:read,groups:read,mpim:read,im:read,read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Slack-Backend: + - h + 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' + Vary: + - Accept-Encoding + Pragma: + - no-cache + 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 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-ghzf + X-Cache: + - Miss from cloudfront + Via: + - 1.1 981753271eb5b6d11bc29d52f173a5da.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - SEA19-C2 + X-Amz-Cf-Id: + - L-rmPvdRvhGVcllMTq-fRBSb6__5GlIq8wmMdyQ1tBF_7KuufPKLLQ== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channels":[{"id":"CRNUDTRQS","name":"everything","is_channel":true,"is_group":false,"is_im":false,"created":1577251090,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"everything","is_shared":false,"parent_conversation":null,"creator":"US1N1DHGQ","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["TS3HWCGMD"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"Everything + but work!","creator":"US3U562F8","last_set":1584078931},"purpose":{"value":"","creator":"","last_set":0},"previous_names":[],"num_members":2},{"id":"CRQ896WKD","name":"general","is_channel":true,"is_group":false,"is_im":false,"created":1577251089,"is_archived":false,"is_general":true,"unlinked":0,"name_normalized":"general","is_shared":false,"parent_conversation":null,"creator":"US1N1DHGQ","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["TS3HWCGMD"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"Company-wide + announcements and work-based matters","creator":"US1N1DHGQ","last_set":1577251089},"purpose":{"value":"This + channel is for workspace-wide communication and announcements. All members + are in this channel.","creator":"US1N1DHGQ","last_set":1577251089},"previous_names":[],"num_members":2},{"id":"CS3U4UHC6","name":"random","is_channel":true,"is_group":false,"is_im":false,"created":1577251089,"is_archived":false,"is_general":false,"unlinked":0,"name_normalized":"random","is_shared":false,"parent_conversation":null,"creator":"US1N1DHGQ","is_ext_shared":false,"is_org_shared":false,"shared_team_ids":["TS3HWCGMD"],"pending_shared":[],"pending_connected_team_ids":[],"is_pending_ext_shared":false,"is_member":true,"is_private":false,"is_mpim":false,"topic":{"value":"Non-work + banter and water cooler conversation","creator":"US1N1DHGQ","last_set":1577251089},"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":"US1N1DHGQ","last_set":1577251089},"previous_names":[],"num_members":2}],"response_metadata":{"next_cursor":""}}' + http_version: null + recorded_at: Thu, 26 Mar 2020 07:13:23 GMT +- 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: + - '1337' + Connection: + - keep-alive + Date: + - Thu, 26 Mar 2020 07:13:23 GMT + Server: + - Apache + X-Slack-Req-Id: + - bd123418a48da77e0d3815020905e2b9 + X-Oauth-Scopes: + - identify,channels:history,groups:history,im:history,mpim:history,channels:read,users:read,users.profile:read,chat:write,users.profile:write + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Slack-Backend: + - h + 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' + Vary: + - Accept-Encoding + Pragma: + - no-cache + 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 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-xy1y + X-Cache: + - Miss from cloudfront + Via: + - 1.1 3cd7af07832481c336aa1c93c9b4a6fe.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - SEA19-C2 + X-Amz-Cf-Id: + - "-Q0HppknvPFixjj0n0k6EfSmC72Ev1URtYcP0D6Fu4X3N6nao6kw7w==" + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"TS3HWCGMD","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":"TS3HWCGMD"},"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":"US1N1DHGQ","team_id":"TS3HWCGMD","name":"nguyen.josephduy","deleted":false,"color":"9f69e7","real_name":"Joseph","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Joseph","real_name_normalized":"Joseph","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"ge6083656f20","first_name":"Joseph","last_name":"","image_24":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-512.png","status_text_canonical":"","team":"TS3HWCGMD"},"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":1585183050},{"id":"US3U562F8","team_id":"TS3HWCGMD","name":"keikei1128","deleted":false,"color":"4bbe2e","real_name":"Sharon + Cheung","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Sharon + Cheung","real_name_normalized":"Sharon Cheung","display_name":"Sharon Cheung","display_name_normalized":"Sharon + Cheung","status_text":"","status_emoji":":poop:","status_expiration":0,"avatar_hash":"c2c34f19a48a","image_original":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_original.jpg","is_custom_image":true,"first_name":"Sharon","last_name":"Cheung","image_24":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_72.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_192.jpg","image_512":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_512.jpg","image_1024":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_1024.jpg","status_text_canonical":"","team":"TS3HWCGMD"},"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":1585206599,"has_2fa":false},{"id":"U01031BGYK0","team_id":"TS3HWCGMD","name":"oscarapi","deleted":false,"color":"e7392d","real_name":"API + BOT","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"API + BOT","real_name_normalized":"API BOT","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9a00fb2c827","api_app_id":"AUVV4G666","always_active":true,"bot_id":"BV21DTJN6","first_name":"API","last_name":"BOT","image_24":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-512.png","status_text_canonical":"","team":"TS3HWCGMD"},"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":1584234381},{"id":"U010D85RKS8","team_id":"TS3HWCGMD","name":"zoom","deleted":false,"color":"3c989f","real_name":"Zoom","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Zoom","real_name_normalized":"Zoom","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"39a23abf8aa7","api_app_id":"A5GE9BMQC","always_active":true,"image_original":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_original.png","is_custom_image":true,"bot_id":"B010D85RJR2","image_24":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_24.png","image_32":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_32.png","image_48":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_48.png","image_72":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_72.png","image_192":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_192.png","image_512":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_512.png","image_1024":"https:\/\/avatars.slack-edge.com\/2020-03-19\/1002265608835_39a23abf8aa77bba1416_1024.png","status_text_canonical":"","team":"TS3HWCGMD"},"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":1584675234}],"cache_ts":1585206803,"response_metadata":{"next_cursor":""}}' + http_version: null + recorded_at: Thu, 26 Mar 2020 07:13:23 GMT +- request: + method: post + uri: https://slack.com/api/chat.postMessage?channel=US1N1DHGQ&text=Hello&token= + body: + encoding: UTF-8 + 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: + - '319' + Connection: + - keep-alive + Date: + - Thu, 26 Mar 2020 07:13:24 GMT + Server: + - Apache + X-Slack-Req-Id: + - 361fac5d18c732b1035b3bcd69875fe6 + X-Oauth-Scopes: + - identify,channels:history,groups:history,im:history,mpim:history,channels:read,users:read,users.profile:read,chat:write,users.profile:write + X-Accepted-Oauth-Scopes: + - chat:write + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Slack-Backend: + - h + 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' + Vary: + - Accept-Encoding + Pragma: + - no-cache + 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 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-ff5q + X-Cache: + - Miss from cloudfront + Via: + - 1.1 981753271eb5b6d11bc29d52f173a5da.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - SEA19-C2 + X-Amz-Cf-Id: + - K5gDJnfhuHBFWBcDxia3QHM-dAmctvX2ult5iDAMSzymNArWZu4Uug== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"channel":"DRRETUX17","ts":"1585206804.065100","message":{"bot_id":"BUYLK8X8R","type":"message","text":"Hello","user":"US3U562F8","ts":"1585206804.065100","team":"TS3HWCGMD","bot_profile":{"id":"BUYLK8X8R","deleted":false,"name":"OSCAR-API","updated":1583963468,"app_id":"AUVV4G666","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":"TS3HWCGMD"}}}' + http_version: null + recorded_at: Thu, 26 Mar 2020 07:13:24 GMT +recorded_with: VCR 5.1.0 diff --git a/test/cassettes/users-list-endpoint.yml b/test/cassettes/users-list-endpoint.yml new file mode 100644 index 00000000..e4e52605 --- /dev/null +++ b/test/cassettes/users-list-endpoint.yml @@ -0,0 +1,147 @@ +--- +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: + - '1159' + Connection: + - keep-alive + Date: + - Mon, 16 Mar 2020 04:43:56 GMT + Server: + - Apache + X-Slack-Req-Id: + - f4bd2f948d70f0fd247ef383c2d738ed + X-Oauth-Scopes: + - identify,channels:read,users:read,chat:write + X-Accepted-Oauth-Scopes: + - users:read + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + X-Slack-Backend: + - h + 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' + Vary: + - Accept-Encoding + Pragma: + - no-cache + 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 + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + Referrer-Policy: + - no-referrer + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-9k48 + X-Cache: + - Miss from cloudfront + Via: + - 1.1 591683988172c7980c4ebb318cbf18a9.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - SEA19-C2 + X-Amz-Cf-Id: + - ileyoua5VRzPsefMq1RhuhvJUdO4wYHdk821eC74vf4lkeAEmAz57A== + body: + encoding: ASCII-8BIT + string: '{"ok":true,"members":[{"id":"USLACKBOT","team_id":"TS3HWCGMD","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":"TS3HWCGMD"},"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":"US1N1DHGQ","team_id":"TS3HWCGMD","name":"nguyen.josephduy","deleted":false,"color":"9f69e7","real_name":"Joseph","tz":"America\/Los_Angeles","tz_label":"Pacific + Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Joseph","real_name_normalized":"Joseph","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"ge6083656f20","first_name":"Joseph","last_name":"","image_24":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/e6083656f2077a422235fefbd53c4f55.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0001-512.png","status_text_canonical":"","team":"TS3HWCGMD"},"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":1584071583},{"id":"US3U562F8","team_id":"TS3HWCGMD","name":"keikei1128","deleted":false,"color":"4bbe2e","real_name":"Sharon + Cheung","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"Sharon + Cheung","real_name_normalized":"Sharon Cheung","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"c2c34f19a48a","image_original":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_original.jpg","is_custom_image":true,"image_24":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_24.jpg","image_32":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_32.jpg","image_48":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_48.jpg","image_72":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_72.jpg","image_192":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_192.jpg","image_512":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_512.jpg","image_1024":"https:\/\/avatars.slack-edge.com\/2020-03-10\/994240739590_c2c34f19a48aa1b5d82d_1024.jpg","status_text_canonical":"","team":"TS3HWCGMD"},"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":1584071583,"has_2fa":false},{"id":"U01031BGYK0","team_id":"TS3HWCGMD","name":"oscarapi","deleted":false,"color":"e7392d","real_name":"API + BOT","tz":"America\/Los_Angeles","tz_label":"Pacific Daylight Time","tz_offset":-25200,"profile":{"title":"","phone":"","skype":"","real_name":"API + BOT","real_name_normalized":"API BOT","display_name":"","display_name_normalized":"","status_text":"","status_emoji":"","status_expiration":0,"avatar_hash":"g9a00fb2c827","api_app_id":"AUVV4G666","always_active":true,"bot_id":"BV21DTJN6","first_name":"API","last_name":"BOT","image_24":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=24&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-24.png","image_32":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=32&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-32.png","image_48":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=48&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-48.png","image_72":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=72&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-72.png","image_192":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=192&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-192.png","image_512":"https:\/\/secure.gravatar.com\/avatar\/9a00fb2c827193a687bdd040cbf63de3.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fdf10d%2Fimg%2Favatars%2Fava_0007-512.png","status_text_canonical":"","team":"TS3HWCGMD"},"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":1584234381}],"cache_ts":1584333836,"response_metadata":{"next_cursor":""}}' + http_version: null + recorded_at: Mon, 16 Mar 2020 04:43:56 GMT +- request: + method: get + uri: https://slack.com/api/bogus.endpoint?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: + - '80' + Connection: + - keep-alive + Date: + - Mon, 16 Mar 2020 04:43:56 GMT + Server: + - Apache + Strict-Transport-Security: + - max-age=31536000; includeSubDomains; preload + 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 + Referrer-Policy: + - no-referrer + X-Slack-Backend: + - h + Access-Control-Expose-Headers: + - x-slack-req-id, retry-after + Vary: + - Accept-Encoding + X-Content-Type-Options: + - nosniff + X-Slack-Req-Id: + - b2f67792aecc7c4abbe6fb43ebffdcb8 + X-Xss-Protection: + - '0' + Access-Control-Allow-Origin: + - "*" + X-Via: + - haproxy-www-huvv + X-Cache: + - Miss from cloudfront + Via: + - 1.1 12a392bc3a7281f8d5d4591bfadc41fc.cloudfront.net (CloudFront) + X-Amz-Cf-Pop: + - SEA19-C2 + X-Amz-Cf-Id: + - 75gcHJdh_cJsJda_KPZZbZh21kyOq-dKAFVE1ZA45eJEu4oSYq2EKw== + body: + encoding: ASCII-8BIT + string: '{"ok":false,"error":"unknown_method","req_method":"bogus.endpoint"}' + http_version: null + recorded_at: Mon, 16 Mar 2020 04:43:56 GMT +recorded_with: VCR 5.1.0 diff --git a/test/channel_test.rb b/test/channel_test.rb new file mode 100644 index 00000000..254c18d2 --- /dev/null +++ b/test/channel_test.rb @@ -0,0 +1,38 @@ +require_relative "test_helper" +require_relative "../lib/channel" + +describe "Channel" do + describe "self.get" do + it "gets a list of channels and returns them as an HTTParty Response" do + result = {} + VCR.use_cassette("channel-list-endpoint") do + result = Channel.get("https://slack.com/api/conversations.list") + end + + expect(result).must_be_kind_of HTTParty::Response + expect(result["ok"]).must_equal true + end + + it "raises an error when a call fails" do + VCR.use_cassette("channel-list-endpoint") do + expect{result = Channel.get("https://slack.com/api/bogus.endpoint")}.must_raise SlackAPIError + end + end + end + + describe "self.list" do + it "return a valid list of the channels" do + result = [] + + VCR.use_cassette("channel-list-endpoint") do + result = Channel.list_all + end + + expect(result).must_be_kind_of Array + expect(result.length).must_be :>, 0 + result.each do |channel| + expect(channel).must_be_kind_of Channel + end + end + end +end \ No newline at end of file diff --git a/test/test_helper.rb b/test/test_helper.rb index 1fcf2bab..088cfa61 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -8,7 +8,7 @@ require 'minitest/reporters' require 'minitest/skip_dsl' require 'vcr' - + Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new VCR.configure do |config| @@ -25,5 +25,12 @@ } # Don't leave our token lying around in a cassette file. + config.filter_sensitive_data("") do + ENV['SLACK_API_TOKEN'] + + end + config.filter_sensitive_data("") do + ENV['BOT_TOKEN'] + end end diff --git a/test/user_test.rb b/test/user_test.rb new file mode 100644 index 00000000..662c29a9 --- /dev/null +++ b/test/user_test.rb @@ -0,0 +1,38 @@ +require_relative "test_helper" +require_relative "../lib/user" + +describe "User" do + describe "self.get" do + it "gets a list of users and returns them as an HTTParty Response" do + result = {} + VCR.use_cassette("users-list-endpoint") do + result = User.get("https://slack.com/api/users.list") + end + + expect(result).must_be_kind_of HTTParty::Response + expect(result["ok"]).must_equal true + end + + it "raises an error when a call fails" do + VCR.use_cassette("users-list-endpoint") do + expect{result = User.get("https://slack.com/api/bogus.endpoint")}.must_raise SlackAPIError + end + end + end + + describe "self.list" do + it "return a valid list of the users" do + result = [] + + VCR.use_cassette("users-list-endpoint") do + result = User.list_all + end + + expect(result).must_be_kind_of Array + expect(result.length).must_be :>, 0 + result.each do |user| + expect(user).must_be_kind_of User + end + end + end +end \ No newline at end of file diff --git a/test/workspace_test.rb b/test/workspace_test.rb new file mode 100644 index 00000000..645769aa --- /dev/null +++ b/test/workspace_test.rb @@ -0,0 +1,148 @@ +require_relative "test_helper" +require_relative '../lib/workspace' + +describe "Workspace" do + describe "Initialize" do + before do + VCR.use_cassette("create_workspace") do + @workspace = Workspace.new + end + end + + it "will create a new Workplace" do + expect(@workspace).must_be_instance_of Workspace + end + + it "will have an array of Channels and Users" do + expect(@workspace.channels).must_be_instance_of Array + expect(@workspace.users).must_be_instance_of Array + end + end + + describe "select_channel(channel_name)" do + before do + VCR.use_cassette("create_workspace")do + @workspace = Workspace.new + end + end + + it "will return an instance of Channel based on the user input" do + @workspace.select_channel("random") + expect(@workspace.selected).must_be_instance_of Channel + expect(@workspace.selected.name).must_equal "random" + end + + it "will return nil if a channel provided isn't valid" do + @workspace.select_channel("nothing found here") + expect(@workspace.selected).must_be_nil + end + + end + + describe "select_channel(channel_name)" do + before do + VCR.use_cassette("create_workspace")do + @workspace = Workspace.new + end + end + + it "will return a Channel based on the user input - using channel name" do + @workspace.select_channel("random") + expect(@workspace.selected).must_be_instance_of Channel + expect(@workspace.selected.name).must_equal "random" + end + + + it "will return a Channel based on the user input - using channel name" do + @workspace.select_channel("CRQ896WKD") + expect(@workspace.selected).must_be_instance_of Channel + expect(@workspace.selected.name).must_equal "general" + end + end + + describe "select_user(user_name)" do + before do + VCR.use_cassette("create_workspace")do + @workspace = Workspace.new + end + end + + it "will return an instance of User based on the user input" do + @workspace.select_user("Sharon Cheung") + expect(@workspace.selected).must_be_instance_of User + expect(@workspace.selected.real_name).must_equal "Sharon Cheung" + end + + it "will return an instance of User based on the user input" do + @workspace.select_user("US1N1DHGQ") + expect(@workspace.selected).must_be_instance_of User + expect(@workspace.selected.real_name).must_equal "Joseph" + end + + it "will return nil if an user provided isn't valid" do + @workspace.select_user("nothing found here") + expect(@workspace.selected).must_be_nil + end + + end + + describe "show_details" do + before do + VCR.use_cassette("create_workspace")do + @workspace = Workspace.new + end + end + + + it " will return a user details" do + @workspace.select_user("Joseph") + user_details = @workspace.show_details + + expect(user_details).must_be_kind_of TablePrint::Returnable + + end + + it "will return a channel details" do + @workspace.select_channel('general') + channel_details = @workspace.show_details + + expect(channel_details).must_be_kind_of TablePrint::Returnable + + end + end + + describe "send_message(message)" do + before do + VCR.use_cassette("create_workspace")do + @workspace = Workspace.new + end + end + + it "will return true when the message go thru when a valid user/channel input" do + message_sent = + VCR.use_cassette("create_workspace") do + @workspace.select_user('Joseph') + message_sent = @workspace.send_message("Hello") + end + + expect(message_sent).must_be_kind_of TrueClass + end + end + + #Optional - updating user setting + xdescribe "set_profile_setting(name, emoji)" do + # tried to write the test for it but couldn't quite figure out yet.. + #can only use it for the authorized user + it "will return ture it is an User that can change the setting" do + VCR.use_cassette("create_workspace")do + @workspace = Workspace.new + end + + @workspace.select_user('keikei1128') + response = @workspace.set_profile_setting("Sharon", ":unicorn_face:") + + expect(response.selected.status_emoji).must_equal ":unicorn_face:" + end + end +end +