pageflow-linkmap-page 1.5.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -6
  3. data/Gemfile +0 -7
  4. data/README.md +0 -5
  5. data/app/assets/javascript/pageflow/linkmap_page/editor/collections/areas_collection.js +8 -1
  6. data/app/assets/javascript/pageflow/linkmap_page/editor/config.js +23 -1
  7. data/app/assets/javascript/pageflow/linkmap_page/editor/controllers/side_bar_controller.js +24 -5
  8. data/app/assets/javascript/pageflow/linkmap_page/editor/models/area.js +4 -1
  9. data/app/assets/javascript/pageflow/linkmap_page/editor/models/color_map_delegator.js +16 -0
  10. data/app/assets/javascript/pageflow/linkmap_page/editor/models/color_map_file.js +6 -0
  11. data/app/assets/javascript/pageflow/linkmap_page/editor/models/masked_image_file.js +7 -0
  12. data/app/assets/javascript/pageflow/linkmap_page/editor/models/page_configuration_mixin.js +49 -55
  13. data/app/assets/javascript/pageflow/linkmap_page/editor/models/processed_file.js +12 -0
  14. data/app/assets/javascript/pageflow/linkmap_page/editor/patterns/area_pattern.js +42 -0
  15. data/app/assets/javascript/pageflow/linkmap_page/editor/routers/side_bar_router.js +3 -1
  16. data/app/assets/javascript/pageflow/linkmap_page/editor/templates/embedded/area_item.jst.ejs +2 -2
  17. data/app/assets/javascript/pageflow/linkmap_page/editor/templates/embedded/area_masks_preview.jst.ejs +4 -2
  18. data/app/assets/javascript/pageflow/linkmap_page/editor/templates/embedded/area_outlines.jst.ejs +3 -2
  19. data/app/assets/javascript/pageflow/linkmap_page/editor/templates/embedded/mobile_info_box_page_item.jst.ejs +2 -0
  20. data/app/assets/javascript/pageflow/linkmap_page/editor/views/areas_list_view.js +1 -0
  21. data/app/assets/javascript/pageflow/linkmap_page/editor/views/configuration_editor_view.js +46 -0
  22. data/app/assets/javascript/pageflow/linkmap_page/editor/views/edit_area_view.js +3 -6
  23. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/area_item_embedded_view.js +75 -10
  24. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/area_masks_preview_embedded_view.js +71 -77
  25. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/area_outlines_embedded_view.js +44 -82
  26. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/areas_embedded_view.js +12 -13
  27. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/mobile_info_box_embedded_view.js +61 -0
  28. data/app/assets/javascript/pageflow/linkmap_page/editor/views/embedded/mobile_info_box_page_item_embedded_view.js +28 -0
  29. data/app/assets/javascript/pageflow/linkmap_page/editor.js +10 -2
  30. data/app/assets/javascript/pageflow/linkmap_page/page_type.js +155 -20
  31. data/app/assets/javascript/pageflow/linkmap_page/widgets/hover_video.js +4 -1
  32. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/area_contains.js +7 -6
  33. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/area_set_mask.js +16 -0
  34. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/color_map.js +83 -142
  35. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/image_data.js +17 -47
  36. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/mask.js +3 -34
  37. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/remote_image.js +3 -6
  38. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap.js +78 -92
  39. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_area_indicators.js +75 -0
  40. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_paginator.js +292 -0
  41. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_pan_zoom.js +241 -0
  42. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_panorama.js +81 -59
  43. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap_scroll_indicators.js +14 -0
  44. data/app/assets/stylesheets/pageflow/linkmap_page/editor/area_outlines.scss +6 -0
  45. data/app/assets/stylesheets/pageflow/linkmap_page/editor/masks_preview.scss +10 -0
  46. data/app/assets/stylesheets/pageflow/linkmap_page/themes/default/mobile_info_box.scss +31 -0
  47. data/app/assets/stylesheets/pageflow/linkmap_page/themes/default/paginator.scss +53 -0
  48. data/app/assets/stylesheets/pageflow/linkmap_page/themes/default/scroll_indicators.scss +5 -1
  49. data/app/assets/stylesheets/pageflow/linkmap_page/themes/default.scss +3 -0
  50. data/app/assets/stylesheets/pageflow/linkmap_page.scss +29 -3
  51. data/app/helpers/pageflow/linkmap_page/areas_helper.rb +37 -11
  52. data/app/jobs/pageflow/linkmap_page/process_source_image_file_job.rb +4 -4
  53. data/app/views/pageflow/linkmap_page/areas/_div.html.erb +13 -7
  54. data/app/views/pageflow/linkmap_page/color_map_files/_color_map_file.json.jbuilder +18 -0
  55. data/app/views/pageflow/linkmap_page/editor/color_map_files/_color_map_file.json.jbuilder +1 -0
  56. data/app/views/pageflow/linkmap_page/editor/masked_image_files/_masked_image_file.json.jbuilder +1 -0
  57. data/app/views/pageflow/linkmap_page/page.html.erb +76 -39
  58. data/config/locales/de.yml +47 -4
  59. data/config/locales/en.yml +43 -4
  60. data/db/migrate/20170330201200_create_mask_sprites.rb +1 -1
  61. data/db/migrate/20171106151700_create_masked_image_files.rb +1 -1
  62. data/db/migrate/20180111145100_create_color_map_files.rb +1 -1
  63. data/db/migrate/20180214201200_drop_mask_sprites.rb +7 -0
  64. data/lib/pageflow/linkmap_page/engine.rb +4 -0
  65. data/lib/pageflow/linkmap_page/page_type.rb +26 -0
  66. data/lib/pageflow/linkmap_page/paperclip_processors/color_mask.rb +1 -1
  67. data/lib/pageflow/linkmap_page/paperclip_processors/colors.rb +1 -1
  68. data/lib/pageflow/linkmap_page/version.rb +1 -1
  69. data/lib/tasks/pageflow_linkmap_page_tasks.rake +8 -7
  70. data/pageflow-linkmap-page.gemspec +11 -5
  71. data/spec/factories/color_map_file.rb +16 -0
  72. data/spec/factories/image_file.rb +25 -0
  73. data/spec/factories/masked_image_file.rb +10 -0
  74. data/spec/helpers/pageflow/linkmap_page/areas_helper_spec.rb +76 -13
  75. data/spec/integration/masked_image_file_type_spec.rb +15 -0
  76. data/spec/models/pageflow/linkmap_page/color_map_file_spec.rb +113 -0
  77. data/spec/models/pageflow/linkmap_page/masked_image_file_spec.rb +87 -0
  78. data/spec/pageflow/linkmap_page/paperclip_processors/colors_spec.rb +46 -0
  79. data/spec/pageflow/linkmap_page/progress_spec.rb +91 -0
  80. data/spec/spec_helper.rb +5 -1
  81. data/spec/support/config/devise.rb +1 -8
  82. data/spec/support/config/{factory_girl.rb → factory_bot.rb} +5 -3
  83. data/spec/support/config/resque.rb +9 -0
  84. data/spec/support/fixtures/black_dots.png +0 -0
  85. data/spec/support/fixtures/color_map.png +0 -0
  86. data/spec/support/fixtures/dots_and_lines.png +0 -0
  87. data/spec/support/fixtures/green_and_black.png +0 -0
  88. data/spec/support/fixtures/red.png +0 -0
  89. data/spec/support/fixtures/transparent.png +0 -0
  90. data/spec/support/matchers/have_color.rb +34 -0
  91. metadata +98 -41
  92. data/app/assets/javascript/pageflow/linkmap_page/editor/models/masks_delegator.js +0 -16
  93. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/area_redraw.js +0 -34
  94. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/mask_sprite.js +0 -68
  95. data/app/assets/javascript/pageflow/linkmap_page/widgets/linkmap/masks.js +0 -99
  96. data/app/controllers/pageflow/linkmap_page/mask_sprites_controller.rb +0 -26
  97. data/app/models/pageflow/linkmap_page/mask_sprite.rb +0 -15
  98. data/config/routes.rb +0 -5
  99. data/spec/controllers/pageflow/linkmap_page/mask_sprites_controller_spec.rb +0 -108
