From 44f14a07dadddf843610a4c25d03a3aef323d79a Mon Sep 17 00:00:00 2001 From: "Jeferson S. Brito" Date: Sun, 15 Sep 2024 13:46:07 -0300 Subject: [PATCH] feat: add MindMap, Node and Edges --- api/app/controllers/mindmaps_controller.rb | 17 + api/app/models/edge.rb | 11 + api/app/models/mind_map.rb | 20 + api/app/models/node.rb | 14 + api/app/models/user.rb | 1 + api/app/views/mindmaps/index.jbuilder | 8 + api/app/views/mindmaps/show.jbuilder | 6 + api/config/routes.rb | 1 + .../20240907184721_create_mind_maps.rb | 13 + api/db/migrate/20240907184819_create_nodes.rb | 14 + api/db/migrate/20240907184914_create_edges.rb | 14 + .../20240915162642_add_graph_id_to_nodes.rb | 5 + api/db/schema.rb | 366 ++++++++++-------- api/spec/factories/edges.rb | 6 + api/spec/factories/mind_maps.rb | 6 + api/spec/factories/nodes.rb | 6 + api/spec/models/edge_spec.rb | 7 + api/spec/models/mind_map_spec.rb | 7 + api/spec/models/node_spec.rb | 7 + api/spec/requests/mind_map_spec.rb | 9 + 20 files changed, 371 insertions(+), 167 deletions(-) create mode 100644 api/app/controllers/mindmaps_controller.rb create mode 100644 api/app/models/edge.rb create mode 100644 api/app/models/mind_map.rb create mode 100644 api/app/models/node.rb create mode 100644 api/app/views/mindmaps/index.jbuilder create mode 100644 api/app/views/mindmaps/show.jbuilder create mode 100644 api/db/migrate/20240907184721_create_mind_maps.rb create mode 100644 api/db/migrate/20240907184819_create_nodes.rb create mode 100644 api/db/migrate/20240907184914_create_edges.rb create mode 100644 api/db/migrate/20240915162642_add_graph_id_to_nodes.rb create mode 100644 api/spec/factories/edges.rb create mode 100644 api/spec/factories/mind_maps.rb create mode 100644 api/spec/factories/nodes.rb create mode 100644 api/spec/models/edge_spec.rb create mode 100644 api/spec/models/mind_map_spec.rb create mode 100644 api/spec/models/node_spec.rb create mode 100644 api/spec/requests/mind_map_spec.rb diff --git a/api/app/controllers/mindmaps_controller.rb b/api/app/controllers/mindmaps_controller.rb new file mode 100644 index 0000000..4539d00 --- /dev/null +++ b/api/app/controllers/mindmaps_controller.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +class MindmapsController < ApplicationController + before_action :authenticate_request, only: :create + + def show + @mm = MindMap.find(params[:id]) + end + + def index + @mmaps = MindMap.all + end + + def create + # TBD + end +end diff --git a/api/app/models/edge.rb b/api/app/models/edge.rb new file mode 100644 index 0000000..64442fc --- /dev/null +++ b/api/app/models/edge.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Edge < ApplicationRecord + belongs_to :from_node, class_name: 'Node' + belongs_to :to_node, class_name: 'Node' + + validates :from_node_id, presence: true + validates :to_node_id, presence: true + + scope :between, ->(from, to) { where(from_node_id: from.id, to_node_id: to.id) } +end diff --git a/api/app/models/mind_map.rb b/api/app/models/mind_map.rb new file mode 100644 index 0000000..3d0b062 --- /dev/null +++ b/api/app/models/mind_map.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class MindMap < ApplicationRecord + belongs_to :category + has_many :nodes, foreign_key: 'graph_id' + + scope :for_category, ->(category) { where(category_id: category.id) } + + def add_node(node) + node.update!(graph_id: self.id) + end + + def remove_node(node) + node.update!(graph_id: nil) + end + + def connect_nodes(from, to) + Edge.create(from_node: from, to_node: to) + end +end diff --git a/api/app/models/node.rb b/api/app/models/node.rb new file mode 100644 index 0000000..bdd878f --- /dev/null +++ b/api/app/models/node.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class Node < ApplicationRecord + belongs_to :nodeable, polymorphic: true + belongs_to :graph, class_name: 'MindMap', foreign_key: 'graph_id', optional: true + + has_many :edges, dependent: :destroy + has_many :edges, foreign_key: 'to_node_id' + + validates :nodeable_type, presence: true + validates :nodeable_id, presence: true + + scope :related_to_exam, ->(exam) { where(nodeable_type: 'Exam', nodeable_id: exam.id) } +end diff --git a/api/app/models/user.rb b/api/app/models/user.rb index 6a45bd5..2027bcf 100644 --- a/api/app/models/user.rb +++ b/api/app/models/user.rb @@ -10,5 +10,6 @@ class User < ApplicationRecord has_many :answer has_many :exams, through: :answer + has_many :mind_map has_one :garden end diff --git a/api/app/views/mindmaps/index.jbuilder b/api/app/views/mindmaps/index.jbuilder new file mode 100644 index 0000000..1f18443 --- /dev/null +++ b/api/app/views/mindmaps/index.jbuilder @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +json.array! @mmaps do |map| + json.id map.id + json.name map.name + json.owner_id map.user_id + json.node_count map.node_ids.count +end diff --git a/api/app/views/mindmaps/show.jbuilder b/api/app/views/mindmaps/show.jbuilder new file mode 100644 index 0000000..76ed5c6 --- /dev/null +++ b/api/app/views/mindmaps/show.jbuilder @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +json.message 'Your mind map' +json.name @mm.name +json.category @mm.category.title +json.nodes @mm.node_ids diff --git a/api/config/routes.rb b/api/config/routes.rb index e48bc68..6526821 100644 --- a/api/config/routes.rb +++ b/api/config/routes.rb @@ -32,5 +32,6 @@ post '/journal/surprise_question', to: 'gardens#evaluate_surprise_question' end resources :trees, only: %i[index show] + resources :mindmaps end end diff --git a/api/db/migrate/20240907184721_create_mind_maps.rb b/api/db/migrate/20240907184721_create_mind_maps.rb new file mode 100644 index 0000000..0bc51f1 --- /dev/null +++ b/api/db/migrate/20240907184721_create_mind_maps.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +class CreateMindMaps < ActiveRecord::Migration[7.0] + def change + create_table :mind_maps do |t| + t.string :name + t.references :category, null: false, foreign_key: true + t.references :user, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/api/db/migrate/20240907184819_create_nodes.rb b/api/db/migrate/20240907184819_create_nodes.rb new file mode 100644 index 0000000..0aac71c --- /dev/null +++ b/api/db/migrate/20240907184819_create_nodes.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CreateNodes < ActiveRecord::Migration[7.0] + def change + create_table :nodes do |t| + t.references :nodeable, polymorphic: true, null: false + t.integer :position + + t.timestamps + end + + add_index :nodes, %i[nodeable_type nodeable_id], name: 'index_nodes_on_nodeable_type_and_nodeable_id', unique: true + end +end diff --git a/api/db/migrate/20240907184914_create_edges.rb b/api/db/migrate/20240907184914_create_edges.rb new file mode 100644 index 0000000..8d558e7 --- /dev/null +++ b/api/db/migrate/20240907184914_create_edges.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +class CreateEdges < ActiveRecord::Migration[7.0] + def change + create_table :edges do |t| + t.references :from_node, null: false, foreign_key: { to_table: :nodes } + t.references :to_node, null: false, foreign_key: { to_table: :nodes } + + t.timestamps + end + + add_index :edges, %i[from_node_id to_node_id], name: 'index_edges_on_from_node_id_and_to_node_id', unique: true + end +end diff --git a/api/db/migrate/20240915162642_add_graph_id_to_nodes.rb b/api/db/migrate/20240915162642_add_graph_id_to_nodes.rb new file mode 100644 index 0000000..76ec9d7 --- /dev/null +++ b/api/db/migrate/20240915162642_add_graph_id_to_nodes.rb @@ -0,0 +1,5 @@ +class AddGraphIdToNodes < ActiveRecord::Migration[7.0] + def change + add_column :nodes, :graph_id, :integer + end +end diff --git a/api/db/schema.rb b/api/db/schema.rb index 4db6e29..9734c59 100644 --- a/api/db/schema.rb +++ b/api/db/schema.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - # This file is auto-generated from the current state of the database. Instead # of editing this file, please use the migrations feature of Active Record to # incrementally modify your database, and then regenerate this schema definition. @@ -12,170 +10,204 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 20_240_817_212_900) do +ActiveRecord::Schema[7.0].define(version: 2024_09_15_162642) do # These are extensions that must be enabled in order to support this database - enable_extension 'plpgsql' - - create_table 'active_storage_attachments', force: :cascade do |t| - t.string 'name', null: false - t.string 'record_type', null: false - t.bigint 'record_id', null: false - t.bigint 'blob_id', null: false - t.datetime 'created_at', null: false - t.index ['blob_id'], name: 'index_active_storage_attachments_on_blob_id' - t.index %w[record_type record_id name blob_id], name: 'index_active_storage_attachments_uniqueness', - unique: true - end - - create_table 'active_storage_blobs', force: :cascade do |t| - t.string 'key', null: false - t.string 'filename', null: false - t.string 'content_type' - t.text 'metadata' - t.string 'service_name', null: false - t.bigint 'byte_size', null: false - t.string 'checksum' - t.datetime 'created_at', null: false - t.index ['key'], name: 'index_active_storage_blobs_on_key', unique: true - end - - create_table 'active_storage_variant_records', force: :cascade do |t| - t.bigint 'blob_id', null: false - t.string 'variation_digest', null: false - t.index %w[blob_id variation_digest], name: 'index_active_storage_variant_records_uniqueness', unique: true - end - - create_table 'answers', force: :cascade do |t| - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'score' - t.bigint 'user_id' - t.bigint 'exam_id' - t.index ['exam_id'], name: 'index_answers_on_exam_id' - t.index ['user_id'], name: 'index_answers_on_user_id' - end - - create_table 'branches', force: :cascade do |t| - t.string 'name' - t.text 'description' - t.integer 'health', default: 100 - t.bigint 'tree_id', null: false - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.index ['tree_id'], name: 'index_branches_on_tree_id' - end - - create_table 'categories', force: :cascade do |t| - t.string 'title' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - end - - create_table 'exams', force: :cascade do |t| - t.string 'title' - t.integer 'difficulty', default: 0 - t.integer 'version' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.bigint 'category_id' - t.index ['category_id'], name: 'index_exams_on_category_id' - t.index ['id'], name: 'index_exams_on_id' - end - - create_table 'exams_questions', id: false, force: :cascade do |t| - t.bigint 'exam_id' - t.bigint 'question_id' - t.index %w[exam_id question_id], name: 'index_exams_questions_on_exam_id_and_question_id', unique: true - t.index ['exam_id'], name: 'index_exams_questions_on_exam_id' - t.index ['question_id'], name: 'index_exams_questions_on_question_id' - end - - create_table 'gardens', force: :cascade do |t| - t.string 'name' - t.bigint 'user_id', null: false - t.integer 'seeds', default: 0 - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'nutrients', default: 0 - t.index ['user_id'], name: 'index_gardens_on_user_id' - end - - create_table 'options', force: :cascade do |t| - t.string 'text' - t.bigint 'question_id', null: false - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.boolean 'correct', default: false - t.index ['question_id'], name: 'index_options_on_question_id' - end - - create_table 'questions', force: :cascade do |t| - t.string 'title' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.bigint 'exam_id' - t.bigint 'revision_id' - t.boolean 'has_duo', default: false - t.daterange 'is_limited_between' - t.index ['exam_id'], name: 'index_questions_on_exam_id' - t.index ['id'], name: 'index_questions_on_id' - t.index ['revision_id'], name: 'index_questions_on_revision_id' - end - - create_table 'revisions', force: :cascade do |t| - t.bigint 'exam_id', null: false - t.bigint 'user_id', null: false - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.integer 'interval_level', default: 0 - t.index ['exam_id'], name: 'index_revisions_on_exam_id' - t.index ['user_id'], name: 'index_revisions_on_user_id' - end - - create_table 'surprise_question_answers', force: :cascade do |t| - t.bigint 'question_id', null: false - t.bigint 'user_id', null: false - t.boolean 'winner', default: false - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.index ['question_id'], name: 'index_surprise_question_answers_on_question_id' - t.index ['user_id'], name: 'index_surprise_question_answers_on_user_id' - end - - create_table 'trees', force: :cascade do |t| - t.string 'name' - t.integer 'phase', default: 0 - t.integer 'health', default: 100 - t.bigint 'garden_id', null: false - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.index ['garden_id'], name: 'index_trees_on_garden_id' - end - - create_table 'users', force: :cascade do |t| - t.string 'username' - t.string 'email' - t.datetime 'created_at', null: false - t.datetime 'updated_at', null: false - t.string 'password_digest' - t.string 'name' - end - - add_foreign_key 'active_storage_attachments', 'active_storage_blobs', column: 'blob_id' - add_foreign_key 'active_storage_variant_records', 'active_storage_blobs', column: 'blob_id' - add_foreign_key 'answers', 'exams' - add_foreign_key 'answers', 'users' - add_foreign_key 'branches', 'trees' - add_foreign_key 'exams', 'categories' - add_foreign_key 'exams_questions', 'exams' - add_foreign_key 'exams_questions', 'questions' - add_foreign_key 'gardens', 'users' - add_foreign_key 'options', 'questions' - add_foreign_key 'questions', 'exams' - add_foreign_key 'questions', 'revisions' - add_foreign_key 'revisions', 'exams' - add_foreign_key 'revisions', 'users' - add_foreign_key 'surprise_question_answers', 'questions' - add_foreign_key 'surprise_question_answers', 'users' - add_foreign_key 'trees', 'gardens' + enable_extension "plpgsql" + + create_table "active_storage_attachments", force: :cascade do |t| + t.string "name", null: false + t.string "record_type", null: false + t.bigint "record_id", null: false + t.bigint "blob_id", null: false + t.datetime "created_at", null: false + t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" + t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table "active_storage_blobs", force: :cascade do |t| + t.string "key", null: false + t.string "filename", null: false + t.string "content_type" + t.text "metadata" + t.string "service_name", null: false + t.bigint "byte_size", null: false + t.string "checksum" + t.datetime "created_at", null: false + t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + + create_table "answers", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "score" + t.bigint "user_id" + t.bigint "exam_id" + t.index ["exam_id"], name: "index_answers_on_exam_id" + t.index ["user_id"], name: "index_answers_on_user_id" + end + + create_table "branches", force: :cascade do |t| + t.string "name" + t.text "description" + t.integer "health", default: 100 + t.bigint "tree_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["tree_id"], name: "index_branches_on_tree_id" + end + + create_table "categories", force: :cascade do |t| + t.string "title" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "edges", force: :cascade do |t| + t.bigint "from_node_id", null: false + t.bigint "to_node_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["from_node_id", "to_node_id"], name: "index_edges_on_from_node_id_and_to_node_id", unique: true + t.index ["from_node_id"], name: "index_edges_on_from_node_id" + t.index ["to_node_id"], name: "index_edges_on_to_node_id" + end + + create_table "exams", force: :cascade do |t| + t.string "title" + t.integer "difficulty", default: 0 + t.integer "version" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "category_id" + t.index ["category_id"], name: "index_exams_on_category_id" + t.index ["id"], name: "index_exams_on_id" + end + + create_table "exams_questions", id: false, force: :cascade do |t| + t.bigint "exam_id" + t.bigint "question_id" + t.index ["exam_id", "question_id"], name: "index_exams_questions_on_exam_id_and_question_id", unique: true + t.index ["exam_id"], name: "index_exams_questions_on_exam_id" + t.index ["question_id"], name: "index_exams_questions_on_question_id" + end + + create_table "gardens", force: :cascade do |t| + t.string "name" + t.bigint "user_id", null: false + t.integer "seeds", default: 0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "nutrients", default: 0 + t.index ["user_id"], name: "index_gardens_on_user_id" + end + + create_table "mind_maps", force: :cascade do |t| + t.string "name" + t.bigint "category_id", null: false + t.bigint "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["category_id"], name: "index_mind_maps_on_category_id" + t.index ["user_id"], name: "index_mind_maps_on_user_id" + end + + create_table "nodes", force: :cascade do |t| + t.string "nodeable_type", null: false + t.bigint "nodeable_id", null: false + t.integer "position" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "graph_id" + t.index ["nodeable_type", "nodeable_id"], name: "index_nodes_on_nodeable" + t.index ["nodeable_type", "nodeable_id"], name: "index_nodes_on_nodeable_type_and_nodeable_id", unique: true + end + + create_table "options", force: :cascade do |t| + t.string "text" + t.bigint "question_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "correct", default: false + t.index ["question_id"], name: "index_options_on_question_id" + end + + create_table "questions", force: :cascade do |t| + t.string "title" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.bigint "exam_id" + t.bigint "revision_id" + t.boolean "has_duo", default: false + t.daterange "is_limited_between" + t.index ["exam_id"], name: "index_questions_on_exam_id" + t.index ["id"], name: "index_questions_on_id" + t.index ["revision_id"], name: "index_questions_on_revision_id" + end + + create_table "revisions", force: :cascade do |t| + t.bigint "exam_id", null: false + t.bigint "user_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "interval_level", default: 0 + t.index ["exam_id"], name: "index_revisions_on_exam_id" + t.index ["user_id"], name: "index_revisions_on_user_id" + end + + create_table "surprise_question_answers", force: :cascade do |t| + t.bigint "question_id", null: false + t.bigint "user_id", null: false + t.boolean "winner", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["question_id"], name: "index_surprise_question_answers_on_question_id" + t.index ["user_id"], name: "index_surprise_question_answers_on_user_id" + end + + create_table "trees", force: :cascade do |t| + t.string "name" + t.integer "phase", default: 0 + t.integer "health", default: 100 + t.bigint "garden_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["garden_id"], name: "index_trees_on_garden_id" + end + + create_table "users", force: :cascade do |t| + t.string "username" + t.string "email" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "password_digest" + t.string "name" + end + + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "answers", "exams" + add_foreign_key "answers", "users" + add_foreign_key "branches", "trees" + add_foreign_key "edges", "nodes", column: "from_node_id" + add_foreign_key "edges", "nodes", column: "to_node_id" + add_foreign_key "exams", "categories" + add_foreign_key "exams_questions", "exams" + add_foreign_key "exams_questions", "questions" + add_foreign_key "gardens", "users" + add_foreign_key "mind_maps", "categories" + add_foreign_key "mind_maps", "users" + add_foreign_key "options", "questions" + add_foreign_key "questions", "exams" + add_foreign_key "questions", "revisions" + add_foreign_key "revisions", "exams" + add_foreign_key "revisions", "users" + add_foreign_key "surprise_question_answers", "questions" + add_foreign_key "surprise_question_answers", "users" + add_foreign_key "trees", "gardens" end diff --git a/api/spec/factories/edges.rb b/api/spec/factories/edges.rb new file mode 100644 index 0000000..bf80739 --- /dev/null +++ b/api/spec/factories/edges.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :edge do + end +end diff --git a/api/spec/factories/mind_maps.rb b/api/spec/factories/mind_maps.rb new file mode 100644 index 0000000..2f7f3d4 --- /dev/null +++ b/api/spec/factories/mind_maps.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :mind_map do + end +end diff --git a/api/spec/factories/nodes.rb b/api/spec/factories/nodes.rb new file mode 100644 index 0000000..3c313b4 --- /dev/null +++ b/api/spec/factories/nodes.rb @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :node do + end +end diff --git a/api/spec/models/edge_spec.rb b/api/spec/models/edge_spec.rb new file mode 100644 index 0000000..9a2f680 --- /dev/null +++ b/api/spec/models/edge_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Edge, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/api/spec/models/mind_map_spec.rb b/api/spec/models/mind_map_spec.rb new file mode 100644 index 0000000..a50a9c6 --- /dev/null +++ b/api/spec/models/mind_map_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe MindMap, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/api/spec/models/node_spec.rb b/api/spec/models/node_spec.rb new file mode 100644 index 0000000..17827d1 --- /dev/null +++ b/api/spec/models/node_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Node, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/api/spec/requests/mind_map_spec.rb b/api/spec/requests/mind_map_spec.rb new file mode 100644 index 0000000..2e467f2 --- /dev/null +++ b/api/spec/requests/mind_map_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'MindMaps', type: :request do + describe 'GET /index' do + pending "add some examples (or delete) #{__FILE__}" + end +end