Clone
entry_submission_service_spec.rb
require 'spec_helper'

describe Locomotive::Steam::EntrySubmissionService do

  let(:site)              { instance_double('Site', default_locale: 'en') }
  let(:locale)            { 'en' }
  let(:type_repository)   { instance_double('ContentTypeRepository') }
  let(:entry_repository)  { instance_double('Repository', site: site, locale: locale, content_type_repository: type_repository) }
  let(:service)           { described_class.new(type_repository, entry_repository, locale) }

  before { allow(entry_repository).to receive(:with).and_return(entry_repository) }

  describe '#find' do

    let(:type_slug) { 'articles' }
    let(:slug)      { 'hello-world' }
    subject { service.find(type_slug, slug) }

    context 'unknown content type' do

      before { allow(type_repository).to receive(:by_slug).and_return(nil) }
      it { is_expected.to eq nil }

    end

    context 'existing content type' do

      let(:type) { instance_double('Articles') }
      let(:entry) { instance_double('Entry', title: 'Hello world', content_type: type, attributes: { title: 'Hello world' }, localized_attributes: []) }

      before do
        allow(type_repository).to receive(:by_slug).and_return(type)
        allow(entry_repository).to receive(:by_slug).with('hello-world').and_return(entry)
      end

      it { is_expected.to eq entry }

    end

  end

  describe '#to_json' do

    let(:entry) { nil }
    subject { service.to_json(entry) }

    it { is_expected.to eq nil }

    context 'existing content entry' do

      let(:field)   { instance_double('TitleField', name: :title, type: :string) }
      let(:fields)  { [field] }
      let(:type)    { instance_double('Articles', slug: 'articles', label_field_name: :title, fields_by_name: { title: field }, persisted_field_names: [:title]) }
      let(:entry)   { Locomotive::Steam::ContentEntry.new(_slug: 'hello-world', title: 'Hello world', content_type: type) }

      before { allow(type).to receive(:fields).and_return(instance_double('FieldRepository', all: fields)) }

      it { is_expected.to match %r{{"_id":null,"_slug":"hello-world","_label":"Hello world","_visible":true,"_position":0,"content_type_slug":"articles","created_at":"[^\"]+","updated_at":"[^\"]+","title":"Hello world"}} }

      context 'with errors' do

        before { entry.errors.add(:title, "can't be blank") }

        it { is_expected.to match %r{,\"errors\":\{\"title\":\[\"can't be blank\"\]\}} }

      end

    end

  end

  describe '#submit' do

    let(:slug)        { nil }
    let(:attributes)  { { title: 'Hello world' } }
    subject { service.submit(slug, attributes) }

    it { is_expected.to eq nil }

    context 'unknown content type' do

      let(:slug) { 'articles' }

      before { allow(type_repository).to receive(:by_slug).with('articles').and_return nil }

      it { is_expected.to eq nil }

    end

    context 'existing content type' do

      let(:unique_fields)     { {} }
      let(:first_validation)  { false }
      let(:errors)            { [:title] }
      let(:enabled)           { true }
      let(:type)  { instance_double('Comments', public_submission_enabled: enabled) }
      let(:entry) { instance_double('Entry', title: 'Hello world', content_type: type, valid?: first_validation, errors: errors, attributes: { title: 'Hello world' }, localized_attributes: []) }
      let(:slug)  { 'comments' }

      before do
        allow(type_repository).to receive(:by_slug).and_return(type)
        allow(type_repository).to receive(:look_for_unique_fields).and_return(unique_fields)
        allow(entry_repository).to receive(:build).with(attributes).and_return(entry)
      end

      context 'public submission disabled' do

        let(:enabled) { false }
        it { is_expected.to eq nil }

      end

      context 'valid' do

        before { expect(entry_repository).to receive(:create) }

        let(:first_validation) { true }
        let(:errors) { {} }

        it { is_expected.to eq entry }
        it { expect(subject.errors.empty?).to eq true }

      end

      context 'not valid' do

        before { expect(entry_repository).not_to receive(:create) }

        it { is_expected.to eq entry }
        it { expect(subject.errors).to eq([:title]) }

        context 'with unique fields' do

          let(:unique_fields) { { title: instance_double('Field', name: 'title') } }

          before do
            allow(entry_repository).to receive(:exists?).with(title: 'Hello world').and_return(true)
            expect(entry.errors).to receive(:add).with(:title, :unique).and_return(true)
          end

          it { is_expected.to eq entry }
          it { expect(subject.errors).to eq([:title]) }

        end

      end

    end

  end

end