diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..6a43182e Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 8d6a243f..cdf7f804 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,5 @@ build-iPhoneSimulator/ # Ignore cassette files /specs/cassettes/ + +.DS_Store diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..5b9ee7b3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Debug Local File", + "type": "Ruby", + "request": "launch", + "cwd": "${workspaceRoot}", + "program": "${file}" + } + ] +} + diff --git a/lib/channel.rb b/lib/channel.rb new file mode 100644 index 00000000..3dc4b7bd --- /dev/null +++ b/lib/channel.rb @@ -0,0 +1,35 @@ +require_relative "recipient" + +module Slack + class Channel < Recipient + attr_reader :slack_id, :name, :num_members, :topic + + def initialize(slack_id, name, num_members, topic) + super(slack_id, name) + @num_members = num_members + @topic = topic + end + + def self.get + url = "https://slack.com/api/channels.list" + params = { + token: ENV["KEY"], + } + + response_from_get = HTTParty.get(url, query: params) + + if response_from_get["ok"] == false + raise ArgumentError, "Request is unsuccessful" + else + return response_from_get + end + end + + def self.list_all + all_channels = Channel.get["channels"].map do |channel| + self.new(channel["id"], channel["name"], channel["num_members"], channel["topic"]["value"]) + end + return all_channels + end + end +end diff --git a/lib/recipient.rb b/lib/recipient.rb new file mode 100644 index 00000000..0e951a1e --- /dev/null +++ b/lib/recipient.rb @@ -0,0 +1,34 @@ +module Slack + class Recipient + attr_reader :slack_id, :name + + def initialize(slack_id, name) + @slack_id = slack_id + @name = name + end + + def post_message(message) + url = "https://slack.com/api/chat.postMessage" + params = { + token: ENV["KEY"], + channel: @slack_id || @name, + text: message, + } + + message_request = HTTParty.post(url, query: params) + if message_request["ok"] == false + raise ArgumentError, "Request is unsuccessful" + else + return message_request + end + end + + # def self.get(url, params) + # HTTParty.GET(url, query: params) + # end + + def self.list_all + raise NotImplementedError, "Please implement in my child." + end + end +end diff --git a/lib/slack.rb b/lib/slack.rb index 960cf2f7..eb22f463 100755 --- a/lib/slack.rb +++ b/lib/slack.rb @@ -1,11 +1,96 @@ #!/usr/bin/env ruby +# require_relative "../spec/test_helper" +require_relative "channel" +require_relative "user" +require_relative "recipient" +require_relative "workspace" +require "dotenv" +require "httparty" +Dotenv.load def main puts "Welcome to the Ada Slack CLI!" - # TODO project + print "Channels loaded: ", Slack::Workspace.channel_list_all.length + + print "\nUsers loaded: ", Slack::Workspace.user_list_all.length + + puts "\nPlease select from the following options: \n list channels, select channel, list users, select user, details, send message, or quit" + selection = gets.chomp.downcase + + until selection == "quit" + case selection + when "list channels" + puts Slack::Workspace.all_channels_details + when "select channel" + puts "Which channel would you like to select?" + channel_identifier = gets.chomp.to_s + selected_channel = Slack::Workspace.select_channel(channel_identifier) + if selected_channel.nil? + puts "This channel doesn't exist. Exiting to main menu" + else + puts "You have selected #{selected_channel.name}. What would you like to do: details, send message, or quit" + answer = gets.chomp.downcase + case answer + when "details" + puts Slack::Workspace.selected_channel_details(selected_channel) + when "send message" + puts "Type message: " + message = gets.chomp + if message == "" + puts "Can't send a blank message. \nType message :" + message = gets.chomp + else + Slack::Recipient.new(selected_channel.slack_id, selected_channel.name).post_message(message) + end + when "quit" + else + puts "Please select a valid input. Returning to main!" + end + end + when "list users" + puts Slack::Workspace.all_users_details + when "select user" + puts "Which user would you like to select?" + user_identifier = gets.chomp.to_s + selected_user = Slack::Workspace.select_user(user_identifier) + if selected_user.nil? + puts "This user doesn't exist. Exiting to main menu" + else + puts "You have selected #{selected_user.name}. What would you like to do: details, send message, or quit" + answer = gets.chomp.downcase + case answer + when "details" + puts Slack::Workspace.selected_user_details(selected_user) + when "send message" + puts "Type message: " + message = gets.chomp + if message == "" + puts "Can't send a blank message. \nType message :" + message = gets.chomp + else + Slack::Recipient.new(selected_user.slack_id, selected_user.name).post_message(message) + end + when "quit" + else + puts "Please select a valid input. Returning to main!" + end + end + when "details" + puts "You haven't selected a user or channel. Exiting to main prompt." + when "send message" + puts "You haven't selected a user or channel. Exiting to main prompt." + when "quit" + else + puts "Please enter a valid selection." + end + puts "What would you like to do next? (list users, select user, list channels, select channel, details, send message, or quit)" + selection = gets.chomp.downcase + end + + # Should we use a case statement here for the 3 options? 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/user.rb b/lib/user.rb new file mode 100644 index 00000000..da45977c --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,30 @@ +require_relative "recipient" + +module Slack + class User < Recipient + attr_reader :slack_id, :name, :real_name + + def initialize(slack_id, name, real_name) + super(slack_id, name) + @real_name = real_name + end + + def self.get + url = "https://slack.com/api/users.list" + params = { + token: ENV["KEY"], + } + + response_from_get = HTTParty.get(url, query: params) + + return response_from_get + end + + def self.list_all + users = User.get["members"].map do |user| + self.new(user["id"], user["name"], user["profile"]["real_name"]) + end + return users + end + end +end diff --git a/lib/workspace.rb b/lib/workspace.rb new file mode 100644 index 00000000..2b28e406 --- /dev/null +++ b/lib/workspace.rb @@ -0,0 +1,69 @@ +require_relative "channel" +require_relative "user" +require_relative "recipient" +require "dotenv" +require "httparty" +require "pry" +Dotenv.load + +module Slack + class Workspace + def self.channel_list_all + channels = Slack::Channel.list_all + name_channels = channels.map do |channel| + channel.name + end + return name_channels + end + + def self.all_channels_details + channels = Slack::Channel.list_all.map do |channel| + "Channel ID: #{channel.slack_id}\nChannel name: #{channel.name} \nMembers: #{channel.num_members} \nChannel Topic: #{channel.topic}" + end + return channels + end + + def self.select_channel(channel_identifier) + find_channel = Slack::Channel.list_all.find do |channel| + channel.name.downcase == channel_identifier.downcase || + channel.slack_id.downcase == channel_identifier.downcase + end + return find_channel + end + + def self.selected_channel_details(chosen_channel) + details = "Channel ID: #{chosen_channel.slack_id}\nChannel name: #{chosen_channel.name} \nMembers: #{chosen_channel.num_members} \nChannel Topic: #{chosen_channel.topic}" + + return details + end + + def self.user_list_all + users = Slack::User.list_all + name_users = users.map do |user| + user.name + end + return name_users + end + + def self.all_users_details + users = Slack::User.list_all.map do |user| + "User ID: #{user.slack_id}: \nReal name: #{user.real_name} \nDisplay name: #{user.name}." + end + return users + end + + def self.select_user(user_identifier) + find_user = Slack::User.list_all.find { + |user| + user.name.downcase == user_identifier.downcase || + user.slack_id.downcase == user_identifier.downcase + } + + return find_user + end + + def self.selected_user_details(chosen_user) + details = "User ID: #{chosen_user.slack_id}: \nReal name: #{chosen_user.real_name} \nDisplay name: #{chosen_user.name}." + end + end +end diff --git a/specs/channel_spec.rb b/specs/channel_spec.rb new file mode 100644 index 00000000..94aa9836 --- /dev/null +++ b/specs/channel_spec.rb @@ -0,0 +1,32 @@ +require_relative "test_helper.rb" + +require "pry" + +describe "Channel class" do + it "Creates an instance of the Channel class" do + new_channel = Slack::Channel.new("id", "name", 3, "topic") + expect(new_channel).must_be_instance_of Slack::Channel + end +end + +describe "Get method" do + it "Successfully GETs response from Slack API" do + VCR.use_cassette("channel_find") do + response = Slack::Channel.get + + expect(response["ok"]).must_equal true + end + end +end + +describe "list_all method" do + it "gives a list of all user information from the API and returns a value of a 'general' channel name" do + VCR.use_cassette("channel_find") do + list_response = Slack::Channel.list_all + ap list_response + + expect(list_response.length).must_equal 3 + expect(list_response[0].name).must_equal "general" + end + end +end diff --git a/specs/recipient_spec.rb b/specs/recipient_spec.rb new file mode 100644 index 00000000..ce03c7ce --- /dev/null +++ b/specs/recipient_spec.rb @@ -0,0 +1,24 @@ +require_relative "test_helper.rb" +require "pry" + +describe "Recipient class" do + it "creates an instance of Recipient class" do + receiver = Slack::Recipient.new("id", "name") + expect(receiver).must_be_instance_of Slack::Recipient + end +end + +describe "Post message method" do + it "will return a true value for 'ok'" do + VCR.use_cassette("message_find") do + recipient_id = "USLACKBOT" + name = "slackbot" + + message = "Hi Slackbot! - Heather and Mina" + + new_message = Slack::Recipient.new(recipient_id, name).post_message(message) + expect(new_message["ok"]).must_equal true + expect(new_message["message"]["text"]).must_match "- Heather and Mina" + end + end +end diff --git a/specs/slack_spec.rb b/specs/slack_spec.rb new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/specs/slack_spec.rb @@ -0,0 +1 @@ + diff --git a/specs/test_helper.rb b/specs/test_helper.rb index 81ccd06b..f9fe7c33 100644 --- a/specs/test_helper.rb +++ b/specs/test_helper.rb @@ -1,15 +1,38 @@ -require 'simplecov' +require "simplecov" SimpleCov.start -require 'minitest' -require 'minitest/autorun' -require 'minitest/reporters' -require 'minitest/skip_dsl' -require 'vcr' +require "minitest" +require "minitest/autorun" +require "minitest/reporters" +require "minitest/skip_dsl" +require "vcr" +require "httparty" +require "dotenv" +require "awesome_print" + +Dotenv.load + +require_relative "../lib/recipient.rb" +require_relative "../lib/channel.rb" +require_relative "../lib/user.rb" +require_relative "../lib/slack.rb" +require_relative "../lib/workspace.rb" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new +# VCR.configure do |config| +# config.cassette_library_dir = "specs/cassettes" +# config.hook_into :webmock + VCR.configure do |config| - config.cassette_library_dir = "specs/cassettes" - config.hook_into :webmock -end \ No newline at end of file + config.cassette_library_dir = "specs/cassettes" # folder where casettes will be located + config.hook_into :webmock # tie into this other tool called webmock + config.default_cassette_options = { + :record => :new_episodes, # record new data when we don't have it yet + :match_requests_on => [:method, :uri, :body], # The http method, URI and body of a request all need to match + } + # Don't leave our token lying around in a cassette file. + config.filter_sensitive_data("KEY") do + ENV["KEY"] + end +end diff --git a/specs/user_spec.rb b/specs/user_spec.rb new file mode 100644 index 00000000..c01382c2 --- /dev/null +++ b/specs/user_spec.rb @@ -0,0 +1,29 @@ +require_relative "test_helper.rb" +require "pry" + +describe "Channel class" do + it "Creates an instance of the Channel class" do + new_user = Slack::User.new("id", "name", "real name") + expect(new_user).must_be_instance_of Slack::User + end +end + +describe "get method" do + it "Successfully GETs response from Slack API" do + VCR.use_cassette("user_find") do + response = Slack::User.get + expect(response["ok"]).must_equal true + end + end +end + +describe "list_all method" do + it "gives a list of all user information from the API" do + VCR.use_cassette("user_find") do + list_response = Slack::User.list_all + ap list_response + expect(list_response.length).must_equal 3 + expect(list_response[0].name).must_equal "slackbot" + end + end +end diff --git a/specs/workspace_spec.rb b/specs/workspace_spec.rb new file mode 100644 index 00000000..c116c265 --- /dev/null +++ b/specs/workspace_spec.rb @@ -0,0 +1,106 @@ +require_relative "test_helper.rb" + +describe "self.channel_list_all" do + it "returns an array of channel names" do + VCR.use_cassette("channel_find") do + list = Slack::Workspace.channel_list_all + + expect(list.length).must_equal 3 + expect(list).must_include "random" + expect(list).wont_include "test" + end + end +end + +describe "self.all_channels_details" do + it "returns an array of channel details" do + VCR.use_cassette("channel_find") do + details = Slack::Workspace.all_channels_details + + expect(details.length).must_equal 3 + end + end +end + +describe "self.select_channel" do + it "can select a channel and return it" do + VCR.use_cassette("channel_find") do + selected_channel = Slack::Workspace.select_channel("general") + + expect(selected_channel.name).must_equal "general" + expect(selected_channel.slack_id).must_equal "CH2NW42JF" + + selected_channel = Slack::Workspace.select_channel("CH2NW42JF") + + expect(selected_channel.name).must_equal "general" + expect(selected_channel.slack_id).must_equal "CH2NW42JF" + + selected_channel = Slack::Workspace.select_channel("geNeral") + expect(selected_channel.name).must_equal "general" + end + end +end + +describe "self.selected_channel_details" do + it "returns the details for the selected channel" do + VCR.use_cassette("channel_find") do + channel = Slack::Channel.new("Pfeiffer_id", "Pfeiffer_name", 5, "Pfeiffer_topic") + channel_details = Slack::Workspace.selected_channel_details(channel) + + expect(channel_details).must_match "Pfeiffer_id" + expect(channel_details).must_match "Pfeiffer_topic" + end + end +end + +describe "self.user_list_all" do + it "returns an array of user names" do + VCR.use_cassette("user_find") do + list = Slack::Workspace.user_list_all + expect(list.length).must_equal 3 + expect(list).must_include "slackbot" + expect(list).wont_include "test" + end + end +end + +describe "self.all_users_details" do + it "returns an array of users details" do + VCR.use_cassette("user_find") do + details = Slack::Workspace.all_users_details + + expect(details.length).must_equal 3 + end + end +end + +describe "self.select_user" do + it "can select a user and return it" do + VCR.use_cassette("user_find") do + selected_user = Slack::Workspace.select_user("slackbot") + + expect(selected_user.name).must_equal "slackbot" + expect(selected_user.slack_id).must_equal "USLACKBOT" + + selected_user = Slack::Workspace.select_user("USLACKBOT") + + expect(selected_user.name).must_equal "slackbot" + expect(selected_user.slack_id).must_equal "USLACKBOT" + + selected_user = Slack::Workspace.select_user("USLACKbOT") + expect(selected_user.name).must_equal "slackbot" + end + end +end + +describe "self.selected_user_details" do + it "returns the details for the selected user" do + VCR.use_cassette("user_find") do + user = Slack::User.new("RS100", "Robot", "Robot Smith") + user_details = Slack::Workspace.selected_user_details(user) + + expect(user_details).must_match "RS100" + expect(user_details).must_match "Robot Smith" + end + end +end