mingle_events 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +4 -0
- data/LICENSE.txt +202 -0
- data/README.textile +117 -0
- data/lib/mingle_events.rb +26 -0
- data/lib/mingle_events/feed.rb +5 -0
- data/lib/mingle_events/feed/author.rb +28 -0
- data/lib/mingle_events/feed/category.rb +75 -0
- data/lib/mingle_events/feed/element_support.rb +19 -0
- data/lib/mingle_events/feed/entry.rb +96 -0
- data/lib/mingle_events/feed/page.rb +61 -0
- data/lib/mingle_events/http_error.rb +26 -0
- data/lib/mingle_events/mingle_basic_auth_access.rb +71 -0
- data/lib/mingle_events/mingle_oauth_access.rb +40 -0
- data/lib/mingle_events/poller.rb +32 -0
- data/lib/mingle_events/processors.rb +10 -0
- data/lib/mingle_events/processors/author_filter.rb +62 -0
- data/lib/mingle_events/processors/card_data.rb +102 -0
- data/lib/mingle_events/processors/card_type_filter.rb +28 -0
- data/lib/mingle_events/processors/category_filter.rb +19 -0
- data/lib/mingle_events/processors/custom_property_filter.rb +30 -0
- data/lib/mingle_events/processors/http_post_publisher.rb +20 -0
- data/lib/mingle_events/processors/pipeline.rb +20 -0
- data/lib/mingle_events/processors/puts_publisher.rb +17 -0
- data/lib/mingle_events/project_custom_properties.rb +33 -0
- data/lib/mingle_events/project_event_fetcher.rb +96 -0
- data/test/mingle_events/feed/author_test.rb +39 -0
- data/test/mingle_events/feed/category_test.rb +20 -0
- data/test/mingle_events/feed/entry_test.rb +140 -0
- data/test/mingle_events/feed/page_test.rb +82 -0
- data/test/mingle_events/poller_test.rb +47 -0
- data/test/mingle_events/processors/author_filter_test.rb +80 -0
- data/test/mingle_events/processors/card_data_test.rb +210 -0
- data/test/mingle_events/processors/card_type_filter_test.rb +51 -0
- data/test/mingle_events/processors/category_filter_test.rb +27 -0
- data/test/mingle_events/processors/custom_property_filter_test.rb +51 -0
- data/test/mingle_events/processors/pipeline_test.rb +32 -0
- data/test/mingle_events/project_custom_properties_test.rb +39 -0
- data/test/mingle_events/project_event_fetcher_test.rb +122 -0
- data/test/test_helper.rb +163 -0
- data/test/web_hook_server/web_hook_server.rb +6 -0
- metadata +140 -0
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
|
2
|
+
|
3
|
+
module MingleEvents
|
4
|
+
module Processors
|
5
|
+
class CategoryFilterTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_removes_events_without_matching_categories
|
8
|
+
event_1 = stub_event(1, [Feed::Category::CARD, Feed::Category::COMMENT_ADDITION])
|
9
|
+
event_2 = stub_event(2, [Feed::Category::CARD, Feed::Category::PROPERTY_CHANGE])
|
10
|
+
event_3 = stub_event(3, [Feed::Category::REVISION_COMMIT])
|
11
|
+
event_4 = stub_event(4, [Feed::Category::CARD, Feed::Category::PROPERTY_CHANGE])
|
12
|
+
event_5 = stub_event(5, [])
|
13
|
+
events = [event_1, event_2, event_3, event_4, event_5]
|
14
|
+
|
15
|
+
filter = CategoryFilter.new([Feed::Category::CARD, Feed::Category::PROPERTY_CHANGE])
|
16
|
+
assert_equal([event_2, event_4], filter.process_events(events))
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def stub_event(id, categories)
|
22
|
+
OpenStruct.new(:entry_id => id, :categories => categories)
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
|
2
|
+
|
3
|
+
module MingleEvents
|
4
|
+
module Processors
|
5
|
+
|
6
|
+
class CustomPropertyFilterTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def test_filters_events_on_custom_property
|
9
|
+
event_1 = stub_event(true)
|
10
|
+
event_2 = stub_event(false)
|
11
|
+
event_3 = stub_event(true)
|
12
|
+
event_4 = stub_event(true)
|
13
|
+
event_5 = stub_event(true)
|
14
|
+
|
15
|
+
card_data = {
|
16
|
+
event_1 => {:custom_properties => {'Priority' => 'High'}},
|
17
|
+
event_3 => {:custom_properties => {'Priority' => 'Low'}},
|
18
|
+
event_4 => {:custom_properties => {'Priority' => 'High'}},
|
19
|
+
event_5 => {:custom_properties => {'Severity' => 'High'}}
|
20
|
+
}
|
21
|
+
def card_data.for_card_event(card_event)
|
22
|
+
self[card_event]
|
23
|
+
end
|
24
|
+
|
25
|
+
filter = CustomPropertyFilter.new('Priority', 'High', card_data)
|
26
|
+
filtered_events = filter.process_events([event_1, event_2, event_3, event_4, event_5])
|
27
|
+
assert_equal([event_1, event_4], filtered_events)
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_drops_events_for_deleted_cards
|
31
|
+
event_1 = stub_event(true)
|
32
|
+
|
33
|
+
card_data = {}
|
34
|
+
def card_data.for_card_event(card_event)
|
35
|
+
self[card_event]
|
36
|
+
end
|
37
|
+
|
38
|
+
filter = CustomPropertyFilter.new('Priority', 'High', card_data)
|
39
|
+
filtered_events = filter.process_events([event_1])
|
40
|
+
assert_equal([], filtered_events)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def stub_event(is_card)
|
46
|
+
OpenStruct.new(:card? => is_card)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'test_helper'))
|
2
|
+
|
3
|
+
module MingleEvents
|
4
|
+
module Processors
|
5
|
+
class PipelineTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_chains_all_processors
|
8
|
+
events = [stub_event(100), stub_event(101), stub_event(102)]
|
9
|
+
pipeline = Pipeline.new([DeleteLastProcessor.new, ReversingProcessor.new])
|
10
|
+
processed_events = pipeline.process_events(events)
|
11
|
+
assert_equal([101, 100], processed_events.map(&:entry_id))
|
12
|
+
end
|
13
|
+
|
14
|
+
def stub_event(id)
|
15
|
+
OpenStruct.new(:entry_id => id)
|
16
|
+
end
|
17
|
+
|
18
|
+
class ReversingProcessor
|
19
|
+
def process_events(events)
|
20
|
+
events.reverse
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class DeleteLastProcessor
|
25
|
+
def process_events(events)
|
26
|
+
events[0..-2]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
module MingleEvents
|
4
|
+
|
5
|
+
class ProjectCustomPropertiesTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
def test_can_lookup_property_name_by_column_name
|
8
|
+
property_definitions_xml = %{
|
9
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
10
|
+
<property_definitions type="array">
|
11
|
+
<property_definition>
|
12
|
+
<name>Account</name>
|
13
|
+
<data_type>string</data_type>
|
14
|
+
<is_numeric type="boolean">false</is_numeric>
|
15
|
+
<column_name>cp_account</column_name>
|
16
|
+
</property_definition>
|
17
|
+
<property_definition>
|
18
|
+
<name>Account ID</name>
|
19
|
+
<data_type>string</data_type>
|
20
|
+
<is_numeric type="boolean">false</is_numeric>
|
21
|
+
<column_name>cp_account_id</column_name>
|
22
|
+
</property_definition>
|
23
|
+
</property_definitions>
|
24
|
+
}
|
25
|
+
|
26
|
+
dummy_mingle_access = StubMingleAccess.new
|
27
|
+
dummy_mingle_access.register_page_content(
|
28
|
+
URI.escape('/api/v2/projects/atlas/property_definitions.xml'),
|
29
|
+
property_definitions_xml
|
30
|
+
)
|
31
|
+
|
32
|
+
project_custom_properties = ProjectCustomProperties.new(dummy_mingle_access, "atlas")
|
33
|
+
assert_equal("Account ID", project_custom_properties.property_name_for_column("cp_account_id"))
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'test_helper'))
|
2
|
+
|
3
|
+
module MingleEvents
|
4
|
+
class ProjectEventFetcherTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
def test_can_fetch_all_entries_and_write_to_disk_when_no_initial_state
|
7
|
+
state_dir = temp_dir
|
8
|
+
fetcher = ProjectEventFetcher.new('atlas', stub_mingle_access, state_dir)
|
9
|
+
|
10
|
+
file_for_first_new_entry = fetcher.fetch_latest
|
11
|
+
|
12
|
+
expected_entry_ids = [
|
13
|
+
'https://mingle.example.com/projects/atlas/events/index/23',
|
14
|
+
'https://mingle.example.com/projects/atlas/events/index/97',
|
15
|
+
'https://mingle.example.com/projects/atlas/events/index/98',
|
16
|
+
'https://mingle.example.com/projects/atlas/events/index/99',
|
17
|
+
'https://mingle.example.com/projects/atlas/events/index/100',
|
18
|
+
'https://mingle.example.com/projects/atlas/events/index/101',
|
19
|
+
'https://mingle.example.com/projects/atlas/events/index/103'
|
20
|
+
]
|
21
|
+
|
22
|
+
assert_expected_entry_chain_written_to_disk(expected_entry_ids, file_for_first_new_entry, fetcher)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_can_fetch_all_entries_and_write_to_disk_when_existing_state
|
26
|
+
state_dir = temp_dir
|
27
|
+
fetcher = ProjectEventFetcher.new('atlas', stub_mingle_access, state_dir)
|
28
|
+
setup_current_state(%{
|
29
|
+
<entry>
|
30
|
+
<id>https://mingle.example.com/projects/atlas/events/index/97</id>
|
31
|
+
<title>entry 97</title>
|
32
|
+
<updated>2011-02-03T01:10:52Z</updated>
|
33
|
+
<author><name>Harry</name></author>
|
34
|
+
</entry>}, fetcher)
|
35
|
+
|
36
|
+
file_for_first_new_entry = fetcher.fetch_latest
|
37
|
+
|
38
|
+
expected_entry_ids = [
|
39
|
+
'https://mingle.example.com/projects/atlas/events/index/98',
|
40
|
+
'https://mingle.example.com/projects/atlas/events/index/99',
|
41
|
+
'https://mingle.example.com/projects/atlas/events/index/100',
|
42
|
+
'https://mingle.example.com/projects/atlas/events/index/101',
|
43
|
+
'https://mingle.example.com/projects/atlas/events/index/103'
|
44
|
+
]
|
45
|
+
|
46
|
+
assert_expected_entry_chain_written_to_disk(expected_entry_ids, file_for_first_new_entry, fetcher)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_no_new_entries_with_current_state
|
50
|
+
state_dir = temp_dir
|
51
|
+
fetcher = ProjectEventFetcher.new('atlas', stub_mingle_access, state_dir)
|
52
|
+
setup_current_state(%{
|
53
|
+
<entry>
|
54
|
+
<id>https://mingle.example.com/projects/atlas/events/index/103</id>
|
55
|
+
<title>entry 103</title>
|
56
|
+
<updated>2011-02-03T01:10:52Z</updated>
|
57
|
+
<author><name>Harry</name></author>
|
58
|
+
</entry>}, fetcher)
|
59
|
+
|
60
|
+
assert_nil fetcher.fetch_latest
|
61
|
+
|
62
|
+
current_state = YAML.load(File.new(File.join(state_dir, 'current_state.yml')))
|
63
|
+
assert_equal(@last_fetched_entry_info_file, current_state[:last_fetched_entry_info_file])
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_no_new_entries_with_no_current_state
|
67
|
+
state_dir = temp_dir
|
68
|
+
mingle_access = StubMingleAccess.new
|
69
|
+
mingle_access.register_page_content('/api/v2/projects/atlas/feeds/events.xml',%{
|
70
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
71
|
+
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:mingle="http://www.thoughtworks-studios.com/ns/mingle">
|
72
|
+
<title>Mingle Events: Blank Project</title>
|
73
|
+
<id>https://mingle.example.com/api/v2/projects/blank_project/feeds/events.xml</id>
|
74
|
+
<link href="https://mingle.example.com/api/v2/projects/blank_project/feeds/events.xml" rel="current"/>
|
75
|
+
<link href="https://mingle.example.com/api/v2/projects/blank_project/feeds/events.xml" rel="self"/>
|
76
|
+
<updated>2011-08-04T19:42:04Z</updated>
|
77
|
+
</feed>})
|
78
|
+
fetcher = ProjectEventFetcher.new('atlas', mingle_access, state_dir)
|
79
|
+
|
80
|
+
assert_nil fetcher.fetch_latest
|
81
|
+
assert !File.exist?(File.join(state_dir, 'current_state.yml'))
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def setup_current_state(last_fetched_entry_xml, fetcher)
|
87
|
+
last_fetched_entry_info = {
|
88
|
+
:entry_xml => last_fetched_entry_xml,
|
89
|
+
:next_entry_file_path => nil
|
90
|
+
}
|
91
|
+
@last_fetched_entry_info_file = fetcher.file_for_entry(Feed::Entry.new(Nokogiri::XML(last_fetched_entry_xml).at('/entry')))
|
92
|
+
FileUtils.mkdir_p(File.dirname(@last_fetched_entry_info_file))
|
93
|
+
File.open(@last_fetched_entry_info_file, 'w') do |out|
|
94
|
+
YAML.dump(last_fetched_entry_info, out)
|
95
|
+
end
|
96
|
+
current_state = {:last_fetched_entry_info_file => @last_fetched_entry_info_file}
|
97
|
+
File.open(fetcher.current_state_file, 'w') do |out|
|
98
|
+
YAML.dump(current_state, out)
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
def assert_expected_entry_chain_written_to_disk(expected_entry_ids, file_for_first_new_entry, fetcher)
|
104
|
+
|
105
|
+
file_for_new_entry = file_for_first_new_entry
|
106
|
+
file_for_last_inspected_entry = nil
|
107
|
+
expected_entry_ids.each_with_index do |expected_entry_id, index|
|
108
|
+
file_for_last_inspected_entry = file_for_new_entry
|
109
|
+
new_entry_info = YAML.load(File.new(file_for_new_entry))
|
110
|
+
new_entry = Feed::Entry.new(Nokogiri::XML(new_entry_info[:entry_xml]).at('/entry'))
|
111
|
+
assert_equal(expected_entry_id, new_entry.entry_id)
|
112
|
+
file_for_new_entry = new_entry_info[:next_entry_file_path]
|
113
|
+
end
|
114
|
+
|
115
|
+
current_state = YAML.load(File.new(fetcher.current_state_file))
|
116
|
+
assert_equal(file_for_last_inspected_entry, current_state[:last_fetched_entry_info_file])
|
117
|
+
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'active_support'
|
8
|
+
|
9
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'mingle_events'))
|
10
|
+
|
11
|
+
MingleEvents.log.level = Logger::WARN
|
12
|
+
|
13
|
+
class Test::Unit::TestCase
|
14
|
+
|
15
|
+
# page 3
|
16
|
+
LATEST_PAGE_CONTENT = %{
|
17
|
+
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:mingle="http://www.thoughtworks-studios.com/ns/mingle">
|
18
|
+
|
19
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml" rel="current"/>
|
20
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml" rel="self"/>
|
21
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=2" rel="next"/>
|
22
|
+
|
23
|
+
<entry>
|
24
|
+
<id>https://mingle.example.com/projects/atlas/events/index/103</id>
|
25
|
+
<title>entry 103</title>
|
26
|
+
<updated>2011-02-03T08:12:42Z</updated>
|
27
|
+
<author><name>Bob</name></author>
|
28
|
+
</entry>
|
29
|
+
<entry>
|
30
|
+
<id>https://mingle.example.com/projects/atlas/events/index/101</id>
|
31
|
+
<title>entry 101</title>
|
32
|
+
<updated>2011-02-03T02:09:16Z</updated>
|
33
|
+
<author><name>Bob</name></author>
|
34
|
+
</entry>
|
35
|
+
<entry>
|
36
|
+
<id>https://mingle.example.com/projects/atlas/events/index/100</id>
|
37
|
+
<title>entry 100</title>
|
38
|
+
<updated>2011-02-03T01:58:02Z</updated>
|
39
|
+
<author><name>Mary</name></author>
|
40
|
+
</entry>
|
41
|
+
</feed>
|
42
|
+
}
|
43
|
+
|
44
|
+
# page 2
|
45
|
+
PAGE_2_CONTENT = %{
|
46
|
+
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:mingle="http://www.thoughtworks-studios.com/ns/mingle">
|
47
|
+
|
48
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml" rel="current"/>
|
49
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=2" rel="self"/>
|
50
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=1" rel="next"/>
|
51
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=3" rel="previous"/>
|
52
|
+
|
53
|
+
<entry>
|
54
|
+
<id>https://mingle.example.com/projects/atlas/events/index/99</id>
|
55
|
+
<title>entry 99</title>
|
56
|
+
<updated>2011-02-03T01:30:52Z</updated>
|
57
|
+
<author><name>Harry</name></author>
|
58
|
+
</entry>
|
59
|
+
|
60
|
+
<entry>
|
61
|
+
<id>https://mingle.example.com/projects/atlas/events/index/98</id>
|
62
|
+
<title>entry 98</title>
|
63
|
+
<updated>2011-02-03T01:20:52Z</updated>
|
64
|
+
<author><name>Harry</name></author>
|
65
|
+
</entry>
|
66
|
+
|
67
|
+
<entry>
|
68
|
+
<id>https://mingle.example.com/projects/atlas/events/index/97</id>
|
69
|
+
<title>entry 97</title>
|
70
|
+
<updated>2011-02-03T01:10:52Z</updated>
|
71
|
+
<author><name>Harry</name></author>
|
72
|
+
</entry>
|
73
|
+
</feed>
|
74
|
+
}
|
75
|
+
|
76
|
+
# page 1
|
77
|
+
PAGE_1_CONTENT = %{
|
78
|
+
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:mingle="http://www.thoughtworks-studios.com/ns/mingle">
|
79
|
+
|
80
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml" rel="current"/>
|
81
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=1" rel="self"/>
|
82
|
+
<link href="https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=2" rel="previous"/>
|
83
|
+
|
84
|
+
<entry>
|
85
|
+
<id>https://mingle.example.com/projects/atlas/events/index/23</id>
|
86
|
+
<title>entry 23</title>
|
87
|
+
<updated>2011-02-01T01:00:52Z</updated>
|
88
|
+
<author><name>Bob</name></author>
|
89
|
+
</entry>
|
90
|
+
</feed>
|
91
|
+
}
|
92
|
+
|
93
|
+
def stub_mingle_access
|
94
|
+
stub = StubMingleAccess.new
|
95
|
+
stub.register_page_content('https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml', LATEST_PAGE_CONTENT)
|
96
|
+
stub.register_page_content('https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=2', PAGE_2_CONTENT)
|
97
|
+
stub.register_page_content('https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=1', PAGE_1_CONTENT)
|
98
|
+
stub.register_page_content('https://mingle.example.com/api/v2/projects/atlas/feeds/events.xml?page=3', LATEST_PAGE_CONTENT)
|
99
|
+
stub.register_page_content('/api/v2/projects/atlas/feeds/events.xml', LATEST_PAGE_CONTENT)
|
100
|
+
stub.register_page_content('/api/v2/projects/atlas/feeds/events.xml?page=2', PAGE_2_CONTENT)
|
101
|
+
stub.register_page_content('/api/v2/projects/atlas/feeds/events.xml?page=1', PAGE_1_CONTENT)
|
102
|
+
stub.register_page_content('/api/v2/projects/atlas/feeds/events.xml?page=3', LATEST_PAGE_CONTENT)
|
103
|
+
|
104
|
+
stub
|
105
|
+
end
|
106
|
+
|
107
|
+
def temp_dir
|
108
|
+
path = File.expand_path(File.join(File.dirname(__FILE__), 'tmp', ActiveSupport::SecureRandom.hex(16)))
|
109
|
+
FileUtils.mkdir_p(path)
|
110
|
+
path
|
111
|
+
end
|
112
|
+
|
113
|
+
def temp_file
|
114
|
+
File.join(temp_dir, ActiveSupport::SecureRandom.hex(16))
|
115
|
+
end
|
116
|
+
|
117
|
+
class StubMingleAccess
|
118
|
+
|
119
|
+
def initialize
|
120
|
+
@pages_by_path = {}
|
121
|
+
@not_found_pages = []
|
122
|
+
end
|
123
|
+
|
124
|
+
def base_url
|
125
|
+
'http://example.com/mingle'
|
126
|
+
end
|
127
|
+
|
128
|
+
def register_page_content(path, content)
|
129
|
+
@pages_by_path[path] = content
|
130
|
+
end
|
131
|
+
|
132
|
+
def register_page_not_found(path)
|
133
|
+
@not_found_pages << path
|
134
|
+
end
|
135
|
+
|
136
|
+
def fetch_page(path)
|
137
|
+
if @not_found_pages.include?(path)
|
138
|
+
rsp = Net::HTTPNotFound.new(nil, '404', 'Page not found!')
|
139
|
+
def rsp.body
|
140
|
+
"404!!!!!"
|
141
|
+
end
|
142
|
+
raise MingleEvents::HttpError.new(rsp, path)
|
143
|
+
end
|
144
|
+
|
145
|
+
raise "Attempting to fetch page at #{path}, but your test has not registered content for this path! Registered paths: #{@pages_by_path.keys.inspect}" unless @pages_by_path.key?(path)
|
146
|
+
@pages_by_path[path]
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
|
151
|
+
class StubProjectCustomProperties
|
152
|
+
|
153
|
+
def initialize(property_names_by_column_names)
|
154
|
+
@property_names_by_column_names = property_names_by_column_names
|
155
|
+
end
|
156
|
+
|
157
|
+
def property_name_for_column(column_name)
|
158
|
+
@property_names_by_column_names[column_name]
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|