Skip to content

Commit

Permalink
Merge pull request #8868 from CitizenLabDotCo/TAN-2625-fix-survey-map…
Browse files Browse the repository at this point in the history
…-layers-in-project-copy

[TAN-2625] Fix map layers when copying survey with project copy
  • Loading branch information
jinjagit authored Sep 16, 2024
2 parents 08c9daf + f4ec50a commit c5d15cb
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 12 deletions.
24 changes: 16 additions & 8 deletions back/app/services/project_copy_service.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

class ProjectCopyService < TemplateService
class ProjectCopyService < TemplateService # rubocop:disable Metrics/ClassLength
def import(template, folder: nil, local_copy: false)
same_template = MultiTenancy::Templates::Utils.translate_and_fix_locales(template)

Expand Down Expand Up @@ -33,6 +33,7 @@ def export(
@include_ideas = include_ideas
@local_copy = local_copy
@project = project
@project_map_configs = project_map_configs
@template = { 'models' => {} }
new_slug = SlugService.new.generate_slug(nil, new_slug) if new_slug

Expand Down Expand Up @@ -397,12 +398,7 @@ def yml_volunteering_causes(shift_timestamps: 0)
end

def yml_maps_map_configs(shift_timestamps: 0)
custom_forms = CustomForm.where(participation_context: [@project, *@project.phases])
custom_fields = CustomField.where(resource: custom_forms)
map_configs = CustomMaps::MapConfig.where(mappable: @project)
.or(CustomMaps::MapConfig.where(mappable: custom_fields))

map_configs.map do |map_config|
@project_map_configs.map do |map_config|
yml_map_config = {
'mappable_ref' => lookup_ref(map_config.mappable_id, %i[project custom_field]),
'center_geojson' => map_config.center_geojson,
Expand All @@ -419,7 +415,9 @@ def yml_maps_map_configs(shift_timestamps: 0)
end

def yml_maps_layers(shift_timestamps: 0)
(@project.map_config&.layers || []).map do |layer|
layers = @project_map_configs.map(&:layers).flatten

layers.map do |layer|
yml_layer = {
'map_config_ref' => lookup_ref(layer.map_config_id, :maps_map_config),
'type' => layer.type,
Expand All @@ -428,6 +426,7 @@ def yml_maps_layers(shift_timestamps: 0)
'geojson' => layer.geojson,
'default_enabled' => layer.default_enabled,
'marker_svg_url' => layer.marker_svg_url,
'ordering' => layer.ordering,
'created_at' => shift_timestamp(layer.created_at, shift_timestamps)&.iso8601,
'updated_at' => shift_timestamp(layer.updated_at, shift_timestamps)&.iso8601
}
Expand Down Expand Up @@ -764,4 +763,13 @@ def map_codes(craftjs_json, layout_images_mapping, layout_service = ContentBuild
end
craftjs_json
end

def project_map_configs
CustomMaps::MapConfig.where(mappable: @project)
.or(
CustomMaps::MapConfig.where(
mappable: CustomField.where(resource: CustomForm.where(participation_context: [@project, *@project.phases]))
)
)
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module Serializers
module CustomMaps
class Layer < Base
ref_attribute :map_config
attributes %i[type layer_url default_enabled geojson marker_svg_url title_multiloc]
attributes %i[type layer_url default_enabled geojson marker_svg_url title_multiloc ordering]
end
end
end
Expand Down
29 changes: 26 additions & 3 deletions back/spec/services/project_copy_service_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -149,68 +149,91 @@
expect(template['models']['idea'].first['custom_field_values']).to match expected_custom_field_values
end

it 'successfully copies map_configs associated with phase-level form custom_fields' do
it 'successfully copies map_configs associated with phase-level form custom_fields, and their layers' do
open_ended_project = create(:single_phase_native_survey_project, title_multiloc: { en: 'open ended' })
form1 = create(:custom_form, participation_context: open_ended_project.phases.first)
page_field = create(:custom_field_page, :for_custom_form, resource: form1)
map_config1 = create(:map_config, zoom_level: 15, mappable: page_field)
layer1 = create(:geojson_layer, map_config: map_config1, title_multiloc: { en: 'Layer 1' })
point_field = create(:custom_field_point, :for_custom_form, resource: form1)
map_config2 = create(:map_config, zoom_level: 17, mappable: point_field)
layer2 = create(:geojson_layer, map_config: map_config2, title_multiloc: { en: 'Layer 2' })
layer3 = create(:esri_feature_layer, map_config: map_config2, title_multiloc: { en: 'Layer 3' })

template = service.export open_ended_project

expect(template['models']['custom_field'].size).to eq 2
expect(template['models']['custom_maps/map_config'].size).to eq 2
expect(template['models']['custom_maps/layer'].size).to eq 3

tenant = create(:tenant)
tenant.switch do
expect(CustomMaps::MapConfig.count).to eq 0
expect(CustomMaps::Layer.count).to eq 0

service.import template

expect(CustomMaps::MapConfig.count).to eq 2
expect(CustomMaps::MapConfig.all.pluck(:zoom_level))
.to match_array [map_config1.zoom_level, map_config2.zoom_level]

expect(CustomMaps::Layer.count).to eq 3
expect(CustomMaps::Layer.all.pluck(:title_multiloc))
.to match_array [layer1.title_multiloc, layer2.title_multiloc, layer3.title_multiloc]
end
end

it 'successfully copies map_configs associated with project-level form custom_fields' do
it 'successfully copies map_configs associated with project-level form custom_fields, and their layers' do
project = create(:project)
form1 = create(:custom_form, participation_context: project)
field1 = create(:custom_field_point, :for_custom_form, resource: form1)
map_config = create(:map_config, zoom_level: 17, mappable: field1)
layer1 = create(:geojson_layer, map_config: map_config, title_multiloc: { en: 'Layer 1' })
layer2 = create(:geojson_layer, map_config: map_config, title_multiloc: { en: 'Layer 2' })

template = service.export project

expect(template['models']['custom_maps/map_config'].size).to eq 1
expect(template['models']['custom_maps/layer'].size).to eq 2

tenant = create(:tenant)
tenant.switch do
expect(CustomMaps::MapConfig.count).to eq 0
expect(CustomMaps::Layer.count).to eq 0

service.import template

expect(CustomMaps::MapConfig.count).to eq 1
expect(CustomMaps::MapConfig.first.zoom_level).to eq map_config.zoom_level

expect(CustomMaps::Layer.count).to eq 2
expect(CustomMaps::Layer.all.pluck(:title_multiloc))
.to match_array [layer1.title_multiloc, layer2.title_multiloc]
end
end

it 'successfully copies map_configs associated with projects' do
it 'successfully copies map_configs associated with projects, and their layers' do
project = create(:project)
map_config = create(:map_config, zoom_level: 17, mappable: project)
layer = create(:geojson_layer, map_config: map_config, title_multiloc: { en: 'Layer title' })

template = service.export project

expect(template['models']['custom_maps/map_config'].size).to eq 1
expect(template['models']['custom_maps/layer'].size).to eq 1

tenant = create(:tenant)
tenant.switch do
expect(CustomMaps::MapConfig.count).to eq 0
expect(CustomMaps::Layer.count).to eq 0

service.import template

expect(CustomMaps::MapConfig.count).to eq 1
expect(CustomMaps::MapConfig.first.zoom_level).to eq map_config.zoom_level

expect(CustomMaps::Layer.count).to eq 1
expect(CustomMaps::Layer.first.title_multiloc).to eq layer.title_multiloc
end
end

Expand Down

0 comments on commit c5d15cb

Please sign in to comment.