Compare commits

...

20 Commits

Author SHA1 Message Date
KaungKaung
a2e1b7f3d2 Merge branch 'development' of https://git.qikbite.asia/KaungKaung/test_rails_kaungkaung into development 2026-01-30 09:39:10 +06:30
KaungKaung
7f6123a6e6 Show Done tasks and Fixed turbo frame and stream bug 2026-01-30 09:38:32 +06:30
KaungKaung
8a94b07955 Fixed turbo frame and stream bug 2026-01-30 09:30:32 +06:30
KaungKaung
7c9aef4324 Merge branch 'development' of https://github.com/kaungkaungc2l/magic into development 2026-01-29 11:14:52 +06:30
KaungKaung
8a7d1716e2 Use find_by and task_dom_id to prevent errors when deleting tasks. 2026-01-29 11:13:04 +06:30
KaungKaung
e3da79930c Render 'complete' button only if the task's status is not 'done'. 2026-01-28 15:27:17 +06:30
KaungKaung
7c9e164a9a Added complete button 2026-01-28 14:59:13 +06:30
KaungKaung
0f5d105be3 Used Turbo Frames/Streams for adding/deleting tasks without refresh entire browser 2026-01-28 14:12:24 +06:30
KaungKaung
910c1912e0 Added CRUD links for projects/tasks and validation display 2026-01-27 16:57:50 +06:30
KaungKaung
fbb09e4015 Validate form data 2026-01-27 16:55:07 +06:30
KaungKaung
cfca2bec27 Configured route for Tasks 2026-01-27 16:53:13 +06:30
KaungKaung
142e14743a CRUD implementation for Projects and Tasks 2026-01-27 16:51:35 +06:30
KaungKaung
ec595da889 Added New Task form 2026-01-27 16:50:25 +06:30
KaungKaung
6c3180f203 Nested routes, Listed tasks associated with projects 2026-01-27 11:43:00 +06:30
KaungKaung
fd0a6fb408 Database seeding 2026-01-27 10:25:17 +06:30
KaungKaung
f72af5d45f Added enum to Task model. Added project to project to tasks. Changed Status data type in Tasks. 2026-01-26 21:50:14 +06:30
KaungKaung
6bbbc67a3c Deleted bots 2026-01-26 16:45:15 +06:30
KaungKaung
754a76fd5d db migration 2026-01-26 15:05:12 +06:30
KaungKaung
e0ac034974 migrated db and defined Proj & Task relationship 2026-01-26 14:36:16 +06:30
KaungKaung
de19e675c8 added Project model with project_name and Task model with title&status 2026-01-26 14:00:27 +06:30
44 changed files with 392 additions and 405 deletions

View File

@@ -1,12 +0,0 @@
version: 2
updates:
- package-ecosystem: bundler
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: weekly
open-pull-requests-limit: 10

View File

@@ -1,124 +0,0 @@
name: CI
on:
pull_request:
push:
branches: [ main ]
jobs:
scan_ruby:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Scan for common Rails security vulnerabilities using static analysis
run: bin/brakeman --no-pager
- name: Scan for known security vulnerabilities in gems used
run: bin/bundler-audit
scan_js:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Scan for security vulnerabilities in JavaScript dependencies
run: bin/importmap audit
lint:
runs-on: ubuntu-latest
env:
RUBOCOP_CACHE_ROOT: tmp/rubocop
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Prepare RuboCop cache
uses: actions/cache@v4
env:
DEPENDENCIES_HASH: ${{ hashFiles('.ruby-version', '**/.rubocop.yml', '**/.rubocop_todo.yml', 'Gemfile.lock') }}
with:
path: ${{ env.RUBOCOP_CACHE_ROOT }}
key: rubocop-${{ runner.os }}-${{ env.DEPENDENCIES_HASH }}-${{ github.ref_name == github.event.repository.default_branch && github.run_id || 'default' }}
restore-keys: |
rubocop-${{ runner.os }}-${{ env.DEPENDENCIES_HASH }}-
- name: Lint code for consistent style
run: bin/rubocop -f github
test:
runs-on: ubuntu-latest
# services:
# redis:
# image: valkey/valkey:8
# ports:
# - 6379:6379
# options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Run tests
env:
RAILS_ENV: test
# RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
# REDIS_URL: redis://localhost:6379/0
run: bin/rails db:test:prepare test
system-test:
runs-on: ubuntu-latest
# services:
# redis:
# image: valkey/valkey:8
# ports:
# - 6379:6379
# options: --health-cmd "redis-cli ping" --health-interval 10s --health-timeout 5s --health-retries 5
steps:
- name: Checkout code
uses: actions/checkout@v6
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: Run System Tests
env:
RAILS_ENV: test
# RAILS_MASTER_KEY: ${{ secrets.RAILS_MASTER_KEY }}
# REDIS_URL: redis://localhost:6379/0
run: bin/rails db:test:prepare test:system
- name: Keep screenshots from failed system tests
uses: actions/upload-artifact@v4
if: failure()
with:
name: screenshots
path: ${{ github.workspace }}/tmp/screenshots
if-no-files-found: ignore

View File

@@ -1,3 +0,0 @@
#!/bin/sh
echo "Docker set up on $KAMAL_HOSTS..."

View File

@@ -1,3 +0,0 @@
#!/bin/sh
echo "Booted app version $KAMAL_VERSION on $KAMAL_HOSTS..."

View File

@@ -1,14 +0,0 @@
#!/bin/sh
# A sample post-deploy hook
#
# These environment variables are available:
# KAMAL_RECORDED_AT
# KAMAL_PERFORMER
# KAMAL_VERSION
# KAMAL_HOSTS
# KAMAL_ROLES (if set)
# KAMAL_DESTINATION (if set)
# KAMAL_RUNTIME
echo "$KAMAL_PERFORMER deployed $KAMAL_VERSION to $KAMAL_DESTINATION in $KAMAL_RUNTIME seconds"

View File

@@ -1,3 +0,0 @@
#!/bin/sh
echo "Rebooted kamal-proxy on $KAMAL_HOSTS"

View File

@@ -1,3 +0,0 @@
#!/bin/sh
echo "Booting app version $KAMAL_VERSION on $KAMAL_HOSTS..."

View File

@@ -1,51 +0,0 @@
#!/bin/sh
# A sample pre-build hook
#
# Checks:
# 1. We have a clean checkout
# 2. A remote is configured
# 3. The branch has been pushed to the remote
# 4. The version we are deploying matches the remote
#
# These environment variables are available:
# KAMAL_RECORDED_AT
# KAMAL_PERFORMER
# KAMAL_VERSION
# KAMAL_HOSTS
# KAMAL_ROLES (if set)
# KAMAL_DESTINATION (if set)
if [ -n "$(git status --porcelain)" ]; then
echo "Git checkout is not clean, aborting..." >&2
git status --porcelain >&2
exit 1
fi
first_remote=$(git remote)
if [ -z "$first_remote" ]; then
echo "No git remote set, aborting..." >&2
exit 1
fi
current_branch=$(git branch --show-current)
if [ -z "$current_branch" ]; then
echo "Not on a git branch, aborting..." >&2
exit 1
fi
remote_head=$(git ls-remote $first_remote --tags $current_branch | cut -f1)
if [ -z "$remote_head" ]; then
echo "Branch not pushed to remote, aborting..." >&2
exit 1
fi
if [ "$KAMAL_VERSION" != "$remote_head" ]; then
echo "Version ($KAMAL_VERSION) does not match remote HEAD ($remote_head), aborting..." >&2
exit 1
fi
exit 0

View File

@@ -1,47 +0,0 @@
#!/usr/bin/env ruby
# A sample pre-connect check
#
# Warms DNS before connecting to hosts in parallel
#
# These environment variables are available:
# KAMAL_RECORDED_AT
# KAMAL_PERFORMER
# KAMAL_VERSION
# KAMAL_HOSTS
# KAMAL_ROLES (if set)
# KAMAL_DESTINATION (if set)
# KAMAL_RUNTIME
hosts = ENV["KAMAL_HOSTS"].split(",")
results = nil
max = 3
elapsed = Benchmark.realtime do
results = hosts.map do |host|
Thread.new do
tries = 1
begin
Socket.getaddrinfo(host, 0, Socket::AF_UNSPEC, Socket::SOCK_STREAM, nil, Socket::AI_CANONNAME)
rescue SocketError
if tries < max
puts "Retrying DNS warmup: #{host}"
tries += 1
sleep rand
retry
else
puts "DNS warmup failed: #{host}"
host
end
end
tries
end
end.map(&:value)
end
retries = results.sum - hosts.size
nopes = results.count { |r| r == max }
puts "Prewarmed %d DNS lookups in %.2f sec: %d retries, %d failures" % [ hosts.size, elapsed, retries, nopes ]

View File

@@ -1,122 +0,0 @@
#!/usr/bin/env ruby
# A sample pre-deploy hook
#
# Checks the Github status of the build, waiting for a pending build to complete for up to 720 seconds.
#
# Fails unless the combined status is "success"
#
# These environment variables are available:
# KAMAL_RECORDED_AT
# KAMAL_PERFORMER
# KAMAL_VERSION
# KAMAL_HOSTS
# KAMAL_COMMAND
# KAMAL_SUBCOMMAND
# KAMAL_ROLES (if set)
# KAMAL_DESTINATION (if set)
# Only check the build status for production deployments
if ENV["KAMAL_COMMAND"] == "rollback" || ENV["KAMAL_DESTINATION"] != "production"
exit 0
end
require "bundler/inline"
# true = install gems so this is fast on repeat invocations
gemfile(true, quiet: true) do
source "https://rubygems.org"
gem "octokit"
gem "faraday-retry"
end
MAX_ATTEMPTS = 72
ATTEMPTS_GAP = 10
def exit_with_error(message)
$stderr.puts message
exit 1
end
class GithubStatusChecks
attr_reader :remote_url, :git_sha, :github_client, :combined_status
def initialize
@remote_url = github_repo_from_remote_url
@git_sha = `git rev-parse HEAD`.strip
@github_client = Octokit::Client.new(access_token: ENV["GITHUB_TOKEN"])
refresh!
end
def refresh!
@combined_status = github_client.combined_status(remote_url, git_sha)
end
def state
combined_status[:state]
end
def first_status_url
first_status = combined_status[:statuses].find { |status| status[:state] == state }
first_status && first_status[:target_url]
end
def complete_count
combined_status[:statuses].count { |status| status[:state] != "pending"}
end
def total_count
combined_status[:statuses].count
end
def current_status
if total_count > 0
"Completed #{complete_count}/#{total_count} checks, see #{first_status_url} ..."
else
"Build not started..."
end
end
private
def github_repo_from_remote_url
url = `git config --get remote.origin.url`.strip.delete_suffix(".git")
if url.start_with?("https://github.com/")
url.delete_prefix("https://github.com/")
elsif url.start_with?("git@github.com:")
url.delete_prefix("git@github.com:")
else
url
end
end
end
$stdout.sync = true
begin
puts "Checking build status..."
attempts = 0
checks = GithubStatusChecks.new
loop do
case checks.state
when "success"
puts "Checks passed, see #{checks.first_status_url}"
exit 0
when "failure"
exit_with_error "Checks failed, see #{checks.first_status_url}"
when "pending"
attempts += 1
end
exit_with_error "Checks are still pending, gave up after #{MAX_ATTEMPTS * ATTEMPTS_GAP} seconds" if attempts == MAX_ATTEMPTS
puts checks.current_status
sleep(ATTEMPTS_GAP)
checks.refresh!
end
rescue Octokit::NotFound
exit_with_error "Build status could not be found"
end

View File

@@ -1,3 +0,0 @@
#!/bin/sh
echo "Rebooting kamal-proxy on $KAMAL_HOSTS..."

View File

