morale 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +19 -0
- data/Gemfile.lock +56 -0
- data/LICENSE +0 -0
- data/README.md +38 -0
- data/Rakefile +150 -0
- data/bin/morale +8 -0
- data/features/accounts.feature +88 -0
- data/features/login.feature +65 -0
- data/features/projects.feature +110 -0
- data/features/step_definitions/models.rb +3 -0
- data/features/support/env.rb +6 -0
- data/features/support/hooks.rb +12 -0
- data/features/tickets.feature +26 -0
- data/lib/morale/account.rb +119 -0
- data/lib/morale/authorization.rb +20 -0
- data/lib/morale/client.rb +76 -0
- data/lib/morale/command.rb +70 -0
- data/lib/morale/commands/account.rb +61 -0
- data/lib/morale/commands/authorization.rb +13 -0
- data/lib/morale/commands/project.rb +63 -0
- data/lib/morale/commands/ticket.rb +36 -0
- data/lib/morale/credentials_store.rb +41 -0
- data/lib/morale/flow.rb +17 -0
- data/lib/morale/platform.rb +64 -0
- data/lib/morale.rb +5 -0
- data/morale.gemspec +70 -0
- data/spec/morale/account_spec.rb +11 -0
- data/spec/morale/client_spec.rb +92 -0
- data/spec/morale/command_spec.rb +67 -0
- data/spec/morale/credentials_store_spec.rb +46 -0
- data/spec/spec_helper.rb +21 -0
- metadata +148 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "json"
|
3
|
+
require "morale/client"
|
4
|
+
|
5
|
+
describe Morale::Client do
|
6
|
+
describe "#authorize" do
|
7
|
+
it "authorizes a user with a valid email address and password" do
|
8
|
+
api_key = "blah"
|
9
|
+
stub_request(:post, "http://blah.lvh.me:3000/api/v1/in").to_return(:body => { "api_key" => "#{api_key}" }.to_json)
|
10
|
+
Morale::Client.authorize(nil, nil, 'blah').api_key.should == api_key
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "#accounts" do
|
15
|
+
it "displays all the accounts for a specific user based on their email" do
|
16
|
+
stub_request(:get, "http://lvh.me:3000/api/v1/accounts?email=someone@example.com").to_return(:body =>
|
17
|
+
[{"account" => {"group_name" => "Shimmy Sham","site_address"=>"shimmy_sham","created_at" => "2011-07-31T21:28:53Z","updated_at" => "2011-07-31T21:28:53Z","plan_id" => 1,"id" => 2}},
|
18
|
+
{"account" => {"group_name" => "Pumpkin Tarts","site_address"=>"pumpkin_tarts","created_at" => "2011-07-31T21:40:24Z","updated_at" => "2011-07-31T21:40:24Z","plan_id" => 1,"id" => 1}}].to_json)
|
19
|
+
|
20
|
+
accounts = Morale::Client.accounts('someone@example.com')
|
21
|
+
accounts.count.should == 2
|
22
|
+
end
|
23
|
+
|
24
|
+
it "displays all the accounts for a specific user based on their api_key" do
|
25
|
+
stub_request(:get, "http://blah:@blah.lvh.me:3000/api/v1/accounts?api_key=").to_return(:body =>
|
26
|
+
[{"account" => {"group_name" => "Shimmy Sham","site_address"=>"shimmy_sham","created_at" => "2011-07-31T21:28:53Z","updated_at" => "2011-07-31T21:28:53Z","plan_id" => 1,"id" => 2}},
|
27
|
+
{"account" => {"group_name" => "Pumpkin Tarts","site_address"=>"pumpkin_tarts","created_at" => "2011-07-31T21:40:24Z","updated_at" => "2011-07-31T21:40:24Z","plan_id" => 1,"id" => 1}}].to_json)
|
28
|
+
|
29
|
+
client = Morale::Client.new('blah')
|
30
|
+
client.accounts.count.should == 2
|
31
|
+
client.accounts[0]["account"]["group_name"].should == "Shimmy Sham"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#projects" do
|
36
|
+
it "displays all the projects for a specific account" do
|
37
|
+
stub_request(:get, "http://blah:@blah.lvh.me:3000/api/v1/projects").to_return(:body =>
|
38
|
+
[{"project" => {"name" => "Skunk Works","created_at" => "2011-07-31T21:40:24Z","updated_at" => "2011-07-31T21:40:24Z","account_id" => 1,"id" => 1}},
|
39
|
+
{"project" => {"name" => "Poop Shoot","created_at" => "2011-07-31T21:28:53Z","updated_at" => "2011-07-31T21:28:53Z","account_id" => 1,"id" => 2}}].to_json)
|
40
|
+
client = Morale::Client.new('blah')
|
41
|
+
client.projects.count.should == 2
|
42
|
+
client.projects[0]["project"]["name"].should == "Skunk Works"
|
43
|
+
client.projects[1]["project"]["id"].should == 2
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should raise unauthorized if a 401 is received" do
|
47
|
+
stub_request(:get, "http://blah:@blah.lvh.me:3000/api/v1/projects").to_return(:status => 401)
|
48
|
+
client = Morale::Client.new('blah')
|
49
|
+
lambda { client.projects.count }.should raise_error(Morale::Client::Unauthorized)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "#ticket" do
|
54
|
+
it "should return a JSON ticket that was created" do
|
55
|
+
stub_request(:post, "http://blah:123456@blah.lvh.me:3000/api/v1/projects/1/tickets").
|
56
|
+
with(:body => "command=This%20is%20a%20test%20that%20should%20create%20a%20new%20task%20as%3A%20Lester").
|
57
|
+
to_return(:body => {
|
58
|
+
"created_at" => "2011-09-27T02:56:03Z",
|
59
|
+
"assigned_to" => { "user" => { "first_name" => "Lester", "last_name" => "Tester", "email" => "test@test.com" } },
|
60
|
+
"title" => "This is a test that should create a new task",
|
61
|
+
"project_id" => "1",
|
62
|
+
"priority" => "null",
|
63
|
+
"archived" => "false",
|
64
|
+
"id" => "1",
|
65
|
+
"created_by" => { "user" => { "first_name" => "Lester", "last_name" => "Tester", "email" => "test@test.com" } },
|
66
|
+
"due_date" => "null",
|
67
|
+
"identifier" => "1" }.to_json
|
68
|
+
)
|
69
|
+
client = Morale::Client.new('blah', '123456')
|
70
|
+
response = client.ticket(1, "This is a test that should create a new task as: Lester")
|
71
|
+
response['title'].should == "This is a test that should create a new task"
|
72
|
+
response['assigned_to']['user']['first_name'].should == "Lester"
|
73
|
+
response['project_id'].should == "1"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "should raise unauthorized if a 401 is received" do
|
77
|
+
stub_request(:post, "http://blah:123456@blah.lvh.me:3000/api/v1/projects/1/tickets").
|
78
|
+
with(:body => "command=This%20is%20a%20test%20that%20should%20create%20a%20new%20task%20as%3A%20Lester").
|
79
|
+
to_return(:status => 401)
|
80
|
+
client = Morale::Client.new('blah', '123456')
|
81
|
+
lambda { client.ticket('1', "This is a test that should create a new task as: Lester") }.should raise_error(Morale::Client::Unauthorized)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should raise notfound if a 404 is received" do
|
85
|
+
stub_request(:post, "http://blah:123456@blah.lvh.me:3000/api/v1/projects/1/tickets").
|
86
|
+
with(:body => "command=This%20is%20a%20test%20that%20should%20create%20a%20new%20task%20as%3A%20Lester").
|
87
|
+
to_return(:status => 404)
|
88
|
+
client = Morale::Client.new('blah', '123456')
|
89
|
+
lambda { client.ticket('1', "This is a test that should create a new task as: Lester") }.should raise_error(Morale::Client::NotFound)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "morale/command"
|
3
|
+
|
4
|
+
describe Morale::Command do
|
5
|
+
describe "#login" do
|
6
|
+
it "should display instructions if credentials are not yet stored" do
|
7
|
+
Morale::Account.subdomain = "blah"
|
8
|
+
stub_request(:post, "http://blah.lvh.me:3000/api/v1/in").to_return(:body => { "api_key" => "blah!" }.to_json)
|
9
|
+
output = process('someone@somewhere.com') { Morale::Command.start ["login"] }
|
10
|
+
output[:stdout].should =~ /Sign in to Morale./
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should ask for your email if credentials are not yet stored" do
|
14
|
+
Morale::Account.subdomain = "blah"
|
15
|
+
stub_request(:post, "http://blah.lvh.me:3000/api/v1/in").to_return(:body => { "api_key" => "blah!" }.to_json)
|
16
|
+
output = process('someone@somewhere.com') { Morale::Command.start ["login"] }
|
17
|
+
output[:stdout].should =~ /Email: /
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should ask for your password if credentials are not yet stored" do
|
21
|
+
Morale::Account.subdomain = "blah"
|
22
|
+
stub_request(:post, "http://blah.lvh.me:3000/api/v1/in").to_return(:body => { "api_key" => "blah!" }.to_json)
|
23
|
+
output = process('someone@somewhere.com') { Morale::Command.start ["login"] }
|
24
|
+
output[:stdout].should =~ /Password: /
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should store your api key once you have signed in if credentials are not yet stored" do
|
28
|
+
Morale::Account.subdomain = "blah"
|
29
|
+
stub_request(:post, "http://blah.lvh.me:3000/api/v1/in").to_return(:body => { "api_key" => "api_key" }.to_json)
|
30
|
+
output = process('someone@somewhere.com') { Morale::Command.start ["login"] }
|
31
|
+
File.read(Morale::Account.location).should =~ /blah/
|
32
|
+
File.read(Morale::Account.location).should =~ /api_key/
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "#accounts" do
|
37
|
+
it "should return all the group names for an account that a user has access to" do
|
38
|
+
stub_request(:get, "http://lvh.me:3000/api/v1/accounts?email=someone@example.com").to_return(:body =>
|
39
|
+
[{"account" => {"group_name" => "Shimmy Sham","site_address"=>"shimmy_sham","created_at" => "2011-07-31T21:28:53Z","updated_at" => "2011-07-31T21:28:53Z","plan_id" => 1,"id" => 2}},
|
40
|
+
{"account" => {"group_name" => "Pumpkin Tarts","site_address"=>"pumpkin_tarts","created_at" => "2011-07-31T21:40:24Z","updated_at" => "2011-07-31T21:40:24Z","plan_id" => 1,"id" => 1}}].to_json)
|
41
|
+
|
42
|
+
output = process() { Morale::Command.start(["accounts", "someone@example.com"]) }
|
43
|
+
output[:stdout].should =~ /1. Pumpkin Tarts/
|
44
|
+
output[:stdout].should =~ /2. Shimmy Sham/
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#projects" do
|
49
|
+
it "should return all the project names for an account" do
|
50
|
+
stub_request(:get, "http://blah:api_key@blah.lvh.me:3000/api/v1/projects").to_return(:body =>
|
51
|
+
[{"project" => {"name" => "Skunk Works","created_at" => "2011-07-31T21:40:24Z","updated_at" => "2011-07-31T21:40:24Z","account_id" => 1,"id" => 1}},
|
52
|
+
{"project" => {"name" => "Poop Shoot","created_at" => "2011-07-31T21:28:53Z","updated_at" => "2011-07-31T21:28:53Z","account_id" => 1,"id" => 2}}].to_json)
|
53
|
+
|
54
|
+
output = process() { Morale::Command.start(["projects"]) }
|
55
|
+
output[:stdout].should =~ /1. Poop Shoot/
|
56
|
+
output[:stdout].should =~ /2. Skunk Works/
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should raise unauthorized if a 401 is retrieved" do
|
60
|
+
stub_request(:post, "http://blah.lvh.me:3000/api/v1/in").to_return(:body => { "api_key" => "api_key" }.to_json)
|
61
|
+
stub_request(:get, "http://blah:api_key@blah.lvh.me:3000/api/v1/projects").to_return(:status => 401)
|
62
|
+
|
63
|
+
output = process() { Morale::Command.start(["projects"]) }
|
64
|
+
output[:stdout].should =~ /Authentication failure/
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'morale/credentials_store'
|
3
|
+
|
4
|
+
describe Morale::CredentialsStore do
|
5
|
+
|
6
|
+
class Dummy; end
|
7
|
+
before (:each) do
|
8
|
+
@dummy = Dummy.new
|
9
|
+
@dummy.extend(Morale::CredentialsStore)
|
10
|
+
end
|
11
|
+
|
12
|
+
after (:each) do
|
13
|
+
@dummy.delete_credentials
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "#location" do
|
17
|
+
it "should return the correct location of the credentials file" do
|
18
|
+
@dummy.location.should == "#{ENV['HOME']}/.morale/credentials"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "#delete_credentials" do
|
23
|
+
it "should clear the credentials field" do
|
24
|
+
@dummy.credentials = "Blah!"
|
25
|
+
@dummy.delete_credentials
|
26
|
+
@dummy.credentials.should be_nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should delete the credentials file" do
|
30
|
+
FileUtils.mkdir_p(File.dirname(@dummy.location))
|
31
|
+
f = File.open(@dummy.location, 'w')
|
32
|
+
f.puts "Blah!"
|
33
|
+
|
34
|
+
@dummy.delete_credentials
|
35
|
+
File.exists?(@dummy.location).should be_false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#write_credentials" do
|
40
|
+
it "should write data to the location of the credentials file" do
|
41
|
+
@dummy.credentials = "Blah!"
|
42
|
+
@dummy.write_credentials
|
43
|
+
File.read(@dummy.location).should =~ /Blah!/
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
|
4
|
+
require "rspec"
|
5
|
+
require "webmock/rspec"
|
6
|
+
|
7
|
+
require "stringio"
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
def process(stdin_str = '')
|
11
|
+
begin
|
12
|
+
require 'stringio'
|
13
|
+
$o_stdin, $o_stdout, $o_stderr = $stdin, $stdout, $stderr
|
14
|
+
$stdin, $stdout, $stderr = StringIO.new(stdin_str), StringIO.new, StringIO.new
|
15
|
+
yield
|
16
|
+
{:stdout => $stdout.string, :stderr => $stderr.string}
|
17
|
+
ensure
|
18
|
+
$stdin, $stdout, $stderr = $o_stdin, $o_stdout, $o_stderr
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: morale
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Brilliant Fantastic
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2011-09-29 00:00:00 -04:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: hirb
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
- 5
|
30
|
+
- 0
|
31
|
+
version: 0.5.0
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: httparty
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
- 7
|
44
|
+
- 8
|
45
|
+
version: 0.7.8
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id002
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: json
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
segments:
|
56
|
+
- 1
|
57
|
+
- 4
|
58
|
+
- 6
|
59
|
+
version: 1.4.6
|
60
|
+
type: :runtime
|
61
|
+
version_requirements: *id003
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: thor
|
64
|
+
prerelease: false
|
65
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
- 14
|
72
|
+
- 6
|
73
|
+
version: 0.14.6
|
74
|
+
type: :runtime
|
75
|
+
version_requirements: *id004
|
76
|
+
description: Client library and command-line tool to manage tickets and control your account on Morale.
|
77
|
+
email: support@teammorale.com
|
78
|
+
executables:
|
79
|
+
- morale
|
80
|
+
extensions: []
|
81
|
+
|
82
|
+
extra_rdoc_files:
|
83
|
+
- README.md
|
84
|
+
- LICENSE
|
85
|
+
files:
|
86
|
+
- Gemfile
|
87
|
+
- Gemfile.lock
|
88
|
+
- LICENSE
|
89
|
+
- README.md
|
90
|
+
- Rakefile
|
91
|
+
- bin/morale
|
92
|
+
- features/accounts.feature
|
93
|
+
- features/login.feature
|
94
|
+
- features/projects.feature
|
95
|
+
- features/step_definitions/models.rb
|
96
|
+
- features/support/env.rb
|
97
|
+
- features/support/hooks.rb
|
98
|
+
- features/tickets.feature
|
99
|
+
- lib/morale.rb
|
100
|
+
- lib/morale/account.rb
|
101
|
+
- lib/morale/authorization.rb
|
102
|
+
- lib/morale/client.rb
|
103
|
+
- lib/morale/command.rb
|
104
|
+
- lib/morale/commands/account.rb
|
105
|
+
- lib/morale/commands/authorization.rb
|
106
|
+
- lib/morale/commands/project.rb
|
107
|
+
- lib/morale/commands/ticket.rb
|
108
|
+
- lib/morale/credentials_store.rb
|
109
|
+
- lib/morale/flow.rb
|
110
|
+
- lib/morale/platform.rb
|
111
|
+
- morale.gemspec
|
112
|
+
- spec/morale/account_spec.rb
|
113
|
+
- spec/morale/client_spec.rb
|
114
|
+
- spec/morale/command_spec.rb
|
115
|
+
- spec/morale/credentials_store_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
has_rdoc: true
|
118
|
+
homepage: http://teammorale.com
|
119
|
+
licenses: []
|
120
|
+
|
121
|
+
post_install_message:
|
122
|
+
rdoc_options:
|
123
|
+
- --charset=UTF-8
|
124
|
+
require_paths:
|
125
|
+
- lib
|
126
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
segments:
|
131
|
+
- 0
|
132
|
+
version: "0"
|
133
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
segments:
|
138
|
+
- 0
|
139
|
+
version: "0"
|
140
|
+
requirements: []
|
141
|
+
|
142
|
+
rubyforge_project: morale
|
143
|
+
rubygems_version: 1.3.6
|
144
|
+
signing_key:
|
145
|
+
specification_version: 2
|
146
|
+
summary: Command line interface to create & manage tickets on Morale.
|
147
|
+
test_files: []
|
148
|
+
|