Skip to content

feat!: Universign 2.0.0 — sign_url/signer_id, lazy load, hardening & 100% coverage#19

Open
ismaelbks wants to merge 17 commits into
masterfrom
feat/v2
Open

feat!: Universign 2.0.0 — sign_url/signer_id, lazy load, hardening & 100% coverage#19
ismaelbks wants to merge 17 commits into
masterfrom
feat/v2

Conversation

@ismaelbks

Copy link
Copy Markdown

Pourquoi

Transaction#url renvoyait un type incohérent — une String après .create, un Array après getTransactionInfo — et les consommateurs devaient extraire l'id du signataire en découpant l'URL à la main (url.split("id=")). Par ailleurs, le constructeur déclenchait systématiquement un appel getTransactionInfo, même juste après .create où l'on a déjà tout → un aller-retour réseau inutile.

Cette PR porte la 2.0.0 : elle corrige ce point, puis nettoie en profondeur la gem (bugs, erreurs, archi), monte la couverture à 100 % et remet à jour outillage/doc/dépendances.

Changements (BREAKING → 2.0.0)

API de transaction

  • Supprime Transaction#url. Ajoute :
    • Transaction#sign_url → l'URL de signature, toujours une String (création ou rechargement).
    • Transaction#signer_id → l'id du signataire, parsé proprement depuis l'URL (?id=…).
  • Chargement paresseux des infos de transaction : getTransactionInfo n'est plus appelé dans le constructeur mais à la première lecture de #data (ou d'un attribut qui en dépend). .create ne fait donc plus d'appel redondant, et sign_url/signer_id sont disponibles sans requête supplémentaire.
  • Transaction#signers est implémenté (renvoyait NotImplementedYet) et expose la progression sous forme de Universign::SignerInfos.

Corrections de bugs

  • Typo TransactionSigner#birtdate=#birthdate=.
  • Signer#first_name/#last_name lisaient des clés que les setters n'écrivaient jamais → corrigé.
  • Document.from_data / Signer.from_data ne sont plus thread-unsafe (fini l'état partagé au niveau classe).

Erreurs & robustesse

  • Tous les raise "string" deviennent des sous-classes typées de Universign::Error (UnknownOption, InvalidSignatureField, SignatureFieldsMustBeAnArray, CheckBoxTextsMustBeAnArray).
  • Safeguard simplifié : code de faute 73020 nommé/documenté, matching par code avant fallback sur la chaîne, suppression du mécanisme de callback inutilisé et du code mort commenté.

Archi & propreté

  • Client : ajout de respond_to_missing? et d'un helper Client.call, suppression du @client stocké en ivar (fuite d'état) et du Transaction#client mort. Toujours un client par appel (thread-safe, pas de pool — inutile pour cette charge).
  • params devient la source de vérité unique pour Document/Signer (fin du double stockage @ivar + params, sauf content/meta_data dont la représentation diffère réellement).
  • SignatureField nettoyé (ordre des kwargs, valeur de retour morte, style des clés).