@@ -1,20 +0,0 @@
# Secrets defined here are available for reference under registry/password, env/secret, builder/secrets,
# and accessories/*/env/secret in config/deploy.yml. All secrets should be pulled from either
# password manager, ENV, or a file. DO NOT ENTER RAW CREDENTIALS HERE! This file needs to be safe for git.
# Example of extracting secrets from 1password (or another compatible pw manager)
# SECRETS=$(kamal secrets fetch --adapter 1password --account your-account --from Vault/Item KAMAL_REGISTRY_PASSWORD RAILS_MASTER_KEY)
# KAMAL_REGISTRY_PASSWORD=$(kamal secrets extract KAMAL_REGISTRY_PASSWORD ${SECRETS})
# RAILS_MASTER_KEY=$(kamal secrets extract RAILS_MASTER_KEY ${SECRETS})
# Example of extracting secrets from Rails credentials
# KAMAL_REGISTRY_PASSWORD=$(rails credentials:fetch kamal.registry_password)
# Use a GITHUB_TOKEN if private repositories are needed for the image
# GITHUB_TOKEN=$(gh config get -h github.com oauth_token)
# Grab the registry password from ENV
# KAMAL_REGISTRY_PASSWORD=$KAMAL_REGISTRY_PASSWORD
# Improve security by using a password manager. Never check config/master.key into git!
RAILS_MASTER_KEY=$(cat config/master.key)

View File

@@ -64,3 +64,5 @@ group :test do
gem "capybara"
gem "selenium-webdriver"
end
gem "tailwindcss", "~> 0.1.1"

View File

@@ -351,6 +351,7 @@ GEM
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.2.0)
tailwindcss (0.1.1)
thor (1.5.0)
thruster (0.1.17)
thruster (0.1.17-aarch64-linux)
@@ -415,6 +416,7 @@ DEPENDENCIES
solid_queue
sqlite3 (>= 2.1)
stimulus-rails
tailwindcss (~> 0.1.1)
thruster
turbo-rails
tzinfo-data
@@ -552,6 +554,7 @@ CHECKSUMS
sshkit (1.25.0) sha256=c8c6543cdb60f91f1d277306d585dd11b6a064cb44eab0972827e4311ff96744
stimulus-rails (1.3.4) sha256=765676ffa1f33af64ce026d26b48e8ffb2e0b94e0f50e9119e11d6107d67cb06
stringio (3.2.0) sha256=c37cb2e58b4ffbd33fe5cd948c05934af997b36e0b6ca6fdf43afa234cf222e1
tailwindcss (0.1.1) sha256=cdd453b13267d6441cba86cc6bf2b91e06bf01171983d90701b8d9b634d3be75
thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
thruster (0.1.17) sha256=6f3f1de43e22f0162d81cbc363f45ee42a1b8460213856c1a899cbf0d3297235
thruster (0.1.17-aarch64-linux) sha256=1b3a34b2814185c2aeaf835b5ecff5348cdcf8e77809f7a092d46e4b962a16ba

View File

@@ -0,0 +1,48 @@
class ProjectsController < ApplicationController
def index
@projects = Project.all
end
def show
@project = Project.find(params[:id])
end
def new
@project = Project.new
end
def create
@project = Project.new(project_params)
if @project.save
redirect_to @project
else
render :new
end
end
def edit
@project = Project.find(params[:id])
end
def update
@project = Project.find(params[:id])
if @project.update(project_params)
redirect_to @project
else
render :edit
end
end
def destroy
@project = Project.find(params[:id])
@project.destroy
redirect_to projects_path
end
private
def project_params
params.require(:project).permit(:project_name, :description)
end
end

View File

@@ -0,0 +1,53 @@
class TasksController < ApplicationController
before_action :set_project
def create
@task = @project.tasks.build(task_params)
if @task.save
respond_to do |format|
format.turbo_stream
format.html { redirect_to @project, notice: "Task created!" }
end
else
respond_to do |format|
format.turbo_stream { render turbo_stream: turbo_stream.replace("new_task", partial: "tasks/form", locals: { project: @project, task: @task }) }
format.html { render "projects/show", status: :unprocessable_entity }
end
end
end
def destroy
@task = @project.tasks.find_by(id: params[:id])
return unless @task
task_dom_id = "task_#{@task.id}"
@task.destroy
respond_to do |format|
format.turbo_stream { render turbo_stream: turbo_stream.remove(task_dom_id) }
format.html { redirect_to @project }
end
end
def complete
@task = @project.tasks.find(params[:id])
@task.update(status: "done")
respond_to do |format|
format.turbo_stream
format.html { redirect_to @project }
end
end
private
def set_project
@project = Project.find(params[:project_id])
end
def task_params
params.require(:task).permit(:title, :status)
end
end

