govuk_content_models 6.0.2
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/.gitignore +17 -0
- data/.ruby-version +1 -0
- data/.travis.yml +14 -0
- data/CONTRIBUTING.md +22 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.md +5 -0
- data/Rakefile +46 -0
- data/app/models/action.rb +60 -0
- data/app/models/answer_edition.rb +13 -0
- data/app/models/artefact.rb +341 -0
- data/app/models/artefact_action.rb +27 -0
- data/app/models/artefact_external_link.rb +15 -0
- data/app/models/business_support/business_size.rb +14 -0
- data/app/models/business_support/business_type.rb +14 -0
- data/app/models/business_support/location.rb +14 -0
- data/app/models/business_support/purpose.rb +14 -0
- data/app/models/business_support/sector.rb +14 -0
- data/app/models/business_support/stage.rb +14 -0
- data/app/models/business_support/support_type.rb +14 -0
- data/app/models/business_support_edition.rb +69 -0
- data/app/models/campaign_edition.rb +72 -0
- data/app/models/completed_transaction_edition.rb +14 -0
- data/app/models/curated_list.rb +32 -0
- data/app/models/edition.rb +286 -0
- data/app/models/expectant.rb +21 -0
- data/app/models/expectation.rb +12 -0
- data/app/models/guide_edition.rb +19 -0
- data/app/models/help_page_edition.rb +13 -0
- data/app/models/licence_edition.rb +35 -0
- data/app/models/local_authority.rb +58 -0
- data/app/models/local_interaction.rb +20 -0
- data/app/models/local_service.rb +49 -0
- data/app/models/local_transaction_edition.rb +49 -0
- data/app/models/overview_dashboard.rb +25 -0
- data/app/models/part.rb +28 -0
- data/app/models/parted.rb +32 -0
- data/app/models/place_edition.rb +20 -0
- data/app/models/programme_edition.rb +26 -0
- data/app/models/simple_smart_answer_edition.rb +66 -0
- data/app/models/simple_smart_answer_edition/node.rb +40 -0
- data/app/models/simple_smart_answer_edition/node/option.rb +31 -0
- data/app/models/tag.rb +88 -0
- data/app/models/transaction_edition.rb +28 -0
- data/app/models/travel_advice_edition.rb +177 -0
- data/app/models/user.rb +54 -0
- data/app/models/video_edition.rb +24 -0
- data/app/models/workflow.rb +217 -0
- data/app/models/workflow_actor.rb +141 -0
- data/app/traits/attachable.rb +60 -0
- data/app/traits/govspeak_smart_quotes_fixer.rb +19 -0
- data/app/traits/taggable.rb +113 -0
- data/app/validators/safe_html.rb +33 -0
- data/app/validators/slug_validator.rb +53 -0
- data/config/mongoid.yml +5 -0
- data/govuk_content_models.gemspec +42 -0
- data/jenkins.sh +7 -0
- data/lib/fact_check_address.rb +36 -0
- data/lib/govuk_content_models.rb +12 -0
- data/lib/govuk_content_models/require_all.rb +14 -0
- data/lib/govuk_content_models/test_helpers/factories.rb +213 -0
- data/lib/govuk_content_models/test_helpers/local_services.rb +24 -0
- data/lib/govuk_content_models/version.rb +4 -0
- data/test/fixtures/contactotron_api_response.json +1 -0
- data/test/fixtures/uploads/image.jpg +0 -0
- data/test/models/artefact_action_test.rb +123 -0
- data/test/models/artefact_external_link_test.rb +32 -0
- data/test/models/artefact_tag_test.rb +52 -0
- data/test/models/artefact_test.rb +583 -0
- data/test/models/business_support/business_size_test.rb +25 -0
- data/test/models/business_support/business_type_test.rb +25 -0
- data/test/models/business_support/location_test.rb +25 -0
- data/test/models/business_support/purpose_test.rb +29 -0
- data/test/models/business_support/sector_test.rb +25 -0
- data/test/models/business_support/stage_test.rb +25 -0
- data/test/models/business_support/support_type_test.rb +25 -0
- data/test/models/business_support_edition_test.rb +186 -0
- data/test/models/campaign_edition_test.rb +90 -0
- data/test/models/curated_list_test.rb +32 -0
- data/test/models/edition_test.rb +826 -0
- data/test/models/fact_check_address_test.rb +36 -0
- data/test/models/help_page_edition_test.rb +38 -0
- data/test/models/licence_edition_test.rb +104 -0
- data/test/models/local_authority_test.rb +113 -0
- data/test/models/local_service_test.rb +199 -0
- data/test/models/local_transaction_edition_test.rb +78 -0
- data/test/models/overview_dashboard_test.rb +47 -0
- data/test/models/simple_smart_answer_edition_test.rb +169 -0
- data/test/models/simple_smart_answer_node_test.rb +134 -0
- data/test/models/simple_smart_answer_option_test.rb +90 -0
- data/test/models/tag_test.rb +92 -0
- data/test/models/time_zone_test.rb +48 -0
- data/test/models/transaction_edition_test.rb +20 -0
- data/test/models/travel_advice_edition_test.rb +480 -0
- data/test/models/user_test.rb +114 -0
- data/test/models/video_edition_test.rb +64 -0
- data/test/models/workflow_actor_test.rb +61 -0
- data/test/models/workflow_test.rb +307 -0
- data/test/test_helper.rb +47 -0
- data/test/traits/attachable_test.rb +143 -0
- data/test/traits/taggable_test.rb +114 -0
- data/test/validators/safe_html_validator_test.rb +86 -0
- data/test/validators/slug_validator_test.rb +42 -0
- metadata +511 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"created_at":"2011-12-02T12:02:43Z","email_address":"contact@example.com","id":189,"name":"Contact Name","opening_hours":null,"postal_address":"1 High Street\nTown","updated_at":"2011-12-02T12:02:43Z","website_url":"http://www.example.com/","phone_numbers":[{"contact_id":189,"created_at":"2011-12-02T12:02:43Z","id":447,"kind":"phone","label":null,"updated_at":"2011-12-02T12:02:43Z","value":"0113 496 0123"},{"contact_id":189,"created_at":"2011-12-02T12:02:43Z","id":448,"kind":"fax","label":null,"updated_at":"2011-12-02T12:02:43Z","value":"028 9018 1337"}]}
|
|
Binary file
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
def merge_attributes(original, *update_hashes)
|
|
4
|
+
# Merge multiple attribute hashes: this also differs from Hash#merge in that
|
|
5
|
+
# it converts symbolic keys to strings
|
|
6
|
+
if update_hashes.empty?
|
|
7
|
+
return original
|
|
8
|
+
else
|
|
9
|
+
first_update, *other_updates = update_hashes
|
|
10
|
+
updated = first_update.reduce(original) do |old, pair|
|
|
11
|
+
key, value = pair
|
|
12
|
+
old.merge(key.to_s => value)
|
|
13
|
+
end
|
|
14
|
+
merge_attributes(updated, *other_updates)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class ArtefactActionTest < ActiveSupport::TestCase
|
|
19
|
+
|
|
20
|
+
DEFAULTS = {
|
|
21
|
+
"business_proposition" => false,
|
|
22
|
+
"active" => false,
|
|
23
|
+
"tag_ids" => [],
|
|
24
|
+
"state" => "draft",
|
|
25
|
+
"related_artefact_ids" => [],
|
|
26
|
+
"paths" => [],
|
|
27
|
+
"prefixes" => [],
|
|
28
|
+
"language" => "en",
|
|
29
|
+
"need_extended_font" => false
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
def base_fields
|
|
33
|
+
{
|
|
34
|
+
slug: "an-artefact",
|
|
35
|
+
name: "An artefact",
|
|
36
|
+
kind: "answer",
|
|
37
|
+
owning_app: "publisher"
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
test "a new artefact should have a create action" do
|
|
42
|
+
a = Artefact.create!(base_fields)
|
|
43
|
+
a.reload
|
|
44
|
+
|
|
45
|
+
assert_equal 1, a.actions.size
|
|
46
|
+
action = a.actions.first
|
|
47
|
+
assert_equal "create", action[:action_type]
|
|
48
|
+
assert_equal merge_attributes(DEFAULTS, base_fields), action.snapshot
|
|
49
|
+
assert action.created_at, "Action has no creation timestamp"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
test "an updated artefact should have two actions" do
|
|
53
|
+
a = Artefact.create!(base_fields)
|
|
54
|
+
a.description = "An artefact of shining wonderment."
|
|
55
|
+
a.save!
|
|
56
|
+
a.reload
|
|
57
|
+
|
|
58
|
+
assert_equal 2, a.actions.size
|
|
59
|
+
assert_equal ["create", "update"], a.actions.map(&:action_type)
|
|
60
|
+
create_snapshot = merge_attributes(DEFAULTS, base_fields)
|
|
61
|
+
update_snapshot = create_snapshot.merge("description" => a.description)
|
|
62
|
+
assert_equal create_snapshot, a.actions[0].snapshot
|
|
63
|
+
assert_equal update_snapshot, a.actions[1].snapshot
|
|
64
|
+
a.actions.each do |action|
|
|
65
|
+
assert action.created_at, "Action has no creation timestamp"
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
test "saving with no tracked changes will not create a new snapshot" do
|
|
70
|
+
a = Artefact.create!(base_fields)
|
|
71
|
+
a.updated_at = Time.zone.now + 5.minutes
|
|
72
|
+
a.save!
|
|
73
|
+
assert_equal 1, a.actions.size
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
test "updating attributes as a user should record a user action" do
|
|
77
|
+
a = Artefact.create!(base_fields)
|
|
78
|
+
user = FactoryGirl.create :user
|
|
79
|
+
updates = {description: "Shiny shiny description"}
|
|
80
|
+
a.update_attributes_as user, updates
|
|
81
|
+
a.reload
|
|
82
|
+
|
|
83
|
+
assert_equal "Shiny shiny description", a.description
|
|
84
|
+
assert_equal 2, a.actions.size
|
|
85
|
+
assert_equal ["create", "update"], a.actions.map(&:action_type)
|
|
86
|
+
assert_equal user, a.actions.last.user
|
|
87
|
+
assert_equal(
|
|
88
|
+
merge_attributes(DEFAULTS, base_fields, updates),
|
|
89
|
+
a.actions.last.snapshot
|
|
90
|
+
)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
test "saving as a user should record a user action" do
|
|
94
|
+
a = Artefact.create!(base_fields)
|
|
95
|
+
user = FactoryGirl.create :user
|
|
96
|
+
updates = {description: "Shiny shiny description"}
|
|
97
|
+
a.description = updates[:description]
|
|
98
|
+
a.save_as user
|
|
99
|
+
a.reload
|
|
100
|
+
|
|
101
|
+
assert_equal "Shiny shiny description", a.description
|
|
102
|
+
assert_equal 2, a.actions.size
|
|
103
|
+
assert_equal ["create", "update"], a.actions.map(&:action_type)
|
|
104
|
+
assert_equal user, a.actions.last.user
|
|
105
|
+
assert_equal(
|
|
106
|
+
merge_attributes(DEFAULTS, base_fields, updates),
|
|
107
|
+
a.actions.last.snapshot
|
|
108
|
+
)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
test "saving as a user with an action type" do
|
|
112
|
+
a = Artefact.create!(base_fields)
|
|
113
|
+
user = FactoryGirl.create :user
|
|
114
|
+
updates = {description: "Shiny shiny description"}
|
|
115
|
+
a.description = updates[:description]
|
|
116
|
+
a.save_as user, action_type: "awesome"
|
|
117
|
+
a.reload
|
|
118
|
+
|
|
119
|
+
assert_equal user, a.actions.last.user
|
|
120
|
+
assert_equal "awesome", a.actions.last.action_type
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class ArtefactExternalLinkTest < ActiveSupport::TestCase
|
|
4
|
+
context "validating a link" do
|
|
5
|
+
should "not be valid without a title or URL" do
|
|
6
|
+
refute ArtefactExternalLink.new.valid?
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
should "not be valid with URL missing" do
|
|
10
|
+
refute ArtefactExternalLink.new(:title => "Foo").valid?
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
should "not be valid with title missing" do
|
|
14
|
+
refute ArtefactExternalLink.new(:url => "http://bar.com").valid?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
should "be valid with both fields supplied" do
|
|
18
|
+
link = ArtefactExternalLink.new(:title => "Foo", :url => "http://bar.com")
|
|
19
|
+
assert link.valid?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should "only be valid if the URL is valid" do
|
|
23
|
+
link = ArtefactExternalLink.new(:title => "Foo", :url => "notreal://foo.com")
|
|
24
|
+
refute link.valid?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
should "be valid with an https URL" do
|
|
28
|
+
link = ArtefactExternalLink.new(:title => "Foo", :url => "https://bar.com")
|
|
29
|
+
assert link.valid?
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class ArtefactTagTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
TEST_SECTIONS = [
|
|
6
|
+
['crime', 'Crime'], ['crime/the-police', 'The Police'], ['crime/batman', 'Batman']
|
|
7
|
+
]
|
|
8
|
+
TEST_KEYWORDS = [['cheese', 'Cheese'], ['bacon', 'Bacon']]
|
|
9
|
+
|
|
10
|
+
setup do
|
|
11
|
+
TEST_SECTIONS.each do |tag_id, title|
|
|
12
|
+
FactoryGirl.create(:tag, :tag_id => tag_id, :tag_type => 'section', :title => title)
|
|
13
|
+
end
|
|
14
|
+
TEST_KEYWORDS.each do |tag_id, title|
|
|
15
|
+
FactoryGirl.create(:tag, :tag_id => tag_id, :tag_type => 'keyword', :title => title)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
test "return primary section title when asked for its section" do
|
|
20
|
+
a = FactoryGirl.create(:artefact)
|
|
21
|
+
a.sections = ['crime', 'crime/the-police']
|
|
22
|
+
a.primary_section = 'crime'
|
|
23
|
+
a.reconcile_tag_ids
|
|
24
|
+
|
|
25
|
+
assert_equal 'Crime', a.section
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "returns title of parent and child tags when its primary section has a parent" do
|
|
29
|
+
parent = Tag.by_tag_id('crime', 'section')
|
|
30
|
+
child = Tag.by_tag_id('crime/batman', 'section')
|
|
31
|
+
child.update_attributes parent_id: parent.tag_id
|
|
32
|
+
|
|
33
|
+
a = FactoryGirl.create(:artefact)
|
|
34
|
+
a.primary_section = child.tag_id
|
|
35
|
+
a.reconcile_tag_ids
|
|
36
|
+
|
|
37
|
+
assert_equal "#{parent.title}:#{child.title}", a.section
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
test "has legacy_sources tag collection" do
|
|
41
|
+
ls1 = FactoryGirl.create(:tag, :tag_id => 'businesslink', :tag_type => 'legacy_source', :title => 'Business Link')
|
|
42
|
+
ls2 = FactoryGirl.create(:tag, :tag_id => 'directgov', :tag_type => 'legacy_source', :title => 'Directgov')
|
|
43
|
+
ls3 = FactoryGirl.create(:tag, :tag_id => 'dvla', :tag_type => 'legacy_source', :title => 'DVLA')
|
|
44
|
+
|
|
45
|
+
a = FactoryGirl.build(:artefact)
|
|
46
|
+
a.legacy_sources = ['businesslink', 'dvla']
|
|
47
|
+
a.save
|
|
48
|
+
|
|
49
|
+
a = Artefact.first
|
|
50
|
+
assert_equal [ls1, ls3], a.legacy_sources
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,583 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class ArtefactTest < ActiveSupport::TestCase
|
|
4
|
+
context "validating slug" do
|
|
5
|
+
should "allow nice clean slugs" do
|
|
6
|
+
a = FactoryGirl.build(:artefact, slug: "its-a-nice-day")
|
|
7
|
+
assert a.valid?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
should "not allow apostrophes in slugs" do
|
|
11
|
+
a = FactoryGirl.build(:artefact, slug: "it's-a-nice-day")
|
|
12
|
+
refute a.valid?
|
|
13
|
+
assert a.errors[:slug].any?
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
should "not allow spaces in slugs" do
|
|
17
|
+
a = FactoryGirl.build(:artefact, slug: "it is-a-nice-day")
|
|
18
|
+
refute a.valid?
|
|
19
|
+
assert a.errors[:slug].any?
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
should "allow slashes in slugs when the namespace is 'done'" do
|
|
23
|
+
a = FactoryGirl.build(:artefact, slug: "done/its-a-nice-day")
|
|
24
|
+
assert a.valid?
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
should "not allow slashes in slugs when the namespace is not 'done'" do
|
|
28
|
+
a = FactoryGirl.build(:artefact, slug: "something-else/its-a-nice-day")
|
|
29
|
+
refute a.valid?
|
|
30
|
+
assert a.errors[:slug].any?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
should "allow travel-advice to have a slug prefixed with 'foreign-travel-advice/'" do
|
|
34
|
+
a = FactoryGirl.build(:artefact, slug: "foreign-travel-advice/aruba", kind: "travel-advice")
|
|
35
|
+
assert a.valid?
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
should "not allow multiple slashes in travel-advice artefacts" do
|
|
39
|
+
a = FactoryGirl.build(:artefact, slug: "foreign-travel-advice/aruba/foo", kind: "travel-advice")
|
|
40
|
+
refute a.valid?
|
|
41
|
+
assert a.errors[:slug].any?
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
should "not allow a foreign-travel-advice prefix for non-travel-advice artefacts" do
|
|
45
|
+
a = FactoryGirl.build(:artefact, slug: "foreign-travel-advice/aruba", kind: "answer")
|
|
46
|
+
refute a.valid?
|
|
47
|
+
assert a.errors[:slug].any?
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
should "allow a government prefix for Inside Government artefacts" do
|
|
51
|
+
a = FactoryGirl.build(:artefact, slug: "government/slug", kind: "case_study")
|
|
52
|
+
assert a.valid?
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
should "allow a government prefix and multiple path parts for Inside Government artefacts" do
|
|
56
|
+
a = FactoryGirl.build(:artefact, slug: "government/something/somewhere/somehow/slug", kind: "case_study")
|
|
57
|
+
assert a.valid?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
should "not allow a government prefix with invalid path parts" do
|
|
61
|
+
a = FactoryGirl.build(:artefact, slug: "government/SomeThing/some.where/somehow/slug", kind: "case_study")
|
|
62
|
+
refute a.valid?
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
should "require a government prefix for Inside Government artefacts" do
|
|
66
|
+
a = FactoryGirl.build(:artefact, slug: "slug", kind: "case_study")
|
|
67
|
+
refute a.valid?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
should "not require a government prefix for Detailed Guides" do
|
|
71
|
+
a = FactoryGirl.build(:artefact, slug: "slug", kind: "detailed_guide")
|
|
72
|
+
assert a.valid?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "help page special case" do
|
|
76
|
+
should "allow a help page to have a help/ prefix on the slug" do
|
|
77
|
+
a = FactoryGirl.build(:artefact, :slug => "help/foo", :kind => "help_page")
|
|
78
|
+
assert a.valid?
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
should "require a help page to have a help/ prefix on the slug" do
|
|
82
|
+
a = FactoryGirl.build(:artefact, :slug => "foo", :kind => "help_page")
|
|
83
|
+
refute a.valid?
|
|
84
|
+
assert_equal 1, a.errors[:slug].count
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
should "not allow other kinds to have a help/ prefix" do
|
|
88
|
+
a = FactoryGirl.build(:artefact, :slug => "help/foo", :kind => "answer")
|
|
89
|
+
refute a.valid?
|
|
90
|
+
assert_equal 1, a.errors[:slug].count
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
context "validating paths and prefixes" do
|
|
96
|
+
setup do
|
|
97
|
+
@a = FactoryGirl.build(:artefact)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
should "be valid when empty" do
|
|
101
|
+
@a.paths = []
|
|
102
|
+
@a.prefixes = []
|
|
103
|
+
assert @a.valid?
|
|
104
|
+
|
|
105
|
+
@a.paths = nil
|
|
106
|
+
@a.prefixes = nil
|
|
107
|
+
assert @a.valid?
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
should "be valid when set to array of absolute URL paths" do
|
|
111
|
+
@a.paths = ["/foo.json"]
|
|
112
|
+
@a.prefixes = ["/foo", "/bar"]
|
|
113
|
+
assert @a.valid?
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
should "be invalid if an entry is not a valid absolute URL path" do
|
|
117
|
+
[
|
|
118
|
+
"not a URL path",
|
|
119
|
+
"http://foo.example.com/bar",
|
|
120
|
+
"bar/baz",
|
|
121
|
+
"/foo/bar?baz=qux",
|
|
122
|
+
].each do |path|
|
|
123
|
+
@a.paths = ["/foo.json", path]
|
|
124
|
+
@a.prefixes = ["/foo", path]
|
|
125
|
+
refute @a.valid?
|
|
126
|
+
assert_equal 1, @a.errors[:paths].count
|
|
127
|
+
assert_equal 1, @a.errors[:prefixes].count
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
should "be invalid with consecutive or trailing slashes" do
|
|
132
|
+
[
|
|
133
|
+
"/foo//bar",
|
|
134
|
+
"/foo/bar///",
|
|
135
|
+
"//bar/baz",
|
|
136
|
+
"//",
|
|
137
|
+
"/foo/bar/",
|
|
138
|
+
].each do |path|
|
|
139
|
+
@a.paths = ["/foo.json", path]
|
|
140
|
+
@a.prefixes = ["/foo", path]
|
|
141
|
+
refute @a.valid?
|
|
142
|
+
assert_equal 1, @a.errors[:paths].count
|
|
143
|
+
assert_equal 1, @a.errors[:prefixes].count
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
should "skip validating these if they haven't changed" do
|
|
148
|
+
# This validation can be expensive, so skip it where unnecessary.
|
|
149
|
+
@a.paths = ["foo"]
|
|
150
|
+
@a.prefixes = ["bar"]
|
|
151
|
+
@a.save :validate => false
|
|
152
|
+
|
|
153
|
+
assert @a.valid?
|
|
154
|
+
end
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
test "should translate kind into internally normalised form" do
|
|
158
|
+
a = Artefact.new(kind: "benefit / scheme")
|
|
159
|
+
a.normalise
|
|
160
|
+
assert_equal "programme", a.kind
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
test "should not translate unknown kinds" do
|
|
164
|
+
a = Artefact.new(kind: "other")
|
|
165
|
+
a.normalise
|
|
166
|
+
assert_equal "other", a.kind
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
test "should store and return related artefacts in order" do
|
|
170
|
+
a = Artefact.create!(slug: "a", name: "a", kind: "place", need_id: 1, owning_app: "x")
|
|
171
|
+
b = Artefact.create!(slug: "b", name: "b", kind: "place", need_id: 2, owning_app: "x")
|
|
172
|
+
c = Artefact.create!(slug: "c", name: "c", kind: "place", need_id: 3, owning_app: "x")
|
|
173
|
+
|
|
174
|
+
a.related_artefacts = [b, c]
|
|
175
|
+
a.save!
|
|
176
|
+
a.reload
|
|
177
|
+
|
|
178
|
+
assert_equal [b, c], a.ordered_related_artefacts
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
test "should store and return related artefacts in order, even when not in natural order" do
|
|
182
|
+
a = Artefact.create!(slug: "a", name: "a", kind: "place", need_id: 1, owning_app: "x")
|
|
183
|
+
b = Artefact.create!(slug: "b", name: "b", kind: "place", need_id: 2, owning_app: "x")
|
|
184
|
+
c = Artefact.create!(slug: "c", name: "c", kind: "place", need_id: 3, owning_app: "x")
|
|
185
|
+
|
|
186
|
+
a.related_artefacts = [c, b]
|
|
187
|
+
a.save!
|
|
188
|
+
a.reload
|
|
189
|
+
|
|
190
|
+
assert_equal [c, b], a.ordered_related_artefacts
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
test "should store and return related artefacts in order, with a scope" do
|
|
194
|
+
a = Artefact.create!(slug: "a", name: "a", kind: "place", need_id: 1, owning_app: "x")
|
|
195
|
+
b = Artefact.create!(state: "live", slug: "b", name: "b", kind: "place", need_id: 2, owning_app: "x")
|
|
196
|
+
c = Artefact.create!(slug: "c", name: "c", kind: "place", need_id: 3, owning_app: "x")
|
|
197
|
+
d = Artefact.create!(state: "live", slug: "d", name: "d", kind: "place", need_id: 3, owning_app: "x")
|
|
198
|
+
|
|
199
|
+
a.related_artefacts = [d, c, b]
|
|
200
|
+
a.save!
|
|
201
|
+
a.reload
|
|
202
|
+
|
|
203
|
+
assert_equal [d, b], a.ordered_related_artefacts(a.related_artefacts.where(state: "live"))
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
test "published_related_artefacts should return all non-publisher artefacts, but only published publisher artefacts" do
|
|
207
|
+
# because currently only publisher has an idea of "published"
|
|
208
|
+
|
|
209
|
+
parent = Artefact.create!(slug: "parent", name: "Parent", kind: "guide", owning_app: "x")
|
|
210
|
+
|
|
211
|
+
a = Artefact.create!(slug: "a", name: "has no published editions", kind: "guide", owning_app: "publisher")
|
|
212
|
+
Edition.create!(panopticon_id: a.id, title: "Unpublished", state: "draft")
|
|
213
|
+
parent.related_artefacts << a
|
|
214
|
+
|
|
215
|
+
b = Artefact.create!(slug: "b", name: "has a published edition", kind: "guide", owning_app: "publisher")
|
|
216
|
+
Edition.create!(panopticon_id: b.id, title: "Published", state: "published")
|
|
217
|
+
parent.related_artefacts << b
|
|
218
|
+
|
|
219
|
+
c = Artefact.create!(slug: "c", name: "not a publisher artefact", kind: "place", owning_app: "x")
|
|
220
|
+
parent.related_artefacts << c
|
|
221
|
+
parent.save!
|
|
222
|
+
|
|
223
|
+
assert_equal [b.slug, c.slug], parent.published_related_artefacts.map(&:slug)
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
test "should raise a not found exception if the slug doesn't match" do
|
|
227
|
+
assert_raise Mongoid::Errors::DocumentNotFound do
|
|
228
|
+
Artefact.from_param("something-fake")
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
test "on save update metadata with associated publication" do
|
|
233
|
+
FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
|
|
234
|
+
artefact = FactoryGirl.create(:artefact,
|
|
235
|
+
slug: "foo-bar",
|
|
236
|
+
kind: "answer",
|
|
237
|
+
name: "Foo bar",
|
|
238
|
+
primary_section: "test-section",
|
|
239
|
+
sections: ["test-section"],
|
|
240
|
+
department: "Test dept",
|
|
241
|
+
owning_app: "publisher",
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
user1 = FactoryGirl.create(:user)
|
|
245
|
+
edition = AnswerEdition.find_or_create_from_panopticon_data(artefact.id, user1, {})
|
|
246
|
+
|
|
247
|
+
assert_equal artefact.name, edition.title
|
|
248
|
+
assert_equal artefact.section, edition.section
|
|
249
|
+
|
|
250
|
+
artefact.name = "Babar"
|
|
251
|
+
artefact.save
|
|
252
|
+
|
|
253
|
+
edition.reload
|
|
254
|
+
assert_equal artefact.name, edition.title
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
test "should not let you edit the slug if the artefact is live" do
|
|
258
|
+
artefact = FactoryGirl.create(:artefact,
|
|
259
|
+
slug: "too-late-to-edit",
|
|
260
|
+
kind: "answer",
|
|
261
|
+
name: "Foo bar",
|
|
262
|
+
owning_app: "publisher",
|
|
263
|
+
state: "live"
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
artefact.slug = "belated-correction"
|
|
267
|
+
refute artefact.save
|
|
268
|
+
|
|
269
|
+
assert_equal "too-late-to-edit", artefact.reload.slug
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# should continue to work in the way it has been:
|
|
273
|
+
# i.e. you can edit everything but the name/title for published content in panop
|
|
274
|
+
test "on save title should not be applied to already published content" do
|
|
275
|
+
FactoryGirl.create(:tag, tag_id: "test-section", title: "Test section", tag_type: "section")
|
|
276
|
+
artefact = FactoryGirl.create(:artefact,
|
|
277
|
+
slug: "foo-bar",
|
|
278
|
+
kind: "answer",
|
|
279
|
+
name: "Foo bar",
|
|
280
|
+
primary_section: "test-section",
|
|
281
|
+
sections: ["test-section"],
|
|
282
|
+
department: "Test dept",
|
|
283
|
+
owning_app: "publisher",
|
|
284
|
+
)
|
|
285
|
+
|
|
286
|
+
user1 = FactoryGirl.create(:user)
|
|
287
|
+
edition = AnswerEdition.find_or_create_from_panopticon_data(artefact.id, user1, {})
|
|
288
|
+
edition.state = "published"
|
|
289
|
+
edition.save!
|
|
290
|
+
|
|
291
|
+
assert_equal artefact.name, edition.title
|
|
292
|
+
assert_equal artefact.section, edition.section
|
|
293
|
+
|
|
294
|
+
artefact.name = "Babar"
|
|
295
|
+
artefact.save
|
|
296
|
+
|
|
297
|
+
edition.reload
|
|
298
|
+
assert_not_equal artefact.name, edition.title
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
test "should indicate when any editions have been published for this artefact" do
|
|
302
|
+
artefact = FactoryGirl.create(:artefact,
|
|
303
|
+
slug: "foo-bar",
|
|
304
|
+
kind: "answer",
|
|
305
|
+
name: "Foo bar",
|
|
306
|
+
owning_app: "publisher",
|
|
307
|
+
)
|
|
308
|
+
user1 = FactoryGirl.create(:user)
|
|
309
|
+
edition = AnswerEdition.find_or_create_from_panopticon_data(artefact.id, user1, {})
|
|
310
|
+
|
|
311
|
+
refute artefact.any_editions_published?
|
|
312
|
+
|
|
313
|
+
edition.state = "published"
|
|
314
|
+
edition.save!
|
|
315
|
+
|
|
316
|
+
assert artefact.any_editions_published?
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
test "should have a specialist_body field present for markdown content" do
|
|
320
|
+
artefact = Artefact.create!(slug: "parent", name: "Harry Potter", kind: "guide", owning_app: "x")
|
|
321
|
+
refute_includes artefact.attributes, "specialist_body"
|
|
322
|
+
|
|
323
|
+
artefact.specialist_body = "Something wicked this way comes"
|
|
324
|
+
assert_includes artefact.attributes, "specialist_body"
|
|
325
|
+
assert_equal "Something wicked this way comes", artefact.specialist_body
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
test "should have 'video' as a supported FORMAT" do
|
|
329
|
+
assert_includes Artefact::FORMATS, "video"
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
test "should find the default owning_app for a format" do
|
|
333
|
+
assert_equal "publisher", Artefact.default_app_for_format("guide")
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
test "should allow creation of artefacts with 'video' as the kind" do
|
|
337
|
+
artefact = Artefact.create!(slug: "omlette-du-fromage", name: "Omlette du fromage", kind: "video", owning_app: "Dexter's Lab")
|
|
338
|
+
|
|
339
|
+
refute artefact.nil?
|
|
340
|
+
assert_equal "video", artefact.kind
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
test "should archive all editions when archived" do
|
|
344
|
+
artefact = FactoryGirl.create(:artefact, state: "live")
|
|
345
|
+
editions = ["draft", "ready", "published", "archived"].map { |state|
|
|
346
|
+
FactoryGirl.create(:programme_edition, panopticon_id: artefact.id, state: state)
|
|
347
|
+
}
|
|
348
|
+
user1 = FactoryGirl.create(:user)
|
|
349
|
+
|
|
350
|
+
artefact.update_attributes_as(user1, state: "archived")
|
|
351
|
+
artefact.save!
|
|
352
|
+
|
|
353
|
+
editions.each &:reload
|
|
354
|
+
editions.each do |edition|
|
|
355
|
+
assert_equal "archived", edition.state
|
|
356
|
+
end
|
|
357
|
+
# remove the previously already archived edition, as no note will have been added
|
|
358
|
+
editions.pop
|
|
359
|
+
editions.each do |edition|
|
|
360
|
+
assert_equal "Artefact has been archived. Archiving this edition.", edition.actions.first.comment
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
test "should restrict what attributes can be updated on an edition that has an archived artefact" do
|
|
365
|
+
artefact = FactoryGirl.create(:artefact, state: "live")
|
|
366
|
+
edition = FactoryGirl.create(:programme_edition, panopticon_id: artefact.id, state: "published")
|
|
367
|
+
artefact.state = "archived"
|
|
368
|
+
artefact.save
|
|
369
|
+
assert_raise RuntimeError do
|
|
370
|
+
edition.update_attributes({state: "archived", title: "Shabba", slug: "do-not-allow"})
|
|
371
|
+
end
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
context "artefact language" do
|
|
375
|
+
should "return english by default" do
|
|
376
|
+
a = FactoryGirl.create(:artefact)
|
|
377
|
+
|
|
378
|
+
assert_equal 'en', a.language
|
|
379
|
+
end
|
|
380
|
+
|
|
381
|
+
should "accept welsh language" do
|
|
382
|
+
a = FactoryGirl.build(:artefact)
|
|
383
|
+
a.language = 'cy'
|
|
384
|
+
a.save
|
|
385
|
+
|
|
386
|
+
a = Artefact.first
|
|
387
|
+
assert_equal 'cy', a.language
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
should "reject a language which is not english or welsh" do
|
|
391
|
+
a = FactoryGirl.build(:artefact)
|
|
392
|
+
a.language = 'pirate'
|
|
393
|
+
|
|
394
|
+
assert ! a.valid?
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
should "has has_extended_chars field set to false by default" do
|
|
398
|
+
a = Artefact.new
|
|
399
|
+
assert_equal false, a.need_extended_font
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
should "allow has_extended_chars to be set" do
|
|
403
|
+
a = FactoryGirl.build(:artefact)
|
|
404
|
+
a.need_extended_font = true
|
|
405
|
+
a.save
|
|
406
|
+
|
|
407
|
+
a = Artefact.first
|
|
408
|
+
assert_equal true, a.need_extended_font
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
|
|
412
|
+
context "returning json representation" do
|
|
413
|
+
context "returning tags" do
|
|
414
|
+
setup do
|
|
415
|
+
FactoryGirl.create(:tag, :tag_type => 'section', :tag_id => 'crime', :title => 'Crime')
|
|
416
|
+
FactoryGirl.create(:tag, :tag_type => 'section', :tag_id => 'justice', :title => 'Justice', :description => "All about justice")
|
|
417
|
+
FactoryGirl.create(:tag, :tag_type => 'legacy_source', :tag_id => 'directgov', :title => 'Directgov')
|
|
418
|
+
FactoryGirl.create(:tag, :tag_type => 'legacy_source', :tag_id => 'businesslink', :title => 'Business Link')
|
|
419
|
+
|
|
420
|
+
@a = FactoryGirl.create(:artefact, :slug => 'fooey')
|
|
421
|
+
end
|
|
422
|
+
|
|
423
|
+
should "return empty array of tags and tag_ids" do
|
|
424
|
+
hash = @a.as_json
|
|
425
|
+
|
|
426
|
+
assert_equal [], hash['tag_ids']
|
|
427
|
+
assert_equal [], hash['tags']
|
|
428
|
+
end
|
|
429
|
+
|
|
430
|
+
context "for an artefact with tags" do
|
|
431
|
+
setup do
|
|
432
|
+
@a.sections = ['justice']
|
|
433
|
+
@a.legacy_sources = ['businesslink']
|
|
434
|
+
@a.save!
|
|
435
|
+
end
|
|
436
|
+
|
|
437
|
+
should "return an array of tag_id strings in tag_ids" do
|
|
438
|
+
hash = @a.as_json
|
|
439
|
+
|
|
440
|
+
assert_equal ['justice', 'businesslink'], hash['tag_ids']
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
should "return an array of tag objects in tags" do
|
|
444
|
+
hash = @a.as_json
|
|
445
|
+
|
|
446
|
+
expected = [
|
|
447
|
+
{
|
|
448
|
+
:id => 'justice',
|
|
449
|
+
:title => 'Justice',
|
|
450
|
+
:type => 'section',
|
|
451
|
+
:description => 'All about justice',
|
|
452
|
+
:short_description => nil
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
:id => 'businesslink',
|
|
456
|
+
:title => 'Business Link',
|
|
457
|
+
:type => 'legacy_source',
|
|
458
|
+
:description => nil,
|
|
459
|
+
:short_description => nil
|
|
460
|
+
}
|
|
461
|
+
]
|
|
462
|
+
assert_equal expected, hash['tags']
|
|
463
|
+
end
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
context "artefact related external links" do
|
|
469
|
+
should "have none by default" do
|
|
470
|
+
artefact = FactoryGirl.create(:artefact)
|
|
471
|
+
assert_equal 0, artefact.external_links.length
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
should "contain the title and URL of the link" do
|
|
475
|
+
artefact = FactoryGirl.create(:artefact)
|
|
476
|
+
artefact.external_links << ArtefactExternalLink.new(:title => "Foo", :url => "http://bar.com")
|
|
477
|
+
assert_equal 1, artefact.external_links.length
|
|
478
|
+
assert_equal "Foo", artefact.external_links.first.title
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
should "have an archived? helper method" do
|
|
483
|
+
published_artefact = FactoryGirl.create(:artefact, :slug => "scooby", :state => "live")
|
|
484
|
+
archived_artefact = FactoryGirl.create(:artefact, :slug => "doo", :state => "archived")
|
|
485
|
+
|
|
486
|
+
refute published_artefact.archived?
|
|
487
|
+
assert archived_artefact.archived?
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
should "have a related_items method which discards artefacts that are archived or completed transactions" do
|
|
491
|
+
generic = FactoryGirl.create(:artefact, slug: "generic")
|
|
492
|
+
archived = FactoryGirl.create(:artefact, :slug => "archived", :state => "archived")
|
|
493
|
+
completed = FactoryGirl.create(:artefact, slug: "completed-transaction", kind: "completed_transaction")
|
|
494
|
+
|
|
495
|
+
assert_equal [generic], Artefact.relatable_items
|
|
496
|
+
end
|
|
497
|
+
|
|
498
|
+
context "related artefacts grouped by section tags" do
|
|
499
|
+
setup do
|
|
500
|
+
FactoryGirl.create(:tag, :tag_id => "fruit", :tag_type => 'section', :title => "Fruit")
|
|
501
|
+
FactoryGirl.create(:tag, :tag_id => "fruit/simple", :tag_type => 'section', :title => "Simple fruits", :parent_id => "fruit")
|
|
502
|
+
FactoryGirl.create(:tag, :tag_id => "fruit/aggregate", :tag_type => 'section', :title => "Aggregrate fruits", :parent_id => "fruit")
|
|
503
|
+
FactoryGirl.create(:tag, :tag_id => "vegetables", :tag_type => 'section', :title => "Vegetables")
|
|
504
|
+
|
|
505
|
+
@artefact = Artefact.create!(slug: "apple", name: "Apple", sections: [], kind: "guide", need_id: 1, owning_app: "x")
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
context "when related items are present in all groups" do
|
|
509
|
+
setup do
|
|
510
|
+
@artefact.sections = ["fruit/simple"]
|
|
511
|
+
|
|
512
|
+
@artefact.related_artefacts = [
|
|
513
|
+
Artefact.create!(slug: "pear", name: "Pear", kind: "guide", sections: ["fruit/simple"], need_id: 4, owning_app: "x"),
|
|
514
|
+
Artefact.create!(slug: "pineapple", name: "Pineapple", kind: "guide", sections: ["fruit/aggregate"], need_id: 2, owning_app: "x"),
|
|
515
|
+
Artefact.create!(slug: "broccoli", name: "Broccoli", kind: "guide", sections: ["vegetables"], need_id: 3, owning_app: "x")
|
|
516
|
+
]
|
|
517
|
+
@artefact.save!
|
|
518
|
+
@artefact.reload
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
should "return a hash of artefacts in the same subsection" do
|
|
522
|
+
artefacts = @artefact.related_artefacts_grouped_by_distance
|
|
523
|
+
assert_equal ["pear"], artefacts['subsection'].map(&:slug)
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
should "return a hash of other artefacts in the same parent section" do
|
|
527
|
+
artefacts = @artefact.related_artefacts_grouped_by_distance
|
|
528
|
+
assert_equal ["pineapple"], artefacts['section'].map(&:slug)
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
should "return a hash of artefacts in other sections" do
|
|
532
|
+
artefacts = @artefact.related_artefacts_grouped_by_distance
|
|
533
|
+
assert_equal ["broccoli"], artefacts['other'].map(&:slug)
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
should "return related artefacts in order, with a scope" do
|
|
537
|
+
a = Artefact.create!(state: "live", slug: "a", name: "a", kind: "place", need_id: 1, owning_app: "x")
|
|
538
|
+
b = Artefact.create!(slug: "b", name: "b", kind: "place", need_id: 2, owning_app: "x")
|
|
539
|
+
c = Artefact.create!(state: "live", slug: "c", name: "c", kind: "place", need_id: 3, owning_app: "x")
|
|
540
|
+
|
|
541
|
+
@artefact.related_artefacts = [c,b,a]
|
|
542
|
+
@artefact.save!
|
|
543
|
+
@artefact.reload
|
|
544
|
+
|
|
545
|
+
assert_equal [c, a], @artefact.related_artefacts_grouped_by_distance(@artefact.related_artefacts.where(state: "live"))["other"]
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
|
|
549
|
+
should "return an empty array for a group with no related artefacts" do
|
|
550
|
+
# @artefact with no related items created in setup block
|
|
551
|
+
|
|
552
|
+
assert_equal [], @artefact.related_artefacts_grouped_by_distance["subsection"]
|
|
553
|
+
assert_equal [], @artefact.related_artefacts_grouped_by_distance["section"]
|
|
554
|
+
assert_equal [], @artefact.related_artefacts_grouped_by_distance["other"]
|
|
555
|
+
end
|
|
556
|
+
|
|
557
|
+
should "return all related artefacts in 'other' when an artefact has no sections" do
|
|
558
|
+
@artefact.related_artefacts = [
|
|
559
|
+
Artefact.create!(slug: "pear", name: "Pear", kind: "guide", sections: ["fruit/simple"], need_id: 4, owning_app: "x"),
|
|
560
|
+
Artefact.create!(slug: "banana", name: "Banana", kind: "guide", sections: ["fruit/simple"], need_id: 6, owning_app: "x")
|
|
561
|
+
]
|
|
562
|
+
|
|
563
|
+
assert_equal [], @artefact.related_artefacts_grouped_by_distance["subsection"]
|
|
564
|
+
assert_equal [], @artefact.related_artefacts_grouped_by_distance["section"]
|
|
565
|
+
assert_equal ["pear", "banana"], @artefact.related_artefacts_grouped_by_distance["other"].map(&:slug)
|
|
566
|
+
end
|
|
567
|
+
|
|
568
|
+
should "return no section level related artefacts if the primary section has no parent_id" do
|
|
569
|
+
FactoryGirl.create(:tag, :tag_id => "fruit/multiple", :tag_type => 'section', :title => "Multiple fruits", :parent_id => nil)
|
|
570
|
+
|
|
571
|
+
@artefact.primary_section = "fruit/multiple"
|
|
572
|
+
@artefact.related_artefacts = [
|
|
573
|
+
Artefact.create!(slug: "fig", name: "Fig", kind: "guide", sections: ["fruit/multiple"], need_id: 4, owning_app: "x"),
|
|
574
|
+
Artefact.create!(slug: "strawberry", name: "Strawberry", kind: "guide", sections: ["fruit/simple"], need_id: 6, owning_app: "x")
|
|
575
|
+
]
|
|
576
|
+
@artefact.save!
|
|
577
|
+
|
|
578
|
+
assert_equal ["fig"], @artefact.related_artefacts_grouped_by_distance["subsection"].map(&:slug)
|
|
579
|
+
assert_equal [], @artefact.related_artefacts_grouped_by_distance["section"]
|
|
580
|
+
assert_equal ["strawberry"], @artefact.related_artefacts_grouped_by_distance["other"].map(&:slug)
|
|
581
|
+
end
|
|
582
|
+
end
|
|
583
|
+
end
|