Outillage, doc & dépendances

  • Suppression du .travis.yml obsolète (Ruby 2.2.2).
  • required_ruby_version >= 3.0 ; frozen_string_literal sur tout lib/.
  • Planchers de dépendances resserrés : activesupport >= 7.0, xmlrpc >= 0.3, bundler >= 2.0.
  • README enrichi (prérequis, reload paresseux, accesseurs, section gestion d'erreurs, guide de migration 1.x → 2.0) et CHANGELOG complété.

Tests & couverture

  • Suppression de VCR/WebMock/dotenv et des cassettes ; le client XML-RPC est stubbé directement, aucun appel réseau.
  • Ajout de SimpleCov (ligne + branche) avec seuil minimum_coverage line: 100, branch: 100.
  • bundle exec rspec60 examples, 0 failures, 100 % de couverture lignes et branches.

Migration côté consommateurs

Remplacer transaction.url (+ split("id=")) par transaction.sign_url / transaction.signer_id, et birtdate: par birthdate:. Voir la section « Upgrading from 1.x to 2.0 » du README. PR Swissroc à suivre (bump ~> 2.0).

ismaelbks and others added 15 commits June 1, 2026 21:13
Transaction#url returned a String after .create but an Array after
getTransactionInfo, and callers had to parse the signer id out of the
URL by hand. Replace it with sign_url (always a String) and signer_id
(parsed from the URL).

Stop fetching the transaction info eagerly in the constructor: it is now
loaded lazily on first access to #data. .create no longer triggers a
redundant getTransactionInfo call, and sign_url/signer_id are available
without any extra request.

BREAKING CHANGE: Transaction#url is removed; use sign_url / signer_id.
The transaction specs replayed recorded HTTP via VCR cassettes. Stub
Universign::Client directly instead, delete the cassettes and the
vcr/webmock/dotenv development dependencies, and use a static dummy
configuration (no network is hit by the suite).
Universign::Document already supports a url param; add a test proving
that a URL document flows through Transaction.create as a url (no base64
content), and note it in the changelog.
- rename TransactionSigner#birtdate= to #birthdate= (typo)
- align Signer#first_name/#last_name readers with the keys written by
  the setters (firstname/lastname), keeping the API-response fallback
- make Signer.from_data and Document.from_data thread-safe by building
  a fresh instance instead of mutating class-level state
- implement Transaction#signers, mapping signerInfos to SignerInfos
- expose Signer#data so SignerInfos accessors resolve

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- replace every raise "string" with typed Universign exceptions
  (UnknownOption, InvalidSignatureField, SignatureFieldsMustBeAnArray,
  CheckBoxTextsMustBeAnArray)
- extract a translate_fault helper: match by fault code first, then fall
  back to fault-string matching
- name the 73020 fault code (SIGNATURE_IN_PROGRESS) and document it
- drop the unused safeguard callback machinery and the dead commented
  code in Service::Document
- freeze AVAILABLE_OPTIONS and DEFAULT_OPTIONS

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- add Client.respond_to_missing? so respond_to?/method work through the
  XML-RPC delegation
- add Client.call convenience and use it in the services, dropping the
  per-instance @client ivar (state leak) — still one client per call
- remove the dead private Transaction#client and unused require/attrs
- Document/Signer readers now derive from params instead of duplicating
  state in instance variables (content and meta_data keep their ivar:
  their stored representation genuinely differs from params)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- remove the obsolete .travis.yml (Ruby 2.2.2 CI, no longer used)
- raise required_ruby_version to >= 3.0
- enable frozen_string_literal across lib/
- README: replace removed Transaction#url with sign_url/signer_id, document
  the new #signers accessor
- CHANGELOG: document the v2 breaking changes

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- reorder kwargs so the required page: comes before the optional name:
- drop the dead @params return value and the unused instance variables
- use a bare signerIndex: symbol key for consistency with the others
- add specs covering coordinates, default signer index, named field and
  the nil-coordinate fallback (the class had no coverage)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- add simplecov as a development dependency
- start it at the top of spec_helper, filtering /spec/ and enabling
  branch coverage

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- cover TransactionSigner setters and signature_field validation
- cover all SignerInfos accessors
- cover Document signature_fields=/check_box_texts= validations and
  document_type
- cover Transaction initiator/created_at/description/each_field and the
  nil signer_id path
- cover Client delegation, unknown-method and respond_to? branches
- cover Error.match_class and DocumentURLInvalid#to_s
- cover the UnknownOption raise in Transaction.create
- enforce minimum_coverage line: 100, branch: 100

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- activesupport '>= 4.1' -> '>= 7.0' (4.x/5.x do not run on Ruby 3+)
- pin a floor for xmlrpc ('>= 0.3')
- bump the bundler dev dependency floor to '>= 2.0'

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- fix grammar in the intro and add a Requirements section
- document the lazy reload and the status/signers/documents accessors
- add an Error handling section listing the typed exceptions
- add an Upgrading from 1.x to 2.0 section
- fix the Development instructions (bundle exec rspec / rake spec) and
  mention the enforced coverage

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
attr_accessor :phone_number generated a writer immediately overridden by
the custom phone_number= setter. Use attr_reader so only the custom
writer (which fills params[:phoneNum]) remains.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- run rubocop (capsens config: standardrb + capsens) autocorrect on the
  whole repository
- mostly double-quoted strings, hash alignment, block delimiters and
  trailing commas
- manually reflow the status / identification_type doc tables that
  exceeded the line length

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ismaelbks and others added 2 commits June 3, 2026 08:28
Universign now returns the signing URL with the signer id in the fragment
("https://app.universign.com/sig/#/?id=...") instead of the query string.
URI#query was nil for these URLs, so Transaction#signer_id returned nil and
callers could not identify the signer. Read the id from the query or the
fragment so both legacy and app.universign.com URLs are supported.
fix: parse signer_id from sign URL fragment
@ismaelbks ismaelbks requested a review from AntoineBecquet June 3, 2026 08:54
@ismaelbks ismaelbks self-assigned this Jun 3, 2026
@ismaelbks

Copy link
Copy Markdown
Author

@claude-review

@ismaelbks

ismaelbks commented Jun 3, 2026

Copy link
Copy Markdown
Author

Je m'occuperai de faire la release si ca te va
PS : Je suis parti sur une majeure car elle est breaking

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants