medusa-project / book-tracker

Medusa Book Tracker
0 stars 0 forks source link

Add controller tests #17

Closed adolski closed 11 months ago

adolski commented 1 year ago

@gaurijo In some of the tests, particularly of TasksController, you'll have to "log in" from the tests. Let me know when you get to that and I'll help.

gaurijo commented 1 year ago

@adolski I forgot to ask earlier - do you want me to commit changes for controller tests to the same PR i have open, or do you prefer I start a new branch and new PR for these?

adolski commented 1 year ago

@gaurijo A new PR would be best.

gaurijo commented 1 year ago

@adolski Okay, will do. I committed some setup related changes to my previous branch but will use a new one moving forward

adolski commented 1 year ago

Logging in from the tests

Normally, when a user clicks a login link, they are redirected to the campus Shibboleth identity provider (IdP). They enter their NetID and password into the form and then upon successful authentication, they are ultimately redirected to the application's /auth/shibboleth/callback route (handled by SessionsController.create()). The request includes an "auth hash" containing various information like the user's email, name, and whatever other attributes that we asked the IdP to release when we registered the app with it.

In the test environment, we don't have access to an IdP. So we define a method in the ActiveSupport::TestCase class (in test/test_helper.rb) that simulates a login by sending a request to the /auth/shibboleth/callback route as if a user had just successfully logged in:

##
# @param user [User]
#
def log_in_as(user)
  post "/auth/shibboleth/callback", env: {
    "omniauth.auth": {
      provider:          "shibboleth",
      "Shib-Session-ID": SecureRandom.hex,
      uid:               user.email,
      info: {
        email: user.email
      },
      extra: {
        raw_info: {
        }
      }
    }
  }
end

(A real request would contain more info than that in the info and extra.raw_info keys. But this is enough to make it work in testing.)

Now, from any test, we can do something like:

test "this is a test of something" do
  user = users(:somebody)
  log_in_as(user)
  ...
end

Once you log in, you will remain logged in even across tests, so you should remember to log out. Here is the logout counterpart to log_in_as() which can be used the same way:

def log_out
  delete logout_path
end
gaurijo commented 1 year ago

I have the auth hash set up in the ActiveSupport::TestCase, but I'm not quite understanding how it gets called on in a test.

For example with Books I have fixture data to call on in test cases. Once this auth hash is setup, where does a user get called from if I have user = users(:example) in my test, since there isn't a users table?

adolski commented 1 year ago

Oops, I forgot that the Book Tracker doesn't have a User model!

It doesn't need one because it doesn't track any actions related to users, and it considers anyone who is a member of the "Library Medusa Admins" AD group to be authorized.

So, you could modify the log_in_as(user) method to just log_in, and replace user.email with some fake email.