Sunday, February 26, 2023

Automating testing of signup

The main trick of testing the sign-up process of most sites is to handle the email verification since that requires you testing framework to parse an incoming email amd follow a link to complete it. I solved this by using SES incoming email functionality whixh through SNS passes the email to a Lambda. This Lambda then stores the parsed verification link in a DynamoDB table indexed by the recipient.

I then use the same Lambda set up with a simple function URL to do an HTTP redirect when you do a get to the verification link. That way you can automate your verification easily by just loading the Lamba URL. Below is the entire Lambda function code for receiving the email, storing it in a DynamoDB table called EmailLinks and also implements a HTTP responder where you call it with link {functionUrl}?email={email to confirmation to redirect to}.

const AWS = require('aws-sdk')
const findLinkRE = /(whatever you need to find the confirmation link from your email in the first match group)/;
const dbClient = new AWS.DynamoDB.DocumentClient();

exports.handler = async (event) => {
    console.log(event);
    if (event.Records) {
        for (let i = 0; i < event.Records.length; i++) {
            const message = JSON.parse(event.Records[i].Sns.Message);
            
            const content = message.content;
            const match = findLinkRE.exec(content)
            if (match) {
                for (let j = 0; j < message.mail.destination.length; j++) {
                    console.log(`Set ${message.mail.destination[j]}: ${match[1]}`);
                    await new Promise(function(resolve, reject) {
                        dbClient.put({
                            TableName: "EmailLinks",
                            Item: {
                                "Email": message.mail.destination[j],
                                "Link": match[1]
                            }
                        }, function(err, data) {
                            if (err) reject(err); else resolve(data);
                        });
                    });
                }
            }
        }
    } else if (event.rawQueryString.startsWith("email=")) {
        const item = await new Promise(function(resolve, reject) {
            dbClient.get({
                TableName: "EmailLinks",
                Key: { "Email": decodeURIComponent(event.rawQueryString.substring(6)) }
            }, function(err, data) {
                if (err) reject(err); else resolve(data);
            });
        });
        if (item && item.Item) {
            const response = {
                statusCode: 301,
                headers: { "location": item.Item.Link, "Content-Type": "text/html" },
                body: JSON.stringify(item.Item),
            };
            return response;
        } else {
            return {
                statusCode: 404,
                headers: { "Content-Type": "text/html" },
                body: "Not found"
            };
        }
    } else {
        return {
            statusCode: 400,
            headers: { "Content-Type": "text/html" },
            body: "Bad request"
        };
    }
};

0 comments:

Post a Comment