@@ -22,44 +22,107 @@ module Pageflow
22
22
  expect(html).to have_selector('div a[href]')
23
23
  end
24
24
 
25
- it 'renders hover image canvas inside linkmap areas' do
25
+ it 'renders hover image inside linkmap areas' do
26
26
  entry = create(:entry)
27
27
  configuration = {'linkmap_areas' => [{}], 'hover_image_id' => 5}
28
28
 
29
29
  html = helper.linkmap_areas_div(entry, configuration)
30
30
 
31
- expect(html).to have_selector('a canvas.hover_image')
31
+ expect(html).to have_selector('a div[class~="image_panorama_5"]')
32
32
  end
33
33
 
34
- it 'sets data-mask-id attribute if area has mask_perma_id' do
34
+ it 'renders masked hover image inside masked linkmap areas' do
35
35
  entry = create(:entry)
36
- configuration = {'linkmap_areas' => [{'mask_perma_id' => '1:2'}]}
36
+ color_map_file = create(:color_map_file)
37
+ masked_image_file = create(:masked_image_file)
38
+ configuration = {
39
+ 'linkmap_areas' => [{'mask_perma_id' => "#{color_map_file.id}:aaa"}],
40
+ 'hover_image_id' => 5,
41
+ 'linkmap_color_map_file_id' => color_map_file.id,
42
+ 'linkmap_masked_hover_image_id' => masked_image_file.id
43
+ }
37
44
 
