Merge branch 'main' of ssh://gitea.apps.sustainabledelivery.com:3022/QTIL/basic_signup_allowlist

This commit is contained in:
Willem van den Ende 2025-09-16 15:40:04 +01:00
commit 73d41c0c9a
13 changed files with 327 additions and 152 deletions

4
.mise.toml Normal file
View File

@ -0,0 +1,4 @@
[tools]
elixir = "1.18.3-otp-27"
erlang = "27"
node = "24"

33
CLAUDE.md Normal file
View File

@ -0,0 +1,33 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
- `mix compile` - Compile source files
- `mix test` - Run all tests
- `mix test test/path/to/test.exs` - Run a specific test file
- `mix test test/path/to/test.exs:LINE` - Run a specific test at a line number
- `mix deps.get` - Install dependencies
- `mix clean` - Clean build artifacts
## Architecture
This is an Elixir library that provides email allowlist functionality for restricting account creation. The library consists of two main modules:
1. **BasicSignupAllowlist** (lib/basic_signup_allowlist.ex) - Public API module that reads the `SIGNUP_ALLOWLIST_EMAILS` environment variable and delegates to the functional core
2. **FunCore.BasicSignupAllowlist** (lib/fun_core/basic_signup_allowlist.ex) - Pure functional core that handles the allowlist logic without side effects
The architecture follows a functional core/imperative shell pattern where:
- The functional core contains pure functions for email normalization and allowlist checking
- The outer module handles environment variable reading and provides the public interface
## Environment Variables
- `SIGNUP_ALLOWLIST_EMAILS` - Comma-separated list of allowed email addresses, or "*" to allow all emails
## Project Configuration
- Elixir version: ~> 1.18 (managed via mise)
- No external dependencies currently
- Test framework: ExUnit with async: false for integration tests that modify environment variables

View File

