<commit_before>require 'spec_helper'

describe ProductsController do
  render_views

  let(:creator) { User.make! }
  let(:collaborator) { User.make! }
  let(:product) { Product.make!(user: creator) }

  describe '#new' do
    it "redirects on signed out" do
      get :new
      expect(response).to redirect_to(new_user_session_path)
    end

    it "is successful when signed in" do
      sign_in creator
      get :new
      expect(response).to be_success
    end
  end

  describe '#show' do
    context 'product is launched' do
      it "is successful" do
        get :show, id: product.slug
        expect(response).to be_success
      end
    end
    context 'product in stealth' do
      let(:product) { Product.make!(launched_at: nil) }

      it "redirects to edit if only name and pitch fields are present" do
        get :show, id: product
        expect(response).to redirect_to(edit_product_path(product))
      end

      it "is successful if fields other than name and pitch are present" do
        product.update_attributes goals: '7'

        get :show, id: product
        expect(response).to be_success
      end
    end
  end

  describe '#edit' do
    it "is successful" do
      product.team_memberships.create(user: product.user, is_core: true)
      sign_in product.user
      get :edit, id: product.slug
      expect(response).to be_success
    end
  end

  describe '#create' do
    before do
      sign_in creator
    end

    context 'with good params' do
      before { post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life', terms_of_service: '1' } }

      it "create's product" do
        expect(assigns(:product)).to be_a(Product)
        expect(assigns(:product)).to be_persisted
      end

      it 'adds user to core team' do
        expect(assigns(:product).core_team).to include(creator)
      end

      it 'should redirect to welcome page' do
        expect(response).to redirect_to(product_welcome_path(assigns(:product)))
      end

      it 'has slug based on name' do
        expect(assigns(:product).slug).to eq('kjdb')
      end

      it 'auto upvotes product' do
        post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }
        expect(assigns(:product).votes.count).to eq(1)
      end

      it 'adds creator to the core team' do
        expect(assigns(:product).core_team).to match_array([creator])
      end

      it 'adds validated transaction entry for product' do
        expect(TransactionLogEntry.validated.count).to eq(1)
      end

      it 'creates a main discussion thread' do
        expect(Discussion.count).to eq(1)
        expect(assigns(:product).main_thread).to be_persisted
      end
    end

    it 'fails if terms of service not accepted' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }
      expect(response).to_not be_success
    end

    it 'creates a product with core team' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, core_team: [collaborator.id]
      expect(assigns(:product).core_team).to include(collaborator)
    end

    it 'gives auto tip contracts to core team members' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, core_team: [collaborator.id]
      expect(assigns(:product).auto_tip_contracts.map(&:user)).to include(collaborator)
    end

    it 'creates an invite for core team members with email' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, core_team: ['<EMAIL>']

      expect(
        Invite.find_by(invitee_email: '<EMAIL>').via.name
      ).to eq('KJDB')
    end

    it 'creates invite with tip to collaborator' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, ownership: { collaborator.id => 10 }

      invite = Invite.find_by(invitee_id: collaborator.id)
      expect(invite.tip_cents).to eq(600)
      expect(invite.via.name).to eq('KJDB')
      expect(invite.core_team?).to be_true
    end
  end

  describe '#update' do
    before do
      sign_in creator
    end

    it 'updates all fields' do
      info_fields = Product::INFO_FIELDS.each_with_object({}) do |field, h|
        h[field.to_sym] = field
      end

      attrs = {
        name: 'KJDB',
        pitch: 'Manage your karaoke life',
        description: 'it is good.'
      }.merge(info_fields)

      patch :update, id: product, product: attrs
      expect(product.reload).to have_attributes(attrs)
    end
  end

  describe '#launch' do
    let(:product) { Product.make!(launched_at: nil, user: creator) }

    before do
      sign_in creator<commit_msg>Fix failing tests<commit_after>require 'spec_helper'

describe ProductsController do
  render_views

  let(:creator) { User.make! }
  let(:collaborator) { User.make! }
  let(:product) { Product.make!(user: creator) }

  describe '#new' do
    it "redirects on signed out" do
      get :new
      expect(response).to redirect_to(new_user_session_path)
    end

    it "is successful when signed in" do
      sign_in creator
      get :new
      expect(response).to be_success
    end
  end

  describe '#show' do
    context 'product is launched' do
      it "is successful" do
        get :show, id: product.slug
        expect(response).to be_success
      end
    end
    context 'product in stealth' do
      let(:product) { Product.make!(launched_at: nil) }

      it "redirects to edit if only name and pitch fields are present" do
        get :show, id: product
        expect(response).to redirect_to(edit_product_path(product))
      end

      it "is successful if fields other than name and pitch are present" do
        product.update_attributes goals: '7'

        get :show, id: product
        expect(response).to be_success
      end
    end
  end

  describe '#edit' do
    it "is successful" do
      product.team_memberships.create(user: product.user, is_core: true)
      sign_in product.user
      get :edit, id: product.slug
      expect(response).to be_success
    end
  end

  describe '#create' do
    before do
      sign_in creator
    end

    context 'with good params' do
      before { post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' } }

      it "create's product" do
        expect(assigns(:product)).to be_a(Product)
        expect(assigns(:product)).to be_persisted
      end

      it 'adds user to core team' do
        expect(assigns(:product).core_team).to include(creator)
      end

      it 'should redirect to welcome page' do
        expect(response).to redirect_to(product_welcome_path(assigns(:product)))
      end

      it 'has slug based on name' do
        expect(assigns(:product).slug).to eq('kjdb')
      end

      it 'auto upvotes product' do
        post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }
        expect(assigns(:product).votes.count).to eq(1)
      end

      it 'adds creator to the core team' do
        expect(assigns(:product).core_team).to match_array([creator])
      end

      it 'creates a main discussion thread' do
        expect(Discussion.count).to eq(1)
        expect(assigns(:product).main_thread).to be_persisted
      end
    end

    it 'fails if terms of service not accepted' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }
      expect(response).to_not be_success
    end

    it 'creates a product with core team' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, core_team: [collaborator.id]
      expect(assigns(:product).core_team).to include(collaborator)
    end

    it 'gives auto tip contracts to core team members' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, core_team: [collaborator.id]
      expect(assigns(:product).auto_tip_contracts.map(&:user)).to include(collaborator)
    end

    it 'creates an invite for core team members with email' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, core_team: ['<EMAIL>']

      expect(
        Invite.find_by(invitee_email: '<EMAIL>').via.name
      ).to eq('KJDB')
    end

    it 'creates invite with tip to collaborator' do
      post :create, product: { name: 'KJDB', pitch: 'Manage your karaoke life' }, ownership: { collaborator.id => 10 }

      invite = Invite.find_by(invitee_id: collaborator.id)
      expect(invite.tip_cents).to eq(60000)
      expect(invite.via.name).to eq('KJDB')
      expect(invite.core_team?).to be_true
    end
  end

  describe '#update' do
    before do
      sign_in creator
    end

    it 'updates all fields' do
      info_fields = Product::INFO_FIELDS.each_with_object({}) do |field, h|
        h[field.to_sym] = field
      end

      attrs = {
        name: 'KJDB',
        pitch: 'Manage your karaoke life',
        description: 'it is good.'
      }.merge(info_fields)

      patch :update, id: product, product: attrs
      expect(product.reload).to have_attributes(attrs)
    end
  end

  describe '#launch' do
    let(:product) { Product.make!(launched_at: nil, user: creator) }

    before do
      sign_in creator
{'fraction_non_alphanumeric': 0.10379829731499672, 'fraction_numerical': 0.0021829294913774284, 'mean_word_length': 2.7430555555555554, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4115324', 'n_tokens_mistral': 2922, 'n_tokens_neox': 2838, 'n_words': 870}