38
45
  html = helper.linkmap_areas_div(entry, configuration)
39
46
 
40
- expect(html).to have_selector('a[data-mask-id="1:2"]')
47
+ image_class = "pageflow_linkmap_page_masked_image_file_aaa_#{masked_image_file.id}"
48
+ expect(html).to have_selector("a div[class~=#{image_class}]")
41
49
  end
42
50
 
43
- it 'does not set data-mask-id attribute if background type is hover_video' do
51
+ it 'only uses masked hover image if area is masked' do
44
52
  entry = create(:entry)
53
+ masked_image_file = create(:masked_image_file)
45
54
  configuration = {
46
- 'linkmap_areas' => [{'mask_perma_id' => '1:2'}],
47
- 'background_type' => 'hover_video'
55
+ 'linkmap_areas' => [{}],
56
+ 'hover_image_id' => 5,
57
+ 'linkmap_masked_hover_image_id' => masked_image_file.id
48
58
  }
49
59
 
50
60
  html = helper.linkmap_areas_div(entry, configuration)
51
61
 
52
- expect(html).not_to have_selector('a[data-mask-id]')
62
+ expect(html).to have_selector('a div[class~="image_panorama_5"]')
53
63
  end
54
64
 
55
- it 'renders attribute with url template for mask sprite' do
65
+ it 'does not use masked hover image if area mask perma id references other image' do
56
66
  entry = create(:entry)
57
- configuration = {}
67
+ masked_image_file = create(:masked_image_file)
68
+ color_map_file = create(:color_map_file)
69
+ other_id = color_map_file.id + 1
70
+ configuration = {
71
+ 'linkmap_areas' => [{'mask_perma_id' => "#{other_id}:aaa"}],
72
+ 'hover_image_id' => 5,
73
+ 'linkmap_masked_hover_image_id' => masked_image_file.id
74
+ }
75
+
76
+ html = helper.linkmap_areas_div(entry, configuration)
77
+
78
+ expect(html).to have_selector('a div[class~="image_panorama_5"]')
79
+ end
80
+
81
+ it 'renders visited image inside linkmap areas' do
82
+ entry = create(:entry)
83
+ configuration = {'linkmap_areas' => [{}], 'visited_image_id' => 5}
84
+
85
+ html = helper.linkmap_areas_div(entry, configuration)
86
+
87
+ expect(html).to have_selector('a div[class~="image_panorama_5"]')
88
+ end
89
+
90
+ it 'renders masked visited image inside masked linkmap areas' do
91
+ entry = create(:entry)
92
+ color_map_file = create(:color_map_file)
93
+ masked_image_file = create(:masked_image_file)
94
+ configuration = {
95
+ 'linkmap_areas' => [{'mask_perma_id' => "#{color_map_file.id}:aaa"}],
96
+ 'hover_image_id' => 5,
97
+ 'linkmap_color_map_file_id' => color_map_file.id,
98
+ 'linkmap_masked_visited_image_id' => masked_image_file.id
99
+ }
100
+
101
+ html = helper.linkmap_areas_div(entry, configuration)
102
+
103
+ image_class = "pageflow_linkmap_page_masked_image_file_aaa_#{masked_image_file.id}"
104
+ expect(html).to have_selector("a div[class~='#{image_class}']")
105
+ end
106
+
107
+ it 'sets data-mask-perma-id attribute if area has mask_perma_id' do
108
+ entry = create(:entry)
109
+ configuration = {'linkmap_areas' => [{'mask_perma_id' => '1:aaa'}]}
110
+
111
+ html = helper.linkmap_areas_div(entry, configuration)
112
+
113
+ expect(html).to have_selector('a[data-mask-perma-id="1:aaa"]')
114
+ end
115
+
116
+ it 'does not set data-mask-perma-id attribute if background type is hover_video' do
117
+ entry = create(:entry)
118
+ configuration = {
119
+ 'linkmap_areas' => [{'mask_perma_id' => '1:aaa'}],
120
+ 'background_type' => 'hover_video'
121
+ }
58
122
 