View File

@@ -0,0 +1,2 @@
module ArticlesHelper
end

View File

@@ -0,0 +1,2 @@
module ProjectsHelper
end

View File

@@ -0,0 +1,2 @@
module TasksHelper
end

5
app/models/project.rb Normal file
View File

@@ -0,0 +1,5 @@
class Project < ApplicationRecord
has_many :tasks, dependent: :destroy
validates :project_name, :description, presence: true
end

7
app/models/task.rb Normal file
View File

@@ -0,0 +1,7 @@
class Task < ApplicationRecord
belongs_to :project
enum :status, { to_do: 0, in_progress: 1, done: 2 }
validates :title, presence: true
end

View File

@@ -0,0 +1,2 @@
<h1>Articles#index</h1>
<p>Find me in app/views/articles/index.html.erb</p>

View File

@@ -0,0 +1,15 @@
<h1>Projects</h1>
<ul>
<% @projects.each do |project| %>
<li><h3><a href="<%= project_path(project) %>"><%= project.project_name %></a></h3></li>
<%= link_to "Destroy", project_path(project), data: {
turbo_method: :delete,
turbo_confirm: "Are you sure?"
} %>
<% end %>
</ul>
<br>
<h2><%= link_to "Add Project", new_project_path %></h2>

View File

@@ -0,0 +1,23 @@
<h1>New Project</h1>
<%= form_with model: @project do |form| %>
<div>
<%= form.label :project_name %><br>
<%= form.text_field :project_name %>
<% @project.errors.full_messages_for(:project_name).each do |message| %>
<p><%= message %></p>
<% end %>
</div>
<div>
<%= form.label :description %><br>
<%= form.text_area :description %>
<% @project.errors.full_messages_for(:description).each do |message| %>
<p><%= message %></p>
<% end %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>

View File

@@ -0,0 +1,20 @@
<h1><%= @project.project_name %></h1>
<p><%= @project.description %></p>
<%= turbo_frame_tag "tasks" do %>
<ul id="tasks_list">
<% # First: pending or in-progress tasks %>
<%= render @project.tasks.reject { |t| t.status == "done" } %>
<% done_tasks = @project.tasks.select { |t| t.status == "done" } %>
<% if done_tasks.any? %>
<%= render done_tasks %>
<% end %>
</ul>
<% end %>
<%= turbo_frame_tag "new_task" do %>
<br>
<h2>Add New Task</h2>
<%= render "tasks/form", project: @project, task: Task.new %>
<% end %>

View File

@@ -0,0 +1,13 @@
<%= form_with model: [project, task], local: false do |f| %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :status %><br>
<%= f.select :status, Task.statuses.keys %>
</p>
<%= f.submit "Create Task" %>
<% end %>

View File

@@ -0,0 +1,20 @@
<turbo-frame id="<%= dom_id(task) %>">
<li id="<%= dom_id(task) %>" class="task-item <%= 'done-task' if task.status == 'done' %>">
<div class="task-title"><%= task.title %></div>
<div class="task-status"><%= task.status.titleize %></div>
<div class="task-actions flex gap-2">
<% unless task.status == "done" %>
<%= button_to "Complete",
complete_project_task_path(task.project, task),
method: :patch,
data: { turbo_frame: dom_id(task) },
class: "task-btn complete-btn" %>
<% end %>
<%= link_to "Destroy",
project_task_path(task.project, task),
data: { turbo_method: :delete, turbo_confirm: "Are you sure?" },
class: "task-btn destroy-btn" %>
</div>
</li>
</turbo-frame>

View File

@@ -0,0 +1,3 @@
<%= turbo_stream.replace dom_id(@task) do %>
<%= render @task %>
<% end %>

