-
Notifications
You must be signed in to change notification settings - Fork 4
Add a metadata field, with feature and unit tests
If your continuing immediately from a previous exercise and the application is already running at http://localhost:3000, you're good to go; otherwise, restart the services that run your application:
Open two separate terminal windows or tabs: in the first, start Fedora, Solr, and your Rails server. In the second, open a Bash prompt to your rails server. See Common (Docker) Tasks for detailed instructions. When you're using Docker, all the commands below should be entered at the root@...#
prompt in the Bash window instead of your local $
prompt.
If you're not running Docker, open three separate terminal windows. In the first, launch your development servers using rails hydra:server
; in the second, launch your test servers using rails hydra:test_server
, use the final window to execute the commands below from the $
prompt.
If you have changes in your current branch -- you can check on this via
git status
-- you'll want to save those before starting this lesson (which uses a separate branch):
git checkout -b work_in_progress
git add .
git commit -m 'checkpoint before beginning first metadata lesson'
git checkout ci_setup
NOTE: If you make experimental changes and want to get back to the minimal code state necessary to run this lesson, you reset your git working tree by running:
git reset --hard origin/ci_setup
- In your main terminal session, run your test suite
rspec
- You can run a single test like this
rspec spec/models/image_spec.rb:6
-
The Hyrax work generator creates a default feature test for each work type you create. As part of the setup for this tutorial, we already ran the generator to create an Image work type (see Building from Scratch#Steps step 9). This feature test can be found in
spec/features/create_image_spec.rb
. We've copied the most relevant part below:scenario do visit '/dashboard' click_link "Works" click_link "Add new work" # If you generate more than one work uncomment these lines # choose "payload_concern", option: "Image" # click_button "Create work" expect(page).to have_content "Add New Image" click_link "Files" # switch tab expect(page).to have_content "Add files" expect(page).to have_content "Add folder" within('span#addfiles') do attach_file("files[]", "#{Hyrax::Engine.root}/spec/fixtures/image.jp2", visible: false) attach_file("files[]", "#{Hyrax::Engine.root}/spec/fixtures/jp2_fits.xml", visible: false) end click_link "Descriptions" # switch tab fill_in('Title', with: 'My Test Work') fill_in('Creator', with: 'Doe, Jane') fill_in('Keyword', with: 'testing') select('In Copyright', from: 'Rights statement') # With selenium and the chrome driver, focus remains on the # select box. Click outside the box so the next line can't find # its element find('body').click choose('image_visibility_open') expect(page).to have_content('Please note, making something visible to the world (i.e. marking this as Public) may be viewed as publishing which could impact your ability to') check('agreement') click_on('Save') expect(page).to have_content('My Test Work') expect(page).to have_content "Your files are being processed by Hyrax in the background." end
-
This feature test interacts with the browser. Try to complete each step of the feature test manually in your browser. Do you think this test should pass?
-
Run your test suite:
rspec spec
OR Run your feature test all by itself:
rspec spec/features/create_image_spec.rb
An Image, in addition to title, creator, keyword, and the metadata fields that are common to all Hyrax objects, also has some Image specific metadata we'd like to track. For our image, we want to save the year, size (original physical dimensions), and latitude and longitude if they are available. Because Fedora 4 stores content as linked data, we need both the name of the field we want to add, and the linked data predicate we want to use to store it. In this example, we're going to add:
- year: http://www.europeana.eu/schemas/edm/year (RDF::Vocab::EDM.year)
- We'll start by adding a test that describes how we expect the new field for year to work. Use your favorite text editor to open
spec/features/create_image_spec.rb
and add these lines after the copyright selection (~line 54):
click_link("Additional fields")
fill_in "Year", with: "2005"
- Run your test suite again using
rspec
. It will fail with the error:
$ rspec spec/features/create_image_spec.rb
. . .
Failure/Error: fill_in 'Year', with: '2005'
Capybara::ElementNotFound
Unable to find visible field "Year" that is not disabled
Recall that Rails uses the MVC (model/view/controller) pattern. In order to add a field to our object, we first need to add it to the Image 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_image_spec
feature is testing whether:
- we can create a user and log in
- a logged in user can access the new Image url
- the expected fields are present on that page
- a file can be attached
- an Image can be submitted without error given a set of metadata and a file
- a new page will be displayed saying the Image has been submitted
- 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 Image model has a year field.
- Open
spec/models/image_spec.rb
. Notice that this is a stub test that was auto-generated when we created our Image work type. Replace lines 6 - 8 (theit "has tests" do
bits inside theRSpec.describe
block) with this:
describe "#year" do
context "with a new Image" do
it "has no year value when it is first created" do
image = Image.new
expect(image.year).to be_empty
end
end
context "with an Image that has a year defined" do
it "can set and retrieve a year value" do
image = Image.new
image.year = ["2005"]
expect(image.year).to eq(["2005"])
end
end
end
-
Run your Image spec again (
rspec spec/models/image_spec.rb
) . Now you have three failing tests! Our unit tests are failing with an error something likeNoMethodError: undefined method 'year'
-
Edit
app/models/image.rb
and add this line at the bottom of the class block, but before the line that saysinclude ::Hyrax::BasicMetadata
:
property :year, predicate: "http://www.europeana.eu/schemas/edm/year"
- Run your Image spec again (
rspec spec/models/image_spec.rb
). Now your unit test should pass. However, your feature test (rspec spec/features/create_image_spec.rb
) is still failing.
At this point, our Image model has the field we want to add but that field isn't being shown on our new Image form.
- As before, we will add our test first. Edit
spec/forms/hyrax/image_form_spec.rb
and replace the parts inside theRspec.describe
block with:
subject { form }
let(:image) { Image.new }
let(:ability) { Ability.new(nil) }
let(:request) { nil }
let(:form) { described_class.new(image, ability, request) }
it "has the expected terms" do
expect(form.terms).to include(:title)
expect(form.terms).to include(:year)
end
- Run your test suite and notice that the image_form_spec is now failing:
Failure/Error: expect(form.terms).to include(:year)
- Edit
app/forms/hyrax/image_form.rb
and add this line:
self.terms += [:year]
- Run your test suite again (
rspec spec
) and all your tests, including your feature test, should now pass.
Add an additional metadata field to the form. Be sure to include feature and unit tests. Here's some typical fields we see folks adding to their model:
- extent: http://purl.org/dc/terms/extent (RDF::Vocab::DC.extent)
- latitude: http://www.w3.org/2003/12/exif/ns#gpsLatitude (RDF::Vocab::EXIF.gpsLatitude)
- longitude: http://www.w3.org/2003/12/exif/ns#gpsLongitude (RDF::Vocab::EXIF.gpsLongitude)
For discussion:
-
Why do we have feature tests and unit tests?
-
How are the model test and the form test different? How are they the same?
-
What is Capybara?
-
This lesson represents a realistic use case. Let's look at a related ticket in our issue tracker.
-
What makes a good ticket?
-
How do metadata decisions get made?
-
How do you track them? See, e.g., this spreadsheet from the Metadata Interest Working Group
To see the changes made during this lesson, go to ../compare/ci_setup...add_new_metadata_field_1