59
123
  html = helper.linkmap_areas_div(entry, configuration)
60
124
 
61
- url_matcher = 'attachments/:id_partition/original'
62
- expect(html).to have_selector("div[data-mask-sprite-url-template*='#{url_matcher}']")
125
+ expect(html).not_to have_selector('a[data-mask-perma-id]')
63
126
  end
64
127
  end
65
128
 
@@ -0,0 +1,15 @@
1
+ require 'spec_helper'
2
+
3
+ require 'pageflow/lint'
4
+
5
+ module Pageflow
6
+ module LinkmapPage
7
+ Pageflow::Lint.file_type(:masked_image_file,
8
+ create_file_type: -> { LinkmapPage.masked_image_file_type },
9
+ create_file: -> { create(:masked_image_file) })
10
+
11
+ Pageflow::Lint.file_type(:color_map_file,
12
+ create_file_type: -> { LinkmapPage.color_map_file_type },
13
+ create_file: -> { create(:color_map_file) })
14
+ end
15
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ module Pageflow
4
+ module LinkmapPage
5
+ describe ColorMapFile, inline_resque: true do
6
+ let(:red_from_palette) { 'f65b57' }
7
+ let(:green_from_palette) { '69a77b' }
8
+
9
+ describe 'process' do
10
+ it 'remaps colors to fixed palette' do
11
+ image_file = create(:image_file, :red_fixture)
12
+ color_map_file = create(:color_map_file, source_image_file: image_file)
13
+
14
+ color_map_file.process
15
+ color_map_file.reload
16
+
17
+ expect(color_map_file.processed_attachment)
18
+ .to have_color(red_from_palette).at(left: 0, top: 0)
19
+ end
20
+
21
+ it 'removes dots and shapes that are smaller than 3x3' do
22
+ image_file = create(:image_file, :dots_and_lines_fixture)
23
+ color_map_file = create(:color_map_file, source_image_file: image_file)
24
+
25
+ color_map_file.process
26
+ color_map_file.reload
27
+
28
+ expect(color_map_file.present_colors.size).to eq(1)
29
+ end
30
+
31
+ it 'handles black the same as transparency' do
32
+ image_file = create(:image_file, :green_and_black_fixture)
33
+ color_map_file = create(:color_map_file, source_image_file: image_file)
34
+
35
+ color_map_file.process
36
+ color_map_file.reload
37
+
38
+ expect(color_map_file.present_colors.size).to eq(1)
39
+ end
40
+
41
+ it 'stores colors used in remapped image' do
42
+ image_file = create(:image_file, :red_fixture)
43
+ color_map_file = create(:color_map_file, source_image_file: image_file)
44
+
45
+ color_map_file.process
46
+ color_map_file.reload
47
+
48
+ expect(color_map_file.present_colors).to eql([red_from_palette])
49
+ end
50
+
51
+ it 'stores width and height of resized image' do
52
+ image_file = create(:image_file, :color_map_fixture)
53
+ color_map_file = create(:color_map_file, source_image_file: image_file)
54
+
55
+ color_map_file.process
56
+ color_map_file.reload
57
+
58
+ expect(color_map_file.width).to eq(20)
59
+ expect(color_map_file.height).to eq(10)
60
+ end
61
+
62
+ it 'stores bounding boxes of colors' do
63
+ image_file = create(:image_file, :color_map_fixture)
64
+ color_map_file = create(:color_map_file, source_image_file: image_file)
65
+
66
+ color_map_file.process
67
+ color_map_file.reload
68
+
69
+ expect(color_map_file.bounding_box_for_color(red_from_palette))
70
+ .to eql(left: 0,
71
+ top: 0,
72
+ width: color_map_file.width / 2,
73
+ height: color_map_file.height / 5 * 2)
74
+
75
+ expect(color_map_file.bounding_box_for_color(green_from_palette))
76
+ .to eql(left: color_map_file.width / 2,
77
+ top: 0,
78
+ width: color_map_file.width / 2,
79
+ height: color_map_file.height)
80
+ end
81
+
82
+ let(:pixel_where_sprite_is_green) { {left: 0, top: 0} }
83
+ let(:pixel_where_sprite_is_red) { {right: 0, top: 0} }
84
+ let(:pixel_where_sprite_is_transparent) { {right: 0, bottom: 0} }
85
+
86
+ it 'creates sprite with color components sorted by color name' do
87
+ image_file = create(:image_file, :color_map_fixture)
88
+ color_map_file = create(:color_map_file, source_image_file: image_file)
89
+
90
+ color_map_file.process
91
+ color_map_file.reload
92
+
93
+ expect(color_map_file.attachment.styles[:sprite])
94
+ .to have_color(green_from_palette).at(pixel_where_sprite_is_green)
95
+ expect(color_map_file.attachment.styles[:sprite])
96
+ .to have_color(red_from_palette).at(pixel_where_sprite_is_red)
97
+ expect(color_map_file.attachment.styles[:sprite])
98
+ .to have_color(:transparent).at(pixel_where_sprite_is_transparent)
99
+ end
100
+
101
+ it 'sets processing progress' do
102
+ image_file = create(:image_file, :color_map_fixture)
103
+ color_map_file = create(:color_map_file, source_image_file: image_file)
104
+
105
+ color_map_file.process
106
+ color_map_file.reload
107
+
108
+ expect(color_map_file.processing_progress).to eq(100)
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ module Pageflow
4
+ module LinkmapPage
5
+ describe MaskedImageFile, inline_resque: true do
6
+ let :color_map_file do
7
+ color_map_image_file = create(:image_file, :color_map_fixture)
8
+
9
+ create(:color_map_file,
10
+ :processed,
11
+ source_image_file: color_map_image_file)
12
+ end
13
+
14
+ let(:pixel_where_color_map_is_red) { {left: 0, top: 0} }
15
+ let(:pixel_where_color_map_is_green) { {right: 0, top: 0} }
16
+ let(:pixel_where_color_map_is_transparent) { {left: 0, bottom: 1} }
17
+
18
+ let(:red_from_color_map_palette) { 'f65b57' }
19
+ let(:green_from_color_map_palette) { '69a77b' }
20
+
21
+ let :transparent_source_image_file do
22
+ create(:image_file, :transparent_fixture)
23
+ end
24
+
25
+ let :single_color_source_image_file do
26
+ create(:image_file, :red_fixture)
27
+ end
28
+
29
+ let(:color_of_source_image) { '#ff0000' }
30
+
31
+ describe 'process' do
32
+ it 'creates images for each color in color map masked to the area of that color' do
33
+ masked_image_file = create(:masked_image_file,
34
+ color_map_file: color_map_file,
35
+ source_image_file: single_color_source_image_file)
36
+
37
+ masked_image_file.process
38
+ masked_image_file.reload
39
+
40
+ expect(masked_image_file.for_color(red_from_color_map_palette))
41
+ .to have_color(color_of_source_image).at(pixel_where_color_map_is_red)
42
+
43
+ expect(masked_image_file.for_color(green_from_color_map_palette))
44
+ .to have_color(color_of_source_image).at(pixel_where_color_map_is_green)
45
+ end
46
+
47
+ it 'leaves other parts of the image transparent' do
48
+ masked_image_file = create(:masked_image_file,
49
+ color_map_file: color_map_file,
50
+ source_image_file: single_color_source_image_file)
51
+
52
+ masked_image_file.process
53
+ masked_image_file.reload
54
+
55
+ expect(masked_image_file.for_color(red_from_color_map_palette))
56
+ .to have_color(:transparent).at(pixel_where_color_map_is_green)
57
+
58
+ expect(masked_image_file.for_color(red_from_color_map_palette))
59
+ .to have_color(:transparent).at(pixel_where_color_map_is_transparent)
60
+ end
61
+
62
+ it 'leaves transparent areas of source image transparent' do
63
+ masked_image_file = create(:masked_image_file,
64
+ color_map_file: color_map_file,
65
+ source_image_file: transparent_source_image_file)
66
+
67
+ masked_image_file.process
68
+ masked_image_file.reload
69
+
70
+ expect(masked_image_file.for_color(red_from_color_map_palette))
71
+ .to have_color(:transparent).at(pixel_where_color_map_is_red)
72
+ end
73
+
74
+ it 'updates processing progress' do
75
+ masked_image_file = create(:masked_image_file,
76
+ color_map_file: color_map_file,
77
+ source_image_file: single_color_source_image_file)
78
+
79
+ masked_image_file.process
80
+ masked_image_file.reload
81
+
82
+ expect(masked_image_file.processing_progress).to eq(100)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ module Pageflow
4
+ module LinkmapPage
5
+ module PaperclipProcessors
6
+ describe Colors::ConvertOutput do
7
+ describe '.parse_unique_colors' do
8
+ it 'parses hex colors from output' do
9
+ output = <<-OUTPUT.unindent
10
+ # ImageMagick pixel enumeration: 3,1,255,srgba
11
+ 0,0: (246,91,87,1) #F65B57 srgba(246,91,87,1)
12
+ 1,0: (105,167,123,1) #69A77B srgba(105,167,123,1)
13
+ 2,0: (0,0,0,0) #00000000 none
14
+ OUTPUT
15
+
16
+ result = Colors::ConvertOutput.parse_unique_colors(output)
17
+
18
+ expect(result).to eq(%w(69a77b f65b57))
19
+ end
20
+ end
21
+
22
+ describe '.parse_trim' do
23
+ it 'parses trimmed dimensions' do
24
+ output = <<-OUTPUT.unindent
25
+ file.png PNG 724x665 1920x1080+606+210 8-bit sRGB 0.010u 0:00.00
26
+ OUTPUT
27
+
28
+ result = Colors::ConvertOutput.parse_trim(output)
29
+
30
+ expect(result).to eq(left: 606, top: 210, width: 724, height: 665)
31
+ end
32
+
33
+ it 'handles empty image output correctly' do
34
+ output = <<-OUTPUT.unindent
35
+ file.png PNG 1x1 1920x1080-1-1 8-bit sRGB 0.010u 0:00.00
36
+ OUTPUT
37
+
38
+ result = Colors::ConvertOutput.parse_trim(output)
39
+
40
+ expect(result).to eq(left: 0, top: 0, width: 0, height: 0)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ module Pageflow
4
+ module LinkmapPage
5
+ describe Progress do
6
+ it 'reports percentage values after each step' do
7
+ reported_values = []
8
+ progress = Progress.new(steps: 4) do |percent|
9
+ reported_values << percent
10
+ end
11
+
12
+ 4.times { progress.step }
13
+
14
+ expect(reported_values).to eq([25, 50, 75, 100])
15
+ end
16
+
17
+ it 'supports dividing a step into sub steps' do
18
+ reported_values = []
19
+ progress = Progress.new(steps: 2) do |percent|
20
+ reported_values << percent
21
+ end
22
+
23
+ progress.divide(steps: 4) do |p|
24
+ 4.times { p.step }
25
+ end
26
+ progress.divide(steps: 2) do |p|
27
+ 2.times { p.step }
28
+ end
29
+
30
+ expect(reported_values).to eq([12.5, 25, 37.5, 50, 75, 100])
31
+ end
32
+
33
+ it 'supports mixing normal and divided steps' do
34
+ reported_values = []
35
+ progress = Progress.new(steps: 3) do |percent|
36
+ reported_values << percent.round(1)
37
+ end
38
+
39
+ progress.step
40
+ progress.divide(steps: 2) do |p|
41
+ 2.times { p.step }
42
+ end
43
+ progress.step
44
+
45
+ expect(reported_values).to eq([33.3, 50, 66.7, 100])
46
+ end
47
+
48
+ it 'calling step to often is ignored' do
49
+ reported_values = []
50
+ progress = Progress.new(steps: 2) do |percent|
51
+ reported_values << percent
52
+ end
53
+
54
+ progress.step
55
+ progress.step
56
+ progress.step
57
+
58
+ expect(reported_values).to eq([50, 100])
59
+ end
60
+
61
+ it 'calling divide when no step is left is ignored' do
62
+ reported_values = []
63
+ progress = Progress.new(steps: 2) do |percent|
64
+ reported_values << percent
65
+ end
66
+
67
+ progress.step
68
+ progress.step
69
+ progress.divide(steps: 2) do |p|
70
+ p.step
71
+ p.step
72
+ end
73
+
74
+ expect(reported_values).to eq([50, 100])
75
+ end
76
+
77
+ it 'ignores calls to step if total steps is 0' do
78
+ reported_values = []
79
+ progress = Progress.new(steps: 0) do |percent|
80
+ reported_values << percent
81
+ end
82
+
83
+ progress.step
84
+ progress.step
85
+ progress.step
86
+
87
+ expect(reported_values).to eq([])
88
+ end
89
+ end
90
+ end
91
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  ENV['RAILS_ENV'] ||= 'test'
2
2
  ENV['PAGEFLOW_PLUGIN_ENGINE'] = 'pageflow_linkmap_page'
