integrity 0.1.8 → 0.1.9.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.
Files changed (77) hide show
  1. data/README.markdown +7 -0
  2. data/Rakefile +77 -124
  3. data/config/config.ru +29 -0
  4. data/config/config.sample.ru +6 -16
  5. data/config/config.sample.yml +15 -12
  6. data/config/config.yml +34 -0
  7. data/lib/integrity.rb +13 -13
  8. data/lib/integrity/app.rb +138 -0
  9. data/lib/integrity/author.rb +39 -0
  10. data/lib/integrity/build.rb +54 -31
  11. data/lib/integrity/commit.rb +71 -0
  12. data/lib/integrity/helpers.rb +3 -3
  13. data/lib/integrity/helpers/authorization.rb +2 -2
  14. data/lib/integrity/helpers/forms.rb +3 -3
  15. data/lib/integrity/helpers/pretty_output.rb +1 -1
  16. data/lib/integrity/helpers/rendering.rb +6 -1
  17. data/lib/integrity/helpers/resources.rb +9 -3
  18. data/lib/integrity/helpers/urls.rb +15 -13
  19. data/lib/integrity/installer.rb +43 -60
  20. data/lib/integrity/migrations.rb +31 -48
  21. data/lib/integrity/notifier.rb +14 -16
  22. data/lib/integrity/notifier/base.rb +29 -19
  23. data/lib/integrity/notifier/test_helpers.rb +100 -0
  24. data/lib/integrity/project.rb +69 -33
  25. data/lib/integrity/project_builder.rb +23 -14
  26. data/lib/integrity/scm/git.rb +15 -14
  27. data/lib/integrity/scm/git/uri.rb +9 -9
  28. data/test/acceptance/api_test.rb +97 -0
  29. data/test/acceptance/browse_project_builds_test.rb +65 -0
  30. data/test/acceptance/browse_project_test.rb +95 -0
  31. data/test/acceptance/build_notifications_test.rb +42 -0
  32. data/test/acceptance/create_project_test.rb +97 -0
  33. data/test/acceptance/delete_project_test.rb +53 -0
  34. data/test/acceptance/edit_project_test.rb +117 -0
  35. data/test/acceptance/error_page_test.rb +18 -0
  36. data/test/acceptance/helpers.rb +2 -0
  37. data/test/acceptance/installer_test.rb +62 -0
  38. data/test/acceptance/manual_build_project_test.rb +82 -0
  39. data/test/acceptance/notifier_test.rb +109 -0
  40. data/test/acceptance/project_syndication_test.rb +30 -0
  41. data/test/acceptance/stylesheet_test.rb +18 -0
  42. data/test/helpers.rb +59 -26
  43. data/test/helpers/acceptance.rb +19 -65
  44. data/test/helpers/acceptance/email_notifier.rb +55 -0
  45. data/test/helpers/acceptance/git_helper.rb +15 -15
  46. data/test/helpers/acceptance/textfile_notifier.rb +3 -3
  47. data/test/helpers/expectations.rb +0 -1
  48. data/test/helpers/expectations/be_a.rb +4 -4
  49. data/test/helpers/expectations/change.rb +5 -5
  50. data/test/helpers/expectations/have.rb +4 -4
  51. data/test/helpers/expectations/predicates.rb +4 -4
  52. data/test/helpers/fixtures.rb +44 -18
  53. data/test/helpers/initial_migration_fixture.sql +44 -0
  54. data/test/unit/build_test.rb +51 -0
  55. data/test/unit/commit_test.rb +83 -0
  56. data/test/unit/helpers_test.rb +56 -0
  57. data/test/unit/integrity_test.rb +18 -0
  58. data/test/unit/migrations_test.rb +56 -0
  59. data/test/unit/notifier_test.rb +123 -0
  60. data/test/unit/project_builder_test.rb +108 -0
  61. data/test/unit/project_test.rb +282 -0
  62. data/test/unit/scm_test.rb +54 -0
  63. data/views/_commit_info.haml +24 -0
  64. data/views/build.haml +2 -2
  65. data/views/error.haml +4 -3
  66. data/views/home.haml +3 -5
  67. data/views/integrity.sass +19 -6
  68. data/views/new.haml +6 -6
  69. data/views/project.builder +9 -9
  70. data/views/project.haml +14 -12
  71. metadata +89 -122
  72. data/VERSION.yml +0 -4
  73. data/app.rb +0 -138
  74. data/integrity.gemspec +0 -76
  75. data/lib/integrity/core_ext/string.rb +0 -5
  76. data/test/helpers/expectations/have_tag.rb +0 -128
  77. data/views/_build_info.haml +0 -18
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + "/helpers"
2
+
3
+ class ManualBuildProjectTest < Test::Unit::AcceptanceTestCase
4
+ story <<-EOS
5
+ As an administrator,
6
+ I want to manually build my project
7
+ So that I know if it builds properly
8
+ EOS
9
+
10
+ scenario "clicking on 'Manual Build' triggers a successful build" do
11
+ git_repo(:my_test_project).add_successful_commit
12
+ Project.gen(:my_test_project, :uri => git_repo(:my_test_project).path)
13
+ login_as "admin", "test"
14
+
15
+ visit "/my-test-project"
16
+ click_button "manual build"
17
+
18
+ assert_have_tag("h1", :content =>
19
+ "Built #{git_repo(:my_test_project).short_head} successfully")
20
+ assert_have_tag("blockquote p", :content => "This commit will work")
21
+ assert_have_tag("span.who", :content => "by: John Doe")
22
+ assert_have_tag("span.when", :content => "today")
23
+ assert_have_tag("pre.output", :content => "Running tests...")
24
+ end
25
+
26
+ scenario "clicking on 'Manual Build' triggers a failed build" do
27
+ git_repo(:my_test_project).add_failing_commit
28
+ Project.gen(:my_test_project, :uri => git_repo(:my_test_project).path)
29
+ login_as "admin", "test"
30
+
31
+ visit "/my-test-project"
32
+ click_button "manual build"
33
+
34
+ assert_have_tag("h1",
35
+ :content => "Built #{git_repo(:my_test_project).short_head} and failed")
36
+ assert_have_tag("blockquote p", :content => "This commit will fail")
37
+ end
38
+
39
+ scenario "fixing the build command and then rebuilding result in a successful build" do
40
+ git_repo(:my_test_project).add_successful_commit
41
+ Project.gen(:my_test_project,
42
+ :uri => git_repo(:my_test_project).path,
43
+ :command => "ruby not-found.rb")
44
+
45
+ login_as "admin", "test"
46
+
47
+ visit "/my-test-project"
48
+ click_button "manual build"
49
+ assert_have_tag("h1", :content => "failed")
50
+
51
+ visit "/my-test-project/edit"
52
+ fill_in "Build script", :with => "./test"
53
+ click_button "Update Project"
54
+
55
+ visit "/my-test-project"
56
+ click_button "Build the last commit"
57
+
58
+ assert_have_tag("h1", :content => "success")
59
+ end
60
+
61
+ scenario "Successful builds should not display the 'Rebuild' button" do
62
+ git_repo(:my_test_project).add_successful_commit
63
+ Project.gen(:my_test_project, :uri => git_repo(:my_test_project).path)
64
+ login_as "admin", "test"
65
+
66
+ visit "/my-test-project"
67
+ click_button "manual build"
68
+
69
+ assert_have_no_tag("button", :content => "Rebuild")
70
+ end
71
+
72
+ scenario "Failed builds should display the 'Rebuild' button" do
73
+ git_repo(:my_test_project).add_failing_commit
74
+ Project.gen(:my_test_project, :uri => git_repo(:my_test_project).path)
75
+ login_as "admin", "test"
76
+
77
+ visit "/my-test-project"
78
+ click_button "manual build"
79
+
80
+ assert_have_tag("button", :content => "Rebuild")
81
+ end
82
+ end
@@ -0,0 +1,109 @@
1
+ require File.dirname(__FILE__) + "/helpers"
2
+
3
+ class NotifierConfigIssues < Test::Unit::AcceptanceTestCase
4
+ story <<-EOS
5
+ As an administrator,
6
+ I want to add multiple projects to Integrity,
7
+ So that I can be certain notifiers remain functional (cf #43)
8
+ EOS
9
+
10
+ before(:each) do
11
+ # This is needed before any available notifier is unset
12
+ # in the global #before
13
+ load File.dirname(__FILE__) + "/../helpers/acceptance/email_notifier.rb"
14
+ end
15
+
16
+ def fill_in_email_notifier
17
+ fill_in "notifiers[Email][to]", :with => "quentin@example.com"
18
+ fill_in "notifiers[Email][from]", :with => "ci@example.com"
19
+ fill_in "notifiers[Email][user]", :with => "inspector"
20
+ fill_in "notifiers[Email][pass]", :with => "gadget"
21
+ fill_in "notifiers[Email][auth]", :with => "simple"
22
+ fill_in "notifiers[Email][domain]", :with => "example.com"
23
+ end
24
+
25
+ def fill_in_project_info(name, repo)
26
+ fill_in "Name", :with => name
27
+ fill_in "Git repository", :with => repo
28
+ fill_in "Branch to track", :with => "master"
29
+ fill_in "Build script", :with => "rake"
30
+ check "Public project"
31
+
32
+ fill_in_email_notifier
33
+ end
34
+
35
+ def assert_have_email_notifier
36
+ assert_have_tag "input#email_notifier_to[@value='quentin@example.com']"
37
+ assert_have_tag "input#email_notifier_from[@value='ci@example.com']"
38
+ assert_have_tag "input#email_notifier_user[@value='inspector']"
39
+ assert_have_tag "input#email_notifier_pass[@value='gadget']"
40
+ assert_have_tag "input#email_notifier_auth[@value='simple']"
41
+ assert_have_tag "input#email_notifier_domain[@value='example.com']"
42
+ end
43
+
44
+ def add_project(name, repo)
45
+ visit "/new"
46
+ fill_in_project_info(name, repo)
47
+ click_button "Create Project"
48
+
49
+ assert_have_tag("h1", :content => name)
50
+ click_link 'Edit Project'
51
+ assert_have_email_notifier
52
+ end
53
+
54
+ def edit_project(name)
55
+ visit "/#{name}"
56
+ click_link "Edit Project"
57
+ assert_have_email_notifier
58
+ fill_in :branch, :with => "testing"
59
+ click_button "Update Project"
60
+ end
61
+
62
+ scenario "an admin can create a public project and retain mailer info" do
63
+ Project.first(:permalink => "integrity").should be_nil
64
+
65
+ login_as "admin", "test"
66
+
67
+ visit "/"
68
+ add_project "Integrity", "git://github.com/foca/integrity.git"
69
+ edit_project "integrity"
70
+
71
+ visit "/integrity"
72
+ click_link "Edit Project"
73
+
74
+ assert_have_email_notifier
75
+ end
76
+
77
+ scenario "an admin can create multiple public projects" do
78
+ Project.first(:permalink => "integrity").should be_nil
79
+
80
+ login_as "admin", "test"
81
+
82
+ visit "/"
83
+
84
+ add_project "Integrity", "git://github.com/foca/integrity.git"
85
+ click_link "projects"
86
+
87
+ add_project "Webrat", "git://github.com/brynary/webrat.git"
88
+ click_link "projects"
89
+
90
+ add_project "Rails", "git://github.com/rails/rails.git"
91
+ click_link "projects"
92
+
93
+ edit_project "integrity"
94
+ edit_project "webrat"
95
+ edit_project "rails"
96
+
97
+ visit "/integrity"
98
+ click_link "Edit Project"
99
+ assert_have_email_notifier
100
+
101
+ visit "/webrat"
102
+ click_link "Edit Project"
103
+ assert_have_email_notifier
104
+
105
+ visit "/rails"
106
+ click_link "Edit Project"
107
+ assert_have_email_notifier
108
+ end
109
+ end
@@ -0,0 +1,30 @@
1
+ require File.dirname(__FILE__) + "/helpers"
2
+
3
+ class ProjectSyndicationTest < Test::Unit::AcceptanceTestCase
4
+ story <<-EOS
5
+ As a user,
6
+ I want to subscribe to a public project's Atom feed
7
+ So I can know the status of my favorite projects while having my morning coffee
8
+ EOS
9
+
10
+ scenario "a public project's page includes an autodiscovery link tag for the feed" do
11
+ Project.gen(:integrity, :public => true)
12
+ visit "/integrity"
13
+
14
+ assert_have_tag("link[@href='/integrity.atom']")
15
+ end
16
+
17
+ scenario "a public project's feed should include the latest builds" do
18
+ commits = 10.of { Commit.gen(:successful) } + 1.of { Commit.gen(:failed) }
19
+ Project.gen(:integrity, :public => true, :commits => commits)
20
+
21
+ visit "/integrity.atom"
22
+
23
+ # TODO: check for content-type
24
+
25
+ assert_have_tag("feed title", :content => "Build history for Integrity")
26
+ assert_have_tag("feed entry", :count => 11)
27
+ assert_have_tag("feed entry:first title", :content => "success")
28
+ assert_have_tag("feed entry:last title", :content => "failed")
29
+ end
30
+ end
@@ -0,0 +1,18 @@
1
+ require File.dirname(__FILE__) + "/helpers"
2
+
3
+ class IntegrityStylesheetTest < Test::Unit::AcceptanceTestCase
4
+ story <<-EOS
5
+ As a user,
6
+ I want the stylesheet to work (even with Sinatra 0.9.1)
7
+ So that Integrity isn't a PITA to use
8
+ EOS
9
+
10
+ scenario "browsing on some Integrity install" do
11
+ visit "/integrity.css"
12
+
13
+ assert_contain("body {")
14
+ # TODO: better test
15
+ assert_equal %Q{"2465c472aacf302259dde5146a841e45"},
16
+ webrat_session.send(:response).headers["ETag"]
17
+ end
18
+ end
data/test/helpers.rb CHANGED
@@ -1,37 +1,43 @@
1
- require File.dirname(__FILE__) + "/../lib/integrity"
1
+ $:.unshift File.dirname(__FILE__) + "/../lib", File.dirname(__FILE__),
2
+ File.dirname(__FILE__) + "/../vendor/webrat/lib"
3
+
4
+ %w(test/unit
5
+ context
6
+ pending
7
+ matchy
8
+ storyteller
9
+ webrat/sinatra
10
+ rr
11
+ mocha
12
+ test/zentest_assertions
13
+ dm-sweatshop).each { |dependency|
14
+ begin
15
+ require dependency
16
+ rescue LoadError
17
+ puts "You're missing some gems required to run the tests."
18
+ puts "Please run `rake test:install_dependencies`"
19
+ puts "You'll probably need to run that command as root or with sudo."
20
+
21
+ puts "Thanks :)"
22
+ puts
23
+
24
+ exit 1
25
+ end
26
+ }
2
27
 
3
28
  begin
4
- require "test/unit"
5
- require "redgreen"
6
- require "context"
7
- require "storyteller"
8
- require "pending"
9
- require "matchy"
10
- require "rr"
11
- require "mocha"
12
29
  require "ruby-debug"
30
+ require "redgreen"
13
31
  rescue LoadError
14
- puts "You're missing some gems required to run the tests."
15
- puts "Please run `rake test:install_dependencies`"
16
- puts "You'll probably need to run that command as root or with sudo."
17
- puts
18
- puts "Thanks :)"
19
- puts
20
-
21
- exit 1
22
32
  end
23
33
 
24
- require File.dirname(__FILE__) / "helpers" / "expectations"
25
- require File.dirname(__FILE__) / "helpers" / "fixtures"
34
+ require "integrity"
35
+ require "helpers/expectations"
36
+ require "helpers/fixtures"
26
37
 
27
38
  module TestHelper
28
- def setup_and_reset_database!
29
- DataMapper.setup(:default, "sqlite3::memory:")
30
- DataMapper.auto_migrate!
31
- end
32
-
33
39
  def ignore_logs!
34
- stub(Integrity).log { nil }
40
+ Integrity.config[:log] = "/tmp/integrity.test.log"
35
41
  end
36
42
  end
37
43
 
@@ -43,5 +49,32 @@ class Test::Unit::TestCase
43
49
  include RR::Adapters::TestUnit
44
50
  include Integrity
45
51
  include TestHelper
46
- end
47
52
 
53
+ before(:all) do
54
+ DataMapper.setup(:default, "sqlite3::memory:")
55
+ end
56
+
57
+ before(:each) do
58
+ RR.reset
59
+ DataMapper.auto_migrate!
60
+ Integrity.instance_variable_set(:@config, nil)
61
+ Notifier.available.each { |n|
62
+ Notifier.send(:remove_const, n.to_s.split(":").last.to_sym)
63
+ }
64
+
65
+ repository(:default) do
66
+ transaction = DataMapper::Transaction.new(repository)
67
+ transaction.begin
68
+ repository.adapter.push_transaction(transaction)
69
+ end
70
+ end
71
+
72
+ after(:each) do
73
+ repository(:default) do
74
+ while repository.adapter.current_transaction
75
+ repository.adapter.current_transaction.rollback
76
+ repository.adapter.pop_transaction
77
+ end
78
+ end
79
+ end
80
+ end
@@ -1,67 +1,10 @@
1
- require 'webrat/rack'
2
- require 'sinatra'
3
- require 'sinatra/test'
4
-
5
- set :environment, :test
6
- disable :run
7
- disable :reload
8
-
9
- Webrat.configuration.instance_variable_set("@mode", :sinatra)
10
-
11
- module Webrat
12
- class SinatraSession < Session
13
- DEFAULT_DOMAIN = "integrity.example.org"
14
-
15
- def initialize(context = nil)
16
- super(context)
17
- @sinatra_test = Sinatra::TestHarness.new
18
- end
19
-
20
- %w(get head post put delete).each do |verb|
21
- class_eval <<-METHOD
22
- def #{verb}(path, data, headers = {})
23
- params = data.inject({}) do |data, (key,value)|
24
- data[key] = Rack::Utils.unescape(value)
25
- data
26
- end
27
- headers['HTTP_HOST'] = DEFAULT_DOMAIN
28
- @sinatra_test.#{verb}(path, params, headers)
29
- end
30
- METHOD
31
- end
32
-
33
- def response_body
34
- @sinatra_test.body
35
- end
36
-
37
- def response_code
38
- @sinatra_test.status
39
- end
40
-
41
- private
42
-
43
- def response
44
- @sinatra_test.response
45
- end
46
-
47
- def current_host
48
- URI.parse(current_url).host || DEFAULT_DOMAIN
49
- end
50
-
51
- def response_location_host
52
- URI.parse(response_location).host || DEFAULT_DOMAIN
53
- end
54
- end
55
- end
56
-
57
- require Integrity.root / "app"
58
- require File.dirname(__FILE__) / "acceptance/git_helper"
1
+ require "helpers/acceptance/git_helper"
59
2
 
60
3
  module AcceptanceHelper
61
4
  include FileUtils
62
5
 
63
6
  def export_directory
64
- Integrity.root / "exports"
7
+ File.dirname(__FILE__) + "/../../exports"
65
8
  end
66
9
 
67
10
  def enable_auth!
@@ -75,7 +18,7 @@ module AcceptanceHelper
75
18
  def AcceptanceHelper.logged_in; true; end
76
19
  basic_auth user, password
77
20
  visit "/login"
78
- Sinatra::Application.before { login_required if AcceptanceHelper.logged_in }
21
+ Integrity::App.before { login_required if AcceptanceHelper.logged_in }
79
22
  end
80
23
 
81
24
  def log_out
@@ -94,9 +37,9 @@ module AcceptanceHelper
94
37
  end
95
38
 
96
39
  def setup_log!
97
- pathname = Integrity.root / "integrity.log"
98
- FileUtils.rm pathname if File.exists?(pathname)
99
- Integrity.config[:log] = pathname
40
+ log_file = Pathname(File.dirname(__FILE__) + "/../../integrity.log")
41
+ log_file.delete if log_file.exist?
42
+ Integrity.config[:log] = log_file
100
43
  end
101
44
  end
102
45
 
@@ -105,15 +48,25 @@ class Test::Unit::AcceptanceTestCase < Test::Unit::TestCase
105
48
  include Test::Storyteller
106
49
  include GitHelper
107
50
  include Webrat::Methods
51
+ include Webrat::Matchers
52
+ include Webrat::HaveTagMatcher
53
+
54
+ # TODO: does this belongs in Webrat::SinatraSession?
108
55
  Webrat::Methods.delegate_to_session :response_code
109
56
 
57
+ def app
58
+ Integrity::App.tap { |app|
59
+ app.set :environment, :test
60
+ app.disable :raise_errors, :run, :reload
61
+ }
62
+ end
63
+
110
64
  before(:all) do
111
- Integrity.config[:base_uri] = "http://#{Webrat::SinatraSession::DEFAULT_DOMAIN}"
65
+ Integrity.config[:base_uri] = "http://www.example.com"
112
66
  end
113
67
 
114
68
  before(:each) do
115
69
  # ensure each scenario is run in a clean sandbox
116
- setup_and_reset_database!
117
70
  enable_auth!
118
71
  setup_log!
119
72
  set_and_create_export_directory!
@@ -124,4 +77,5 @@ class Test::Unit::AcceptanceTestCase < Test::Unit::TestCase
124
77
  destroy_all_git_repos
125
78
  rm_r export_directory if File.directory?(export_directory)
126
79
  end
80
+
127
81
  end