Add a metadata field, with feature and unit tests - RepoCamp/connect2017 GitHub Wiki

Goals

Write a feature spec for adding an ETD

  1. Add these lines to spec/features/create_etd_spec.rb, after the last expect statement:
      visit '/concern/etds/new'
      fill_in 'Title', with: 'Journey to Skull Island'
      fill_in 'Creator', with: 'Quest, Jane'
      fill_in 'Keyword', with: 'Adventure'
      select('In Copyright', from: 'Rights statement')
      choose('open')
      check('agreement')
      click_on('Files')
      within('#addfiles') do
        attach_file('files[]', "#{fixture_path}/fake_text1.pdf")
      end
      click_on('Save')
      expect(page).to have_content 'Your files are being processed'
      expect(page).to have_content 'Journey to Skull Island'
      expect(page).to have_content 'Quest, Jane'
      expect(page).to have_content 'Adventure'
    
  2. Make a directory called spec/fixtures and add the fake_text1.pdf file to it.
  3. Run your test suite again, and it should pass this time:
     rspec spec/features/create_etd_spec.rb    
    
  4. The test should pass. We just wrote a test for the behavior we already observed in our development environment.

Note: you can see the outcome of this section on github.

For discussion:

  • Let's read through the feature spec together. What is it doing?
  • Compare this with entering the same information manually into our local development environment.
  • What is a fixture object?

Add a metadata field

An ETD, in addition to title, creator, keyword, and the metadata fields that are common to all Hyrax objects, also has some special ETD metadata. For a thesis or dissertation, we need to know the degree, department, and school associated with this document. Because Fedora 4 stores content as linked data, we need to know not only the name of the field we want to add, but also the linked data predicate we should use. In this example, we're going to add:

For discussion:

Add a new metadata field to our feature spec

  1. Add these lines to spec/features/create_etd_spec.rb, after the "Rights statement" line:
click_link("Additional fields")
fill_in "Degree", with: "Bachelor of Arts with Honors"
  1. Run your test suite again. It will fail with the error:
Capybara::ElementNotFound
Unable to find visible field "Degree" that is not disabled

Add a new metadata field to our model

Recall that rails uses the "mvc" or "model view controller" pattern. In order to add a field to our ETD object, we first need to add it to the ETD model.

So far we've only been writing feature specs, also sometimes called integration tests. These are a kind of automated test that exercises many parts of the application at once. For example, our create_etd_spec feature is testing whether:

  1. we can create a user and log in
  2. a logged in user can access the new ETD url
  3. the expected fields are present on that page
  4. a file can be attached
  5. an ETD can be submitted without error given a set up metadata and a file
  6. a new page will be displayed saying the ETD has been submitted
  7. that new page will contain the expected metadata

In contrast, we are now going to write a unit test, which will only test one thing: Whether the ETD model has a degree field.

  1. Open spec/models/etd_spec.rb. Notice that this is a stub test that was auto-generated when we created our ETD work type. Replace lines 6 - 8 (the bits inside the RSpec.describe block) with this:
  describe "#degree" do
    context "with a new ETD" do
      it "has no degree value when it is first created" do
        etd = Etd.new
        expect(etd.degree).to be_empty
      end
    end

    context "with an ETD that has a degree defined" do
      it "can set and retrieve a degree value" do
        etd = Etd.new
        etd.degree = ["Bachelor of Arts with Honors"]
        expect(etd.degree).to eq(["Bachelor of Arts with Honors"])
      end
    end
  end
  1. Run your test suite again. Now you have two failing tests! Our unit test is failing with an error something like method_missing: undefined method 'degree'
  2. Edit app/models/etd.rb and add this line at the bottom of the class block, but before the line that says include ::Hyrax::BasicMetadata:
property :degree, predicate: "http://vivoweb.org/ontology/core#AcademicDegree"

  1. Run your test suite again. Now your unit test should pass. However, your feature test is still failing.

For discussion:

  • Why do we have feature tests and unit tests?
  • What is Capybara?
  • Why is the degree String in brackets?

Add a new metadata field to our form

Now our ETD model has the field we want to add, but that field isn't being shown on our new ETD form.

  1. As before, we will add our test first. Edit spec/forms/hyrax/etd_form_spec.rb and replace the parts inside the Rspec.describe block with:
  subject { form }
  let(:etd)     { Etd.new }
  let(:ability) { Ability.new(nil) }
  let(:request) { nil }
  let(:form)    { described_class.new(etd, ability, request) }
  it "has the expected terms" do
    expect(form.terms).to include(:title)
    expect(form.terms).to include(:degree)
  end
  1. Run your test suite and notice that the etd_form_spec is now failing:
Failure/Error: expect(form.terms).to include(:degree)
  1. Edit app/forms/hyrax/etd_form.rb and add this line:
self.terms += [:degree]
  1. Run your test suite again (bundle exec rake ci) and all your tests, including your feature test, should now pass.

For discussion:

  • How are the model test and the form test different? How are they the same?

Note: You can see all the changes made during this exercise on the github repo.

Pair exercise

We added one metadata field here: degree. Choose either department or school and add a second metadata field. Or, define your own metadata field, as long as you pick something that can be a simple string.

Next: Add metadata to views & Solr

HOME