3
3
 
4
- require 'factory_girl_rails'
4
+ require 'unindent'
5
5
 
6
6
  require 'pageflow/support'
7
7
  Pageflow::Dummy.setup
@@ -17,4 +17,8 @@ RSpec.configure do |config|
17
17
  config.use_transactional_fixtures = true
18
18
  config.infer_base_class_for_anonymous_controllers = false
19
19
  config.order = "random"
20
+
21
+ config.expect_with :rspec do |expectations|
22
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
23
+ end
20
24
  end
@@ -1,10 +1,3 @@
1
1
  RSpec.configure do |config|
2
- module DeviseTestHelpersWithScope
3
- def sign_in(user)
4
- super(:user, user)
5
- end
6
- end
7
-
8
- config.include Devise::TestHelpers, type: :controller
9
- config.include DeviseTestHelpersWithScope, type: :controller
2
+ config.include Devise::Test::ControllerHelpers, type: :controller
10
3
  end
@@ -1,12 +1,14 @@
1
+ require 'factory_bot_rails'
2
+
1
3
  RSpec.configure do |config|
2
- # Allow to use build and create methods without FactoryGirl prefix.
3
- config.include FactoryGirl::Syntax::Methods
4
+ # Allow to use build and create methods without FactoryBot prefix.
5
+ config.include FactoryBot::Syntax::Methods
4
6
 
