commit
2830949764
19
.github/workflows/main.yml
vendored
19
.github/workflows/main.yml
vendored
|
@ -17,19 +17,22 @@ jobs:
|
|||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pip install pytest
|
||||
pytest
|
||||
|
||||
- name: Test formatting
|
||||
run: |
|
||||
pip install black
|
||||
black --check .
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -r requirements.txt
|
||||
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
pip install pytest
|
||||
pytest
|
||||
|
||||
- name: Publish to Docker Registry
|
||||
uses: elgohr/Publish-Docker-Github-Action@master
|
||||
with:
|
||||
|
|
|
@ -41,7 +41,7 @@ def activate():
|
|||
user = activation_code.user
|
||||
user.activated = True
|
||||
login_user(user)
|
||||
email_utils.send_welcome_email(user.email, user.name)
|
||||
email_utils.send_welcome_email(user)
|
||||
|
||||
# activation code is to be used only once
|
||||
ActivationCode.delete(activation_code.id)
|
||||
|
|
|
@ -130,7 +130,7 @@ def facebook_callback():
|
|||
|
||||
db.session.commit()
|
||||
login_user(user)
|
||||
email_utils.send_welcome_email(user.email, user.name)
|
||||
email_utils.send_welcome_email(user)
|
||||
|
||||
flash(f"Welcome to SimpleLogin {user.name}!", "success")
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ def github_callback():
|
|||
)
|
||||
db.session.commit()
|
||||
login_user(user)
|
||||
email_utils.send_welcome_email(user.email, user.name)
|
||||
email_utils.send_welcome_email(user)
|
||||
|
||||
flash(f"Welcome to SimpleLogin {user.name}!", "success")
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ def google_callback():
|
|||
|
||||
db.session.commit()
|
||||
login_user(user)
|
||||
email_utils.send_welcome_email(user.email, user.name)
|
||||
email_utils.send_welcome_email(user)
|
||||
|
||||
flash(f"Welcome to SimpleLogin {user.name}!", "success")
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<h1> Billing </h1>
|
||||
|
||||
<p>
|
||||
You are on the <b>{{ current_user.plan_name() }}</b> plan. Thank you very much for supporting SimpleLogin. 🙌
|
||||
You are on the <b>{{ current_user.get_subscription().plan_name() }}</b> plan. Thank you very much for supporting SimpleLogin. 🙌
|
||||
</p>
|
||||
|
||||
{% if sub.cancelled %}
|
||||
|
|
|
@ -20,7 +20,10 @@ def custom_alias():
|
|||
if not current_user.can_create_new_alias():
|
||||
# notify admin
|
||||
LOG.error("user %s tries to create custom alias", current_user)
|
||||
flash("ony premium user can choose custom alias", "warning")
|
||||
flash(
|
||||
"You have reached free plan limit, please upgrade to create new aliases",
|
||||
"warning",
|
||||
)
|
||||
return redirect(url_for("dashboard.index"))
|
||||
|
||||
user_custom_domains = [cd.domain for cd in current_user.verified_custom_domains()]
|
||||
|
|
|
@ -24,7 +24,7 @@ class CouponForm(FlaskForm):
|
|||
@login_required
|
||||
def lifetime_licence():
|
||||
# sanity check: make sure this page is only for free user
|
||||
if current_user.is_premium():
|
||||
if current_user.lifetime_or_active_subscription():
|
||||
flash("You are already a premium user", "warning")
|
||||
return redirect(url_for("dashboard.index"))
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ from app.dashboard.base import dashboard_bp
|
|||
@dashboard_bp.route("/pricing", methods=["GET", "POST"])
|
||||
@login_required
|
||||
def pricing():
|
||||
# sanity check: make sure this page is only for free user
|
||||
if current_user.is_premium():
|
||||
# sanity check: make sure this page is only for free or trial user
|
||||
if not current_user.should_upgrade():
|
||||
flash("You are already a premium user", "warning")
|
||||
return redirect(url_for("dashboard.index"))
|
||||
|
||||
|
|
|
@ -29,12 +29,21 @@ def _render(template_name, **kwargs) -> str:
|
|||
return template.render(**kwargs)
|
||||
|
||||
|
||||
def send_welcome_email(email, name):
|
||||
def send_welcome_email(user):
|
||||
send_email(
|
||||
email,
|
||||
f"Welcome to SimpleLogin {name}!",
|
||||
_render("welcome.txt", name=name),
|
||||
_render("welcome.html", name=name),
|
||||
user.email,
|
||||
f"Welcome to SimpleLogin {user.name}",
|
||||
_render("welcome.txt", name=user.name, user=user),
|
||||
_render("welcome.html", name=user.name, user=user),
|
||||
)
|
||||
|
||||
|
||||
def send_trial_end_soon_email(user):
|
||||
send_email(
|
||||
user.email,
|
||||
f"Your trial will end soon {user.name}",
|
||||
_render("trial-end.txt", name=user.name, user=user),
|
||||
_render("trial-end.html", name=user.name, user=user),
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -122,6 +122,11 @@ class User(db.Model, ModelMixin, UserMixin):
|
|||
# some users could have lifetime premium
|
||||
lifetime = db.Column(db.Boolean, default=False, nullable=False, server_default="0")
|
||||
|
||||
# user can use all premium features until this date
|
||||
trial_end = db.Column(
|
||||
ArrowType, default=lambda: arrow.now().shift(days=7, hours=1), nullable=True
|
||||
)
|
||||
|
||||
profile_picture = db.relationship(File)
|
||||
|
||||
@classmethod
|
||||
|
@ -141,11 +146,8 @@ class User(db.Model, ModelMixin, UserMixin):
|
|||
|
||||
return user
|
||||
|
||||
def should_upgrade(self):
|
||||
return not self.is_premium()
|
||||
|
||||
def is_premium(self):
|
||||
"""user is premium if they have a active subscription"""
|
||||
def lifetime_or_active_subscription(self) -> bool:
|
||||
"""True if user has lifetime licence or active subscription"""
|
||||
if self.lifetime:
|
||||
return True
|
||||
|
||||
|
@ -155,7 +157,35 @@ class User(db.Model, ModelMixin, UserMixin):
|
|||
|
||||
return False
|
||||
|
||||
def can_create_new_alias(self):
|
||||
def in_trial(self):
|
||||
"""return True if user does not have lifetime licence or an active subscription AND is in trial period"""
|
||||
if self.lifetime_or_active_subscription():
|
||||
return False
|
||||
|
||||
if self.trial_end and arrow.now() < self.trial_end:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def should_upgrade(self):
|
||||
return not self.lifetime_or_active_subscription()
|
||||
|
||||
def is_premium(self) -> bool:
|
||||
"""
|
||||
user is premium if they:
|
||||
- have a lifetime deal or
|
||||
- in trial period or
|
||||
- active subscription
|
||||
"""
|
||||
if self.lifetime_or_active_subscription():
|
||||
return True
|
||||
|
||||
if self.trial_end and arrow.now() < self.trial_end:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def can_create_new_alias(self) -> bool:
|
||||
if self.is_premium():
|
||||
return True
|
||||
|
||||
|
@ -197,7 +227,6 @@ class User(db.Model, ModelMixin, UserMixin):
|
|||
|
||||
def suggested_names(self) -> (str, [str]):
|
||||
"""return suggested name and other name choices """
|
||||
|
||||
other_name = convert_to_id(self.name)
|
||||
|
||||
return self.name, [other_name, "Anonymous", "whoami"]
|
||||
|
@ -206,17 +235,6 @@ class User(db.Model, ModelMixin, UserMixin):
|
|||
names = self.name.split(" ")
|
||||
return "".join([n[0].upper() for n in names if n])
|
||||
|
||||
def plan_name(self) -> str:
|
||||
if self.is_premium():
|
||||
sub = self.get_subscription()
|
||||
|
||||
if sub.plan == PlanEnum.monthly:
|
||||
return "Monthly ($2.99/month)"
|
||||
else:
|
||||
return "Yearly ($29.99/year)"
|
||||
else:
|
||||
return "Free Plan"
|
||||
|
||||
def get_subscription(self):
|
||||
"""return *active* subscription
|
||||
TODO: support user unsubscribe and re-subscribe
|
||||
|
@ -638,6 +656,12 @@ class Subscription(db.Model, ModelMixin):
|
|||
|
||||
user = db.relationship(User)
|
||||
|
||||
def plan_name(self):
|
||||
if self.plan == PlanEnum.monthly:
|
||||
return "Monthly ($2.99/month)"
|
||||
else:
|
||||
return "Yearly ($29.99/year)"
|
||||
|
||||
|
||||
class DeletedAlias(db.Model, ModelMixin):
|
||||
"""Store all deleted alias to make sure they are NOT reused"""
|
||||
|
|
10
cron.py
10
cron.py
|
@ -1,7 +1,7 @@
|
|||
import arrow
|
||||
|
||||
from app.config import IGNORED_EMAILS, ADMIN_EMAIL
|
||||
from app.email_utils import send_email
|
||||
from app.email_utils import send_email, send_trial_end_soon_email
|
||||
from app.extensions import db
|
||||
from app.log import LOG
|
||||
from app.models import (
|
||||
|
@ -16,6 +16,13 @@ from app.models import (
|
|||
from server import create_app
|
||||
|
||||
|
||||
def send_trial_end_soon():
|
||||
for user in User.query.filter(User.trial_end.isnot(None)).all():
|
||||
if arrow.now().shift(days=3) > user.trial_end >= arrow.now().shift(days=2):
|
||||
LOG.d("Send trial end email to user %s", user)
|
||||
send_trial_end_soon_email(user)
|
||||
|
||||
|
||||
def stats():
|
||||
"""send admin stats everyday"""
|
||||
if not ADMIN_EMAIL:
|
||||
|
@ -103,3 +110,4 @@ if __name__ == "__main__":
|
|||
|
||||
with app.app_context():
|
||||
stats()
|
||||
send_trial_end_soon()
|
||||
|
|
|
@ -54,7 +54,14 @@ from app.email_utils import (
|
|||
)
|
||||
from app.extensions import db
|
||||
from app.log import LOG
|
||||
from app.models import GenEmail, ForwardEmail, ForwardEmailLog, CustomDomain, Directory
|
||||
from app.models import (
|
||||
GenEmail,
|
||||
ForwardEmail,
|
||||
ForwardEmailLog,
|
||||
CustomDomain,
|
||||
Directory,
|
||||
User,
|
||||
)
|
||||
from app.utils import random_string
|
||||
from server import create_app
|
||||
|
||||
|
@ -138,8 +145,8 @@ class MailHandler:
|
|||
|
||||
# Only premium user can use the directory feature
|
||||
if directory:
|
||||
dir_user = directory.user
|
||||
if dir_user.is_premium():
|
||||
dir_user: User = directory.user
|
||||
if dir_user.can_create_new_alias():
|
||||
LOG.d("create alias %s for directory %s", alias, directory)
|
||||
on_the_fly = True
|
||||
|
||||
|
@ -166,8 +173,8 @@ class MailHandler:
|
|||
|
||||
# Only premium user can continue using the catch-all feature
|
||||
if custom_domain and custom_domain.catch_all:
|
||||
domain_user = custom_domain.user
|
||||
if domain_user.is_premium():
|
||||
domain_user: User = custom_domain.user
|
||||
if domain_user.can_create_new_alias():
|
||||
LOG.d("create alias %s for domain %s", alias, custom_domain)
|
||||
on_the_fly = True
|
||||
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
meo
|
||||
cat
|
||||
chat
|
||||
chat
|
||||
alo
|
||||
hey
|
||||
yeah
|
||||
yes
|
29
migrations/versions/2020_013010_7c39ba4ec38d_.py
Normal file
29
migrations/versions/2020_013010_7c39ba4ec38d_.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
"""empty message
|
||||
|
||||
Revision ID: 7c39ba4ec38d
|
||||
Revises: ba6f13ccbabb
|
||||
Create Date: 2020-01-30 10:10:01.245257
|
||||
|
||||
"""
|
||||
import sqlalchemy_utils
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '7c39ba4ec38d'
|
||||
down_revision = 'ba6f13ccbabb'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
def upgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('users', sa.Column('trial_end', sqlalchemy_utils.types.arrow.ArrowType(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade():
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('users', 'trial_end')
|
||||
# ### end Alembic commands ###
|
|
@ -381,7 +381,7 @@ def setup_paddle_callback(app: Flask):
|
|||
|
||||
elif request.form.get("alert_name") == "subscription_cancelled":
|
||||
subscription_id = request.form.get("subscription_id")
|
||||
LOG.debug("Cancel subscription %s", subscription_id)
|
||||
LOG.error("Cancel subscription %s", subscription_id)
|
||||
|
||||
sub: Subscription = Subscription.get_by(subscription_id=subscription_id)
|
||||
if sub:
|
||||
|
|
3
shell.py
3
shell.py
|
@ -36,6 +36,7 @@ app = create_app()
|
|||
with app.app_context():
|
||||
# to test email template
|
||||
# with open("/tmp/email.html", "w") as f:
|
||||
# f.write(_render("welcome.html", name="John Wick"))
|
||||
# user = User.get(1)
|
||||
# f.write(_render("welcome.html", user=user, name=user.name))
|
||||
|
||||
embed()
|
||||
|
|
|
@ -100,8 +100,8 @@ a, a:hover {
|
|||
padding-top: 25px;
|
||||
color: #000000;
|
||||
font-family: sans-serif;" class="paragraph">
|
||||
Cheers. <br>
|
||||
<a href="https://twitter.com/nguyenkims">Son</a> - SimpleLogin founder.
|
||||
Regards, <br>
|
||||
Son - SimpleLogin founder.
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
@ -114,19 +114,6 @@ a, a:hover {
|
|||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- PARAGRAPH -->
|
||||
<!-- Set text color and font family ("sans-serif" or "Georgia, serif"). Duplicate all text styles in links, including line-height -->
|
||||
<tr>
|
||||
<td align="center" valign="top" style="border-collapse: collapse; border-spacing: 0; margin: 0; padding: 0; padding-left: 6.25%; padding-right: 6.25%; width: 87.5%; font-size: 17px; font-weight: 400; line-height: 160%;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 25px;
|
||||
color: #000000;
|
||||
font-family: sans-serif;" class="paragraph">
|
||||
This email ends up in Spam/Junk? <br>
|
||||
Here's how to <a href="https://simplelogin.io/help">whitelist SimpleLogin</a>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- End of WRAPPER -->
|
||||
</table>
|
||||
|
||||
|
@ -146,7 +133,7 @@ a, a:hover {
|
|||
|
||||
<!-- ICON 1 -->
|
||||
<td align="center" valign="middle" style="margin: 0; padding: 0; padding-left: 10px; padding-right: 10px; border-collapse: collapse; border-spacing: 0;"><a target="_blank"
|
||||
href="https://github.com/simple-login/"
|
||||
href="https://github.com/simple-login/app"
|
||||
style="text-decoration: none;"><img border="0" vspace="0" hspace="0" style="padding: 0; margin: 0; outline: none; text-decoration: none; -ms-interpolation-mode: bicubic; border: none; display: inline-block;
|
||||
color: #000000;"
|
||||
alt="F" title="Github"
|
||||
|
|
25
templates/emails/trial-end.html
Normal file
25
templates/emails/trial-end.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block content %}
|
||||
{% if name %}
|
||||
{{ render_text("Hi " + name + ",") }}
|
||||
{% else %}
|
||||
{{ render_text("Hi,") }}
|
||||
{% endif %}
|
||||
|
||||
{{ render_text("Your trial will end " + user.trial_end.humanize() + ".") }}
|
||||
|
||||
{{ render_text("When the trial ends:") }}
|
||||
|
||||
{{ render_text("- All aliases/domains/directories you have created are <b>kept</b> and continue working.") }}
|
||||
{{ render_text("- You cannot create new aliases if you exceed the free plan limit, i.e. have more than 5 aliases.") }}
|
||||
{{ render_text("- As features like <b>catch-all</b> or <b>directory</b> allow you to create aliases on-the-fly, those aliases cannot be automatically created if you have more than 5 aliases.") }}
|
||||
{{ render_text("- You cannot add new domain or directory.") }}
|
||||
|
||||
{{ render_text('You can <a href="https://app.simplelogin.io/dashboard/pricing">upgrade</a> today to continue using all these Premium features (and much more coming).') }}
|
||||
|
||||
{{ render_text('Let me know if you need to extend your trial period.') }}
|
||||
|
||||
|
||||
{% endblock %}
|
||||
|
17
templates/emails/trial-end.txt
Normal file
17
templates/emails/trial-end.txt
Normal file
|
@ -0,0 +1,17 @@
|
|||
Hi {{name}}
|
||||
|
||||
Your trial will end {{ user.trial_end.humanize() }}.
|
||||
|
||||
When the trial ends:
|
||||
|
||||
- All aliases/domains/directories you have created are kept and continue working.
|
||||
- You cannot create new aliases if you exceed the free plan limit, i.e. have more than 5 aliases.
|
||||
- As features like "catch-all" or "directory" allow you to create aliases on-the-fly, those aliases cannot be automatically created if you have more than 5 aliases.
|
||||
- You cannot add new domain or directory.
|
||||
|
||||
You can upgrade today to continue using all these Premium features (and much more coming).
|
||||
|
||||
Let me know if you need to extend your trial period.
|
||||
|
||||
Best,
|
||||
Son - SimpleLogin founder.
|
|
@ -11,12 +11,16 @@
|
|||
|
||||
{{ render_text('To better secure your account, I recommend enabling Multi-Factor Authentication (MFA) on your <a href="https://app.simplelogin.io/dashboard/setting">Setting page</a>.') }}
|
||||
|
||||
{{ render_text('If you use Chrome or Firefox, SimpleLogin extension could be handy to quickly create aliases. Chrome extension can be installed on <a href="https://chrome.google.com/webstore/detail/simplelogin-your-anti-spa/dphilobhebphkdjbpfohgikllaljmgbn">Chrome Store</a> and Firefox on <a href="https://addons.mozilla.org/en-GB/firefox/addon/simplelogin/">Firefox Store</a>.') }}
|
||||
{{ render_text('SimpleLogin browser extension could be handy to quickly manage aliases. Chrome (or other Chromium-based browsers like Brave or Vivaldi) extension can be installed on <a href="https://chrome.google.com/webstore/detail/simplelogin-your-anti-spa/dphilobhebphkdjbpfohgikllaljmgbn">Chrome Store</a>, Firefox on <a href="https://addons.mozilla.org/en-GB/firefox/addon/simplelogin/">Firefox Store</a> and Safari on <a href="https://apps.apple.com/us/app/simplelogin/id1494051017?mt=12&fbclid=IwAR0M0nnEKgoieMkmx91TSXrtcScj7GouqRxGgXeJz2un_5ydhIKlbAI79Io">AppStore</a>.') }}
|
||||
|
||||
{{ render_text('If you have a domain, for example for your business or your project, you can import your domain into SimpleLogin
|
||||
and create your business emails backed by your personal email. This is cheaper and more convenient than buying a GSuite account. By the way, all our business emails are actually aliases :).') }}
|
||||
and create your <b>business emails</b> using email alias. This is cheaper and more convenient than buying a dedicated solution like GSuite. By the way, all our business emails are actually aliases.') }}
|
||||
|
||||
{{ render_text('Importing domain is only available for Premium plan though, shoot me an email by replying to this email if you need a trial period.') }}
|
||||
{% if user.in_trial() %}
|
||||
{{ render_text('You can use all premium features like <em>custom domain</em> or <em>alias directory</em> during the <b>trial period</b>. Your trial will end ' + user.trial_end.humanize() + ".") }}
|
||||
{% endif %}
|
||||
|
||||
{{ render_text('If there\'s anything that\'s bugging you, even the smallest of issues that could be done better, I want to hear about it - so hit the reply button.') }}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
|
|
@ -5,16 +5,27 @@ My name is Son. I’m the founder of SimpleLogin and I wanted to be the first to
|
|||
To better secure your account, I recommend enabling Multi-Factor Authentication (MFA) on your setting page at
|
||||
https://app.simplelogin.io/dashboard/setting
|
||||
|
||||
If you use Chrome or Firefox, SimpleLogin extension could be quite handy to quickly create aliases.
|
||||
You can install Chrome extension on
|
||||
SimpleLogin browser extension could be handy to quickly manage aliases.
|
||||
|
||||
Chrome (or other Chromium-based browsers like Brave or Vivaldi) extension can be installed on:
|
||||
https://chrome.google.com/webstore/detail/simplelogin-your-anti-spa/dphilobhebphkdjbpfohgikllaljmgbn
|
||||
|
||||
and Firefox on
|
||||
Firefox on
|
||||
https://addons.mozilla.org/en-GB/firefox/addon/simplelogin/
|
||||
|
||||
and Safari on
|
||||
https://apps.apple.com/us/app/simplelogin/id1494051017?mt=12&fbclid=IwAR0M0nnEKgoieMkmx91TSXrtcScj7GouqRxGgXeJz2un_5ydhIKlbAI79Io
|
||||
|
||||
If you have a domain, for example for your business or your project, you can import your domain into SimpleLogin
|
||||
and create your business emails backed by your personal email! By the way, all our business emails are actually aliases 🤫.
|
||||
Importing domain is only available for Premium plan though, shoot me an email if you need a trial period.
|
||||
and create your business emails backed by your personal email! By the way, all our business emails are actually aliases.
|
||||
|
||||
{% if user.in_trial() %}
|
||||
You can use all premium features like custom domain or alias directory during the trial period.
|
||||
Your trial will end {{ user.trial_end.humanize() }}.
|
||||
{% endif %}
|
||||
|
||||
If there's anything that's bugging you, even the smallest of issues that could be done better, I want to hear about it - so hit the reply button.
|
||||
|
||||
|
||||
Thanks.
|
||||
Son - SimpleLogin founder.
|
||||
|
|
|
@ -25,15 +25,16 @@
|
|||
{{ current_user.name }}
|
||||
</span>
|
||||
|
||||
{% if current_user.is_premium() %}
|
||||
{% if current_user.in_trial() %}
|
||||
<small class="text-success d-block mt-1">Trial ends {{ current_user.trial_end|dt }}</small>
|
||||
{% elif current_user.lifetime_or_active_subscription() %}
|
||||
<small class="text-success d-block mt-1">Premium</small>
|
||||
{% endif %}
|
||||
|
||||
</span>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
|
||||
|
||||
|
||||
<a class="dropdown-item" href="{{ url_for('auth.logout') }}">
|
||||
<i class="dropdown-icon fe fe-log-out"></i> Sign out
|
||||
</a>
|
||||
|
|
|
@ -32,6 +32,7 @@ def test_out_of_quota(flask_client):
|
|||
user = User.create(
|
||||
email="a@b.c", password="password", name="Test User", activated=True
|
||||
)
|
||||
user.trial_end = None
|
||||
db.session.commit()
|
||||
|
||||
# create api_key
|
||||
|
|
|
@ -28,17 +28,16 @@ def test_out_of_quota(flask_client):
|
|||
user = User.create(
|
||||
email="a@b.c", password="password", name="Test User", activated=True
|
||||
)
|
||||
user.trial_end = None
|
||||
db.session.commit()
|
||||
|
||||
# create api_key
|
||||
api_key = ApiKey.create(user.id, "for test")
|
||||
db.session.commit()
|
||||
|
||||
# create 3 random alias to run out of quota
|
||||
# create MAX_NB_EMAIL_FREE_PLAN random alias to run out of quota
|
||||
for _ in range(MAX_NB_EMAIL_FREE_PLAN):
|
||||
GenEmail.create_new(user.id, prefix="test1")
|
||||
GenEmail.create_new(user.id, prefix="test2")
|
||||
GenEmail.create_new(user.id, prefix="test3")
|
||||
|
||||
r = flask_client.post(
|
||||
url_for("api.new_random_alias", hostname="www.test.com"),
|
||||
|
|
|
@ -4,7 +4,7 @@ from app.extensions import db
|
|||
from app.models import User, ApiKey, AliasUsedOn, GenEmail
|
||||
|
||||
|
||||
def test_success(flask_client):
|
||||
def test_user_in_trial(flask_client):
|
||||
user = User.create(
|
||||
email="a@b.c", password="password", name="Test User", activated=True
|
||||
)
|
||||
|
@ -19,7 +19,7 @@ def test_success(flask_client):
|
|||
)
|
||||
|
||||
assert r.status_code == 200
|
||||
assert r.json == {"is_premium": False, "name": "Test User"}
|
||||
assert r.json == {"is_premium": True, "name": "Test User"}
|
||||
|
||||
|
||||
def test_wrong_api_key(flask_client):
|
||||
|
|
|
@ -28,10 +28,16 @@ def test_profile_picture_url(flask_client):
|
|||
assert user.profile_picture_url() == "http://sl.test/static/default-avatar.png"
|
||||
|
||||
|
||||
def test_suggested_emails_for_user_who_cannot_create_new_email(flask_client):
|
||||
def test_suggested_emails_for_user_who_cannot_create_new_alias(flask_client):
|
||||
# make sure user is not in trial
|
||||
user = User.create(
|
||||
email="a@b.c", password="password", name="Test User", activated=True
|
||||
email="a@b.c",
|
||||
password="password",
|
||||
name="Test User",
|
||||
activated=True,
|
||||
trial_end=None,
|
||||
)
|
||||
|
||||
db.session.commit()
|
||||
|
||||
# make sure user runs out of quota to create new email
|
||||
|
|
Loading…
Reference in a new issue