README.adoc
= RSpec::PGPMatchers
ifdef::env-yard[:relfileprefix: file.]
image:https://img.shields.io/gem/v/rspec-pgp_matchers.svg[
Gem Version, link="https://rubygems.org/gems/rspec-pgp_matchers"]
image:https://img.shields.io/travis/riboseinc/rspec-pgp_matchers/master.svg[
Build Status, link="https://travis-ci.org/riboseinc/rspec-pgp_matchers/branches"]
image:https://img.shields.io/codecov/c/github/riboseinc/rspec-pgp_matchers.svg[
Test Coverage, link="https://codecov.io/gh/riboseinc/rspec-pgp_matchers"]
image:https://img.shields.io/codeclimate/maintainability/riboseinc/rspec-pgp_matchers.svg[
"Code Climate", link="https://codeclimate.com/github/riboseinc/rspec-pgp_matchers"]
RSpec matchers for testing PGP-encrypted messages, and signatures.
CAUTION: This gem is not meant to bridge GnuPG executables to production
environments. Use it in developments and tests only.
IMPORTANT: This gem calls GnuPG executables internally. However, it does not
rely on machine-readable interface yet, and may easily break when they change
something in GnuPG's human-readable output. As long as it is not resolved in
a better way, we are going to maintain compatibility with the most recent
versions of GnuPG. At the moment of writing this statement, it is GnuPG 2.2.9.
TIP: In order to check which GnuPG version this gem was tested against,
check out builds in Travis. One of the build steps in a "before script" phase
executes `gpg --version` to make things clear.
== Usage
=== Getting started
1. Make sure that you have GnuPG 2.2 installed.
2. Add this line to your application’s Gemfile:
+
[source,ruby]
----
gem "rspec-pgp_matchers", github: "riboseinc/rspec-pgp_matchers", require: false, group: :test
----
3. And following to your spec helper:
+
[source,ruby]
----
require "rspec/pgp_matchers"
RSpec::PGPMatchers.homedir = "path/to/pgp_home_directory/with/development/keys"
----
=== Matching signatures
[source,ruby]
----
text = "Some text"
signer_uid = "mail@example.com"
someones_uid = "someone@example.com"
# Not defined in this gem, but required for this example
signature = sign_text(text: text, signer: signer_uid, ascii_armor: true)
# Both following do pass
expect(signature).to be_a_valid_pgp_signature_of(text)
expect(signature).to be_a_valid_pgp_signature_of(text).signed_by(signer_uid)
# This one fails
expect(signature).to be_a_valid_pgp_signature_of(text).signed_by(someones_uid)
----
=== Matching encrypted messages
[source,ruby]
----
text = "Some text"
recipient1_uid = "mail1@example.com"
recipient2_uid = "mail2@example.com"
someones_uid = "someone@example.com"
# Not defined in this gem, but required for this example
encrypted = encrypt_text(
text: text,
recipients: [recipient1_uid, recipient2_uid],
ascii_armor: true
)
# Following do pass
expect(encrypted).to be_a_pgp_encrypted_message
expect(encrypted).to be_a_pgp_encrypted_message.containing(text)
expect(encrypted).to be_a_pgp_encrypted_message.encrypted_for(recipient1_uid, recipient2_uid)
# This one fails
expect(encrypted).to be_a_pgp_encrypted_message.encrypted_for(someones_uid)
----
=== Running arbitrary GnuPG commands
An `RSpec::PGPMatchers::GPGRunner` module can be used to run arbitrary GnuPG
commands:
[source,ruby]
----
RSpec::PGPMatchers::GPGRunner.run_command("--decrypt PATH_TO_FILE")
RSpec::PGPMatchers::GPGRunner.run_command("--list-keys")
----
Also, convenient helpers are defined for two common commands:
[source,ruby]
----
RSpec::PGPMatchers::GPGRunner.run_decrypt("encrypted_string")
RSpec::PGPMatchers::GPGRunner.run_verify("cleartext", "signature_string")
----
In all above cases, a triple consisting of captured standard output, captured
standard error, and `Process::Status` instance is returned.
=== Working with passphrase-protected keys
Consider using unprotected keys in your tests. It will save you a lot of
hassle. However, passphrase-protected keys are also supported. See
`<<PROTECTED_KEYS.adoc#,PROTECTED_KEYS.adoc>>` for details.
=== Unusual GnuPG executable name
By default, this gem assumes that GnuPG executable is named `gpg`, and that
it is in `$PATH`. This behaviour can be changed, for example:
[source,ruby]
----
RSpec::PGPMatchers.gpg_executable = "gpg2" # different executable name
RSpec::PGPMatchers.gpg_executable = "/opt/gpg/bin/gpg" # absolute path
RSpec::PGPMatchers.gpg_executable = "../gpg/bin/gpg" # relative path
----
Avoid hardcoding values. Usually, setting a proper `$PATH` environment variable
is better than assigning an absolute path to `gpg_executable` attribute.
== Development
After checking out the repo, run `bin/setup` to install dependencies.
Then, run `rake spec` to run the tests. You can also run `bin/console`
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run
`bundle exec rake install`. To release a new version, update the version
number in `version.rb`, and then run `bundle exec rake release`, which
will create a git tag for the version, push git commits and tags, and
push the `.gem` file to https://rubygems.org[rubygems.org].
=== Submodules
GnuPG is installed via scripts maintained in a sister repository
https://github.com/riboseinc/gpg-build-scripts[riboseinc/gpg-build-scripts],
and included here as a Git submodule. Learn more about submodules from
https://blog.github.com/2016-02-01-working-with-submodules/[The GitHub Blog].
== Contributing
Bug reports and pull requests are welcome on GitHub at
https://github.com/riboseinc/rspec-pgp_matchers.
== Credits
This gem is developed, maintained and funded by
https://www.ribose.com[Ribose Inc].
== License
The gem is available as open source under the terms of the
https://opensource.org/licenses/MIT[MIT License].