Commit 171c0eae by Vandana Singh

Worked on crud operation and testcases

parent ebb60b88
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
// Place all the styles related to the flower controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
class Api::V1::FlowerController < ApplicationController
def index
flower = Flower.all.order(created_at: :desc)
render json: flower
end
def create
# puts flower_params,'flower_params'
flower = Flower.create!(flower_params)
if flower
render json: flower
else
render json: flower.errors
end
end
def show
if flower
render json: flower
else
render json: flower.errors
end
end
def destroy
# puts flower,'flower_params'
flower&.destroy
render json: { message: 'Flower deleted!' }
end
def uploadFile
@filename = params[:file];
@lines = File.read(@filename.path)
doc = Nokogiri.XML(@lines, nil, 'utf-8')
name = doc.search('NAME').text
color = doc.search('COLOR').text
flower = Flower.create!(name: name, color: color)
render json: flower
end
private
def flower_params
params.permit(:name, :image, :color)
end
def flower
@flower ||= Flower.find(params[:id])
end
end
\ No newline at end of file
......@@ -5,6 +5,8 @@ class Api::V1::RecipesController < ApplicationController
end
def create
puts "valueuiuiuiuiuiuiuiiiuiuiiuiuiiuiuiuiuiuiuiuiuiuiu #{recipe_params}"
recipe = Recipe.create!(recipe_params)
if recipe
render json: recipe
......
module FlowerHelper
end
import React from "react";
import { Link } from "react-router-dom";
class AddFlower extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
color: "",
file: {}
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.fileUpload = this.fileUpload.bind(this);
this.submitFile = this.submitFile.bind(this);
this.stripHtmlEntities = this.stripHtmlEntities.bind(this);
}
stripHtmlEntities(str) {
return String(str)
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;");
}
onChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
onSubmit(event) {
event.preventDefault();
const url = "/api/v1/flower/create";
const { name, color } = this.state;
if (name.length == 0 || color.length == 0)
return;
const body = {
name,
color,
};
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch(url, {
method: "POST",
headers: {
"X-CSRF-Token": token,
"Content-Type": "application/json"
},
body: JSON.stringify(body)
})
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error("Network response was not ok.");
})
.then(response => this.props.history.push(`/flower/${response.id}`))
.catch(error => console.log(error.message));
}
fileUpload(event) {
this.setState({ [event.target.name]: event.target.files[0] });
}
submitFile(event) {
event.preventDefault();
const url = "/api/v1/flower/uploadFile";
const { file } = this.state;
if (file.length == 0)
return;
const formData = new FormData();
formData.append('file', file);
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch(url, {
method: "POST",
headers: {
"X-CSRF-Token": token,
},
body: formData
})
.then(response => {
if (response.ok) {
return response.json()
}
throw new Error("Network response was not ok.");
}).then(response => this.props.history.push(`/flower/${response.id}`))
.catch(error => console.log(error.message));
}
render() {
return (
<div className="container mt-5">
<div className="row">
<div className="col-sm-12 col-lg-6 offset-lg-3">
<h1 className="font-weight-normal mb-5">
Add a new flower to our awesome flower collection.
</h1>
<form onSubmit={this.submitFile}>
<input onChange={this.fileUpload} name="file" type="file" required />
<button type="submit" className="btn custom-button mt-3">
Upload File
</button>
</form>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label htmlFor="flowerName">flower name</label>
<input
type="text"
name="name"
id="flowerName"
className="form-control"
required
onChange={this.onChange}
/>
</div>
<div className="form-group">
<label htmlFor="flowerCOlor">Color</label>
<input
type="text"
name="color"
id="color"
className="form-control"
required
onChange={this.onChange}
/>
</div>
<button type="submit" className="btn custom-button mt-3">
Create flower
</button>
<Link to="/listFlower" className="btn btn-link mt-3">
Back to flowers
</Link>
</form>
</div>
</div>
</div>
);
}
}
export default AddFlower;
\ No newline at end of file
import React from "react";
import { Link } from "react-router-dom";
class flower extends React.Component {
constructor(props) {
super(props);
this.state = { flower: { color: "" } };
this.deleteflower = this.deleteflower.bind(this);
}
componentDidMount() {
const {
match: {
params: { id }
}
} = this.props;
const url = `/api/v1/flower/show/${id}`;
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error("Network response was not ok.");
})
.then(response => this.setState({ flower: response }))
.catch(() => this.props.history.push("/listFlower"));
console.log("hiiiiiiiiiiiiiiii");
}
render() {
const { flower } = this.state;
let color = "No color";
if (flower.color.length > 0) {
color = flower.color
.split(",")
.map((color, index) => (
<li key={index} className="list-group-item">
{color}
</li>
));
}
return (
<div className="">
<div className="hero position-relative d-flex align-items-center justify-content-center">
<img
src={flower.image}
alt={`${flower.name} image`}
className="img-fluid position-absolute"
/>
<div className="overlay bg-dark position-absolute" />
<h1 className="display-4 position-relative text-white">
{flower.name}
</h1>
</div>
<div className="container py-5">
<div className="row">
<div className="col-sm-12 col-lg-3">
<ul className="list-group">
<h5 className="mb-2">Color</h5>
{color}
</ul>
</div>
<div className="col-sm-12 col-lg-2">
<button type="button" className="btn btn-danger" onClick={this.deleteflower}>
Delete flower
</button>
</div>
</div>
<Link to="/listFlower" className="btn btn-link">
Back to flowers
</Link>
</div>
</div>
);
}
deleteflower() {
const {
match: {
params: { id }
}
} = this.props;
const url = `/api/v1/flower/destroy/${id}`;
const token = document.querySelector('meta[name="csrf-token"]').content;
fetch(url, {
method: "DELETE",
headers: {
"X-CSRF-Token": token,
"Content-Type": "application/json"
}
})
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error("Network response was not ok.");
})
.then(() => this.props.history.push("/listFlower"))
.catch(error => console.log(error.message));
}
}
export default flower;
\ No newline at end of file
......@@ -27,6 +27,13 @@ export default () => (
>
View Employees
</Link>
<Link
to="/listFlower"
className="btn btn-lg custom-button"
role="button"
>
View Flowers
</Link>
</div>
</div>
</div>
......
import React from "react";
import { Link } from "react-router-dom";
class ListFlower extends React.Component {
constructor(props) {
super(props);
this.state = {
flowers: []
};
}
componentDidMount() {
const url = "/api/v1/flower/index";
fetch(url)
.then(response => {
if (response.ok) {
return response.json();
}
throw new Error("Network response was not ok.");
})
.then(response => this.setState({ flowers: response }))
.catch(() => this.props.history.push("/"));
}
render() {
const { flowers } = this.state;
const allflowers = flowers.map((flower, index) => (
<div key={index} className="col-md-6 col-lg-4">
<div className="card mb-4">
<img
src={flower.image}
className="card-img-top"
alt={`${flower.name} image`}
/>
<div className="card-body">
<h5 className="card-title">{flower.name}</h5>
<Link to={`/flower/${flower.id}`} className="btn custom-button">
View flower
</Link>
</div>
</div>
</div>
));
const noFlower = (
<div className="vw-100 vh-50 d-flex align-items-center justify-content-center">
<h4>
No flowers yet. Why not <Link to="/addFlower">create one</Link>
</h4>
</div>
);
return (
<>
<section className="jumbotron jumbotron-fluid text-center">
<div className="container py-5">
<h1 className="display-4">flowers for every occasion</h1>
<p className="lead text-muted">
We’ve pulled together our most popular flowers.
</p>
</div>
</section>
<div className="py-5">
<main className="container">
<div className="text-right mb-3">
<Link to="/addFlower" className="btn custom-button">
Add New Flower
</Link>
</div>
<div className="row">
{flowers.length > 0 ? allflowers : noFlower}
</div>
<Link to="/" className="btn btn-link">
Home
</Link>
</main>
</div>
</>
);
}
}
export default ListFlower;
\ No newline at end of file
......@@ -7,7 +7,9 @@ import NewRecipe from "../components/NewRecipe";
import Employees from "../components/Employees";
import Employee from "../components/Employee";
import NewEmployee from "../components/NewEmployee";
import ListFlower from '../components/ListFlower'
import AddFlower from '../components/AddFlower'
import flower from '../components/Flower'
export default (
<Router>
<Switch>
......@@ -18,6 +20,9 @@ export default (
<Route path="/employees" exact component={Employees} />
<Route path="/employee/:id" exact component={Employee} />
<Route path="/employee" exact component={NewEmployee} />
<Route path="/listFlower" exact component={ListFlower} />
<Route path="/addFlower" exact component={AddFlower} />
<Route path="/flower/:id" exact component={flower} />
</Switch>
</Router>
);
\ No newline at end of file
class Flower < ApplicationRecord
validates :name, presence: true
validates :color, presence: true
end
......@@ -17,6 +17,15 @@ Rails.application.routes.draw do
post 'recipes/uploadFile'
end
end
namespace :api do
namespace :v1 do
get 'flower/index'
post 'flower/create'
get 'flower/show/:id', to: 'flower#show'
delete 'flower/destroy/:id', to: 'flower#destroy'
post 'flower/uploadFile'
end
end
root 'homepage#index'
get '/*path' => 'homepage#index'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
......
class CreateFlowers < ActiveRecord::Migration[5.2]
def change
create_table :flowers do |t|
t.string :name
t.text :color
t.string :image
t.timestamps
end
end
end
......@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_09_30_024252) do
ActiveRecord::Schema.define(version: 2020_10_02_123017) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
......@@ -27,6 +27,14 @@ ActiveRecord::Schema.define(version: 2020_09_30_024252) do
t.datetime "updated_at", null: false
end
create_table "flowers", force: :cascade do |t|
t.string "name"
t.text "color"
t.string "image"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "recipes", force: :cascade do |t|
t.string "name", null: false
t.text "ingredients", null: false
......
FactoryBot.define do
factory :random_flower, class: Flower do
name { Faker::FunnyName.name }
color { Faker::Color.color_name }
end
end
require 'rails_helper'
RSpec.describe Flower, type: :model do
context 'Validation Test Case' do
let(:flower) { build(:random_flower) }
it 'name validation' do
# flower = Employee.new(lastName: 'last', email: 'vijay@getnada.com', phone: '0909128031', dob: '11/11/1111', address: 'Noida').save
flower.name = nil
expect(flower.save).to eq(false)
end
it 'color validation' do
# employee = Employee.new(firstName: 'vijay', email: 'vijay@getnada.com', phone: '0909128031', dob: '11/11/1111', address: 'Noida').save
flower.color = nil;
expect(flower.save).to eq(false)
end
it 'null validation' do
flower = Flower.new(name: 'lily',color: 'pink').save
expect(flower).to eq(true)
end
context 'Flower Table Operations Test Case' do
it 'Save Flower Test' do
flower = Flower.new(name: 'lily',color: 'pink').save
# puts flower,'pppppppppppppp'
expect(flower).to eq(true)
end
it 'Delete Flower Test' do
flower = Flower.delete(name: 'jkjkjkjkjk')
# puts flower,'kkkkkkkkkkkkkkk'
expect(flower).to eq(0)
end
end
# context 'scope test' do
# let(:xxx) { create_list(:random_flower, 5)}
# it 'should return active user' do
# expect(Flower.active_employee.size).to eq(5)
# end
# end
end
end
......@@ -5,6 +5,7 @@ require File.expand_path('../config/environment', __dir__)
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require 'capybara/rails'
# Add additional requires below this line. Rails is not loaded until this point!
# Requires supporting ruby files with custom matchers and macros, etc, in
......
require 'rails_helper'
RSpec.describe "Api::V1::Flowers", type: :request do
describe "GET /index" do
it "INdexxxxxxxxxxxxxxx" do
get("/api/v1/flower/index")
expect(response.status).to eq(200)
# expect(response).to be_successful #response.success
end
end
describe "POST /create" do
it "returns http success for createeeeeeeeeeeeee" do
# flower = Flower.create!(name: 'Quality', color: 'Pinkkkkkkkkkkk').save
# post("/api/v1/flower/create")
flower = post "/api/v1/flower/create",params:{name:'Casual Leave', color:'pink'}
expect(response).to have_http_status(:success)
end
end
describe "GET /show" do
it "returns http success for show" do
flower = Flower.create!(name: 'Quality', color: 'Pinkkkkkkkkkkk')
# puts flower,'showwwwwwwwwwwwwwwwwwwwww'
get("/api/v1/flower/show/#{flower.to_param}")
expect(response).to have_http_status(:success)
end
end
describe "DELETE /destroy" do
it "returns http success for destroy" do
flower = Flower.create!(name: 'Quality', color: 'Pinkkkkkkkkkkk')
# puts flower,'deleteeeeeeeeeeeeeeeeeeeeeee'
delete("/api/v1/flower/destroy/#{flower.to_param}")
expect(response.status).to eq(200)
end
end
end
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment