MagicPodのWeb APIコールを利用したMailSlurpの自動テストTips

# 概要
メールアカウントをログインIDとして利用するシステムの場合に、テスト用のメールサーバーにMailSlurpを利用することがあるかと思います。プランによって月々利用できるinboxの最大数と受信メール数が定まっており、自動テスト内で利用することで、システムから送信されるメールの受信検証やメール認証についてのテストをしている事例も多く見られるようになりました。
今回紹介する事例は、MagicPodからMailSlurpのAPIを利用した、
1. Expiredの期限設定をしてinbox（MailSlurpにテストの度に新規作成されるメールBox）を整理する。
2. inbox毎にfavouriteやtag設定をして、次回行なうテスト内容に対応できるようにする。
3. 実行したいテストに対応したinbox作成の時期（CreatedAT）とfavouriteやtagでinboxを抽出する。
についての紹介です。
MagicPodには、日時計算を行なうテストステップとWeb APIコールを行なうテストステップが用意されていますので、これを使います。<br>![Qiita005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/eebc10b5-c185-5a0c-0238-0908ed54f709.png)
MailSlurpのAPIを使って設定を行なったり、返信をJSON形式のデータで受取ったりする場合のWeb APIコールの使い方も、本記事で扱っています。紹介した事例以外でも、様々な応用があろうかと思います。
尚、MagicPodの[ヘルプセンター](https://support.magic-pod.com/hc/ja/articles/4408910398617-Email%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88)にも、MailSlurpを利用した自動テストについての記事がありますので、併せて参考になさって下さい。

# 紹介する事例
* 有効期限が過ぎたら、無効なアカウントになっているかの検証をしたい。
* アカウント作成テストと、既存アカウント利用テストとで、アカウントを分けたい。
* 有効期限を過ぎたアカウントの、再度有効化テストをしたい。

メール認証でよく見かけるのは、期限が設定されていて、その期限を過ぎるとメール認証操作ができなくなって、アカウント作成から再度おこなう必要がある事例です。24時間とか多いように思います。<br>
また、メール認証の期限切れではなく、例えばキャンペーン期間中に作成したアカウントが、キャンペーン期間を過ぎたら、キャンペーン商品の購入などで、再有効化されるかどうかのテストでは、一定の期間を経たユーザーアカウントをテストで使うことが考えられます。<br>
再有効化テストの場合は、Expired設定せずに、tagで何のテストに使うか識別できるようにしておき、自動テストから該当するinboxを抽出してテストで使えるようにしておきます。<br>
このようにテストしたい事項によって、inboxを整理しておく事例の紹介となります。<br>
MailSlurpの[REST APIの資料](https://docs.mailslurp.com/api/#inboxcontroller)と[Swagger UI](https://docs.mailslurp.com/api/)を参考にしながら、自動テストを実装していきます。
それでは、1つずつ見ていきましょう。

# 有効期限切れの検証
MailSlurpのフリープラン以外では、Expiredを自分で設定しないとランダムなアドレスで新規作成されたメールボックスが、どんどん増えます。作成した日付はCreatedATとしてメールアドレス毎に記録されていますので、
![Qiita015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/59b112bb-7c81-b196-9348-30624abf1de5.png)
MailSlurpで用意されているAPIから、GET /inboxes/pagnatedのパラメータとして、before（指定した日付以前に作成された、有効期限を過ぎていると思われるinboxを抽出する）を使います。<br>
最近の仕様変更で、MagicPodの日時計算ステップが秒単位で計算できるようになりましたが、24時間で期限を迎えるような場合は、日または時間単位で十分かもしれません。
![Qiita003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/eff440d2-5f39-ad55-1247-03ad60b444b4.png)
日付書式は、MailSlurpに渡して利用できるような形式にする必要があります。これは、[Swagger UI](https://api.mailslurp.com/swagger-ui/index.html)の資料に実際にパラメータを指定して動作確認できるようなものがありますので、ここを利用します。
MagicPodにも書式指定したプレビューが表示されますので、この表示をSwagger UIで試してみると正解に辿り着きやすいです。
![Qiita004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/4aedd2c1-dcf9-bfaa-a2c8-65f6d94e6511.png)
このSwagger UIには、curlで送るコマンドや送信するHeaderやBodyについても、どんな値を指定すれば良いのか（日付の書式など）が示されるため、参考にしてテストステップの実装を行ないます。
![Qiita018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/2d512074-41a0-8e11-e874-2cbd63ca82f7.png)
-H に続く記述が、どうやらMagicPodのWeb APIコールのヘッダーに必要な記述のようです。
```
'https://api.mailslurp.com/inboxes/paginated?page=0&size=20&sort=ASC&before=2023-05-30T23%3A59%3A59.000Z'
```
APIに渡す変数は、MagicPodのテストステップで記述します。日時計算ステップで変数に格納された値をAPIに渡す変数（図ではgetParam）に記述しています。
![Qiita006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/f8d3b21d-180b-d686-6b7e-8efc77ac5928.png)
${beforeYMDT}という変数で、APIに渡すようにできます。
MagicPodのWeb APIコールの設定では、コマンド送信に必要なAPI Keyの他に、戻り値の書式を指定します。例えば、JSONデータとして以下のような値が取得できた場合、
```
{
  "content": [
    {
      "id": "ここにinboxIDが入ります",
      "emailAddress": "string",
      "createdAt": "2023-06-14T23:15:26.789Z",
      "favourite": true,
      "name": "string",
      "tags": [
        "string"
      ],
      "teamAccess": true,
      "inboxType": "HTTP_INBOX",
      "virtualInbox": true,
      "expiresAt": "string"
    }
  ]
}
```
inboxIDは、jsonResponse["content"][0]["ID"]
メールアドレスは、jsonResponse["content"][0]["emailAddress"]
抽出されたJSONデータの最初のデータなら[0]　です。
![Qiita007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/d87d04fe-a789-98ca-c08b-89fe902ba010.png)
getParamを指定したコマンド送信の戻り値から、inboxIDとメールアドレスをJSONデータから取得してその後の自動テストに用います。このJSONデータの戻り値もSwagger UIで実際に確認できますので、値取得の参考にします。
メール認証を求める着信が、抽出されたinboxIDのメールボックスにあるハズですので、最新のメールから本文と記載されたリンクを拾って、着信から24時間過ぎたメールのリンクをクリックして、無効であることを自動テストします。
![Qiita008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/09f89b83-6728-394d-ca97-f3497abae4bb.png)
最後に着信したメールをinboxから取り出すコマンドを使っても良いし、inbox内のメール数を取得して、1を引いたメールIDで指定するのでも、どちらでも良いかと思います。htmlメールであれば、MailSlurpで用意されたコマンドを利用することも可能ですし、テキストメールならば、MagicPodの正規表現を使って、本文からリンクを取り出すことも可能です。
![Qiita009.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/b930ad22-fcbb-d3ba-3900-aa201597a00f.png)
正規表現は、これでいけました。
```
(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@=+\$&]+)
```
ただ、どうしてもアンパサンドが変換ミス（amp;が付いてしまう）するので、これをブランクに置き換えることもしています。
本文中のリンクに遷移して、「残念でした。期限切れです」になれば、success。
# アカウント作成テストと、既存アカウント利用テストとで、アカウントを分けたい
MailSlurpに作成されるメールアドレスをアカウントの新規作成テストと、既存アカウントの再有効化テストとの両方で使うことになりますが、前者は使い捨て、後者は条件による再利用という違いがありますので、MailSlurpのinboxを整理しておかないと、毎月500アカウントもの新規inboxが増殖を続けた場合、例えばMailSlurpダッシュボードから受信メールの確認をするにしても探す気力も無くなり、普段から整理できるようにしておく意味でもExpired設定とtag付けは必須かと思います。<br>
MailSlurpのダッシュボードでは、Favouriteやtagによるフィルター機能もありますので、自動テストから利用しているMailSlurpではありますが、エラー発生時の1次解析のことも考慮して、inboxが爆増したり、整理できてないような状況にはしておかないことをお薦めします。<br>
アカウント作成テストでは、自動テストの最後にExpired設定をして、時間経過したら自動的に削除されるようにしておきます。ここでもMagicPodの日付計算ステップを利用して、変数Expiredに削除期限を指定します。
![Qiita012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/828723e3-249b-8866-5069-e12a98f02279.png)
上記の例では1ヶ月後に削除する場合です。
MailSlurpのAPIは、inboxID指定のPATCHを使いますが、ヘッダーにキーContent-Typeに、値として、application/json の記載が必要です。
やはり、Swagger UIで動作確認した結果を参考にしています。
![Qiita010.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/afcc0744-4b02-8dfb-4cb5-f56585185df6.png)
ボディにはMagicPodで定義した変数Expiredを記載します。
![Qiita011.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/12dee486-97fa-564f-b41f-a2fe6ff49b28.png)
アカウントの新規作成テストの最後に、このWeb APIコールを入れておけば、指定した時期を過ぎれば自動削除・自動整理されますので、整理の手間が省けます。再利用したいアカウントには、この処理をしておかなければinboxがExpiredになることはありません。
# 有効期限を過ぎたアカウントの、再度有効化テスト
例えば無料体験キャンペーン期間があって、キャンペーン期間が過ぎたら正規購入のような手続きを経ることで、キャンペーン期間中に作成したユーザーが、再びシステムの利用が可能になることを検証したい場合、inbox作成日時（CreatedAT）の他に有効化したかどうかをinbox毎に区別できるようにする必要があります。inboxをfavouriteにして、テストが終わったらfavouriteを解除するとか、tagの内容をテスト前後で変更するなどです。<br>
MailSlurpから、CreatedATの他に、favouriteやtagを使って、テストするアカウントを取り出し、テストが終わったら、そのテストでは呼び出されないようにinboxを変更しておきます。
inboxにどんなtagが付けられたかは、MailSlurp画面のinbox毎に、詳細確認できます。
![Qiita016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/4abc2975-688c-4f61-54c7-968f3715abab.png)
tagに日本語を使う場合、ENCODEしてAPIに渡す必要がある点、注意です。Swagger UIで試してみて、旨くできた場合のcurlコマンドを参照にするといいでしょう。
![Qiita017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/765de3ac-c75b-6ac8-6d60-98a64ad26bfd.png)
前述のgetParamに
```
page=0&size=20&sort=ASC&favourite=true&tag=%E8%B3%BC%E5%85%A5%E3%83%86%E3%82%B9%E3%83%88&before=${beforeYMDT}
```
といった感じです。favourite=trueに続いて、指定したいtagを記載します。結果的に、ある日付以前、且つ、tagで指定したワードがあるinboxのみ抽出することになります。tag使うときの注意点としては、一意に抽出できるようなtagを予め付けておくことです。例えば、<br>
キャンペーン1、キャンペーン2は区別されますが、キャンペーン1とキャンペーン10のtagを付けたinboxは、tag=キャンペーン1とした場合、区別されません。このあたりもSwagger UIを使って、戻り値のJSONデータを確認しながらの実装になります。
![Qiita014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/b87882ab-702b-5af1-bb1f-16f1de436f2e.png)
**テストで、tagにtagDataで指定したワードを仕込んでおく場合は、Web APIコールのボディに上記のようなことを書き込んで更新しておきます。
再有効化テストで使うアカウントが抽出できたら、購入などの自動テストを行ない、キャンペーン期間中に作成されて、一度は無効化されたアカウントが、再有効化ができたかのテストを行ないます。<br>
テストの最後にfavouriteをfalseにしておくとか、tagの内容を書き換えておくなどのテストステップをMagicPodのWeb APIコールで記述しておけば、次回からテスト済みのinboxはテストで使われません。
![Qiita013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/939617/23f787e9-7fc4-7855-e3af-34ff691a14fd.png)
# 総括
メールアドレスをログインIDとして利用している場合のMailSlurpを使った自動テストの事例を紹介しました。MagicPodのテストステップを紹介しましたが、MagicPod以外の自動テスト実行環境でもAPIを利用する手段に違いがあっても、MailSlurpの使い方自体は同様に行えると思います。自動テストで扱うメールアドレスを使ったアカウントを、時間経過やどんなテストで使うのかによって、MailSlurpから抽出できるようにしておくことで、アカウントの状態変化や属性に応じた自動テストができます。このような自動テストを定期的に実行することで、仕様変更や機能追加によって、意図しない機能に影響が及んでしまったというエラーを捕捉することができますので、
- 期限過ぎたのに、期限切れになっていない。
- 再有効化ができない。
といったバグは流出を防げます。発生したらマズいバグは、自動テストで回帰テストできるようにしておくことが大切です。