View File

@@ -0,0 +1,7 @@
<%= turbo_stream.append "tasks" do %>
<%= render @task %> <!-- renders _task.html.erb -->
<% end %>
<%= turbo_stream.replace "new_task" do %>
<%= render "tasks/form", project: @project, task: Task.new %>
<% end %>

View File

@@ -0,0 +1 @@
<%= turbo_stream.remove dom_id(@task) %>

View File

@@ -1,4 +1,17 @@
Rails.application.routes.draw do
root "projects#index"
resources :projects do
resources :tasks do
member do
patch :complete
end
end
end
# Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.

View File

@@ -0,0 +1,9 @@
class CreateProjects < ActiveRecord::Migration[8.1]
def change
create_table :projects do |t|
t.string :project_name
t.timestamps
end
end
end

View File

@@ -0,0 +1,10 @@
class CreateTasks < ActiveRecord::Migration[8.1]
def change
create_table :tasks do |t|
t.string :title
t.string :status
t.timestamps
end
end
end

View File

@@ -0,0 +1,5 @@
class AddDescriptionToProjects < ActiveRecord::Migration[8.1]
def change
add_column :projects, :description, :string
end
end

View File

@@ -0,0 +1,6 @@
class ChangeStatusTypeInTasks < ActiveRecord::Migration[8.1]
def change
remove_column :tasks, :status, :string
add_column :tasks, :status, :integer, default: 0, null: false
end
end

View File

@@ -0,0 +1,5 @@
class AddProjectToTasks < ActiveRecord::Migration[8.1]
def change
add_reference :tasks, :project, null: false, foreign_key: true
end
end

31
db/schema.rb generated Normal file
View File

@@ -0,0 +1,31 @@
# 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.
#
# This file is the source Rails uses to define your schema when running `bin/rails
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.1].define(version: 2026_01_26_094649) do
create_table "projects", force: :cascade do |t|
t.datetime "created_at", null: false
t.string "description"
t.string "project_name"
t.datetime "updated_at", null: false
end
create_table "tasks", force: :cascade do |t|
t.datetime "created_at", null: false
t.integer "project_id", null: false
t.integer "status", default: 0, null: false
t.string "title"
t.datetime "updated_at", null: false
t.index ["project_id"], name: "index_tasks_on_project_id"
end
add_foreign_key "tasks", "projects"
end

View File

@@ -7,3 +7,43 @@
# ["Action", "Comedy", "Drama", "Horror"].each do |genre_name|
# MovieGenre.find_or_create_by!(name: genre_name)
# end
# db/seeds.rb
Task.destroy_all
Project.destroy_all
project1 = Project.create!(
project_name: "project one",
description: "This is project one"
)
project2 = Project.create!(
project_name: "project two",
description: "This is project two"
)
Task.create!(
title: "first task of project one",
status: :to_do,
project: project1
)
Task.create!(
title: "second task of project one",
status: :in_progress,
project: project1
)
Task.create!(
title: "third task of project one",
status: :done,
project: project1
)
Task.create!(
title: "first task of project two",
status: :to_do,
project: project2
)
puts "Seeding complete"

View File

@@ -0,0 +1,8 @@
require "test_helper"
class ProjectsControllerTest < ActionDispatch::IntegrationTest
test "should get index" do
get projects_index_url
assert_response :success
end
end

View File

@@ -0,0 +1,7 @@
require "test_helper"
class TasksControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end
end

7
test/fixtures/projects.yml vendored Normal file
View File

@@ -0,0 +1,7 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
project_name: MyString
two:
project_name: MyString

9
test/fixtures/tasks.yml vendored Normal file
View File

@@ -0,0 +1,9 @@
# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
title: MyString
status: MyString
two:
title: MyString
status: MyString

View File

@@ -0,0 +1,7 @@
require "test_helper"
class ProjectTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end

7
test/models/task_test.rb Normal file
View File

@@ -0,0 +1,7 @@
require "test_helper"
class TaskTest < ActiveSupport::TestCase
# test "the truth" do
# assert true
# end
end