Commit 7ebcb238 by ivan Lan

Refactory Catalog tagging with id & Improve spec for the change

parent 8f0730f9
require 'swagger_helper'
namespace = '<%= @namespace %>'
RSpec.describe "#{namespace}/products/:product_id/product_series", type: :request, capture_examples: true, tags: ["#{namespace} API", "product_series"] do
RSpec.describe "#{namespace}/products", type: :request, capture_examples: true, tags: ["#{namespace} API", "product"] do
before do
class Catalog < Shotengai::Catalog; end
@clothes = Catalog.create!(name: '衣服')
@jacket = Catalog.create!(name: '上衣', super_catalog: @clothes)
@products = create_list(:product, 3)
@product_1 = @products.first
@series_1 = create(
:product_series,
product: @product_1,
spec: {
"颜色" => "白色",
"大小" => "S",
}
)
@series_2 = create(
:product_series, {
product: @product_1,
spec: {
"颜色" => "黑色",
"大小" => "S",
}
}
)
@product_1.update(catalog_ids: @clothes.id)
@series = create(:product_series, product: @product_1)
end
path "/#{namespace}/products/{product_id}/product_series" do
parameter :product_id, in: :path, type: :string
let(:product_id) { @product_1.id }
path "/#{namespace}/products" do
get(summary: '用户 某商品的 商品系列 列表') do
get(summary: '用户 商品列表') do
parameter :page, in: :query, type: :string
parameter :per_page, in: :query, type: :string
parameter :per_page, in: :query, type: :string
parameter :catalog_ids, in: :query, type: :array
let(:page) { 1 }
let(:per_page) { 100 }
let(:per_page) { 999 }
produces 'application/json'
consumes 'application/json'
response(200, description: 'successful') do
it {
expect(JSON.parse(response.body)['product_series'].count).to eq(@product_1.series.count)
}
it { expect(JSON.parse(response.body)['products'].count).to eq(Product.count) }
end
response(200, description: 'filter by catalog') do
let(:catalog_ids) { [@clothes.id] }
it { expect(JSON.parse(response.body)['products'].count).to eq(1) }
end
end
end
path "/#{namespace}/product_series/{id}" do
parameter :id, in: :path, type: :string
path "/#{namespace}/products/{id}" do
parameter 'id', in: :path, type: :string
let(:id) { @series_1.id }
let(:id) { @product_1.id }
get(summary: '用户 商品系列的详情') do
get(summary: '用户 商品详情') do
produces 'application/json'
consumes 'application/json'
response(200, description: 'successful') do
# it { p response.body }
it {
expect(JSON.parse(response.body)['series'].count).to eq(@product_1.series.count), "correct product's series"
}
end
end
end
end
\ No newline at end of file
end
......@@ -2,7 +2,8 @@ require 'swagger_helper'
namespace = '<%= @namespace %>'
RSpec.describe "#{namespace}/products", type: :request, capture_examples: true, tags: ["#{namespace} API", "product"] do
before do
@merchant = create(:merchant)
@merchant = Merchant.register "merchant", "password"
@auth_token = Merchant.login "merchant", "password"
class Catalog < Shotengai::Catalog; end
@clothes = Catalog.create!(name: '衣服')
......@@ -10,38 +11,32 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
@products = create_list(:product, 3, manager: @merchant)
@product_1 = @products.first
@product_1.update(catalog_list: ['衣服'])
@product_1.update(catalog_ids: @clothes.id)
@series = create(:product_series, product: @product_1)
end
path "/#{namespace}/products" do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
get(summary: '商家 商品列表') do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
parameter :page, in: :query, type: :string
parameter :per_page, in: :query, type: :string
parameter :status, in: :query, type: :string
parameter :catalog_list, in: :query, type: :array
parameter :catalog_ids, in: :query, type: :array
let(:page) { 1 }
let(:per_page) { 2 }
let(:per_page) { 999 }
produces 'application/json'
consumes 'application/json'
response(200, description: 'successful') do
it { expect(JSON.parse(response.body)['products'].count).to eq(2) }
it { expect(JSON.parse(response.body)['products'].count).to eq(Product.where(manager: @merchant).count) }
end
response(200, description: 'filter by catalog') do
let(:catalog_list) { @product_1.catalog_list }
let(:catalog_ids) { [@clothes.id] }
it { expect(JSON.parse(response.body)['products'].count).to eq(1) }
end
......@@ -53,17 +48,15 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
end
post(summary: '管理员新建商品') do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
parameter :product, in: :body, schema: {
type: :object, properties: {
product: {
type: :object, properties: {
title: { type: :string },
# default_series_id: { type: :integer },
default_series_id: { type: :integer },
need_express: { type: :boolean },
need_time_attr: { type: :boolean },
cover_image: { type: :string },
......@@ -89,7 +82,7 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
meta2: { type: :ineteger },
},
},
catalog_list: { type: :array }
catalog_ids: { type: :array }
}
}
}
......@@ -103,12 +96,12 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
{
product: product_attrs.merge(
default_series_id: @series.id,
catalog_list: ['衣服', '上衣'],
catalog_ids: [@clothes.id, @jacket.id],
)
}
}
it 'check attrs' do
body = JSON.parse(response.body)
body = JSON.parse(response.body)
the_same_values = ['spec', 'banners', 'detail', 'meta', 'title', 'need_express', 'need_time_attr'] # and so on
expect(product_attrs.values_at the_same_values).to eq(body.values_at the_same_values)
expect(body['default_series']['id']).to eq(@series.id), 'correct default_series'
......@@ -125,10 +118,8 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
let(:ids) { @products.first(2).map(&:id) }
let(:event) { 'put_on_shelf' }
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
produces 'application/json'
consumes 'application/json'
response(200, description: 'successful') do
......@@ -143,16 +134,9 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
parameter 'id', in: :path, type: :string
let(:id) { @product_1.id }
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
get(summary: '商户 商品详情') do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
produces 'application/json'
consumes 'application/json'
response(200, description: 'successful') do
......@@ -162,10 +146,8 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
end
end
patch(summary: 'update product') do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
produces 'application/json'
consumes 'application/json'
......@@ -201,7 +183,7 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
meta2: { type: :ineteger },
},
},
catalog_list: { type: :array }
catalog_ids: { type: :array }
}
}
}
......@@ -213,10 +195,8 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
end
delete(summary: 'delete product') do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
produces 'application/json'
consumes 'application/json'
......@@ -229,16 +209,9 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
parameter 'id', in: :path, type: :string
let(:id) { @product_1.id }
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
post(summary: '商户 上架商品') do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
produces 'application/json'
consumes 'application/json'
......@@ -252,16 +225,9 @@ RSpec.describe "#{namespace}/products", type: :request, capture_examples: true,
parameter 'id', in: :path, type: :string
let(:id) { @product_1.id }
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
post(summary: '商户 下架商品') do
parameter :manager_type, in: :query, type: :string
parameter :manager_id, in: :query, type: :integer
let(:manager_id) { @merchant.id }
let(:manager_type) { @merchant.class.name }
parameter 'Merchant-Token', in: :header, type: :string
let('Merchant-Token') { @auth_token.token }
before { @product_1.update!(status: 'on_sale') }
produces 'application/json'
......
......@@ -3,4 +3,5 @@ json.extract! order, :id, :seq, :address, :amount
:pay_time, :delivery_time, :receipt_time,
:delivery_way, :delivery_cost,
:merchant_remark, :mark, :customer_remark,
:status, :status_zh, :meta, :created_at
\ No newline at end of file
:status, :status_zh, :meta, :created_at
json.snapshots order.snapshots, partial: 'shotengai/share/snapshot_simple', as: :snapshot
......@@ -47,6 +47,13 @@ module Shotengai
where(super_catalog_id: nil).map(&:tree)
end
def ids_to_tags ids
where(id: ids).map(&:tag_chain).reduce(:|)
end
def parse_tag tag
tag.split('-').last
end
# def input_from_file
# end
end
......@@ -57,6 +64,10 @@ module Shotengai
ary
end
def tag
"#{self.class.name}-#{id}"
end
def nest_level
ancestors.count
end
......@@ -65,6 +76,10 @@ module Shotengai
ancestors.map(&:name)
end
def tag_chain
ancestors.map(&:tag)
end
def brothers
super_catalog.sub_catalogs
end
......
......@@ -9,9 +9,9 @@ module Shotengai
skip_before_action :buyer_auth
def index_query resources
params[:catalog_list] ?
resources.tagged_with(params[:catalog_list], on: :catalogs) :
resources
p params[:catalog_ids]
p ::Catalog.find_by_id(params[:catalog_ids])
resources.catalog_list_filter(::Catalog.find_by_id(params[:catalog_ids]))
end
end
end
......
......@@ -13,10 +13,8 @@ module Shotengai
end
def index_query resources
(
params[:catalog_list] ?
resources.tagged_with(params[:catalog_list], on: :catalogs) :
resources
resources.catalog_list_filter(
::Catalog.find_by_id(params[:catalog_ids])
).where(
params[:status].blank?.! && { status: params[:status] }
)
......@@ -60,7 +58,7 @@ module Shotengai
# NOTE: :catalog_list is a default catalog list for template example, maybe should move it to the template controller, but it need add controller template for every controller
params.require(resource_key).permit(
:title, :default_series_id,
:need_express, :need_time_attr, :cover_image, catalog_list: [],
:need_express, :need_time_attr, :cover_image, catalog_ids: [],
banners: []
).merge(
{ spec: spec, detail: detail, meta: meta }
......
......@@ -111,14 +111,29 @@ module Shotengai
catalog_class = catalog_class_name.constantize
tag_name = options[:as] || catalog_class.model_name.singular
acts_as_taggable_on tag_name.to_sym
# set { validate_name_chain: false } to skip the validate_name_chain
# 只有完整替换(只属于一个分类)的时候才进行验证,add remove 暂时未添加
# Just catalogs_list= have a validation
options[:validate_name_chain].eql?(false) || class_eval do
define_method("#{tag_name}_list=") { |value|
super catalog_class.validate_name_chain(value)
list_name = "#{tag_name}_list".to_sym
class_eval do
# define_method("#{tag_name}_list=") { |value|
# super catalog_class.validate_name_chain(value)
# }
scope "#{list_name}_filter".to_sym, ->(catalogs) {
tags = catalogs && catalogs.try(:tag) || catalogs&.map(&:tag)
tags ? tagged_with(tags, on: list_name) : all
}
define_method("#{tag_name}_ids=") { |ids|
send("#{list_name}=", catalog_class.ids_to_tags(ids))
}
define_method(list_name) {
catalog_class.where(id: super().map { |tag| Shotengai::Catalog.parse_tag(tag) }).select(:name).map(&:name)
}
end
# instance_eval do
# define_method(:)
# end
end
end
......
......@@ -99,11 +99,11 @@ module Shotengai
###### view
def total_price
revised_amount || count * self.price
(revised_amount || count.to_d * self.price).round(2)
end
def total_original_price
count * original_price
(count * original_price).round(2)
end
def is_in_cart
......
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