0

I'm making some unit testing with rspec to Active Campaign and on the response I encounter this error:

Failures:

  1) Create Token for Active Campaign updates a contact
     Failure/Error: expect(response_body).to eq(200)
     
       expected: 200
            got: "\"{\\\"error\\\":{\\\"reason\\\":\\\"Invalid Record\\\",\\\"message\\\":{\\\"user\\\":[\\\"must exist\\\"]}},\\\"meta\\\":{\\\"message\\\":\\\"Invalid Record\\\",\\\"type\\\":\\\"error\\\",\\\"code\\\":422,\\\
     
       (compared using ==)

This is my spec:

require 'rails_helper'

RSpec.describe 'Create Token for Active Campaign', type: :request do
  let(:user) { create(:user) }
  let(:create_active_params) do
    {
      contact: {
        id: '100',
        email: 'john@sample.com',
        app_user_id: 12,
        first_name: 'john',
        last_name: 'Doe',
        tags: 'form-step-1'
      }
    }
  end

  it 'updates a contact' do
    VCR.use_cassette('update_contact') do
      post '/api/v1/active_campaign_contacts', params: create_active_params.to_json, headers: { 'Content-Type' => 'application/json' }
      response_body = JSON.dump(response.body)
      expect(response_body).to eq(200)
    end
  end
end

This is my controller I am testing: (which works perfectly fine without rspec)

class API::V1::ActiveCampaignContactsController < API::V1::ApiController
  BASE_URL = Rails.application.credentials.dig(:active_campaign, :url)
  private_constant :BASE_URL
  API_KEY = Rails.application.credentials.dig(:active_campaign, :key)
  private_constant :API_KEY

  def create
    update_contact
  end

  def update_contact
    contact = create_token
    url = URI("#{BASE_URL}/api/3/contacts/#{contact.active_campaign_id}")
    http = Net::HTTP.new(url.host, url.port)
    http.use_ssl = true

    request = Net::HTTP::Put.new(url)
    request['Accept'] = 'application/json'
    request['Content-Type'] = 'application/json'
    request['api-token'] = API_KEY
    data = { contact: { fieldValues: [{ field: '1', value: token.email_token }] } }
    request.body = JSON.dump(data)
    response = http.request(request)
    response.code == '200' ? render(json: { success: true }) : render(json: { success: false })
  end

  def create_token
    Token.create_with(
      email_token: SecureRandom.urlsafe_base64(12),
      active_campaign_id: params.dig(:contact, :id)&.to_i
    ).find_or_create_by!(
      user_id: params.dig(:contact, :app_user_id)&.to_i
    )
  end
end

The controller above works perfectly fine without running the specs. So I'm really not sure what could be failing.

In details, my model Tokens has a t.references :user so whenever I save a Tokenit looks for a user_id

My Tokensmodel:

class Token < ApplicationRecord
  belongs_to :user
end

And this is what is being saved or the actual columns when a token is saved:

[#<Token:0x00007f9cdce64080
  id: 16,
  email_token: "K287IeBkuA9fdjAr",
  active_campaign_id: 100,
  user_id: 12,
  created_at: Thu, 23 Jun 2022 19:12:28.119304000 UTC +00:00,
  updated_at: Thu, 23 Jun 2022 19:12:28.119304000 UTC +00:00>]

So, it does not nag for a user, but somehow my spec does.

What could I be missing here?

theKid
  • 522
  • 6
  • 19
  • 2
    A user with id 12 does not exist in your test database. That being said your test is wrong too because `response.body` will never equal 200. – engineersmnky Jun 24 '22 at 00:10
  • Those this means that if I have a user Id of 12 in my spec, that user is has to live on my db? I thought those were generated by the factory or something. – theKid Jun 24 '22 at 01:30
  • 3
    Change `app_user_id: 12` to `app_user_id: user.id`. This will use your initial `let` that creates a user – engineersmnky Jun 24 '22 at 01:32

0 Answers0