Git Product home page Git Product logo

Comments (5)

timwis avatar timwis commented on May 25, 2024 1

Okay, thanks @javierjulio. I struggled to work out how the callback implementation works, so I'm not sure I'll be able to provide a fix either. I'll look for an alternative implementation as you suggest.

from activeadmin.

javierjulio avatar javierjulio commented on May 25, 2024

@timwis thank you. Can you please use our bug report template script instead? You should be able to replicate it using that. Sorry, I don't use this callback feature so I'm not familiar with it or what could be wrong if anything.

from activeadmin.

timwis avatar timwis commented on May 25, 2024

Sure @javierjulio, see below. I've just made after_save raise (after_save shouldn't be called in the two test cases, as the data is invalid). There's probably a cleaner assertion I could use, but it's late and that's all I could think of! Hope that's okay. For context, my real world use case is hitting a third party forums API when my users resource is created/updated, to update the display name and permissions. I don't want to do it in the model callbacks because then it would get fired on my model tests etc.

It looks like the callbacks are defined here, but I'm not familiar enough with metaprogramming to understand where it's going wrong :/

# frozen_string_literal: true
require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  # Use `ACTIVE_ADMIN_PATH=. ruby tasks/bug_report_template.rb` to run
  # locally, otherwise run against the default branch.
  if ENV["ACTIVE_ADMIN_PATH"]
    gem "activeadmin", path: ENV["ACTIVE_ADMIN_PATH"], require: false
  else
    gem "activeadmin", github: "activeadmin/activeadmin", require: false
  end

  # Change Rails version if necessary.
  gem "rails", "~> 7.0.0"

  gem "sprockets", "~> 4.0"
  gem "importmap-rails", "~> 2.0"
  gem "sqlite3", platform: :mri

  # Fixes an issue on CI with default gems when using inline bundle with default
  # gems that are already activated
  # Ref: rubygems/rubygems#6386
  if ENV["CI"]
    require "net/protocol"
    require "timeout"

    gem "net-protocol", Net::Protocol::VERSION
    gem "timeout", Timeout::VERSION
  end
end

require "active_record"

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :active_admin_comments, force: true do |_t|
  end

  create_table :posts, force: true do |t|
    t.string :title
    t.string :slug
    t.text :body
    t.boolean :published
    t.integer :update_count, default: 0
  end

  add_index :posts, :slug, unique: true
end

require "action_controller/railtie"
require "action_view/railtie"
require "active_admin"

class TestApp < Rails::Application
  config.root = __dir__
  config.hosts << ".example.com"
  config.session_store :cookie_store, key: "cookie_store_key"
  config.secret_key_base = "secret_key_base"

  config.logger = Logger.new($stdout)
  Rails.logger = config.logger
end

class ApplicationController < ActionController::Base
  include Rails.application.routes.url_helpers
end

class ApplicationRecord < ActiveRecord::Base
  primary_abstract_class

  def self.ransackable_attributes(auth_object = nil)
    authorizable_ransackable_attributes
  end

  def self.ransackable_associations(auth_object = nil)
    authorizable_ransackable_associations
  end
end

class Post < ApplicationRecord
  validates :title, presence: true
  validates :slug, uniqueness: true
end

ActiveAdmin.setup do |config|
  # Authentication disabled by default. Override if necessary.
  config.authentication_method = false
  config.current_user_method = false
end

Rails.application.initialize!

ActiveAdmin.register_page "Dashboard" do
  menu priority: 1, label: proc { I18n.t("active_admin.dashboard") }
  content do
    "Test Me"
  end
end

ActiveAdmin.register Post do
  permit_params :title, :slug, :body, :published

  after_save do |post|
    # real world use case: e.g. hit external API
    raise "after_save called"
  end
end

Rails.application.routes.draw do
  ActiveAdmin.routes(self)
end

require "minitest/autorun"
require "rack/test"
require "rails/test_help"

# Replace this with the code necessary to make your test fail.
class BugTest < ActionDispatch::IntegrationTest
  def test_create_when_required_attribute_is_empty
    assert_difference("Post.count", 0) do
      invalid_params = { title: "", slug: "test", body: "test body", published: false }
      post admin_posts_url, params: { post: invalid_params } # happens when editing existing posts too
    end
    # minitest has no refute_raises assertion, but the raise will fail the test anyway
  end

  def test_create_when_unique_constraint_violated
    Post.create!(title: "test", slug: "test", body: "test", published: false)

    assert_difference("Post.count", 0) do
      invalid_params = { title: "another test", slug: "test", body: "test", published: false }
      post admin_posts_url, params: { post: invalid_params }
    end
    # minitest has no refute_raises assertion, but the raise will fail the test anyway
  end

  private

  def app
    Rails.application
  end
end

from activeadmin.

javierjulio avatar javierjulio commented on May 25, 2024

Thanks @timwis. To be upfront, I would welcome a fix, I just wouldn't expect to come from us so this is unlikely to be resolved. I'm not familiar with our callbacks implementation. It seems to be a roll-your-own setup so I don't know how this works for Rails and whether it behaves the same or not. I would suggest finding an alternative. You could just override the update action for an admin resource and queue the third party call there if you don't want it in a model callback.

from activeadmin.

javierjulio avatar javierjulio commented on May 25, 2024

For anyone else coming here, please refer to the earlier comment: #8244 (comment)

from activeadmin.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.