5
7
  # Make sure factories are up to date when using spring. Skip in CI
6
8
  # since reloading causes factories to be excluded in test coverage.
7
9
  unless ENV['CI']
8
10
  config.before(:all) do
9
- FactoryGirl.reload
11
+ FactoryBot.reload
10
12
  end
11
13
  end
12
14
  end
@@ -0,0 +1,9 @@
1
+ RSpec.configure do |config|
2
+ config.before(:each, inline_resque: true) do
3
+ Resque.inline = true
4
+ end
5
+
6
+ config.after(:each, inline_resque: true) do
7
+ Resque.inline = false
8
+ end
9
+ end
Binary file
Binary file
@@ -0,0 +1,34 @@
1
+ require 'chunky_png'
2
+
3
+ RSpec::Matchers.define :have_color do |expected_color|
4
+ expected_color =
5
+ if expected_color == :transparent
6
+ ChunkyPNG::Color.parse('#00000000')
7
+ else
8
+ ChunkyPNG::Color.parse(expected_color)
9
+ end
10
+
11
+ match do |attachment|
12
+ actual_color(attachment) == expected_color
13
+ end
14
+
15
+ failure_message do |attachment|
16
+ "expected image to have pixel with color #{ChunkyPNG::Color.to_hex(expected_color)} " \
17
+ "at #{@position}, but found #{ChunkyPNG::Color.to_hex(actual_color(attachment))}."
18
+ end
19
+
20
+ chain :at do |position|
21
+ @position = position
22
+ end
23
+
24
+ def actual_color(attachment)
25
+ @actual_color ||= Pageflow::LinkmapPage::PaperclipTempfile.for(attachment) do |path|
26
+ image = ChunkyPNG::Image.from_file(path)
27
+
28
+ x = @position.fetch(:left) { image.width - 1 - @position[:right] }
29
+ y = @position.fetch(:top) { image.height - 1 - @position[:bottom] }
30
+
31
+ ChunkyPNG::Color.parse(image[x, y])
32
+ end
33
+ end
34
+ end