@ -1,21 +1,23 @@
# BasicSignupWhitelist
# BasicSignupAllowlist
**TODO: Add description**
Minimal function to restrict account creation for the first few accounts. Useful for deploying architectural spikes and bootstrapping.
Why? Phx Auth offers easy account creation, but no UI to manage created accounts, allowing spammers to create accounts. When putting demoes live, you don't necessarily want to create elaborate account management and invite systems first.
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `basic_signup_whitelist` to your list of dependencies in `mix.exs`:
by adding `basic_signup_allow` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:basic_signup_whitelist, "~> 0.1.0"}
{:basic_signup_allowlist, "~> 0.1.0"}
]
end
```
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/basic_signup_whitelist>.
be found at <https://hexdocs.pm/basic_signup_allowlist>.

View File

@ -0,0 +1,51 @@
defmodule BasicSignupAllowlist do
import FunCore.BasicSignupAllowlist
@signup_allowlist_emails "SIGNUP_ALLOWLIST_EMAILS"
@moduledoc """
Checks if an email address is allowed based on the SIGNUP_ALLOWLIST_EMAILS env variable.
"""
@doc """
Returns the name of the environment variable used for the signup allowlist.
"""
@spec signup_allowlist_emails() :: String.t()
def signup_allowlist_emails, do: @signup_allowlist_emails
@doc """
Checks if an email address is allowed based on the SIGNUP_ALLOWLIST_EMAILS env variable.
Rules:
- Returns true if ALLOWED_EMAILS == "*" (all emails allowed)
- Returns true if email matches any entry in the comma-separated list
- Returns false if:
* Environment variable doesn't exist
* Environment variable is empty string
* Email not found in allowlist
## Examples
iex> BasicSignupAllowlist.forbid_signup_with_any_email()
iex> BasicSignupAllowlist.signup_allowed?("joe@example.com")
false
iex> BasicSignupAllowlist.allow_signup_with_all_emails()
iex> BasicSignupAllowlist.signup_allowed?("joe@example.com")
true
"""
@spec signup_allowed?(String.t()) :: boolean()
def signup_allowed?(email) do
env_value = System.get_env(@signup_allowlist_emails)
signup_allowed_fun(env_value, email)
end
def allow_signup_with_all_emails() do
System.put_env(signup_allowlist_emails(), "*")
end
def forbid_signup_with_any_email() do
System.delete_env(signup_allowlist_emails())
end
end

View File

@ -1,33 +0,0 @@
defmodule BasicSignupWhitelist do
import FunCore.BasicSignupWhitelist
@moduledoc """
Checks if an email address is allowed based on the SIGNUP_ALLOWED_EMAILS env variable.
"""
@doc """
Checks if an email address is allowed based on the SIGNUP_ALLOWED_EMAILS env variable.
Rules:
- Returns true if ALLOWED_EMAILS == "*" (all emails allowed)
- Returns true if email matches any entry in the comma-separated list
- Returns false if:
* Environment variable doesn't exist
* Environment variable is empty string
* Email not found in whitelist
## Examples
iex> System.delete_env("SIGNUP_ALLOWED_EMAILS")
iex> BasicSignupWhitelist.mail_whitelisted("joe@example.com")
false
iex> System.put_env("SIGNUP_ALLOWED_EMAILS","*")
iex> BasicSignupWhitelist.mail_whitelisted("joe@example.com")
true
"""
def mail_whitelisted(email) do
env_value = System.get_env("SIGNUP_ALLOWED_EMAILS")
mail_whitelisted_fun(env_value, email)
end
end

View File

@ -0,0 +1,35 @@
defmodule FunCore.BasicSignupAllowlist do
@moduledoc """
Functional core for email allowlist checking logic.
"""
@doc """
Normalizes an email address by trimming whitespace and converting to lowercase.
"""
@spec normalize(String.t()) :: String.t()
def normalize(email) do
email |> String.trim() |> String.downcase()
end
@doc """
Converts a comma-separated string of email addresses into a normalized list.
"""
@spec addresses_as_list(String.t()) :: [String.t()]
def addresses_as_list(addresses_str) do
addresses_str
|> String.split(",")
|> Enum.map(&normalize/1)
end
@doc """
Checks if an email is allowed based on the allowlist configuration.
"""
@spec signup_allowed_fun(String.t() | nil, String.t()) :: boolean()
def signup_allowed_fun(signups_allowed, email_received) do
case signups_allowed do
nil -> false
"*" -> true
list_str -> normalize(email_received) in addresses_as_list(list_str)
end
end
end

View File

@ -1,19 +0,0 @@
defmodule FunCore.BasicSignupWhitelist do
def normalize(email) do
email |> String.trim() |> String.downcase()
end
def addresses_as_list(addresses_str) do
addresses_str
|> String.split(",")
|> Enum.map(&normalize/1)
end
def mail_whitelisted_fun(signups_allowed, email_received) do
case signups_allowed do
nil -> false
"*" -> true
list_str -> normalize(email_received) in addresses_as_list(list_str)
end
end
end

View File

@ -1,9 +1,9 @@
defmodule BasicSignupWhitelist.MixProject do
defmodule BasicSignupAllowlist.MixProject do
use Mix.Project
def project do
[
app: :basic_signup_whitelist,
app: :basic_signup_allowlist,
version: "0.1.0",
elixir: "~> 1.18",
start_permanent: Mix.env() == :prod,

110
plan.md
View File

@ -1,17 +1,17 @@
# whitelist sketch
# allowlist sketch
Here's a complete Mix project structure with the email whitelist functionality and tests:
Here's a complete Mix project structure with the email allowlist functionality and tests:
## Project Structure
```
email_whitelist_test/
email_allowlist_test/
├── config
│ └── config.exs
├── lib
│ └── email_whitelist.ex
│ └── email_allowlist.ex
├── test
│ ├── email_whitelist_test.exs
│ ├── email_allowlist_test.exs
│ └── test_helper.exs
├── mix.exs
└── README.md
@ -25,7 +25,7 @@ defmodule EmailWhitelistTest.MixProject do
def project do
[
app: :email_whitelist_test,
app: :email_allowlist_test,
version: "0.1.0",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
@ -47,11 +47,11 @@ end
import Config
# Configure your application
config :email_whitelist_test, :allowed_emails,
config :email_allowlist_test, :allowed_emails,
["user@domain.com", "admin@example.org"]
```
## 3. `lib/email_whitelist.ex` - Main Implementation
## 3. `lib/email_allowlist.ex` - Main Implementation
```elixir
defmodule EmailWhitelist do
@ -64,10 +64,10 @@ defmodule EmailWhitelist do
- Returns false if:
* Environment variable doesn't exist
* Environment variable is empty string
* Email not found in whitelist
* Email not found in allowlist
"""
def mail_whitelisted(email) do
def mail_allowlisted(email) do
normalized_email = String.downcase(email)
env_var = System.get_env("ALLOWED_EMAILS")
@ -94,13 +94,13 @@ end
ExUnit.start()
```
## 5. `test/email_whitelist_test.exs` - Test Cases
## 5. `test/email_allowlist_test.exs` - Test Cases
```elixir
defmodule EmailWhitelistTest do
use ExUnit.Case, async: true
describe "mail_whitelisted/1" do
describe "mail_allowlisted/1" do
setup do
# Save original env var
original_env = System.get_env("ALLOWED_EMAILS")
@ -119,59 +119,59 @@ defmodule EmailWhitelistTest do
test "allows all emails when ALLOWED_EMAILS is '*'" do
System.put_env("ALLOWED_EMAILS", "*")
assert EmailWhitelist.mail_whitelisted("any@example.com") == true
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
assert EmailWhitelist.mail_whitelisted("test@test.co.uk") == true
assert EmailWhitelist.mail_allowlisted("any@example.com") == true
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
assert EmailWhitelist.mail_allowlisted("test@test.co.uk") == true
end
test "allows whitelisted emails" do
test "allows allowlisted emails" do
System.put_env("ALLOWED_EMAILS", "user@domain.com,admin@example.org")
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
assert EmailWhitelist.mail_whitelisted("ADMIN@EXAMPLE.ORG") == true
assert EmailWhitelist.mail_whitelisted("User@Domain.Com") == true
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
assert EmailWhitelist.mail_allowlisted("ADMIN@EXAMPLE.ORG") == true
assert EmailWhitelist.mail_allowlisted("User@Domain.Com") == true
end
test "rejects non-whitelisted emails" do
test "rejects non-allowlisted emails" do
System.put_env("ALLOWED_EMAILS", "user@domain.com,admin@example.org")
assert EmailWhitelist.mail_whitelisted("invalid@example.com") == false
assert EmailWhitelist.mail_whitelisted("test@test.co.uk") == false
assert EmailWhitelist.mail_allowlisted("invalid@example.com") == false
assert EmailWhitelist.mail_allowlisted("test@test.co.uk") == false
end
test "rejects when ALLOWED_EMAILS is nil" do
System.delete_env("ALLOWED_EMAILS")
assert EmailWhitelist.mail_whitelisted("any@example.com") == false
assert EmailWhitelist.mail_allowlisted("any@example.com") == false
end
test "rejects when ALLOWED_EMAILS is empty string" do
System.put_env("ALLOWED_EMAILS", "")
assert EmailWhitelist.mail_whitelisted("any@example.com") == false
assert EmailWhitelist.mail_allowlisted("any@example.com") == false
end
test "handles whitespace in email list" do
test "handles allowspace in email list" do
System.put_env("ALLOWED_EMAILS", " user@domain.com , admin@example.org , test@test.co.uk ")
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
assert EmailWhitelist.mail_whitelisted("ADMIN@EXAMPLE.ORG") == true
assert EmailWhitelist.mail_whitelisted("test@test.co.uk") == true
assert EmailWhitelist.mail_whitelisted("invalid@example.com") == false
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
assert EmailWhitelist.mail_allowlisted("ADMIN@EXAMPLE.ORG") == true
assert EmailWhitelist.mail_allowlisted("test@test.co.uk") == true
assert EmailWhitelist.mail_allowlisted("invalid@example.com") == false
end
test "case insensitive matching works" do
System.put_env("ALLOWED_EMAILS", "User@Domain.Com,ADMIN@EXAMPLE.ORG")
assert EmailWhitelist.mail_whitelisted("user@domain.com") == true
assert EmailWhitelist.mail_whitelisted("USER@DOMAIN.COM") == true
assert EmailWhitelist.mail_whitelisted("admin@example.org") == true
assert EmailWhitelist.mail_allowlisted("user@domain.com") == true
assert EmailWhitelist.mail_allowlisted("USER@DOMAIN.COM") == true
assert EmailWhitelist.mail_allowlisted("admin@example.org") == true
end
test "empty email returns false" do
System.put_env("ALLOWED_EMAILS", "user@domain.com")
assert EmailWhitelist.mail_whitelisted("") == false
assert EmailWhitelist.mail_allowlisted("") == false
end
end
end
@ -182,24 +182,24 @@ end
```markdown
# EmailWhitelistTest
A simple Mix project demonstrating email whitelist functionality.
A simple Mix project demonstrating email allowlist functionality.
## Installation
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `email_whitelist_test` to your list of dependencies in `mix.exs`:
by adding `email_allowlist_test` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:email_whitelist_test, "~> 0.1.0"}
{:email_allowlist_test, "~> 0.1.0"}
]
end
```
## Usage
The main function is `EmailWhitelist.mail_whitelisted/1` which checks if an email address is allowed.
The main function is `EmailWhitelist.mail_allowlisted/1` which checks if an email address is allowed.
Environment variable configuration:
- `ALLOWED_EMAILS="*"` - Allow all emails
@ -221,8 +221,8 @@ MIT
1. **Create the project structure:**
```bash
mkdir email_whitelist_test
cd email_whitelist_test
mkdir email_allowlist_test
cd email_allowlist_test
```
2. **Create all files with the content above**
@ -251,7 +251,7 @@ Finished in 0.05 seconds (0.04s async, 0.01s sync)
The tests cover all your specified requirements:
- ✅ All emails allowed when `ALLOWED_EMAILS="*"`
- ✅ Specific emails allowed when in list
- ✅ Non-whitelisted emails rejected
- ✅ Non-allowlisted emails rejected
- ✅ Missing environment variable handled properly
- ✅ Empty environment variable handled properly
- ✅ Whitespace trimming in email lists
@ -272,7 +272,7 @@ You can easily switch from a local path dependency to a git dependency by simply
```elixir
def deps do
[
{:email_whitelist_test, path: "../email_whitelist_test"}
{:email_allowlist_test, path: "../email_allowlist_test"}
]
end
```
@ -281,7 +281,7 @@ end
```elixir
def deps do
[
{:email_whitelist_test, git: "https://github.com/yourusername/email_whitelist_test.git"}
{:email_allowlist_test, git: "https://github.com/yourusername/email_allowlist_test.git"}
]
end
```
@ -292,7 +292,7 @@ After changing the dependency specification:
```bash
# Remove the old dependency
mix deps.clean email_whitelist_test
mix deps.clean email_allowlist_test
# Fetch the new git dependency
mix deps.get
@ -302,21 +302,21 @@ mix deps.get
### Specify a Branch or Tag:
```elixir
{:email_whitelist_test,
git: "https://github.com/yourusername/email_whitelist_test.git",
{:email_allowlist_test,
git: "https://github.com/yourusername/email_allowlist_test.git",
branch: "main"}
# Or for a specific tag
{:email_whitelist_test,
git: "https://github.com/yourusername/email_whitelist_test.git",
{:email_allowlist_test,
git: "https://github.com/yourusername/email_allowlist_test.git",
tag: "v1.0.0"}
```
### For Private Repositories:
```elixir
{:email_whitelist_test,
git: "https://github.com/yourusername/email_whitelist_test.git",
github: "yourusername/email_whitelist_test",
{:email_allowlist_test,
git: "https://github.com/yourusername/email_allowlist_test.git",
github: "yourusername/email_allowlist_test",
branch: "main"}
```
@ -326,7 +326,7 @@ mix deps.get
```elixir
def deps do
[
{:email_whitelist_test, path: "../email_whitelist_test"}
{:email_allowlist_test, path: "../email_allowlist_test"}
]
end
```
@ -335,8 +335,8 @@ end
```elixir
def deps do
[
{:email_whitelist_test,
git: "https://github.com/yourusername/email_whitelist_test.git",
{:email_allowlist_test,
git: "https://github.com/yourusername/email_allowlist_test.git",
branch: "main"}
]
end
@ -352,7 +352,7 @@ end
## Important Notes:
- **No code changes needed** - your existing imports and usage remain identical
- **Same module names** - `EmailWhitelist.mail_whitelisted/1` works the same
- **Same module names** - `EmailWhitelist.mail_allowlisted/1` works the same
- **Same function signatures** - no API changes required
- **Cache cleared** - you'll need to run `mix deps.get` to fetch the new version
@ -360,7 +360,7 @@ end
```bash
# Edit your mix.exs file, then:
mix deps.clean email_whitelist_test
mix deps.clean email_allowlist_test
mix deps.get
```

102
rename_module.sh Executable file
View File

@ -0,0 +1,102 @@
#!/bin/bash
# Script to rename BasicSignupWhitelist module to BasicSignupAllowlist
# This includes renaming files, module names, function names, and all references
# Works recursively through all subdirectories
echo "Starting module rename from Whitelist to Allowlist..."
echo ""
# Counter for renamed files
renamed_count=0
# 1. Find and rename ALL files containing "whitelist" recursively
echo "Finding and renaming files recursively..."
echo "----------------------------------------"
# Use find to locate all files with whitelist in the name
# Process deepest files first to avoid path issues
while IFS= read -r -d '' file; do
dir=$(dirname "$file")
filename=$(basename "$file")
newname="${filename//whitelist/allowlist}"
newname="${newname//Whitelist/Allowlist}"
if [ "$filename" != "$newname" ]; then
mv "$file" "$dir/$newname"
echo " ✓ Renamed: $file$dir/$newname"
((renamed_count++))
fi
done < <(find . -type f \( -name "*whitelist*" -o -name "*Whitelist*" \) \( -name "*.ex" -o -name "*.exs" \) -print0 | sort -zr)
if [ $renamed_count -eq 0 ]; then
echo " No files needed renaming"
fi
echo ""
# 2. Replace all occurrences of BasicSignupWhitelist with BasicSignupAllowlist
echo "Updating module names in all .ex and .exs files..."
echo "---------------------------------------------------"
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/BasicSignupWhitelist/BasicSignupAllowlist/g' {} +
echo " ✓ Updated module names from BasicSignupWhitelist to BasicSignupAllowlist"
# 3. Replace function names (mail_whitelisted -> mail_allowlisted)
echo ""
echo "Updating function names..."
echo "--------------------------"
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/mail_whitelisted/mail_allowlisted/g' {} +
echo " ✓ Updated function names from mail_whitelisted to mail_allowlisted"
# 4. Replace case-sensitive variations of whitelist/allowlist
echo ""
echo "Updating all whitelist references (case-sensitive)..."
echo "-----------------------------------------------------"
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/whitelist/allowlist/g' {} +
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/Whitelist/Allowlist/g' {} +
find . -type f \( -name "*.ex" -o -name "*.exs" \) ! -path "./_build/*" ! -path "./deps/*" -exec sed -i 's/WHITELIST/ALLOWLIST/g' {} +
echo " ✓ Updated all case variations of whitelist to allowlist"
# 5. Update references in config files (mix.exs, README.md, etc.)
echo ""
echo "Updating references in configuration and documentation files..."
echo "--------------------------------------------------------------"
for file in mix.exs README.md CLAUDE.md .formatter.exs; do
if [ -f "$file" ]; then
sed -i 's/whitelist/allowlist/g' "$file"
sed -i 's/Whitelist/Allowlist/g' "$file"
sed -i 's/WHITELIST/ALLOWLIST/g' "$file"
echo " ✓ Updated references in $file"
fi
done
# 6. Clean up old build artifacts
echo ""
echo "Cleaning up old build artifacts..."
echo "----------------------------------"
if [ -d "_build" ]; then
# Find and remove directories with whitelist in the name
find _build -type d -name "*whitelist*" -exec rm -rf {} + 2>/dev/null
echo " ✓ Removed old build directories containing 'whitelist'"
echo " Note: Run 'mix clean' and 'mix compile' to rebuild completely"
else
echo " No _build directory found"
fi
# 7. Show summary of changes
echo ""
echo "============================================"
echo "Module rename complete!"
echo "============================================"
echo ""
echo "Summary:"
echo " - Renamed $renamed_count file(s)"
echo " - Updated all module and function references"
echo " - Cleaned build artifacts"
echo ""
echo "Recommended next steps:"
echo " 1. Run 'mix clean' to clean all build artifacts"
echo " 2. Run 'mix deps.get' if you have dependencies"
echo " 3. Run 'mix compile --force' to recompile with new module names"
echo " 4. Run 'mix test' to ensure all tests still pass"
echo " 5. Commit these changes to version control"

View File

@ -0,0 +1,29 @@
defmodule BasicSignupAllowlistTest do
use ExUnit.Case, async: false
doctest BasicSignupAllowlist
defp allow_signups_for(allowlist) do
System.put_env(BasicSignupAllowlist.signup_allowlist_emails(), allowlist)
end
describe "setup in describe block" do
setup do
on_exit(fn ->
# resetting values did not work, so 'just' set it to the effect without this module configured.
System.put_env(BasicSignupAllowlist.signup_allowlist_emails(), "*")
end)
:ok
end
test "When not set, not allowlisted" do
System.delete_env(BasicSignupAllowlist.signup_allowlist_emails())
refute BasicSignupAllowlist.signup_allowed?("joe@example.com")
end
test "When set to star, allowlisted" do
allow_signups_for("*")
assert BasicSignupAllowlist.signup_allowed?("joe@example.com")
end
end
end

View File

@ -1,29 +0,0 @@
defmodule BasicSignupWhitelistTest do
use ExUnit.Case, async: false
doctest BasicSignupWhitelist
defp allow_signups_for(whitelist) do
System.put_env("SIGNUP_ALLOWED_EMAILS", whitelist)
end
describe "setup in describe block" do
setup do
on_exit(fn ->
# resetting values did not work, so 'just' set it to the effect without this module configured.
System.put_env("SIGNUP_ALLOWED_EMAILS", "*")
end)
:ok
end
test "When not set, not whitelisted" do
System.delete_env("SIGNUP_ALLOWED_EMAILS")
refute BasicSignupWhitelist.mail_whitelisted("joe@example.com")
end
test "When set to star, whitelisted" do
allow_signups_for("*")
assert BasicSignupWhitelist.mail_whitelisted("joe@example.com")
end
end
end

View File

@ -1,6 +1,6 @@
defmodule FunCore.BasicSignupWhitelistTest do
defmodule FunCore.BasicSignupAllowlistTest do
use ExUnit.Case
import FunCore.BasicSignupWhitelist
import FunCore.BasicSignupAllowlist
test "addresses_as_list" do
assert addresses_as_list("joe@example.com, jane@example.com") == [
@ -14,27 +14,27 @@ defmodule FunCore.BasicSignupWhitelistTest do
assert "jane@example.com" in lst
end
describe "Not whitelisted when allowed list is" do
describe "Not allowlisted when allowed list is" do
test "not set" do
refute(mail_whitelisted_fun(nil, "joe@example.com"))
refute(signup_allowed_fun(nil, "joe@example.com"))
end
test "empty" do
refute(mail_whitelisted_fun("j", "joe@example.com"))
refute(signup_allowed_fun("j", "joe@example.com"))
end
end
describe "Whitelisted when" do
describe "Allowlisted when" do
test "*" do
assert(mail_whitelisted_fun("*", "jane@example.com"))
assert(signup_allowed_fun("*", "jane@example.com"))
end
test "Multiple set and one match" do
assert(mail_whitelisted_fun("joe@example.com, jane@example.com", "jane@example.com"))
assert(signup_allowed_fun("joe@example.com, jane@example.com", "jane@example.com"))
end
test "Matches with different casings" do
assert(mail_whitelisted_fun("joe@Example.com, jane@example.com", "Joe@example.com"))
assert(signup_allowed_fun("joe@Example.com, jane@example.com", "Joe@example.com"))
end
end
end