diff --git a/package.json b/package.json index 926c9a2b..e466e96b 100644 --- a/package.json +++ b/package.json @@ -109,6 +109,7 @@ "redfour": "^1.0.0", "redis": "^2.7.1", "request": "^2.81.0", + "request-promise": "^4.2.1", "serve-favicon": "^2.4.2", "shortid": "^2.2.8", "slugify": "^1.1.0", diff --git a/setup/sql/mailtrain-test.sql b/setup/sql/mailtrain-test.sql index 95af27a0..b88e5bef 100644 --- a/setup/sql/mailtrain-test.sql +++ b/setup/sql/mailtrain-test.sql @@ -119,7 +119,7 @@ CREATE TABLE `campaigns` ( KEY `parent_index` (`parent`), KEY `check_index` (`last_check`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; -INSERT INTO `campaigns` (`id`, `cid`, `type`, `parent`, `name`, `description`, `list`, `segment`, `template`, `source_url`, `editor_name`, `editor_data`, `last_check`, `check_status`, `from`, `address`, `reply_to`, `subject`, `html`, `html_prepared`, `text`, `status`, `scheduled`, `status_change`, `delivered`, `blacklisted`, `opened`, `clicks`, `unsubscribed`, `bounced`, `complained`, `created`, `open_tracking_disabled`, `click_tracking_disabled`) VALUES (1,'BkwHWgCWb',1,NULL,'Merge Tags','',1,0,0,'','codeeditor',NULL,NULL,NULL,'My Awesome Company','admin@example.com','','Test message','\r\n
\r\n
LINK_UNSUBSCRIBE
\r\n \r\n
LINK_PREFERENCES
\r\n \r\n
LINK_BROWSER
\r\n \r\n
EMAIL
\r\n
[EMAIL]
\r\n
FIRST_NAME
\r\n
[FIRST_NAME]
\r\n
LAST_NAME
\r\n
[LAST_NAME]
\r\n
FULL_NAME
\r\n
[FULL_NAME]
\r\n
SUBSCRIPTION_ID
\r\n
[SUBSCRIPTION_ID]
\r\n
LIST_ID
\r\n
[LIST_ID]
\r\n
CAMPAIGN_ID
\r\n
[CAMPAIGN_ID]
\r\n
MERGE_TEXT
\r\n
[MERGE_TEXT]
\r\n
MERGE_NUMBER
\r\n
[MERGE_NUMBER]
\r\n
MERGE_WEBSITE
\r\n
[MERGE_WEBSITE]
\r\n
MERGE_GPG_PUBLIC_KEY
\r\n
[MERGE_GPG_PUBLIC_KEY/GPG Fallback Text]
\r\n
MERGE_MULTILINE_TEXT
\r\n
[MERGE_MULTILINE_TEXT]
\r\n
MERGE_JSON
\r\n
[MERGE_JSON]
\r\n
MERGE_DATE_MMDDYY
\r\n
[MERGE_DATE_MMDDYY]
\r\n
MERGE_DATE_DDMMYY
\r\n
[MERGE_DATE_DDMMYY]
\r\n
MERGE_BIRTHDAY_MMDD
\r\n
[MERGE_BIRTHDAY_MMDD]
\r\n
MERGE_BIRTHDAY_DDMM
\r\n
[MERGE_BIRTHDAY_DDMM]
\r\n
MERGE_DROP_DOWNS
\r\n
[MERGE_DROP_DOWNS]
\r\n
MERGE_CHECKBOXES
\r\n
[MERGE_CHECKBOXES]
\r\n
','\n
\n
LINK_UNSUBSCRIBE
\n \n
LINK_PREFERENCES
\n \n
LINK_BROWSER
\n \n
EMAIL
\n
[EMAIL]
\n
FIRST_NAME
\n
[FIRST_NAME]
\n
LAST_NAME
\n
[LAST_NAME]
\n
FULL_NAME
\n
[FULL_NAME]
\n
SUBSCRIPTION_ID
\n
[SUBSCRIPTION_ID]
\n
LIST_ID
\n
[LIST_ID]
\n
CAMPAIGN_ID
\n
[CAMPAIGN_ID]
\n
MERGE_TEXT
\n
[MERGE_TEXT]
\n
MERGE_NUMBER
\n
[MERGE_NUMBER]
\n
MERGE_WEBSITE
\n
[MERGE_WEBSITE]
\n
MERGE_GPG_PUBLIC_KEY
\n
[MERGE_GPG_PUBLIC_KEY/GPG Fallback Text]
\n
MERGE_MULTILINE_TEXT
\n
[MERGE_MULTILINE_TEXT]
\n
MERGE_JSON
\n
[MERGE_JSON]
\n
MERGE_DATE_MMDDYY
\n
[MERGE_DATE_MMDDYY]
\n
MERGE_DATE_DDMMYY
\n
[MERGE_DATE_DDMMYY]
\n
MERGE_BIRTHDAY_MMDD
\n
[MERGE_BIRTHDAY_MMDD]
\n
MERGE_BIRTHDAY_DDMM
\n
[MERGE_BIRTHDAY_DDMM]
\n
MERGE_DROP_DOWNS
\n
[MERGE_DROP_DOWNS]
\n
MERGE_CHECKBOXES
\n
[MERGE_CHECKBOXES]
\n
','',1,NOW(),NULL,0,0,0,0,0,0,0,NOW(),0,0); +INSERT INTO `campaigns` (`id`, `cid`, `type`, `parent`, `name`, `description`, `list`, `segment`, `template`, `source_url`, `editor_name`, `editor_data`, `last_check`, `check_status`, `from`, `address`, `reply_to`, `subject`, `html`, `html_prepared`, `text`, `status`, `scheduled`, `status_change`, `delivered`, `blacklisted`, `opened`, `clicks`, `unsubscribed`, `bounced`, `complained`, `created`, `open_tracking_disabled`, `click_tracking_disabled`) VALUES (1,'BkwHWgCWb',1,NULL,'Merge Tags','',1,0,0,'','codeeditor',NULL,NULL,NULL,'My Awesome Company','admin@example.com','','Test message','\r\n
\r\n
LINK_UNSUBSCRIBE
\r\n \r\n
LINK_PREFERENCES
\r\n \r\n
LINK_BROWSER
\r\n \r\n
EMAIL
\r\n
[EMAIL]
\r\n
FIRST_NAME
\r\n
[FIRST_NAME]
\r\n
LAST_NAME
\r\n
[LAST_NAME]
\r\n
FULL_NAME
\r\n
[FULL_NAME]
\r\n
SUBSCRIPTION_ID
\r\n
[SUBSCRIPTION_ID]
\r\n
LIST_ID
\r\n
[LIST_ID]
\r\n
CAMPAIGN_ID
\r\n
[CAMPAIGN_ID]
\r\n
MERGE_TEXT
\r\n
[MERGE_TEXT]
\r\n
MERGE_NUMBER
\r\n
[MERGE_NUMBER]
\r\n
MERGE_WEBSITE
\r\n
[MERGE_WEBSITE]
\r\n
MERGE_GPG_PUBLIC_KEY
\r\n
[MERGE_GPG_PUBLIC_KEY/GPG Fallback Text]
\r\n
MERGE_MULTILINE_TEXT
\r\n
[MERGE_MULTILINE_TEXT]
\r\n
MERGE_JSON
\r\n
[MERGE_JSON]
\r\n
MERGE_DATE_MMDDYYYY
\r\n
[MERGE_DATE_MMDDYYYY]
\r\n
MERGE_DATE_DDMMYYYY
\r\n
[MERGE_DATE_DDMMYYYY]
\r\n
MERGE_BIRTHDAY_MMDD
\r\n
[MERGE_BIRTHDAY_MMDD]
\r\n
MERGE_BIRTHDAY_DDMM
\r\n
[MERGE_BIRTHDAY_DDMM]
\r\n
MERGE_DROP_DOWNS
\r\n
[MERGE_DROP_DOWNS]
\r\n
MERGE_CHECKBOXES
\r\n
[MERGE_CHECKBOXES]
\r\n
','\n
\n
LINK_UNSUBSCRIBE
\n \n
LINK_PREFERENCES
\n \n
LINK_BROWSER
\n \n
EMAIL
\n
[EMAIL]
\n
FIRST_NAME
\n
[FIRST_NAME]
\n
LAST_NAME
\n
[LAST_NAME]
\n
FULL_NAME
\n
[FULL_NAME]
\n
SUBSCRIPTION_ID
\n
[SUBSCRIPTION_ID]
\n
LIST_ID
\n
[LIST_ID]
\n
CAMPAIGN_ID
\n
[CAMPAIGN_ID]
\n
MERGE_TEXT
\n
[MERGE_TEXT]
\n
MERGE_NUMBER
\n
[MERGE_NUMBER]
\n
MERGE_WEBSITE
\n
[MERGE_WEBSITE]
\n
MERGE_GPG_PUBLIC_KEY
\n
[MERGE_GPG_PUBLIC_KEY/GPG Fallback Text]
\n
MERGE_MULTILINE_TEXT
\n
[MERGE_MULTILINE_TEXT]
\n
MERGE_JSON
\n
[MERGE_JSON]
\n
MERGE_DATE_MMDDYYYY
\n
[MERGE_DATE_MMDDYYYY]
\n
MERGE_DATE_DDMMYYYY
\n
[MERGE_DATE_DDMMYYYY]
\n
MERGE_BIRTHDAY_MMDD
\n
[MERGE_BIRTHDAY_MMDD]
\n
MERGE_BIRTHDAY_DDMM
\n
[MERGE_BIRTHDAY_DDMM]
\n
MERGE_DROP_DOWNS
\n
[MERGE_DROP_DOWNS]
\n
MERGE_CHECKBOXES
\n
[MERGE_CHECKBOXES]
\n
','',1,NOW(),NULL,0,0,0,0,0,0,0,NOW(),0,0); CREATE TABLE `confirmations` ( `id` int(11) unsigned NOT NULL AUTO_INCREMENT, `cid` varchar(255) CHARACTER SET ascii NOT NULL, @@ -156,8 +156,8 @@ INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (4,1,'GPG Public Key','MERGE_GPG_PUBLIC_KEY',NULL,'gpg',NULL,NULL,'custom_gpg_public_key_ryvj51cz',1,NOW()); INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (5,1,'Multiline Text','MERGE_MULTILINE_TEXT',NULL,'longtext',NULL,NULL,'custom_multiline_text_bjbfojawb',1,NOW()); INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (6,1,'JSON','MERGE_JSON',NULL,'json',NULL,NULL,'custom_json_skqjkcb',1,NOW()); -INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (7,1,'Date (MM/DD/YY)','MERGE_DATE_MMDDYY',NULL,'date-us',NULL,NULL,'custom_date_mmddyy_rjkeojrzz',1,NOW()); -INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (8,1,'Date (DD/MM/YY)','MERGE_DATE_DDMMYY',NULL,'date-eur',NULL,NULL,'custom_date_ddmmyy_ryedsk0wz',1,NOW()); +INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (7,1,'Date (MM/DD/YYYY)','MERGE_DATE_MMDDYYYY',NULL,'date-us',NULL,NULL,'custom_date_mmddyy_rjkeojrzz',1,NOW()); +INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (8,1,'Date (DD/MM/YYYY)','MERGE_DATE_DDMMYYYY',NULL,'date-eur',NULL,NULL,'custom_date_ddmmyy_ryedsk0wz',1,NOW()); INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (9,1,'Birthday (MM/DD)','MERGE_BIRTHDAY_MMDD',NULL,'birthday-us',NULL,NULL,'custom_birthday_mmdd_h18coj0zz',1,NOW()); INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (10,1,'Birthday (DD/MM)','MERGE_BIRTHDAY_DDMM',NULL,'birthday-eur',NULL,NULL,'custom_birthday_ddmm_r1g3s1czz',1,NOW()); INSERT INTO `custom_fields` (`id`, `list`, `name`, `key`, `default_value`, `type`, `group`, `group_template`, `column`, `visible`, `created`) VALUES (11,1,'Drop Downs','MERGE_DROP_DOWNS',NULL,'dropdown',NULL,NULL,NULL,1,NOW()); @@ -324,21 +324,21 @@ CREATE TABLE `settings` ( `value` text NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `key` (`key`) -) ENGINE=InnoDB AUTO_INCREMENT=114 DEFAULT CHARSET=utf8mb4; +) ENGINE=InnoDB AUTO_INCREMENT=148 DEFAULT CHARSET=utf8mb4; INSERT INTO `settings` (`id`, `key`, `value`) VALUES (1,'smtp_hostname','localhost'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (2,'smtp_port','5587'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (3,'smtp_encryption','NONE'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (4,'smtp_user','testuser'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (5,'smtp_pass','testpass'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (6,'service_url','http://localhost:3000/'); -INSERT INTO `settings` (`id`, `key`, `value`) VALUES (7,'admin_email','admin@example.com'); +INSERT INTO `settings` (`id`, `key`, `value`) VALUES (7,'admin_email','keep.admin@mailtrain.org'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (8,'smtp_max_connections','5'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (9,'smtp_max_messages','100'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (10,'smtp_log',''); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (11,'default_sender','My Awesome Company'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (12,'default_postaddress','1234 Main Street'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (13,'default_from','My Awesome Company'); -INSERT INTO `settings` (`id`, `key`, `value`) VALUES (14,'default_address','admin@example.com'); +INSERT INTO `settings` (`id`, `key`, `value`) VALUES (14,'default_address','keep.admin@mailtrain.org'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (15,'default_subject','Test message'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (16,'default_homepage','https://mailtrain.org'); INSERT INTO `settings` (`id`, `key`, `value`) VALUES (17,'db_schema_version','29'); @@ -1229,7 +1229,7 @@ CREATE TABLE `users` ( KEY `check_reset` (`username`(191),`reset_token`,`reset_expire`), KEY `token_index` (`access_token`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4; -INSERT INTO `users` (`id`, `username`, `password`, `email`, `access_token`, `reset_token`, `reset_expire`, `created`) VALUES (1,'admin','$2a$10$mzKU71G62evnGB2PvQA4k..Wf9jASk.c7a8zRMHh6qQVjYJ2r/g/K','admin@example.com',NULL,NULL,NULL,NOW()); +INSERT INTO `users` (`id`, `username`, `password`, `email`, `access_token`, `reset_token`, `reset_expire`, `created`) VALUES (1,'admin','$2a$10$mzKU71G62evnGB2PvQA4k..Wf9jASk.c7a8zRMHh6qQVjYJ2r/g/K','keep.admin@mailtrain.org','7833d148e22c85474c314f43ae4591a7c9adec26',NULL,NULL,NOW()); SET UNIQUE_CHECKS=1; SET FOREIGN_KEY_CHECKS=1; diff --git a/test/e2e/lib/config.js b/test/e2e/lib/config.js index 223d2103..2fa99a3e 100644 --- a/test/e2e/lib/config.js +++ b/test/e2e/lib/config.js @@ -9,7 +9,9 @@ module.exports = { users: { admin: { username: 'admin', - password: 'test' + password: 'test', + email: 'keep.admin@mailtrain.org', + accessToken: '7833d148e22c85474c314f43ae4591a7c9adec26' } }, lists: { @@ -18,41 +20,59 @@ module.exports = { cid: 'Hkj1vCoJb', publicSubscribe: 1, unsubscriptionMode: 0, // (one-step, no form) + customFields: [ + { type: 'text', key: 'MERGE_TEXT', column: 'custom_text_field_byiiqjrw' }, + { type: 'number', key: 'MERGE_NUMBER', column: 'custom_number_field_r1dd91awb' }, + { type: 'website', key: 'MERGE_WEBSITE', column: 'custom_website_field_rkq991cw' }, + { type: 'gpg', key: 'MERGE_GPG_PUBLIC_KEY', column: 'custom_gpg_public_key_ryvj51cz' }, + { type: 'longtext', key: 'MERGE_MULTILINE_TEXT', column: 'custom_multiline_text_bjbfojawb' }, + { type: 'json', key: 'MERGE_JSON', column: 'custom_json_skqjkcb' }, + { type: 'date-us', key: 'MERGE_DATE_MMDDYYYY', column: 'custom_date_mmddyy_rjkeojrzz' }, + { type: 'date-eur', key: 'MERGE_DATE_DDMMYYYY', column: 'custom_date_ddmmyy_ryedsk0wz' }, + { type: 'birthday-us', key: 'MERGE_BIRTHDAY_MMDD', column: 'custom_birthday_mmdd_h18coj0zz' }, + { type: 'birthday-eur', key: 'MERGE_BIRTHDAY_DDMM', column: 'custom_birthday_ddmm_r1g3s1czz' }, + // TODO: Add remaining custom fields, dropdowns and checkboxes + ] }, l2: { id: 2, cid: 'SktV4HDZ-', publicSubscribe: 1, unsubscriptionMode: 1, // (one-step, with form) + customFields: [] }, l3: { id: 3, cid: 'BkdvNBw-W', publicSubscribe: 1, unsubscriptionMode: 2, // (two-step, no form) + customFields: [] }, l4: { id: 4, cid: 'rJMKVrDZ-', publicSubscribe: 1, unsubscriptionMode: 3, // (two-step, with form) + customFields: [] }, l5: { id: 5, cid: 'SJgoNSw-W', publicSubscribe: 1, unsubscriptionMode: 4, // (manual unsubscribe) + customFields: [] }, l6: { id: 6, cid: 'HyveEPvWW', publicSubscribe: 0, unsubscriptionMode: 0, // (one-step, no form) + customFields: [] } }, settings: { 'service-url': 'http://localhost:' + config.www.port + '/', - 'admin-email': 'admin@example.com', + 'admin-email': 'keep.admin@mailtrain.org', 'default-homepage': 'https://mailtrain.org', 'smtp-hostname': config.testserver.host, 'smtp-port': config.testserver.port, diff --git a/test/e2e/lib/page.js b/test/e2e/lib/page.js index 3a79f014..d201948f 100644 --- a/test/e2e/lib/page.js +++ b/test/e2e/lib/page.js @@ -14,7 +14,7 @@ module.exports = (...extras) => Object.assign({ elements: {}, async getElement(key) { - return await driver.findElement(By.css(this.elements[key])); + return await driver.findElement(By.css(this.elements[key] || key)); }, async getLinkParams(key) { @@ -38,7 +38,7 @@ module.exports = (...extras) => Object.assign({ if (selector) { await driver.wait(until.elementLocated(By.css(selector)), waitTimeout); } - + for (const elem of (this.elementsToWaitFor || [])) { const sel = this.elements[elem]; if (!sel) { diff --git a/test/e2e/page-objects/subscription.js b/test/e2e/page-objects/subscription.js index 251e92b9..34a389c9 100644 --- a/test/e2e/page-objects/subscription.js +++ b/test/e2e/page-objects/subscription.js @@ -3,6 +3,49 @@ const config = require('../lib/config'); const web = require('../lib/web'); const mail = require('../lib/mail'); +const expect = require('chai').expect; + +const fieldHelpers = list => ({ + async fillFields(subscription) { + if (subscription.EMAIL && this.url === `/subscription/${list.cid}`) { + await this.setValue('emailInput', subscription.EMAIL); + } + + if (subscription.FIRST_NAME) { + await this.setValue('firstNameInput', subscription.FIRST_NAME); + } + + if (subscription.LAST_NAME) { + await this.setValue('lastNameInput', subscription.LAST_NAME); + } + + for (const field of list.customFields) { + if (field.key in subscription) { + await this.setValue(`[name="${field.column}"]`, subscription[field.key]); + } + } + }, + + async assertFields(subscription) { + if (subscription.EMAIL) { + expect(await this.getValue('emailInput')).to.equal(subscription.EMAIL); + } + + if (subscription.FIRST_NAME) { + expect(await this.getValue('firstNameInput')).to.equal(subscription.FIRST_NAME); + } + + if (subscription.LAST_NAME) { + expect(await this.getValue('lastNameInput')).to.equal(subscription.LAST_NAME); + } + + for (const field of list.customFields) { + if (field.key in subscription) { + expect(await this.getValue(`[name="${field.column}"]`)).to.equal(subscription[field.key]); + } + } + } +}); module.exports = list => ({ @@ -17,7 +60,7 @@ module.exports = list => ({ lastNameInput: '#main-form input[name="last-name"]', submitButton: 'a[href="#submit"]' } - }), + }, fieldHelpers(list)), webSubscribeNonPublic: web({ url: `/subscription/${list.cid}`, @@ -83,7 +126,7 @@ module.exports = list => ({ links: { manageAddressLink: `/subscription/${list.cid}/manage-address/:ucid` } - }), + }, fieldHelpers(list)), webManageAddress: web({ url: `/subscription/${list.cid}/manage-address/:ucid`, diff --git a/test/e2e/tests/subscription.js b/test/e2e/tests/subscription.js index ef81bcda..040cdcc2 100644 --- a/test/e2e/tests/subscription.js +++ b/test/e2e/tests/subscription.js @@ -7,6 +7,8 @@ const { useCase, step, precondition, driver } = require('../lib/mocha-e2e'); const shortid = require('shortid'); const expect = require('chai').expect; const createPage = require('../page-objects/subscription'); +const faker = require('faker'); +const request = require('request-promise'); function getPage(listConf) { return createPage(listConf); @@ -16,6 +18,59 @@ function generateEmail() { return 'keep.' + shortid.generate() + '@mailtrain.org'; } +function generateCustomFieldValue(field) { + // https://github.com/marak/Faker.js/#api-methods + switch (field.type) { + case 'text': + return faker.lorem.words(); + case 'website': + return faker.internet.url(); + case 'gpg': + return ''; + case 'longtext': + return faker.lorem.lines(); + case 'json': + return `{"say":"${faker.lorem.word()}"}`; + case 'number': + return faker.random.number().toString(); + case 'option': + return Math.round(Math.random()); + case 'date-us': + return '10/20/2017'; + case 'date-eur': + return '20/10/2017'; + case 'birthday-us': + return '10/20'; + case 'birthday-eur': + return '20/10'; + default: + return ''; + } +} + +function generateSubscriptionData(listConf) { + const data = { + EMAIL: generateEmail(), + FIRST_NAME: faker.name.firstName(), + LAST_NAME: faker.name.lastName(), + TIMEZONE: 'Europe/Tallinn', + }; + + listConf.customFields.forEach(field => { + data[field.key] = generateCustomFieldValue(field); + }); + + return data; +} + +function changeSubscriptionData(listConf, subscription) { + const data = generateSubscriptionData(listConf); + delete data.EMAIL; + const changedSubscription = Object.assign({}, subscription, data); + // TODO: Make sure values have actually changed. + return changedSubscription; +} + async function subscribe(listConf, subscription) { const page = getPage(listConf); @@ -24,16 +79,7 @@ async function subscribe(listConf, subscription) { }); await step('User submits a valid email and other subscription info.', async () => { - await page.webSubscribe.setValue('emailInput', subscription.email); - - if (subscription.firstName) { - await page.webSubscribe.setValue('firstNameInput', subscription.firstName); - } - - if (subscription.lastName) { - await page.webSubscribe.setValue('lastNameInput', subscription.lastName); - } - + await page.webSubscribe.fillFields(subscription); await page.webSubscribe.submit(); }); @@ -42,7 +88,7 @@ async function subscribe(listConf, subscription) { }); await step('System sends an email with a link to confirm the subscription.', async () => { - await page.mailConfirmSubscription.fetchMail(subscription.email); + await page.mailConfirmSubscription.fetchMail(subscription.EMAIL); }); await step('User clicks confirm subscription in the email', async () => { @@ -54,7 +100,7 @@ async function subscribe(listConf, subscription) { }); await step('System sends an email with subscription confirmation.', async () => { - await page.mailSubscriptionConfirmed.fetchMail(subscription.email); + await page.mailSubscriptionConfirmed.fetchMail(subscription.EMAIL); subscription.unsubscribeLink = await page.mailSubscriptionConfirmed.getHref('unsubscribeLink'); subscription.manageLink = await page.mailSubscriptionConfirmed.getHref('manageLink'); @@ -79,7 +125,7 @@ suite('Subscription use-cases', () => { useCase('Subscription to a public list (main scenario)', async () => { await subscribe(config.lists.l1, { - email: generateEmail() + EMAIL: generateEmail() }); }); @@ -105,7 +151,7 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l1); const subscription = await subscriptionExistsPrecondition(config.lists.l1, { - email: generateEmail() + EMAIL: generateEmail() }); await step('User navigates to list subscribe page', async () => { @@ -113,7 +159,7 @@ suite('Subscription use-cases', () => { }); await step('User submits the email which has been already registered.', async () => { - await page.webSubscribe.setValue('emailInput', subscription.email); + await page.webSubscribe.setValue('emailInput', subscription.EMAIL); await page.webSubscribe.submit(); }); @@ -122,7 +168,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email informing that the address has been already registered.', async () => { - await page.mailAlreadySubscribed.fetchMail(subscription.email); + await page.mailAlreadySubscribed.fetchMail(subscription.EMAIL); }); }); @@ -138,11 +184,7 @@ suite('Subscription use-cases', () => { useCase('Change profile info', async () => { const page = getPage(config.lists.l1); - const subscription = await subscriptionExistsPrecondition(config.lists.l1, { - email: generateEmail(), - firstName: 'John', - lastName: 'Doe' - }); + let subscription = await subscriptionExistsPrecondition(config.lists.l1, generateSubscriptionData(config.lists.l1)); await step('User clicks the manage subscription button.', async () => { await page.mailSubscriptionConfirmed.click('manageLink'); @@ -150,16 +192,12 @@ suite('Subscription use-cases', () => { await step('Systems shows a form to change subscription details. The form contains data entered during subscription.', async () => { await page.webManage.waitUntilVisibleAfterRefresh(); - expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email); - expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName); - expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName); + await page.webManage.assertFields(subscription); }); - await step('User enters another name and submits the form.', async () => { - subscription.firstName = 'Adam'; - subscription.lastName = 'B'; - await page.webManage.setValue('firstNameInput', subscription.firstName); - await page.webManage.setValue('lastNameInput', subscription.lastName); + await step('User enters other values and submits the form.', async () => { + subscription = changeSubscriptionData(config.lists.l1, subscription); + await page.webManage.fillFields(subscription); await page.webManage.submit(); }); @@ -168,14 +206,11 @@ suite('Subscription use-cases', () => { }); await step('User navigates to manage subscription again.', async () => { - // await page.webManage.navigate(subscription.manageLink); await page.webManage.navigate({ ucid: subscription.ucid }); }); await step('Systems shows a form with the changes made previously.', async () => { - expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email); - expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName); - expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName); + await page.webManage.assertFields(subscription); }); }); @@ -183,9 +218,9 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l1); const subscription = await subscriptionExistsPrecondition(config.lists.l1, { - email: generateEmail(), - firstName: 'John', - lastName: 'Doe' + EMAIL: generateEmail(), + FIRST_NAME: 'John', + LAST_NAME: 'Doe' }); await step('User clicks the manage subscription button.', async () => { @@ -194,9 +229,7 @@ suite('Subscription use-cases', () => { await step('Systems shows a form to change subscription details. The form contains data entered during subscription.', async () => { await page.webManage.waitUntilVisibleAfterRefresh(); - expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email); - expect(await page.webManage.getValue('firstNameInput')).to.equal(subscription.firstName); - expect(await page.webManage.getValue('lastNameInput')).to.equal(subscription.lastName); + await page.webManage.fillFields(subscription); }); await step('User clicks the change address button.', async () => { @@ -208,8 +241,8 @@ suite('Subscription use-cases', () => { }); await step('User fills in a new email address and submits the form.', async () => { - subscription.email = generateEmail(); - await page.webManageAddress.setValue('emailNewInput', subscription.email); + subscription.EMAIL = generateEmail(); + await page.webManageAddress.setValue('emailNewInput', subscription.EMAIL); await page.webManageAddress.submit(); }); @@ -220,7 +253,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email with a link to confirm the address change.', async () => { - await page.mailConfirmAddressChange.fetchMail(subscription.email); + await page.mailConfirmAddressChange.fetchMail(subscription.EMAIL); }); await step('User clicks confirm subscription in the email', async () => { @@ -231,11 +264,11 @@ suite('Subscription use-cases', () => { await page.webManage.waitUntilVisibleAfterRefresh(); await page.webManage.waitForFlash(); expect(await page.webManage.getFlash()).to.contain('Email address changed'); - expect(await page.webManage.getValue('emailInput')).to.equal(subscription.email); + expect(await page.webManage.getValue('emailInput')).to.equal(subscription.EMAIL); }); await step('System sends an email with subscription confirmation.', async () => { - await page.mailSubscriptionConfirmed.fetchMail(subscription.email); + await page.mailSubscriptionConfirmed.fetchMail(subscription.EMAIL); }); }); @@ -243,7 +276,7 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l1); const subscription = await subscriptionExistsPrecondition(config.lists.l1, { - email: generateEmail() + EMAIL: generateEmail() }); await step('User clicks the unsubscribe button.', async () => { @@ -255,7 +288,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email that confirms unsubscription.', async () => { - await page.mailUnsubscriptionConfirmed.fetchMail(subscription.email); + await page.mailUnsubscriptionConfirmed.fetchMail(subscription.EMAIL); }); }); @@ -263,7 +296,7 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l2); const subscription = await subscriptionExistsPrecondition(config.lists.l2, { - email: generateEmail() + EMAIL: generateEmail() }); await step('User clicks the unsubscribe button.', async () => { @@ -283,7 +316,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email that confirms unsubscription.', async () => { - await page.mailUnsubscriptionConfirmed.fetchMail(subscription.email); + await page.mailUnsubscriptionConfirmed.fetchMail(subscription.EMAIL); }); }); @@ -291,7 +324,7 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l3); const subscription = await subscriptionExistsPrecondition(config.lists.l3, { - email: generateEmail() + EMAIL: generateEmail() }); await step('User clicks the unsubscribe button.', async () => { @@ -303,7 +336,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email with a link to confirm unsubscription.', async () => { - await page.mailConfirmUnsubscription.fetchMail(subscription.email); + await page.mailConfirmUnsubscription.fetchMail(subscription.EMAIL); }); await step('User clicks the confirm unsubscribe button in the email.', async () => { @@ -315,7 +348,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email that confirms unsubscription.', async () => { - await page.mailUnsubscriptionConfirmed.fetchMail(subscription.email); + await page.mailUnsubscriptionConfirmed.fetchMail(subscription.EMAIL); }); }); @@ -323,7 +356,7 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l4); const subscription = await subscriptionExistsPrecondition(config.lists.l4, { - email: generateEmail() + EMAIL: generateEmail() }); await step('User clicks the unsubscribe button.', async () => { @@ -343,7 +376,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email with a link to confirm unsubscription.', async () => { - await page.mailConfirmUnsubscription.fetchMail(subscription.email); + await page.mailConfirmUnsubscription.fetchMail(subscription.EMAIL); }); await step('User clicks the confirm unsubscribe button in the email.', async () => { @@ -355,7 +388,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email that confirms unsubscription.', async () => { - await page.mailUnsubscriptionConfirmed.fetchMail(subscription.email); + await page.mailUnsubscriptionConfirmed.fetchMail(subscription.EMAIL); }); }); @@ -363,7 +396,7 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l5); await subscriptionExistsPrecondition(config.lists.l5, { - email: generateEmail() + EMAIL: generateEmail() }); await step('User clicks the unsubscribe button.', async () => { @@ -379,9 +412,9 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l1); const subscription = await subscriptionExistsPrecondition(config.lists.l1, { - email: generateEmail(), - firstName: 'John', - lastName: 'Doe' + EMAIL: generateEmail(), + FIRST_NAME: 'John', + LAST_NAME: 'Doe' }); await step('User clicks the unsubscribe button.', async () => { @@ -393,7 +426,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email that confirms unsubscription.', async () => { - await page.mailUnsubscriptionConfirmed.fetchMail(subscription.email); + await page.mailUnsubscriptionConfirmed.fetchMail(subscription.EMAIL); }); await step('User clicks the resubscribe button.', async () => { @@ -402,9 +435,9 @@ suite('Subscription use-cases', () => { await step('Systems shows the subscription form. The form contains data entered during initial subscription.', async () => { await page.webSubscribe.waitUntilVisibleAfterRefresh(); - expect(await page.webSubscribe.getValue('emailInput')).to.equal(subscription.email); - expect(await page.webSubscribe.getValue('firstNameInput')).to.equal(subscription.firstName); - expect(await page.webSubscribe.getValue('lastNameInput')).to.equal(subscription.lastName); + expect(await page.webSubscribe.getValue('emailInput')).to.equal(subscription.EMAIL); + expect(await page.webSubscribe.getValue('firstNameInput')).to.equal(subscription.FIRST_NAME); + expect(await page.webSubscribe.getValue('lastNameInput')).to.equal(subscription.LAST_NAME); }); await step('User submits the subscription form.', async () => { @@ -416,7 +449,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email with a link to confirm the subscription.', async () => { - await page.mailConfirmSubscription.fetchMail(subscription.email); + await page.mailConfirmSubscription.fetchMail(subscription.EMAIL); }); await step('User clicks confirm subscription in the email', async () => { @@ -428,7 +461,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email with subscription confirmation. The manage and unsubscribe links are identical with the initial subscription.', async () => { - await page.mailSubscriptionConfirmed.fetchMail(subscription.email); + await page.mailSubscriptionConfirmed.fetchMail(subscription.EMAIL); const unsubscribeLink = await page.mailSubscriptionConfirmed.getHref('unsubscribeLink'); const manageLink = await page.mailSubscriptionConfirmed.getHref('manageLink'); expect(subscription.unsubscribeLink).to.equal(unsubscribeLink); @@ -440,9 +473,9 @@ suite('Subscription use-cases', () => { const page = getPage(config.lists.l1); const oldSubscription = await subscriptionExistsPrecondition(config.lists.l1, { - email: generateEmail(), - firstName: 'old first name', - lastName: 'old last name' + EMAIL: generateEmail(), + FIRST_NAME: 'old first name', + LAST_NAME: 'old last name' }); await step('User clicks the unsubscribe button.', async () => { @@ -454,12 +487,12 @@ suite('Subscription use-cases', () => { }); await step('System sends an email that confirms unsubscription.', async () => { - await page.mailUnsubscriptionConfirmed.fetchMail(oldSubscription.email); + await page.mailUnsubscriptionConfirmed.fetchMail(oldSubscription.EMAIL); }); const newSubscription = await subscriptionExistsPrecondition(config.lists.l1, { - email: generateEmail(), - firstName: 'new first name' + EMAIL: generateEmail(), + FIRST_NAME: 'new first name' }); await step('User clicks the manage subscription button.', async () => { @@ -467,6 +500,7 @@ suite('Subscription use-cases', () => { }); await step('User clicks the change address button.', async () => { + await page.webManage.waitUntilVisibleAfterRefresh(); await page.webManage.click('manageAddressLink'); }); @@ -475,7 +509,7 @@ suite('Subscription use-cases', () => { }); await step('User fills in the email address of the original subscription and submits the form.', async () => { - await page.webManageAddress.setValue('emailNewInput', oldSubscription.email); + await page.webManageAddress.setValue('emailNewInput', oldSubscription.EMAIL); await page.webManageAddress.submit(); }); @@ -486,7 +520,7 @@ suite('Subscription use-cases', () => { }); await step('System sends an email with a link to confirm the address change.', async () => { - await page.mailConfirmAddressChange.fetchMail(oldSubscription.email); + await page.mailConfirmAddressChange.fetchMail(oldSubscription.EMAIL); }); await step('User clicks confirm subscription in the email', async () => { @@ -497,13 +531,117 @@ suite('Subscription use-cases', () => { await page.webManage.waitUntilVisibleAfterRefresh(); await page.webManage.waitForFlash(); expect(await page.webManage.getFlash()).to.contain('Email address changed'); - expect(await page.webManage.getValue('emailInput')).to.equal(oldSubscription.email); - expect(await page.webManage.getValue('firstNameInput')).to.equal(newSubscription.firstName); + expect(await page.webManage.getValue('emailInput')).to.equal(oldSubscription.EMAIL); + expect(await page.webManage.getValue('firstNameInput')).to.equal(newSubscription.FIRST_NAME); expect(await page.webManage.getValue('lastNameInput')).to.equal(''); }); await step('System sends an email with subscription confirmation.', async () => { - await page.mailSubscriptionConfirmed.fetchMail(oldSubscription.email); + await page.mailSubscriptionConfirmed.fetchMail(oldSubscription.EMAIL); + }); + }); + +}); + + +async function apiSubscribe(listConf, subscription) { + await step('Add subscription via API call.', async () => { + const response = await request({ + uri: `${config.baseUrl}/api/subscribe/${listConf.cid}?access_token=${config.users.admin.accessToken}`, + method: 'POST', + json: subscription + }); + expect(response.error).to.be.a('undefined'); + expect(response.data.id).to.be.a('string'); + subscription.ucid = response.data.id; + }); + return subscription; +} + +suite('API Subscription use-cases', () => { + + useCase('Subscription to list #1, without confirmation.', async () => { + const page = getPage(config.lists.l1); + const subscription = await apiSubscribe(config.lists.l1, generateSubscriptionData(config.lists.l1)); + + await step('User navigates to manage subscription.', async () => { + await page.webManage.navigate({ ucid: subscription.ucid }); + }); + + await step('Systems shows a form containing the data submitted with the API call.', async () => { + await page.webManage.assertFields(subscription); + }); + }); + + useCase('Subscription to list #1, with confirmation.', async () => { + const page = getPage(config.lists.l1); + + const subscription = await apiSubscribe(config.lists.l1, Object.assign(generateSubscriptionData(config.lists.l1), { + REQUIRE_CONFIRMATION: 'yes' + })); + + await step('System sends an email with a link to confirm the subscription.', async () => { + await page.mailConfirmSubscription.fetchMail(subscription.EMAIL); + }); + + await step('User clicks confirm subscription in the email', async () => { + await page.mailConfirmSubscription.click('confirmLink'); + }); + + await step('System shows a notice that subscription has been confirmed.', async () => { + await page.webSubscribedNotice.waitUntilVisibleAfterRefresh(); + }); + + await step('System sends an email with subscription confirmation.', async () => { + await page.mailSubscriptionConfirmed.fetchMail(subscription.EMAIL); + }); + + await step('User navigates to manage subscription.', async () => { + await page.webManage.navigate({ ucid: subscription.ucid }); + }); + + await step('Systems shows a form containing the data submitted with the API call.', async () => { + await page.webManage.assertFields(subscription); + }); + }); + + useCase('Change profile info', async () => { + const page = getPage(config.lists.l1); + + const initialSubscription = await apiSubscribe(config.lists.l1, generateSubscriptionData(config.lists.l1)); + + const update = changeSubscriptionData(config.lists.l1, initialSubscription); + delete update.FIRST_NAME; + + const changedSubscription = await apiSubscribe(config.lists.l1, update); + changedSubscription.FIRST_NAME = initialSubscription.FIRST_NAME; + + expect(changedSubscription.ucid).to.equal(initialSubscription.ucid); + + await step('User navigates to manage subscription.', async () => { + await page.webManage.navigate({ ucid: changedSubscription.ucid }); + }); + + await step('Systems shows a form containing the updated subscription data.', async () => { + await page.webManage.assertFields(changedSubscription); + }); + }); + + useCase('Unsubscribe', async () => { + const subscription = await apiSubscribe(config.lists.l1, generateSubscriptionData(config.lists.l1)); + + await step('Unsubsribe via API call.', async () => { + const response = await request({ + uri: `${config.baseUrl}/api/unsubscribe/${config.lists.l1.cid}?access_token=${config.users.admin.accessToken}`, + method: 'POST', + json: { + EMAIL: subscription.EMAIL + } + }); + + expect(response.error).to.be.a('undefined'); + expect(response.data.id).to.be.a('number'); // FIXME Shouldn't data.id be the cid instead of the DB id? + expect(response.data.unsubscribed).to.equal(true); }); });