artisan-core 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/artisan/iterations/iteration_workflow_interactor.rb +2 -1
- data/lib/artisan/iterations/move_to_backlog.rb +2 -0
- data/lib/artisan/notifications/event_mailer.rb +26 -0
- data/lib/artisan/notifications/inviter.rb +40 -0
- data/lib/artisan/projects/project_creator.rb +2 -2
- data/lib/artisan/projects/projects_interactor.rb +5 -1
- data/lib/artisan/reports/burn_up_chart.rb +5 -0
- data/lib/artisan/reports/high_charts_data_retriever.rb +6 -4
- data/lib/artisan/reports/high_charts_interactor.rb +2 -0
- data/lib/artisan/stories/stories_interactor.rb +2 -1
- data/lib/artisan/story_exporter.rb +2 -0
- data/lib/artisan/{member.rb → teams/member.rb} +0 -0
- data/lib/artisan/teams/team.rb +53 -0
- metadata +39 -57
- data/lib/artisan/event_mailer.rb +0 -22
- data/lib/artisan/inviter.rb +0 -36
- data/lib/artisan/repository.rb +0 -51
- data/lib/artisan/team.rb +0 -50
- data/spec/crud_strategy_spec.rb +0 -100
- data/spec/event_mailer_spec.rb +0 -86
- data/spec/inviter_spec.rb +0 -58
- data/spec/member_spec.rb +0 -58
- data/spec/repository_spec.rb +0 -32
- data/spec/story_board_spec.rb +0 -36
- data/spec/story_collection_spec.rb +0 -61
- data/spec/story_column_changer_spec.rb +0 -222
- data/spec/story_exporter_spec.rb +0 -25
- data/spec/story_sorter_spec.rb +0 -67
- data/spec/team_spec.rb +0 -107
data/lib/artisan/repository.rb
DELETED
@@ -1,51 +0,0 @@
|
|
1
|
-
module Artisan
|
2
|
-
class RecordNotFound < RuntimeError
|
3
|
-
attr_reader :base
|
4
|
-
|
5
|
-
def initialize(base = nil)
|
6
|
-
@base = base
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
|
-
class Repository
|
11
|
-
def self.register_repo(repo)
|
12
|
-
@repo = repo
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.story
|
16
|
-
repo.story
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.project
|
20
|
-
repo.project
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.iteration
|
24
|
-
repo.iteration
|
25
|
-
end
|
26
|
-
|
27
|
-
def self.user
|
28
|
-
repo.user
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.future_user
|
32
|
-
repo.future_user
|
33
|
-
end
|
34
|
-
|
35
|
-
def self.project_configuration
|
36
|
-
repo.project_configuration
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.change
|
40
|
-
repo.change
|
41
|
-
end
|
42
|
-
|
43
|
-
def self.member
|
44
|
-
repo.member
|
45
|
-
end
|
46
|
-
|
47
|
-
def self.repo
|
48
|
-
@repo
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
data/lib/artisan/team.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
require 'artisan/repository'
|
2
|
-
require 'ostruct'
|
3
|
-
|
4
|
-
class Team
|
5
|
-
|
6
|
-
attr_reader :project
|
7
|
-
|
8
|
-
def initialize(project, current_user)
|
9
|
-
@project = project
|
10
|
-
end
|
11
|
-
|
12
|
-
def add_team_member(user)
|
13
|
-
add_member(user, false)
|
14
|
-
end
|
15
|
-
|
16
|
-
def add_team_owner(user)
|
17
|
-
add_member(user, true)
|
18
|
-
end
|
19
|
-
|
20
|
-
def owner?(user)
|
21
|
-
return false if project.nil? || !user?(user)
|
22
|
-
project_repo.is_owner?(project, user)
|
23
|
-
end
|
24
|
-
|
25
|
-
def user?(user)
|
26
|
-
project_repo.is_member?(project, user)
|
27
|
-
end
|
28
|
-
|
29
|
-
def remove_user(user)
|
30
|
-
project_repo.remove_member(project, user)
|
31
|
-
if !user.nil?
|
32
|
-
Artisan::Member.new(OpenStruct.new(:user => user, :project => project)).remove_from_email_lists
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def owners
|
37
|
-
project_repo.owners(project)
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def add_member(user, owner)
|
43
|
-
project_repo.add_member(project, user, owner) unless user?(user)
|
44
|
-
end
|
45
|
-
|
46
|
-
def project_repo
|
47
|
-
Artisan::Repository.project
|
48
|
-
end
|
49
|
-
|
50
|
-
end
|
data/spec/crud_strategy_spec.rb
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
require "artisan/crud_strategy"
|
2
|
-
require "artisan-memory-repository/models/user"
|
3
|
-
require "artisan/callbacks"
|
4
|
-
|
5
|
-
class TestModel
|
6
|
-
attr_accessor :id, :attributes
|
7
|
-
def initialize
|
8
|
-
@id = 3
|
9
|
-
@attributes = {}
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
class TestRepository
|
14
|
-
def save(model)
|
15
|
-
true
|
16
|
-
end
|
17
|
-
|
18
|
-
def new(*args)
|
19
|
-
TestModel.new
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
describe Artisan::CrudStrategy do
|
24
|
-
|
25
|
-
let(:model) { TestModel.new }
|
26
|
-
let(:model_attributes) { {:test => "test"}}
|
27
|
-
let(:user) { Artisan::Repository.user.new }
|
28
|
-
|
29
|
-
let(:callback) do
|
30
|
-
Artisan::Callbacks.build do |callback|
|
31
|
-
callback.on(:success) { @success_callback_triggered = true }
|
32
|
-
callback.on(:failure) { @failure_callback_triggered = true }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
let(:interactor) { Artisan::CrudStrategy }
|
37
|
-
let(:repository) { mock('repository') }
|
38
|
-
|
39
|
-
before do
|
40
|
-
TestModel.stub!(:find).and_return(model)
|
41
|
-
end
|
42
|
-
|
43
|
-
context "Create" do
|
44
|
-
|
45
|
-
before do
|
46
|
-
repository.stub!(:new).and_return(model)
|
47
|
-
repository.stub!(:save).and_return(true)
|
48
|
-
end
|
49
|
-
|
50
|
-
it "creates a new model" do
|
51
|
-
new_model = interactor.create(model, callback, repository)
|
52
|
-
new_model.should == model
|
53
|
-
end
|
54
|
-
|
55
|
-
it "calls successful callbacks" do
|
56
|
-
interactor.create(model_attributes, callback, repository)
|
57
|
-
|
58
|
-
@success_callback_triggered.should be_true
|
59
|
-
end
|
60
|
-
|
61
|
-
it "calls failure callbacks on failed save" do
|
62
|
-
failure_callback_triggered = false
|
63
|
-
failure_callback = Proc.new { |model| failure_callback_triggered = true }
|
64
|
-
repository.should_receive(:save).and_return(false)
|
65
|
-
interactor.create(model_attributes, callback, repository)
|
66
|
-
|
67
|
-
@failure_callback_triggered.should be_true
|
68
|
-
end
|
69
|
-
|
70
|
-
end
|
71
|
-
|
72
|
-
|
73
|
-
context "Update" do
|
74
|
-
|
75
|
-
before do
|
76
|
-
model.stub(:update_attributes).and_return(true)
|
77
|
-
end
|
78
|
-
|
79
|
-
it "finds and updates the project" do
|
80
|
-
model.should_receive(:update_attributes).with(model_attributes).and_return(true)
|
81
|
-
|
82
|
-
interactor.update(model, model_attributes, user, callback).should == model
|
83
|
-
end
|
84
|
-
|
85
|
-
it "completes a successful callback" do
|
86
|
-
interactor.update(model, model_attributes, user, callback)
|
87
|
-
@success_callback_triggered.should be_true
|
88
|
-
end
|
89
|
-
|
90
|
-
it "completes a failure callback" do
|
91
|
-
model.stub(:update_attributes).and_return(false)
|
92
|
-
failure_callback_triggered = false
|
93
|
-
failure_callback = Proc.new { failure_callback_triggered = true }
|
94
|
-
interactor.update(model, model_attributes, user, callback)
|
95
|
-
@failure_callback_triggered.should be_true
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
end
|
data/spec/event_mailer_spec.rb
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
require "artisan/event_mailer"
|
2
|
-
require "artisan-memory-repository/models/project"
|
3
|
-
require "artisan-memory-repository/models/story"
|
4
|
-
require "artisan-memory-repository/models/user"
|
5
|
-
|
6
|
-
class Notifier; end # stubbed out for tests
|
7
|
-
|
8
|
-
describe EventMailer do
|
9
|
-
|
10
|
-
describe "mailing" do
|
11
|
-
|
12
|
-
before(:each) do
|
13
|
-
@project = Artisan::Repository.project.new(:name => "Test")
|
14
|
-
@project_configuration = double(:story_completed_email_list => ["hello@world.com", "dude@test.com"], :story_assigned_email_list => ["uhh@derp.com", "dude@test.com"])
|
15
|
-
@project.project_configuration = @project_configuration
|
16
|
-
@event_mailer = EventMailer.new(@project)
|
17
|
-
end
|
18
|
-
|
19
|
-
it "takes a project and sets a configuration" do
|
20
|
-
@event_mailer.instance_variable_get(:@configuration).should == @project_configuration
|
21
|
-
@event_mailer.instance_variable_get(:@project_name).should == @project.name
|
22
|
-
end
|
23
|
-
|
24
|
-
it "alerts the notifier for a new assigned user to a story" do
|
25
|
-
user = Artisan::Repository.user.new(:full_name => "Mister McGoo")
|
26
|
-
story = Artisan::Repository.story.new(:assigned_user => user, :name => "Test")
|
27
|
-
|
28
|
-
email_list = "uhh@derp.com, dude@test.com"
|
29
|
-
Notifier.should_receive(:new_assigned_user).with(@project.name, user.full_name, story.name, email_list).and_return(double(:deliver => nil))
|
30
|
-
@event_mailer.new_assigned_user(story)
|
31
|
-
end
|
32
|
-
|
33
|
-
it "alerts the notifier for a completed story on a project" do
|
34
|
-
story = Artisan::Repository.story.new(:name => "Test")
|
35
|
-
|
36
|
-
email_list = "hello@world.com, dude@test.com"
|
37
|
-
Notifier.should_receive(:completed_story).with(@project.name, story.name, email_list).and_return(double(:deliver => nil))
|
38
|
-
@event_mailer.completed_story(story)
|
39
|
-
end
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
context "archived projects" do
|
44
|
-
before(:each) do
|
45
|
-
@project = Artisan::Repository.project.new(:archived => true)
|
46
|
-
@event_mailer = EventMailer.new(@project)
|
47
|
-
end
|
48
|
-
|
49
|
-
it "does not alert the notifier of completed story if the project is archived" do
|
50
|
-
Notifier.should_not_receive(:completed_story)
|
51
|
-
@event_mailer.completed_story(nil)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "does not alert the notifier of a new assigned user if the project is archived" do
|
55
|
-
Notifier.should_not_receive(:new_assigned_user)
|
56
|
-
@event_mailer.new_assigned_user(nil)
|
57
|
-
end
|
58
|
-
|
59
|
-
end
|
60
|
-
|
61
|
-
describe "empty email lists" do
|
62
|
-
before(:each) do
|
63
|
-
@project = Artisan::Repository.project.new(:name => "Test")
|
64
|
-
@project_configuration = double(:story_completed_email_list => [], :story_assigned_email_list => [])
|
65
|
-
@project.project_configuration = @project_configuration
|
66
|
-
@event_mailer = EventMailer.new(@project)
|
67
|
-
end
|
68
|
-
|
69
|
-
it "does not alert notififer if the assigned email list is empty" do
|
70
|
-
user = Artisan::Repository.user.new(:full_name => "Mister McGoo")
|
71
|
-
story = Artisan::Repository.story.new(:assigned_user => user, :name => "Test")
|
72
|
-
|
73
|
-
Notifier.should_not_receive(:new_assigned_user)
|
74
|
-
@event_mailer.new_assigned_user(story)
|
75
|
-
end
|
76
|
-
|
77
|
-
it "does not alert the notifier if the completed email list is empty" do
|
78
|
-
story = Artisan::Repository.story.new(:name => "Test")
|
79
|
-
|
80
|
-
Notifier.should_not_receive(:new_assigned_user)
|
81
|
-
@event_mailer.completed_story(story)
|
82
|
-
end
|
83
|
-
|
84
|
-
end
|
85
|
-
|
86
|
-
end
|
data/spec/inviter_spec.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require "artisan/repository"
|
2
|
-
require "artisan/inviter"
|
3
|
-
require "spec_helper"
|
4
|
-
|
5
|
-
class FutureUsers; end
|
6
|
-
class Invites; end
|
7
|
-
|
8
|
-
describe Inviter do
|
9
|
-
let(:email) { 'test@user.com' }
|
10
|
-
let(:name) { 'Mister Person' }
|
11
|
-
|
12
|
-
before do
|
13
|
-
Invites.stub!(:invite).and_return(mock('invites', :deliver => nil))
|
14
|
-
end
|
15
|
-
|
16
|
-
context "alerts" do
|
17
|
-
it "alerts if name and email are nil" do
|
18
|
-
inviter = Inviter.new(nil, nil)
|
19
|
-
lambda{inviter.invite}.should raise_exception("Name and email fields are required, please fill out all fields and try again.")
|
20
|
-
end
|
21
|
-
|
22
|
-
it "alerts if name is blank" do
|
23
|
-
inviter = Inviter.new("", email)
|
24
|
-
lambda{inviter.invite}.should raise_exception("Name and email fields are required, please fill out all fields and try again.")
|
25
|
-
end
|
26
|
-
|
27
|
-
it "alerts if email is blank" do
|
28
|
-
inviter = Inviter.new(name, "")
|
29
|
-
lambda{inviter.invite}.should raise_exception("Name and email fields are required, please fill out all fields and try again.")
|
30
|
-
end
|
31
|
-
|
32
|
-
it "alerts if email is invalid" do
|
33
|
-
inviter = Inviter.new(name, "totallyNotAnEmail")
|
34
|
-
lambda{inviter.invite}.should raise_exception("Name and email fields are required, please fill out all fields and try again.")
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
context "sends invitations" do
|
39
|
-
it "delivers mail with valid addressed" do
|
40
|
-
mail = mock('invite mailer')
|
41
|
-
Invites.should_receive(:invite).with(name, email).and_return(mail)
|
42
|
-
mail.should_receive(:deliver)
|
43
|
-
inviter = Inviter.new(name, email)
|
44
|
-
inviter.invite
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
context "future users" do
|
49
|
-
it "Adds the email to the future users table" do
|
50
|
-
project = Artisan::Repository.project.create(:name => "Test")
|
51
|
-
|
52
|
-
inviter = Inviter.new(name, email)
|
53
|
-
inviter.add_to_future_users(project)
|
54
|
-
|
55
|
-
Artisan::Repository.future_user.find_by_email(email).project_id.should == project.id
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
data/spec/member_spec.rb
DELETED
@@ -1,58 +0,0 @@
|
|
1
|
-
require "artisan/member"
|
2
|
-
require "artisan-memory-repository/models/user"
|
3
|
-
require "artisan-memory-repository/models/project"
|
4
|
-
require "artisan-memory-repository/models/member"
|
5
|
-
|
6
|
-
describe Artisan::Member do
|
7
|
-
|
8
|
-
before(:each) do
|
9
|
-
@user = Artisan::Repository.user.new(:email => "test@gmail.com")
|
10
|
-
@project = Artisan::Repository.project.new
|
11
|
-
@member = Artisan::Repository.member.new
|
12
|
-
@member.stub!(:project).and_return(@project)
|
13
|
-
@member.stub!(:user).and_return(@user)
|
14
|
-
@members = Artisan::Member.new(@member)
|
15
|
-
end
|
16
|
-
|
17
|
-
it "adds the member to the project's completed story email list" do
|
18
|
-
@members.member.project.project_configuration = stub(:story_completed_email_list => []).as_null_object
|
19
|
-
|
20
|
-
@members.add_to_completed_list
|
21
|
-
|
22
|
-
@project.project_configuration.story_completed_email_list.should == [@user.email]
|
23
|
-
end
|
24
|
-
|
25
|
-
it "adds the member to the project's assigned story email list" do
|
26
|
-
@members.member.project.project_configuration = stub(:story_assigned_email_list => []).as_null_object
|
27
|
-
|
28
|
-
@members.add_to_assigned_list
|
29
|
-
|
30
|
-
@project.project_configuration.story_assigned_email_list.should == [@user.email]
|
31
|
-
end
|
32
|
-
|
33
|
-
it "removes the member from the project's completed story email list" do
|
34
|
-
@members.member.project.project_configuration = stub(:story_completed_email_list => [@user.email]).as_null_object
|
35
|
-
|
36
|
-
@members.remove_from_completed_list
|
37
|
-
|
38
|
-
@project.project_configuration.story_completed_email_list.should == []
|
39
|
-
end
|
40
|
-
|
41
|
-
it "removes the member from the project's assigned story email list" do
|
42
|
-
@members.member.project.project_configuration = stub(:story_assigned_email_list => [@user.email]).as_null_object
|
43
|
-
|
44
|
-
@members.remove_from_assigned_list
|
45
|
-
|
46
|
-
@project.project_configuration.story_assigned_email_list.should == []
|
47
|
-
end
|
48
|
-
|
49
|
-
it "removes the member from the project's email lists" do
|
50
|
-
@members.member.project.project_configuration = stub(:story_completed_email_list => [@user.email], :story_assigned_email_list => [@user.email]).as_null_object
|
51
|
-
|
52
|
-
@members.remove_from_email_lists
|
53
|
-
|
54
|
-
@project.project_configuration.story_completed_email_list.should == []
|
55
|
-
@project.project_configuration.story_assigned_email_list.should == []
|
56
|
-
end
|
57
|
-
|
58
|
-
end
|
data/spec/repository_spec.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require 'artisan/repository'
|
2
|
-
|
3
|
-
test_repo = Class.new(Artisan::Repository) {}
|
4
|
-
|
5
|
-
describe Artisan::Repository do
|
6
|
-
let(:fake_repo) do
|
7
|
-
Class.new do
|
8
|
-
def project
|
9
|
-
"fake-projects"
|
10
|
-
end
|
11
|
-
|
12
|
-
def story
|
13
|
-
"fake-stories"
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
let(:repo_instance) { fake_repo.new }
|
19
|
-
before { test_repo.register_repo(repo_instance) }
|
20
|
-
|
21
|
-
it "registers a top level repository" do
|
22
|
-
test_repo.repo.should == repo_instance
|
23
|
-
end
|
24
|
-
|
25
|
-
it "delegates to the given repository for stories" do
|
26
|
-
test_repo.story.should == "fake-stories"
|
27
|
-
end
|
28
|
-
|
29
|
-
it "delegates to the given repository for stories" do
|
30
|
-
test_repo.project.should == "fake-projects"
|
31
|
-
end
|
32
|
-
end
|
data/spec/story_board_spec.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
require "artisan/story_board"
|
2
|
-
require "artisan/stories/stories_interactor"
|
3
|
-
|
4
|
-
describe Artisan::StoryBoard do
|
5
|
-
let(:repository) { stub }
|
6
|
-
let(:iteration) { Artisan::Repository.iteration.create }
|
7
|
-
|
8
|
-
before do
|
9
|
-
Artisan::Repository.stub(:story).and_return(repository)
|
10
|
-
end
|
11
|
-
|
12
|
-
it "calculates total points for stories in backlog" do
|
13
|
-
iteration.stub!(:project).and_return(nil)
|
14
|
-
Artisan::Stories::StoriesInteractor.stub_chain(:new, :backlog, :points).and_return(5)
|
15
|
-
board = Artisan::StoryBoard.new(iteration)
|
16
|
-
board.backlog_total.should == 5
|
17
|
-
end
|
18
|
-
|
19
|
-
it "calculates total points for 'ready' stories" do
|
20
|
-
repository.should_receive(:ready).with(iteration).and_return([double(:estimate => 2), double(:estimate => 3)])
|
21
|
-
board = Artisan::StoryBoard.new(iteration)
|
22
|
-
board.ready_total.should == 5
|
23
|
-
end
|
24
|
-
|
25
|
-
it "calculates total points for 'working' stories" do
|
26
|
-
repository.should_receive(:working).with(iteration).and_return([double(:estimate => 2), double(:estimate => 3)])
|
27
|
-
board = Artisan::StoryBoard.new(iteration)
|
28
|
-
board.working_total.should == 5
|
29
|
-
end
|
30
|
-
|
31
|
-
it "calculates total points for 'complete' stories" do
|
32
|
-
repository.should_receive(:completed).with(iteration).and_return([double(:estimate => 2), double(:estimate => 3)])
|
33
|
-
board = Artisan::StoryBoard.new(iteration)
|
34
|
-
board.complete_total.should == 5
|
35
|
-
end
|
36
|
-
end
|