require 'swagger_helper' namespace = '<%= @customer_class_name.underscore %>' RSpec.describe "#{namespace}/orders", type: :request, capture_examples: true, tags: ["#{namespace} API", "order"] do before do @user = create(:user) @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", } } ) @snapshot_1 = create(:product_snapshot, series: @series_1, count: 2) @snapshot_2 = create(:product_snapshot, series: @series_1, count: 5) @snapshot_other = create(:product_snapshot, series: @series_2, count: 5) @orders = create_list(:order, 3, buyer: @user) @order_1 = @orders.first @cart = @order_1.class.cart_class.create!(buyer: @user) @snapshot_1.update!(order: @order_1) @snapshot_other.update!(order: @order_1) @snapshot_2.update!(order_cart: @cart) end path "/#{namespace}/orders/cart" do get(summary: '用户 购物车') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } response(200, description: 'cart') do it { expect(JSON.parse(response.body)['snapshots'].count).to eq(1) } end end end path "/#{namespace}/orders/add_to_cart" do post(summary: '用户 添加快照至购物车( using series_id & count )') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } parameter :snapshot, in: :body, schema: { type: :object, properties: { snapshot: { type: :object, properties: { shotengai_series_id: { type: :integer }, count: { type: :integer }, } } } } response(201, description: 'Create snapshot and add it to the cart') do let(:snapshot) { { snapshot: { shotengai_series_id: @series_1.id, count: 10, } } } it { expect(JSON.parse(response.body)['count']).to eq(10) expect(@cart.snapshots.count).to eq(2) } end end end path "/#{namespace}/orders" do get(summary: '用户 订单列表') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } parameter :page, in: :query, type: :string parameter :per_page, in: :query, type: :string parameter :status, in: :query, type: :string let(:page) { 1 } let(:per_page) { 100 } produces 'application/json' consumes 'application/json' response(200, description: 'successful') do it { expect(JSON.parse(response.body)['orders'].count).to eq(3) } end response(200, description: 'filter by status') do before { @orders.last.pay! } let(:status) { 'paid' } it { expect(JSON.parse(response.body)['orders'].count).to eq(1) } end end post(summary: '用户 创建订单(using incr_snapshot_ids') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } parameter :order, in: :body, schema: { type: :object, properties: { order: { type: :object, properties: { address: { type: :string }, user_remark: { type: :text }, incr_snapshot_ids: { type: :array }, # gone_snapshot_ids: { type: :array }, } } } } response(201, description: 'successful') do let(:order) {{ order: { address: 'This is an special address.', user_remark: 'user remark ...', incr_snapshot_ids: [ @snapshot_2.id ], } }} it { body = JSON.parse(response.body) expect(body['snapshots'].count).to eq(1) expect(body['snapshots'].first['id']).to eq(@snapshot_2.id) expect(@snapshot_2.reload.is_in_cart).to eq(false) } end response(400, description: 'failed, Cannot edit a snapshot which order was already paid.') do let(:order) {{ order: { incr_snapshot_ids: [ @snapshot_1.id ], } }} before { @order_1.pay! } it { expect(response.status).to eq(400) } end end end path "/#{namespace}/orders/create_directly" do post(summary: 'create order') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } parameter :order_and_snapshot_params, in: :body, schema: { type: :object, properties: { order: { type: :object, properties: { address: { type: :string }, user_remark: { type: :text }, }, snapshot: { type: :object, properties: { shotengai_series_id: { type: :integer }, count: { type: :integer }, } } } } } response(201, description: 'successful') do let(:order_and_snapshot_params) { { order: { address: 'This is an special address.', user_remark: 'user remark ...' }, snapshot: { shotengai_series_id: @series_1.id, count: 10, } } } it { body = JSON.parse(response.body) expect(body['snapshots'].count).to eq(1) expect(body['snapshots'].first['shotengai_series_id']).to eq(@series_1.id) } end end end path "/#{namespace}/orders/{id}" do parameter :id, in: :path, type: :integer let(:id) { @order_1.id } get(summary: '用户 订单详情') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } response(200, description: 'successful') do it { expect(JSON.parse(response.body)['snapshots'].count).to eq(@order_1.snapshots.count) } end end patch( summary: 'update order 【 incr_snapshot_ids 移入该order的snapshot_id 数组, gone_snapshot_ids 移入购物车的 snapshot_id 数组 】' ) do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } parameter :order, in: :body, schema: { type: :object, properties: { order: { type: :object, properties: { address: { type: :string }, user_remark: { type: :text }, incr_snapshot_ids: { type: :array }, gone_snapshot_ids: { type: :array }, } } } } response(200, description: 'successful') do let(:order) {{ order: { address: 'This is an special address.', user_remark: 'user remark ...', incr_snapshot_ids: [ @snapshot_2.id ], gone_snapshot_ids: [ @snapshot_1.id ], } }} it { expect(@order_1.reload.address).to eq('This is an special address.') # Move @snapshot_1 out of order to the cart expect(@snapshot_1.reload.is_in_cart).to eq(true) # Move @snapshot_2 into order expect(@snapshot_2.reload.is_in_cart).to eq(false) } end response(403, description: 'failed, Can edit a unpaid order only.') do let(:order) {{ order: { address: 'This is an special address.', user_remark: 'user remark ...' } }} before { @order_1.pay! } it { expect(response.status).to eq(403) } end end end path "/#{namespace}/orders/{id}/pay" do parameter :id, in: :path, type: :integer let(:id) { @order_1.id } post(summary: '用户 支付订单') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } produces 'application/json' consumes 'application/json' response(200, description: 'successful') do it { expect(JSON.parse(response.body)['pay_time']).not_to be_nil } end end end path "/#{namespace}/orders/{id}/cancel" do parameter :id, in: :path, type: :integer let(:id) { @order_1.id } post(summary: '用户 取消未支付订单') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } produces 'application/json' consumes 'application/json' response(200, description: 'successful') do it { expect(JSON.parse(response.body)['status']).to eq('canceled') } end response(400, description: 'failed , you can cancel a order which status is unpaid') do before { @order_1.pay! } it { expect(response.status).to eq(400) } end end end path "/#{namespace}/orders/{id}/get_it" do parameter :id, in: :path, type: :integer let(:id) { @order_1.id } post(summary: '用户 确认收货') do produces 'application/json' consumes 'application/json' parameter :buyer_type, in: :query, type: :string parameter :buyer_id, in: :query, type: :integer let(:buyer_id) { @user.id } let(:buyer_type) { @user.class.name } before { @order_1.update!(status: 'delivering') } produces 'application/json' consumes 'application/json' response(200, description: 'successful') do it { expect(JSON.parse(response.body)['receipt_time']).not_to be_nil } end end end end