diff --git a/app/models/decidim/navigation_maps/blueprint.rb b/app/models/decidim/navigation_maps/blueprint.rb index 9ad6906..12897f9 100644 --- a/app/models/decidim/navigation_maps/blueprint.rb +++ b/app/models/decidim/navigation_maps/blueprint.rb @@ -7,6 +7,10 @@ class Blueprint < ApplicationRecord self.table_name = "decidim_navigation_maps_blueprints" belongs_to :organization, foreign_key: :decidim_organization_id, class_name: "Decidim::Organization" + has_many :areas, + foreign_key: "decidim_navigation_maps_blueprint_id", + class_name: "Decidim::NavigationMaps::BlueprintArea", + dependent: :destroy validates :organization, presence: true validates :image, @@ -14,8 +18,6 @@ class Blueprint < ApplicationRecord file_content_type: { allow: ["image/jpeg", "image/png", "image/svg+xml"] } mount_uploader :image, Decidim::NavigationMaps::BlueprintUploader - - # validates :blueprint, presence: true end end end diff --git a/app/models/decidim/navigation_maps/blueprint_area.rb b/app/models/decidim/navigation_maps/blueprint_area.rb new file mode 100644 index 0000000..31eb995 --- /dev/null +++ b/app/models/decidim/navigation_maps/blueprint_area.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Decidim + module NavigationMaps + # Abstract class from which all models in this engine inherit. + class BlueprintArea < ApplicationRecord + self.table_name = "decidim_navigation_maps_blueprint_areas" + + belongs_to :blueprint, foreign_key: :decidim_navigation_maps_blueprint_id, class_name: "Decidim::NavigationMaps::Blueprint" + + validates :blueprint, presence: true + end + end +end diff --git a/db/migrate/20191125142751_create_decidim_navigation_maps_blueprint_areas.rb b/db/migrate/20191125142751_create_decidim_navigation_maps_blueprint_areas.rb new file mode 100644 index 0000000..ae6ef06 --- /dev/null +++ b/db/migrate/20191125142751_create_decidim_navigation_maps_blueprint_areas.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +class CreateDecidimNavigationMapsBlueprintAreas < ActiveRecord::Migration[5.2] + class Blueprint < ApplicationRecord + self.table_name = "decidim_navigation_maps_blueprints" + end + + class Area < ApplicationRecord + self.table_name = "decidim_navigation_maps_blueprint_areas" + end + + def change + create_table :decidim_navigation_maps_blueprint_areas do |t| + t.jsonb :area + t.references :decidim_navigation_maps_blueprint, null: false, foreign_key: true, index: { name: "decidim_navigation_maps_constraint_blueprint_id" } + t.jsonb :title, default: {} + t.jsonb :description, default: {} + t.string :area_type + t.string :url + + t.timestamps + end + + # Search areas and create distributed entries + Blueprint.find_each do |blueprint| + blueprint.blueprint.each do |_key, area| + Area.create!( + area: area, + decidim_navigation_maps_blueprint_id: blueprint.id, + area_type: "link", + url: area["properties"]["link"] + ) + end + end + end +end diff --git a/lib/decidim/navigation_maps/test/factories.rb b/lib/decidim/navigation_maps/test/factories.rb index f520f5f..2daca44 100644 --- a/lib/decidim/navigation_maps/test/factories.rb +++ b/lib/decidim/navigation_maps/test/factories.rb @@ -5,13 +5,15 @@ FactoryBot.define do factory :blueprint, class: Decidim::NavigationMaps::Blueprint do organization { create(:organization) } - blueprint { { x: 1, y: 1 } } image { Decidim::Dev.test_file("city.jpeg", "image/jpeg") } - title do - { en: "Tab 1" } - end - description do - { en: "Description for blueprint 1" } - end + title { Decidim::Faker::Localized.word } + description { generate_localized_title } + end + + factory :blueprint_area, class: Decidim::NavigationMaps::BlueprintArea do + blueprint { create(:blueprint) } + area { { x: 1, y: 1 } } + title { Decidim::Faker::Localized.word } + description { generate_localized_title } end end diff --git a/spec/model/blueprint_area_spec.rb b/spec/model/blueprint_area_spec.rb new file mode 100644 index 0000000..174aef6 --- /dev/null +++ b/spec/model/blueprint_area_spec.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +require "spec_helper" + +module Decidim + module NavigationMaps + describe BlueprintArea do + subject { blueprint_area } + + let(:organization) { create(:organization) } + let(:blueprint) { create(:blueprint, organization: organization) } + let(:blueprint_area) { build(:blueprint_area, blueprint: blueprint) } + let(:data) { { x: "coord x", y: "coord y" } } + + it { is_expected.to be_valid } + + it "blueprint is associated with organization" do + expect(subject.blueprint).to eq(blueprint) + expect(subject.blueprint.organization).to eq(organization) + end + + # TODO: validate json area + + # context "when no data" do + # let(:data) { [] } + # it "is not valid" do + # expect(subject).not_to be_valid + # end + # end + end + end +end diff --git a/spec/model/blueprint_spec.rb b/spec/model/blueprint_spec.rb index 965113c..1caf738 100644 --- a/spec/model/blueprint_spec.rb +++ b/spec/model/blueprint_spec.rb @@ -8,8 +8,7 @@ module NavigationMaps subject { blueprint } let(:organization) { create(:organization) } - let(:data) { [x: "coord x", y: "coord y"] } - let(:blueprint) { build(:blueprint, blueprint: data, organization: organization) } + let(:blueprint) { create(:blueprint, organization: organization) } it { is_expected.to be_valid } @@ -37,14 +36,27 @@ module NavigationMaps it { is_expected.not_to be_valid } end - # TODO: validate json blueprint + context "when areas are defined" do + let(:blueprint) { build(:blueprint, organization: organization) } - # context "when no data" do - # let(:data) { [] } - # it "is not valid" do - # expect(subject).not_to be_valid - # end - # end + let(:areas) { [area1, area2] } + let(:area1) { create(:blueprint_area, area: data1, blueprint: blueprint) } + let(:area2) { create(:blueprint_area, area: data2, blueprint: blueprint) } + let(:data1) { { x: "coord x", y: "coord y" } } + let(:data2) { { x: "coord x", y: "coord y" } } + + it { is_expected.to be_valid } + + it "areas belong to blueprint" do + expect(area1.blueprint).to eq(blueprint) + expect(area2.blueprint).to eq(blueprint) + end + + it "blueprint contains areas" do + expect(blueprint.areas).to include(area1) + expect(blueprint.areas).to include(area2) + end + end end end end