Rendering certificates
Moving on to actually generating some certificates.
We start with a feature test. Create a new file in your features folder, named certificate_generation.feature and add the following scenario:
# features/certificate_generation.feature
Feature: As a course administrator,
In order to be able to issue the right certificates for a course,
I want to display course title, course date and the
participants name on the certificate
Scenario: Generate a certificate
Given the delivery for the course "Basic" is set to "2015-12-01"
And the data file for "2015-12-01" is imported
And I am on 2015-12-01 show page
And I click "Generate certificates" link
Then 3 certificates should be generatedThat will do for now. Run cucumber and see the tests fail.
Add some new step definition in your application_steps.rb
# features/step_definitions/application_steps.rb
And(/^the data file for "([^"]*)" is imported$/) do |date|
steps %q(
And I am on the Course index page
And I click on "#{date}" for the "Basic programming" Course
When I select the "students.csv" file
And I click "Submit" link
)
end
Then(/^([^"]*) certificates should be generated$/) do |count|
pdf_count = Dir['pdf/**/*.pdf'].length
expect(pdf_count).to eq count.to_i
endAlso, add the Generate certificates link to the deliveries/show.erb template:
Okay, running the scenario now will tell us that no certificates have been created:
This is as far as we can go with our feature test at the moment. Let's create a Certificate class and the module for generating pdf's.
From your terminal, run these commands to create your spec and tour class file:
Make sure you require the class file in your controller:
Let's start with adding some specs:
And add the class definition:
Make sure you run your specs after every update.
We also need to update relationship in the Student models. We start by writing specs for that:
Then the implementation
We are going to add a mechanism to generate a unique identifier for each certificate using a callback that will be invoked when the Certificate is created. We also want to make sure that the certificate has access to all the relevant information that we are going to use while creating the pdf.
In the certificate_spec.rb add the following test:
And make the following additions to your Certificate class:
If you run into some errors with the database you need to add the following code to your spec_helper.rb:
Now we need to add a module that will handle the pdf creation for us. We will be using a gem called Prawn. Prawn is a PDF document generator for Ruby.
Let's start by adding it to our Gemfile and install it using bundle install
(Since we'll only be using Prawn in our pdf generation module, we don't need to load it in our controller.)
Create a new file called certificate_generator.rb in your lib folder and add the following code to it:
Modify your Certificate class by adding an after :create callback to it so that we invoke the CertificateGenerator every time an instance of Certificate is created:
Alright, let's shift our attention back to the controller and the feature tests. We left off with the failing step that tested if 3 certificate was being created, remember?
We need to create a route and tell it that we want to generate a certificate for each Student that has a relationship with that Delivery
Before we run our tests again head over to your terminal and create a folder named pdf
Now run your tests with cucumber features/certificate_generation.feature
We will be getting some conflicts in our tests if we keep the generated pdf's in the pdf folder while running our tests. We need to clear that folder after each run. In our database cleaner strategy, let's add a command to purge all files from that directory after each test:
And in our certificate_spec.rb we can add an after action to the describe block that tests the generator:
That pretty much concludes this part. In the next step we will make the certificate look a little better with a custom background, fonts and colors.
Last updated