19 |
20 | {% with messages = get_flashed_messages() %}
21 | {% if messages %}
22 |
23 | {% for message in messages %}
24 | {{ message }}
25 | {% endfor %}
26 |
27 | {% endif %}
28 | {% endwith %}
29 |
30 |
31 |
40 |
41 |
42 | {% endblock body %}
43 |
--------------------------------------------------------------------------------
/subscribie/blueprints/subscriber/templates/subscriber/forgot_password.html:
--------------------------------------------------------------------------------
1 | {% extends "subscriber/layout.html" %}
2 | {% block title %} {{ _('Login') }} {% endblock %}
3 |
4 | {% block body %}
5 |
6 |
{{ _('Reset your password') }}
7 |
8 |
9 |
10 |
{{ _('We will send you an email to reset your password') }}.
11 |
18 |
19 |
20 |
21 | {% endblock body %}
22 |
--------------------------------------------------------------------------------
/subscribie/blueprints/subscriber/templates/subscriber/list_files.html:
--------------------------------------------------------------------------------
1 | {% extends "subscriber/layout.html" %}
2 | {% block title %} {{ _('Account') }} - {{ company.name }} {% endblock %}
3 |
4 | {% block body %}
5 |
6 |
{{ _('Uploaded files') }}
7 |
8 |
9 |
10 | {{ _('Uploaded files') }}
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
{{ _('Uploaded Files') }}
19 |
{{ _('Files listed here will be available to your subscribers when they login') }}.
20 |
25 |
26 |
27 | {{ _('File name') }}
28 | {{ _('Created at') }}
29 |
30 | {% for file in files %}
31 |
32 | {{ file.file_name }}
33 | {{ file.created_at.strftime('%d/%m/%Y %H:%M') }}
34 |
35 | {% endfor %}
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | {% endblock %}
46 |
--------------------------------------------------------------------------------
/subscribie/blueprints/subscriber/templates/subscriber/login.html:
--------------------------------------------------------------------------------
1 | {% extends "subscriber/layout.html" %}
2 | {% block title %} {{ _('Login') }} {% endblock %}
3 |
4 | {% block body %}
5 |
6 |
{{ _('Customer Login') }}
7 |
8 |
24 |
25 | {% endblock body %}
26 |
--------------------------------------------------------------------------------
/subscribie/blueprints/subscriber/templates/subscriber/reset_password.html:
--------------------------------------------------------------------------------
1 | {% extends "subscriber/layout.html" %}
2 | {% block title %} {{ _('Change password') }} {% endblock %}
3 |
4 | {% block body %}
5 |
6 |
{{ _('Set a new password') }}
7 |
8 |
21 |
22 | {% endblock body %}
23 |
--------------------------------------------------------------------------------
/subscribie/blueprints/subscriber/templates/subscriber/update_choices.html:
--------------------------------------------------------------------------------
1 | {% extends "subscriber/layout.html" %}
2 | {% block title %} {{ _('Update Choices') }} - {{ company.name }} {% endblock %}
3 |
4 | {% block body %}
5 |
6 |
7 |
8 |
9 |
{{ _('Choose your options') }}
10 |
11 | {{ _('Your') }} {{ plan.title }} {{ _('plan has the following options') }}
12 |
13 |
31 |
32 |
33 |
34 |
35 | {% endblock %}
36 |
--------------------------------------------------------------------------------
/subscribie/custom_pages/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/custom_pages/.gitkeep
--------------------------------------------------------------------------------
/subscribie/database.py:
--------------------------------------------------------------------------------
1 | from flask_sqlalchemy import SQLAlchemy
2 |
3 | database = SQLAlchemy()
4 |
--------------------------------------------------------------------------------
/subscribie/emails/donation.jinja2.html:
--------------------------------------------------------------------------------
1 |
Hello {{ first_name or ''}},
2 |
3 |
Thanks for your Donations to {{ company_name or '' }}.
4 |
5 |
With your support we will be able to help others
6 |
7 |
Sincerly,{{ company_name or '' }}.
8 |
--------------------------------------------------------------------------------
/subscribie/emails/subscriber-payment-failed-notification.jinja2.html:
--------------------------------------------------------------------------------
1 | Hi {{ subscriber_first_name or '' }},
2 |
3 |
This is a message from {{ company.name }}.
4 |
5 |
The system says a payment collection failed.
6 |
7 |
The system gave the following reason: "{{ failure_message }} / {{ failure_code }}."
8 |
9 |
Please could you log into your account where you can retry payments (under 'Failed Invoices').
10 |
11 |
If you need to, you can also change your payment details (under 'Payment Settings').
12 |
13 |
Thank you!
14 |
--------------------------------------------------------------------------------
/subscribie/emails/subscriber-reset-password.jinja2.html:
--------------------------------------------------------------------------------
1 |
Reset your password - {{ company.name }}
2 |
3 |
Please use the following link to reset your password:
4 |
5 |
Reset my password
--------------------------------------------------------------------------------
/subscribie/emails/update-choices.jinja2.html:
--------------------------------------------------------------------------------
1 |
{{ company.name }} - Update Choices
2 |
3 |
Your subscription has options which you can choose from.
4 |
5 |
Please use the following link to set your options:
6 |
7 |
Login & update my options
--------------------------------------------------------------------------------
/subscribie/emails/user-new-subscriber-notification.jinja2.html:
--------------------------------------------------------------------------------
1 | You have a new subscriber!
2 |
3 | {% if subscriber_email %}
4 | Email: {{ subscriber_email }}
5 | {% endif %}
6 |
7 | {% if subscription %}
8 | Name: {{ subscription.person.given_name }} {{ subscription.person.family_name }}
9 | {% endif %}
--------------------------------------------------------------------------------
/subscribie/emails/user-reset-password.jinja2.html:
--------------------------------------------------------------------------------
1 |
Reset your password - {{ company.name }}
2 |
3 |
Please use the following link to reset your password:
4 |
5 |
Reset my password
--------------------------------------------------------------------------------
/subscribie/emails/welcome.jinja2.html:
--------------------------------------------------------------------------------
1 |
Hello {{ first_name or ''}},
2 |
3 |
Welcome to {{ company_name or '' }}.
4 |
5 |
Plan name: {{ plan.title }}
6 |
7 |
8 | {% if plan.requirements.instant_payment %}
9 |
Upfront payment: {{ plan.showSellPrice() }}
10 | {% endif %}
11 |
12 | {% if plan.requirements.subscription %}
13 |
Interval: {{ plan.interval_unit }}
14 |
Amount: {{ plan.showIntervalAmount() }}
15 | {% if first_charge_date %}
16 |
Your first payment will be taken on: {{ first_charge_date }}
17 | {% endif %}
18 |
Each payment will be on the same day {{ plan.interval_unit }}
19 | {% endif %}
20 |
21 |
22 |
You can login to manage your account at:
23 | My account
24 |
25 |
26 |
Once again welcome to {{ company_name }}.
27 |
--------------------------------------------------------------------------------
/subscribie/schemas/__init__.py:
--------------------------------------------------------------------------------
1 | from .schemas import Plan, PlanCreate, PlanRequirementsCreate, PlanUpdate, Shop, Company
2 |
--------------------------------------------------------------------------------
/subscribie/static/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/static/.gitkeep
--------------------------------------------------------------------------------
/subscribie/tasks.py:
--------------------------------------------------------------------------------
1 | import logging
2 | import queue
3 | import threading
4 | from flask import current_app
5 |
6 | log = logging.getLogger(__name__)
7 |
8 | task_queue = queue.Queue()
9 |
10 |
11 | # Usage:
12 | """
13 | task_queue.put(lambda: print("long running task"))
14 | """
15 |
16 |
17 | def fifo_queue():
18 | def worker():
19 | while True:
20 | item = task_queue.get()
21 | log.info("Working on task from task_queue")
22 | try:
23 | item() # Execute task
24 | task_queue.task_done()
25 | log.info("Finished working on task from task_queue")
26 | except Exception as e:
27 | log.error(f"Error running task: {e}")
28 |
29 | # turn-on the worker thread
30 | threading.Thread(target=worker, daemon=True).start()
31 |
32 | # block until all tasks are done
33 | task_queue.join()
34 |
35 |
36 | thread = threading.Thread(target=fifo_queue)
37 | thread.start()
38 |
39 |
40 | def background_task(f):
41 | def bg_f(*a, **kw):
42 | app = current_app._get_current_object()
43 | kw["app"] = app # inject flask app for app context
44 |
45 | threading.Thread(target=f, args=a, kwargs=kw).start()
46 |
47 | return bg_f
48 |
--------------------------------------------------------------------------------
/subscribie/themes/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/.gitkeep
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/builder/_formhelpers.html:
--------------------------------------------------------------------------------
1 | {% macro render_field(field) %}
2 |
{{ field.label }}
3 | {{ field(**kwargs)|safe }}
4 | {% if field.errors %}
5 |
6 | {% for error in field.errors %}
7 | {{ error }}
8 | {% endfor %}
9 |
10 | {% endif %}
11 |
12 | {% endmacro %}
13 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/builder/changed.html:
--------------------------------------------------------------------------------
1 | dfsok
2 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/builder/changes.html:
--------------------------------------------------------------------------------
1 | Testing
2 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/builder/refund-policy.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 | {% block title %} Refund Policy Subscribie {% endblock %}
3 |
4 | {% block body %}
5 |
6 |
7 |
8 |
12 |
13 |
14 | You may close your Account at any time by emailing hello@subscriptionwebsitebuilder.co.uk and following the instructions given in our response.
15 | Once Closed:
16 |
17 | We will cease providing you the Services and they will no longer be accessible
18 | You will not be entitled to any refunds of any Fees, pro rata or otherwise.
19 | Your online store will be taken offline
20 |
21 |
22 |
23 | We reserve the right to modify or terminate the Service or your Account without notice at any time. For example, upgrades, security , these examples are non-exhaustive
24 |
25 |
26 |
27 |
Start now
29 |
31 | or be inspired
32 |
33 |
34 |
35 |
36 | {% endblock %}
37 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/builder/shops.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {% for shop in shops %}
4 | {% if 'prodtest' not in shop['site_url'] %}
5 |
6 | {{ shop['email'] }}
7 | {{ shop['site_url'] }}
8 |
9 | {% endif %}
10 | {% endfor %}
11 |
12 |
13 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/builder/total.html:
--------------------------------------------------------------------------------
1 | beter
2 |
3 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/credit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/credit.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/feature1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/feature1.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/feature2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/feature2.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/feature3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/feature3.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/google-signin-component.js:
--------------------------------------------------------------------------------
1 | // Define cusom element
2 | // See https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots
3 | customElements.define('google-signin',
4 | class extends HTMLElement {
5 | constructor() {
6 | super();
7 | let template = document.getElementById('google-signin-template');
8 | let templateContent = template.content;
9 |
10 | const shadowRoot = this.attachShadow({mode: 'open'})
11 | .appendChild(templateContent.cloneNode(true));
12 | }
13 | }
14 | );
15 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/google-signin-template.css:
--------------------------------------------------------------------------------
1 | .btn-google {
2 | padding: 0.5rem 2.5rem;
3 | width: 100%;
4 | text-decoration: none;
5 | display: block;
6 | border-radius: 0.25rem;
7 | color: #555;
8 | text-align: center;
9 | box-sizing:border-box;
10 | background-position: left center;
11 | background-repeat: no-repeat;
12 | background-color: white;
13 | background-image: url(./google-icon.svg);
14 |
15 | }
16 |
17 | .btn-google:hover {
18 | background-color: #dfdfdf;
19 | }
20 |
21 | .btn-google--lg {
22 | font-size: 1.5rem;
23 | background-size: 4rem 4rem;
24 | }
25 |
26 | .btn-google--border {
27 | border: 1px solid #ccc;
28 | }
29 |
30 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/google_tag_manager.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/google_tag_manager.jpg
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/iconfinder_Circled_Facebook_svg_5279111.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/iconfinder_Circled_Facebook_svg_5279111.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/iconfinder_Circled_Instagram_svg_5279112.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/iconfinder_Circled_Instagram_svg_5279112.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/iconfinder_Circled_Twitter_svg_5279123.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/iconfinder_Circled_Twitter_svg_5279123.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/meta-thumbnail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/meta-thumbnail.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/no-credit.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/no-credit.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/photos/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/photos/.gitkeep
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/right_top.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/right_top.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/snackbar.min.css:
--------------------------------------------------------------------------------
1 | .snackbar-container{transition:all .5s ease;transition-property:top,right,bottom,left,opacity;font-family:Roboto,sans-serif;font-size:14px;min-height:14px;background-color:#070b0e;position:fixed;display:flex;justify-content:space-between;align-items:center;color:#fff;line-height:22px;padding:18px 24px;bottom:-100px;top:-100px;opacity:0;z-index:9999}.snackbar-container .action{background:inherit;display:inline-block;border:none;font-size:inherit;text-transform:uppercase;color:#4caf50;margin:0 0 0 24px;padding:0;min-width:min-content;cursor:pointer}@media (min-width:640px){.snackbar-container{min-width:288px;max-width:568px;display:inline-flex;border-radius:2px;margin:24px}}@media (max-width:640px){.snackbar-container{left:0;right:0;width:100%}}.snackbar-pos.bottom-center{top:auto!important;bottom:0;left:50%;transform:translate(-50%,0)}.snackbar-pos.bottom-left{top:auto!important;bottom:0;left:0}.snackbar-pos.bottom-right{top:auto!important;bottom:0;right:0}.snackbar-pos.top-left{bottom:auto!important;top:0;left:0}.snackbar-pos.top-center{bottom:auto!important;top:0;left:50%;transform:translate(-50%,0)}.snackbar-pos.top-right{bottom:auto!important;top:0;right:0}@media (max-width:640px){.snackbar-pos.bottom-center,.snackbar-pos.top-center{left:0;transform:none}}
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/start-a-subscription-website-example.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/start-a-subscription-website-example.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/subscription-embed-widgetpng.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-builder/static/subscription-embed-widgetpng.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-builder/static/tick.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Subscription Builder - Success
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/jesmond/errors/ui-error.html:
--------------------------------------------------------------------------------
1 | {% extends "layout.html" %}
2 |
3 | {% block body %}
4 |
9 |
10 | {% endblock %}
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/box.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/fb.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/google_tag_manager.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-jesmond/static/google_tag_manager.jpg
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/insta.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/packing_peanuts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-jesmond/static/packing_peanuts.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/tawk_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-jesmond/static/tawk_logo.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/tawk_property_id.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/themes/theme-jesmond/static/tawk_property_id.png
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/tick.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Subscription Builder - Success
5 | Created with Sketch.
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/subscribie/themes/theme-jesmond/static/twitter.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/subscribie/translations/de/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/translations/de/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/subscribie/translations/es/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/translations/es/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/subscribie/translations/fr/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/translations/fr/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/subscribie/translations/hr/LC_MESSAGES/messages.mo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/translations/hr/LC_MESSAGES/messages.mo
--------------------------------------------------------------------------------
/subscribie/uploads/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/subscribie/uploads/.gitkeep
--------------------------------------------------------------------------------
/test.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -exou
4 |
5 | . .venv/bin/activate
6 | python -m pytest
7 |
--------------------------------------------------------------------------------
/tests/amber.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | file_format_version: 1
3 | public_key: 8476e2922afdc8945e2f44397b55eb174561b60e73066a0c913fc932c5e83342
4 | secrets:
5 | - name: KEEP_SHOPS_LIST
6 | sha256: 296a9b19f60ee6fdb6e18b5cecbbf0ba42ce5a17b27d72f1424739133bdec79c
7 | cipher: ae434df42ed4fd10c631136de57d6b3f8bff71d9a0717073fd75c3f6857f856d825031322486e64a18f7da022080e377ea42d3d777f35cf7bf16cdca37fde5fcca0f923d9a251085b441e596841a7edb5e5b7c9fdff0895d5e5eea157783adb37dedf0c4fb65b20b838aa8376621ffa0ae516c2e7870f1fc7feb95
8 | - name: PYTHONUNBUFFERED
9 | sha256: 6b86b273ff34fce19d6b804eff5a3f5747ada4eaa22f1d49c01e52ddb7875b4b
10 | cipher: 2e710eda7dee482e2456cd256153d65b10eee45e9046317a406587fe517a114fe92892583c6e3f6980474c345458971db7
11 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/.env.example:
--------------------------------------------------------------------------------
1 | PLAYWRIGHT_HEADLESS=false
2 | PLAYWRIGHT_HOST=http://127.0.0.1:5000/
3 | PLAYWRIGHT_SLOWMO=500
4 |
5 | PLAWRIGHT_MAX_RETRIES=1
6 | # GLOBAL EMAIL SETTINGS #
7 | IMAP_SEARCH_UNSEEN="1"
8 | IMAP_SEARCH_SINCE_DATE="21-Aug-2022"
9 | EMAIL_SEARCH_API_HOST="email-search-api.example.com"
10 |
11 | # SHOP OWNER EMAIL SETTINGS #
12 | SHOP_OWNER_EMAIL_HOST="email.example.co.uk"
13 | SHOP_OWNER_EMAIL_USER="alice@example.co.uk"
14 | SHOP_OWNER_MAGIC_LOGIN_IMAP_SEARCH_SUBJECT="Subscribie Magic Login"
15 | SHOP_OWNER_EMAIL_PASSWORD="secret"
16 |
17 | # SUBSCRIBER EMAIL SEttingS #
18 | SUBSCRIBER_EMAIL_HOST="email.example.co.uk"
19 | SUBSCRIBER_EMAIL_USER="test@example.co.uk"
20 | SUBSCRIBER_EMAIL_PASSWORD="secret"
21 | RESET_PASSWORD_IMAP_SEARCH_SUBJECT="Password Reset"
22 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/delete-connect-account-id.js:
--------------------------------------------------------------------------------
1 | // global-setup.js
2 | const { test, expect, chromium } = require('@playwright/test');
3 |
4 | module.exports = async config => {
5 | const { baseURL, storageState } = config.projects[0].use;
6 | const browser = await chromium.launch();
7 | const page = await browser.newPage();
8 | await page.goto(baseURL + '/auth/login');
9 | await page.fill('#email', 'admin@example.com');
10 | await page.fill('#password', 'password');
11 | await page.click('#login');
12 |
13 | const content = await page.textContent('.card-title')
14 | expect(content === 'Checklist'); // If we see "Checklist", we're logged in to admin
15 |
16 | await new Promise(x => setTimeout(x, 5000));
17 | await page.goto(baseURL + '/admin/delete-connect-account');
18 | console.log('deleting-connect-account-id');
19 | await new Promise(x => setTimeout(x, 2000)); //2 secconds
20 | await page.goto(baseURL + 'admin/dashboard')
21 | const connect_to_stripe = await page.textContent('text="Review Stripe"');
22 | expect (connect_to_stripe == 'Review Stripe');
23 | console.log('stripe is not connected');
24 |
25 | await page.context().storageState({ path: storageState });
26 | await browser.close();
27 | };
28 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/1005_subscriber_terms_and_condition_check_test.spec.js:
--------------------------------------------------------------------------------
1 | const { test, expect } = require('@playwright/test');
2 | const { set_test_name_cookie } = require('./features/set_test_name_cookie');
3 | const TEST_SUBSCRIBER_EMAIL_USER = process.env.TEST_SUBSCRIBER_EMAIL_USER;
4 |
5 |
6 | test('@1005@subscriber @1005_subscriber_terms_and_condition_check_test', async ({ page }) => {
7 |
8 | await set_test_name_cookie(page, "@1005_subscriber_terms_and_condition_check_test");
9 | await page.goto("/auth/logout");
10 | await page.goto("/account/logout");
11 | //login in as subscriber
12 | await page.goto("/account/login");
13 | await page.fill('#email', TEST_SUBSCRIBER_EMAIL_USER);
14 | await page.fill('#password', 'password');
15 | await page.click('text=Sign In');
16 | await page.textContent('.card-title') === "Your subscriptions";
17 | console.log("Logged in as a subscriber");
18 | //check Terms and Conditions is attached
19 | await page.goto('/account/subscriptions');
20 | await page.textContent('.card-title') === "Your subscriptions";
21 | await page.locator('text=Terms and Conditions');
22 | await new Promise(x => setTimeout(x, 1000));
23 | // check the terms and conditions page
24 | await page.click("text=Terms and Conditions");
25 | await page.locator("testing");
26 | console.log("terms and condition are shown in the subscriber side");
27 | });
28 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/1065_shop_owner_enabling_donations.spec.js:
--------------------------------------------------------------------------------
1 | const { admin_login } = require('./features/admin_login');
2 | const { set_test_name_cookie } = require('./features/set_test_name_cookie');
3 |
4 | const { test, expect } = require('@playwright/test');
5 | //Subscribie enable donation test
6 | test("@1065 @1065_shop_owner_enabling_donations", async ({ page }) => {
7 | console.log("enabling Donations...");
8 | await admin_login(page);
9 | await set_test_name_cookie(page, "@1065_shop_owner_enabling_donations");
10 | // Go to enable donations
11 | await page.goto('/admin/donate-enabled-settings');
12 | const donations_settings = await page.content("text=Donations Settings");
13 | expect(donations_settings === "Donations Settings");
14 |
15 | await page.click('text="Enable"');
16 | await page.click('text="Save"');
17 | await page.textContent('.alert-heading') === "Notification";
18 |
19 | //Check the admin dashboard if donors settings are enabled in the dashboard
20 | await page.goto('/admin/dashboard');
21 | const donations_in_dashboard = await page.content("text=Donations to your shop");
22 | expect(donations_in_dashboard === "Donations to your shop");
23 |
24 | await page.goto('/');
25 | const donation_heading = await page.content("text=Donate");
26 | expect(donation_heading === "Donate");
27 | });
28 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/1333_shop_owner_add_free_text_question.spec.js:
--------------------------------------------------------------------------------
1 | import { test, expect } from '@playwright/test';
2 | const { admin_login } = require('./features/admin_login');
3 | const { set_test_name_cookie } = require('./features/set_test_name_cookie');
4 |
5 | const testName = "@1333_shop_owner_add_free_text_question";
6 |
7 | test(testName, async ({ page }) => {
8 | await admin_login(page);
9 | await set_test_name_cookie(page, testName);
10 | await page.goto("/admin/dashboard");
11 | await page.getByRole('button', { name: 'Questions (Simple Forms)' }).click();
12 | await page.getByRole('link', { name: 'Add / Edit / Delete Questions' }).click();
13 | await page.getByRole('link', { name: 'Add Question' }).click();
14 | await page.getByRole('textbox').click();
15 | await page.getByRole('textbox').fill('Where did you hear about us?');
16 | await page.getByRole('button', { name: 'Save' }).click();
17 | await page.getByRole('cell', { name: 'Where did you hear about us?' }).first().click();
18 | });
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/212_shop_owner_slogan_creation.spec.js:
--------------------------------------------------------------------------------
1 | const { test, expect } = require('@playwright/test');
2 | const { admin_login } = require('./features/admin_login');
3 | const { set_test_name_cookie } = require('./features/set_test_name_cookie');
4 |
5 | //Subscribie tests
6 | test("@212@shop-owner@slogan creation @212_shop_owner_slogan_creation", async ({ page }) => {
7 | await admin_login(page);
8 | await set_test_name_cookie(page, "@212_shop_owner_slogan_creation");
9 | console.log("checking if slogan is already created...");
10 | await page.goto('/');
11 | let slogan_exists = await page.evaluate(() => document.body.textContent);
12 | if (slogan_exists === 'this is a slogan') {
13 | console.log("slogan already created, exiting test");
14 | test.skip();
15 | }
16 | // Go to edit plan page
17 | await page.goto('/admin/edit');
18 |
19 | //edit slogan
20 | await page.fill("input[name='slogan']", 'this is a slogan');
21 | await page.click("text=Hair Gel");
22 | await page.click('text="Save"');
23 |
24 | //verify home page plan creation
25 | await page.goto("/");
26 | await page.reload();
27 | const slogan_created = await page.textContent('text=this is a slogan');
28 | expect(slogan_created === 'this is a slogan');
29 | });
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/387_shop_owner_change_shop_colour.spec.js:
--------------------------------------------------------------------------------
1 |
2 | const { test, expect } = require('@playwright/test');
3 | const { admin_login } = require('./features/admin_login');
4 | const { set_test_name_cookie } = require('./features/set_test_name_cookie');
5 |
6 | test("@387@shop-owner@change_shop_colour @387_shop_owner_change_shop_colour", async ({ page }) => {
7 | await admin_login(page);
8 | await set_test_name_cookie(page, "@387_shop_owner_change_shop_colour");
9 |
10 | console.log("changing shop colour...");
11 | // Go to style your shop
12 | await page.goto('/style/style-shop');
13 | const style_shop = await page.content("text=Style Your Shop");
14 | expect(style_shop === "Style Your Shop");
15 |
16 | await page.fill('input[name="primary"]', "0b5394");
17 | await new Promise(x => setTimeout(x, 3000));
18 | await page.fill('input[name="font"]', "000000");
19 | await page.click('text="Save"');
20 |
21 | // check if its changed
22 | console.log("checking if shop style has changed");
23 | await page.goto('/style/style-shop');
24 | await page.content('input[style="background-color: rgb(11, 83, 148); color: white;"]');
25 |
26 | //screenshot of the changed style shop;
27 | await page.goto('/');
28 | });
29 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/463_shop_owner_adding_vat.spec.js:
--------------------------------------------------------------------------------
1 |
2 | const { test, expect } = require('@playwright/test');
3 | const { admin_login } = require('./features/admin_login');
4 | const { set_test_name_cookie } = require('./features/set_test_name_cookie');
5 |
6 |
7 | test("@463@shop-owner@adding VAT @463_shop_owner_adding_vat", async ({ page }) => {
8 | await admin_login(page);
9 | await set_test_name_cookie(page, "@463_shop_owner_adding_vat");
10 | console.log("enabling VAT...");
11 | // Go to style your shop
12 | await page.goto('/admin/vat-settings');
13 | const VAT_settings = await page.content("text=VAT Settings");
14 | expect(VAT_settings === "VAT Settings");
15 |
16 | await page.click('text="Yes. Charge VAT at 20%"');
17 | await new Promise(x => setTimeout(x, 1000));
18 | await page.click('text="Save"');
19 | await page.textContent('.alert-heading') === "Notification";
20 |
21 | });
22 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/704_shop_owner_magic_login_receives_email.js:
--------------------------------------------------------------------------------
1 | const { test, expect } = require('@playwright/test');
2 | const checkShopOwnerLogin = require('./checkShopOwnerLogin.js');
3 |
4 | const SHOP_OWNER_LOGIN_URL = process.env.SHOP_OWNER_LOGIN_URL
5 | const SHOP_OWNER_EMAIL = process.env.SHOP_OWNER_EMAIL_USER
6 |
7 | test('@704@shop_owner@magic login receives email', async ({ page }) => {
8 | await page.goto(SHOP_OWNER_LOGIN_URL);
9 | await page.fill('#email', SHOP_OWNER_EMAIL);
10 | await page.click('#login');
11 | await new Promise(r => setTimeout(r, 5000));
12 | checkShopOwnerLogin.checkShopOwnerLogin();
13 | console.log(checkShopOwnerLogin.magic_login_url);
14 | await new Promise(r => setTimeout(r, 5000));
15 | await page.goto(checkShopOwnerLogin.magic_login_url);
16 | await new Promise(r => setTimeout(r, 5000));
17 | });
18 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/features/admin_login.js:
--------------------------------------------------------------------------------
1 | var admin_login = async function (page) {
2 | await page.goto(process.env['PLAYWRIGHT_HOST'] + '/auth/login');
3 | await page.fill('#email', 'admin@example.com');
4 | await page.fill('#password', 'password');
5 | await page.click('#login');
6 | await page.goto(process.env['PLAYWRIGHT_HOST'] + '/admin/dashboard');
7 | }
8 |
9 |
10 | module.exports.admin_login = admin_login
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/features/clear_db.js:
--------------------------------------------------------------------------------
1 | const { admin_login } = require('./admin_login');
2 | const { expect } = require('@playwright/test');
3 | const URL = process.env['PLAYWRIGHT_HOST'];
4 | var clear_db = async function (page) {
5 | await page.goto(URL + '/admin/remove-subscriptions');
6 | const contentSubscriptions = await page.evaluate(() => document.body.textContent.indexOf("all subscriptions deleted"));
7 | expect(contentSubscriptions > -1);
8 |
9 | await page.goto(URL + '/admin/remove-people');
10 | const contentPeople = await page.evaluate(() => document.body.textContent.indexOf("all people deleted"));
11 | expect(contentPeople > -1);
12 |
13 | await page.goto(URL + '/admin/remove-transactions');
14 | const contentTransactions = await page.evaluate(() => document.body.textContent.indexOf("all transactions deleted"));
15 | expect(contentTransactions > -1);
16 |
17 | await page.goto(URL + '/admin/remove-documents');
18 | const contentDocuments = await page.evaluate(() => document.body.textContent.indexOf("all documents deleted"));
19 | expect(contentDocuments > -1);
20 | // End Clear DB
21 | }
22 |
23 | module.exports.clear_db = clear_db
24 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/features/fetch_upcomming_invoices.js:
--------------------------------------------------------------------------------
1 | var fetch_upcomming_invoices = async function (page) {
2 | // Go to upcoming payments and ensure plan is attached to upcoming invoice
3 | await page.goto('/admin/upcoming-invoices');
4 | await new Promise(x => setTimeout(x, 35000));
5 | await page.click('#fetch_upcoming_invoices');
6 | await new Promise(x => setTimeout(x, 30000));
7 | await page.goto('/admin/upcoming-invoices');
8 | }
9 |
10 | module.exports.fetch_upcomming_invoices = fetch_upcomming_invoices;
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/e2e/features/set_test_name_cookie.js:
--------------------------------------------------------------------------------
1 | var set_test_name_cookie = async function (page, testName) {
2 | /* Drop a cookie to cause Subscribie to display a visual
3 | feedback overlay showing the test name/number running at the time.
4 | */
5 | await page.goto(`/admin/set-test-name/${testName}`);
6 |
7 | //await new Promise(x => setTimeout(x, 19000));
8 | }
9 |
10 | module.exports.set_test_name_cookie = set_test_name_cookie;
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/github.spec.js:
--------------------------------------------------------------------------------
1 | const { test, expect } = require('@playwright/test');
2 |
3 | test.describe("Github actions test:", () => {
4 | const magic_login_receives_email = require('./tests/704_shop_owner_magic_login_receives_email');
5 |
6 | });
7 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/logo-subscribie.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/tests/browser-automated-tests-playwright/logo-subscribie.png
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/requirements.txt:
--------------------------------------------------------------------------------
1 | graphviz
2 |
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/test-videos/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Subscribie/subscribie/4ba736e39a1e867186fee4e4ec28ae8b4b1d3a3e/tests/browser-automated-tests-playwright/test-videos/.gitkeep
--------------------------------------------------------------------------------
/tests/browser-automated-tests-playwright/worker2.spec.js:
--------------------------------------------------------------------------------
1 | /*
2 | const { test, expect } = require('@playwright/test');
3 |
4 | test.beforeEach(async ({ page }) => {
5 | //Login
6 | await page.goto('/auth/login');
7 | await page.fill('#email', 'admin@example.com');
8 | await page.fill('#password', 'password');
9 | await page.click('#login');
10 |
11 | const content = await page.textContent('.card-title')
12 | expect(content === 'Checklist'); // If we see "Checklist", we're logged in to admin
13 |
14 | await new Promise(x => setTimeout(x, 5000));
15 | });
16 |
17 | const plan_creation = require('./tests/shop_owner_plan_creation');
18 |
19 | const custom_url = require('./tests/1219_shop_owner_enable_custom_url');
20 |
21 | const changing_plans_order = require('./tests/275_shop_owner_changing_plans_order');
22 |
23 | const share_private_plan_url = require('./tests/491_shop_owner_share_private_plan_url');
24 |
25 | const order_plan_with_choice_options_and_required_note = require('./tests/264_subscriber_order_plan_with_choice_options_and_required_note');
26 |
27 | const order_plan_with_cancel_at = require('./tests/516_subscriber_order_plan_with_cancel_at');
28 |
29 | const order_plan_cooling_off = require('./tests/133_subscriber_order_plan_with_cooling_off');
30 |
31 | const enabling_donations = require('./tests/1065_shop_owner_enabling_donations');
32 |
33 | const checkout_donations = require('./tests/1065_subscriber_checkout_donation');
34 | */
35 |
--------------------------------------------------------------------------------